/* AverageReferenceMontageGenerator.java created 2007-11-23
*
*/
package org.signalml.domain.montage.generators;
import java.util.ArrayList;
import java.util.List;
import org.signalml.app.model.components.validation.ValidationErrors;
import org.signalml.domain.montage.system.ChannelType;
import org.signalml.domain.montage.Montage;
import org.signalml.domain.montage.MontageException;
import org.signalml.domain.montage.SourceChannel;
import org.signalml.domain.montage.SourceMontage;
import org.signalml.domain.montage.generators.AbstractMontageGenerator;
import org.signalml.domain.montage.system.ChannelFunction;
import org.springframework.validation.Errors;
/**
* This class represents a generator for an average reference montage.
* In the average reference montage the outputs of all of the amplifiers are
* summed and averaged, and this averaged signal is used as the common reference
* for each channel.
* (source: {@code http://en.wikipedia.org/wiki/Electroencephalography})
*
* This class generates montage of that type from the given "raw" montage and checks if
* the given {@link SourceMontage montages} are valid average reference montages.
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
public class AverageReferenceMontageGenerator extends AbstractMontageGenerator {
private static final long serialVersionUID = 1L;
/**
* an array with names of {@link SourceChannel source channels} that
* this generator will use as reference channels in the created
* {@link Montage montages} (actually in the
* {@link MontageChannel montage channels} in a montage)
*/
protected String[] referenceChannelsNames;
/**
* Constructor. Creates a generator for an average reference montage
* based on the <i>refChannels</i> array.
* @param refChannels array with labels of
* {@link SourceChannel source channels} that will be used as
* reference channels in created {@link Montage montage}
* (actually in {@link MontageChannel montage channels} in a montage)
* @throws NullPointerException if the array of channels is null or empty
*/
public AverageReferenceMontageGenerator(String[] refChannelsNames) {
if (refChannelsNames == null) {
throw new NullPointerException("Channels cannot be null or empty");
}
this.referenceChannelsNames = refChannelsNames;
}
/**
* Creates an average reference montage from a given montage.
* @param sourceMontage the montage to be used
* @throws MontageException thrown if there is no channel with some label
*/
@Override
public void createMontage(Montage montage) throws MontageException {
List<SourceChannel> referenceSourceChannels = getReferenceSourceChannels(montage);
String token = "-1/" + Integer.toString(referenceSourceChannels.size());
boolean oldMajorChange = montage.isMajorChange();
try {
montage.setMajorChange(true);
montage.reset();
int size = montage.getSourceChannelCount();
int index;
for (int i=0; i<size; i++) {
index = montage.addMontageChannel(i);
for (SourceChannel referenceSourceChannel: referenceSourceChannels) {
SourceChannel sourceChannel = montage.getSourceChannelAt(i);
if (sourceChannel.getFunction() == ChannelFunction.EEG
&& !sourceChannel.isChannelType(ChannelType.REFERENCE))
montage.setReference(index, referenceSourceChannel.getChannel(), token);
}
}
} finally {
montage.setMajorChange(oldMajorChange);
}
montage.setMontageGenerator(this);
montage.setChanged(false);
}
/**
* Returns the list of the {@link SourceChannel SourceChannels} from
* given sourceMontage that will be used as the reference channels.
* @param sourceMontage the source montage to be search through
* @return the list of reference {@link SourceChannel SourceChannels}.
*/
protected List<SourceChannel> getReferenceSourceChannels(SourceMontage sourceMontage) {
List<SourceChannel> sourceChannels = new ArrayList<SourceChannel>();
for (int i = 0; i < referenceChannelsNames.length; i++) {
SourceChannel sourceChannel = sourceMontage.getSourceChannelByLabel(referenceChannelsNames[i]);
if (sourceChannel != null)
sourceChannels.add(sourceChannel);
}
return sourceChannels;
}
/**
* Checks if the montage is a valid average reference montage.
* @param sourceMontage the montage to be checked
* @param errors Errors object used to report errors
* @return true if the montage is a valid average reference montage,
* false otherwise
*/
@Override
public boolean validateSourceMontage(SourceMontage sourceMontage, ValidationErrors errors) {
boolean ok = true;
List<SourceChannel> sourceChannels = new ArrayList<SourceChannel>();
for (int i = 0; i < referenceChannelsNames.length; i++) {
SourceChannel sourceChannel = sourceMontage.getSourceChannelByLabel(referenceChannelsNames[i]);
if (sourceChannel != null)
sourceChannels.add(sourceChannel);
else {
onNotFound(referenceChannelsNames[i], errors);
ok = false;
}
}
return ok;
}
}