From f0707a869b471d524f44c0cc19ac69d4354dda85 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Fri, 12 Jul 2024 14:46:01 +0200 Subject: [PATCH 01/17] MIES_WaveBuilder.ipf: Add per sweep minimum/maximum to wave note We need to calculate the extrema after filling them into the final stimset to accomodate for trailing baseline which is zero. --- Packages/MIES/MIES_Constants.ipf | 2 +- Packages/MIES/MIES_WaveBuilder.ipf | 31 +++++++++++++++++++ .../tests/Basic/UTF_WaveBuilderRegression.ipf | 13 +++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Packages/MIES/MIES_Constants.ipf b/Packages/MIES/MIES_Constants.ipf index 72950c4feb..32e950e9c8 100644 --- a/Packages/MIES/MIES_Constants.ipf +++ b/Packages/MIES/MIES_Constants.ipf @@ -25,7 +25,7 @@ Constant ANALYSISBROWSER_PANEL_VERSION = 5 Constant PSX_PLOT_PANEL_VERSION = 1 /// Version of the stimset wave note -Constant STIMSET_NOTE_VERSION = 11 +Constant STIMSET_NOTE_VERSION = 12 /// Version of the epoch information for DA+TTL data Constant SWEEP_EPOCH_VERSION = 9 diff --git a/Packages/MIES/MIES_WaveBuilder.ipf b/Packages/MIES/MIES_WaveBuilder.ipf index 4c58ed9670..c8c607486e 100644 --- a/Packages/MIES/MIES_WaveBuilder.ipf +++ b/Packages/MIES/MIES_WaveBuilder.ipf @@ -470,6 +470,8 @@ static Function/WAVE WB_GetStimSet([string setName]) last = length - 1 Multithread stimSet[0, last][i] = wv[p] + + WB_AppendSweepMinMax(stimSet, i, numSweeps, numEpochs) endfor if(SegWvType[98]) @@ -779,6 +781,7 @@ static Function/WAVE WB_MakeWaveBuilderWave(WAVE WP, WAVE/T WPT, WAVE SegWvType, AddEntryIntoWaveNoteAsList(WaveBuilderWave, "Sweep", var = stepCount) AddEntryIntoWaveNoteAsList(WaveBuilderWave, "Epoch", var = NaN) AddEntryIntoWaveNoteAsList(WaveBuilderWave, "ITI", var = SegWvType[99], appendCR = 1) + // Minimum, Maximum is appended later for(i = 0; i < numEpochs; i += 1) type = SegWvType[i] @@ -1041,6 +1044,34 @@ static Function/WAVE WB_MakeWaveBuilderWave(WAVE WP, WAVE/T WPT, WAVE SegWvType, return WaveBuilderWave End +static Function WB_AppendSweepMinMax(WAVE wv, variable sweep, variable numSweeps, variable numEpochs) + + variable minimum, maximum, idx, first, last, trailSep + string entry + + first = (sweep == 0) + last = (sweep + 1 == numSweeps) + + MatrixOP/FREE singleSweep = col(wv, sweep) + + [minimum, maximum] = WaveMinAndMax(singleSweep) + + WAVE/T wvNote = ListToTextWave(note(wv), "\r") + // "Version" line preceds the first sweep + idx = 1 + sweep * (numEpochs + 1) + + sprintf entry, "Minimum = %.15g;", minimum + wvNote[idx] += entry + + sprintf entry, "Maximum = %.15g;", maximum + wvNote[idx] += entry + + // append a trailing CR except for the last entry + trailSep = !last + + Note/K wv, TextWaveToList(wvNote, "\r", trailSep = trailSep) +End + /// @brief Update the accumulated stimset duration for the mouse selection via GetEpochID() /// /// @param[in] epochIndex index of the epoch diff --git a/Packages/tests/Basic/UTF_WaveBuilderRegression.ipf b/Packages/tests/Basic/UTF_WaveBuilderRegression.ipf index b5f95588b1..b78b58e4c1 100644 --- a/Packages/tests/Basic/UTF_WaveBuilderRegression.ipf +++ b/Packages/tests/Basic/UTF_WaveBuilderRegression.ipf @@ -78,7 +78,7 @@ End // UTF_TD_GENERATOR WB_GatherStimsets Function WB_RegressionTest([string stimset]) - variable i, j, sweepCount, duration, epochCount + variable i, j, sweepCount, duration, epochCount, minimum, maximum string text // stock MIES stimset @@ -171,6 +171,17 @@ Function WB_RegressionTest([string stimset]) break endswitch endfor + + MatrixOP/FREE singleSweep = col(wv, i) + + // check minimum/maximum + minimum = WB_GetWaveNoteEntryAsNumber(text, SWEEP_ENTRY, key = "Minimum", sweep = i) + MatrixOP/FREE minimumCal = minVal(singleSweep) + CHECK_CLOSE_VAR(minimum, minimumCal[0]) + + maximum = WB_GetWaveNoteEntryAsNumber(text, SWEEP_ENTRY, key = "Maximum", sweep = i) + MatrixOP/FREE maximumCal = maxVal(singleSweep) + CHECK_CLOSE_VAR(maximum, maximumCal[0]) endfor // check ITIs From f180ef066c4f2032d146aef9d2e2d6e681cee3e6 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Fri, 12 Jul 2024 22:38:40 +0200 Subject: [PATCH 02/17] DAP_GetDAScaleMax: Add function to return the maximum possible DAScale value --- Packages/MIES/MIES_DAEphys.ipf | 69 ++++++++++++++++ .../HardwareBasic/UTF_BasicHardwareTests.ipf | 79 +++++++++++++++++++ 2 files changed, 148 insertions(+) diff --git a/Packages/MIES/MIES_DAEphys.ipf b/Packages/MIES/MIES_DAEphys.ipf index f19585e551..b10b96c282 100644 --- a/Packages/MIES/MIES_DAEphys.ipf +++ b/Packages/MIES/MIES_DAEphys.ipf @@ -5469,3 +5469,72 @@ Function DAP_TPSettingsToGUI(string device, [string entry]) TP_RestartTestPulse(device, TPState) endif End + +/// @brief Return the maximum possible DAScale value +/// +/// @param device DAC device +/// @param headstage headstage +/// @param stimsetName name of the stimset +/// @param stimsetColumn set sweep count of the given stimset to use for min/max calculation +Function DAP_GetDAScaleMax(string device, variable headstage, string stimsetName, variable stimsetColumn) + + variable minData, maxData, gain, hardwareType, DAC, minStimset, maxStimset, activeDACIndex + variable result, minimum, maximum + string ctrl, text, msg + + if(DAP_DeviceIsUnLocked(device)) + return NaN + endif + + DAC = AFH_GetDACFromHeadstage(device, headstage) + if(!IsValidHeadstage(DAC)) + return NaN + endif + + if(WB_StimsetIsFromThirdParty(stimsetName)) + return NaN + endif + + WAVE/Z stimset = WB_CreateAndGetStimSet(stimsetName) + ASSERT(WaveExists(stimset), "Could not create stimset") + + if(stimsetColumn >= DimSize(stimset, COLS)) + return NaN + endif + + text = note(stimset) + minStimset = WB_GetWaveNoteEntryAsNumber(text, SWEEP_ENTRY, key = "Minimum", sweep = stimsetColumn) + maxStimset = WB_GetWaveNoteEntryAsNumber(text, SWEEP_ENTRY, key = "Maximum", sweep = stimsetColumn) + ASSERT(IsFinite(minStimset) && IsFinite(maxStimset), "Invalid minimum/maximum") + + hardwareType = GetHardwareType(device) + [minData, maxData] = HW_GetDataRange(hardwareType, XOP_CHANNEL_TYPE_DAC, 1) + + WAVE DAQConfigWave = GetDAQConfigWave(device) + WAVE DACs = GetDACListFromConfig(DAQConfigWave) + activeDACIndex = GetRowIndex(DACs, val = DAC) + + WAVE gains = SWS_GetChannelGains(device, timing = GAIN_BEFORE_DAQ) + gain = gains[activeDACIndex] + ASSERT(IsFinite(gain), "Invalid gain") + + minimum = minData / (minStimset * gain) + maximum = maxData / (maxStimset * gain) + + if(IsInf(minimum) && IsInf(maximum)) + result = Inf + elseif(IsInf(minimum)) + result = maximum + elseif(IsInf(maximum)) + result = minimum + else + result = min(minimum, maximum) + endif + + result = trunc(result) + + sprintf msg, "result %g, minimum %g, maximum %g, minData %g, maxData %g, minStimset %g, maxStimset %g, channel gain %g\r", result, minimum, maximum, minData, maxData, minStimset, maxStimset, gain + DEBUGPRINT(msg) + + return result +End diff --git a/Packages/tests/HardwareBasic/UTF_BasicHardwareTests.ipf b/Packages/tests/HardwareBasic/UTF_BasicHardwareTests.ipf index 157776d1aa..ec42cee8a3 100644 --- a/Packages/tests/HardwareBasic/UTF_BasicHardwareTests.ipf +++ b/Packages/tests/HardwareBasic/UTF_BasicHardwareTests.ipf @@ -2445,3 +2445,82 @@ static Function TestCustomElectrodeNamesInNWB_REENTRY([string str]) CHECK_EQUAL_VAR(GetSetVariable(str, "SetVar_Sweep"), 1) TestNwbExportV2() End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function GetDataLimitsCheckWorks([string str]) + + variable DAScaleLimit + + // unlocked device + DAScaleLimit = DAP_GetDAScaleMax(str, 1, "StimulusSetA_DA_0", 0) + CHECK(IsNaN(DAScaleLimit)) + + STRUCT DAQSettings s + InitDAQSettingsFromString(s, "MD1_RA1_I0_L0_BKG1_TP1" + \ + "__HS1_DA1_AD2_CM:IC:_ST:StimulusSetA_DA_0:") + + AcquireData_NG(s, str) + + CtrlNamedBackGround StopTPAfterSomeTime, start=(ticks + 120), period=60, proc=StopTP_IGNORE +End + +static Function GetDataLimitsCheckWorks_REENTRY([string str]) + + string stimset, ctrl + variable DAScaleLimit, headstage, DAC, stimsetAColumnZeroLimit, stimsetAColumnOneLimit + variable stimsetEndingColumnZeroLimit + + headstage = 1 + DAC = 1 + stimset = "StimulusSetA_DA_0" + +#ifdef TESTS_WITH_NI_HARDWARE + stimsetAColumnZeroLimit = 4000 + stimsetAColumnOneLimit = 2000 + stimsetEndingColumnZeroLimit = 1333 +#else + stimsetAColumnZeroLimit = 4095 + stimsetAColumnOneLimit = 2047 + stimsetEndingColumnZeroLimit = 1365 +#endif + + // unassociated/unused headstage + DAScaleLimit = DAP_GetDAScaleMax(str, 0, stimset, 0) + CHECK(IsNaN(DAScaleLimit)) + + // invalid setColumn + DAScaleLimit = DAP_GetDAScaleMax(str, headstage, stimset, 4711) + CHECK(IsNaN(DAScaleLimit)) + + DAScaleLimit = DAP_GetDAScaleMax(str, headstage, stimset, 0) + CHECK_EQUAL_VAR(DAScaleLimit, stimsetAColumnZeroLimit) + + DAScaleLimit = DAP_GetDAScaleMax(str, headstage, stimset, 1) + CHECK_EQUAL_VAR(DAScaleLimit, stimsetAColumnOneLimit) + + // constant zero stimset + stimset = "ConstantZero_DA_0" + ctrl = GetPanelControl(DAC, CHANNEL_TYPE_DAC, CHANNEL_CONTROL_WAVE) + PGC_SetAndActivateControl(str, ctrl, str = stimset) + DAScaleLimit = DAP_GetDAScaleMax(str, headstage, stimset, 0) + CHECK_EQUAL_VAR(DAScaleLimit, Inf) + + // stimset with non-zero minimum and maximum + stimset = "EpochTest0_DA_0" + ctrl = GetPanelControl(DAC, CHANNEL_TYPE_DAC, CHANNEL_CONTROL_WAVE) + PGC_SetAndActivateControl(str, ctrl, str = stimset) + DAScaleLimit = DAP_GetDAScaleMax(str, headstage, stimset, 0) + CHECK_EQUAL_VAR(DAScaleLimit, stimsetAColumnZeroLimit) + + // stimset with zero maximum + stimset = "IV_Curve_ending_DA_0" + ctrl = GetPanelControl(DAC, CHANNEL_TYPE_DAC, CHANNEL_CONTROL_WAVE) + PGC_SetAndActivateControl(str, ctrl, str = stimset) + DAScaleLimit = DAP_GetDAScaleMax(str, headstage, stimset, 0) + CHECK_EQUAL_VAR(DAScaleLimit, stimsetEndingColumnZeroLimit) + + // third party + WB_MakeStimsetThirdParty(stimset) + DAScaleLimit = DAP_GetDAScaleMax(str, headstage, stimset, 0) + CHECK(IsNaN(DAScaleLimit)) +End From e3edfe8df1e66908f854b63aeedb0adfe12fd704 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Mon, 15 Jul 2024 16:08:02 +0200 Subject: [PATCH 03/17] SetDaScale/SetDAScaleModOp: Allow to respect DAScale limits When limitCheck is true we now return 1 when setting the new DAScale value would be out of range for the current external command sensitivity of the MCC amplifier. This also requires that we now pass in the sweep number. The default of limitCheck is still false. Only when all analysis functions are ported, can we flip the default. --- Packages/MIES/MIES_AnalysisFunctions.ipf | 60 +++++++++++++++---- .../MIES_AnalysisFunctions_MultiPatchSeq.ipf | 8 +-- ...isFunctions_MultiPatchSeq_SpikeControl.ipf | 6 +- .../MIES/MIES_AnalysisFunctions_PatchSeq.ipf | 22 +++---- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions.ipf b/Packages/MIES/MIES_AnalysisFunctions.ipf index 1421d3adf0..aabd9b2faf 100644 --- a/Packages/MIES/MIES_AnalysisFunctions.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions.ipf @@ -853,8 +853,8 @@ Function FitResistance(string device, variable headstage, [variable showPlot, va endif End -/// @brief Helper for setting the DAScale -Function SetDAScaleModOp(string device, variable headstage, variable modifier, string operator, [variable invert, variable roundTopA]) +/// @brief Helper for setting the DAScale, see also SetDAScale() +Function SetDAScaleModOp(string device, variable sweepNo, variable headstage, variable modifier, string operator, [variable invert, variable roundTopA, variable limitCheck]) if(ParamIsDefault(invert)) invert = 0 @@ -868,13 +868,17 @@ Function SetDAScaleModOp(string device, variable headstage, variable modifier, s roundTopA = !!roundTopA endif + if(ParamIsDefault(limitCheck)) + limitCheck = 1 + else + limitCheck = !!limitCheck + endif + strswitch(operator) case "+": - SetDAScale(device, headstage, offset = invert ? -modifier : modifier, roundTopA = roundTopA) - break + return SetDAScale(device, sweepNo, headstage, offset = invert ? -modifier : modifier, roundTopA = roundTopA, limitCheck = limitCheck) case "*": - SetDAScale(device, headstage, relative = invert ? 1 / modifier : modifier, roundTopA = roundTopA) - break + return SetDAScale(device, sweepNo, headstage, relative = invert ? 1 / modifier : modifier, roundTopA = roundTopA, limitCheck = limitCheck) default: ASSERT(0, "Invalid operator") break @@ -883,16 +887,22 @@ End /// @brief Set the DAScale value of the given headstage /// -/// @param device device +/// The limit check assumes that the next sweep is the next sweep of the current stimset (aka has a set count + 1). +/// +/// @param device device /// @param headstage MIES headstage +/// @param sweepNo Sweep number /// @param absolute (optional) DAScale value in `A` (Amperes) /// @param relative (optional) relative DAScale modifier /// @param offset (optional) offset DAScale value /// @param roundTopA (optional, defaults to false) round the set DAScale to integer pA values -Function SetDAScale(string device, variable headstage, [variable absolute, variable relative, variable offset, variable roundTopA]) +/// @param limitCheck (optional, defaults to true) check if the new DAScale value would be out of range +/// +/// @return 0 on sucessful limits check, 1 on out-of-range and NaN if the limits check was skipped +Function SetDAScale(string device, variable sweepNo, variable headstage, [variable absolute, variable relative, variable offset, variable roundTopA, variable limitCheck]) - variable amps, DAC - string DAUnit, ctrl, lbl + variable amps, DAC, nextStimsetColumn, DAScaleLimit, skipCountExisting, setCount + string DAUnit, ctrl, lbl, stimSetName ASSERT(ParamIsDefault(absolute) + ParamIsDefault(relative) + ParamIsDefault(offset) == 2, "One of absolute, relative or offset has to be present") @@ -902,6 +912,12 @@ Function SetDAScale(string device, variable headstage, [variable absolute, varia roundTopA = !!roundTopA endif + if(ParamIsDefault(limitCheck)) + limitCheck = 1 + else + limitCheck = !!limitCheck + endif + DAC = AFH_GetDACFromHeadstage(device, headstage) ASSERT(IsFinite(DAC), "Does not work with unassociated DA channels") @@ -924,7 +940,27 @@ Function SetDAScale(string device, variable headstage, [variable absolute, varia amps = roundTopA ? round(amps) : amps ASSERT(IsFinite(amps), "Invalid non-finite value") + + if(limitCheck) + stimSetName = AFH_GetStimSetNameForHeadstage(device, headstage) + WAVE numericalValues = GetLBNumericalValues(device) + + nextStimsetColumn = AFH_GetNextSweepSetCount(numericalValues, sweepNo, headstage) + + DAScaleLimit = DAP_GetDAScaleMax(device, headstage, stimsetName, nextStimsetColumn) + ASSERT(IsFinite(DAScaleLimit), "Unsupported return value from DAP_GetDataLimits") + + // the border value is not valid, see DC_CheckIfDataWaveHasBorderVals + if(amps >= DAScaleLimit) + return 1 + endif + endif + PGC_SetAndActivateControl(device, ctrl, val = amps) + + if(limitCheck) + return 0 + endif End /// @brief Return a list of required parameters @@ -1016,7 +1052,7 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s) return 1 endif - SetDAScale(device, i, absolute = -20e-12) + SetDAScale(device, s.sweepNo, i, absolute = -20e-12) autoBiasCheck = ampParam[%AutoBiasEnable][0][i] holdingPotential = ampParam[%AutoBiasVcom][0][i] @@ -1155,7 +1191,7 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s) sprintf msg, "(%s, %d): ΔR = %.0W1PΩ, V_target = %.0W1PV, I = %.0W1PA", device, i, resistanceFitted[i], targetV, amps DEBUGPRINT(msg) - SetDAScale(device, i, absolute = amps) + SetDAScale(device, s.sweepNo, i, absolute = amps) endfor break case POST_SET_EVENT: diff --git a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf index 1ef84d4064..441a369d5f 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf @@ -633,7 +633,7 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) continue endif - SetDAScale(device, i, absolute = MSQ_FRE_INIT_AMP_p100) + SetDAScale(device, s.sweepNo, i, absolute = MSQ_FRE_INIT_AMP_p100) endfor PGC_SetAndActivateControl(device, "Check_DataAcq1_DistribDaq", val = 0) @@ -759,7 +759,7 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) ASSERT(headstagePassed[i] != 1, "Unexpected headstage passing") headstagePassed[i] = 0 else - SetDAScale(device, i, absolute = newDAScaleValue) + SetDAScale(device, s.sweepNo, i, absolute = newDAScaleValue) endif endfor @@ -861,7 +861,7 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) val = AFH_GetAnalysisParamNumerical("PostDAQDAScaleForFailedHS", s.params) * PICO_TO_ONE endif - SetDAScale(device, i, absolute = val) + SetDAScale(device, s.sweepNo, i, absolute = val) endfor endif @@ -1218,7 +1218,7 @@ Function MSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) index = mod(DAScalesIndex[i], DimSize(DAScales, ROWS)) ASSERT(isFinite(daScaleOffset[i]), "DAScale offset is non-finite") - SetDAScale(device, i, absolute = (DAScales[index] + daScaleOffset[i]) * PICO_TO_ONE) + SetDAScale(device, s.sweepNo, i, absolute = (DAScales[index] + daScaleOffset[i]) * PICO_TO_ONE) DAScalesIndex[i] += 1 endfor endif diff --git a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq_SpikeControl.ipf b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq_SpikeControl.ipf index e69b84c7df..546066919a 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq_SpikeControl.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq_SpikeControl.ipf @@ -728,7 +728,7 @@ static Function SC_ReactToQCFailures(string device, variable sweepNo, string par if(!spikePositionsQCLBN[i]) sprintf msg, "spike position QC failed on HS%d, adapting DAScale", i DebugPrint(msg) - SetDAScaleModOp(device, i, daScaleSpikePositionModifier, daScaleSpikePositionOperator) + SetDAScaleModOp(device, sweepNo, i, daScaleSpikePositionModifier, daScaleSpikePositionOperator) endif continue @@ -752,7 +752,7 @@ static Function SC_ReactToQCFailures(string device, variable sweepNo, string par strswitch(spikeCountStateLBN[i]) case SC_SPIKE_COUNT_STATE_STR_TOO_MANY: - SetDAScaleModOp(device, i, daScaleTooManySpikesModifier, daScaleTooManySpikesOperator) + SetDAScaleModOp(device, sweepNo, i, daScaleTooManySpikesModifier, daScaleTooManySpikesOperator) break case SC_SPIKE_COUNT_STATE_STR_MIXED: printf "The spike count on headstage %d in sweep %d is mixed (some pulses have too few, others too many)\n", i, sweepNo @@ -766,7 +766,7 @@ static Function SC_ReactToQCFailures(string device, variable sweepNo, string par ControlWindowToFront() endif case SC_SPIKE_COUNT_STATE_STR_TOO_FEW: // fallthrough-by-design - SetDAScaleModOp(device, i, daScaleModifier, daScaleOperator) + SetDAScaleModOp(device, sweepNo, i, daScaleModifier, daScaleOperator) break case SC_SPIKE_COUNT_STATE_STR_GOOD: // nothing to do diff --git a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf index 5d429afc15..12e00ab03a 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf @@ -4270,7 +4270,7 @@ Function PSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) ASSERT(0, "Invalid case") break endswitch - SetDAScale(device, i, absolute = DAScale * PICO_TO_ONE) + SetDAScale(device, s.sweepNo, i, absolute = DAScale * PICO_TO_ONE) endif endfor endif @@ -4411,7 +4411,7 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) PGC_SetAndActivateControl(device, "check_Settings_ITITP", val = 0) PSQ_StoreStepSizeInLBN(device, PSQ_SQUARE_PULSE, s.sweepNo, PSQ_SP_INIT_AMP_p100) - SetDAScale(device, s.headstage, absolute = PSQ_SP_INIT_AMP_p100) + SetDAScale(device, s.sweepNo, s.headstage, absolute = PSQ_SP_INIT_AMP_p100) return 0 @@ -4464,7 +4464,7 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) RA_SkipSweeps(device, Inf, SWEEP_SKIP_AUTO, limitToSetBorder = 1) endif elseif(CheckIfClose(stepSize, PSQ_SP_INIT_AMP_m50)) - SetDAScale(device, s.headstage, absolute = DAScale + stepsize) + SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize) elseif(CheckIfClose(stepSize, PSQ_SP_INIT_AMP_p10)) WAVE value = LBN_GetNumericWave() value[INDEP_HEADSTAGE] = DAScale @@ -4480,7 +4480,7 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) elseif(CheckIfClose(stepSize, PSQ_SP_INIT_AMP_p100)) PSQ_StoreStepSizeInLBN(device, PSQ_SQUARE_PULSE, s.sweepNo, PSQ_SP_INIT_AMP_m50) stepsize = PSQ_SP_INIT_AMP_m50 - SetDAScale(device, s.headstage, absolute = DAScale + stepsize) + SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize) else ASSERT(0, "Unknown stepsize") endif @@ -4496,7 +4496,7 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) ASSERT(0, "Unknown stepsize") endif - SetDAScale(device, s.headstage, absolute = DAScale + stepsize) + SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize) endif sprintf msg, "Sweep has %s\r", ToPassFail(sweepPassed) @@ -4705,7 +4705,7 @@ Function PSQ_Rheobase(string device, STRUCT AnalysisFunction_V3 &s) endif endif - SetDAScale(device, s.headstage, absolute = finalDAScale) + SetDAScale(device, s.sweepNo, s.headstage, absolute = finalDAScale) return 0 @@ -4894,7 +4894,7 @@ Function PSQ_Rheobase(string device, STRUCT AnalysisFunction_V3 &s) break endif - SetDAScale(device, s.headstage, absolute = DAScale) + SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale) break case POST_SET_EVENT: WAVE numericalValues = GetLBNumericalValues(device) @@ -5145,7 +5145,7 @@ Function PSQ_Ramp(string device, STRUCT AnalysisFunction_V3 &s) PGC_SetAndActivateControl(device, "check_Settings_ITITP", val = 1) PGC_SetAndActivateControl(device, "Check_Settings_InsertTP", val = 1) - SetDAScale(device, s.headstage, absolute = PSQ_RA_DASCALE_DEFAULT * PICO_TO_ONE) + SetDAScale(device, s.sweepNo, s.headstage, absolute = PSQ_RA_DASCALE_DEFAULT * PICO_TO_ONE) return 0 @@ -6184,7 +6184,7 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) result[INDEP_HEADSTAGE] = initialDAScale ED_AddEntryToLabnotebook(device, key, result, overrideSweepNo = s.sweepNo) - SetDAScale(device, s.headstage, absolute = initialDAScale, roundTopA = 1) + SetDAScale(device, s.sweepNo, s.headstage, absolute = initialDAScale, roundTopA = 1) WAVE result = LBN_GetNumericWave() key = CreateAnaFuncLBNKey(PSQ_CHIRP, PSQ_FMT_LBN_CR_INIT_UOD) @@ -6423,7 +6423,7 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) // adapt DAScale and finish daScaleModifier = AFH_GetAnalysisParamNumerical("DAScaleModifier", s.params) daScaleOperator = AFH_GetAnalysisParamTextual("DAScaleOperator", s.params) - SetDAScaleModOp(device, s.headstage, daScaleModifier, daScaleOperator, roundTopA = 1) + SetDAScaleModOp(device, s.sweepNo, s.headstage, daScaleModifier, daScaleOperator, roundTopA = 1) return ANALYSIS_FUNC_RET_EARLY_STOP endif @@ -6447,7 +6447,7 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) break case PSQ_CR_INCREASE: case PSQ_CR_DECREASE: // fallthrough-by-design - SetDAScale(device, s.headstage, relative = scalingFactorDAScale, roundTopA = 1) + SetDAScale(device, s.sweepNo, s.headstage, relative = scalingFactorDAScale, roundTopA = 1) break default: ASSERT(0, "impossible case") From 80abddade02d57c50dcaeade1129d995e656d33f Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 16:27:43 +0200 Subject: [PATCH 04/17] MIES_AnalysisFunctions.ipf: Add CreateOverrideResults --- Packages/MIES/MIES_AnalysisFunctions.ipf | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Packages/MIES/MIES_AnalysisFunctions.ipf b/Packages/MIES/MIES_AnalysisFunctions.ipf index aabd9b2faf..b7b25e9320 100644 --- a/Packages/MIES/MIES_AnalysisFunctions.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions.ipf @@ -1010,6 +1010,36 @@ Function/S ReachTargetVoltage_CheckParam(string name, STRUCT CheckParametersStru endswitch End +/// #ReachTargetVoltage: +/// +/// Rows: +/// - Headstage +/// +/// Cols: +/// - 0: Resistance [MΩ] +static Function/WAVE CreateOverrideResults() + + variable numRows, numCols + + numRows = LABNOTEBOOK_LAYER_COUNT + numCols = 1 + + WAVE/Z/D wv = GetOverrideResults() + + if(WaveExists(wv)) + ASSERT(IsNumericWave(wv), "overrideResults wave must be numeric here") + Redimension/D/N=(numRows, numCols) wv + else + Make/D/N=(numRows, numCols) root:overrideResults/WAVE=wv + endif + + wv[] = 0 + + SetDimensionLabels(wv, "Resistance", COLS) + + return wv +End + /// @brief Analysis function to experimentally determine the cell resistance by sweeping /// through a wave of target voltages. /// From 0ba3c508e8b75f671a4b304326cda2d6f13ee7ec Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:48:29 +0200 Subject: [PATCH 05/17] ReportOutOfRangeDAScale: Add it --- Packages/MIES/MIES_AnalysisFunctions.ipf | 82 +++++++++++++++++++ .../MIES_AnalysisFunctions_MultiPatchSeq.ipf | 1 + .../MIES/MIES_AnalysisFunctions_PatchSeq.ipf | 1 + Packages/MIES/MIES_Constants.ipf | 3 + 4 files changed, 87 insertions(+) diff --git a/Packages/MIES/MIES_AnalysisFunctions.ipf b/Packages/MIES/MIES_AnalysisFunctions.ipf index b7b25e9320..b20a2f5942 100644 --- a/Packages/MIES/MIES_AnalysisFunctions.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions.ipf @@ -1262,6 +1262,88 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s) endswitch End +/// @brief Report a future out of range DAScale value to the user and the labnotebook +/// +/// Usage for a single headstage: +/// +/// \rst +/// .. code-block:: igorpro +/// +/// WAVE oorDAScale = LBN_GetNumericWave() +/// oorDAScale[s.headstage] = SetDAScale(...) +/// +/// if(oorDAScale[s.headstage]) +/// ReportOutOfRangeDAScale(...) +/// endif +/// \endrst +Function ReportOutOfRangeDAScale(string device, variable sweepNo, variable anaFuncType, WAVE oorDAScale) + + variable i + string key + + ASSERT(GetHardwareType(device) != HARDWARE_SUTTER_DAC, "Missing support for Sutter amplifier") + + switch(anaFuncType) + case PSQ_CHIRP: + case PSQ_RAMP: + case PSQ_DA_SCALE: + case PSQ_SQUARE_PULSE: + case PSQ_RHEOBASE: + key = CreateAnaFuncLBNKey(anaFuncType, PSQ_FMT_LBN_DASCALE_OOR) + ED_AddEntryToLabnotebook(device, key, oorDAScale, overrideSweepNo = sweepNo, unit = LABNOTEBOOK_BINARY_UNIT) + break + case MSQ_FAST_RHEO_EST: + case MSQ_DA_SCALE: + case SC_SPIKE_CONTROL: + key = CreateAnaFuncLBNKey(anaFuncType, MSQ_FMT_LBN_DASCALE_OOR) + ED_AddEntryToLabnotebook(device, key, oorDAScale, overrideSweepNo = sweepNo, unit = LABNOTEBOOK_BINARY_UNIT) + break + case INVALID_ANALYSIS_FUNCTION: // ReachTargetVoltage + ED_AddEntryToLabnotebook(device, LBN_DASCALE_OUT_OF_RANGE, oorDAScale, unit = LABNOTEBOOK_BINARY_UNIT) + break + default: + ASSERT(0, "Unknown analysis function") + endswitch + + WAVE statusHS = DAG_GetChannelState(device, CHANNEL_TYPE_HEADSTAGE) + + Make/FREE/N=(NUM_HEADSTAGES) failedHS = statusHS[p] && oorDAScale[p] == 1 + + if(Sum(failedHS) == 0) + return NaN + endif + + printf "(%s) The DAScale value could not be set as it is out-of-range.\r", GetRTStackInfo(2) + printf "Please adjust the \"External Command Sensitivity\" in the MultiClamp Commander application and try again.\r" + ControlWindowToFront() + + for(i = 0; i < NUM_HEADSTAGES; i += 1) + + if(!failedHS[i]) + continue + endif + + ForceSetEvent(device, i) + endfor + + RA_SkipSweeps(device, Inf, SWEEP_SKIP_AUTO) +End + +/// @brief Manually force the pre/post set events +/// +/// Required to do before skipping sweeps. +/// @todo this hack must go away. +static Function ForceSetEvent(string device, variable headstage) + + variable DAC + + WAVE setEventFlag = GetSetEventFlag(device) + DAC = AFH_GetDACFromHeadstage(device, headstage) + + setEventFlag[DAC][%PRE_SET_EVENT] = 1 + setEventFlag[DAC][%POST_SET_EVENT] = 1 +End + Function/S SetControlInEvent_CheckParam(string name, STRUCT CheckParametersStruct &s) string type, event diff --git a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf index 441a369d5f..3e85524529 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf @@ -28,6 +28,7 @@ /// MSQ_FMT_LBN_SET_PASS Pass/fail state of the complete set On/Off Numerical FRE, DS, SC No No No No No /// MSQ_FMT_LBN_ACTIVE_HS Active headstages in pre set event On/Off Numerical FRE, DS No Yes No No No /// MSQ_FMT_LBN_DASCALE_EXC Allowed DAScale exceeded given limit (none) Numerical FRE No Yes No No No +/// MSQ_FMT_LBN_DASCALE_OOR Future DAScale value is out of range On/Off Numerical FRE, DS, SC No Yes No No /// MSQ_FMT_LBN_PULSE_DUR Square pulse duration ms Numerical FRE No Yes No No No /// MSQ_FMT_LBN_SPIKE_POSITIONS Spike positions with ``P{1}_R{2}``, pulse index (``{1}``) and (none) Textual SC No Yes Yes Yes Yes /// region (``{2}``), as key and the spike positions as value in pulse diff --git a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf index 12e00ab03a..6e1c3025c5 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf @@ -42,6 +42,7 @@ /// PSQ_FMT_LBN_STEPSIZE Current DAScale step size (none) Numerical SP, RB No No /// PSQ_FMT_LBN_STEPSIZE_FUTURE Future DAScale step size (none) Numerical RB No No /// PSQ_FMT_LBN_RB_DASCALE_EXC Range for valid DAScale values is exceeded On/Off Numerical RB No Yes +/// PSQ_FMT_LBN_DASCALE_OOR Future DAScale value is out of range On/Off Numerical CR,XXX Yes Yes /// PSQ_FMT_LBN_RB_LIMITED_RES Failed due to limited DAScale resolution On/Off Numerical RB No Yes /// PSQ_FMT_LBN_FINAL_SCALE Final DAScale of the given headstage, only set on success (none) Numerical SP, RB No No /// PSQ_FMT_LBN_SPIKE_DASCALE_ZERO Sweep spiked with DAScale of 0 On/Off Numerical SP No No diff --git a/Packages/MIES/MIES_Constants.ipf b/Packages/MIES/MIES_Constants.ipf index 32e950e9c8..2378e061e6 100644 --- a/Packages/MIES/MIES_Constants.ipf +++ b/Packages/MIES/MIES_Constants.ipf @@ -1139,6 +1139,7 @@ StrConstant PSQ_BASELINE_SELECTION_SHORT_NAME_RE_MATCHER = "^U_BLS[[:digit:]]+$" /// @anchor PatchSeqLabnotebookFormatStrings ///@{ StrConstant PSQ_FMT_LBN_RB_DASCALE_EXC = "%s DAScale exceeded" +StrConstant PSQ_FMT_LBN_DASCALE_OOR = "%s DAScale out of range" StrConstant PSQ_FMT_LBN_STEPSIZE = "%s step size" StrConstant PSQ_FMT_LBN_STEPSIZE_FUTURE = "%s step size (fut.)" StrConstant PSQ_FMT_LBN_SPIKE_DETECT = "%s spike detected" @@ -1241,6 +1242,7 @@ StrConstant LBN_DELTA_V = "Delta V" StrConstant LBN_RESISTANCE_FIT = "ResistanceFromFit" StrConstant LBN_RESISTANCE_FIT_ERR = "ResistanceFromFit_Err" StrConstant LBN_AUTOBIAS_TARGET_DIAG = "Autobias target voltage from dialog" +StrConstant LBN_DASCALE_OUT_OF_RANGE = "DAScale out of range" ///@} /// @anchor PatchSeqAnalysisFunctionTypes @@ -1419,6 +1421,7 @@ StrConstant MSQ_FMT_LBN_SPIKE_COUNTS_STATE = "%s Spike counts state" StrConstant MSQ_FMT_LBN_IDEAL_SPIKE_COUNTS = "%s Ideal spike counts" StrConstant MSQ_FMT_LBN_RERUN_TRIAL = "%s Rerun Trials" StrConstant MSQ_FMT_LBN_RERUN_TRIAL_EXC = "%s Rerun Trials exceeded" +StrConstant MSQ_FMT_LBN_DASCALE_OOR = "%s DAScale out of range" ///@} /// @name Workaround flags for CreateAnaFuncLBNKey() From 9d49cd0ffac4dbf7341ebf6c90a75ee65e6c34be Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Mon, 15 Jul 2024 19:49:42 +0200 Subject: [PATCH 06/17] ReachTargetVoltage: Port to new SetDAscale behaviour We can't check the limits in the PRE_DAQ_EVENT event, so we have to disable it there. --- Packages/MIES/MIES_AnalysisFunctions.ipf | 15 +++++- .../UTF_ReachTargetVoltage.ipf | 48 +++++++++++++++++-- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions.ipf b/Packages/MIES/MIES_AnalysisFunctions.ipf index b20a2f5942..8baf2c7f0d 100644 --- a/Packages/MIES/MIES_AnalysisFunctions.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions.ipf @@ -1082,7 +1082,7 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s) return 1 endif - SetDAScale(device, s.sweepNo, i, absolute = -20e-12) + SetDAScale(device, s.sweepNo, i, absolute = -20e-12, limitCheck = 0) autoBiasCheck = ampParam[%AutoBiasEnable][0][i] holdingPotential = ampParam[%AutoBiasVcom][0][i] @@ -1175,6 +1175,7 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s) WAVE deltaV = LBN_GetNumericWave() WAVE deltaI = LBN_GetNumericWave() WAVE resistance = LBN_GetNumericWave() + WAVE oorDAScale = LBN_GetNumericWave() CalculateTPLikePropsFromSweep(numericalValues, textualValues, s.scaledDACWave, deltaI, deltaV, resistance) @@ -1186,6 +1187,14 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s) WAVE/Z resistanceFitted = GetLastSetting(numericalValues, s.sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT, UNKNOWN_MODE) ASSERT(WaveExists(resistanceFitted), "Expected fitted resistance data") +#ifdef AUTOMATED_TESTING + WAVE/Z overrideResults = GetOverrideResults() + + if(WaveExists(overrideResults)) + resistanceFitted[] = overrideResults[p][%Resistance] * MEGA_TO_ONE + endif +#endif + for(i = 0; i < NUM_HEADSTAGES; i += 1) if(!statusHS[i]) @@ -1221,8 +1230,10 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s) sprintf msg, "(%s, %d): ΔR = %.0W1PΩ, V_target = %.0W1PV, I = %.0W1PA", device, i, resistanceFitted[i], targetV, amps DEBUGPRINT(msg) - SetDAScale(device, s.sweepNo, i, absolute = amps) + oorDAScale[i] = SetDAScale(device, s.sweepNo, i, absolute = amps) endfor + + ReportOutOfRangeDAScale(device, s.sweepNo, INVALID_ANALYSIS_FUNCTION, oorDAScale) break case POST_SET_EVENT: if(!DAG_HeadstageIsHighestActive(device, s.headstage)) diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_ReachTargetVoltage.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_ReachTargetVoltage.ipf index 0d869be962..23f24768e2 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_ReachTargetVoltage.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_ReachTargetVoltage.ipf @@ -24,7 +24,7 @@ static Function GlobalPreInit(string device) PASS() End -static Function [WAVE/Z deltaI, WAVE/Z deltaV, WAVE/Z resistance, WAVE/Z resistanceErr, WAVE/Z autobiasFromDialog] GetLBNEntries_IGNORE(string device, variable sweepNo, variable headstage) +static Function [WAVE/Z deltaI, WAVE/Z deltaV, WAVE/Z resistance, WAVE/Z resistanceErr, WAVE/Z autobiasFromDialog, WAVE/Z outOfRangeDAScale] GetLBNEntries_IGNORE(string device, variable sweepNo, variable headstage) WAVE numericalValues = GetLBNumericalValues(device) @@ -33,6 +33,7 @@ static Function [WAVE/Z deltaI, WAVE/Z deltaV, WAVE/Z resistance, WAVE/Z resista WAVE/Z resistance = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT, headstage, UNKNOWN_MODE) WAVE/Z resistanceErr = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT_ERR, headstage, UNKNOWN_MODE) WAVE/Z autobiasFromDialog = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_AUTOBIAS_TARGET_DIAG, headstage, UNKNOWN_MODE) + WAVE/Z outOfRangeDAScale = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_DASCALE_OUT_OF_RANGE, headstage, UNKNOWN_MODE) End static Function RTV_Works_preAcq(string device) @@ -56,13 +57,14 @@ static Function RTV_Works_REENTRY([string str]) sweepNo = AFH_GetLastSweepAcquired(str) CHECK_EQUAL_VAR(sweepNo, 5) - [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, sweepNo, 1) + [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog, WAVE outOfRangeDAScale] = GetLBNEntries_IGNORE(str, sweepNo, 1) CHECK_WAVE(deltaI, NUMERIC_WAVE) CHECK_WAVE(deltaV, NUMERIC_WAVE) CHECK_WAVE(resistance, NUMERIC_WAVE) CHECK_WAVE(resistanceErr, NUMERIC_WAVE) CHECK_WAVE(autobiasFromDialog, NULL_WAVE) + CHECK_WAVE(outOfRangeDAScale, NUMERIC_WAVE) End static Function RTV_WorksWithIndexing_preAcq(string device) @@ -87,13 +89,14 @@ static Function RTV_WorksWithIndexing_REENTRY([string str]) sweepNo = AFH_GetLastSweepAcquired(str) CHECK_EQUAL_VAR(sweepNo, 6) - [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, 0, 1) + [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog, WAVE outOfRangeDAScale] = GetLBNEntries_IGNORE(str, 0, 1) CHECK_WAVE(deltaI, NUMERIC_WAVE) CHECK_WAVE(deltaV, NUMERIC_WAVE) CHECK_WAVE(resistance, NUMERIC_WAVE) CHECK_WAVE(resistanceErr, NUMERIC_WAVE) CHECK_WAVE(autobiasFromDialog, NUMERIC_WAVE) + CHECK_WAVE(outOfRangeDAScale, NUMERIC_WAVE) CHECK_EQUAL_WAVES(autobiasFromDialog, {-69, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA) CHECK_EQUAL_VAR(GetSetVariable(str, "setvar_DataAcq_AutoBiasV"), -69) @@ -135,7 +138,7 @@ static Function RTV_WorksWithMultipleHeadstages_REENTRY([string str]) sweepNo = AFH_GetLastSweepAcquired(str) CHECK_EQUAL_VAR(sweepNo, 5) - [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, sweepNo, 1) + [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog, WAVE outOfRangeDAScale] = GetLBNEntries_IGNORE(str, sweepNo, 1) CHECK_WAVE(deltaI, NUMERIC_WAVE) CHECK_WAVE(deltaV, NUMERIC_WAVE) @@ -143,7 +146,7 @@ static Function RTV_WorksWithMultipleHeadstages_REENTRY([string str]) CHECK_WAVE(resistanceErr, NUMERIC_WAVE) CHECK_WAVE(autobiasFromDialog, NULL_WAVE) - [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, sweepNo, 2) + [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog, WAVE outOfRangeDAScale] = GetLBNEntries_IGNORE(str, sweepNo, 2) CHECK_WAVE(deltaI, NUMERIC_WAVE) CHECK_WAVE(deltaV, NUMERIC_WAVE) @@ -151,3 +154,38 @@ static Function RTV_WorksWithMultipleHeadstages_REENTRY([string str]) CHECK_WAVE(resistanceErr, NUMERIC_WAVE) CHECK_WAVE(autobiasFromDialog, NULL_WAVE) End + +static Function RTV_ReportsDAScaleOutOfRange_preAcq(string device) + + AFH_AddAnalysisParameter("ReachTargetVoltage_DA_0", "EnableIndexing", var = 0) +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function RTV_ReportsDAScaleOutOfRange([string str]) + + WAVE overrideResults = MIES_AF#CreateOverrideResults() + + overrideResults[1] = 3e-6 // MOhm + + [STRUCT DAQSettings s] = PS_GetDAQSettings(str) + AcquireData_NG(s, str) +End + +static Function RTV_ReportsDAScaleOutOfRange_REENTRY([string str]) + + variable sweepNo + + CHECK_EQUAL_VAR(GetSetVariable(str, "SetVar_Sweep"), 2) + + sweepNo = AFH_GetLastSweepAcquired(str) + CHECK_EQUAL_VAR(sweepNo, 1) + + [WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog, WAVE outOfRangeDAScale] = GetLBNEntries_IGNORE(str, sweepNo, 1) + + CHECK_WAVE(deltaI, NUMERIC_WAVE) + CHECK_WAVE(deltaV, NUMERIC_WAVE) + CHECK_WAVE(resistance, NUMERIC_WAVE) + // we don't care about resistanceErr as we overwrote the resistance + CHECK_WAVE(autobiasFromDialog, NULL_WAVE) + CHECK_WAVE(outOfRangeDAScale, NUMERIC_WAVE) +End From 628c1ea49d945a81383cd108f8007a689bad032e Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:51:44 +0200 Subject: [PATCH 07/17] SC_SpikeControl: Add support for DAScale limit checks --- .../MIES/MIES_AnalysisFunctions_Dashboard.ipf | 10 ++ .../MIES_AnalysisFunctions_MultiPatchSeq.ipf | 2 +- ...isFunctions_MultiPatchSeq_SpikeControl.ipf | 55 +++++--- .../UTF_MultiPatchSeqSpikeControl.ipf | 123 +++++++++++++++++- 4 files changed, 171 insertions(+), 19 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf index 9bd099fc1a..b97e734e38 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf @@ -9,6 +9,8 @@ /// @file MIES_AnalysisFunctions_Dashboard.ipf /// @brief __AD__ Dashboard for pass/fail style analysis functions +static StrConstant AD_OOR_DASCALE_MSG = "Failure as the future DAScale would be out of range" + /// @brief Update the dashboards of all databrowsers Function AD_UpdateAllDatabrowser() @@ -102,6 +104,7 @@ static Function/S AD_GetResultMessage(variable anaFuncType, variable passed, WAV // - MSQ_FMT_LBN_RERUN_TRIALS_EXC present // - Spike counts state // - Spontaneous spiking check + // - Out of range DAScale // - Not enough sweeps // PSQ_AR @@ -622,6 +625,13 @@ static Function/S AD_GetSpikeControlFailMsg(WAVE numericalValues, WAVE textualVa return "Maximum number of rerun trials exceeded" endif + key = CreateAnaFuncLBNKey(SC_SPIKE_CONTROL, MSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDASCale = GetLastSettingEachSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE) + + if(AD_LabnotebookEntryExistsAndIsTrue(oorDASCale)) + return AD_OOR_DASCALE_MSG + endif + return "Failure as we ran out of sweeps" End diff --git a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf index 3e85524529..c2420eb027 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf @@ -424,7 +424,7 @@ End /// Searches in the complete SCI and assumes that the entries are either 0/1/NaN. /// /// @todo merge with LBN functions once these are reworked. -static Function MSQ_GetLBNEntryForHSSCIBool(WAVE numericalValues, variable sweepNo, variable type, string str, variable headstage) +Function MSQ_GetLBNEntryForHSSCIBool(WAVE numericalValues, variable sweepNo, variable type, string str, variable headstage) string key diff --git a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq_SpikeControl.ipf b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq_SpikeControl.ipf index 546066919a..8b3c930b5f 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq_SpikeControl.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq_SpikeControl.ipf @@ -151,10 +151,11 @@ End /// @brief Return pass/fail state of the sweep /// -/// This is true iff we have for the current stimulus set sweep count a passing headstage +/// This is true iff we have for the current stimulus set sweep count a passing +/// headstage and did not have a SetDAScale/SetDAScaleModOp out-of-range condition. static Function SC_GetSweepPassed(string device, variable sweepNo) - variable setSweepCount + variable setSweepCount, setSweepQC WAVE headstageQCTotalPerSweepCount = SC_GetHeadstageQCForSetCount(device, sweepNo) @@ -162,8 +163,12 @@ static Function SC_GetSweepPassed(string device, variable sweepNo) setSweepCount = SC_GetSetSweepCount(numericalValues, sweepNo) FindValue/RMD=[][setSweepCount]/V=(0.0) headstageQCTotalPerSweepCount + setSweepQC = (V_Value == -1) - return V_Value == -1 + Make/N=(NUM_HEADSTAGES)/FREE DAScaleOOR = MSQ_GetLBNEntryForHSSCIBool(numericalValues, sweepNo, \ + SC_SPIKE_CONTROL, MSQ_FMT_LBN_DASCALE_OOR, p) + + return setSweepQC && Sum(DAScaleOOR) == 0 End /// @brief Given a list of pulses by their indizes, this function return only the diagonal @@ -689,6 +694,7 @@ End static Function SC_ReactToQCFailures(string device, variable sweepNo, string params) variable daScaleSpikePositionModifier, daScaleModifier, daScaleTooManySpikesModifier, i, autoBiasV, autobiasModifier, prevSliderPos + variable limitCheck string daScaleOperator, daScaleSpikePositionOperator, daScaleTooManySpikesOperator string key, msg @@ -705,6 +711,8 @@ static Function SC_ReactToQCFailures(string device, variable sweepNo, string par WAVE textualValues = GetLBTextualValues(device) WAVE statusHS = DAG_GetActiveHeadstages(device, I_CLAMP_MODE) + WAVE oorDAScale = LBN_GetNumericWave() + key = CreateAnaFuncLBNKey(SC_SPIKE_CONTROL, MSQ_FMT_LBN_SPIKE_COUNTS_STATE, query = 1) WAVE/T spikeCountStateLBN = GetLastSetting(textualValues, sweepNo, key, UNKNOWN_MODE) @@ -724,11 +732,13 @@ static Function SC_ReactToQCFailures(string device, variable sweepNo, string par continue endif + limitCheck = !AFH_LastSweepInSet(device, sweepNo, i, POST_SWEEP_EVENT) + if(headstageQCLBN[i]) if(!spikePositionsQCLBN[i]) sprintf msg, "spike position QC failed on HS%d, adapting DAScale", i DebugPrint(msg) - SetDAScaleModOp(device, sweepNo, i, daScaleSpikePositionModifier, daScaleSpikePositionOperator) + oorDAScale[i] = SetDAScaleModOp(device, sweepNo, i, daScaleSpikePositionModifier, daScaleSpikePositionOperator, limitCheck = limitCheck) endif continue @@ -752,7 +762,7 @@ static Function SC_ReactToQCFailures(string device, variable sweepNo, string par strswitch(spikeCountStateLBN[i]) case SC_SPIKE_COUNT_STATE_STR_TOO_MANY: - SetDAScaleModOp(device, sweepNo, i, daScaleTooManySpikesModifier, daScaleTooManySpikesOperator) + oorDAScale[i] = SetDAScaleModOp(device, sweepNo, i, daScaleTooManySpikesModifier, daScaleTooManySpikesOperator, limitCheck = limitCheck) break case SC_SPIKE_COUNT_STATE_STR_MIXED: printf "The spike count on headstage %d in sweep %d is mixed (some pulses have too few, others too many)\n", i, sweepNo @@ -766,7 +776,7 @@ static Function SC_ReactToQCFailures(string device, variable sweepNo, string par ControlWindowToFront() endif case SC_SPIKE_COUNT_STATE_STR_TOO_FEW: // fallthrough-by-design - SetDAScaleModOp(device, sweepNo, i, daScaleModifier, daScaleOperator) + oorDAScale[i] = SetDAScaleModOp(device, sweepNo, i, daScaleModifier, daScaleOperator, limitCheck = limitCheck) break case SC_SPIKE_COUNT_STATE_STR_GOOD: // nothing to do @@ -780,6 +790,8 @@ static Function SC_ReactToQCFailures(string device, variable sweepNo, string par if(prevSliderPos != GetSliderPositionIndex(device, "slider_DataAcq_ActiveHeadstage")) PGC_SetAndActivateControl(device, "slider_DataAcq_ActiveHeadstage", val = prevSliderPos) endif + + ReportOutOfRangeDAScale(device, sweepNo, SC_SPIKE_CONTROL, oorDAScale) End Function/S SC_SpikeControl_GetParams() @@ -1096,17 +1108,10 @@ Function SC_SpikeControl(string device, STRUCT AnalysisFunction_V3 &s) SC_ProcessPulses(device, s.sweepNo, minimumSpikePosition, idealNumberOfSpikes) - // sweep QC - sweepPassed = SC_GetSweepPassed(device, s.sweepNo) - - WAVE sweepQCLBN = LBN_GetNumericWave() - sweepQCLBN[INDEP_HEADSTAGE] = sweepPassed - key = CreateAnaFuncLBNKey(SC_SPIKE_CONTROL, MSQ_FMT_LBN_SWEEP_PASS) - ED_AddEntryToLabnotebook(device, key, sweepQCLBN, unit = LABNOTEBOOK_BINARY_UNIT) - [minTrials, maxTrials] = SC_GetTrials(device, s.sweepNo, s.headstage) - SC_ReactToQCFailures(device, s.sweepNo, s.params) + // sweep QC + sweepPassed = SC_GetSweepPassed(device, s.sweepNo) if(!sweepPassed) if(SC_CanStillSkip(maxTrials, s.params)) @@ -1117,6 +1122,17 @@ Function SC_SpikeControl(string device, STRUCT AnalysisFunction_V3 &s) endif endif + // needs to take sweep skipping into account + SC_ReactToQCFailures(device, s.sweepNo, s.params) + + // and maybe we had a DASCale out of range so sweepPassed has changed + sweepPassed = SC_GetSweepPassed(device, s.sweepNo) + + WAVE sweepQCLBN = LBN_GetNumericWave() + sweepQCLBN[INDEP_HEADSTAGE] = sweepPassed + key = CreateAnaFuncLBNKey(SC_SPIKE_CONTROL, MSQ_FMT_LBN_SWEEP_PASS) + ED_AddEntryToLabnotebook(device, key, sweepQCLBN, unit = LABNOTEBOOK_BINARY_UNIT) + WAVE statusHS = DAG_GetActiveHeadstages(device, I_CLAMP_MODE) WAVE rerunExceeded = LBN_GetNumericWave() @@ -1135,8 +1151,13 @@ Function SC_SpikeControl(string device, STRUCT AnalysisFunction_V3 &s) // work around broken XXX_SET_EVENT // we are done and were not successful else - // still some trials left - setPassed = NaN + Make/N=(NUM_HEADSTAGES)/FREE DAScaleOOR = MSQ_GetLBNEntryForHSSCIBool(numericalValues, s.sweepNo, \ + SC_SPIKE_CONTROL, MSQ_FMT_LBN_DASCALE_OOR, p) + + if(Sum(DAScaleOOR) == 0) + // still some trials left + setPassed = NaN + endif endif endif diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqSpikeControl.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqSpikeControl.ipf index b0b575f380..99433c4930 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqSpikeControl.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqSpikeControl.ipf @@ -81,7 +81,7 @@ static Function/WAVE GetLBNEntriesWave_IGNORE() + "rerunTrials_HS0;rerunTrials_HS1;rerunTrialsExceeded_HS0;rerunTrialsExceeded_HS1;" \ + "spikeCounts_HS0;spikeCounts_HS1;spikeCountsState_HS0;spikeCountsState_HS1;" \ + "spikePositions_HS0;spikePositions_HS1;spikePositionQC_HS0;spikePositionQC_HS1;spontSpikeQC_HS0;spontSpikeQC_HS1;" \ - + "autoBiasV_HS0;autoBiasV_HS1;" + + "autoBiasV_HS0;autoBiasV_HS1;DAScaleOutOfRange_HS0;DAScaleOutOfRange_HS1;" Make/FREE/WAVE/N=(ItemsInList(list)) wv SetDimensionLabels(wv, list, ROWS) @@ -135,6 +135,9 @@ static Function/WAVE GetLBNEntries_IGNORE(string device, variable sweepNo) wv[%autoBiasV_HS0] = GetLastSettingEachSCI(numericalValues, sweepNo, "Autobias Vcom", 0, DATA_ACQUISITION_MODE) wv[%autoBiasV_HS1] = GetLastSettingEachSCI(numericalValues, sweepNo, "Autobias Vcom", 1, DATA_ACQUISITION_MODE) + wv[%DAScaleOutOfRange_HS0] = GetLBNSingleEntry_IGNORE(device, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + wv[%DAScaleOutOfRange_HS1] = GetLBNSingleEntry_IGNORE(device, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + return wv End @@ -223,6 +226,9 @@ static Function SC_Test1_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 0, 0, 0}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS1], {0, 0, 0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS0], {0, 0, 0, NaN}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS1], {0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -309,6 +315,9 @@ static Function SC_Test2_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 0}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS1], {0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS0], {0, NaN}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS1], {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End @@ -404,6 +413,9 @@ static Function SC_Test3_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 0}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS1], {0, 0}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%DAScaleOutOfRange_HS0], NULL_WAVE) + CHECK_WAVE(lbnEntries[%DAScaleOutOfRange_HS1], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End @@ -499,6 +511,9 @@ static Function SC_Test4_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 0}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS1], {0, 0}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%DAScaleOutOfRange_HS0], NULL_WAVE) + CHECK_WAVE(lbnEntries[%DAScaleOutOfRange_HS1], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End @@ -595,6 +610,9 @@ static Function SC_Test5_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 10, 20, 30}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS1], {0, 10, 20, 30}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%DAScaleOutOfRange_HS0], NULL_WAVE) + CHECK_WAVE(lbnEntries[%DAScaleOutOfRange_HS1], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -681,6 +699,9 @@ static Function SC_Test6_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 0}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS1], {0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS0], {0, NaN}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS1], {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End @@ -800,6 +821,9 @@ static Function SC_Test7_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 0, 0, 0}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS1], {0, 0, 0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS0], {0, 0, 0, NaN}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS1], {0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -938,6 +962,9 @@ static Function SC_Test8_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 0, 0, 0}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS1], {0, 0, 0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS0], {0, 0, 0, NaN}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS1], {0, 0, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End @@ -1027,5 +1054,99 @@ static Function SC_Test9_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 0}, mode = WAVE_DATA) CHECK_WAVE(lbnEntries[%autoBiasV_HS1], NULL_WAVE) + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS0], {0, NaN}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%DAScaleOutOfRange_HS1], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End + +static Function SC_Test10_preInit(string device) + + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "DAScaleModifier", var = 2500) + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "DAScaleOperator", str = "+") + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "MaxTrials", var = 3) + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "DAScaleSpikePositionModifier", var = 3) + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "DAScaleSpikePositionOperator", str = "*") + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "MinimumSpikePosition", var = 50) + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "AutoBiasBaselineModifier", var = 10) + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "FailedPulseLevel", var = 1) + AFH_AddAnalysisParameter("SC_SpikeControl_DA_0", "IdealNumberOfSpikesPerPulse", var = 1) +End + +static Function SC_Test10_preAcq(string device) + + PGC_SetAndActivateControl(device, DAP_GetClampModeControl(V_CLAMP_MODE, 1), val = 1) +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function SC_Test10([string str]) + + [STRUCT DAQSettings s] = MSQ_GetDAQSettings(str) + AcquireData_NG(s, str) + + WAVE/T wv = MSQ_CreateOverrideResults(str, 0, SC_SPIKE_CONTROL) + + // SPF: spike position fails + + // [sweep][headstage][pulse][region] + + // all sweeps, HS0: Too few (SPF) + // all sweeps, HS1: Good (SPF) + + wv[][0][][0, 1] = "" // no spike + wv[][1][][0, 1] = "SpikePosition_ms:4" +End + +static Function SC_Test10_REENTRY([string str]) + + variable sweepNo, autobiasV + string lbl, failedPulses, spikeCounts, spikePos + + sweepNo = 1 + + WAVE/WAVE lbnEntries = GetLBNEntries_IGNORE(str, sweepNo) + + CHECK_EQUAL_WAVES(lbnEntries[%setPass], {0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%sweepPass], {0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%idealSpikeCounts], {1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%failedPulseLevel], {1}, mode = WAVE_DATA) + + CHECK_EQUAL_WAVES(lbnEntries[%headstagePass_HS0], {0, 0}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%headstagePass_HS1], NULL_WAVE) + + CHECK_EQUAL_WAVES(lbnEntries[%setSweepCount_HS0], {0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%setSweepCount_HS1], {0, 0}, mode = WAVE_DATA) + + CHECK_EQUAL_WAVES(lbnEntries[%rerunTrials_HS0], {0, 1}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%rerunTrials_HS1], NULL_WAVE) + + CHECK_EQUAL_WAVES(lbnEntries[%rerunTrialsExceeded_HS0], {0, 0}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%rerunTrialsExceeded_HS1], NULL_WAVE) + + spikeCounts = "P0_R0:0,;P1_R0:0,;P2_R0:0,;P3_R0:0,;P4_R0:0,;P5_R0:0,;P6_R0:0,;P7_R0:0,;P8_R0:0,;P9_R0:0,;" + CHECK_EQUAL_TEXTWAVES(lbnEntries[%spikeCounts_HS0], {spikeCounts, spikeCounts}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%spikeCounts_HS1], NULL_WAVE) + + CHECK_WAVE(lbnEntries[%spikePositions_HS0], NULL_WAVE) + CHECK_WAVE(lbnEntries[%spikePositions_HS1], NULL_WAVE) + + CHECK_EQUAL_TEXTWAVES(lbnEntries[%spikeCountsState_HS0], {SC_SPIKE_COUNT_STATE_STR_TOO_FEW, SC_SPIKE_COUNT_STATE_STR_TOO_FEW}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%spikeCountsState_HS1], NULL_WAVE) + + CHECK_EQUAL_WAVES(lbnEntries[%spikePositionQC_HS0], {0, 0}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%spikePositionQC_HS1], NULL_WAVE) + + CHECK_EQUAL_WAVES(lbnEntries[%spontSpikeQC_HS0], {0, 0}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%spontSpikeQC_HS1], NULL_WAVE) + + CHECK_EQUAL_WAVES(lbnEntries[%stimScale_HS0], {1, 2501}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%stimScale_HS1], {1, 1}, mode = WAVE_DATA) + + CHECK_EQUAL_WAVES(lbnEntries[%autoBiasV_HS0], {0, 10}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%autoBiasV_HS1], NULL_WAVE) + + CHECK_EQUAL_WAVES(lbnEntries[%DAScaleOutOfRange_HS0], {0, 1}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%DAScaleOutOfRange_HS1], NULL_WAVE) + + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) +End From 48ec217763f6f148e0b4da0698faf2ddd18f87a4 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:52:38 +0200 Subject: [PATCH 08/17] PSQ_Ramp: Add support for DAScale limit checks --- Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf index 6e1c3025c5..19d41eda86 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf @@ -5146,7 +5146,7 @@ Function PSQ_Ramp(string device, STRUCT AnalysisFunction_V3 &s) PGC_SetAndActivateControl(device, "check_Settings_ITITP", val = 1) PGC_SetAndActivateControl(device, "Check_Settings_InsertTP", val = 1) - SetDAScale(device, s.sweepNo, s.headstage, absolute = PSQ_RA_DASCALE_DEFAULT * PICO_TO_ONE) + SetDAScale(device, s.sweepNo, s.headstage, absolute = PSQ_RA_DASCALE_DEFAULT * PICO_TO_ONE, limitCheck = 0) return 0 From 4c00f3f8cf3a81b6b5f064651cb3cb2cba7eb8c0 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:52:38 +0200 Subject: [PATCH 09/17] MSQ_FastRheoEst: Add support for DAScale limit checks --- .../MIES/MIES_AnalysisFunctions_Dashboard.ipf | 10 +- .../MIES_AnalysisFunctions_MultiPatchSeq.ipf | 25 ++- .../UTF_MultiPatchSeqFastRheoEstimate.ipf | 178 ++++++++++++++++++ 3 files changed, 205 insertions(+), 8 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf index b97e734e38..d840c9b464 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf @@ -98,14 +98,15 @@ static Function/S AD_GetResultMessage(variable anaFuncType, variable passed, WAV // MSQ_FRE // - MSQ_FMT_LBN_DASCALE_EXC present (optional) + // - Out of range DAScale // - Not enough sweeps // MSQ_SC // - MSQ_FMT_LBN_RERUN_TRIALS_EXC present // - Spike counts state // - Spontaneous spiking check - // - Out of range DAScale // - Not enough sweeps + // - Out of range DAScale // PSQ_AR // - baseline QC @@ -611,6 +612,13 @@ static Function/S AD_GetFastRheoEstFailMsg(WAVE numericalValues, variable sweepN return "Max DA scale exceeded failure" endif + key = CreateAnaFuncLBNKey(MSQ_FAST_RHEO_EST, MSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDASCale = GetLastSettingEachSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE) + + if(AD_LabnotebookEntryExistsAndIsTrue(oorDASCale)) + return AD_OOR_DASCALE_MSG + endif + return "Failure as we ran out of sweeps" End diff --git a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf index c2420eb027..112a399bc9 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf @@ -571,7 +571,7 @@ End /// @endverbatim Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) - variable totalOnsetDelay, setPassed, sweepPassed, multiplier, newDAScaleValue, found, val + variable totalOnsetDelay, setPassed, sweepPassed, multiplier, newDAScaleValue, found, val, limitCheck variable i, postDAQDAScale, postDAQDAScaleFactor, DAC, maxDAScale, allHeadstagesExceeded, minRheoOffset string key, msg, ctrl string stimsets = "" @@ -634,7 +634,7 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) continue endif - SetDAScale(device, s.sweepNo, i, absolute = MSQ_FRE_INIT_AMP_p100) + SetDAScale(device, s.sweepNo, i, absolute = MSQ_FRE_INIT_AMP_p100, limitCheck = 0) endfor PGC_SetAndActivateControl(device, "Check_DataAcq1_DistribDaq", val = 0) @@ -687,6 +687,7 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) WAVE headstagePassed = LBN_GetNumericWave() WAVE finalDAScale = LBN_GetNumericWave() WAVE rangeExceededNew = LBN_GetNumericWave() + WAVE oorDAScale = LBN_GetNumericWave() key = CreateAnaFuncLBNKey(MSQ_FAST_RHEO_EST, MSQ_FMT_LBN_STEPSIZE, query = 1) WAVE stepSize = GetLastSettingSCI(numericalValues, s.sweepNo, key, s.headstage, UNKNOWN_MODE) @@ -760,10 +761,13 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) ASSERT(headstagePassed[i] != 1, "Unexpected headstage passing") headstagePassed[i] = 0 else - SetDAScale(device, s.sweepNo, i, absolute = newDAScaleValue) + limitCheck = !AFH_LastSweepInSet(device, s.sweepNo, s.headstage, s.eventType) + oorDAScale[i] = SetDAScale(device, s.sweepNo, i, absolute = newDAScaleValue, limitCheck = limitCheck) endif endfor + ReportOutOfRangeDAScale(device, s.sweepNo, MSQ_FAST_RHEO_EST, oorDAScale) + key = CreateAnaFuncLBNKey(MSQ_FAST_RHEO_EST, MSQ_FMT_LBN_SPIKE_DETECT) ED_AddEntryToLabnotebook(device, key, spikeDetection, unit = LABNOTEBOOK_BINARY_UNIT) @@ -795,8 +799,9 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) totalRangeExceeded[i] = MSQ_GetLBNEntryForHSSCIBool(numericalValues, s.sweepNo, MSQ_FAST_RHEO_EST, \ MSQ_FMT_LBN_DASCALE_EXC, i) - sweepPassed = sweepPassed && MSQ_GetLBNEntryForHSSCIBool(numericalValues, s.sweepNo, MSQ_FAST_RHEO_EST, \ - MSQ_FMT_LBN_HEADSTAGE_PASS, i) + sweepPassed = sweepPassed \ + && MSQ_GetLBNEntryForHSSCIBool(numericalValues, s.sweepNo, MSQ_FAST_RHEO_EST, MSQ_FMT_LBN_HEADSTAGE_PASS, i) \ + && !MSQ_GetLBNEntryForHSSCIBool(numericalValues, s.sweepNo, MSQ_FAST_RHEO_EST, MSQ_FMT_LBN_DASCALE_OOR, i) endfor allHeadstagesExceeded = Sum(totalRangeExceeded) == Sum(statusHSIC) @@ -826,8 +831,13 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) PGC_SetAndActivateControl(device, "Check_Settings_InsertTP", val = 1) WAVE numericalValues = GetLBNumericalValues(device) + + Make/N=(NUM_HEADSTAGES)/FREE oorDAScale = MSQ_GetLBNEntryForHSSCIBool(numericalValues, s.sweepNo, \ + MSQ_DA_SCALE, MSQ_FMT_LBN_DASCALE_OOR, p) + // assuming that all headstages have the same sweeps in their SCI - setPassed = MSQ_NumPassesInSet(numericalValues, MSQ_FAST_RHEO_EST, s.sweepNo, s.headstage) >= 1 + setPassed = MSQ_NumPassesInSet(numericalValues, MSQ_FAST_RHEO_EST, s.sweepNo, s.headstage) >= 1 \ + && Sum(oorDAScale) == 0 sprintf msg, "Set has %s\r", ToPassFail(setPassed) DEBUGPRINT(msg) @@ -862,7 +872,8 @@ Function MSQ_FastRheoEst(string device, STRUCT AnalysisFunction_V3 &s) val = AFH_GetAnalysisParamNumerical("PostDAQDAScaleForFailedHS", s.params) * PICO_TO_ONE endif - SetDAScale(device, s.sweepNo, i, absolute = val) + // we can't check this here, as we don't know the next stimset + SetDAScale(device, s.sweepNo, i, absolute = val, limitCheck = 0) endfor endif diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqFastRheoEstimate.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqFastRheoEstimate.ipf index 913f1f8942..3801149eca 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqFastRheoEstimate.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqFastRheoEstimate.ipf @@ -134,6 +134,12 @@ static Function MSQ_FRE1_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -223,6 +229,12 @@ static Function MSQ_FRE2_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -310,6 +322,12 @@ static Function MSQ_FRE3_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -402,6 +420,12 @@ static Function MSQ_FRE4_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -500,6 +524,12 @@ static Function MSQ_FRE5_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End @@ -592,6 +622,12 @@ static Function MSQ_FRE6_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 0, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_WAVE(oorDAScale, NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End @@ -703,6 +739,12 @@ static Function MSQ_FRE7_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End @@ -805,6 +847,12 @@ static Function MSQ_FRE8_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -901,6 +949,12 @@ static Function MSQ_FRE9_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, NaN}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) End @@ -1007,5 +1061,129 @@ static Function MSQ_FRE10_REENTRY([string str]) WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0}, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {1, 1}) End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function MSQ_FRE11([string str]) + + ST_SetStimsetParameter("MSQ_FastRheoEst_DA_0", "Total number of steps", var = 50) + + [STRUCT DAQSettings s] = MSQ_GetDAQSettings(str) + AcquireData_NG(s, str) + + WAVE wv = MSQ_CreateOverrideResults(str, 0, MSQ_FAST_RHEO_EST) + // all tests fail + wv = 0 +End + +static Function MSQ_FRE11_REENTRY([string str]) + + variable sweepNo, numEntries + string lbl + +#ifdef TESTS_WITH_NI_HARDWARE + sweepNo = 38 +#else + sweepNo = 39 +#endif + + numEntries = sweepNo + 1 + + WAVE numericalValues = GetLBNumericalValues(str) + + WAVE/Z setPass = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_SET_PASS, NaN, INDEP) + CHECK_EQUAL_WAVES(setPass, {0}, mode = WAVE_DATA) + + Make/FREE/D/N=(numEntries) sweepPassRef = 0 + + WAVE/Z sweepPass = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_SWEEP_PASS, 0, INDEP_EACH_SCI) + CHECK_EQUAL_WAVES(sweepPass, sweepPassRef, mode = WAVE_DATA) + + WAVE/Z sweepPass = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_SWEEP_PASS, 1, INDEP_EACH_SCI) + CHECK_EQUAL_WAVES(sweepPass, sweepPassRef, mode = WAVE_DATA) + + Make/FREE/D/N=(numEntries) headstagePassRef = 0 + + WAVE/Z headstagePass = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_HEADSTAGE_PASS, 0, EACH_SCI) + CHECK_EQUAL_WAVES(headstagePass, headstagePassRef, mode = WAVE_DATA) + + WAVE/Z headstagePass = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_HEADSTAGE_PASS, 1, EACH_SCI) + CHECK_EQUAL_WAVES(headstagePass, headstagePassRef, mode = WAVE_DATA) + + Make/FREE/D/N=(numEntries) spikeDetectionWaveRef = 0 + + WAVE/Z spikeDetectionWave = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_SPIKE_DETECT, 0, EACH_SCI) + CHECK_EQUAL_WAVES(spikeDetectionWave, spikeDetectionWaveRef, mode = WAVE_DATA) + + WAVE/Z spikeDetectionWave = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_SPIKE_DETECT, 1, EACH_SCI) + CHECK_EQUAL_WAVES(spikeDetectionWave, spikeDetectionWaveRef, mode = WAVE_DATA) + + Make/FREE/D/N=(numEntries) stimScaleRef = 100 * (p + 1) + + WAVE/Z stimScale = GetLastSettingEachSCI(numericalValues, sweepNo, STIMSET_SCALE_FACTOR_KEY, 0, UNKNOWN_MODE) + CHECK_EQUAL_WAVES(stimScale, stimScaleRef, mode = WAVE_DATA, tol = 1e-10) + + WAVE/Z stimScale = GetLastSettingEachSCI(numericalValues, sweepNo, STIMSET_SCALE_FACTOR_KEY, 1, UNKNOWN_MODE) + CHECK_EQUAL_WAVES(stimScale, stimScaleRef, mode = WAVE_DATA, tol = 1e-10) + + Make/FREE/D/N=(numEntries) stepSizesRef = 100 + + WAVE/Z stepsizes = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_STEPSIZE, 0, EACH_SCI) + stepsizes *= ONE_TO_PICO + CHECK_EQUAL_WAVES(stepsizes, stepSizesRef, mode = WAVE_DATA) + + WAVE/Z stepsizes = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_STEPSIZE, 1, EACH_SCI) + stepsizes *= ONE_TO_PICO + CHECK_EQUAL_WAVES(stepsizes, stepSizesRef, mode = WAVE_DATA) + + WAVE/Z activeHS = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_ACTIVE_HS, 0, SINGLE_SCI) + CHECK_EQUAL_WAVES(activeHS, {1, 1, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + WAVE/Z statusHS = DAG_GetChannelState(str, CHANNEL_TYPE_HEADSTAGE) + WaveTransform/O zapNaNs, activeHS + CHECK_EQUAL_WAVES(activeHS, statusHS, mode = WAVE_DATA) + + Make/FREE/D/N=(numEntries) rangeExceededRef = NaN + + rangeExceededRef[0] = 0 + + WAVE/Z rangeExceeded = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_EXC, 0, EACH_SCI) + CHECK_EQUAL_WAVES(rangeExceeded, rangeExceededRef, mode = WAVE_DATA) + + WAVE/Z rangeExceeded = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_EXC, 1, EACH_SCI) + CHECK_EQUAL_WAVES(rangeExceeded, rangeExceededRef, mode = WAVE_DATA) + + WAVE/Z finalDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_FINAL_SCALE, 0, EACH_SCI) + CHECK_WAVE(finalDAScale, NULL_WAVE) + + lbl = GetSpecialControlLabel(CHANNEL_TYPE_DAC, CHANNEL_CONTROL_SCALE) + CHECK_CLOSE_VAR(DAG_GetNumericalValue(str, lbl, index = 0), Sum(stepSizesRef)) + + lbl = GetSpecialControlLabel(CHANNEL_TYPE_DAC, CHANNEL_CONTROL_SCALE) + CHECK_CLOSE_VAR(DAG_GetNumericalValue(str, lbl, index = 1), Sum(stepSizesRef)) + + WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 0, SINGLE_SCI) + CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + + WAVE/Z pulseDuration = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_PULSE_DUR, 1, SINGLE_SCI) + CHECK_EQUAL_WAVES(pulseDuration, {3, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-8) + + Make/FREE/D/N=(numEntries) oorDAScaleRef = 0 + + oorDAScaleRef[numEntries - 1] = 1 + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, oorDAScaleRef, mode = WAVE_DATA) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(str, sweepNo, MSQ_FMT_LBN_DASCALE_OOR, 1, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, oorDAScaleRef, mode = WAVE_DATA) + + CommonAnalysisFunctionChecks(str, sweepNo, {0, 0}) +End From d93abb8db2ee73c8f8e8fce120aa5d4bed9e4592 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:52:38 +0200 Subject: [PATCH 10/17] MSQ_DAScale: Add support for DAScale limit checks --- .../MIES/MIES_AnalysisFunctions_Dashboard.ipf | 20 ++++++- .../MIES_AnalysisFunctions_MultiPatchSeq.ipf | 60 ++++++++++++------- .../UTF_MultiPatchSeqDaScale.ipf | 39 ++++++++++++ 3 files changed, 96 insertions(+), 23 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf index d840c9b464..4969965e33 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf @@ -94,7 +94,7 @@ static Function/S AD_GetResultMessage(variable anaFuncType, variable passed, WAV endif // MSQ_DA - // - always passes + // - Out of range DAScale // MSQ_FRE // - MSQ_FMT_LBN_DASCALE_EXC present (optional) @@ -154,8 +154,7 @@ static Function/S AD_GetResultMessage(variable anaFuncType, variable passed, WAV switch(anaFuncType) case MSQ_DA_SCALE: - BUG("Unknown reason for failure") - return "Failure" + return AD_GetMultiDAScaleFailMsg(numericalValues, sweepNo, headstage) case MSQ_FAST_RHEO_EST: return AD_GetFastRheoEstFailMsg(numericalValues, sweepNo, headstage) case PSQ_ACC_RES_SMOKE: @@ -586,6 +585,21 @@ static Function/S AD_GetDAScaleFailMsg(WAVE numericalValues, WAVE/T textualValue return "Failure" End +static Function/S AD_GetMultiDAScaleFailMsg(WAVE numericalValues, variable sweepNo, variable headstage) + + string key + + key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDASCale = GetLastSettingEachSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE) + + if(AD_LabnotebookEntryExistsAndIsTrue(oorDASCale)) + return AD_OOR_DASCALE_MSG + endif + + BUG("Unknown reason for failure") + return "Failure" +End + static Function/S AD_GetRheobaseFailMsg(WAVE numericalValues, WAVE/T textualValues, variable sweepNo, DFREF sweepDFR, variable headstage) string key, prefix, msg, pattern diff --git a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf index 112a399bc9..e439b41b97 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_MultiPatchSeq.ipf @@ -1070,7 +1070,7 @@ End /// Function MSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) - variable i, index, ret, headstagePassed, val, sweepNo + variable i, index, ret, headstagePassed, val, sweepNo, limitCheck, sweepPassed string msg, key, ctrl switch(s.eventType) @@ -1154,32 +1154,19 @@ Function MSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) DisableControls(device, "Button_DataAcq_SkipBackwards;Button_DataAcq_SkipForward") break - case POST_SWEEP_EVENT: + case POST_SET_EVENT: if(!DAG_HeadstageIsHighestActive(device, s.headstage)) return NaN endif - WAVE values = LBN_GetNumericWave() - WAVE statusHSIC = DAG_GetActiveHeadstages(device, I_CLAMP_MODE) - values[0, NUM_HEADSTAGES - 1] = statusHSIC[p] ? 1 : NaN - key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_HEADSTAGE_PASS) - ED_AddEntryToLabnotebook(device, key, values, unit = LABNOTEBOOK_BINARY_UNIT) - - WAVE values = LBN_GetNumericWave() - values[INDEP_HEADSTAGE] = 1 - key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_SWEEP_PASS) - ED_AddEntryToLabnotebook(device, key, values, unit = LABNOTEBOOK_BINARY_UNIT) + WAVE numericalValues = GetLBNumericalValues(device) - break - case POST_SET_EVENT: - - if(!DAG_HeadstageIsHighestActive(device, s.headstage)) - return NaN - endif + key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_SWEEP_PASS, query = 1) + WAVE sweepPass = GetLastSettingIndepEachSCI(numericalValues, s.sweepNo, key, s.headstage, UNKNOWN_MODE) WAVE values = LBN_GetNumericWave() - values[INDEP_HEADSTAGE] = 1 + values[INDEP_HEADSTAGE] = IsNaN(GetRowIndex(sweepPass, val = 0)) key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_SET_PASS) ED_AddEntryToLabnotebook(device, key, values, unit = LABNOTEBOOK_BINARY_UNIT) @@ -1222,6 +1209,8 @@ Function MSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) WAVE statusHS = DAG_GetChannelState(device, CHANNEL_TYPE_HEADSTAGE) + WAVE oorDAScale = LBN_GetNumericWave() + for(i = 0; i < NUM_HEADSTAGES; i += 1) if(!statusHS[i]) continue @@ -1229,9 +1218,40 @@ Function MSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) index = mod(DAScalesIndex[i], DimSize(DAScales, ROWS)) + limitCheck = (s.eventType == POST_SWEEP_EVENT) && !AFH_LastSweepInSet(device, s.sweepNo, s.headstage, s.eventType) + ASSERT(isFinite(daScaleOffset[i]), "DAScale offset is non-finite") - SetDAScale(device, s.sweepNo, i, absolute = (DAScales[index] + daScaleOffset[i]) * PICO_TO_ONE) + oorDAScale[i] = SetDAScale(device, s.sweepNo, i, absolute = (DAScales[index] + daScaleOffset[i]) * PICO_TO_ONE, limitCheck = limitCheck) DAScalesIndex[i] += 1 endfor + + ReportOutOfRangeDAScale(device, s.sweepNo, MSQ_DA_SCALE, oorDAScale) + + if(s.eventType == POST_SWEEP_EVENT) + WAVE numericalValues = GetLBNumericalValues(device) + + Make/N=(NUM_HEADSTAGES)/FREE oorDAScale = MSQ_GetLBNEntryForHSSCIBool(numericalValues, s.sweepNo, \ + MSQ_DA_SCALE, MSQ_FMT_LBN_DASCALE_OOR, p) + + WAVE values = LBN_GetNumericWave() + WAVE statusHSIC = DAG_GetActiveHeadstages(device, I_CLAMP_MODE) + values[0, NUM_HEADSTAGES - 1] = statusHSIC[p] ? !oorDAScale[p] : NaN + key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_HEADSTAGE_PASS) + ED_AddEntryToLabnotebook(device, key, values, unit = LABNOTEBOOK_BINARY_UNIT) + + sweepPassed = Sum(oorDAScale) == 0 + + WAVE values = LBN_GetNumericWave() + values[INDEP_HEADSTAGE] = sweepPassed + key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_SWEEP_PASS) + ED_AddEntryToLabnotebook(device, key, values, unit = LABNOTEBOOK_BINARY_UNIT) + + if(!sweepPassed) + WAVE values = LBN_GetNumericWave() + values[INDEP_HEADSTAGE] = 0 + key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_SET_PASS) + ED_AddEntryToLabnotebook(device, key, values, unit = LABNOTEBOOK_BINARY_UNIT) + endif + endif endif End diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqDaScale.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqDaScale.ipf index 6dd3c6f843..0be3e454c7 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqDaScale.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_MultiPatchSeqDaScale.ipf @@ -83,5 +83,44 @@ static Function MSQ_DS1_REENTRY([string str]) WAVE/Z stimScale = GetLBNSingleEntry_IGNORE(sweepNo, str, STIMSET_SCALE_FACTOR_KEY, 0, EACH_SCI) CHECK_EQUAL_WAVES(stimScale, {33, 43, 53, 63, 73}, mode = WAVE_DATA) + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(sweepNo, str, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + CommonAnalysisFunctionChecks(str, sweepNo, setPass) +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function MSQ_DS2([string str]) + + AFH_AddAnalysisParameter("MSQ_DAScale_DA_0", "DAScales", wv = {1000, 1500, 2000, 3000, 5000}) + + [STRUCT DAQSettings s] = MSQ_GetDAQSettings(str) + AcquireData_NG(s, str) +End + +static Function MSQ_DS2_REENTRY([string str]) + + variable sweepNo + + sweepNo = 3 + + WAVE/Z headstageActive = GetLBNSingleEntry_IGNORE(sweepNo, str, MSQ_FMT_LBN_ACTIVE_HS, 0, SINGLE_SCI) + CHECK_EQUAL_WAVES(headstageActive, {1, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + WAVE/Z setPass = GetLBNSingleEntry_IGNORE(sweepNo, str, MSQ_FMT_LBN_SET_PASS, NaN, INDEP) + CHECK_EQUAL_WAVES(setPass, {0}, mode = WAVE_DATA) + + WAVE/Z sweepPass = GetLBNSingleEntry_IGNORE(sweepNo, str, MSQ_FMT_LBN_SWEEP_PASS, 0, INDEP_EACH_SCI) + CHECK_EQUAL_WAVES(sweepPass, {1, 1, 1, 0}, mode = WAVE_DATA) + + WAVE/Z headstagePass = GetLBNSingleEntry_IGNORE(sweepNo, str, MSQ_FMT_LBN_HEADSTAGE_PASS, 0, EACH_SCI) + CHECK_EQUAL_WAVES(headstagePass, {1, 1, 1, 0}, mode = WAVE_DATA) + + WAVE/Z stimScale = GetLBNSingleEntry_IGNORE(sweepNo, str, STIMSET_SCALE_FACTOR_KEY, 0, EACH_SCI) + CHECK_EQUAL_WAVES(stimScale, {1023, 1523, 2023, 3023}, mode = WAVE_DATA, tol = 1e-12) + + WAVE/Z oorDAScale = GetLBNSingleEntry_IGNORE(sweepNo, str, MSQ_FMT_LBN_DASCALE_OOR, 0, EACH_SCI) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 1}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPass) End From 5d5d85ccc59639d42c29e7e65079553331be7e6d Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:52:38 +0200 Subject: [PATCH 11/17] PSQ_DAScale: Add support for DAScale limit checks --- .../MIES/MIES_AnalysisFunctions_Dashboard.ipf | 8 + .../MIES/MIES_AnalysisFunctions_PatchSeq.ipf | 36 +++- .../UTF_PatchSeqDAScale_Adapt.ipf | 190 +++++++++++++++--- .../UTF_PatchSeqDAScale_Sub.ipf | 129 ++++++++++++ .../UTF_PatchSeqDAScale_Supra.ipf | 112 +++++++++++ 5 files changed, 444 insertions(+), 31 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf index 4969965e33..0ca838871e 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf @@ -120,6 +120,7 @@ static Function/S AD_GetResultMessage(variable anaFuncType, variable passed, WAV // PSQ_DA // - baseline QC + // - Out of range DAScale // - SUB/SUPRA: needs at least $NUM_DA_SCALES passing sweeps // - SUPRA: if the FinalSlopePercent parameter is present this has to be reached as well // - ADAPT: - fewer than $NumInvalidSlopeSweepsAllowed invalid f-I slopes @@ -496,6 +497,13 @@ static Function/S AD_GetDAScaleFailMsg(WAVE numericalValues, WAVE/T textualValue WAVE/T params = GetLastSettingTextSCI(numericalValues, textualValues, sweepNo, "Function params", headstage, DATA_ACQUISITION_MODE) endif + key = CreateAnaFuncLBNKey(MSQ_DA_SCALE, MSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDASCale = GetLastSettingEachSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE) + + if(AD_LabnotebookEntryExistsAndIsTrue(oorDASCale)) + return AD_OOR_DASCALE_MSG + endif + opMode = AFH_GetAnalysisParamTextual("OperationMode", params[headstage]) strswitch(opMode) diff --git a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf index 19d41eda86..aee7ab2a49 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf @@ -2671,6 +2671,15 @@ static Function PSQ_DS_AdaptiveDetermineSweepQCResults(string device, variable s return PSQ_RESULTS_DONE endif + key = CreateAnaFuncLBNKey(PSQ_DA_SCALE, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDAScale = GetLastSetting(numericalValues, sweepNo, key, UNKNOWN_MODE) + + if(WaveExists(oorDAScale) && oorDAScale[headstage]) + PSQ_ForceSetEvent(device, headstage) + RA_SkipSweeps(device, Inf, SWEEP_SKIP_AUTO, limitToSetBorder = 1) + return PSQ_RESULTS_DONE + endif + if(PSQ_DS_AdaptiveIsFinished(device, sweepNo, headstage, numSweepsWithSaturation)) PSQ_ForceSetEvent(device, headstage) RA_SkipSweeps(device, Inf, SWEEP_SKIP_AUTO, limitToSetBorder = 1) @@ -2878,6 +2887,13 @@ static Function PSQ_DS_AdaptiveIsFinished(string device, variable sweepNo, varia endif endif + key = CreateAnaFuncLBNKey(PSQ_DA_SCALE, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDAScale = GetLastSetting(numericalValues, sweepNo, key, UNKNOWN_MODE) + + if(WaveExists(oorDAScale) && oorDAScale[headstage]) + return 0 + endif + [WAVE sweepPassed, emptySCI] = PSQ_DS_GetLabnotebookData(numericalValues, textualValues, sweepNo, headstage, PSQ_DS_SWEEP_PASS, fromRhSuAd = fromRhSuAd) if(DimSize(sweepPassed, ROWS) < numSweepsWithSaturation) @@ -3682,7 +3698,7 @@ Function PSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) variable sweepPassed, setPassed, length, minLength, reachedFinalSlope, fitOffset, fitSlope, apfreq, enoughFIPointsPassedQC variable minimumSpikeCount, maximumSpikeCount, daScaleModifierParam, measuredAllFutureDAScales, fallbackDAScaleRangeFac variable sweepsInSet, passesInSet, acquiredSweepsInSet, multiplier, asyncAlarmPassed, supraStimsetCycle - variable daScaleStepMinNorm, daScaleStepMaxNorm, maxSlope, validFit, emptySCI + variable daScaleStepMinNorm, daScaleStepMaxNorm, maxSlope, validFit, emptySCI, oorDAScaleQC, limitCheck string msg, stimset, key, opMode, offsetOp, textboxString, str, errMsg variable daScaleOffset variable finalSlopePercent = NaN @@ -4189,9 +4205,13 @@ Function PSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) enoughSweepsPassed = PSQ_NumPassesInSet(numericalValues, PSQ_DA_SCALE, s.sweepNo, s.headstage) >= numSweepsPass + key = CreateAnaFuncLBNKey(PSQ_DA_SCALE, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDAScale = GetLastSetting(numericalValues, s.sweepNo, key, UNKNOWN_MODE) + oorDAScaleQC = !(WaveExists(oorDAScale) && oorDAScale[s.headstage]) + strswitch(opMode) case PSQ_DS_SUB: - setPassed = enoughSweepsPassed + setPassed = enoughSweepsPassed && oorDAScaleQC break case PSQ_DS_SUPRA: if(IsFinite(finalSlopePercent)) @@ -4199,12 +4219,12 @@ Function PSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) WAVE fISlopeReached = GetLastSettingIndepEachSCI(numericalValues, s.sweepNo, key, s.headstage, UNKNOWN_MODE) ASSERT(WaveExists(fISlopeReached), "Missing fiSlopeReached LBN entry") - setPassed = enoughSweepsPassed && Sum(fISlopeReached) > 0 + setPassed = enoughSweepsPassed && Sum(fISlopeReached) > 0 && oorDAScaleQC else sprintf msg, "Final slope percentage not present\r" DEBUGPRINT(msg) - setPassed = enoughSweepsPassed + setPassed = enoughSweepsPassed && oorDAScaleQC endif break case PSQ_DS_ADAPT: @@ -4234,6 +4254,8 @@ Function PSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) if(s.eventType == PRE_SET_EVENT || s.eventType == POST_SWEEP_EVENT) WAVE statusHS = DAG_GetChannelState(device, CHANNEL_TYPE_HEADSTAGE) + WAVE oorDAScale = LBN_GetNumericWave() + for(i = 0; i < NUM_HEADSTAGES; i += 1) if(!statusHS[i]) continue @@ -4271,9 +4293,13 @@ Function PSQ_DAScale(string device, STRUCT AnalysisFunction_V3 &s) ASSERT(0, "Invalid case") break endswitch - SetDAScale(device, s.sweepNo, i, absolute = DAScale * PICO_TO_ONE) + + limitCheck = (s.eventType == POST_SWEEP_EVENT) && !AFH_LastSweepInSet(device, s.sweepNo, i, s.eventType) + oorDAScale[i] = SetDAScale(device, s.sweepNo, i, absolute = DAScale * PICO_TO_ONE, limitCheck = limitCheck) endif endfor + + ReportOutOfRangeDAScale(device, s.sweepNo, PSQ_DA_SCALE, oorDAScale) endif if(s.eventType != MID_SWEEP_EVENT) diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Adapt.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Adapt.ipf index b9449dfd3a..0032aeb085 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Adapt.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Adapt.ipf @@ -8,31 +8,34 @@ /// /// .. Column order: test overrides, labnotebook entries, analysis parameters /// -///============= ==================== ============================ ============================== ========================= ====================== ============================ ======================= ================================== ============ ==================== ================== ====================== ============================== ========== ============= ================= ========================= ============================== ============================== =========================== ============================= ========================= =================== -/// Test case Baseline chunk0 QC Baseline chunk [1, inf] QC Enough rheobase/supra sweeps Passing rheobase sweeps Passing supra sweeps Valid initial f-I slope QC Valid initial f-I fit Initial f-I data is dense enough Failed f-I Valid f-I slope QC Fit f-I slope QC Enough f-I points QC Measured all future DAScales Async QC Sampling QC SlopePercentage NumSweepsWithSaturation DAScaleRangeFactor NumInvalidSlopeSweepsAllowed MaxFrequencyChangePercent DaScaleStepWidthMinMaxRatio AbsFrequencyMinDistance SamplingFrequency -///============= ==================== ============================ ============================== ========================= ====================== ============================ ======================= ================================== ============ ==================== ================== ====================== ============================== ========== ============= ================= ========================= ============================== ============================== =========================== ============================= ========================= =================== -/// PS_DS_AD1 - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ - ✓ def 2 def def 5 3 2 def -/// PS_DS_AD2 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 1 def def 25 3 2 def -/// PS_DS_AD2a ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 2 def -/// PS_DS_AD2b ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 1.5 2 def -/// PS_DS_AD3 [-,✓,✓] ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,✓,✓] [-,✓,✓] ✓ [✓,-,✓] ✓ ✓ def 2 def def 25 3 2 def -/// PS_DS_AD4 ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 2 def -/// PS_DS_AD4a ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 2 def -/// PS_DS_AD5 ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 2 def -/// PS_DS_AD6 ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ def 1 def def 25 3 2 def -/// PS_DS_AD7 ✓ ✓ ✓ ✓ ✓ - ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 1 def def 10 1.1 2 def -/// PS_DS_AD8 ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 1 def def 25 3 2 def -/// PS_DS_AD9 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-] [-,-] ✓ ✓ ✓ ✓ def 3 2 2 45 3 2 def -/// PS_DS_AD10 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ - ✓ ✓ def 2 def def 25 1.2 2 def -/// PS_DS_AD11 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-,✓] ✓ [-,-,✓] ✓ ✓ 60 1 1 1 45 1.2 2 def -/// PS_DS_AD12 [✓,-,✓,✓] ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-,✓,✓] ✓ [-,✓-,,✓] ✓ ✓ def 2 def def 25 3 1.1 def -/// PS_DS_AD13 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - def 2 def def 25 3 0.5 def -/// PS_DS_AD14 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,✓ ] [-,✓ ] ✓ ✓ ✓ ✓ ✓ def 1 def def 25 3 2 def -/// PS_DS_AD15 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,✓ ] [-,✓ ] ✓ ✓ [-,-,✓] ✓ ✓ def 1 def def 25 3 2 def -/// PS_DS_AD16 ✓ [-,-,✓,-,✓] ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-,✓,✓,✓] ✓ [✓,✓,-,✓,✓] ✓ ✓ def 2 def def 25 3 1.1 def -/// PS_DS_AD17 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ def 2 def def 25 3 1.1 def -/// PS_DS_AD18 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ def 3 def def 25 3 1.1 def -///============= ==================== ============================ ============================== ========================= ====================== ============================ ======================= ================================== ============ ==================== ================== ====================== ============================== ========== ============= ================= ========================= ============================== ============================== =========================== ============================= ========================= =================== +///============= ==================== ============================ ============================== ========================= ====================== ============================ ======================= ================================== ============ ==================== ================== ====================== ============================== ========== ============= ====================== ================= ========================= ============================== ============================== =========================== ============================= ========================= =================== +/// Test case Baseline chunk0 QC Baseline chunk [1, inf] QC Enough rheobase/supra sweeps Passing rheobase sweeps Passing supra sweeps Valid initial f-I slope QC Valid initial f-I fit Initial f-I data is dense enough Failed f-I Valid f-I slope QC Fit f-I slope QC Enough f-I points QC Measured all future DAScales Async QC Sampling QC Out of range DAScale SlopePercentage NumSweepsWithSaturation DAScaleRangeFactor NumInvalidSlopeSweepsAllowed MaxFrequencyChangePercent DaScaleStepWidthMinMaxRatio AbsFrequencyMinDistance SamplingFrequency +///============= ==================== ============================ ============================== ========================= ====================== ============================ ======================= ================================== ============ ==================== ================== ====================== ============================== ========== ============= ====================== ================= ========================= ============================== ============================== =========================== ============================= ========================= =================== +/// PS_DS_AD1 - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ - ✓ ✓ def 2 def def 5 3 2 def +/// PS_DS_AD2 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 1 def def 25 3 2 def +/// PS_DS_AD2a ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 2 def +/// PS_DS_AD2b ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 1.5 2 def +/// PS_DS_AD3 [-,✓,✓] ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,✓,✓] [-,✓,✓] ✓ [✓,-,✓] ✓ ✓ ✓ def 2 def def 25 3 2 def +/// PS_DS_AD4 ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 2 def +/// PS_DS_AD4a ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 2 def +/// PS_DS_AD5 ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 2 def +/// PS_DS_AD6 ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ def 1 def def 25 3 2 def +/// PS_DS_AD7 ✓ ✓ ✓ ✓ ✓ - ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 1 def def 10 1.1 2 def +/// PS_DS_AD8 ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ def 1 def def 25 3 2 def +/// PS_DS_AD9 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-] [-,-] ✓ ✓ ✓ ✓ ✓ def 3 2 2 45 3 2 def +/// PS_DS_AD10 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ - ✓ ✓ ✓ def 2 def def 25 1.2 2 def +/// PS_DS_AD11 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-,✓] ✓ [-,-,✓] ✓ ✓ ✓ 60 1 1 1 45 1.2 2 def +/// PS_DS_AD12 [✓,-,✓,✓] ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-,✓,✓] ✓ [-,✓-,,✓] ✓ ✓ ✓ def 2 def def 25 3 1.1 def +/// PS_DS_AD12 [✓,-,✓,✓] ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-,✓,✓] ✓ [-,✓-,,✓] ✓ ✓ ✓ def 2 def def 25 3 1.1 def +/// PS_DS_AD13 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ def 2 def def 25 3 0.5 def +/// PS_DS_AD13 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ def 2 def def 25 3 0.5 def +/// PS_DS_AD14 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,✓ ] [-,✓ ] ✓ ✓ ✓ ✓ ✓ ✓ def 1 def def 25 3 2 def +/// PS_DS_AD15 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,✓ ] [-,✓ ] ✓ ✓ [-,-,✓] ✓ ✓ ✓ def 1 def def 25 3 2 def +/// PS_DS_AD16 ✓ [-,-,✓,-,✓] ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ [-,-,✓,✓,✓] ✓ [✓,✓,-,✓,✓] ✓ ✓ ✓ def 2 def def 25 3 1.1 def +/// PS_DS_AD17 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ def 2 def def 25 3 1.1 def +/// PS_DS_AD18 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ ✓ def 3 def def 25 3 1.1 def +/// PS_DS_AD19 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ - ✓ ✓ ✓ ✓ - def def def def 25 def def def +///============= ==================== ============================ ============================== ========================= ====================== ============================ ======================= ================================== ============ ==================== ================== ====================== ============================== ========== ============= ====================== ================= ========================= ============================== ============================== =========================== ============================= ========================= =================== /// /// @endrst @@ -128,6 +131,7 @@ static Function/WAVE GetLBNSingleEntry_IGNORE(string device, variable sweepNo, s case PSQ_FMT_LBN_DA_AT_FI_OFFSET: case PSQ_FMT_LBN_DA_FI_SLOPE: case PSQ_FMT_LBN_BL_QC_PASS: + case PSQ_FMT_LBN_DASCALE_OOR: key = CreateAnaFuncLBNKey(type, name, query = 1) return GetLastSettingEachSCI(numericalValues, sweepNo, key, PSQ_TEST_HEADSTAGE, UNKNOWN_MODE) case PSQ_FMT_LBN_SET_PASS: @@ -177,7 +181,7 @@ static Function/WAVE GetWave_IGNORE() "fiSlopesFromRhSuAd;fiOffsetsFromRhSuAd;sweepPassFromRhSuAd;" + \ "fiSlopeReachedPassFromRhSuAd;daScale;" + \ "apFreqFromRhSuAd;dascaleFromRhSuAd;minDaScaleNorm;" + \ - "maxDAScaleNorm" + "maxDAScaleNorm;oorDAScale" Make/FREE/WAVE/N=(ItemsInList(list)) wv SetDimensionLabels(wv, list, ROWS) @@ -215,6 +219,7 @@ static Function/WAVE GetEntries_IGNORE(string device, variable sweepNo) wv[%dascaleFromRhSuAd] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_DA_AT_RSA_DASCALE) wv[%minDaScaleNorm] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_DA_AT_MIN_DASCALE_NORM) wv[%maxDaScaleNorm] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_DA_AT_MAX_DASCALE_NORM) + wv[%oorDAScale] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) wv[%futureDAScalesPass] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_DA_AT_FUTURE_DASCALES_PASS) wv[%fiSlopeReachedPass] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_DA_fI_SLOPE_REACHED_PASS) @@ -455,6 +460,8 @@ static Function PS_DS_AD1_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) @@ -476,6 +483,8 @@ static Function PS_DS_AD1_REENTRY_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%setPass], {0}, mode = WAVE_DATA) CHECK_EQUAL_WAVES(entries[%sweepPass], {0, 0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, 0, NaN}, mode = WAVE_DATA) + WAVE/Z overrideResults = GetOverrideResults() CHECK_WAVE(overrideResults, NUMERIC_WAVE) failingAdaptiveSweep = JWN_GetNumberFromWaveNote(overrideResults, "FailingAdaptiveSweep") @@ -586,6 +595,8 @@ static Function PS_DS_AD2_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_WAVE(entries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -695,6 +706,8 @@ static Function PS_DS_AD2a_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -804,6 +817,8 @@ static Function PS_DS_AD2b_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -916,6 +931,8 @@ static Function PS_DS_AD3_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -1182,6 +1199,8 @@ static Function PS_DS_AD6_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_WAVE(entries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -1291,6 +1310,8 @@ static Function PS_DS_AD7_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -1451,6 +1472,8 @@ static Function PS_DS_AD9_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -1557,6 +1580,8 @@ static Function PS_DS_AD10_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -1675,6 +1700,8 @@ static Function PS_DS_AD11_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -1788,6 +1815,8 @@ static Function PS_DS_AD12_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -1897,6 +1926,8 @@ static Function PS_DS_AD13_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_WAVE(entries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -2007,6 +2038,8 @@ static Function PS_DS_AD14_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -2118,6 +2151,8 @@ static Function PS_DS_AD15_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -2236,6 +2271,8 @@ static Function PS_DS_AD16_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%oorDAScale], {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -2341,6 +2378,8 @@ static Function PS_DS_AD17_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_WAVE(entries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End @@ -2450,6 +2489,105 @@ static Function PS_DS_AD18_REENTRY([string str]) CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_WAVE(entries[%oorDAScale], NULL_WAVE) + + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) + CheckSurveyPlot(str, entries) +End + +static Function PS_DS_AD19_preAcq(string device) + + // use defaults + + Make/FREE asyncChannels = {2, 4} + AFH_AddAnalysisParameter("PSQ_DaScale_Adapt_DA_0", "AsyncQCChannels", wv = asyncChannels) + + SetAsyncChannelProperties(device, asyncChannels, -1e6, +1e6) + + WAVE/Z overrideResults = GetOverrideResults() + CHECK_WAVE(overrideResults, NUMERIC_WAVE) + JWN_SetWaveInWaveNote(overrideResults, "PassingRheobaseSweep", {5}) + JWN_SetWaveInWaveNote(overrideResults, "PassingSupraSweep", {7}) + JWN_SetWaveInWaveNote(overrideResults, "PassingRhSuAdSweeps", {4, 5, 6, 7}) + + Make/FREE/D DAScalesFromRhSuAd = {1000, 1500, 2500, 3000} + JWN_SetWaveInWaveNote(overrideResults, "DAScalesRhSuAd", DAScalesFromRhSuAd) + + Make/FREE/D apFrequenciesFromRhSuAd = {1, 2, 3, 4} + JWN_SetWaveInWaveNote(overrideResults, "APFrequenciesRhSuAd", apFrequenciesFromRhSuAd) +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function PS_DS_AD19([string str]) + + [STRUCT DAQSettings s] = PS_GetDAQSettings(str) + AcquireData_NG(s, str) + + WAVE wv = PSQ_CreateOverrideResults(str, PSQ_TEST_HEADSTAGE, PSQ_DA_SCALE, opMode = PSQ_DS_ADAPT) + + wv[][][%APFrequency] = 16 + p + wv[][][%AsyncQC] = 1 + wv[][][%BaselineQC] = 1 +End + +static Function PS_DS_AD19_REENTRY([string str]) + + variable sweepNo + + sweepNo = 0 + + WAVE/WAVE entries = GetEntries_IGNORE(str, sweepNo) + + CHECK_EQUAL_TEXTWAVES(entries[%opMode], {PSQ_DS_ADAPT}, mode = WAVE_DATA) + + CHECK_EQUAL_WAVES(entries[%setPass], {0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%sweepPass], {1}, mode = WAVE_DATA) + + CHECK_EQUAL_WAVES(entries[%rmsShortPass], {1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%rmsLongPass], {1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%baselinePass], {1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%asyncPass], {1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%samplingPass], {1}, mode = WAVE_DATA) + + CHECK_EQUAL_WAVES(entries[%futureDAScalesPass], {0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%fiSlopeReachedPass], {0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%enoughFIPointsPass], {1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%validSlopePass], {1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%initialValidSlopePass], {1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%fiSlopeReachedPassFromRhSuAd], {0, 0, 0}, mode = WAVE_DATA) + + Make/FREE/D minDAScaleNormRef = {142.8571428571429} + CHECK_EQUAL_WAVES(entries[%minDaScaleNorm], minDAScaleNormRef, mode = WAVE_DATA, tol = 1e-24) + + Make/FREE/D maxDAScaleNormRef = {428.5714285714286} + CHECK_EQUAL_WAVES(entries[%maxDaScaleNorm], maxDAScaleNormRef, mode = WAVE_DATA, tol = 1e-24) + + [WAVE apFreqRef, WAVE apFreqFromRhSuAd, WAVE DAScalesFromRhSuAd, WAVE sweepPassedFRomRhSuAd] = ExtractRefValuesFromOverride(sweepNo) + + CHECK_EQUAL_WAVES(entries[%apfreq], apFreqRef, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%apFreqFromRhSuAd], apFreqFromRhSuAd, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%dascaleFromRhSuAd], DAScalesFromRhSuAd, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%sweepPassFromRhSuAd], sweepPassedFRomRhSuAd, mode = WAVE_DATA) + + Make/FREE/D maxSlopeRef = {2.1e-12} + Make/FREE/D fiSlopeRef = {2.1e-12} + Make/FREE/D fiOffsetRef = {-58.99999999999999} + Make/FREE/T futureDAScalesRef = {"3571.42857142857;5857.14285714286;"} + + Make/FREE/D fiSlopesFromRhSuAdRef = {2e-13, 1e-13, 2e-13} + Make/FREE/D fiOffsetsFromRhSuAdRef = {-1, 0.5, -2} + Make/FREE/D DAScalesRef = {3571.428571428572} + + CHECK_EQUAL_WAVES(entries[%maxSlope], maxSlopeRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%fiSlope], fiSlopeRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%fiOffset], fiOffsetRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_TEXTWAVES(entries[%futureDAScales], futureDAScalesRef, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(entries[%fiSlopesFromRhSuAd], fiSlopesFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%fiOffsetsFromRhSuAd], fiOffsetsFromRhSuAdRef, mode = WAVE_DATA, tol = 1e-24) + CHECK_EQUAL_WAVES(entries[%dascale], DAScalesRef, mode = WAVE_DATA, tol = 1e-24) + + CHECK_EQUAL_WAVES(entries[%oorDAScale], {1}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, entries[%setPass]) CheckSurveyPlot(str, entries) End diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Sub.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Sub.ipf index c34773f6bf..ffe40fc784 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Sub.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Sub.ipf @@ -71,6 +71,7 @@ static Function/WAVE GetLBNEntries_IGNORE(string device, variable sweepNo, strin case PSQ_FMT_LBN_TARGETV: case PSQ_FMT_LBN_LEAKCUR: case PSQ_FMT_LBN_LEAKCUR_PASS: + case PSQ_FMT_LBN_DASCALE_OOR: return GetLastSettingEachSCI(numericalValues, sweepNo, key, PSQ_TEST_HEADSTAGE, UNKNOWN_MODE) break case PSQ_FMT_LBN_RMS_SHORT_THRESHOLD: @@ -238,6 +239,9 @@ static Function PS_DS_Sub1_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520}) End @@ -431,6 +435,9 @@ static Function PS_DS_Sub2_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520, 2520, 3020, 3020, 3520}) End @@ -600,6 +607,9 @@ static Function PS_DS_Sub3_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), 4) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) End @@ -814,6 +824,9 @@ static Function PS_DS_Sub4_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), 4) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520, 2520, 3020, 3020, 3520}) End @@ -961,6 +974,9 @@ static Function PS_DS_Sub5_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520}) End @@ -1108,6 +1124,9 @@ static Function PS_DS_Sub5a_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520}) End @@ -1323,6 +1342,9 @@ static Function PS_DS_Sub6_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), 4) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520, 2520, 3020}) End @@ -1494,6 +1516,9 @@ static Function PS_DS_Sub7_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), 6) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520}, sweep = 0) CheckPSQChunkTimes(str, {20, 520}, sweep = 1) @@ -1678,6 +1703,9 @@ static Function PS_DS_Sub8_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), 8) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}, sweep = 0) CheckPSQChunkTimes(str, {20, 520}, sweep = 1) @@ -1834,6 +1862,9 @@ static Function PS_DS_Sub9_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) End @@ -2005,6 +2036,104 @@ static Function PS_DS_Sub10_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_WAVE(oorDAScale, NULL_WAVE) + + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) + CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) +End + +static Function PS_DS_Sub11_preAcq(string device) + + Make/FREE asyncChannels = {2, 3} + AFH_AddAnalysisParameter("PSQ_DaScale_Sub_DA_0", "AsyncQCChannels", wv = asyncChannels) + + AFH_AddAnalysisParameter("PSQ_DaScale_Sub_DA_0", "DAScales", wv = {1000, 2000, 2500, 3000, 5000}) + + SetAsyncChannelProperties(device, asyncChannels, -1e6, +1e6) +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function PS_DS_Sub11([string str]) + + [STRUCT DAQSettings s] = PS_GetDAQSettings(str) + AcquireData_NG(s, str) + + WAVE wv = PSQ_CreateOverrideResults(str, PSQ_TEST_HEADSTAGE, PSQ_DA_SCALE, opMode = PSQ_DS_SUB) + // pre pulse chunk pass + // first post pulse chunk pass + // async QC passes + wv[] = 0 + wv[0, 1][] = 1 + wv[][][3] = 1 +End + +static Function PS_DS_Sub11_REENTRY([string str]) + + variable sweepNo, numEntries + + sweepNo = 3 + + WAVE numericalValues = GetLBNumericalValues(str) + + WAVE/Z setPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SET_PASS) + CHECK_EQUAL_WAVES(setPassed, {0}, mode = WAVE_DATA) + + WAVE/Z sweepPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SWEEP_PASS) + CHECK_EQUAL_WAVES(sweepPassed, {1, 1, 1, 1}, mode = WAVE_DATA) + + WAVE/Z samplingPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SAMPLING_PASS) + CHECK_EQUAL_WAVES(samplingPassed, {1, 1, 1, 1}, mode = WAVE_DATA) + + WAVE/Z asyncPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_ASYNC_PASS) + CHECK_EQUAL_WAVES(asyncPassed, {1, 1, 1, 1}, mode = WAVE_DATA) + + WAVE/Z spikeDetection = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SPIKE_DETECT) + CHECK_WAVE(spikeDetection, NULL_WAVE) + + WAVE/Z spikeCount = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SPIKE_COUNT) + CHECK_WAVE(spikeCount, NULL_WAVE) + + WAVE/Z pulseDuration = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_PULSE_DUR) + CHECK_EQUAL_WAVES(pulseDuration, {1000, 1000, 1000, 1000}, mode = WAVE_DATA, tol = 1e-3) + + WAVE/Z fISlope = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DA_fI_SLOPE) + CHECK_WAVE(fISlope, NULL_WAVE) + + WAVE/Z fISlopeReached = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DA_fI_SLOPE_REACHED_PASS) + CHECK_EQUAL_WAVES(fISlopeReached, {0, 0, 0, 0}, mode = WAVE_DATA) + + WAVE/Z/T opMode = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DA_OPMODE) + CHECK_EQUAL_TEXTWAVES(opMode, {PSQ_DS_SUB, PSQ_DS_SUB, PSQ_DS_SUB, PSQ_DS_SUB}, mode = WAVE_DATA) + + WAVE/Z deltaI = GetLBNEntries_IGNORE(str, sweepNo, LBN_DELTA_I) + CHECK_WAVE(deltaI, NUMERIC_WAVE) + + WAVE/Z deltaV = GetLBNEntries_IGNORE(str, sweepNo, LBN_DELTA_V) + CHECK_WAVE(deltaV, NUMERIC_WAVE) + + WAVE/Z resistance = GetLBNEntries_IGNORE(str, sweepNo, LBN_RESISTANCE_FIT) + CHECK_WAVE(resistance, NUMERIC_WAVE) + + WAVE/Z resistanceErr = GetLBNEntries_IGNORE(str, sweepNo, LBN_RESISTANCE_FIT_ERR) + CHECK_WAVE(resistanceErr, NUMERIC_WAVE) + + WAVE/Z sweeps = AFH_GetSweepsFromSameRACycle(numericalValues, sweepNo) + CHECK_WAVE(sweeps, NUMERIC_WAVE) + numEntries = DimSize(sweeps, ROWS) + CHECK_EQUAL_VAR(numEntries, 4) + + numEntries = DimSize(sweepPassed, ROWS) + WAVE/Z stimScale = GetLBNEntries_IGNORE(str, sweepNo, STIMSET_SCALE_FACTOR_KEY) + Make/FREE/D/N=(numEntries) stimScaleRef = {1000, 2000, 2500, 3000} + + CHECK_EQUAL_WAVES(stimScale, stimScaleRef, mode = WAVE_DATA, tol = 1e-14) + + CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_WAVE(oorDAScale, NUMERIC_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) End diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Supra.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Supra.ipf index b719c38505..201afce02f 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Supra.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqDAScale_Supra.ipf @@ -69,6 +69,7 @@ static Function/WAVE GetLBNEntries_IGNORE(string device, variable sweepNo, strin case PSQ_FMT_LBN_TARGETV: case PSQ_FMT_LBN_LEAKCUR: case PSQ_FMT_LBN_LEAKCUR_PASS: + case PSQ_FMT_LBN_DASCALE_OOR: return GetLastSettingEachSCI(numericalValues, sweepNo, key, PSQ_TEST_HEADSTAGE, UNKNOWN_MODE) break case PSQ_FMT_LBN_RMS_SHORT_THRESHOLD: @@ -172,6 +173,9 @@ static Function PS_DS_Supra1_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) End @@ -258,6 +262,9 @@ static Function PS_DS_Supra2_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) End @@ -345,6 +352,9 @@ static Function PS_DS_Supra3_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) End @@ -432,6 +442,9 @@ static Function PS_DS_Supra4_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) End @@ -535,6 +548,9 @@ static Function PS_DS_Supra5_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) End @@ -623,6 +639,102 @@ static Function PS_DS_Supra6_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) + CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) +End + +static Function PS_DS_Supra7_preAcq(string device) + + Make/FREE asyncChannels = {2, 3} + AFH_AddAnalysisParameter("PSQ_DaScale_Supr_DA_0", "AsyncQCChannels", wv = asyncChannels) + + AFH_AddAnalysisParameter("PSQ_DaScale_Supr_DA_0", "DAScales", wv = {1000, 1500, 1750, 2000, 5000}) + + SetAsyncChannelProperties(device, asyncChannels, -1e6, +1e6) +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function PS_DS_Supra7([string str]) + + [STRUCT DAQSettings s] = PS_GetDAQSettings(str, "PSQ_DaScale_Supr_DA_0") + AcquireData_NG(s, str) + + WAVE wv = PSQ_CreateOverrideResults(str, PSQ_TEST_HEADSTAGE, PSQ_DA_SCALE, opMode = PSQ_DS_SUPRA) + // pre pulse chunk pass + // second post pulse chunk pass + wv = 0 + wv[0][][0] = 1 + wv[1][][0] = 1 + // Spike and non-spiking + wv[0][][1] = mod(q, 2) == 0 + // increasing number of spikes + wv[0][][2] = q + 1 + // async QC passes + wv[][][3] = 1 +End + +static Function PS_DS_Supra7_REENTRY([string str]) + + variable sweepNo, numEntries + + sweepNo = 3 + + WAVE numericalValues = GetLBNumericalValues(str) + + WAVE/Z setPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SET_PASS) + CHECK_EQUAL_WAVES(setPassed, {0}, mode = WAVE_DATA) + + WAVE/Z sweepPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SWEEP_PASS) + CHECK_EQUAL_WAVES(sweepPassed, {1, 1, 1, 1}, mode = WAVE_DATA) + + WAVE/Z samplingPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SAMPLING_PASS) + CHECK_EQUAL_WAVES(samplingPassed, {1, 1, 1, 1}, mode = WAVE_DATA) + + WAVE/Z asyncPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_ASYNC_PASS) + CHECK_EQUAL_WAVES(asyncPassed, {1, 1, 1, 1}, mode = WAVE_DATA) + + WAVE/Z baselineQCPassed = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_BL_QC_PASS) + CHECK_EQUAL_WAVES(sweepPassed, baselineQCPassed) + + WAVE/Z spikeDetection = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SPIKE_DETECT) + CHECK_EQUAL_WAVES(spikeDetection, {1, 0, 1, 0}, mode = WAVE_DATA, tol = 1e-3) + + WAVE/Z spikeCount = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_SPIKE_COUNT) + CHECK_EQUAL_WAVES(spikeCount, {1, 0, 3, 0}, mode = WAVE_DATA, tol = 1e-3) + + WAVE/Z pulseDuration = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_PULSE_DUR) + CHECK_EQUAL_WAVES(pulseDuration, {1000, 1000, 1000, 1000}, mode = WAVE_DATA, tol = 1e-3) + + WAVE spikeFreq = GetAnalysisFuncDAScaleSpikeFreq(str, PSQ_TEST_HEADSTAGE) + CHECK_EQUAL_WAVES(spikeFreq, {1, 0, 3, 0}, mode = WAVE_DATA, tol = 1e-3) + + WAVE/Z fISlope = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DA_fI_SLOPE) + CHECK_EQUAL_WAVES(fISlope, {0, -0.2, 0.2, 0}, mode = WAVE_DATA, tol = 1e-3) + + WAVE/Z fISlopeReached = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DA_fI_SLOPE_REACHED_PASS) + CHECK_EQUAL_WAVES(fISlopeReached, {0, 0, 0, 0}, mode = WAVE_DATA) + + WAVE/Z/T opMode = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DA_OPMODE) + CHECK_EQUAL_TEXTWAVES(opMode, {PSQ_DS_SUPRA, PSQ_DS_SUPRA, PSQ_DS_SUPRA, PSQ_DS_SUPRA}, mode = WAVE_DATA) + + WAVE/Z sweeps = AFH_GetSweepsFromSameRACycle(numericalValues, sweepNo) + CHECK_WAVE(sweeps, NUMERIC_WAVE) + numEntries = DimSize(sweeps, ROWS) + CHECK_EQUAL_VAR(numEntries, 4) + + numEntries = DimSize(sweepPassed, ROWS) + WAVE/Z stimScale = GetLBNEntries_IGNORE(str, sweepNo, STIMSET_SCALE_FACTOR_KEY) + Make/FREE/D/N=(numEntries) stimScaleRef = {PSQ_DS_OFFSETSCALE_FAKE + 1000, PSQ_DS_OFFSETSCALE_FAKE + 1500, PSQ_DS_OFFSETSCALE_FAKE + 1750, PSQ_DS_OFFSETSCALE_FAKE + 2000} + CHECK_EQUAL_WAVES(stimScale, stimScaleRef, mode = WAVE_DATA, tol = 1e-14) + + CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingDAScale(str, PSQ_TEST_HEADSTAGE, PSQ_DS_SUB), -1) + + WAVE/Z oorDAScale = GetLBNEntries_IGNORE(str, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 1}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, setPassed) CheckPSQChunkTimes(str, {20, 520, 2020, 2520}) End From 513bbf6c66ad47d4751bc5fe92a76ae80305b5c4 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:52:38 +0200 Subject: [PATCH 12/17] PSQ_SquarePulse: Add support for DAScale limit checks --- .../MIES/MIES_AnalysisFunctions_Dashboard.ipf | 8 ++ .../MIES/MIES_AnalysisFunctions_PatchSeq.ipf | 22 +++- .../UTF_PatchSeqSquarePulse.ipf | 124 ++++++++++++++++++ 3 files changed, 148 insertions(+), 6 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf index 0ca838871e..036cff7968 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf @@ -146,6 +146,7 @@ static Function/S AD_GetResultMessage(variable anaFuncType, variable passed, WAV // - seal threshold QC // PSQ_SP + // - Out of range DAScale // - only reached PSQ_FMT_LBN_STEPSIZE step size and not PSQ_SP_INIT_AMP_p10 with a spike // PSQ_VM @@ -445,6 +446,13 @@ static Function/S AD_GetSquarePulseFailMsg(WAVE numericalValues, variable sweepN endif endif + key = CreateAnaFuncLBNKey(PSQ_SQUARE_PULSE, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDASCale = GetLastSettingEachSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE) + + if(AD_LabnotebookEntryExistsAndIsTrue(oorDASCale)) + return AD_OOR_DASCALE_MSG + endif + key = CreateAnaFuncLBNKey(PSQ_SQUARE_PULSE, PSQ_FMT_LBN_STEPSIZE, query = 1, waMode = waMode) stepSize = GetLastSettingIndepSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE) if(!IsFinite(stepSize)) diff --git a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf index aee7ab2a49..6b66b76d30 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf @@ -4394,7 +4394,7 @@ End Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) variable stepsize, DAScale, totalOnsetDelay, setPassed, sweepPassed, multiplier - variable val, samplingFrequencyPassed, asyncAlarmPassed, ret + variable val, samplingFrequencyPassed, asyncAlarmPassed, ret, limitCheck string key, msg multiplier = AFH_GetAnalysisParamNumerical("SamplingMultiplier", s.params) @@ -4438,7 +4438,7 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) PGC_SetAndActivateControl(device, "check_Settings_ITITP", val = 0) PSQ_StoreStepSizeInLBN(device, PSQ_SQUARE_PULSE, s.sweepNo, PSQ_SP_INIT_AMP_p100) - SetDAScale(device, s.sweepNo, s.headstage, absolute = PSQ_SP_INIT_AMP_p100) + SetDAScale(device, s.sweepNo, s.headstage, absolute = PSQ_SP_INIT_AMP_p100, limitCheck = 0) return 0 @@ -4471,11 +4471,15 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) WAVE asyncChannels = AFH_GetAnalysisParamWave("AsyncQCChannels", s.params) asyncAlarmPassed = PSQ_CheckAsyncAlarmStateAndStoreInLabnotebook(device, PSQ_SQUARE_PULSE, s.sweepNo, asyncChannels) + WAVE oorDAScale = LBN_GetNumericWave() + sweepPassed = 0 sprintf msg, "DAScale %g, stepSize %g", DAScale, stepSize DEBUGPRINT(msg) + limitCheck = !AFH_LastSweepInSet(device, s.sweepNo, s.headstage, s.eventType) + if(spikeDetection[s.headstage]) // headstage spiked if(CheckIfSmall(DAScale, tol = 1e-14)) WAVE value = LBN_GetNumericWave() @@ -4491,7 +4495,7 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) RA_SkipSweeps(device, Inf, SWEEP_SKIP_AUTO, limitToSetBorder = 1) endif elseif(CheckIfClose(stepSize, PSQ_SP_INIT_AMP_m50)) - SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize) + oorDAScale[s.headstage] = SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize, limitCheck = limitCheck) elseif(CheckIfClose(stepSize, PSQ_SP_INIT_AMP_p10)) WAVE value = LBN_GetNumericWave() value[INDEP_HEADSTAGE] = DAScale @@ -4506,8 +4510,8 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) endif elseif(CheckIfClose(stepSize, PSQ_SP_INIT_AMP_p100)) PSQ_StoreStepSizeInLBN(device, PSQ_SQUARE_PULSE, s.sweepNo, PSQ_SP_INIT_AMP_m50) - stepsize = PSQ_SP_INIT_AMP_m50 - SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize) + stepsize = PSQ_SP_INIT_AMP_m50 + oorDAScale[s.headstage] = SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize, limitCheck = limitCheck) else ASSERT(0, "Unknown stepsize") endif @@ -4523,7 +4527,13 @@ Function PSQ_SquarePulse(string device, STRUCT AnalysisFunction_V3 &s) ASSERT(0, "Unknown stepsize") endif - SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize) + oorDAScale[s.headstage] = SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale + stepsize, limitCheck = limitCheck) + endif + + ReportOutOfRangeDAScale(device, s.sweepNo, PSQ_SQUARE_PULSE, oorDAScale) + + if(oorDAScale[s.headstage]) + sweepPassed = 0 endif sprintf msg, "Sweep has %s\r", ToPassFail(sweepPassed) diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqSquarePulse.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqSquarePulse.ipf index e55858521a..f0106a441e 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqSquarePulse.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqSquarePulse.ipf @@ -69,6 +69,15 @@ static Function/WAVE GetStimScaleFactor_IGNORE(variable sweepNo, string device) return GetLastSettingEachRAC(numericalValues, sweepNo, STIMSET_SCALE_FACTOR_KEY, PSQ_TEST_HEADSTAGE, UNKNOWN_MODE) End +static Function/WAVE GetOORDAScale_IGNORE(variable sweepNo, string device) + + string key + + WAVE numericalValues = GetLBNumericalValues(device) + key = CreateAnaFuncLBNKey(PSQ_SQUARE_PULSE, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + return GetLastSettingEachRAC(numericalValues, sweepNo, key, PSQ_TEST_HEADSTAGE, UNKNOWN_MODE) +End + static Function PS_SP1_preAcq(string device) Make/FREE asyncChannels = {2, 3} @@ -127,6 +136,9 @@ static Function PS_SP1_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {100e-12, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) @@ -191,6 +203,9 @@ static Function PS_SP2_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {100e-12, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) @@ -256,6 +271,9 @@ static Function PS_SP3_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {100e-12, -50e-12, 10e-12, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) @@ -321,6 +339,9 @@ static Function PS_SP4_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {100e-12, -50e-12, NaN, 10e-12, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) @@ -387,6 +408,9 @@ static Function PS_SP5_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {100e-12, -50e-12, 10e-12, NaN}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) @@ -454,6 +478,9 @@ static Function PS_SP6_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {-50e-12, NaN, NaN, 10e-12, NaN}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, NaN, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) @@ -519,6 +546,9 @@ static Function PS_SP7_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {-50e-12, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) @@ -587,6 +617,9 @@ static Function PS_SP8_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {100e-12}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) @@ -653,6 +686,97 @@ static Function PS_SP9_REENTRY([string str]) WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) CHECK_EQUAL_WAVES(stepSizes, {100e-12, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA, tol = 1e-13) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) + Make/FREE/N=0 chunkTimes + CheckPSQChunkTimes(str, chunkTimes) +End + +static Function PS_SP10_preAcq(string device) + + ST_SetStimsetParameter("PatchSeqSquarePu_DA_0", "Total number of steps", var = 50) + + Make/FREE asyncChannels = {2, 3} + AFH_AddAnalysisParameter("PatchSeqSquarePu_DA_0", "AsyncQCChannels", wv = asyncChannels) + + SetAsyncChannelProperties(device, asyncChannels, -1e6, +1e6) +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function PS_SP10([string str]) + + [STRUCT DAQSettings s] = PS_GetDAQSettings(str) + AcquireData_NG(s, str) + + WAVE wv = PSQ_CreateOverrideResults(str, PSQ_TEST_HEADSTAGE, PSQ_SQUARE_PULSE) + // no spikes + wv[][][0] = 0 + wv[][][1] = 1 +End + +static Function PS_SP10_REENTRY([string str]) + + variable sweepNo, sweepPassed, setPassed, finalDAScale, numEntries, numEntriesRef + string key + +#ifdef TESTS_WITH_NI_HARDWARE + sweepNo = 38 + numEntriesRef = sweepNo + 1 +#else + sweepNo = 39 + numEntriesRef = sweepNo + 1 +#endif + + WAVE numericalValues = GetLBNumericalValues(str) + + key = CreateAnaFuncLBNKey(PSQ_SQUARE_PULSE, PSQ_FMT_LBN_SWEEP_PASS, query = 1) + sweepPassed = GetLastSettingIndep(numericalValues, sweepNo, key, UNKNOWN_MODE) + CHECK_EQUAL_VAR(sweepPassed, 0) + + key = CreateAnaFuncLBNKey(PSQ_SQUARE_PULSE, PSQ_FMT_LBN_SET_PASS, query = 1) + setPassed = GetLastSettingIndep(numericalValues, sweepNo, key, UNKNOWN_MODE) + CHECK_EQUAL_VAR(setPassed, 0) + + WAVE/Z samplingIntervalQCWave = GetSamplingIntervalQCResults_IGNORE(sweepNo, str) + Make/FREE/N=(numEntriesRef) samplingIntervalQCWaveRef = 1 + CHECK_EQUAL_WAVES(samplingIntervalQCWave, samplingIntervalQCWaveRef, mode = WAVE_DATA) + + WAVE/Z asyncQCWave = GetAsyncQCResults_IGNORE(sweepNo, str) + Make/FREE/N=(numEntriesRef) asyncQCWaveRef = 1 + CHECK_EQUAL_WAVES(asyncQCWave, asyncQCWaveRef, mode = WAVE_DATA) + + key = CreateAnaFuncLBNKey(PSQ_SQUARE_PULSE, PSQ_FMT_LBN_FINAL_SCALE, query = 1) + finalDaScale = GetLastSettingIndep(numericalValues, sweepNo, key, UNKNOWN_MODE) + CHECK_EQUAL_VAR(finalDAScale, NaN) + + key = CreateAnaFuncLBNKey(PSQ_SQUARE_PULSE, PSQ_FMT_LBN_SPIKE_DASCALE_ZERO, query = 1) + WAVE/Z daScaleZero = GetLastSetting(numericalValues, sweepNo, key, UNKNOWN_MODE) + CHECK(!WaveExists(daScaleZero)) + WAVE/Z spikeDetectionWave = GetSpikeResults_IGNORE(sweepNo, str) + Make/FREE/N=(numEntriesRef) spikeDetectionWaveRef = 0 + CHECK_EQUAL_WAVES(spikeDetectionWave, spikeDetectionWaveRef, mode = WAVE_DATA) + + WAVE/Z sweeps = AFH_GetSweepsFromSameRACycle(numericalValues, sweepNo) + CHECK_WAVE(sweeps, NUMERIC_WAVE) + numEntries = DimSize(sweeps, ROWS) + CHECK_EQUAL_VAR(numEntries, numEntriesRef) + + WAVE/Z stimScale = GetStimScaleFactor_IGNORE(sweepNo, str) + Make/FREE/N=(numEntriesRef) stimScaleRef = 100 * (p + 1) + CHECK_EQUAL_WAVES(stimScale, stimScaleRef, tol = 1e-14, mode = WAVE_DATA) + + WAVE/Z stepSizes = GetDAScaleStepSize_IGNORE(sweepNo, str) + Make/FREE/N=(numEntriesRef) stepSizesRef = NaN + stepSizesRef[0] = 100e-12 + CHECK_EQUAL_WAVES(stepSizes, stepSizesRef, mode = WAVE_DATA, tol = 1e-13) + + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + Make/FREE/N=(numEntriesRef) oorDAScaleRef = 0 + oorDAScaleRef[Inf] = 1 + CHECK_EQUAL_WAVES(oorDAScale, oorDAScaleRef, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) Make/FREE/N=0 chunkTimes CheckPSQChunkTimes(str, chunkTimes) From 55a71464622f0220c9092dca8f8dc21693c58856 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:52:38 +0200 Subject: [PATCH 13/17] PSQ_Rheobase: Add support for DAScale limit checks --- .../MIES/MIES_AnalysisFunctions_Dashboard.ipf | 8 ++ .../MIES/MIES_AnalysisFunctions_PatchSeq.ipf | 16 ++- .../UTF_PatchSeqRheobase.ipf | 135 ++++++++++++++++++ 3 files changed, 156 insertions(+), 3 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf index 036cff7968..edc0de31f8 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf @@ -139,6 +139,7 @@ static Function/S AD_GetResultMessage(variable anaFuncType, variable passed, WAV // PSQ_RB // - baseline QC // - Difference to initial DAScale larger than 60pA? + // - Out of range DAScale // - Not enough sweeps // PSQ_SE @@ -620,6 +621,13 @@ static Function/S AD_GetRheobaseFailMsg(WAVE numericalValues, WAVE/T textualValu string key, prefix, msg, pattern + key = CreateAnaFuncLBNKey(PSQ_RHEOBASE, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDASCale = GetLastSettingEachSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE) + + if(AD_LabnotebookEntryExistsAndIsTrue(oorDASCale)) + return AD_OOR_DASCALE_MSG + endif + prefix = AD_GetPerSweepFailMessage(PSQ_RHEOBASE, numericalValues, textualValues, sweepNo, sweepDFR, headstage) key = CreateAnaFuncLBNKey(PSQ_RHEOBASE, PSQ_FMT_LBN_SPIKE_DETECT, query = 1) diff --git a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf index 6b66b76d30..c74f16bbbd 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf @@ -4664,7 +4664,7 @@ End /// @endverbatim Function PSQ_Rheobase(string device, STRUCT AnalysisFunction_V3 &s) - variable DAScale, val, numSweeps, currentSweepHasSpike, lastSweepHasSpike, setPassed, diff + variable DAScale, val, numSweeps, currentSweepHasSpike, lastSweepHasSpike, setPassed, diff, limitCheck variable baselineQCPassed, finalDAScale, initialDAScale, stepSize, previousStepSize, samplingFrequencyPassed variable totalOnsetDelay, asyncAlarmPassed variable i, ret, numSweepsWithSpikeDetection, sweepNoFound, length, minLength, multiplier, chunk @@ -4742,7 +4742,7 @@ Function PSQ_Rheobase(string device, STRUCT AnalysisFunction_V3 &s) endif endif - SetDAScale(device, s.sweepNo, s.headstage, absolute = finalDAScale) + SetDAScale(device, s.sweepNo, s.headstage, absolute = finalDAScale, limitCheck = 0) return 0 @@ -4931,7 +4931,17 @@ Function PSQ_Rheobase(string device, STRUCT AnalysisFunction_V3 &s) break endif - SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale) + WAVE oorDAScale = LBN_GetNumericWave() + limitCheck = !AFH_LastSweepInSet(device, s.sweepNo, s.headstage, s.eventType) + oorDAScale[s.headstage] = SetDAScale(device, s.sweepNo, s.headstage, absolute = DAScale, limitCheck = limitCheck) + ReportOutOfRangeDAScale(device, s.sweepNo, PSQ_RHEOBASE, oorDAScale) + + if(oorDAScale[s.headstage]) + WAVE result = LBN_GetNumericWave() + key = CreateAnaFuncLBNKey(PSQ_RHEOBASE, PSQ_FMT_LBN_SET_PASS) + result[INDEP_HEADSTAGE] = 0 + ED_AddEntryToLabnotebook(device, key, result, unit = LABNOTEBOOK_BINARY_UNIT) + endif break case POST_SET_EVENT: WAVE numericalValues = GetLBNumericalValues(device) diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqRheobase.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqRheobase.ipf index fb8c4e385b..2e9dcb35f9 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqRheobase.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqRheobase.ipf @@ -117,6 +117,15 @@ static Function/WAVE GetStimScaleFactor_IGNORE(variable sweepNo, string device) return GetLastSettingEachRAC(numericalValues, sweepNo, STIMSET_SCALE_FACTOR_KEY, PSQ_TEST_HEADSTAGE, DATA_ACQUISITION_MODE) End +static Function/WAVE GetOORDAScale_IGNORE(variable sweepNo, string device) + + string key + + WAVE numericalValues = GetLBNumericalValues(device) + key = CreateAnaFuncLBNKey(PSQ_RHEOBASE, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + return GetLastSettingEachRAC(numericalValues, sweepNo, key, PSQ_TEST_HEADSTAGE, UNKNOWN_MODE) +End + static Function PS_RB1_preAcq(string device) Make/FREE asyncChannels = {2, 3} @@ -201,6 +210,12 @@ static Function PS_RB1_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), -1) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_WAVE(oorDAScale, NULL_WAVE) + + WAVE/Z baselineQCWave = GetBaselineQCResults_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(baselineQCWave, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520}) End @@ -278,6 +293,9 @@ static Function PS_RB2_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), -1) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) End @@ -355,6 +373,9 @@ static Function PS_RB3_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), -1) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) End @@ -432,6 +453,9 @@ static Function PS_RB4_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), 0) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) @@ -522,6 +546,9 @@ static Function PS_RB5_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), 1) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) End @@ -601,6 +628,9 @@ static Function PS_RB6_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), 2) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {NaN, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) End @@ -678,6 +708,9 @@ static Function PS_RB7_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), -1) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {NaN, NaN, 0, 0, 0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520}, sweep = 0) CheckPSQChunkTimes(str, {20, 520}, sweep = 1) @@ -772,6 +805,9 @@ static Function PS_RB8_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), 3) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) End @@ -856,6 +892,9 @@ static Function PS_RB9_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), 2) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) End @@ -938,6 +977,9 @@ static Function PS_RB10_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), -1) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) End @@ -1030,6 +1072,99 @@ static Function PS_RB11_REENTRY([string str]) CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), -1) + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_WAVE(oorDAScale, NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) CheckPSQChunkTimes(str, {20, 520}) End + +static Function PS_RB12_preAcq(string device) + + Make/FREE asyncChannels = {2, 3} + AFH_AddAnalysisParameter("Rheobase_DA_0", "AsyncQCChannels", wv = asyncChannels) + + SetAsyncChannelProperties(device, asyncChannels, -1e6, +1e6) + +#ifdef TESTS_WITH_NI_HARDWARE + SetFinalDAScale(3999e-12) +#else + SetFinalDAScale(4090e-12) +#endif +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function PS_RB12([string str]) + + [STRUCT DAQSettings s] = PS_GetDAQSettings(str) + AcquireData_NG(s, str) + + WAVE wv = PSQ_CreateOverrideResults(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE) + // baseline QC passes, async QC passes and no spikes at all + wv = 0 + wv[0, 1][][0] = 1 + wv[0, 1][][0] = 1 + wv[][][2] = 1 +End + +static Function PS_RB12_REENTRY([string str]) + + variable sweepNo, setPassed, i, numEntries, onsetDelay + variable initialDAScale, stepsize, finalDAScale + string key + + WAVE numericalValues = GetLBNumericalValues(str) + + sweepNo = 0 + numEntries = sweepNo + 1 + + key = CreateAnaFuncLBNKey(PSQ_RHEOBASE, PSQ_FMT_LBN_INITIAL_SCALE, query = 1) + initialDAScale = GetLastSettingIndepRAC(numericalValues, sweepNo, key, UNKNOWN_MODE) + CHECK_EQUAL_VAR(initialDAScale, PSQ_GetFinalDAScaleFake()) + + key = CreateAnaFuncLBNKey(PSQ_RHEOBASE, PSQ_FMT_LBN_SET_PASS, query = 1) + setPassed = GetLastSettingIndep(numericalValues, sweepNo, key, UNKNOWN_MODE) + CHECK_EQUAL_VAR(setPassed, 0) + + WAVE/Z samplingIntervalQCWave = GetSamplingIntervalQCResults_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(samplingIntervalQCWave, {1}, mode = WAVE_DATA) + + WAVE/Z asyncQCWave = GetAsyncQCResults_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(asyncQCWave, {1}, mode = WAVE_DATA) + + WAVE/Z baselineQCWave = GetBaselineQCResults_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(baselineQCWave, {1}, mode = WAVE_DATA) + + WAVE/Z spikeDetectionWave = GetSpikeResults_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(spikeDetectionWave, {0}, mode = WAVE_DATA) + +#ifdef TESTS_WITH_NI_HARDWARE + finalDAScale = 3999e-12 +#else + finalDAScale = 4090e-12 +#endif + + WAVE/Z stimScale = GetStimScaleFactor_IGNORE(sweepNo, str) + Make/FREE/D/N=(numEntries) stimScaleRef = (p * PSQ_RB_DASCALE_STEP_LARGE + finalDAScale) * ONE_TO_PICO + + CHECK_EQUAL_WAVES(stimScale, stimScaleRef, mode = WAVE_DATA, tol = 1e-14) + + WAVE/Z durations = GetPulseDurations_IGNORE(sweepNo, str) + Make/N=(numEntries)/FREE durationsRef = 3 + CHECK_EQUAL_WAVES(durations, durationsRef, mode = WAVE_DATA, tol = 0.01) + + key = CreateAnaFuncLBNKey(PSQ_RHEOBASE, PSQ_FMT_LBN_STEPSIZE_FUTURE, query = 1) + stepSize = GetLastSettingIndepRAC(numericalValues, sweepNo, key, UNKNOWN_MODE) + CHECK_EQUAL_VAR(stepSize, PSQ_RB_DASCALE_STEP_LARGE) + + WAVE/Z limitedResolution = GetLimitedResolution_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(limitedResolution, {0}, mode = WAVE_DATA, tol = 0.01) + + CHECK_EQUAL_VAR(MIES_PSQ#PSQ_GetLastPassingLongRHSweep(str, PSQ_TEST_HEADSTAGE, PSQ_RHEOBASE_TEST_DURATION), -1) + + WAVE/Z oorDAScale = GetOORDAScale_IGNORE(sweepNo, str) + CHECK_EQUAL_WAVES(oorDAScale, {1}, mode = WAVE_DATA) + + CommonAnalysisFunctionChecks(str, sweepNo, {setPassed}) + CheckPSQChunkTimes(str, {20, 520, 1023, 1523}) +End From ed7210fedf1a37937d1b0b9b48e0f4ee6d3f1ef4 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 22 Oct 2024 14:52:38 +0200 Subject: [PATCH 14/17] PSQ_Chirp: Add support for DAScale limit checks --- .../MIES/MIES_AnalysisFunctions_Dashboard.ipf | 8 ++ .../MIES/MIES_AnalysisFunctions_PatchSeq.ipf | 35 ++++- .../UTF_PatchSeqChirp.ipf | 134 +++++++++++++++++- 3 files changed, 170 insertions(+), 7 deletions(-) diff --git a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf index edc0de31f8..d54a1c47ce 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_Dashboard.ipf @@ -117,6 +117,7 @@ static Function/S AD_GetResultMessage(variable anaFuncType, variable passed, WAV // - baseline QC // - needs at least PSQ_CR_NUM_SWEEPS_PASS passing sweeps with the same to-full-pA rounded DAScale // - spike found while none expected (optional) + // - Out of range DAScale // PSQ_DA // - baseline QC @@ -687,6 +688,13 @@ static Function/S AD_GetChirpFailMsg(WAVE numericalValues, WAVE/T textualValues, string text = "" variable i, numSweeps, setPassed, maxOccurences + key = CreateAnaFuncLBNKey(PSQ_CHIRP, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDASCale = GetLastSettingEachSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE) + + if(AD_LabnotebookEntryExistsAndIsTrue(oorDASCale)) + return AD_OOR_DASCALE_MSG + endif + msg = AD_GetPerSweepFailMessage(PSQ_CHIRP, numericalValues, textualValues, sweepNo, sweepDFR, headstage, numRequiredPasses = PSQ_CR_NUM_SWEEPS_PASS) if(!IsEmpty(msg)) diff --git a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf index c74f16bbbd..3b2969912b 100644 --- a/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf +++ b/Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf @@ -6096,9 +6096,9 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) variable InnerRelativeBound, OuterRelativeBound, sweepPassed, setPassed, boundsAction, failsInSet, leftSweeps, chunk, multiplier variable length, minLength, DAC, resistance, passingDaScaleSweep, sweepsInSet, passesInSet, acquiredSweepsInSet, samplingFrequencyPassed variable targetVoltage, initialDAScale, baselineQCPassed, insideBounds, scalingFactorDAScale, initLPF, ampBesselFilter - variable fifoTime, i, ret, range, chirpStart, chirpDuration, userOnsetDelay, asyncAlarmPassed + variable fifoTime, i, ret, range, chirpStart, chirpDuration, userOnsetDelay, asyncAlarmPassed, limitCheck variable numberOfChirpCycles, cycleEnd, maxOccurences, level, numberOfSpikesFound, abortDueToSpikes, spikeCheck, besselFilterRestore - variable spikeCheckPassed, daScaleModifier, chirpEnd, numSweepsFailedAllowed, boundsEvaluationMode, stimsetPass + variable spikeCheckPassed, daScaleModifier, chirpEnd, numSweepsFailedAllowed, boundsEvaluationMode, stimsetPass, oorDAScalePassed string setName, key, msg, stimset, str, daScaleOperator innerRelativeBound = AFH_GetAnalysisParamNumerical("InnerRelativeBound", s.params) @@ -6231,7 +6231,8 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) result[INDEP_HEADSTAGE] = initialDAScale ED_AddEntryToLabnotebook(device, key, result, overrideSweepNo = s.sweepNo) - SetDAScale(device, s.sweepNo, s.headstage, absolute = initialDAScale, roundTopA = 1) + // not checking DAScale limits as we can't do that in PRE_SET_EVENT + SetDAScale(device, s.sweepNo, s.headstage, absolute = initialDAScale, roundTopA = 1, limitCheck = 0) WAVE result = LBN_GetNumericWave() key = CreateAnaFuncLBNKey(PSQ_CHIRP, PSQ_FMT_LBN_CR_INIT_UOD) @@ -6292,7 +6293,16 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) WAVE asyncChannels = AFH_GetAnalysisParamWave("AsyncQCChannels", s.params) asyncAlarmPassed = PSQ_CheckAsyncAlarmStateAndStoreInLabnotebook(device, PSQ_CHIRP, s.sweepNo, asyncChannels) - sweepPassed = (baselineQCPassed == 1 && insideBounds == 1 && samplingFrequencyPassed == 1 && asyncAlarmPassed == 1 && stimsetPass == 1) + key = CreateAnaFuncLBNKey(PSQ_CHIRP, PSQ_FMT_LBN_DASCALE_OOR, query = 1) + WAVE/Z oorDAScaleLBN = GetLastSetting(numericalValues, s.sweepNo, key, UNKNOWN_MODE) + oorDAScalePassed = !(WaveExists(oorDAScaleLBN) ? oorDAScaleLBN[s.headstage] : 0) + + sweepPassed = (baselineQCPassed == 1 \ + && insideBounds == 1 \ + && samplingFrequencyPassed == 1 \ + && asyncAlarmPassed == 1 \ + && stimsetPass == 1 \ + && oorDAScalePassed == 1) if(spikeCheck) sweepPassed = (sweepPassed == 1 && spikeCheckPassed == 1) @@ -6454,6 +6464,8 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) endif endif + limitCheck = !AFH_LastSweepInSet(device, s.sweepNo, s.headstage, s.eventType) + // no early return here because we want to do baseline QC checks (and chunk creation) always if(IsNaN(baselineQCPassed)) @@ -6470,7 +6482,10 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) // adapt DAScale and finish daScaleModifier = AFH_GetAnalysisParamNumerical("DAScaleModifier", s.params) daScaleOperator = AFH_GetAnalysisParamTextual("DAScaleOperator", s.params) - SetDAScaleModOp(device, s.sweepNo, s.headstage, daScaleModifier, daScaleOperator, roundTopA = 1) + + WAVE oorDAScale = LBN_GetNumericWave() + oorDAScale[s.headstage] = SetDAScaleModOp(device, s.sweepNo, s.headstage, daScaleModifier, daScaleOperator, roundTopA = 1, limitCheck = limitCheck) + ReportOutOfRangeDAScale(device, s.sweepNo, PSQ_CHIRP, oorDAScale) return ANALYSIS_FUNC_RET_EARLY_STOP endif @@ -6487,6 +6502,8 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) key = CreateAnaFuncLBNKey(PSQ_CHIRP, PSQ_FMT_LBN_CR_INSIDE_BOUNDS) ED_AddEntryToLabnotebook(device, key, result, overrideSweepNo = s.sweepNo, unit = LABNOTEBOOK_BINARY_UNIT) + WAVE oorDAScale = LBN_GetNumericWave() + switch(boundsAction) case PSQ_CR_PASS: case PSQ_CR_RERUN: // fallthrough-by-design @@ -6494,11 +6511,17 @@ Function PSQ_Chirp(string device, STRUCT AnalysisFunction_V3 &s) break case PSQ_CR_INCREASE: case PSQ_CR_DECREASE: // fallthrough-by-design - SetDAScale(device, s.sweepNo, s.headstage, relative = scalingFactorDAScale, roundTopA = 1) + oorDAScale[s.headstage] = SetDAScale(device, s.sweepNo, s.headstage, relative = scalingFactorDAScale, roundTopA = 1, limitCheck = limitCheck) + + if(oorDAScale[s.headstage]) + return ANALYSIS_FUNC_RET_EARLY_STOP + endif break default: ASSERT(0, "impossible case") endswitch + + ReportOutOfRangeDAScale(device, s.sweepNo, PSQ_CHIRP, oorDAScale) endif if(IsFinite(baselineQCPassed) && baselineQCPassed) diff --git a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqChirp.ipf b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqChirp.ipf index 43dc8c70a7..45eea7629d 100644 --- a/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqChirp.ipf +++ b/Packages/tests/HardwareAnalysisFunctions/UTF_PatchSeqChirp.ipf @@ -38,7 +38,7 @@ static Function/WAVE GetLBNEntriesWave_IGNORE() string list = "sweepPass;setPass;insideBounds;baselinePass;spikePass;stimsetPass;" \ + "boundsState;boundsAction;initialDAScale;DAScale;resistance;spikeCheck;" \ + "samplingPass;autobiasTargetV;initUserOnsetDelay;userOnsetDelay;asyncPass;" \ - + "initLowPassFilter;lowPassFilter" + + "initLowPassFilter;lowPassFilter;oorDAScale" Make/FREE/WAVE/N=(ItemsInList(list)) wv SetDimensionLabels(wv, list, ROWS) @@ -71,6 +71,7 @@ static Function/WAVE GetLBNEntries_IGNORE(string device, variable sweepNo) wv[%asyncPass] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_ASYNC_PASS) wv[%initLowPassFilter] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_CR_INIT_LPF) wv[%lowPassFilter] = GetLBNSingleEntry_IGNORE(device, sweepNo, "LPF cutoff") + wv[%oorDAScale] = GetLBNSingleEntry_IGNORE(device, sweepNo, PSQ_FMT_LBN_DASCALE_OOR) return wv End @@ -98,6 +99,7 @@ static Function/WAVE GetLBNSingleEntry_IGNORE(string device, variable sweepNo, s case PSQ_FMT_LBN_BL_QC_PASS: case PSQ_FMT_LBN_SPIKE_PASS: case PSQ_FMT_LBN_PULSE_DUR: + case PSQ_FMT_LBN_DASCALE_OOR: key = CreateAnaFuncLBNKey(PSQ_CHIRP, name, query = 1) return GetLastSettingEachSCI(numericalValues, sweepNo, key, PSQ_TEST_HEADSTAGE, UNKNOWN_MODE) case STIMSET_SCALE_FACTOR_KEY: @@ -219,6 +221,8 @@ static Function PS_CR1_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, empty, empty, incomplete = 1) @@ -299,6 +303,8 @@ static Function PS_CR2_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20 + 2, 520 + 2, 2020 + 2, 2520 + 2}, {522, 854.6995}, empty) @@ -376,6 +382,8 @@ static Function PS_CR2a_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) // CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 852.6995}) End @@ -452,6 +460,8 @@ static Function PS_CR2b_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 852.6995}, empty) @@ -530,6 +540,8 @@ static Function PS_CR3_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {14, 14, 14}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty // CheckChirpUserEpochs(str, {20, 520}, empty, incomplete = 1) @@ -637,6 +649,8 @@ static Function PS_CR4_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {14, 14, 14, 14, 14, 14}, mode = WAVE_DATA) CheckMCCLPF(str, 14) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, NaN, 0, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty @@ -747,6 +761,8 @@ static Function PS_CR4a_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, NaN, 0, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, {520, 1038.854}, empty, sweep = 0) @@ -856,6 +872,8 @@ static Function PS_CR4b_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, NaN, 0, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, {520, 1038.854}, empty, sweep = 0) @@ -964,6 +982,8 @@ static Function PS_CR5_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, NaN, 0, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, {520, 1038.854}, empty, sweep = 0) @@ -1075,6 +1095,8 @@ static Function PS_CR6_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, NaN, 0, NaN, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, {520, 1038.854}, empty, sweep = 0) @@ -1182,6 +1204,8 @@ static Function PS_CR7_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, {520, 1038.854}, empty, sweep = 0) @@ -1287,6 +1311,8 @@ static Function PS_CR8_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, {520, 1038.854}, empty, sweep = 0) @@ -1399,6 +1425,8 @@ static Function PS_CR9_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {NaN, NaN, 0, 0, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 1038.854}, empty, sweep = 0) @@ -1510,6 +1538,8 @@ static Function PS_CR9a_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {NaN, NaN, 0, 0, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 1038.854}, empty, sweep = 0) @@ -1621,6 +1651,8 @@ static Function PS_CR9b_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {NaN, NaN, 0, 0, NaN, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 1038.854}, empty, sweep = 0) @@ -1728,6 +1760,8 @@ static Function PS_CR10_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {NaN, 0, NaN, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 1038.854}, empty, sweep = 0) @@ -1816,6 +1850,8 @@ static Function PS_CR11_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, 0, 0}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, empty, empty, incomplete = 1) @@ -1899,6 +1935,8 @@ static Function PS_CR12_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 852.6995}, {520, 1519.992}) End @@ -1994,6 +2032,8 @@ static Function PS_CR13_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, NaN, NaN, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, empty, empty, sweep = 0, incomplete = 1) @@ -2094,6 +2134,8 @@ static Function PS_CR13a_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, NaN, NaN, 0, NaN}, mode = WAVE_DATA) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20 + 2, 520 + 2}, empty, empty, sweep = 0, incomplete = 1) @@ -2103,6 +2145,86 @@ static Function PS_CR13a_REENTRY([string str]) CheckChirpUserEpochs(str, {20 + 2, 520 + 2, 2020 + 2, 2520 + 2}, {520 + 2, 1038.854 + 2}, {520 + 2, 1519.992 + 2}, sweep = 4) End +static Function PS_CR13b_preAcq(string device) + + AFH_AddAnalysisParameter("PatchSeqChirp_DA_0", "SpikeCheck", var = 1) + AFH_AddAnalysisParameter("PatchSeqChirp_DA_0", "FailedLevel", var = 10) + AFH_AddAnalysisParameter("PatchSeqChirp_DA_0", "DAScaleOperator", str = "*") + AFH_AddAnalysisParameter("PatchSeqChirp_DA_0", "DAScaleModifier", var = 100) + AFH_AddAnalysisParameter("PatchSeqChirp_DA_0", "BoundsEvaluationMode", str = "Symmetric") + AFH_AddAnalysisParameter("PatchSeqChirp_DA_0", "NumberOfFailedSweeps", var = 3) + AFH_AddAnalysisParameter("PatchSeqChirp_DA_0", "UserOnsetDelay", var = 2) + + Make/FREE asyncChannels = {2, 3} + AFH_AddAnalysisParameter("PatchSeqChirp_DA_0", "AsyncQCChannels", wv = asyncChannels) + + SetAsyncChannelProperties(device, asyncChannels, -1e6, +1e6) +End + +// UTF_TD_GENERATOR DeviceNameGeneratorMD1 +static Function PS_CR13b([string str]) + + [STRUCT DAQSettings s] = PS_GetDAQSettings(str) + AcquireData_NG(s, str) + + WAVE wv = PSQ_CreateOverrideResults(str, PSQ_TEST_HEADSTAGE, PSQ_CHIRP) + wv = 0 + + // layer 0: BL passes + wv[][][0] = 1 + + // layer 3: Spikes check during chirp passes + wv[][][3] = 0 + + // layer 4: async QC passes + wv[][][4] = 1 +End + +static Function PS_CR13b_REENTRY([string str]) + + variable sweepNo, setPassed + string key + + sweepNo = 1 + + WAVE/WAVE lbnEntries = GetLBNEntries_IGNORE(str, sweepNo) + + CHECK_EQUAL_WAVES(lbnEntries[%sweepPass], {0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%setPass], {0}, mode = WAVE_DATA) + CHECK_WAVE(lbnEntries[%baselinePass], NULL_WAVE) + CHECK_EQUAL_WAVES(lbnEntries[%samplingPass], {1, 1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%asyncPass], {1, 1}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%spikePass], {0, 0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%stimsetPass], {1, 1}, mode = WAVE_DATA) + + CHECK_WAVE(lbnEntries[%insideBounds], NULL_WAVE) + CHECK_WAVE(lbnEntries[%boundsState], NULL_WAVE) + CHECK_WAVE(lbnEntries[%boundsAction], NULL_WAVE) + + CHECK_EQUAL_WAVES(lbnEntries[%initialDAScale], {30e-12}, mode = WAVE_DATA, tol = 1e-14) + CHECK_EQUAL_WAVES(lbnEntries[%DAScale], {30, 3000}, mode = WAVE_DATA, tol = 1e-14) + CHECK_EQUAL_WAVES(lbnEntries[%resistance], {1e9}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%spikeCheck], {1}, mode = WAVE_DATA) + + CHECK_EQUAL_WAVES(lbnEntries[%autobiasTargetV], {70, 70}, mode = WAVE_DATA) + CHECK_EQUAL_VAR(DAG_GetNumericalValue(str, "setvar_DataAcq_AutoBiasV"), 70) + + CHECK_EQUAL_WAVES(lbnEntries[%initUserOnsetDelay], {0}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%userOnsetDelay], {2, 2}, mode = WAVE_DATA) + CHECK_EQUAL_VAR(DAG_GetNumericalValue(str, "setvar_DataAcq_OnsetDelayUser"), 0) + + CHECK_EQUAL_WAVES(lbnEntries[%initLowPassFilter], {LPF_BYPASS}, mode = WAVE_DATA) + CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) + CheckMCCLPF(str, LPF_BYPASS) + + CHECK_EQUAL_WAVES(lbnEntries[%oorDAScale], {0, 1}, mode = WAVE_DATA) + + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) + Make/FREE/N=0 empty + CheckChirpUserEpochs(str, {20 + 2, 520 + 2}, empty, empty, sweep = 0, incomplete = 1) + CheckChirpUserEpochs(str, {20 + 2, 520 + 2}, empty, empty, sweep = 1, incomplete = 1) +End + // No a, b as boundsState evaluation is always passing static Function PS_CR14_preAcq(string device) @@ -2177,6 +2299,8 @@ static Function PS_CR14_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, empty, empty, incomplete = 1) @@ -2260,6 +2384,8 @@ static Function PS_CR15_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 852.6995}, empty) @@ -2344,6 +2470,8 @@ static Function PS_CR16_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520, 2020, 2520}, {520, 852.6995}, empty) @@ -2425,6 +2553,8 @@ static Function PS_CR17_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF, PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, {20, 520}, empty, empty, sweep = 0, incomplete = 1) @@ -2506,6 +2636,8 @@ static Function PS_CR18_REENTRY([string str]) CHECK_EQUAL_WAVES(lbnEntries[%lowPassFilter], {PSQ_CR_DEFAULT_LPF}, mode = WAVE_DATA) CheckMCCLPF(str, LPF_BYPASS) + CHECK_WAVE(lbnEntries[%oorDAScale], NULL_WAVE) + CommonAnalysisFunctionChecks(str, sweepNo, lbnEntries[%setPass]) Make/FREE/N=0 empty CheckChirpUserEpochs(str, empty, empty, empty, incomplete = 1) From 468ef414a724d5655d0f9d4f2cd6eee79f771f63 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 5 Nov 2024 11:45:36 +0100 Subject: [PATCH 15/17] MIES_Constants.ipf: Raise versions --- Packages/MIES/MIES_Constants.ipf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Packages/MIES/MIES_Constants.ipf b/Packages/MIES/MIES_Constants.ipf index 2378e061e6..994631d7b3 100644 --- a/Packages/MIES/MIES_Constants.ipf +++ b/Packages/MIES/MIES_Constants.ipf @@ -47,16 +47,16 @@ Constant RESULTS_VERSION = 3 ///@{ Constant PSQ_PIPETTE_BATH_VERSION = 4 Constant PSQ_ACC_RES_SMOKE_VERSION = 2 -Constant PSQ_CHIRP_VERSION = 13 -Constant PSQ_DA_SCALE_VERSION = 11 -Constant PSQ_RAMP_VERSION = 6 -Constant PSQ_RHEOBASE_VERSION = 5 -Constant PSQ_SQUARE_PULSE_VERSION = 4 +Constant PSQ_CHIRP_VERSION = 14 +Constant PSQ_DA_SCALE_VERSION = 12 +Constant PSQ_RAMP_VERSION = 7 +Constant PSQ_RHEOBASE_VERSION = 6 +Constant PSQ_SQUARE_PULSE_VERSION = 5 Constant PSQ_SEAL_EVALUATION_VERSION = 3 Constant PSQ_TRUE_REST_VM_VERSION = 2 -Constant MSQ_FAST_RHEO_EST_VERSION = 1 -Constant MSQ_DA_SCALE_VERSION = 1 -Constant SC_SPIKE_CONTROL_VERSION = 2 +Constant MSQ_FAST_RHEO_EST_VERSION = 2 +Constant MSQ_DA_SCALE_VERSION = 2 +Constant SC_SPIKE_CONTROL_VERSION = 3 ///@} /// Especially interesting for PXP consumers like the analysis browser. From 15ef1deb4242e0210a6f137f1bf368c6df3e03ae Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Tue, 5 Nov 2024 13:15:45 +0100 Subject: [PATCH 16/17] Packages/doc/dot: Adapt flowcharts for out of range DAScale values --- Packages/doc/dot/multi-patch-seq-dascale.dot | 20 +- .../multi-patch-seq-fast-rheo-estimate.dot | 31 ++- .../doc/dot/multi-patch-seq-spike-control.dot | 45 ++-- Packages/doc/dot/patch-seq-chirp.dot | 209 +++++++++--------- Packages/doc/dot/patch-seq-dascale.dot | 95 ++++---- Packages/doc/dot/patch-seq-rheobase.dot | 29 ++- Packages/doc/dot/patch-seq-squarepulse.dot | 22 +- 7 files changed, 264 insertions(+), 187 deletions(-) diff --git a/Packages/doc/dot/multi-patch-seq-dascale.dot b/Packages/doc/dot/multi-patch-seq-dascale.dot index d83ffebae5..700880dee4 100644 --- a/Packages/doc/dot/multi-patch-seq-dascale.dot +++ b/Packages/doc/dot/multi-patch-seq-dascale.dot @@ -33,18 +33,23 @@ digraph G { "Prepare DAQ" -> "Enable \"Multidevice DAQ\""; "Pre Set Event" -> "Enable \"Autobias\""; "Pre Set Event" -> "Set next DAScale value,\nuse the analysis parameter values as offset\nonto the earlier FastRheoEstimate guess"; - "Post Sweep Event" -> "Set next DAScale value,\nuse the analysis parameter values as offset\nonto the earlier FastRheoEstimate guess"; - "Post Sweep Event" -> "Mark all active headstages as passed"; + n32 [label="Check if setting the DAScale value\n for the next sweep\n would be out of range"]; + "Post Sweep Event" -> n32; "Post Set Event" -> "Read active headstages from labnotebook\nand turn them all on again"; "Enable \"Multidevice DAQ\"" -> "Enable \"Repeated Acquisition\""; "Enable \"Autobias\"" -> "Enable \"Insert TP\""; "Mark all active headstages as passed" -> "Mark Sweep as passed"; + "Mark set as passed" [label="Are all sweeps passing?"]; "Read active headstages from labnotebook\nand turn them all on again" -> "Mark set as passed"; + "Read active headstages from labnotebook\nand turn them all on again" -> "Update Dashboard"; n29 [label="\"Unlocked Indexing\" is active"]; "Enable \"Repeated Acquisition\"" -> n29; "Enable \"Insert TP\"" -> "Enable \"TP during ITI\""; "Enable \"Insert TP\"" -> "Force Sampling Multiplier to 1"; - "Mark set as passed" -> "Update Dashboard"; + n39 [label="Mark set as passed"]; + "Mark set as passed" -> n39 [label=Yes]; + n40 [label="Mark set as failed"]; + "Mark set as passed" -> n40 [label=No]; n29 -> Abort [label=Yes]; "Enable \"TP during ITI\"" -> "Valid Autobias voltage (finite and non-zero)"; "Force Sampling Multiplier to 1" -> "Check if no TTL channels are active"; @@ -58,4 +63,13 @@ digraph G { "Turn off active non-IC headstages\nor headstages which have not passed FastRheoEstimate" -> "Check if there is at least\none active IC headstage"; "Check if there is at least\none active IC headstage" -> "All checks passed"; "All checks passed" -> Abort [label=No]; + n33 [label="Set DAScale"]; + n32 -> n33 [label=No]; + n35 [label="Mark headstage as failed, others as passing"]; + n32 -> n35 [label=Yes]; + n33 -> "Mark all active headstages as passed"; + n36 [label="Add \"DAScale out of range\" labnotebook entry"]; + n35 -> n36; + n37 [label="Mark Sweep as failed"]; + n36 -> n37; } diff --git a/Packages/doc/dot/multi-patch-seq-fast-rheo-estimate.dot b/Packages/doc/dot/multi-patch-seq-fast-rheo-estimate.dot index 60e4b63705..4831efeb4f 100644 --- a/Packages/doc/dot/multi-patch-seq-fast-rheo-estimate.dot +++ b/Packages/doc/dot/multi-patch-seq-fast-rheo-estimate.dot @@ -35,6 +35,9 @@ digraph G { "Write initial stepsize of 100pA into\nlabnotebook for all active IC headstages" -> "Set \"DAScale exceeded\" labnotebook entry\nto false for all active IC headstages"; "Set \"DAScale exceeded\" labnotebook entry\nto false for all active IC headstages" -> "Store active headstages in labnotebook"; "Store active headstages in labnotebook" -> "Turn off active non-IC headstages"; + "Turn off active non-IC headstages" -> "Set \"User onset delay\" to 0ms"; + "Set \"User onset delay\" to 0ms" -> "Set \"Termination delay\" to 0 ms"; + "Set \"Termination delay\" to 0 ms" -> "Disable \"dDAQ\"/\"oodDAQ\""; "Start DAQ/RA (only call for last active headstage)" -> "Prepare DAQ/Pre Set Event"; "Start DAQ/RA (only call for last active headstage)" -> "Post Sweep Event"; "Start DAQ/RA (only call for last active headstage)" -> "Post DAQ Event"; @@ -44,22 +47,27 @@ digraph G { "Post Sweep Event" -> "Iterate over all active headstages"; "Post Sweep Event" -> "Store pulse duration in labnotebook"; "Post DAQ Event" -> "Update Dashboard"; - "Post Set Event" -> "Mark set as passed if 1 sweep passed,\nas failure otherwise"; "Post Set Event" -> "Set \"TP during ITI\" to enabled"; + n59 [label="Do we have a \"DAScale out of range\" labnotebook entry\n in the SCI"]; + "Post Set Event" -> n59; n60 -> "Enable \"Multidevice DAQ\""; "Iterate over all active headstages" -> "Active headstages left?"; - "Mark set as passed if 1 sweep passed,\nas failure otherwise" -> "Analysis parameter \"PostDAQSetDAScale\" is true"; "Set \"TP during ITI\" to enabled" -> "Set \"TP inserting\" to enabled"; + n59 -> "Mark set as passed if 1 sweep passed,\nas failure otherwise" [label=No]; + n62 [label="Mark set as failed"]; + n59 -> n62 [label=Yes]; "Enable \"Multidevice DAQ\"" -> "Enable \"Repeated Acquisition\""; "Active headstages left?" -> "Have all headstages passed in one sweep\nof their stimset cycle?" [label=No]; "Active headstages left?" -> "Headstage passed?" [label=Yes]; - "Analysis parameter \"PostDAQSetDAScale\" is true" -> "Set DAScale to the stored LBN value taking into account\nthe analysis parameter \"PostDAQDAScaleFactor\"\nand \"PostDAQDAScaleMinOffset\"\ -.\nSet it to \"PostDAQDAScaleForFailedHS\" for failed headstages."; + "Mark set as passed if 1 sweep passed,\nas failure otherwise" -> "Analysis parameter \"PostDAQSetDAScale\" is true"; + n62 -> "Analysis parameter \"PostDAQSetDAScale\" is true"; n61 [label="Is \"Unlocked indexing\" active"]; "Enable \"Repeated Acquisition\"" -> n61; "Have all headstages passed in one sweep\nof their stimset cycle?" -> "Mark sweep as failed" [label=No]; "Have all headstages passed in one sweep\nof their stimset cycle?" -> "Mark sweep as passed" [label=Yes]; "Headstage passed?" -> "Headstage exceeded DAScale\n according to labnotebook entry?" [label=No]; + "Analysis parameter \"PostDAQSetDAScale\" is true" -> "Set DAScale to the stored LBN value taking into account\nthe analysis parameter \"PostDAQDAScaleFactor\"\nand \"PostDAQDAScaleMinOffset\"\ +.\nSet it to \"PostDAQDAScaleForFailedHS\" for failed headstages."; "Set DAScale to the stored LBN value taking into account\nthe analysis parameter \"PostDAQDAScaleFactor\"\nand \"PostDAQDAScaleMinOffset\"\ .\nSet it to \"PostDAQDAScaleForFailedHS\" for failed headstages." -> "Read active headstages from labnotebook\nand turn them all on again"; n61 -> Abort [label=Yes]; @@ -76,20 +84,25 @@ digraph G { "Step size from labnotebook? (2)" -> "Offset DAScale by +10pA" [label="+10pA"]; "Step size from labnotebook? (2)" -> "Offset DAScale by +100pA" [label="+100pA"]; "Store DAScale in labnotebook" -> "Mark headstage as passed"; + "Mark headstage as failed" [label="Would the new DAScale value\n for the next sweep be out of range?"]; "Offset DAScale by -50pA" -> "Mark headstage as failed"; "Write step size of -50pA to labnotebook" -> "Offset DAScale by -50pA"; "Write step size of +10pA to labnotebook" -> "Offset DAScale by +10pA"; "Offset DAScale by +10pA" -> "Mark headstage as failed"; "Offset DAScale by +100pA" -> "Mark headstage as failed"; "Mark headstage as passed" -> "Set DAScale to zero"; - "Mark headstage as failed" -> "\"MaximumDAScale\" analysis parameter is not NaN?"; + n64 [label="Add \"DAScale out of range\" labnotebook entry"]; + "Mark headstage as failed" -> n64 [label=Yes]; + n68 [label="Set DAScale"]; + "Mark headstage as failed" -> n68; + n66 [label="Mark headstage as failed"]; + n64 -> n66; + n68 -> n66; + n66 -> "\"MaximumDAScale\" analysis parameter is not NaN?"; "\"MaximumDAScale\" analysis parameter is not NaN?" -> "DAScale is larger than \"MaximumDAScale\"?" [label=Yes]; - "Turn off active non-IC headstages" -> "Set \"User onset delay\" to 0ms"; "DAScale is larger than \"MaximumDAScale\"?" -> "Mark headstage as \"DAScale exceeded\"\nin labnotebook" [label=Yes]; + "Mark headstage as \"DAScale exceeded\"\nin labnotebook" -> "Set DAScale to zero"; "Disable \"dDAQ\"/\"oodDAQ\"" -> "Set \"TP during ITI\" to disabled"; "Set \"TP during ITI\" to disabled" -> "Set \"ITI\" to 100ms"; "Set \"ITI\" to 100ms" -> "Set \"TP inserting\" to disabled"; - "Set \"User onset delay\" to 0ms" -> "Set \"Termination delay\" to 0 ms"; - "Set \"Termination delay\" to 0 ms" -> "Disable \"dDAQ\"/\"oodDAQ\""; - "Mark headstage as \"DAScale exceeded\"\nin labnotebook" -> "Set DAScale to zero"; } diff --git a/Packages/doc/dot/multi-patch-seq-spike-control.dot b/Packages/doc/dot/multi-patch-seq-spike-control.dot index 032a94deb4..7bd77060eb 100644 --- a/Packages/doc/dot/multi-patch-seq-spike-control.dot +++ b/Packages/doc/dot/multi-patch-seq-spike-control.dot @@ -124,16 +124,38 @@ on some pulses\n and \"Too Many\" on others."]; n51 -> n52 [label=True]; n53 [label="Mark sweep as failed"]; n51 -> n53 [label=False]; + n74 [label="Was spontaneous spiking detected?"]; + n88 -> n74 [label=Failed]; + n79 [label="Spike Count state?"]; + n88 -> n79 [label=Failed]; + n94 [label="Spike position passed?"]; + n88 -> n94 [label=Passed]; n63 [label="Mark set as passed if all IC headstages\n passed with all set sweep counts."]; n52 -> n63; n54 [label="Analysis parameter \"Max Trials\" present?"]; n53 -> n54; + n75 [label="Add \"Auto bias baseline modifier\" analysis parameter\n value to autobias target voltage"]; + n74 -> n75 [label=Yes]; + n81 [label="Decrease DA Scale according to analysis parameters\n \"DaScaleTooManySpikesModifier\" and \"DaScaleTooManySpikesOperator\""]; + n79 -> n81 [label="Too Many"]; + n82 [label="Warn user in history once\nduring this RA cycle"]; + n79 -> n82 [label=Mixed]; + n83 [label="Increase DA scale according to analysis parameters\n \"DAScaleModifier\"\n and \"DAScaleOperator\""]; + n79 -> n83 [label="Too Few"]; + n77 [label="Increase DA scale according to analysis parameters\n \"DAScaleSpikePositionModifier\"\n and \"DAScaleSpikePositionOperator\""]; + n94 -> n77 [label=Failed]; n70 [label="Set passed?"]; n63 -> n70; n55 [label="Check if the current trial count\nof the current set sweep count\n exceeds \"Max Trials\""]; n54 -> n55 [label=Yes]; n56 [label="Skip back one sweep"]; n54 -> n56 [label=No]; + n76 [label="Would the new DA scale for the next sweep be out of range?"]; + n81 -> n76; + n62 [label="Increase DA scale according to analysis parameters\n \"DAScaleModifier\" and \"DAScaleOperator\""]; + n82 -> n62; + n83 -> n76; + n77 -> n76; n65 [label="Analysis parameter \"Max Trials\" present? [2]"]; n70 -> n65 [label=No]; n68 [label="Skip to end of active set"]; @@ -142,27 +164,14 @@ on some pulses\n and \"Too Many\" on others."]; n57 [label="Add \"Rerun Trials Exceeded\"\n into numerical labnotebook"]; n55 -> n57 [label=Yes]; n56 -> n63; + n90 [label="Add \"DAScale out of range\" labnotebook entry"]; + n76 -> n90 [label=Yes]; + n62 -> n76; n66 [label="Was it reached on all IC headstages?"]; n65 -> n66 [label=Yes]; n67 [label="Mark set as failed"]; n66 -> n67; n67 -> n68; - n74 [label="Was spontaneous spiking detected?"]; - n88 -> n74 [label=Failed]; - n79 [label="Spike Count state?"]; - n88 -> n79 [label=Failed]; - n94 [label="Spike position passed?"]; - n88 -> n94 [label=Passed]; - n75 [label="Add \"Auto bias baseline modifier\" analysis parameter\n value to autobias target voltage"]; - n74 -> n75 [label=Yes]; - n81 [label="Decrease DA Scale according to analysis parameters\n \"DaScaleTooManySpikesModifier\" and \"DaScaleTooManySpikesOperator\""]; - n79 -> n81 [label="Too Many"]; - n82 [label="Warn user in history once\nduring this RA cycle"]; - n79 -> n82 [label=Mixed]; - n83 [label="Increase DA scale according to analysis parameters\n \"DAScaleModifier\"\n and \"DAScaleOperator\""]; - n79 -> n83 [label="Too Few"]; - n77 [label="Increase DA scale according to analysis parameters\n \"DAScaleSpikePositionModifier\"\n and \"DAScaleSpikePositionOperator\""]; - n94 -> n77 [label=Failed]; - n62 [label="Increase DA scale according to analysis parameters\n \"DAScaleModifier\" and \"DAScaleOperator\""]; - n82 -> n62; + n96 [label="Mark sweep as failed"]; + n90 -> n96; } diff --git a/Packages/doc/dot/patch-seq-chirp.dot b/Packages/doc/dot/patch-seq-chirp.dot index ffc466bd10..d7b47afe89 100644 --- a/Packages/doc/dot/patch-seq-chirp.dot +++ b/Packages/doc/dot/patch-seq-chirp.dot @@ -31,147 +31,156 @@ digraph G { "Start DAQ/RA" -> "Prepare DAQ/Pre Set Event"; "Mid Sweep Event" -> "BL QC passed?"; "Mid Sweep Event" -> "\"Inside Bounds\" labnotebook\n entry present?"; - n63 [label="Is \"SpikeCheck\" enabled?\n (Given by optional analysis parameter\n \"SpikeCheck\" defaulting to 1)"]; + n63 [label="Is \"SpikeCheck\" enabled?\n (Given by optional analysis parameter\n \"SpikeCheck\" defaulting to 1)"]; "Mid Sweep Event" -> n63; - n91 [URL="../_static/images/async-qc-channels.svg", + n91 [URL="../_static/images/async-qc-channels.svg", label="Standard AsyncQCChannels handling", target=_graphviz]; "Pre Sweep Config Event" -> n91; "Post DAQ Event" -> "Update Dashboard"; "Post Set Event" -> "Update Dashboard"; - "Post Set Event" -> "Has three passing sweeps in set\n with the same DAScale value? [1]"; - n84 [label="Set \"Delay onset user\" back from labnotebook entry"]; + n84 [label="Set \"Delay onset user\" back from labnotebook entry"]; "Post Set Event" -> n84; - n97 [label="Read analysis parameter\n \"AmpBesselFilterRestore\",\n defaulting to true."]; + n97 [label="Read analysis parameter\n \"AmpBesselFilterRestore\",\n defaulting to true."]; "Post Set Event" -> n97; - n92 [URL="../_static/images/async-qc-channels.svg", + n92 [URL="../_static/images/async-qc-channels.svg", label="Standard AsyncQCChannels handling", target=_graphviz]; "Post Sweep Event" -> n92; "Prepare DAQ/Pre Set Event" -> "Enable \"Autobias\""; "Prepare DAQ/Pre Set Event" -> "Valid Autobias voltage (finite and non-zero)"; - n95 [label="Store amplifier setting\n LPF primary output in labnotebook"]; + n95 [label="Store amplifier setting\n LPF primary output in labnotebook"]; "Prepare DAQ/Pre Set Event" -> n95; - "BL QC passed?" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=No]; - "Calculate number of cycles\n in chirp, store in labnotebook" [label="Add stimset QC entry\nwhich denotes if the stimset is suitable"]; - "\"Inside Bounds\" labnotebook\n entry present?" -> "Calculate number of cycles\n in chirp, store in labnotebook" [label=No]; - n64 [label="Store Spike check in labnotebook"]; + "BL QC passed?" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=No]; + "Calculate number of cycles\n in chirp, store in labnotebook" [label="Add stimset QC entry\nwhich denotes if the stimset is suitable"]; + "\"Inside Bounds\" labnotebook\n entry present?" -> "Calculate number of cycles\n in chirp, store in labnotebook" [label=No]; + n64 [label="Store Spike check in labnotebook"]; n63 -> n64; - n65 [label="Spike QC labnotebook entry found?"]; + n65 [label="Spike QC labnotebook entry found?"]; n63 -> n65; - "Has three passing sweeps in set\n with the same DAScale value? [1]" -> "Mark set as failed\n in labnotebook" [label=No]; - "Has three passing sweeps in set\n with the same DAScale value? [1]" -> "Mark set as passed\n in labnotebook" [label=Yes]; - n98 [label="Set amplifier setting\n LPF primary output\n from labnotebook entry"]; - n97 -> n98 [label=True]; - n73 [label="\"Spike Check\" labnotebook entry is true?"]; + n98 [label="Set amplifier setting\n LPF primary output\n from labnotebook entry"]; + n97 -> n98 [label=True]; + n73 [label="\"Spike Check\" labnotebook entry is true?"]; n92 -> n73; "Enable \"Autobias\"" -> "Enable \"TP during ITI\""; "Valid Autobias voltage (finite and non-zero)" -> "Check if no TTL channels are active"; - n96 [label="Use \"AmpBesselFilter\" analysis parameter\n (defaulting to 10e3 if not present)\n as LPF primary output"]; + n96 [label="Use \"AmpBesselFilter\" analysis parameter\n (defaulting to 10e3 if not present)\n as LPF primary output"]; n95 -> n96; - "Grab next completely acquired chunk\n(500ms) of stimset baseline" -> "Chunk already evaluated?" [label="Have one"]; - "Grab next completely acquired chunk\n(500ms) of stimset baseline" -> "Last chunk?" [label="None left"]; - n99 [label="Early sweep stop\nand jump to end of set"]; - "Calculate number of cycles\n in chirp, store in labnotebook" -> n99 [label=Failed]; - n100 [labell="Add user epoch for chirp evaluation cycles"]; - "Calculate number of cycles\n in chirp, store in labnotebook" -> n100 [label=Passed]; - n66 [label="Has acquired data in chirp region?"]; - n65 -> n66 [label=No]; - n87 [label="Read analysis parameter \"UseTrueRestingMembranePotentialVoltage\",\n defaulting to true."]; + "Grab next completely acquired chunk\n(500ms) of stimset baseline" -> "Chunk already evaluated?" [label="Have one"]; + "Grab next completely acquired chunk\n(500ms) of stimset baseline" -> "Last chunk?" [label="None left"]; + n99 [label="Early sweep stop\nand jump to end of set"]; + "Calculate number of cycles\n in chirp, store in labnotebook" -> n99 [label=Failed]; + n100 [labell="Add user epoch for chirp evaluation cycles"]; + "Calculate number of cycles\n in chirp, store in labnotebook" -> n100 [label=Passed]; + n66 [label="Has acquired data in chirp region?"]; + n65 -> n66 [label=No]; + "Has three passing sweeps in set\n with the same DAScale value? [1]" -> "Mark set as failed\n in labnotebook" [label=No]; + "Has three passing sweeps in set\n with the same DAScale value? [1]" -> "Mark set as passed\n in labnotebook" [label=Yes]; + n87 [label="Read analysis parameter \"UseTrueRestingMembranePotentialVoltage\",\n defaulting to true."]; "Mark set as passed\n in labnotebook" -> n87; - n73 -> "Has BL QC and \"Inside Bounds\"\n entries being true in labnotebook?" [label=No]; - n74 [label="Spike QC passed?"]; - n73 -> n74 [label=Yes]; + n73 -> "Has BL QC and \"Inside Bounds\"\n entries being true in labnotebook?" [label=No]; + n74 [label="Spike QC passed?"]; + n73 -> n74 [label=Yes]; "Enable \"TP during ITI\"" -> "Enable \"Multidevice DAQ\""; "Check if no TTL channels are active" -> "Stimset is large enough"; - "Chunk already evaluated?" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=Yes]; - "Chunk already evaluated?" -> "Baseline chunk type" [label=No]; - "Last chunk?" -> "Mark Sweep as failed" [label=Yes]; - "Acquired requested number of cycles?\n(Given by optional analysis parameter\n\"NumberOfChirpCycles\" defaulting to 1.)" -> "Calculate min/max of AD data during these cycles" [label=Yes]; - n68 [label="Has spike in AD data of acquired chirp region?\nUses \"FailedLevel\" analysis parameter for spike search."]; - n66 -> n68 [label=Yes]; - n80 [label="Is the analysis parameter \"AutobiasTargetVAtSetEnd\" present?\n If yes, set the autobias target voltage to it."]; - n87 -> n80 [label=False]; - n88 [label="Find passing set with PSQ_TrueRestingMembranePotential\n analysis function"]; - n87 -> n88 [label=True]; - "Has BL QC and \"Inside Bounds\"\n entries being true in labnotebook?" -> "Mark sweep as failed\n in labnotebook" [label=No]; - n76 [label="Read \"SamplingFrequency\" analysis parameter\n (defaulting to 50kHz) if not present"]; - "Has BL QC and \"Inside Bounds\"\n entries being true in labnotebook?" -> n76 [label=Yes]; - n74 -> "Has BL QC and \"Inside Bounds\"\n entries being true in labnotebook?" [label=Yes]; - n74 -> "Mark sweep as failed\n in labnotebook" [label=No]; - "Mark sweep as failed\n in labnotebook" -> "Has three passing sweeps in set\n with the same DAScale value? [2]"; - n85 [label="Check if the acquired data\n has that sampling interval"]; - n76 -> n85; + "Chunk already evaluated?" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=Yes]; + "Chunk already evaluated?" -> "Baseline chunk type" [label=No]; + "Last chunk?" -> "Mark Sweep as failed" [label=Yes]; + n100 -> "Acquired requested number of cycles?\n(Given by optional analysis parameter\n\"NumberOfChirpCycles\" defaulting to 1.)"; + n68 [label="Has spike in AD data of acquired chirp region?\nUses \"FailedLevel\" analysis parameter for spike search."]; + n66 -> n68 [label=Yes]; + n80 [label="Is the analysis parameter \"AutobiasTargetVAtSetEnd\" present?\n If yes, set the autobias target voltage to it."]; + n87 -> n80 [label=False]; + n88 [label="Find passing set with PSQ_TrueRestingMembranePotential\n analysis function"]; + n87 -> n88 [label=True]; + "Has BL QC and \"Inside Bounds\"\n entries being true in labnotebook?" -> "Mark sweep as failed\n in labnotebook" [label=No]; + n76 [label="Read \"SamplingFrequency\" analysis parameter\n (defaulting to 50kHz) if not present"]; + "Has BL QC and \"Inside Bounds\"\n entries being true in labnotebook?" -> n76 [label=Yes]; + n74 -> "Has BL QC and \"Inside Bounds\"\n entries being true in labnotebook?" [label=Yes]; + n74 -> "Mark sweep as failed\n in labnotebook" [label=No]; "Enable \"Multidevice DAQ\"" -> "Disable \"dDAQ\"/\"oodDAQ\""; "Stimset is large enough" -> "Check if mode is IC"; - "Baseline chunk type" -> "Check RMS short" [label="pre pulse"]; - "Baseline chunk type" -> "Check target voltage [2]" [label="post pulse"]; - "Calculate min/max of AD data during these cycles" -> "Determine bounds state and action\n from min/max values and table\n store in labnotebook"; - n69 [label="Add Spike QC failed labnotebook entry"]; - n68 -> n69 [label=Yes]; - n71 [label="Has acquired past the end of chirp?"]; - n68 -> n71 [label=No]; - n88 -> n80 [label=None]; - n90 [label="Read full average voltage from labnotebook\n from that sweep and set it as autobias target voltage."]; - n88 -> n90 [label=Found]; - "Has three passing sweeps in set\n with the same DAScale value? [2]" -> "Skip to end of set" [label=Yes]; - "Has three passing sweeps in set\n with the same DAScale value? [2]" -> "Read analysis parameter \"NumberOfFailedSweeps\",\n if not present use 3.\n Have that many sweeps failed?" [label=No]; - n85 -> "Mark sweep as failed\n in labnotebook" [label=No]; - n85 -> "Skip to end of DAQ" [label=No]; - n93 [label="Has Async Channels QC\n labnotebook entry passed?"]; - n85 -> n93 [label=Yes]; + "Baseline chunk type" -> "Check RMS short" [label="pre pulse"]; + "Baseline chunk type" -> "Check target voltage [2]" [label="post pulse"]; + "Acquired requested number of cycles?\n(Given by optional analysis parameter\n\"NumberOfChirpCycles\" defaulting to 1.)" -> "Calculate min/max of AD data during these cycles" [label=Yes]; + n69 [label="Add Spike QC failed labnotebook entry"]; + n68 -> n69 [label=Yes]; + n71 [label="Has acquired past the end of chirp?"]; + n68 -> n71 [label=No]; + n88 -> n80 [label=None]; + n90 [label="Read full average voltage from labnotebook\n from that sweep and set it as autobias target voltage."]; + n88 -> n90 [label=Found]; + "Mark sweep as failed\n in labnotebook" -> "Has three passing sweeps in set\n with the same DAScale value? [2]"; + n85 [label="Check if the acquired data\n has that sampling interval"]; + n76 -> n85; "Disable \"dDAQ\"/\"oodDAQ\"" -> "Enable \"Repeated Acquisition\""; "Check if mode is IC" -> "Check if only one headstage is active"; - "Check RMS short" -> "Check RMS long" [label=Passed]; - "Check RMS short" -> "Add BL QC failed labnotebook entry" [label=Failed]; + "Check RMS short" -> "Check RMS long" [label=Passed]; + "Check RMS short" -> "Add BL QC failed labnotebook entry" [label=Failed]; "Check target voltage [2]" -> "Mark chunk as passed/failed [2]"; - "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Store \"Inside Bounds\" as true in labnotebook" [label=PASS]; - "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Store \"Inside Bounds\" as false in labnotebook" [label=RERUN]; - "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Store \"Inside Bounds\" as false in labnotebook" [label=INCREASE]; - "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Store \"Inside Bounds\" as false in labnotebook" [label=DECREASE]; - "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Abort Sweep" [label=RERUN]; - "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Calculate scaling factor\n to be inside the bounds" [label=INCREASE]; - "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Calculate scaling factor\n to be inside the bounds" [label=DECREASE]; - n67 [label="Increase DA scale according to analysis parameters\n \"DAScaleModifier\" and \"DAScaleOperator\""]; + "Calculate min/max of AD data during these cycles" -> "Determine bounds state and action\n from min/max values and table\n store in labnotebook"; + "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Store \"Inside Bounds\" as true in labnotebook" [label=PASS]; + "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Store \"Inside Bounds\" as false in labnotebook" [label=RERUN]; + "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Store \"Inside Bounds\" as false in labnotebook" [label=INCREASE]; + "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Store \"Inside Bounds\" as false in labnotebook" [label=DECREASE]; + "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Abort Sweep" [label=RERUN]; + "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Calculate scaling factor\n to be inside the bounds" [label=INCREASE]; + "Determine bounds state and action\n from min/max values and table\n store in labnotebook" -> "Calculate scaling factor\n to be inside the bounds" [label=DECREASE]; + n67 [label="Increase DA scale according to analysis parameters\n \"DAScaleModifier\" and \"DAScaleOperator\""]; n69 -> n67; - n72 [label="Add Spike QC passed labnotebook entry"]; - n71 -> n72 [label=Yes]; - "Read analysis parameter \"NumberOfFailedSweeps\",\n if not present use 3.\n Have that many sweeps failed?" -> "Skip to end of DAQ" [label=Yes]; - "Read analysis parameter \"NumberOfFailedSweeps\",\n if not present use 3.\n Have that many sweeps failed?" -> "Set can still pass?" [label=No]; - n93 -> "Mark sweep as failed\n in labnotebook" [label=No]; - n93 -> "Mark sweep as passed\n in labnotebook" [label=Yes]; + n72 [label="Add Spike QC passed labnotebook entry"]; + n71 -> n72 [label=Yes]; + "Has three passing sweeps in set\n with the same DAScale value? [2]" -> "Skip to end of set" [label=Yes]; + "Has three passing sweeps in set\n with the same DAScale value? [2]" -> "Read analysis parameter \"NumberOfFailedSweeps\",\n if not present use 3.\n Have that many sweeps failed?" [label=No]; + n85 -> "Mark sweep as failed\n in labnotebook" [label=No]; + n85 -> "Skip to end of DAQ" [label=No]; + n106 [label="Do we have a \"DAScale out of range\" labnotebook entry\n in the SCI"]; + n85 -> n106 [label=Yes]; + "Read analysis parameter \"NumberOfFailedSweeps\",\n if not present use 3.\n Have that many sweeps failed?" -> "Skip to end of DAQ" [label=Yes]; + "Read analysis parameter \"NumberOfFailedSweeps\",\n if not present use 3.\n Have that many sweeps failed?" -> "Set can still pass?" [label=No]; + n106 -> "Mark sweep as failed\n in labnotebook" [label=Yes]; + n106 -> "Skip to end of DAQ" [label=Yes]; + n93 [label="Has Async Channels QC\n labnotebook entry passed?"]; + n106 -> n93 [label=No]; "Enable \"Repeated Acquisition\"" -> "Enable \"Insert TP\""; "Check if only one headstage is active" -> "All checks passed"; - "Check RMS long" -> "Add BL QC failed labnotebook entry" [label=Failed]; - "Check RMS long" -> "Check target voltage [1]" [label=Passed]; + "Check RMS long" -> "Add BL QC failed labnotebook entry" [label=Failed]; + "Check RMS long" -> "Check target voltage [1]" [label=Passed]; "Add BL QC failed labnotebook entry" -> "Early Sweep stop"; - "Mark chunk as passed/failed [2]" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=Failed]; - "Mark chunk as passed/failed [2]" -> "Add BL QC passed labnotebook entry" [label=Passed]; - "Calculate scaling factor\n to be inside the bounds" -> "Adjust DAScale (rounded to full pA)\n according to scaling factor"; - n75 [label="Abort sweep"]; - n67 -> n75; - "Set can still pass?" -> "Skip to end of DAQ" [label=No]; + "Mark chunk as passed/failed [2]" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=Failed]; + "Mark chunk as passed/failed [2]" -> "Add BL QC passed labnotebook entry" [label=Passed]; + "Calculate scaling factor\n to be inside the bounds" -> "Calculate DAScale (rounded to full pA)\n according to scaling factor"; + n101 [label="Would the next DAScale value be out of range?"]; + n67 -> n101; + "Set can still pass?" -> "Skip to end of DAQ" [label=No]; + n93 -> "Mark sweep as failed\n in labnotebook" [label=No]; + n93 -> "Mark sweep as passed\n in labnotebook" [label=Yes]; "Mark sweep as passed\n in labnotebook" -> "Has three passing sweeps in set\n with the same DAScale value? [2]"; - n89 [label="Use \"SamplingMultiplier\" analysis parameter\n (defaulting to 4 if not present) and set it."]; + n89 [label="Use \"SamplingMultiplier\" analysis parameter\n (defaulting to 4 if not present) and set it."]; "Enable \"Insert TP\"" -> n89; - "All checks passed" -> Abort [label=No]; - "All checks passed" -> "Look for an existing and passing PSQ_DAScale sweep\n in subthreshold mode" [label=Yes]; + "All checks passed" -> Abort [label=No]; + "All checks passed" -> "Look for an existing and passing PSQ_DAScale sweep\n in subthreshold mode" [label=Yes]; "Check target voltage [1]" -> "Mark chunk as passed/failed [1]"; "Add BL QC passed labnotebook entry" -> "Early Sweep stop"; - "Adjust DAScale (rounded to full pA)\n according to scaling factor" -> "Abort Sweep"; - n78 [label="Is the analysis parameter \"AutobiasTargetV\" present?\n If yes, set the autobias target voltage to it."]; + "Calculate DAScale (rounded to full pA)\n according to scaling factor" -> n101; + n102 [label="Add \"DAScale out of range\" labnotebook entry"]; + n101 -> n102 [label=Yes]; + n103 [label="SetDAScale value"]; + n101 -> n103 [label=No]; + n78 [label="Is the analysis parameter \"AutobiasTargetV\" present?\n If yes, set the autobias target voltage to it."]; n89 -> n78; - "Look for an existing and passing PSQ_DAScale sweep\n in subthreshold mode" -> Abort [label="Not found"]; - "Look for an existing and passing PSQ_DAScale sweep\n in subthreshold mode" -> "Get DeltaI/DeltaV from labnotebook" [label=Found]; - "Mark chunk as passed/failed [1]" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=Passed]; - "Mark chunk as passed/failed [1]" -> "Early sweep stop, repurpose ITI and add 10s to ITI" [label=Failed]; - n82 [label="Store \"Delay onset user\" in labnotebook"]; + "Look for an existing and passing PSQ_DAScale sweep\n in subthreshold mode" -> Abort [label="Not found"]; + "Look for an existing and passing PSQ_DAScale sweep\n in subthreshold mode" -> "Get DeltaI/DeltaV from labnotebook" [label=Found]; + "Mark chunk as passed/failed [1]" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=Passed]; + "Mark chunk as passed/failed [1]" -> "Early sweep stop, repurpose ITI and add 10s to ITI" [label=Failed]; + n82 [label="Store \"Delay onset user\" in labnotebook"]; n78 -> n82; "Get DeltaI/DeltaV from labnotebook" -> "Calculate Resistance from it\n store in labnotebook"; - n83 [label=" Is the analysis parameter \"UserOnsetDelay\" present?\n If yes, set it."]; + n83 [label=" Is the analysis parameter \"UserOnsetDelay\" present?\n If yes, set it."]; n82 -> n83; "Calculate Resistance from it\n store in labnotebook" -> "Calculate initial DAScale\n store in labnotebook"; n83 -> "All checks passed"; "Calculate initial DAScale\n store in labnotebook" -> "Set DAScale"; - n100 -> "Acquired requested number of cycles?\n(Given by optional analysis parameter\n\"NumberOfChirpCycles\" defaulting to 1.)"; + n105 [label="Jump to end of active set"]; + n102 -> n105; } diff --git a/Packages/doc/dot/patch-seq-dascale.dot b/Packages/doc/dot/patch-seq-dascale.dot index c400a1bee4..874e6a172c 100644 --- a/Packages/doc/dot/patch-seq-dascale.dot +++ b/Packages/doc/dot/patch-seq-dascale.dot @@ -45,6 +45,7 @@ digraph G { "Prepare DAQ/Pre Set Event" -> "Enable \"Autobias\""; "Prepare DAQ/Pre Set Event" -> "Valid Autobias voltage (finite and non-zero)"; "BL QC passed?" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=No]; + "Mark set as passed if $NUM_DA_SCALES\nsweeps passed, as failure otherwise" [label="Do we have a \"DAScale out of range\" labnotebook entry\n in the SCI"]; "Get OperationMode [2]" -> "Mark set as passed if $NUM_DA_SCALES\nsweeps passed, as failure otherwise" [label=Sub]; "Get OperationMode [2]" -> "Labnotebook has fI-Slope reached entry?" [label=Supra]; n79 [label="Do we have measured all\n required DAScales?"]; @@ -57,6 +58,9 @@ digraph G { "Valid Autobias voltage (finite and non-zero)" -> "Check if no TTL channels are active"; "Grab next completely acquired chunk\n(500ms) of stimset baseline" -> "Chunk already evaluated?" [label="Have one"]; "Grab next completely acquired chunk\n(500ms) of stimset baseline" -> "Last chunk?" [label="None left"]; + "Mark set as passed if $NUM_DA_SCALES\nsweeps passed, as failure otherwise" -> "Mark set as failed" [label=Yes]; + n126 [label="Mark set as passed if $NUM_DA_SCALES\nsweeps passed, as failure otherwise"]; + "Mark set as passed if $NUM_DA_SCALES\nsweeps passed, as failure otherwise" -> n126 [label=No]; "Labnotebook has fI-Slope reached entry?" -> "Mark set as passed if $NUM_DA_SCALES\nsweeps passed, as failure otherwise" [label=No]; "Labnotebook has fI-Slope reached entry?" -> "Reached?" [label=Yes]; n79 -> "Mark set as failed" [label=No]; @@ -85,23 +89,37 @@ QC and f-I slope QC passing?"]; n72 -> "Check if the Set can still pass"; n76 [label="Check if the acquired data\n has that sampling interval"]; n75 -> n76; + n87 -> n90 [label=Failure]; + n88 [label="Write the AP frequency to the labnotebook"]; + n87 -> n88 [label=Sucess]; + n93 [labe="Fetch sweeps with passing BL QC from SCI\ and append their AP frequency\n DAScale data to the supra data", + label="Fetch AP frequency and DAScale data\n from passing sweeps of this SCI"]; + n90 -> n93; + "Enable \"Multidevice DAQ\"" -> "Disable \"dDAQ\"/\"oodDAQ\""; + "Stimset is large enough" -> "Check if mode is IC"; + "Baseline chunk type" -> "Check RMS short" [label="pre pulse"]; + "Baseline chunk type" -> "Check target voltage [2]" [label="post pulse"]; + n132 -> "Mark set as failed" [label=No]; + n132 -> n81 [label=Yes]; "Check if the Set can still pass" -> "Skip to end" [label=No]; n76 -> n72 [label=No]; n76 -> "Skip to end" [label=No]; n77 [label="Has Async Channels QC\n labnotebook entry passed?"]; n76 -> n77 [label=Yes]; - "Enable \"Multidevice DAQ\"" -> "Disable \"dDAQ\"/\"oodDAQ\""; - "Stimset is large enough" -> "Check if mode is IC"; - "Baseline chunk type" -> "Check RMS short" [label="pre pulse"]; - "Baseline chunk type" -> "Check target voltage [2]" [label="post pulse"]; - n77 -> n72 [label=No]; - n86 [label="Mark sweep as passed"]; - n77 -> n86; + n88 -> n90; + n94 [label="Do overshoot correction:\n This means we want to ensure that all acquired AP frequency DAScale data\n has a stepwidth of smaller \ +than MaxFrequencyChangePercent.\n If this is not the case we add DAScale values to the future DAScale list"]; + n93 -> n94 [label="Do we have passing sweeps in this SCI?"]; + n104 [label="Determine if we have more than two\n points to fit and write the\ result into the labnotebook"]; + n93 -> n104; "Disable \"dDAQ\"/\"oodDAQ\"" -> "Enable \"Repeated Acquisition\""; "Check if mode is IC" -> "Check if only one headstage is active"; "Check RMS short" -> "Check RMS long" [label=Passed]; "Check RMS short" -> "Add BL QC failed labnotebook entry" [label=Failed]; "Check target voltage [2]" -> "Mark chunk as passed/failed [2]"; + n77 -> n72 [label=No]; + n86 [label="Mark sweep as passed"]; + n77 -> n86; n86 -> "Calculate TP-like properties\nand store them in the\nlabnotebook" [label=Supra]; n86 -> "Search for spikes\n(x range: pulse onset to end of pulse\ny condition: max above 0.01mV)" [label=Sub]; "Enable \"Repeated Acquisition\"" -> "Enable \"Insert TP\""; @@ -120,24 +138,22 @@ QC and f-I slope QC passing?"]; "All checks passed" -> "Get OperationMode" [label=Yes]; "Check target voltage [1]" -> "Mark chunk as passed/failed [1]"; "Add BL QC passed labnotebook entry" -> "Early Sweep stop"; - n88 [label="Write the AP frequency to the labnotebook"]; - n87 -> n88 [label=Sucess]; - n87 -> n90 [label=Failure]; - n88 -> n90; - n93 [labe="Fetch sweeps with passing BL QC from SCI\ and append their AP frequency\n DAScale data to the supra data", - label="Fetch AP frequency and DAScale data\n from passing sweeps of this SCI"]; - n90 -> n93; + "Check if $NUM_DA_SCALES\nsweeps passed from RA cycle" -> "Skip to end of active set" [label=Yes]; + "Use next DAScale value" [label="Would the next DAScale value be out of range?"]; + "Check if $NUM_DA_SCALES\nsweeps passed from RA cycle" -> "Use next DAScale value" [label=No]; + "Optional parameter ShowPlot\nis true or missing" -> "Plot the resistance (Sub)\nor fI (Supra)" [label=Yes]; + "Write number of spikes\ninto labnotebook" -> "Analysis parameters MinimumSpikeCount,\n MaximumSpikeCount,\n DAScaleModifier\n present?"; + "Write number of spikes\ninto labnotebook" -> "Determine pulse duration\nand write it into the labnotebook"; "Get OperationMode" -> "Look for a rheobase sweep with passing set QC,\n pulse duration longer than 500ms\n and having spiked" [label=Supra]; "Get OperationMode" -> "Use the DAScale values\nfrom the analysis parameters" [label=Sub]; n110 [label="Look for a supra SCI with passing set QC\n and a long rheobase SCI with passing set QC"]; "Get OperationMode" -> n110 [label="Adaptive Supra"]; "Mark chunk as passed/failed [1]" -> "Grab next completely acquired chunk\n(500ms) of stimset baseline" [label=Passed]; "Mark chunk as passed/failed [1]" -> "Early sweep stop, repurpose ITI and add 10s to ITI" [label=Failed]; - "Check if $NUM_DA_SCALES\nsweeps passed from RA cycle" -> "Skip to end of active set" [label=Yes]; - "Check if $NUM_DA_SCALES\nsweeps passed from RA cycle" -> "Use next DAScale value" [label=No]; - "Optional parameter ShowPlot\nis true or missing" -> "Plot the resistance (Sub)\nor fI (Supra)" [label=Yes]; - "Write number of spikes\ninto labnotebook" -> "Analysis parameters MinimumSpikeCount,\n MaximumSpikeCount,\n DAScaleModifier\n present?"; - "Write number of spikes\ninto labnotebook" -> "Determine pulse duration\nand write it into the labnotebook"; + n122 [label="Add \"DAScale out of range\" labnotebook entry"]; + "Use next DAScale value" -> n122 [label=Yes]; + n123 [label="Set DAScale"]; + "Use next DAScale value" -> n123 [label=No]; "Analysis parameters MinimumSpikeCount,\n MaximumSpikeCount,\n DAScaleModifier\n present?" -> "Use next DAScale value" [label=No]; "Analysis parameters MinimumSpikeCount,\n MaximumSpikeCount,\n DAScaleModifier\n present?" -> "Spike count relative to\nMin and Max?" [label=Yes]; "Determine pulse duration\nand write it into the labnotebook" -> "Create spike frequency vs DAScale (fI) data\nand peform linear regression"; @@ -148,6 +164,13 @@ QC and f-I slope QC passing?"]; n133 [label="Add all passing sweeps from the previous SCI\n if all of the following conditions are met:\n- DAScale adaptive suprathreshold was \ run\n- failing set QC\n-all analysis parameters are the same\n- same targetV autobias value"]; n110 -> n133 [label=Found]; + n94 -> n104; + n95 [label="Fit the last two AP frequency\n and DAScale data from RhSuAd plus this SCI\n ignoring entries with the same AP frequency\n as their \ +right neighbour"]; + n104 -> n95 [label=Yes]; + "Use the DAScale value of that sweep\n as offset to the DAScale values from the analysis parameters" -> "Use first DAScale value"; + n134 [label="Store list of passing RhSuAd sweeps\n in the labnotebook"]; + n133 -> n134; "Spike count relative to\nMin and Max?" -> "Use next DAScale value" [label="In-between"]; "Spike count relative to\nMin and Max?" -> "Adapt DAScale\n by a factor of 1 - Modifier" [label=Above]; "Spike count relative to\nMin and Max?" -> "Adapt DAScale\n by a factor of 1 + Modifier" [label=Below]; @@ -156,25 +179,16 @@ run\n- failing set QC\n-all analysis parameters are the same\n- same targetV aut "Adapt DAScale\n by a factor of 1 - Modifier" -> "Use next DAScale value"; "Adapt DAScale\n by a factor of 1 + Modifier" -> "Use next DAScale value"; "Write fI-Slope into labnotebook" -> "Optional FinalSlopePercent\nparameter present?"; - "Use the DAScale value of that sweep\n as offset to the DAScale values from the analysis parameters" -> "Use first DAScale value"; n114 [label="Gather AP frequency and DAScale data\n from all RhSuAd sweeps\n but using the adaptive E1 epoch length for evaluations"]; - n116 [label="Store frequency and DAScale data\n in the labnotebook"]; - n114 -> n116; - n134 [label="Store list of passing RhSuAd sweeps\n in the labnotebook"]; - n133 -> n134; n134 -> n114; "Optional FinalSlopePercent\nparameter present?" -> "Add labnotebook entry if the\ndesired fI-Slope was reached or not" [label=Yes]; - n132 -> "Mark set as failed" [label=No]; - n132 -> n81 [label=Yes]; - n94 [label="Do overshoot correction:\n This means we want to ensure that all acquired AP frequency DAScale data\n has a stepwidth of smaller \ -than MaxFrequencyChangePercent.\n If this is not the case we add DAScale values to the future DAScale list"]; - n93 -> n94 [label="Do we have passing sweeps in this SCI?"]; - n104 [label="Determine if we have more than two\n points to fit and write the\ result into the labnotebook"]; - n93 -> n104; - n94 -> n104; - n95 [label="Fit the last two AP frequency\n and DAScale data from RhSuAd plus this SCI\n ignoring entries with the same AP frequency\n as their \ -right neighbour"]; - n104 -> n95 [label=Yes]; + n116 [label="Store frequency and DAScale data\n in the labnotebook"]; + n114 -> n116; + n117 [label="Fit the AP frequency and DAScale data\n ignoring entries with the same AP frequency\n as their right neighbour"]; + n116 -> n117; + n117 -> Abort [label=Failure]; + n118 [label="Store the fit slope and offset\n in the labnotebook"]; + n117 -> n118 [label=Success]; n97 [label="Write fit slope and offset to the labnotebook"]; n95 -> n97 [label="Sucess?"]; n98 [label="Mark the fit slope as invalid in the labnotebook"]; @@ -209,16 +223,12 @@ QC and f-I slope QC passing?"]; n109 -> n100 [label=Yes]; n103 [label="Measured all future DAScale values?"]; n100 -> n103 [label=Yes]; - n106 [label="Calculate new DAScale value by\n extrapolating fit slope and offset\n and using MaximumChangePercent - 2 as frequency distance.\n Uses the fit slopes and offsets from the\n passing sweep with the highest DAScale searching from the back."]; + n106 [label="Calculate new DAScale value by\n extrapolating fit slope and offset\n and using MaximumChangePercent - 2 as frequency distance.\n \ +Uses the fit slopes and offsets from the\n passing sweep with the highest DAScale searching from the back."]; n103 -> n106 [label=Yes]; n108 [label="Use the next DAScale value"]; n103 -> n108 [label=No]; n106 -> n108; - n117 [label="Fit the AP frequency and DAScale data\n ignoring entries with the same AP frequency\n as their right neighbour"]; - n116 -> n117; - n117 -> Abort [label=Failure]; - n118 [label="Store the fit slope and offset\n in the labnotebook"]; - n117 -> n118 [label=Success]; n119 [label="Calculate the maximum fit slope\n and store it in the labnotebook"]; n118 -> n119; n128 [label="Calculate the normalized minimum and maximum\n DAScale step witdths and store them in the labnotebook"]; @@ -226,6 +236,7 @@ QC and f-I slope QC passing?"]; n131 [label="Plot AP frequency and f-I slope both versus DAScale"]; n128 -> n131; n120 [label="Do overshoot correction"]; + n131 -> n120; n121 [label="Determine if the fit slopes are valid\n and store that in the labnotebook"]; n120 -> n121 [label=Needed]; n135 [label="Do we have at least NumSweepsWithSaturation\n sweeps which are adjacent, ignoring sweeps with failed sweep QC,\n and have sweep \ @@ -236,5 +247,5 @@ QC and f-I slope QC passing?"]; n135 -> n136 [label=Yes]; n137 [label="Reuse already set DAScale value"]; n136 -> n137; - n131 -> n120; + n122 -> "Skip to end of active set"; } diff --git a/Packages/doc/dot/patch-seq-rheobase.dot b/Packages/doc/dot/patch-seq-rheobase.dot index 4612f22012..12a94a2ee8 100644 --- a/Packages/doc/dot/patch-seq-rheobase.dot +++ b/Packages/doc/dot/patch-seq-rheobase.dot @@ -45,21 +45,21 @@ digraph G { "BL QC passed? [1]" -> "Grab next completely acquired chunk\n (500ms) of stimset baseline" [label=No]; "Mark set as failed if it has not yet passed" -> "Skip to end" [label=Failure]; n91 -> "First Sweep?"; - "First Sweep?" -> "Store final DAScale of last sweep\n from previous RAC as initial DAScale" [label=Yes]; - n60 [label="Read \"SamplingFrequency\" analysis parameter\n (defaulting to 50kHz) if not present"]; - "First Sweep?" -> n60 [label=No]; "Stimset is large enough" -> "Check if only one headstage is active"; "Set \"Repeat Sets\" to 1" -> "Enable \"Autobias\""; "Grab next completely acquired chunk\n (500ms) of stimset baseline" -> "Chunk already evaluated?" [label="Have one"]; "Grab next completely acquired chunk\n (500ms) of stimset baseline" -> "Last chunk?" [label="None left"]; - "Store final DAScale of last sweep\n from previous RAC as initial DAScale" -> "Store DAScale stepsize of 10pA in LBN"; - n61 [label="Check if the acquired data\n has that sampling interval"]; - n60 -> n61; + "First Sweep?" -> "Store final DAScale of last sweep\n from previous RAC as initial DAScale" [label=Yes]; + n60 [label="Read \"SamplingFrequency\" analysis parameter\n (defaulting to 50kHz) if not present"]; + "First Sweep?" -> n60 [label=No]; "Check if only one headstage is active" -> "Valid Autobias voltage (finite and non-zero)"; "Enable \"Autobias\"" -> "Set \"TP during ITI\""; "Chunk already evaluated?" -> "Grab next completely acquired chunk\n (500ms) of stimset baseline" [label=Yes]; "Chunk already evaluated?" -> "Baseline chunk type" [label=No]; "Last chunk?" -> "Mark BL QC as failed" [label=Yes]; + "Store final DAScale of last sweep\n from previous RAC as initial DAScale" -> "Store DAScale stepsize of 10pA in LBN"; + n61 [label="Check if the acquired data\n has that sampling interval"]; + n60 -> n61; "Store DAScale stepsize of 10pA in LBN" -> n60; n61 -> "BL QC passed? [2]" [label=Yes]; n61 -> "Mark set as failed" [label=No]; @@ -76,19 +76,20 @@ digraph G { "Check RMS short" -> "Mark BL QC as failed" [label=Failed]; "Check RMS short" -> "Check RMS long" [label=Passed]; "Check target voltage [2]" -> "Mark chunk as passed/failed [2]"; - "Spike detected?\n(x range: pulse onset to end of sweep\ny condition: max above 0.01mV)\nStore result in labnotebook" -> "Previous sweep has opposite spike result\nand same step size?"; + n65 -> "Spike detected?\n(x range: pulse onset to end of sweep\ny condition: max above 0.01mV)\nStore result in labnotebook" [label=Yes]; "All required analysis parameters present?\nSamplingMultiplier: variable" -> "Search for final DAScale in one of the existing sweeps"; "Disable \"dDAQ\"/\"oodDAQ\"" -> "Enable \"Repeated Acquisition\""; "Check RMS long" -> "Mark BL QC as failed" [label=Failed]; "Check RMS long" -> "Check target voltage [1]" [label=Passed]; "Mark chunk as passed/failed [2]" -> "Grab next completely acquired chunk\n (500ms) of stimset baseline" [label=Failed]; "Mark chunk as passed/failed [2]" -> "Mark BL QC as passed" [label=Passed]; - "Previous sweep has opposite spike result\nand same step size?" -> "DAScale larger than 50pA\nor stepsize is 2pA" [label=Yes]; - "Previous sweep has opposite spike result\nand same step size?" -> "Spike detected? (queried from labnotebook)" [label=No]; + "Spike detected?\n(x range: pulse onset to end of sweep\ny condition: max above 0.01mV)\nStore result in labnotebook" -> "Previous sweep has opposite spike result\nand same step size?"; "Search for final DAScale in one of the existing sweeps" -> "All checks passed"; "Enable \"Repeated Acquisition\"" -> "Set \"ITI\" to 4s"; "Check target voltage [1]" -> "Mark chunk as passed/failed [1]"; "Mark BL QC as passed" -> "Early sweep stop"; + "Previous sweep has opposite spike result\nand same step size?" -> "DAScale larger than 50pA\nor stepsize is 2pA" [label=Yes]; + "Previous sweep has opposite spike result\nand same step size?" -> "Spike detected? (queried from labnotebook)" [label=No]; "DAScale larger than 50pA\nor stepsize is 2pA" -> "Mark set as passed" [label=Yes]; "DAScale larger than 50pA\nor stepsize is 2pA" -> "Store DAScale stepsize of 2pA in LBN" [label=No]; "Spike detected? (queried from labnotebook)" -> "Offset DAScale by minus\nstepsize from LBN" [label=Yes]; @@ -103,11 +104,17 @@ digraph G { "Offset DAScale by minus\nstepsize from LBN" -> "DAScale is zero?"; "Offset DAScale by plus\nstepsize from LBN" -> "DAScale is zero?"; "DAScale is zero?" -> "Stepsize?" [label=Yes]; - "DAScale is zero?" -> "Difference to initial DAScale larger than 60pA?" [label=No]; + n66 [label="Would the new DA scale for the next sweep be out of range?"]; + "DAScale is zero?" -> n66 [label=No]; "Stepsize?" -> "Set DAScale and stepsize to 2pA" [label="10pA"]; "Stepsize?" -> "Add \"limited resolution\"\nlabnotebook entry" [label="2pA"]; "Difference to initial DAScale larger than 60pA?" -> "Set \"range exceeded\" labnotebook\nentry to true for sweep" [label=Yes]; "Add \"limited resolution\"\nlabnotebook entry" -> "Mark set as failed"; "Set \"range exceeded\" labnotebook\nentry to true for sweep" -> "Mark set as failed"; - n65 -> "Spike detected?\n(x range: pulse onset to end of sweep\ny condition: max above 0.01mV)\nStore result in labnotebook" [label=Yes]; + n68 [label="Set DAScale"]; + n66 -> n68 [label=No]; + n69 [label="Add \"DAScale out of range\" labnotebook entry"]; + n66 -> n69 [label=Yes]; + n68 -> "Difference to initial DAScale larger than 60pA?"; + n69 -> "Mark set as failed"; } diff --git a/Packages/doc/dot/patch-seq-squarepulse.dot b/Packages/doc/dot/patch-seq-squarepulse.dot index f98abfbcbc..83a5fbd24c 100644 --- a/Packages/doc/dot/patch-seq-squarepulse.dot +++ b/Packages/doc/dot/patch-seq-squarepulse.dot @@ -41,6 +41,8 @@ digraph G { target=_graphviz]; "Pre Sweep Config Event" -> n92; "Post Set Event" -> "Mark set as passed if 1 sweep passed,\nas failure otherwise"; + n48 [label="Do we have a \"DAScale out of range\" labnotebook entry\n in the SCI"]; + "Post Set Event" -> n48; "Enable \"Multidevice DAQ\"" -> "Disable \"dDAQ\"/\"oodDAQ\""; "Check if mode is IC" -> "Check if no TTL channels are active"; n37 [label="Read \"SamplingFrequency\" analysis parameter\n (defaulting to 50kHz) if not present"]; @@ -49,17 +51,18 @@ digraph G { n91 -> n43; "Spike detected?\n(x range: pulse onset to end of sweep\ny condition: max above 0.01mV)\nStore result in labnotebook" -> "DAScale is zero" [label=Yes]; "Spike detected?\n(x range: pulse onset to end of sweep\ny condition: max above 0.01mV)\nStore result in labnotebook" -> "Step Size from labnotebook?" [label=No]; - n38 [label="Check if the acquired data\n has that sampling interval"]; - n37 -> n38; "Mark set as passed if 1 sweep passed,\nas failure otherwise" -> "Skip to end" [label=Failure]; "Disable \"dDAQ\"/\"oodDAQ\"" -> "Set \"TP inserting\" to disabled"; "Check if no TTL channels are active" -> "Check if only one headstage is active"; + n38 [label="Check if the acquired data\n has that sampling interval"]; + n37 -> n38; + n39 [label="Mark Sweep as failure"]; + n43 -> n39 [label=No]; "DAScale is zero" -> "Step size from labnotebook?" [label=No]; "DAScale is zero" -> "Add labnotebook entry\ndocumenting this case" [label=Yes]; "Step Size from labnotebook?" -> "Write step size of\n+10pA to labnotebook" [label="-50pA"]; "Step Size from labnotebook?" -> "Offset DAScale\nby +10pA" [label="+10pA"]; "Step Size from labnotebook?" -> "Offset DAScale\nby +100pA" [label="+100pA"]; - n39 [label="Mark Sweep as failure"]; n38 -> n39 [label=No]; "Set \"TP inserting\" to disabled" -> "Set \"TP during ITI\" to disabled"; "Check if only one headstage is active" -> "All checks passed"; @@ -68,6 +71,7 @@ digraph G { "Step size from labnotebook?" -> "Write step size of\n-50pA to labnotebook" [label="+100pA"]; "Add labnotebook entry\ndocumenting this case" -> "Mark sweep as failure [2]"; "Write step size of\n+10pA to labnotebook" -> "Offset DAScale\nby +10pA"; + "Mark sweep as failed [1]" [label="Would the new DA scale for the next sweep be out of range?"]; "Offset DAScale\nby +10pA" -> "Mark sweep as failed [1]"; "Offset DAScale\nby +100pA" -> "Mark sweep as failed [1]"; n39 -> "Skip to end of active set"; @@ -78,9 +82,19 @@ digraph G { "Offset DAScale\nby -50pA" -> "Mark sweep as failed [1]"; "Write step size of\n-50pA to labnotebook" -> "Offset DAScale\nby -50pA"; "Mark sweep as failure [2]" -> "Three sweeps exist with\nthis labnotebook entry?"; + n44 [label="Add \"DAScale out of range\" labnotebook entry"]; + "Mark sweep as failed [1]" -> n44 [label=Yes]; + n46 [label="Set DAScale"]; + "Mark sweep as failed [1]" -> n46 [label=No]; "Set \"ITI\" to 100ms" -> "Enable \"Repeated Acquisition\""; "Set DAScale to 100pA" -> "Write initial stepsize of 100pA into labnotebook"; "Mark sweep as passed" -> "Skip to end of active set"; "Three sweeps exist with\nthis labnotebook entry?" -> "Skip to end of active set" [label=Yes]; - n43 -> n39 [label=No]; + n45 [label="Mark sweep as failed"]; + n44 -> n45; + n46 -> n45; + n47 [label="Mark set as failure"]; + n47 -> "Skip to end"; + n48 -> "Mark set as passed if 1 sweep passed,\nas failure otherwise" [label=No]; + n48 -> n47 [label=Yes]; } From db6e32cc3d5927f54d3c1b578c77045319cc9248 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Mon, 20 Jan 2025 15:41:31 +0100 Subject: [PATCH 17/17] DC_PlaceDataInDAQDataWave: Suggest to tweak DAScale in case of too large values Change requested by Tim Jarsky. --- Packages/MIES/MIES_DataConfigurator.ipf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/MIES/MIES_DataConfigurator.ipf b/Packages/MIES/MIES_DataConfigurator.ipf index c0355dc5b4..604a67de24 100644 --- a/Packages/MIES/MIES_DataConfigurator.ipf +++ b/Packages/MIES/MIES_DataConfigurator.ipf @@ -1008,7 +1008,7 @@ static Function DC_PlaceDataInDAQDataWave(string device, variable numActiveChann [ret, row, column] = DC_CheckIfDataWaveHasBorderVals(device, dataAcqOrTP) if(ret) - printf "Some values in DataWave exceed device limits for %s mode (channel index %g, position %g). Maybe the DA/AD Gain needs adjustment?\r", SelectString(dataAcqOrTP, "DATA_ACQUISITION", "TestPulse"), column, row + printf "Some values in DataWave exceed device limits for %s mode (channel index %g, position %g). Maybe the DA scale needs adjustment?\r", SelectString(dataAcqOrTP, "DATA_ACQUISITION", "TestPulse"), column, row ControlWindowToFront() Abort endif