/* BookToTagMethod.java created 2008-03-22
*
*/
package org.signalml.method.booktotag;
import static org.signalml.app.util.i18n.SvarogI18n._;
import java.awt.Color;
import java.util.Arrays;
import java.util.LinkedHashSet;
import org.apache.log4j.Logger;
import org.signalml.domain.book.StandardBook;
import org.signalml.domain.book.StandardBookAtom;
import org.signalml.domain.book.StandardBookSegment;
import org.signalml.domain.tag.StyledTagSet;
import org.signalml.method.AbstractMethod;
import org.signalml.method.ComputationException;
import org.signalml.method.MethodExecutionTracker;
import org.signalml.method.TrackableMethod;
import org.signalml.plugin.export.SignalMLException;
import org.signalml.plugin.export.method.BaseMethodData;
import org.signalml.plugin.export.signal.SignalSelectionType;
import org.signalml.plugin.export.signal.Tag;
import org.signalml.plugin.export.signal.TagStyle;
import org.springframework.validation.Errors;
/**
* BookToTagMethod class provides method which executes BookToTagData.
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
public class BookToTagMethod extends AbstractMethod implements TrackableMethod {
/**
* Logger to save history of execution at.
*/
protected static final Logger logger = Logger.getLogger(BookToTagMethod.class);
private static final String UID = "10984681-2eea-42aa-b637-bc4781baf692";
private static final String NAME = "bookToTag";
private static final int[] VERSION = new int[] {1,0};
/**
* Creates new instance of BookToTagMethod.
*/
public BookToTagMethod() throws SignalMLException {
super();
}
/**
* {@inheritDoc}
*/
@Override
public String getUID() {
return UID;
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return NAME;
}
/**
* {@inheritDoc}
*/
@Override
public int[] getVersion() {
return VERSION;
}
/**
* {@inheritDoc}
*/
@Override
public BaseMethodData createData() {
return new BookToTagData();
}
/**
* {@inheritDoc}
*/
@Override
public boolean supportsDataClass(Class<?> clazz) {
return BookToTagData.class.isAssignableFrom(clazz);
}
/**
* {@inheritDoc}
*/
@Override
public Class<?> getResultClass() {
return BookToTagResult.class;
}
/**
* {@inheritDoc}
*/
@Override
public void validate(Object data, Errors errors) {
super.validate(data, errors);
// TODO validation
}
/**
* Executes this BookToTagMethod and returns BookToTagResult containing result of computation.
*
* @param dataObj the data object
* @param tracker the tracker used to monitor the execution
* @return the result object
* @throws ComputationException when computation fails for
* reasons other than bad input data, e.g. when book is empty
*/
@Override
public Object doComputation(Object dataObj, final MethodExecutionTracker tracker) throws ComputationException {
BookToTagData data = (BookToTagData) dataObj;
tracker.resetTickers();
StandardBook book = data.getBook();
LinkedHashSet<Integer> channels = data.getChannels();
int channelCount = channels.size();
int segmentCount = book.getSegmentCount();
int[] channelArr = new int[channelCount];
int i = 0;
for (Integer integer : channels) {
channelArr[i] = integer;
i++;
}
if (channelCount <=0 || segmentCount <= 0) {
throw new ComputationException("Empty book");
}
int stepCount = channelCount * segmentCount;
tracker.setTickerLimits(new int[] {stepCount});
StandardBookSegment firstSegment = book.getSegmentAt(0, channelArr[0]);
float pageSize = firstSegment.getSegmentTimeLength();
int blocksPerPage = 5; // TODO add to configuration maybe
float blockSize = pageSize / blocksPerPage;
StyledTagSet resultTagSet = new StyledTagSet(pageSize, blocksPerPage);
TagStyle pageStyle = null;
TagStyle blockStyle = null;
TagStyle channelStyle = null;
if (data.isMakePageTags()) {
pageStyle = new TagStyle(SignalSelectionType.PAGE, "P", "Page", Color.YELLOW, Color.YELLOW, 1, null, null, false);
resultTagSet.addStyle(pageStyle);
}
if (data.isMakeBlockTags()) {
blockStyle = new TagStyle(SignalSelectionType.BLOCK, "B", "Block", Color.ORANGE, Color.ORANGE, 1, null, null, false);
resultTagSet.addStyle(blockStyle);
}
if (data.isMakePageTags()) {
channelStyle = new TagStyle(SignalSelectionType.CHANNEL, "C", "Channel", Color.RED, Color.RED, 1, null, null, false);
resultTagSet.addStyle(channelStyle);
}
boolean pageMarked;
boolean[] blockMarked = new boolean[blocksPerPage];
int e;
int j;
int atomCount;
StandardBookSegment segment;
StandardBookAtom atom;
float segmentPosition;
int blockIndex;
for (i=0; i<segmentCount; i++) {
pageMarked = false;
Arrays.fill(blockMarked, false);
for (e=0; e<channelCount; e++) {
segment = book.getSegmentAt(i, channelArr[e]);
if (segment.getSegmentTimeLength() != pageSize) {
logger.warn("Incompatible segment length [" + segment.getSegmentTimeLength() + "]");
tracker.tick(0);
continue;
}
segmentPosition = segment.getSegmentTime();
atomCount = segment.getAtomCount();
if (atomCount > 0 && !pageMarked && data.isMakePageTags()) {
resultTagSet.addTag(new Tag(pageStyle, segmentPosition, pageSize));
pageMarked = true;
}
for (j=0; j<atomCount; j++) {
atom = segment.getAtomAt(j);
if (data.isMakeBlockTags()) {
blockIndex = (int) Math.floor(atom.getTimePosition() / blockSize);
if (blockIndex >= blocksPerPage) {
logger.warn("Incorrect block index [" + blockIndex + "]");
}
if (!blockMarked[blockIndex]) {
resultTagSet.addTag(new Tag(blockStyle, segmentPosition + blockIndex*blockSize, blockSize));
blockMarked[blockIndex] = true;
}
}
if (data.isMakeChannelTags()) {
resultTagSet.addTag(new Tag(channelStyle, segmentPosition + atom.getTimePosition(), atom.getTimeScale(), channelArr[e]));
}
}
tracker.tick(0);
}
}
BookToTagResult result = new BookToTagResult();
result.setTagSet(resultTagSet);
return result;
}
/**
* {@inheritDoc}
*/
@Override
public int getTickerCount() {
return 1;
}
/**
* {@inheritDoc}
*/
@Override
public String getTickerLabel(int ticker) {
return _("Segments processed");
}
}