package org.signalml.plugin.newartifact.logic.algorithm; import java.util.Arrays; import org.signalml.plugin.newartifact.data.NewArtifactConstants; public class MuscleActivityArtifactAlgorithm extends NewArtifactAlgorithmBase { private final double weights[]; private final FFTHelper fftHelper; public MuscleActivityArtifactAlgorithm(NewArtifactConstants constants) { super(constants); int smallBlockLength = this.constants.getSmallBlockLength(); this.weights = new double[smallBlockLength]; for (int j = 1; j < smallBlockLength + 1; ++j) { this.weights[j - 1] = (1.0d - Math.cos(2.0d * j * Math.PI / (smallBlockLength + 1))) / 2.0d; } this.fftHelper = new FFTHelper(this.constants.getSmallBlockLength(), 2 * this.constants.getSmallBlockPowerVectorLength()); this.resultBuffer = new double[2][this.constants.channelCount * this.constants.getBlockCapacity()]; } @Override public double[][] computeHead(NewArtifactAlgorithmData data) { return this.zeros(2, this.constants.channelCount * this.constants.getBlockCapacity()); } @Override public double[][] computeTail(NewArtifactAlgorithmData data) { return this.computeHead(data); } @Override public double[][] compute(NewArtifactAlgorithmData data) { double signal[][] = data.signal; int channelCount = this.constants.channelCount; double subSignal[][] = new double[signal.length][]; int paddingLeft = this.constants.getPaddingLength(); int smallBlockLength = this.constants.getSmallBlockLength(); double coefficient = this.constants .getFreqChangeCoefficientForSmallBlock(); int lowMuscleStart = (int)(this.constants.getFm1() * coefficient); int lowMuscleEnd = (int)(this.constants.getFs1() * coefficient) - 1; int highMuscleStart = (int)(this.constants.getFs2() * coefficient); int highMuscleEnd = (int)(this.constants.getFm2() * coefficient); for (int k = 0; k < this.constants.getBlockCapacity(); ++k) { for (int i = 0; i < channelCount; ++i) { int start = paddingLeft + k * smallBlockLength; double v[] = subSignal[i] = Arrays.copyOfRange(signal[i], start, start + smallBlockLength); for (int j = 0; j < smallBlockLength; ++j) { v[j] *= this.weights[j]; } } DetrendHelper.detrend(subSignal); double y[] = new double[2 * smallBlockLength]; for (int i = 0; i < channelCount; ++i) { double u[] = subSignal[i]; double sumL, sumML, sumMH, sumP, sumAll; sumL = sumML = sumMH = sumP = 0.0d; this.fftHelper.fft(u, y); int j; for (j = 0; j < 2 * lowMuscleStart; j += 2) { sumL += y[j]; } for (; j <= 2 * lowMuscleEnd; j += 2) { sumML += y[j]; } for (; j <= 2 * highMuscleStart; j += 2) { sumP += y[j]; } for (; j <= 2 * highMuscleEnd; j += 2) { sumMH += y[j]; } sumAll = sumL + sumML + sumMH + MuscleActivityArtifactAlgorithm.DELTA; this.resultBuffer[0][i + k * channelCount] = (sumML + sumMH) / sumAll; this.resultBuffer[1][i + k * channelCount] = sumP / (sumAll + sumP); } } return this.resultBuffer; } }