package org.signalml.plugin.newstager.logic.artifact;
import java.util.Arrays;
import org.signalml.plugin.domain.montage.PluginChannel;
import org.signalml.plugin.newstager.data.NewStagerArtifactAlgorithmData;
import org.signalml.plugin.newstager.data.NewStagerConstants;
import org.signalml.plugin.newstager.exception.NewStagerPluginException;
public class NewStagerArtifactMontageAlgorithm extends
NewStagerArtifactAnalysisAlgorithmBase {
private static final double NORMALIZING_FACTOR = 20.0d;
private static final double butterEEGNum[] = { 0.293416181696000d,
-1.467080908480002d, 2.934161816960004d, -2.934161816960004d,
1.467080908480002d, -0.293416181696000d
};
private static final double butterEEGDen[] = { 1.000000000000000d,
-2.630709206701736d, 3.100229979210853d, -1.937767771895702d,
0.634524080553226d, -0.086086775910497d
};
private int montageArtifactCount;
private int c3a2Count;
private int c4a1Count;
private final NewStagerArtifactAlgorithmData data;
public NewStagerArtifactMontageAlgorithm(NewStagerArtifactAlgorithmData data) {
this.data = data;
}
public boolean run(double signal[][]) {
this.montageArtifactCount = 0;
this.c3a2Count = 0;
this.c4a1Count = 0;
int halfEpochSize = this.data.constants.blockLengthInSecondsINT >> 1;
boolean eegFlag = this.data.parameters.analyseEEGChannelsFlag;
boolean emgFlag = this.data.parameters.analyseEMGChannelFlag;
if (!eegFlag && !emgFlag) {
return false;
}
try {
if (emgFlag) {
this.computeMontageArtifactCount(signal);
}
if (eegFlag) {
this.computeEEGArtifactCount(signal);
}
} catch (NewStagerPluginException e) {
return false;
}
if (emgFlag & eegFlag) {
return (this.montageArtifactCount > halfEpochSize
|| this.c3a2Count > halfEpochSize || this.c4a1Count > halfEpochSize);
} else if (emgFlag) {
return this.montageArtifactCount > halfEpochSize;
} else {
return this.c3a2Count > halfEpochSize
|| this.c4a1Count > halfEpochSize;
}
}
private void computeMontageArtifactCount(double signal[][])
throws NewStagerPluginException {
NewStagerConstants constants = this.data.constants;
double montageThreshold = this.data.parameters.thresholds.montageEMGThreshold;
double montageToneThreshold = this.data.parameters.thresholds.montageToneEMGThreshold;
double emgChannelSignal[] = this.getChannelData(this.data.channels,
PluginChannel.EMG, signal);
double emgMean[] = this.computeItermediateMean(
Arrays.copyOf(emgChannelSignal, emgChannelSignal.length),
constants);
double emgFilteredMean[] = this.computeItermediateMeanFiltered(
emgChannelSignal,
NewStagerArtifactMontageAlgorithm.butterEEGNum,
NewStagerArtifactMontageAlgorithm.butterEEGDen, constants);
assert(emgFilteredMean.length == emgMean.length);
int count = 0;
for (int i = 0; i < emgMean.length; ++i) {
if (emgMean[i] > montageThreshold
&& emgFilteredMean[i] > montageToneThreshold) {
++count;
}
}
this.montageArtifactCount = count;
}
private void computeEEGArtifactCount(double signal[][])
throws NewStagerPluginException {
this.c3a2Count = this.computeDifferenceArtifactCount(signal,
PluginChannel.C3, PluginChannel.A2);
this.c4a1Count = this.computeDifferenceArtifactCount(signal,
PluginChannel.C4, PluginChannel.A1);
}
private int computeDifferenceArtifactCount(double signal[][],
PluginChannel channel1, PluginChannel channel2)
throws NewStagerPluginException {
double channelSignal1[] = this.getChannelData(this.data.channels, channel1, signal);
double channelSignal2[] = this.getChannelData(this.data.channels, channel2, signal);
double threshold = this.data.parameters.thresholds.montageEEGThreshold;
assert(channelSignal1.length == channelSignal2.length);
int length = channelSignal1.length;
double channelSignalDifference[] = new double[length];
for (int i = 0; i < length; ++i) {
channelSignalDifference[i] = channelSignal1[i] - channelSignal2[i]
/ NewStagerArtifactMontageAlgorithm.NORMALIZING_FACTOR;
}
double mean[] = this.computeItermediateMeanFiltered(
channelSignalDifference,
NewStagerArtifactMontageAlgorithm.butterEEGNum,
NewStagerArtifactMontageAlgorithm.butterEEGDen,
this.data.constants);
int count = 0;
for (int i = 0; i < mean.length; ++i) {
if (mean[i] > threshold) {
++count;
}
}
return count;
}
}