예제 #1
0
        private const double refractory         = 1; // in seconds

        internal IISZapper(int phaseWidth, double amplitude, int channel, int numPulses, double rate,
                           Task stimDigitalTask, Task stimAnalogTask, DigitalSingleChannelWriter stimDigitalWriter,
                           AnalogMultiChannelWriter stimAnalogWriter, double deviceRefreshRate, NeuroRighter sender)
        {
            const int prePadding  = 100;
            const int postPadding = 100;

            const double offsetVoltage    = 0.0;
            const int    interPhaseLength = 0;

            this.stimDigitalTask   = stimDigitalTask;
            this.stimDigitalWriter = stimDigitalWriter;
            this.stimAnalogTask    = stimAnalogTask;
            this.stimAnalogWriter  = stimAnalogWriter;
            this.channel           = channel - 1;

            sp = new StimPulse(phaseWidth, phaseWidth, amplitude, -amplitude, channel,
                               numPulses, rate, offsetVoltage, interPhaseLength, prePadding, postPadding, true);

            stimAnalogTask.Timing.SamplesPerChannel  = numPulses * sp.analogPulse.GetLength(1);
            stimDigitalTask.Timing.SamplesPerChannel = numPulses * sp.digitalData.GetLength(0);

            totalNumReadsTraining   = (int)(numSecondsTraining / deviceRefreshRate);
            totalNumReadsRefractory = (int)(refractory / deviceRefreshRate);
            numReadsRefractory      = totalNumReadsRefractory;
        }
예제 #2
0
        internal IISZapper(int phaseWidth, double amplitude, int channel, int numPulses, double rate,
            Task stimDigitalTask, Task stimAnalogTask, DigitalSingleChannelWriter stimDigitalWriter,
            AnalogMultiChannelWriter stimAnalogWriter, double deviceRefreshRate, NeuroRighter sender)
        {
            const int prePadding = 100;
            const int postPadding = 100;

            const double offsetVoltage = 0.0;
            const int interPhaseLength = 0;

            this.stimDigitalTask = stimDigitalTask;
            this.stimDigitalWriter = stimDigitalWriter;
            this.stimAnalogTask = stimAnalogTask;
            this.stimAnalogWriter = stimAnalogWriter;
            this.channel = channel - 1;

            sp = new StimPulse(phaseWidth, phaseWidth, amplitude, -amplitude, channel,
                numPulses, rate, offsetVoltage, interPhaseLength, prePadding, postPadding, true);

            stimAnalogTask.Timing.SamplesPerChannel = numPulses * sp.analogPulse.GetLength(1);
            stimDigitalTask.Timing.SamplesPerChannel = numPulses * sp.digitalData.GetLength(0);

            totalNumReadsTraining = (int)(numSecondsTraining / deviceRefreshRate);
            totalNumReadsRefractory = (int)(refractory / deviceRefreshRate);
            numReadsRefractory = totalNumReadsRefractory;
        }
