예제 #1
0
        internal override void read(short[,] data, int numChannelsData, int startChannelData, int length)
        {
            unsafe
            {
                fixed(short *pdata = &data[0, 0], pbuffer = &_buffer[0, 0])
                {
                    for (int c = startChannelData; c < startChannelData + numChannelsData; ++c)
                    {
                        int baseOfDimData   = (c - startChannelData) * length; //BaseOfDim is in ref to input data, which has no channel offset
                        int baseOfDimBuffer = (MEAChannelMappings.channel2LinearCR(c) - 1) * BUFFER_LENGTH;

                        //Check to see if we'll loop back to front of buffer here, rather than wasting an if statement in the loop
                        if (_currentLocationRead[c] + length < BUFFER_LENGTH)
                        {
                            //Check for buffer overrun
                            if (_currentLocationWrite[c] > _currentLocationRead[c])
                            {
                                if (_currentLocationWrite[c] - _currentLocationRead[c] < length)
                                {
                                    System.Windows.Forms.MessageBox.Show("Buffer Overrun");
                                }
                            }

                            //We can copy blithely, without worry of looping back around
                            for (int i = 0; i < length; ++i)
                            {
                                pbuffer[baseOfDimBuffer + _currentLocationRead[c]++] = pdata[baseOfDimData + i];
                                //if (_currentLocationRead[c] != _currentLocationWrite[c]) { /* do nothing */}
                                //else
                                //    System.Windows.Forms.MessageBox.Show("Buffer Overrun");
                            }
                        }
                        else
                        {
                            //Check for buffer overruns
                            if (_currentLocationWrite[c] > _currentLocationRead[c])
                            {
                                //Since we're guaranteed to go to end of buffer, if write head is higher, we will overrun
                                System.Windows.Forms.MessageBox.Show("Buffer Overrun");
                            }
                            int firstDistance = BUFFER_LENGTH - _currentLocationRead[c];
                            for (int i = 0; i < firstDistance; ++i)
                            {
                                pbuffer[baseOfDimBuffer + _currentLocationRead[c]++] = pdata[baseOfDimData + i];
                            }
                            _currentLocationRead[c] = 0; //Reset read head

                            if (_currentLocationWrite[c] < length - firstDistance)
                            {
                                System.Windows.Forms.MessageBox.Show("Buffer Overrun");
                            }
                            for (int i = firstDistance; i < length; ++i)
                            {
                                pbuffer[baseOfDimBuffer + _currentLocationRead[c]++] = pdata[baseOfDimData + i];
                            }


                            //for (int i = 0; i < length; ++i)
                            //{
                            //    pbuffer[baseOfDimBuffer + _currentLocationRead[c]] = pdata[baseOfDimData + i];
                            //    if (++_currentLocationRead[c] < BUFFER_LENGTH) { /* do nothing */ }
                            //    else { _currentLocationRead[c] = 0; }
                            //    if (_currentLocationRead[c] != _currentLocationWrite[c]) { /* do nothing */}
                            //    else
                            //        System.Windows.Forms.MessageBox.Show("Buffer Overrun");
                            //}
                        }
                    }
                }
            }

            //for (int c = 0; c < numChannelsData; ++c)
            //{
            //    //Check to see if we'll loop back to front of buffer here, rather than wasting an if statement in the loop
            //    if (_currentLocationRead[startChannelData + c] + length < BUFFER_LENGTH)
            //    {
            //        //We can copy blithely, without worry of looping back around
            //        for (int i = 0; i < length; ++i)
            //        {
            //            _buffer[startChannelData + c][_currentLocationRead[startChannelData + c]++] = data[c, i];
            //            if (_currentLocationRead[c] != _currentLocationWrite[c]) { /* do nothing */}
            //            else
            //                System.Windows.Forms.MessageBox.Show("Buffer Overrun");
            //        }
            //    }
            //    else
            //    {
            //        for (int i = 0; i < length; ++i)
            //        {
            //            _buffer[startChannelData + c][_currentLocationRead[startChannelData + c]] = data[c, i];
            //            if (++_currentLocationRead[startChannelData + c] < BUFFER_LENGTH) { /* do nothing */ }
            //            else { _currentLocationRead[startChannelData + c] = 0; }
            //            if (_currentLocationRead[c] != _currentLocationWrite[c]) { /* do nothing */}
            //            else
            //                System.Windows.Forms.MessageBox.Show("Buffer Overrun");
            //        }
            //    }
            //}
        }
