Skip to content

PSQ_SearchForSpikes: Make it faster #2687

@t-b

Description

@t-b

From #2653 (comment):

Total time: 170.379, Time in Function code: 74.9018 (44%)
Top function percentages:
Function MIES_AnalysisFunctions_PatchSeq.ipf PSQ_SearchForSpikes: 44%
Function MIES_Cache.ipf CA_GetCacheIndex: 42%

Annotated Top Functions:

*******************************************************************************************
Function: MIES_AnalysisFunctions_PatchSeq.ipf PSQ_SearchForSpikes; Percent total 44%
*******************************************************************************************
[00]*         	|static Function/WAVE PSQ_SearchForSpikes(string device, variable type, WAVE sweepWave, variable headstage, variable offset, variable level, [variable searchEnd, variable numberOfSpikesReq, WAVE spikePositions, variable &numberOfSpikesFound])
[00]          	|
[00]          	|	variable first, last, overrideValue, rangeSearchLevel
[00]          	|	variable minVal, maxVal, numSpikesFoundOverride
[00]          	|	string msg
[00]          	|
[00]*         	|	WAVE spikeDetection = LBN_GetNumericWave()
[00]*         	|	spikeDetection = ((p == headstage) ? 0 : NaN)
[00]          	|
[00]*         	|	WAVE config = AFH_GetConfigWave(device, sweepWave)
[00]          	|
[00]*         	|	if(ParamIsDefault(searchEnd))
[00]*         	|		searchEnd = Inf
[00]*         	|	endif
[00]          	|
[00]*         	|	if(ParamIsDefault(numberOfSpikesReq))
[00]          	|		numberOfSpikesReq = 1
[00]          	|	else
[00]*         	|		ASSERT(numberOfSpikesReq > 0, "Invalid numberOfSpikesFound")
[00]*         	|		numberOfSpikesReq = trunc(numberOfSpikesReq)
[00]*         	|	endif
[00]          	|
[00]*         	|	if(!ParamIsDefault(numberOfSpikesFound))
[00]          	|		numberOfSpikesFound = NaN
[00]*         	|	endif
[00]          	|
[00]*         	|	sprintf msg, "Type %d, headstage %d, offset %g, numberOfSpikesReq %d", type, headstage, offset, numberOfSpikesReq
[00]*         	|	DEBUGPRINT(msg)
[00]          	|
[00]*         	|	if(type == PSQ_CHIRP || type == PSQ_TRUE_REST_VM)
[00]          	|		first = offset
[00]          	|		last  = searchEnd
[00]          	|	else
[00]          	|		// search pulse in DA and use the pulse as search region
[00]*         	|		WAVE singleDA = AFH_ExtractOneDimDataFromSweep(device, sweepWave, headstage, XOP_CHANNEL_TYPE_DAC, config = config)
[01]*         	|		[minVal, maxVal] = WaveMinAndMax(singleDA, offset, Inf)
[00]          	|
[00]*         	|		if(minVal == 0 && maxVal == 0)
[00]          	|			if(type == PSQ_SQUARE_PULSE)
[00]          	|				first = 0
[00]          	|				last  = searchEnd
[00]          	|			else
[00]          	|				return spikeDetection
[00]*         	|			endif
[00]          	|		else
[00]*         	|			rangeSearchLevel = minVal + GetMachineEpsilon(WaveType(singleDA))
[00]          	|
[00]*         	|			Make/FREE/D levels
[17]**        	|			FindLevels/R=(offset, Inf)/Q/N=2/DEST=levels singleDA, rangeSearchLevel
[00]*         	|			ASSERT(V_LevelsFound == 2, "Could not find two levels")
[00]*         	|			first = levels[0]
[00]          	|
[00]*         	|			if(type == PSQ_DA_SCALE)
[00]*         	|				last = levels[1]
[00]          	|			else
[00]*         	|				last = searchEnd
[00]          	|			endif
[00]          	|		endif
[00]*         	|	endif
[00]          	|
[00]*         	|	if(TestOverrideActive())
[00]          	|		WAVE overrideResults = GetOverrideResults()
[00]          	|		NVAR count           = $GetCount(device)
[00]          	|
[00]          	|		switch(type)
[00]          	|			case PSQ_TRUE_REST_VM:
[00]          	|				overrideValue          = overrideResults[0][count][1]
[00]          	|				numSpikesFoundOverride = overrideValue
[00]          	|				break
[00]          	|			case PSQ_CHIRP:
[00]          	|				overrideValue          = !overrideResults[0][count][3]
[00]          	|				numSpikesFoundOverride = overrideValue > 0
[00]          	|				break
[00]          	|			case PSQ_RHEOBASE:
[00]          	|				overrideValue          = overrideResults[0][count][1]
[00]          	|				numSpikesFoundOverride = overrideValue > 0
[00]          	|				break
[00]          	|			case PSQ_SQUARE_PULSE:
[00]          	|				overrideValue          = overrideResults[0][count][0]
[00]          	|				numSpikesFoundOverride = overrideValue > 0
[00]          	|				break
[00]          	|			case PSQ_RAMP:
[00]          	|				overrideValue          = overrideResults[0][count][1]
[00]          	|				numSpikesFoundOverride = overrideValue > 0
[00]          	|				break
[00]          	|			case PSQ_DA_SCALE:
[00]          	|				overrideValue = overrideResults[0][count][1]
[00]          	|				if(overrideValue > 0)
[00]          	|					numSpikesFoundOverride = overrideResults[0][count][2]
[00]          	|				else
[00]          	|					numSpikesFoundOverride = 0
[00]          	|				endif
[00]          	|				break
[00]          	|			default:
[00]          	|				FATAL_ERROR("unsupported type")
[00]          	|		endswitch
[00]          	|
[00]          	|		if(overrideValue == 0 || overrideValue == 1)
[00]          	|			spikeDetection[headstage] = overrideValue
[00]          	|		else
[00]          	|			spikeDetection[headstage] = overrideValue >= first && overrideValue <= last
[00]          	|		endif
[00]          	|
[00]          	|		if(!ParamIsDefault(spikePositions))
[00]          	|			ASSERT(WaveExists(spikePositions), "Wave spikePositions must exist")
[00]          	|			Redimension/D/N=(numSpikesFoundOverride) spikePositions
[00]          	|			spikePositions[] = overrideValue
[00]          	|		endif
[00]          	|
[00]          	|		if(!ParamIsDefault(numberOfSpikesFound))
[00]          	|			numberOfSpikesFound = numSpikesFoundOverride
[00]*         	|		endif
[00]          	|	else
[00]          	|
[00]*         	|		WAVE singleAD = AFH_ExtractOneDimDataFromSweep(device, sweepWave, headstage, XOP_CHANNEL_TYPE_ADC, config = config)
[00]*         	|		ASSERT(!cmpstr(WaveUnits(singleAD, -1), "mV"), "Unexpected AD Unit")
[00]          	|
[00]*         	|		if(type == PSQ_CHIRP)
[00]          	|			// use PA plot logic
[00]          	|			Duplicate/R=(first, last)/FREE singleAD, chirpChunk
[00]          	|
[00]          	|			ASSERT(numberOfSpikesReq == Inf, "Unexpected value of numberOfSpikesReq")
[00]          	|			WAVE spikePositionsResult = PA_SpikePositionsForNonVC(chirpChunk, level)
[00]          	|
[00]          	|			spikeDetection[headstage] = DimSize(spikePositionsResult, ROWS) > 0
[00]          	|
[00]          	|			if(!ParamIsDefault(numberOfSpikesFound))
[00]          	|				numberOfSpikesFound = DimSize(spikePositionsResult, ROWS)
[00]*         	|			endif
[00]          	|		else
[00]*         	|			if(numberOfSpikesReq == 1)
[00]          	|				// search the spike from the start till the end
[00]          	|				FindLevel/Q/R=(first, last)/B=3 singleAD, level
[00]          	|				spikeDetection[headstage] = !V_flag
[00]          	|
[00]          	|				if(!ParamIsDefault(spikePositions))
[00]          	|					ASSERT(WaveExists(spikePositions), "Wave spikePositions must exist")
[00]          	|					Redimension/D/N=(numberOfSpikesReq) spikePositions
[00]          	|					spikePositions[0] = V_LevelX
[00]          	|				endif
[00]          	|
[00]          	|				if(!ParamIsDefault(numberOfSpikesFound))
[00]          	|					numberOfSpikesFound = spikeDetection[headstage]
[00]*         	|				endif
[00]*         	|			elseif(numberOfSpikesReq > 1)
[00]*         	|				Make/D/FREE/N=0 crossings
[26]***       	|				FindLevels/Q/R=(first, last)/N=(numberOfSpikesReq)/DEST=crossings/EDGE=(FINDLEVEL_EDGE_INCREASING)/B=3 singleAD, level
[00]*         	|				spikeDetection[headstage] = IsFinite(numberOfSpikesReq) ? (!V_flag) : (V_LevelsFound > 0)
[00]          	|
[00]*         	|				if(!ParamIsDefault(spikePositions))
[00]*         	|					ASSERT(WaveExists(spikePositions), "Wave spikePositions must exist")
[00]*         	|					Redimension/D/N=(V_LevelsFound) spikePositions
[00]          	|
[00]*         	|					if(spikeDetection[headstage])
[00]*         	|						spikePositions[] = crossings[p]
[00]          	|					endif
[00]          	|				endif
[00]          	|
[00]*         	|				if(!ParamIsDefault(numberOfSpikesFound))
[00]          	|					numberOfSpikesFound = V_LevelsFound
[00]*         	|				endif
[00]          	|			else
[00]          	|				FATAL_ERROR("Invalid number of spikes value")
[00]*         	|			endif
[00]          	|		endif
[00]*         	|	endif
[00]          	|
[00]*         	|	ASSERT(IsFinite(spikeDetection[headstage]), "Expected finite result")
[00]          	|
[00]*         	|	return DEBUGPRINTw(spikeDetection)
[00]          	|End

We use PSQ_SearchForSpikes in the following analysis functions:

  • DAScale Supra
  • Square Pulse
  • Rheobase
  • Ramp
  • Chirp
  • TrueRestingMembranePotential

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions