scripts/channelClasses/standard/Standard.java

/////////////////////////////////////////////////////////////////
// Processes data by performing filtering on EEG,EMG,EOG channels
//
// This code is compiled at runtime, but compilation can be tested by:
//    javac -cp build scripts/channelClasses/standard/Standard.java
//    rm scripts/channelClasses/standard/Standard.class 
// and by:
//    java -cp build:lib/derby.jar frontendClasses.CLI -scriptsX
/////////////////////////////////////////////////////////////////
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 performing filtering on selected channels.
 * <p>TODO:
 * Presently EMG is minimally processed.  However it (particularly 
 * Orbicularis Occuli EMG) should be processed to help in quantifying
 * startle responses.  This means: HP filtering with cutoff=30Hz, 
 * taking the absolute value of each sample, smoothing over a 10ms
 * window, and perhaps then subtracting the baseline activity level.  
 */
public class Standard 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 EEG channels */
    float sdLowerThreshold;
    /** SD in uV, to detect noisy EEG 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; in Hz
     * @param sdLowerThreshold SD in uV, to detect flat channels
     * @param sdUpperThreshold SD in uV, to detect noisy channels
     */
    public Standard(Recording rec, float highpassCutoff,
                    float sdLowerThreshold, float sdUpperThreshold) {
        this.rec = rec;
        this.highpassCutoff = highpassCutoff;
        this.sdLowerThreshold = sdLowerThreshold;
        this.sdUpperThreshold = sdUpperThreshold;
        warnings = new ArrayList<String>();
    } // Standard

    ////////////////////////////////////////////////////////////////////
    /** Initialize instance by setting its parameters to default values.
     */
    public Standard(Recording rec) {
        this(rec,0.5f,1.0f,50.0f);
    } // Standard

    ////////////////////////////////////////////////////////////////////
    /** Update recording data by performing channel-oriented operations.
     * <p>Available modes are EEG, EOG, REF, EMG, EDA, RES, ECG, EVE.
     */
    public void update() {
        // Process EEG
        ArrayList<SeriesAnalog> subset = selectMode(rec, DataMode.EEG);
        subtractTemporalMean(subset);
        filterHP(highpassCutoff, 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("Dropping "+s.getPrimaryLabel()+" has SD="+bs.sd+
                              " which is outside allowed range "+
                              sdLowerThreshold+" to "+sdUpperThreshold);
        }
        ArrayList<SeriesAnalog> result = subsetThresholded;

        // Process EMG and EOG
        subset = selectMode(rec, DataMode.EMG);
        subset = listsUnion(subset,selectMode(rec, DataMode.EOG));
        subtractTemporalMean(subset);
        filterHP(highpassCutoff, 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, and filter mains?
        subset = selectMode(rec, DataMode.ECG);
        subset = listsUnion(subset,selectMode(rec, DataMode.RES));
        subset = listsUnion(subset,selectMode(rec, DataMode.REF));
        subtractTemporalMean(subset);
        for(SeriesAnalog s: subset) s.filterMains();
        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+"]\n";
        for(String w: warnings)
            s += w+"\n";
        return s;
    } // toString
}

 


Validate HTML CSS Generated 2011-08-12T10:28:13+1000 Chris Rennie