예제 #2
0
        //DateTime spkClk;

        private void bwSpikes_DoWork(object sender, DoWorkEventArgs e)
        {
            //spkClk = DateTime.Now;
            Object[] state      = (Object[])e.Argument;
            int      taskNumber = (int)state[0];

            //Debugger.Write(taskNumber.ToString() + ": dowork begin");
            trackingProc[taskNumber]++;
            //double[][] filtSpikeData;
            //Copy data into a new buffer
            for (int i = 0; i < numChannelsPerDev; ++i)
            {
                spikeData[taskNumber][i].GetRawData(0, spikeBufferLength, filtSpikeData[taskNumber * numChannelsPerDev + i], 0);
            }
            //Debugger.Write(taskNumber.ToString() + ": raw data read");

            // Increment the number of times the DAQ has been polled for spike data
            ++(numSpikeReads[taskNumber]);
            ulong startTime = (ulong)(numSpikeReads[taskNumber] - 1) * (ulong)spikeBufferLength; //Used to mark spike time for *.spk file


            //Account for Pre-amp gain
            double ampdec = (1 / Properties.Settings.Default.PreAmpGain);

            for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
            {
                for (int j = 0; j < spikeBufferLength; ++j)
                {
                    filtSpikeData[i][j] = ampdec * filtSpikeData[i][j];
                }
            }

            // Send filtSpikeData to datSrv
            if (Properties.Settings.Default.useRawDataBuffer)
            {
                datSrv.RawElectrodeSrv.WriteToBuffer(filtSpikeData, taskNumber, numChannelsPerDev);
            }

            //  Debugger.Write(taskNumber.ToString() + ": raw data sent to rawsrv");
            #region Write RAW data
            //Write data to file

            if (switch_record.Value && recordingSettings.recordRaw && spikeTask != null)
            {
                lock (recordingSettings.rawOut)
                {
                    for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
                    {
                        // Temporary storage for converte data
                        Int16[] tempBuff;

                        // Convert raw data to 16-bit int
                        tempBuff = neuralDataScaler.ConvertSoftRawRowToInt16(ref filtSpikeData[i]);

                        // Send data to file writer
                        for (int j = 0; j < spikeBufferLength; ++j)
                        {
                            recordingSettings.rawOut.read(tempBuff[j], i);
                        }
                    }
                }
            }

            #endregion

            // Debugger.Write(taskNumber.ToString() + ": raw written");

            #region Raw Spike Detection

            if (recordingSettings.recordRawSpike)
            {
                lock (rawSpikeObj)
                {
                    //newWaveforms: 0 based indexing for internal NR processing (datSrv, plotData)
                    EventBuffer <SpikeEvent> newWaveformsRaw = new EventBuffer <SpikeEvent>(Properties.Settings.Default.RawSampleFrequency);
                    switch (spikeDet.detectorType)
                    {
                    case 0:
                        for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
                        {
                            newWaveformsRaw.Buffer.AddRange(spikeDet.spikeDetectorRaw.DetectSpikes(filtSpikeData[i], i, startTime));
                        }
                        break;

                    case 1:
                        for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
                        {
                            newWaveformsRaw.Buffer.AddRange(spikeDet.spikeDetectorRaw.DetectSpikesSimple(filtSpikeData[i], i, startTime));
                        }
                        break;
                    }

                    //Extract waveforms, convert to 1 based indexing
                    EventBuffer <SpikeEvent> toRawsrvRaw = new EventBuffer <SpikeEvent>(spikeSamplingRate);
                    if (Properties.Settings.Default.ChannelMapping != "invitro") //|| numChannels != 64) //check this first, so we don't have to check it for each spike
                    {
                        for (int j = 0; j < newWaveformsRaw.Buffer.Count; ++j)   //For each threshold crossing
                        {
                            SpikeEvent tmp = (SpikeEvent)newWaveformsRaw.Buffer[j].DeepClone();
                            tmp.Channel = InVivoChannelMappings.Channel2LinearCR(tmp.Channel);
                            toRawsrvRaw.Buffer.Add(tmp);
                        }
                    }
                    else //in vitro mappings
                    {
                        for (int j = 0; j < newWaveformsRaw.Buffer.Count; ++j) //For each threshold crossing
                        {
                            SpikeEvent tmp = (SpikeEvent)newWaveformsRaw.Buffer[j].DeepClone();
                            tmp.Channel = MEAChannelMappings.channel2LinearCR(tmp.Channel);
                            toRawsrvRaw.Buffer.Add(tmp);
                        }
                    }

                    // Record spike waveforms
                    if (switch_record.Value)
                    {
                        for (int j = 0; j < newWaveformsRaw.Buffer.Count; ++j) //For each threshold crossing
                        {
                            SpikeEvent tmp = toRawsrvRaw.Buffer[j];
                            lock (recordingSettings.spkOutRaw) //Lock so another NI card doesn't try writing at the same time
                            {
                                recordingSettings.spkOutRaw.WriteSpikeToFile((short)tmp.Channel, (int)tmp.SampleIndex,
                                                                             tmp.Threshold, tmp.Waveform, tmp.Unit);
                            }
                        }
                    }
                }
            }

            #endregion

            // Debugger.Write(taskNumber.ToString() + ": raw spikes filtered");

            #region LFP_Filtering
            //Filter for LFPs
            if (!Properties.Settings.Default.SeparateLFPBoard && Properties.Settings.Default.UseLFPs)
            {
                //Copy to new array
                for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
                {
                    for (int j = 0; j < spikeBufferLength; ++j)
                    {
                        filtLFPData[i][j] = filtSpikeData[i][j];
                    }
                }

                #region ArtiFilt (interpolation filtering)
                if (checkBox_artiFilt.Checked)
                {
                    artiFilt.filter(ref filtLFPData, stimIndices, taskNumber * numChannelsPerDev, numChannelsPerDev, numStimReads[taskNumber] - 1);
                }
                #endregion

                if (checkBox_LFPsFilter.Checked)
                {
                    for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
                    {
                        lfpFilter[i].filterData(filtLFPData[i]);
                    }
                }

                //Downsample for LFPs
                double dsFactor = (double)spikeSamplingRate / (double)lfpSamplingRate;
                if (dsFactor % 1 == 0) //If it's an integer
                {
                    for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
                    {
                        for (int j = 0; j < lfpBufferLength; ++j)
                        {
                            finalLFPData[i][j] = filtLFPData[i][(int)(dsFactor * j)];
                        }
                    }
                }
                else
                {
                    for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
                    {
                        for (int j = 0; j < lfpBufferLength; ++j)
                        {
                            finalLFPData[i][j] = filtLFPData[i][(int)(Math.Round(dsFactor * j))];
                        }
                    }
                }

                //Do IISZapper stuff
                if (IISDetected != null)
                {
                    IISDetected(this, finalLFPData, numSpikeReads[taskNumber]);
                }

                // Send to datSrv
                if (Properties.Settings.Default.useLFPDataBuffer)
                {
                    datSrv.LFPSrv.WriteToBuffer(finalLFPData, 0, numChannels);
                }

                #region WriteLFPFile
                if (switch_record.Value && recordingSettings.recordLFP && spikeTask != null) //Convert to 16-bit ints, then write to file
                {
                    for (int i = taskNumber * numChannelsPerDev; i < (taskNumber + 1) * numChannelsPerDev; ++i)
                    {
                        // Temporary storage for converte data
                        Int16[] tempLFPBuff;

                        // Convert raw data to 16-bit int
                        tempLFPBuff = neuralDataScaler.ConvertSoftRawRowToInt16(ref finalLFPData[i]);

                        // Send data to file writer
                        for (int j = 0; j < lfpBufferLength; ++j)
                        {
                            recordingSettings.lfpOut.read((short)tempLFPBuff[j], i);
                        }
                    }
                }
                #endregion

                //Digital ref LFP signals
                if (!checkBox_digRefLFPs.Checked) /* Do nothing, since prefetch makes if faster than else */ } {
예제 #3
0
 internal override void read(short data, int channel)
 {
     _buffer[MEAChannelMappings.channel2LinearCR(channel) - 1, _currentLocationRead[channel]] = data;
     if (++_currentLocationRead[channel] < BUFFER_LENGTH) /* do nothing */ } {