예제 #3
0
        internal void populate(Boolean addTrigger)
        {
            //Compute total length of pulse, in samples
            int totalLength = 0;

            for (int c = 0; c < interpulseIntervals.Count; ++c)
            {
                totalLength += interpulseIntervals[c];          //All interpulse intervals
            }
            totalLength += prePadding[0];                       //The 'off' time of first pulse
            totalLength += postPadding[channel.Count - 1];      //'off' time of last pulse
            totalLength += width1[channel.Count - 1] + width2[channel.Count - 1] +
                           interphaseLength[channel.Count - 1]; //and length of last pulse
            if (addTrigger)                                     //If trigger is being added to end, add that length too
            {
                totalLength += 1 + StimPulse.STIM_SAMPLING_FREQ * WATCH_TIME / 1000;
            }

            //This experiment REQUIRES triggers, therefore MUST use 32-bit ports!!!
            int numRows = 4;

            if (Properties.Settings.Default.StimPortBandwidth != 32)
            {
                System.Windows.Forms.MessageBox.Show("Must use 32-bit port for this experiment, since triggers must be used.", "Port-size error");
                return;
            }

            //Set aside space for analog pulse
            analogPulse = new double[numRows, totalLength]; //Only make one pulse of train, the padding zeros will ensure proper rate when sampling is regenerative
            digitalData = new UInt32[totalLength + 2 * (StimPulse.NUM_SAMPLES_BLANKING + 2)];

            //Bookkeeping variable for constructing pulse
            int offset = 0;

            for (int c = 0; c < channel.Count; ++c) //for each pulse
            {
                //Setup voltage waveform, pos. then neg.
                int size = Convert.ToInt32((((double)width1[c] + (double)width2[c]) / 1000000.0) * StimPulse.STIM_SAMPLING_FREQ + prePadding[c] + postPadding[c] + interphaseLength[c]); //Num. pts. in pulse
                //What was that doing? Convert width to seconds, divide by sample duration, mult. by
                //two since the pulse is biphasic, add padding to both sides

                #region AnalogPulseCreation
                //v1 and v2 encode channel number
                double v1 = Math.Ceiling((double)channel[c] / 8.0);
                double v2 = (double)((channel[c] - 1) % 8) + 1.0;

                for (int j = 0; j < prePadding[c]; ++j)
                {
                    analogPulse[2, j + offset] = offsetVoltage[c];
                }
                for (int j = prePadding[c]; j < prePadding[c] + Convert.ToInt32(((double)width1[c] / 1000000.0) * StimPulse.STIM_SAMPLING_FREQ); ++j)
                {
                    analogPulse[2, j + offset] = amp1[c] + offsetVoltage[c];
                }
                for (int j = prePadding[c] + Convert.ToInt32(((double)width1[c] / 1000000.0) * StimPulse.STIM_SAMPLING_FREQ); j < prePadding[c] + Convert.ToInt32(((double)width1[c] / 1000000.0) * StimPulse.STIM_SAMPLING_FREQ) + interphaseLength[c]; ++j)
                {
                    analogPulse[2, j + offset] = offsetVoltage[c];
                }
                for (int j = prePadding[c] + Convert.ToInt32(((double)width1[c] / 1000000.0) * StimPulse.STIM_SAMPLING_FREQ) + interphaseLength[c]; j < size - postPadding[c]; ++j)
                {
                    analogPulse[2, j + offset] = amp2[c] + offsetVoltage[c];
                }
                for (int j = size - postPadding[c]; j < size; ++j)
                {
                    analogPulse[2, j + offset] = offsetVoltage[c];
                }
                for (int j = prePadding[c]; j < 20 + prePadding[c]; ++j)
                {
                    analogPulse[3, j + offset] = v1;
                }
                for (int j = 20 + prePadding[c]; j < 40 + prePadding[c]; ++j)
                {
                    analogPulse[3, j + offset] = v2;
                }
                for (int j = 40 + prePadding[c]; j < 60 + prePadding[c]; ++j)
                {
                    analogPulse[3, j + offset] = amp1[c];
                }
                for (int j = 60 + prePadding[c]; j < 80 + prePadding[c]; ++j)
                {
                    analogPulse[3, j + offset] = (double)(width1[c]) / 100.0;
                }

                //Add trigger, if applicable
                if (addTrigger && c == channel.Count - 1)
                {
                    for (int j = size; j < StimPulse.STIM_SAMPLING_FREQ * WATCH_TIME / 1000; ++j)
                    {
                        analogPulse[0, j + offset] = 4.0; //4 Volts, TTL-compatible
                    }
                    analogPulse[0, analogPulse.GetLength(1) - 1] = 0.0;
                }
                #endregion

                #region DigitalPulseCreation
                //Get data bits lined up to control MUXes
                UInt32 temp;
                if (c == 0)
                {
                    temp = StimPulse.channel2MUX((double)channel[c]);
                }
                else
                {
                    temp = StimPulse.channel2MUX((double)channel[c], true, false); //select channel without start trigger for AO
                }
                UInt32 temp_noEn      = StimPulse.channel2MUX_noEN((double)channel[c]);
                UInt32 temp_blankOnly = Convert.ToUInt32(Math.Pow(2, (Properties.Settings.Default.StimPortBandwidth == 32 ? BLANKING_BIT_32bitPort : BLANKING_BIT_8bitPort)));

                for (int j = 1; j <= StimPulse.NUM_SAMPLES_BLANKING; ++j)
                {
                    digitalData[j + offset] = temp_blankOnly;
                }
                digitalData[StimPulse.NUM_SAMPLES_BLANKING + 1 + offset] = temp_noEn;
                for (int j = StimPulse.NUM_SAMPLES_BLANKING + 2; j < size + StimPulse.NUM_SAMPLES_BLANKING + 2; ++j)
                {
                    digitalData[j + offset] = temp;
                }
                digitalData[size + StimPulse.NUM_SAMPLES_BLANKING + 2 + offset] = temp_noEn;
                for (int j = size + StimPulse.NUM_SAMPLES_BLANKING + 3; j < size + 2 * StimPulse.NUM_SAMPLES_BLANKING + 3; ++j)
                {
                    digitalData[j + offset] = temp_blankOnly;
                }
                #endregion

                //Update offset to account for interphase length
                if (c < interpulseIntervals.Count)
                {
                    offset += interpulseIntervals[c]; //this has one less member than all the stimpulses
                }
                //NB: this form of offset changing assumes homogeneous prepaddings
            }
        }
예제 #4
0
        private void bw_stim_DoWork(object sender, DoWorkEventArgs e)
        {
            //Get pulse arguments
            double[] stim_params = (double[])e.Argument;

            //Select between uni- and biphasic pulses
            int phase2Width = (int)stim_params[0];
            if (radioButton_OnDemandUniphasic.Checked)
                phase2Width = 0;

            if (stim_params[3] * 1000 / stim_params[4] < 500)
            {
                //Create pulse
                StimPulse sp = new StimPulse((int)stim_params[0], phase2Width, stim_params[1], -stim_params[1],
                    (int)stim_params[2], (int)stim_params[3], (int)stim_params[4], (double)stim_params[5], (int)stim_params[6], 10, 10, true);
                if (stim_params[3] == 1)
                {
                    stimPulseTask.Timing.SamplesPerChannel = sp.analogPulse.GetLength(1);
                    stimDigitalTask.Timing.SamplesPerChannel = sp.digitalData.Length;
                }

                //Write
                stimPulseWriter.WriteMultiSample(true, sp.analogPulse);
                if (Properties.Settings.Default.StimPortBandwidth == 32)
                    stimDigitalWriter.WriteMultiSamplePort(true, sp.digitalData);
                else if (Properties.Settings.Default.StimPortBandwidth == 8)
                    stimDigitalWriter.WriteMultiSamplePort(true, StimPulse.convertTo8Bit(sp.digitalData));

                DateTime stimStartTime = DateTime.Now;
                stimStopTime = stimStartTime.AddMilliseconds(((double)stim_params[3] * 1000.0) / (double)stim_params[4]);
                //timer.Enabled = true;
                stimPulseTask.WaitUntilDone();
                stimDigitalTask.WaitUntilDone();
                stimPulseTask.Stop();
                stimDigitalTask.Stop();
            }
            else
            {
                //Make a single stim pulse, but with the correct number of zeros to insure proper rate
                //when task is regenerative
                StimPulse sp = new StimPulse((int)stim_params[0], phase2Width, stim_params[1], -stim_params[1], (int)stim_params[2], 1, (int)stim_params[4], (double)stim_params[5], (int)stim_params[6], 10, 10, true);
                if (stim_params[3] == 1)
                {
                    stimPulseTask.Timing.SamplesPerChannel = sp.analogPulse.GetLength(1);
                    stimDigitalTask.Timing.SamplesPerChannel = sp.digitalData.Length;
                }
                stimPulseWriter.WriteMultiSample(true, sp.analogPulse);
                //stimDigitalWriter.WriteWaveform(true, sp.digitalPulse);
                if (Properties.Settings.Default.StimPortBandwidth == 32)
                    stimDigitalWriter.WriteMultiSamplePort(true, sp.digitalData);
                else if (Properties.Settings.Default.StimPortBandwidth == 8)
                    stimDigitalWriter.WriteMultiSamplePort(true, StimPulse.convertTo8Bit(sp.digitalData));
                DateTime stimStartTime = DateTime.Now;
                stimStopTime = stimStartTime.AddMilliseconds(((double)stim_params[3] * 1000.0) / (double)stim_params[4]);
                stimTimer = new System.Threading.Timer(stim_timer_tick, null, 100, 100);
            }
        }
