scripts/channelClasses/standard/ExtraEog.java
/////////////////////////////////////////////////////////////////
// Processes data by creating EOGV,EOGH channels, and then performing
// standard filtering
//
// This code is compiled at runtime, but compilation can be tested by:
// javac -cp build scripts/channelClasses/standard/ExtraEog.java
// rm scripts/channelClasses/standard/ExtraEog.class
/////////////////////////////////////////////////////////////////
package standard;
import java.io.*;
import java.util.*;
import generalClasses.*;
import recordingClasses.Recording;
import seriesClasses.*;
import channelClasses.ChannelScript;
import static channelClasses.Channel.*;
/////////////////////////////////////////////////////////////////
/** Processes data by creating EOGV,EOGH channels, and then performing
* standard filtering
*/
public class ExtraEog extends ChannelScript
{
/** Recording instance to be operated on */
Recording rec = null;
/** Cutoff in Hz, applied only to EEG,EMG,EOG */
float highpassCutoff;
/** SD in uV, to detect flat channels */
float sdLowerThreshold;
/** SD in uV, to detect noisy channels */
float sdUpperThreshold;
/** Log of warnings generated during update */
ArrayList<String> warnings = null;
////////////////////////////////////////////////////////////////////
/** Initialize instance by setting its parameters to specified values.
* @param highpassCutoff Highpass cutoff applied to EEG,EMG and EOG
* @param sdLowerThreshold SD in uV, to detect flat channels
* @param sdUpperThreshold SD in uV, to detect noisy channels
*/
public ExtraEog(Recording rec, float highpassCutoff,
float sdLowerThreshold, float sdUpperThreshold) {
this.rec = rec;
this.highpassCutoff = highpassCutoff;
this.sdLowerThreshold = sdLowerThreshold;
this.sdUpperThreshold = sdUpperThreshold;
warnings = new ArrayList<String>();
} // ExtraEog
////////////////////////////////////////////////////////////////////
/** Initialize instance by setting its parameters to default values.
*/
public ExtraEog(Recording rec) {
this(rec, 0.5f,1.0f,50.0f);
} // ExtraEog
////////////////////////////////////////////////////////////////////
/** Update recording data by performing channel-oriented operations.
* <p>Available modes are EEG, EOG, REF, EMG, EDA, RES, ECG, EVE.
*/
public void update() {
// Create EOGV = VPVA-VNVB and EOGH = HPHL-HNHR.
ArrayList<SeriesAnalog> vp = selectSite(rec, "VPVA");
ArrayList<SeriesAnalog> vn = selectSite(rec, "VNVB");
ArrayList<SeriesAnalog> hp = selectSite(rec, "HPHL");
ArrayList<SeriesAnalog> hn = selectSite(rec, "HNHR");
ArrayList<SeriesAnalog> subsetEOG = new ArrayList<SeriesAnalog>();
if(vp.size()==1 && vn.size()==1) {
SeriesAnalog s = vp.get(0).clone();
s.sub(vn.get(0));
s.setSites(new SiteSet(new Site("EOGV")));
subsetEOG.add(s);
}
if(hp.size()==1 && hn.size()==1) {
SeriesAnalog s = hp.get(0).clone();
s.sub(hn.get(0));
s.setSites(new SiteSet(new Site("EOGH")));
subsetEOG.add(s);
}
subtractTemporalMean(subsetEOG);
ArrayList<SeriesAnalog> result = subsetEOG;
// Process EEG
ArrayList<SeriesAnalog> subset = selectMode(rec, DataMode.EEG);
filterHP(highpassCutoff, subset); // NB: this does not remove DC
subtractTemporalMean(subset);
ArrayList<SeriesAnalog> subsetThresholded=new ArrayList<SeriesAnalog>();
for(int i=0; i<subset.size(); i++) {
SeriesAnalog s = subset.get(i);
BasicStats bs = s.getStats();
boolean ok = bs.sd > sdLowerThreshold && bs.sd < sdUpperThreshold;
if(ok) subsetThresholded.add(s);
else warnings.add("Channel "+s.getPrimaryLabel()+" has SD="+bs.sd);
}
result = listsUnion(result, subsetThresholded);
// Process EMG
subset = selectMode(rec, DataMode.EMG);
filterHP(highpassCutoff, subset);
subtractTemporalMean(subset);
result = listsUnion(result, subset);
// Process EDA,EVE: do nothing to them
subset = selectMode(rec, DataMode.EDA);
subset = listsUnion(subset,selectMode(rec, DataMode.EVE));
result = listsUnion(result, subset);
// Process RES,ECG,REF: subtract temporal mean
subset = selectMode(rec, DataMode.ECG);
subset = listsUnion(subset,selectMode(rec, DataMode.RES));
subset = listsUnion(subset,selectMode(rec, DataMode.REF));
subtractTemporalMean(subset);
result = listsUnion(result, subset);
// Update Recording object
replaceAllSeries(rec, result);
} // update
////////////////////////////////////////////////////////////////////
/** Dump summary of this class or object
* @return String representation of this object
*/
public String toString() {
String s = "<<<"+this.getClass().toString()+">>>\n";
s += "Highpass (Hz) = "+ highpassCutoff+"\n";
s += "Allowed range of SD = ["+sdLowerThreshold+","+sdUpperThreshold+"]";
for(String w: warnings)
s += w+"\n";
return s;
} // toString
}