scripts/channelClasses/mock_gng/Simple.java

/////////////////////////////////////////////////////////////////
// This script generates (somewhat) realistic GNG data.
//
// Run with (for example)
//    java -cp build:lib/derby.jar -Dserver.cache.enable=false -Djava.library.path=c frontendClasses/CLI -scriptChannel mock_gng/Simple -reviewSeries -paradigm gng -eventSelection "Stim='Go' or Stim='NoGo'" -binH stim -binZ site -display "TiledStack()" -v
/////////////////////////////////////////////////////////////////
package mock_gng;

import java.io.*;
import java.util.*;

import epochClasses.*;
import generalClasses.*;
import recordingClasses.Recording;
import seriesClasses.*;
import seriesClasses.seriesGeneration.Erlang;
import channelClasses.ChannelScript;
import static channelClasses.Channel.*;

/////////////////////////////////////////////////////////////////
/** This script generates (somewhat) realistic GNG data.
 * The EEG contains 126 Go, and 42 NoGo epochs.
 *
 * <p>The intended effect is:
 * <ol><li>Demonstrate event generation</li>
 * </ol>
 */
public class Simple extends ChannelScript
{
    /** Recording instance to be operated on */
    Recording rec = null;
    /** Time series */
    ArrayList<SeriesAnalog> list = new ArrayList<SeriesAnalog>();
    /** Events.  May be left empty */
    ArrayList<Event> ev = new ArrayList<Event>();

    ////////////////////////////////////////////////////////////////////
    /** Initialize instance by setting its parameters to default values.
     */
    public Simple(Recording rec) {
        this.rec = rec;
    } // Simple



    ////////////////////////////////////////////////////////////////////
    /** Update recording data by performing channel-oriented operations.
     */
    public void update() {
        // Template - used to encapsulate all sampling characteristics
        float x0 = 0.0f;             // in seconds: times start at x0
        float xDelta = 0.004f;       // in seconds: times increment by xDelta
        float duration = 253.0f;     // in seconds: times end at x0+duration
        int nIndexes = Math.round(duration/xDelta);
        SeriesAnalog template = new SeriesAnalog(new SiteSet(), // sites
                                                 x0,            // x0
                                                 xDelta,        // xDelta
                                                 new Units(Unit.s),  // xUnits
                                                 nIndexes,      // # samples
                                                 new Units(Unit.uV), // yUnits
                                                 DataMode.EEG); // DataMode

        // Channels 
        String[] labels = {"Fz", "C3", "Cz", "C4", "Pz", "ECG"};

        // Standard ERP; update event list also
        SeriesAnalog erp = getEegWithErps(template);

        // Generate time series
        for(int site=0; site<labels.length; site++) {    
            // What modality?
            DataMode mode = DataMode.EEG;
            if(labels[site].matches("[eE][oO][gG].*"))       mode=DataMode.EOG;
            else if(labels[site].matches("[eE][cCkK][gG].*"))mode=DataMode.ECG;

            // New series
            SeriesAnalog sum = null;

            if(mode.equals(DataMode.EEG)) {
                // Create sum of noise and ERPs
                float t0 = 0.09f;
                sum = getEegWithAlpha(template, t0);
                sum.add(erp);
            } else if(mode.equals(DataMode.ECG)) {
                sum = getEcg(template);
            }
            sum.setSites(new SiteSet(new Site(labels[site])));
            sum.setMode(mode);
    
            // Append sum to result
            list.add(sum);
        }

        // Add synthetic time series to the currently empty Recording
        replaceAllSeries(rec, list);
        replaceAllEvents(rec, ev);
    } // update


    ////////////////////////////////////////////////////////////////////
    /** Dump summary of this class or object
     * @return String representation of this object
     */
    public String toString() {
        String s = "<<<"+this.getClass().toString()+">>>\n";
        return s;
    } // toString


