Skip to content

Commit

Permalink
Merge pull request #2073 from AllenInstitute/bugfix/2073-various-swee…
Browse files Browse the repository at this point in the history
…pformula

Various minor SF adaptations
  • Loading branch information
t-b authored Mar 26, 2024
2 parents ee7e65f + a578cf1 commit 00c92fe
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 43 deletions.
44 changes: 44 additions & 0 deletions Packages/MIES/MIES_AnalysisFunctionHelpers.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,50 @@ Function AFH_AddAnalysisParameter(string setName, string name, [variable var, st
endif
End

/// @brief Return a stringified version of the analysis parameter value
///
/// @param name name of the parameter
/// @param params serialized parameters, usually just #AnalysisFunction_V3.params
Function/S AFH_GetAnalysisParameterAsText(string name, string params)

string type
variable numericValue

ASSERT(AFH_IsValidAnalysisParameter(name), "Name is not a legal non-liberal igor object name")

type = AFH_GetAnalysisParamType(name, params, typeCheck = 0)

strswitch(type)
case "variable":
numericValue = AFH_GetAnalysisParamNumerical(name, params)
if(!IsNan(numericValue))
return num2str(numericValue)
endif
break
case "string":
return AFH_GetAnalysisParamTextual(name, params)
break
case "wave":
WAVE/Z wv = AFH_GetAnalysisParamWave(name, params)
if(WaveExists(wv))
return NumericWaveToList(wv, ";")
endif
break
case "textwave":
WAVE/Z wv = AFH_GetAnalysisParamTextWave(name, params)
if(WaveExists(wv))
return TextWaveToList(wv, ";")
endif
break
case "": // unknown name
break
default:
ASSERT(0, "invalid type")
endswitch

return ""
End

/// @brief Return the headstage from the given active AD count
///
/// @param statusADC channel status as returned by GetLastSetting()
Expand Down
20 changes: 16 additions & 4 deletions Packages/MIES/MIES_SweepFormula.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,8 @@ static Function/S SF_GetAnnotationPrefix(string dataType)
return ""
case SF_DATATYPE_TP:
return "TP "
case SF_DATATYPE_LABNOTEBOOK:
return "LB "
default:
ASSERT(0, "Invalid dataType")
endswitch
Expand All @@ -1232,7 +1234,8 @@ static Function/S SF_GetTraceAnnotationText(STRUCT SF_PlotMetaData& plotMetaData

strswitch(plotMetaData.dataType)
case SF_DATATYPE_EPOCHS: // fallthrough
case SF_DATATYPE_SWEEP: // fallthrough
case SF_DATATYPE_SWEEP: // fallthrough
case SF_DATATYPE_LABNOTEBOOK: // fallthrough
case SF_DATATYPE_TP:
sweepNo = JWN_GetNumberFromWaveNote(data, SF_META_SWEEPNO)
annotationPrefix = SF_GetAnnotationPrefix(plotMetaData.dataType)
Expand Down Expand Up @@ -1288,7 +1291,7 @@ Function [STRUCT RGBColor s] SF_GetTraceColor(string graph, string opStack, WAVE
s.blue = 0x0000

Make/FREE/T stopInheritance = {SF_OPSHORT_MINUS, SF_OPSHORT_PLUS, SF_OPSHORT_DIV, SF_OPSHORT_MULT}
Make/FREE/T doInheritance = {SF_OP_DATA, SF_OP_TP, SF_OP_PSX, SF_OP_PSX_STATS, SF_OP_EPOCHS}
Make/FREE/T doInheritance = {SF_OP_DATA, SF_OP_TP, SF_OP_PSX, SF_OP_PSX_STATS, SF_OP_EPOCHS, SF_OP_LABNOTEBOOK}

WAVE/T opStackW = ListToTextWave(opStack, ";")
numDoInh = DimSize(doInheritance, ROWS)
Expand Down Expand Up @@ -1900,7 +1903,16 @@ static Function SF_FormulaPlotter(string graph, string formula, [DFREF dfr, vari
WAVE wvY = dataInGraph[l][%WAVEY]
trace = tracesInGraph[l]

WAVE/Z traceColor = JWN_GetNumericWaveFromWaveNote(wvY, SF_META_TRACECOLOR)
info = AxisInfo(win, "left")
isCategoryAxis = (NumberByKey("ISCAT", info) == 1)

if(isCategoryAxis)
WAVE traceColorHolder = wvX
else
WAVE traceColorHolder = wvY
endif

WAVE/Z traceColor = JWN_GetNumericWaveFromWaveNote(traceColorHolder, SF_META_TRACECOLOR)
if(WaveExists(traceColor))
ASSERT(DimSize(traceColor, ROWS) == 3, "Need 3-element wave for color specification.")
ModifyGraph/W=$win rgb($trace)=(traceColor[0], traceColor[1], traceColor[2])
Expand Down Expand Up @@ -5459,7 +5471,7 @@ Function/WAVE SF_OperationFitLine(variable jsonId, string jsonPath, string graph

SFH_CheckArgumentCount(jsonId, jsonPath, SF_OP_FITLINE, 0, maxArgs = 1)

WAVE/T/Z constraints = SFH_GetArgumentAsWave(jsonId, jsonPath, graph, SF_OP_FITLINE, 0, defOp = "wave()", singleResult = 1)
WAVE/T/Z constraints = SFH_GetArgumentAsWave(jsonId, jsonPath, graph, SF_OP_FITLINE, 0, defWave = $"", singleResult = 1)

[WAVE holdWave, WAVE initialValues] = SF_ParseFitConstraints(constraints, 2)

Expand Down
37 changes: 31 additions & 6 deletions Packages/MIES/MIES_SweepFormula_Helpers.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -215,26 +215,32 @@ End
///
/// opShort = "countBirds"
/// WAVE/D birds = SFH_GetArgumentAsWave(jsonId, jsonPath, graph, opShort, 0, singleResult = 1)
/// WAVE/T types = SFH_GetArgumentAsWave(jsonId, jsonPath, graph, opShort, 1, defOp = "birdTypes()", singleResult = 1)
/// WAVE/T types = SFH_GetArgumentAsWave(jsonId, jsonPath, graph, opShort, 1, defOp = "birdTypes()", singleResult = 1, expectedWaveType = IGOR_TYPE_TEXT_WAVE)
///
/// \endrst
///
/// Here `birds` is argument number 0 and mandatory as `defOp` is not present. Passing `singleResult == 1` already
/// unpacks the outer wave reference wave container. It should always be passed if you only expect one wave to be
/// returned.
///
/// The second argument `birdTypes` is optional, if not present the operation `birdTypes()` is called and its result returned.
Function/WAVE SFH_GetArgumentAsWave(variable jsonId, string jsonPath, string graph, string opShort, variable argNum, [string defOp, variable singleResult])
/// The second argument `birdTypes` is optional, if not present the operation `birdTypes()` is called and its result returned. Alternatively `defWave` can be supplied which is then returned if the argument is not present.
Function/WAVE SFH_GetArgumentAsWave(variable jsonId, string jsonPath, string graph, string opShort, variable argNum, [string defOp, WAVE/Z defWave, variable singleResult, variable expectedWaveType])

variable checkExist, numArgs
variable checkExist, numArgs, checkWaveType, realWaveType
string msg

if(ParamIsDefault(defOp))
if(ParamIsDefault(defOp) && ParamIsDefault(defWave))
checkExist = 1
else
checkExist = 0
endif

if(ParamIsDefault(expectedWaveType))
checkWaveType = 0
else
checkWaveType = !!checkWaveType
endif

if(ParamIsDefault(singleResult))
singleResult = 0
else
Expand All @@ -252,8 +258,23 @@ Function/WAVE SFH_GetArgumentAsWave(variable jsonId, string jsonPath, string gra

WAVE/Z data = input[0]
SFH_CleanUpInput(input)

Make/FREE types = {WaveType(data)}
else
WAVE data = input
Make/FREE/N=(DimSize(input, ROWS)) types = WaveType(input[p])
endif

if(checkWaveType)
if(expectedWaveType == IGOR_TYPE_TEXT_WAVE)
// we are using selector 0 for WaveType
realWaveType = 0
else
realWaveType = expectedWaveType
endif

sprintf msg, "Argument #%d of operation %s: Expected wave type %d", argNum, opShort, expectedWaveType
SFH_ASSERT(IsConstant(types, realWaveType), msg)
endif

return data
Expand All @@ -262,7 +283,11 @@ Function/WAVE SFH_GetArgumentAsWave(variable jsonId, string jsonPath, string gra
sprintf msg, "Argument #%d of operation %s is mandatory", argNum, opShort
SFH_ASSERT(!checkExist, msg)

return SF_ExecuteFormula(defOp, graph, singleResult = singleResult, useVariables=0)
if(!ParamIsDefault(defOp))
return SF_ExecuteFormula(defOp, graph, singleResult = singleResult, useVariables=0)
endif

return defWave
End

/// @brief Assertion for sweep formula
Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_SweepFormula_PSX.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -4222,7 +4222,7 @@ Function/WAVE PSX_Operation(variable jsonId, string jsonPath, string graph)
sweepFilterLow = SFH_GetArgumentAsNumeric(jsonID, jsonPath, graph, SF_OP_PSX, 3, defValue = PSX_DEFAULT_FILTER_LOW, checkFunc = IsNullOrPositiveAndFinite)
sweepFilterHigh = SFH_GetArgumentAsNumeric(jsonID, jsonPath, graph, SF_OP_PSX, 4, defValue = PSX_DEFAULT_FILTER_HIGH, checkFunc = IsNullOrPositiveAndFinite)
maxTauFactor = SFH_GetArgumentAsNumeric(jsonID, jsonPath, graph, SF_OP_PSX, 5, defValue = PSX_DEFAULT_MAX_TAU_FACTOR, checkFunc = IsStrictlyPositiveAndFinite)
WAVE riseTime = SFH_GetArgumentAsWave(jsonID, jsonPath, graph, SF_OP_PSX, 6, defOp = "psxRiseTime()", singleResult = 1)
WAVE riseTime = SFH_GetArgumentAsWave(jsonID, jsonPath, graph, SF_OP_PSX, 6, defOp = "psxRiseTime()", expectedWaveType = IGOR_TYPE_64BIT_FLOAT, singleResult = 1)
ASSERT(IsNumericWave(riseTime), "Invalid return from psxRiseTime")
WAVE deconvFilter = SFH_GetArgumentAsWave(jsonID, jsonPath, graph, SF_OP_PSX, 7, defOp = "psxDeconvFilter()", singleResult = 1)
Expand Down
30 changes: 2 additions & 28 deletions Packages/MIES/MIES_WaveBuilderPanel.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -2016,36 +2016,10 @@ Function WBP_ListBoxProc_AnalysisParams(lba) : ListBoxControl
params = WBP_GetAnalysisParameters()
name = listWave[row][%Name]

value = ""
value = AFH_GetAnalysisParameterAsText(name, params)
type = listWave[row][%Type]
if(!IsEmpty(type))
strswitch(type)
case "variable":
numericValue = AFH_GetAnalysisParamNumerical(name, params)
if(!IsNan(numericValue))
value = num2str(numericValue)
endif
break
case "string":
value = AFH_GetAnalysisParamTextual(name, params)
break
case "wave":
WAVE/Z wv = AFH_GetAnalysisParamWave(name, params)
if(WaveExists(wv))
value = NumericWaveToList(wv, ";")
endif
break
case "textwave":
WAVE/Z wv = AFH_GetAnalysisParamTextWave(name, params)
if(WaveExists(wv))
value = TextWaveToList(wv, ";")
endif
break
default:
ASSERT(0, "invalid type")
break
endswitch

if(!IsEmpty(type))
SetPopupMenuString(win, "popup_param_types", type)
endif

Expand Down
6 changes: 3 additions & 3 deletions Packages/MIES/analysis_function_parameters.itx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ BEGIN
"BaselineRMSShortThreshold" "variable" "optional" "AR, CR, DA, PB, RA, RB, SE, VM" "Threshold value in mV for the short RMS baseline QC check (defaults to 0.07)"
"BaselineTargetVThreshold" "variable" "optional" "CR, DA, RA, RB" "Threshold value in mV for the target V baseline QC check (defaults to 1)"
"BoundsEvaluationMode" "string" "required" "CR" "Select the bounds evaluation mode: Symmetric (Lower and Upper), Depolarized (Upper) or Hyperpolarized (Lower)"
"DAScaleModifier" "variable" "mixed" "CR, DA, SC" "Modifier value to the DA Scale of headstages for too few spikes\rPercentage how the DAScale value is adapted if it is outside of the MinimumSpikeCount\"/\"MaximumSpikeCount\" band. Only for \"Supra\".\rModifier value to the DA Scale of headstages with spikes during chirp"
"DAScaleOperator" "string" "mixed" "CR, SC" "Set the math operator to use for combining the DAScale and the too few spikes modifier. Valid strings are \"+\" (addition) and \"*\" (multiplication).\rSet the math operator to use for combining the DAScale and the modifier. Valid strings are \"+\" (addition) and \"*\" (multiplication)."
"DAScaleModifier" "variable" "mixed" "CR, DA, SC" "Modifier value to the DA Scale of headstages with spikes during chirp\rPercentage how the DAScale value is adapted if it is outside of the MinimumSpikeCount\"/\"MaximumSpikeCount\" band. Only for \"Supra\".\rModifier value to the DA Scale of headstages for too few spikes"
"DAScaleOperator" "string" "mixed" "CR, SC" "Set the math operator to use for combining the DAScale and the modifier. Valid strings are \"+\" (addition) and \"*\" (multiplication).\rSet the math operator to use for combining the DAScale and the too few spikes modifier. Valid strings are \"+\" (addition) and \"*\" (multiplication)."
"DAScales" "wave" "required" "DA, DS" "DA Scale Factors in pA"
"DAScaleSpikePositionModifier" "variable" "required" "SC" "Modifier value to the DA Scale of headstages with failing spike positions."
"DAScaleSpikePositionOperator" "string" "required" "SC" "Set the math operator to use for combining the DAScale and the spike position modifier. Valid strings are \"+\" (addition) and \"*\" (multiplication)."
Expand Down Expand Up @@ -51,7 +51,7 @@ BEGIN
"PostDAQDAScaleForFailedHS" "variable" "required" "FR" "Failed headstages will be set to this DAScale value [pA] in the post set event"
"PostDAQDAScaleMinOffset" "variable" "required" "FR" "Mininum absolute offset value applied to the found DAScale [pA]"
"RelativeVoltageDiff" "variable" "required" "VM" "Maximum relative allowed difference of the baseline membrane potentials [%].\r Set to `inf` to disable this check."
"SamplingFrequency" "variable" "optional" "AR, CR, DA, PB, RA, RB, SE, SP, VM" "Required sampling frequency for the acquired data [kHz]. Defaults to ITC:50 NI:50.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:200 NI:250.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:200 NI:250.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:200 NI:250.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:50 NI:50."
"SamplingFrequency" "variable" "optional" "AR, CR, DA, PB, RA, RB, SE, SP, VM" "Required sampling frequency for the acquired data [kHz]. Defaults to ITC:50 NI:50.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:200 NI:250.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:50 NI:50.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:50 NI:50.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:200 NI:250.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:50 NI:50.\rRequired sampling frequency for the acquired data [kHz]. Defaults to ITC:200 NI:250."
"SamplingMultiplier" "variable" "required" "AR, CR, DA, FR, PB, RA, RB, SE, SP, VM" "Sampling multiplier, use 1 for no multiplier"
"SealThreshold" "variable" "required" "SE" "Minimum required seal threshold [GΩ]"
"ShowPlot" "variable" "optional" "DA" "Show the resistance (\"Sub\") or the f-I (\"Supra\") plot, defaults to true."
Expand Down
68 changes: 67 additions & 1 deletion Packages/tests/Basic/UTF_AnalysisFunctionParameters.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,8 @@ static Function/WAVE GetAnalysisFunctions()

SetDimensionLabels(wv, funcs, ROWS)

Sort/DIML wv, wv

return wv
End

Expand Down Expand Up @@ -928,7 +930,7 @@ static Function GenerateAnalysisFunctionTable()
// if this test fails and the CRC changes
// commit the file `Packages/MIES/analysis_function_parameters.itx`
// and check that the changes therein are intentional
CHECK_EQUAL_VAR(WaveCRC(0, output, 0), 303837295)
CHECK_EQUAL_VAR(WaveCRC(0, output, 0), 2280254664)
StoreWaveOnDisk(output, "analysis_function_parameters")
End

Expand Down Expand Up @@ -957,3 +959,67 @@ static Function GenerateAnalysisFunctionLegend()
CHECK_EQUAL_VAR(WaveCRC(0, output, 0), 2579934075)
StoreWaveOnDisk(output, "analysis_function_abrev_legend")
End

/// @name AFH_GetAnalysisParameterAsText
/// @{
Function GAPasT_AbortsWithEmptyName()

try
AFH_GetAnalysisParameterAsText("", "name:textwave=0")
FAIL()
catch
PASS()
endtry
End

Function GAPasT_AbortsWithIllegalName()

try
AFH_GetAnalysisParameterAsText("123", "name:textwave=0")
FAIL()
catch
PASS()
endtry
End

Function GAPasT_AbortsWithIllegalType()

try
AFH_GetAnalysisParameterAsText("name", "name:invalidType=0")
FAIL()
catch
PASS()
endtry
End

static Function/WAVE GetAnalysisParameterValues()

Make/FREE/N=(5)/WAVE waves

Make/FREE/T wv0 = {"var", "123"}
waves[0] = wv0

Make/FREE/T wv1 = {"str", "abcd"}
waves[1] = wv1

Make/FREE/T wv2 = {"wv", "1;2;"}
waves[2] = wv2

Make/FREE/T wv3 = {"txtwv", "a;b;"}
waves[3] = wv3

Make/FREE/T wv4 = {"i_dont_exist", ""}
waves[4] = wv4

return waves
End

/// UTF_TD_GENERATOR GetAnalysisParameterValues
Function GAPasT_Works([WAVE/T wv])

string result

result = AFH_GetAnalysisParameterAsText(wv[0], "var:variable=123,str:string=abcd,wv:wave=1|2,txtwv:textwave=a|b")
CHECK_EQUAL_STR(result, wv[1])
End
/// @}

0 comments on commit 00c92fe

Please sign in to comment.