예제 #5
0
        private void bw_openLoop_DoWork(object sender, DoWorkEventArgs e)
        {
            //DEBUGGING
            stimPulseTask.Control(TaskAction.Verify);
            stimDigitalTask.Control(TaskAction.Verify);

            stim_params sp = (stim_params)e.Argument;

            //Create randomized list of channels
            int numStimChannels = sp.stimChannelList.GetLength(0);
            ArrayList chListSorted = new ArrayList(numStimChannels);
            int[] chListRand = new int[numStimChannels];
            for (int i = 0; i < numStimChannels; ++i)
                chListSorted.Add(sp.stimChannelList[i]);
            Random r = new Random();
            for (int i = 0; i < numStimChannels; ++i)
            {
                int j = r.Next(chListSorted.Count);
                chListRand[i] = (int)chListSorted[j];
                chListSorted.RemoveAt(j);
            }

            StimPulse spulse = new StimPulse(sp.width1, sp.width2, sp.v1, sp.v2, chListRand, sp.rate, sp.offsetVoltage, sp.interphaseLength, sp.prephaseLength, sp.postphaseLength);
            stimPulseWriter.WriteMultiSample(true, spulse.analogPulse);
            if (Properties.Settings.Default.StimPortBandwidth == 32)
                stimDigitalWriter.WriteMultiSamplePort(true, spulse.digitalData);
            else if (Properties.Settings.Default.StimPortBandwidth == 8)
                stimDigitalWriter.WriteMultiSamplePort(true, StimPulse.convertTo8Bit(spulse.digitalData));
        }
예제 #6
0
        private void bw_genExpt_DoWork(object sender, DoWorkEventArgs e)
        {
            //NB: Within new threads, you shouldn't reference any of the main forms controls
            //expt_Params ep = (expt_Params)e.Argument;
            List<Object> exptParams = (List<Object>)e.Argument;  //exptParams.Add(channels, numTrials, voltages, pulsesPerTrain, pulseWidths, trainRate);

            int[] channels = (int[])exptParams[0];
            int numTrials = (int)exptParams[1];
            double[] voltages = (double[])exptParams[2];
            int[] pulsesPerTrain = (int[])exptParams[3];
            int[] pulseWidths = (int[])exptParams[4];
            int trainRate = (int)exptParams[5];

            stimList = new ArrayList(channels.Length * voltages.Length * numTrials * pulseWidths.Length * pulsesPerTrain.Length);
            for (int i = 0; i < channels.Length; ++i)
            {
                for (int v = 0; v < voltages.Length; ++v)
                {
                    for (int ppt = 0; ppt < pulsesPerTrain.Length; ++ppt)
                    {
                        for (int pw = 0; pw < pulseWidths.Length; ++pw)
                        {
                            for (int j = 0; j < numTrials; ++j) //Repeat each test 5x
                            {
                                StimPulse sp = new StimPulse(pulseWidths[pw], pulseWidths[pw], voltages[v], -voltages[v], channels[i], pulsesPerTrain[ppt], trainRate, 0.0, 0, 100, 100, false);
                                stimList.Add(sp);
                            }
                        }
                    }
                }
            }
        }