Using the Spike Detection Plugin
The spike detector plugin uses the Spikeprocessing class to estimate the noise level, detect spikes, computes spike times, and extract waveforms. It is also aware of blanking and stimulation parameters. Thus, it automatically excludes the segment that is contaminated with artifacts from the noise level estimation. The spike detector plugin saves the detection results in a Spikes object per channel which is then stored in the SpikeResponse object. The SpikeResponse object is then attached to the Dataframe using getDataframe().setNSweepResponses(spikeResponses) to make the information available to all subsequent plugins along the pipeline.
Adding the detection plugin is straightforward and only requires a small modification of example16.
And this is what the new code looks like:
def example17(): sampleRate = 24414 numChannels = 32 sweepLen = int(sampleRate/2) enableCISimulation = True enableBlanking = True #set up the stimulation parameter object #set stimulation parameters level_dB=5 # in dB in relation to 100 uA clickRate=50 # 300, 900, 1800 ears='left' # other options are 'right' and 'both' Must be set to 'left' or 'right' during simulation duration = 0.01 # This defines the duration of the stimulation numClicks = 1 nloop = 0 reference_Simulation=0.100 # set reference to 100 uA levelRePeak = True # normally we set levels relative to RMS If you want to set them relative to abs max instead, set this to True clickShape_CI_Simulation = np.array([0,1,0,-1,0]) # use a biphasic pulse blankingEndOffsetInSeconds = 0.012 # This offset shifts the end of the blanking. This can be useful if the filter artifacts occur beyond the actual duration of the stimulation. #set up the stimulation parameter object stimulatorModule.soundPlayer=stimulatorModule.pygameSoundHardware() stimulatorModule.soundPlayer.sampleRate = 25000 stim=stimulatorModule.clickTrainObject() stim.clickShape= clickShape_CI_Simulation stim.stimParams['duration (s)']=duration # this parameter controls the duration of the stimulation. stim.stimParams['ABL (dB)']=level_dB #ABL means Average Binaural Level stim.stimParams['clickRate (Hz)']=clickRate stim.stimParams['Nloop']=nloop stim.stimParams['numClicks']=numClicks stim.reference=reference_Simulation stim.clickShape=clickShape_CI_Simulation stim.levelRePeak=levelRePeak stim.ears=ears stim.ready() aDatasource = pipeline.Datasource() aDatasource.setName("Eyphs PushDataSource") sweepSpikeFiltFiltPlugin = pipeline.SweepSpikeFiltFiltPlugin() sweepSpikeFiltFiltPlugin.setName("Eyphs SweepSpikeFiltFiltPlugin") aSpikeSimulationPlugin = pipeline.SpikeSimulationPlugin() aSpikeSimulationPlugin.setName("Eyphs SpikeSimulationPlugin") aSpikeSimulationPlugin.loadSpikeTemplates("FilteredSpikeTemplates.npy") debugSpikeAmplitudes = [0.0001, 0.0001, 0.0001, 0.0001] debugSpikePositions = [0.1, 0.2, 0.3, 0.4] aSpikeSimulationPlugin.setDebug(False) aSpikeSimulationPlugin.setDebugSpikeAmplitudes(debugSpikeAmplitudes) aSpikeSimulationPlugin.setDebugSpikePositions(debugSpikePositions) aSweepInterBlankingPlugin = pipeline.SweepInterBlankingPlugin() aSweepInterBlankingPlugin.setName("Eyphs SweepInterBlankingPlugin") aSweepInterBlankingPlugin.setEndOffsetInSeconds(blankingEndOffsetInSeconds) aSweepInterBlankingPlugin.setEnabled(enableBlanking) aArtifactSimulationPlugin = pipeline.ArtifactSimulationPlugin() aArtifactSimulationPlugin.setName("Eyphs ArtifactSimulationPlugin") aArtifactSimulationPlugin.setEnabled(enableCISimulation) aSpikeSimulationPlugin = pipeline.SpikeSimulationPlugin() aSpikeDetector = pipeline.SpikeDetector() aSpikeDetector.setName("Eyphs SpikeDetector") aSpikeDetector.setStimEndOffsetInSeconds(blankingEndOffsetInSeconds) aDisplay = pipeline.MplSweepDataDisplay(plt) aDatasink = pipeline.Datasink() aDatasink.setName("Eyphs DataSink") #assemble the pipeline aDatasource.setOutput(sweepSpikeFiltFiltPlugin) sweepSpikeFiltFiltPlugin.setOutput(aSpikeSimulationPlugin) aSpikeSimulationPlugin.setOutput(aArtifactSimulationPlugin) aArtifactSimulationPlugin.setOutput(aSweepInterBlankingPlugin) aSweepInterBlankingPlugin.setOutput(aSpikeDetector) aSpikeDetector.setOutput(aDisplay) aDisplay.setOutput(aDatasink) for n in range(100): #generate multichannel data and random background noise sigTupel=tuple(0.000015*np.random.normal(0,1.0, numChannels*sweepLen)) data=RZ2ephys.MCsweep(sigTupel,sweepLen,sampleRate,0) stimObjectCopy = copy.deepcopy(stim) aDataframe = pipeline.Dataframe() aDataframe.setStimObject(stimObjectCopy) aDataframe.setFrameNumber(n) aDataframe.setData(data) aDatasource.addDataframe(aDataframe) aDatasource.run()
Running the code yields a plot that is identical to Fig26. This because we are not yet doing anything with the data.
Right now, the only evidence that the spike detector is active is because we get the message "Hello from: Eyphs SpikeDetector " in the console. It would be really nice to plot the spike times in an informative way. And this is what we are going to do next!