    ////////////////////////////////////////////////////////////////////
    /** Generate pseudo EEG containing ERPs.  Also update the event list, ev.
     * The event labels must match those in SeriesBinary.buildXXX_NS5Event().
     * The ERP is about +15 uV in amplitude.
     */
    private SeriesAnalog getEegWithErps(SeriesAnalog template) {
        float erpDuration = 1.0f;
        float xDelta = template.getXDelta(); // sampling interval, in seconds
        int nIndexes = Math.round(erpDuration/xDelta);
        if((nIndexes&1)==0) nIndexes++;
        float x0 = -(nIndexes-1)*xDelta/2;  // so wavelet is centred on 0 secs
        SeriesAnalog wavelet = new SeriesAnalog(new SiteSet(), // sites
                                                x0,            // x0
                                                xDelta,        // xDelta
                                                new Units(Unit.s),  // xUnits
                                                nIndexes,      // # samples
                                                new Units(),   // yUnits
                                                DataMode.EEG); // DataMode
        float lnorm = -1.0f;
        SeriesAnalog erp =SeriesAnalog.getModelledErpTimeseries(wavelet,lnorm);

        // Generate multiple impulses, y[], with modulated areas, plus events
        String[] stim = {
            "Go", "Go", "Go", "Go", "Go", "Go",                //   0
            "Go", "Go", "Go", "Go", "Go", "Go",                //   6
            "Go", "Go", "Go", "Go", "Go", "Go",                //  12
            "NoGo", "NoGo", "NoGo", "NoGo", "NoGo", "NoGo",    //  18
            "Go", "Go", "Go", "Go", "Go", "Go",                //  24
            "Go", "Go", "Go", "Go", "Go", "Go",                //  30
            "NoGo", "NoGo", "NoGo", "NoGo", "NoGo", "NoGo",    //  36
            "Go", "Go", "Go", "Go", "Go", "Go",                //  42
            "Go", "Go", "Go", "Go", "Go", "Go",                //  48
            "NoGo", "NoGo", "NoGo", "NoGo", "NoGo", "NoGo",    //  54
            "Go", "Go", "Go", "Go", "Go", "Go",                //  60
            "Go", "Go", "Go", "Go", "Go", "Go",                //  66
            "NoGo", "NoGo", "NoGo", "NoGo", "NoGo", "NoGo",    //  72
            "Go", "Go", "Go", "Go", "Go", "Go",                //  78
            "Go", "Go", "Go", "Go", "Go", "Go",                //  84
            "Go", "Go", "Go", "Go", "Go", "Go",                //  90
            "Go", "Go", "Go", "Go", "Go", "Go",                //  96
            "Go", "Go", "Go", "Go", "Go", "Go",                // 102
            "NoGo", "NoGo", "NoGo", "NoGo", "NoGo", "NoGo",    // 108
            "Go", "Go", "Go", "Go", "Go", "Go",                // 114
            "Go", "Go", "Go", "Go", "Go", "Go",                // 120
            "Go", "Go", "Go", "Go", "Go", "Go",                // 126
            "NoGo", "NoGo", "NoGo", "NoGo", "NoGo", "NoGo",    // 132
            "Go", "Go", "Go", "Go", "Go", "Go",                // 138
            "Go", "Go", "Go", "Go", "Go", "Go",                // 144
            "Go", "Go", "Go", "Go", "Go", "Go",                // 150
            "Go", "Go", "Go", "Go", "Go", "Go",                // 156
            "NoGo", "NoGo", "NoGo", "NoGo", "NoGo", "NoGo"     // 162
        };
        int nEvents = stim.length;
        float[] y = new float[template.getNIndexes()];
        double meanRT = 0.32;                   // mean RT in seconds
        Erlang ran = new Erlang(meanRT/4, 4, 0);// 'mu' or 'scale' = mean/4,k=4
        // SD of distrib = sqrt(k)*'mu'
        for(int i=0; i<nEvents; i++) {
            float time = template.getFirstX() + 1.050f + i*1.500f;
            String label = null;
            float scale = 0;
            double rt = 0;
            if(stim[i].equalsIgnoreCase("Go")) {
                label = "Go";
                scale = 1.0f;
                rt = ran.gen();
            } else {
                label = "NoGo";
                scale = 1.0f;
                rt = 0;
            }
            int offset = template.getIndex(time);
            if(offset>=0 && offset<template.getNIndexes())
                y[offset] = scale;
            ev.add(new Event(time, 0, 0.500, label));
            if(rt>0.2 && rt<1.0)
                ev.add(new Event(time+rt, "Butt:L"));
        }

        SeriesAnalog s = new SeriesAnalog(template,y);
        return s.convolveAsym(erp);
    } // getEegWithErps

    ////////////////////////////////////////////////////////////////////
    /** Generate pseudo EEG containing alpha
     */
    private SeriesAnalog getEegWithAlpha(SeriesAnalog template, float t0) {
        float lnorm = 2.5f;
        return SeriesAnalog.getModelledEegTimeseries(template,t0,lnorm);
    } // getEegWithAlpha


    ////////////////////////////////////////////////////////////////////
    /** Generate pseudo ECG.
     * The wavelet is a standard ERP, but deliberately truncated to
     * make it more spike-like.
     * The ECG will have R-R intervals of 0.80+var seconds, where 'var'
     * has a gamma distribution, with mean equal to 0.1 seconds.
     */
    private SeriesAnalog getEcg(SeriesAnalog template) {
        float ecgDuration = 0.2f;
        float xDelta = template.getXDelta(); // sampling interval, in seconds
        int nIndexes = Math.round(ecgDuration/xDelta);
        if((nIndexes&1)==0) nIndexes++;
        float x0 = -(nIndexes-1)*xDelta/2;  // so wavelet is centred on 0 secs
        SeriesAnalog wavelet = new SeriesAnalog(new SiteSet(), // sites
                                                x0,            // x0
                                                xDelta,        // xDelta
                                                new Units(Unit.s),  // xUnits
                                                nIndexes,      // # samples
                                                new Units(),   // yUnits
                                                DataMode.ECG); // DataMode
        float lnorm = -5.0f;
        SeriesAnalog erp =SeriesAnalog.getModelledErpTimeseries(wavelet,lnorm);

        Erlang ran = new Erlang(0.1/5, 5, 0);  // scale = mean/5
        ArrayList<Float> timesList = new ArrayList<Float>();
        float t = template.getFirstX()+0.3f;  // time of first ECG event
        float duration = template.getXDelta()*template.getNIndexes();
        while(t<duration) {
            timesList.add(new Float(t));
            t += (float)(0.8+ran.gen());
        }
        float[] times = new float[timesList.size()];
        for(int i=0; i<timesList.size(); i++) times[i] = timesList.get(i);
    
        return SeriesAnalog.getImpulseTimeseries(template,times)
            .mul(xDelta).convolveAsym(erp);
    } // getEcg

}    

 


Validate HTML CSS Generated 2009-09-06T16:13:22+1000 Chris Rennie