From 5583b7e90b59a97e3ae0294552fb803867ff7a7b Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Mon, 19 Aug 2024 21:52:18 +0200 Subject: [PATCH 1/2] GetWaveDimensions: Add it Although the function is rather short, it is still nicer to have a single instance of the code. We also choose to use a double precision wave as that holds all possible current wave sizes and does not have the various issues as the 64bit integer waves have. --- Packages/MIES/MIES_PulseAveraging.ipf | 4 +-- Packages/MIES/MIES_Utilities_WaveHandling.ipf | 17 +++++++--- .../tests/Basic/UTF_Utils_WaveHandling.ipf | 32 ++++++++++++++++++- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/Packages/MIES/MIES_PulseAveraging.ipf b/Packages/MIES/MIES_PulseAveraging.ipf index d227002048..92564885e2 100644 --- a/Packages/MIES/MIES_PulseAveraging.ipf +++ b/Packages/MIES/MIES_PulseAveraging.ipf @@ -3448,12 +3448,12 @@ static Function/S PA_ShowImage(string win, STRUCT PulseAverageSettings &pa, STRU scaleChanged = (DimOffset(img, ROWS) != refScaleLeft) || (DimOffset(img, ROWS) + (DimSize(img, ROWS) - 1) * DimDelta(img, ROWS) != refScaleRight) xUnits = WaveUnits(set2[0][0], ROWS) - Make/FREE/N=(MAX_DIMENSION_COUNT) oldSizes = DimSize(img, p) + WAVE oldSizes = GetWaveDimensions(img) EnsureLargeEnoughWave(img, indexShouldExist = requiredEntries, dimension = COLS, initialValue = NaN) Redimension/N=(refScalePoints, -1) img // inclusive scale must be set after redimension SetScale/P x, refScaleLeft, refScaleDelta, xUnits, img - Make/FREE/N=(MAX_DIMENSION_COUNT) newSizes = DimSize(img, p) + WAVE newSizes = GetWaveDimensions(img) if(!(mode != POST_PLOT_ADDED_SWEEPS \ || !EqualWaves(oldSizes, newSizes, EQWAVES_DATA) \ diff --git a/Packages/MIES/MIES_Utilities_WaveHandling.ipf b/Packages/MIES/MIES_Utilities_WaveHandling.ipf index 3466992bf9..9c355e4695 100644 --- a/Packages/MIES/MIES_Utilities_WaveHandling.ipf +++ b/Packages/MIES/MIES_Utilities_WaveHandling.ipf @@ -78,7 +78,7 @@ threadsafe Function EnsureLargeEnoughWave(WAVE wv, [variable indexShouldExist, v Make/FREE/L/N=(MAX_DIMENSION_COUNT) targetSizes = -1 targetSizes[dimension] = indexShouldExist - Make/FREE/L/N=(MAX_DIMENSION_COUNT) oldSizes = DimSize(wv, p) + WAVE oldSizes = GetWaveDimensions(wv) Redimension/N=(targetSizes[ROWS], targetSizes[COLS], targetSizes[LAYERS], targetSizes[CHUNKS]) wv @@ -115,14 +115,22 @@ Function EnsureSmallEnoughWave(wv, [maximumSize]) maximumSize = MAXIMUM_WAVE_SIZE endif - Make/FREE/I/N=(MAX_DIMENSION_COUNT) oldSizes - oldSizes[] = DimSize(wv, p) + WAVE oldSizes = GetWaveDimensions(wv) if(oldSizes[ROWS] > maximumSize) Redimension/N=(maximumSize, -1, -1, -1) wv endif End +/// @brief Return a wave with `MAX_DIMENSION_COUNT` entries with the size of each dimension +threadsafe Function/WAVE GetWaveDimensions(WAVE wv) + + ASSERT_TS(WaveExists(wv), "Missing wave") + Make/FREE/D/N=(MAX_DIMENSION_COUNT) sizes = DimSize(wv, p) + + return sizes +End + /// @brief Returns the size of the wave in bytes threadsafe static Function GetWaveSizeImplementation(wv) WAVE wv @@ -616,8 +624,7 @@ threadsafe Function ReduceWaveDimensionality(WAVE/Z wv, [variable minDimension]) minDimension = ParamIsDefault(minDimension) ? COLS : minDimension ASSERT_TS(IsInteger(minDimension) && minDimension >= ROWS && minDimension < MAX_DIMENSION_COUNT, "Invalid minDimension") minDimension = limit(minDimension, COLS, MAX_DIMENSION_COUNT - 1) - Make/FREE/N=(MAX_DIMENSION_COUNT) waveSize - waveSize[] = DimSize(wv, p) + WAVE waveSize = GetWaveDimensions(wv) for(i = MAX_DIMENSION_COUNT - 1; i >= minDimension; i -= 1) if(waveSize[i] == 1) waveSize[i] = 0 diff --git a/Packages/tests/Basic/UTF_Utils_WaveHandling.ipf b/Packages/tests/Basic/UTF_Utils_WaveHandling.ipf index 115270d103..6550744118 100644 --- a/Packages/tests/Basic/UTF_Utils_WaveHandling.ipf +++ b/Packages/tests/Basic/UTF_Utils_WaveHandling.ipf @@ -1225,7 +1225,7 @@ Function RUR_Works() WAVE dup = RemoveUnusedRows(wv) - Make/FREE/N=(MAX_DIMENSION_COUNT) dims = DimSize(dup, p) + WAVE dims = GetWaveDimensions(dup) CHECK_EQUAL_WAVES(dims, {4, 3, 2, 0}, mode = WAVE_DATA) CHECK(!WaveRefsEqual(wv, dup)) End @@ -1944,3 +1944,33 @@ Function ZWI_Works3() End /// @} + +/// GetWaveDimensions +/// @{ + +Function GWD_ChecksParam() + + try + GetWaveDimensions($"") + FAIL() + catch + CHECK_NO_RTE() + endtry +End + +Function GWD_Works() + + Make/FREE/N=0 wv + WAVE sizes = GetWaveDimensions(wv) + CHECK_EQUAL_WAVES(sizes, {0, 0, 0, 0}, mode = WAVE_DATA) + + Make/FREE/N=(1, 2, 3, 4) wv + WAVE sizes = GetWaveDimensions(wv) + CHECK_EQUAL_WAVES(sizes, {1, 2, 3, 4}, mode = WAVE_DATA) + + Make/FREE/N=(1, 2, 0, 4) wv + WAVE sizes = GetWaveDimensions(wv) + CHECK_EQUAL_WAVES(sizes, {1, 2, 0, 4}, mode = WAVE_DATA) +End + +/// @} From ba7eb2123974a05bdd807e996e4f39246e704f38 Mon Sep 17 00:00:00 2001 From: Thomas Braun Date: Mon, 19 Aug 2024 22:33:49 +0200 Subject: [PATCH 2/2] MIES_SweepFormula.ipf: Enhance mismatched waves message for basic math operations --- Packages/MIES/MIES_SweepFormula.ipf | 29 ++++++++++++--- .../Basic/UTF_SweepFormula_Operations.ipf | 36 +++++++++++++++++++ Packages/tests/UTF_DataGenerators.ipf | 8 +++++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/Packages/MIES/MIES_SweepFormula.ipf b/Packages/MIES/MIES_SweepFormula.ipf index ca07c9b4cf..e0c0ae2e30 100644 --- a/Packages/MIES/MIES_SweepFormula.ipf +++ b/Packages/MIES/MIES_SweepFormula.ipf @@ -3268,6 +3268,27 @@ static Function/WAVE SF_OperationEpochsImpl(string graph, WAVE/T epochPatterns, return output End +static Function SF_AssertOnMismatchedWaves(WAVE data0, WAVE data1, string opShort) + + string msg, size0Str, size1Str + variable ret + + ret = EqualWaves(data0, data1, EQWAVES_DIMSIZE) + + if(ret) + return NaN + endif + + WAVE size0 = GetWaveDimensions(data0) + WAVE size1 = GetWaveDimensions(data1) + + size0Str = NumericWaveToList(size0, ", ", trailSep = 0) + size1Str = NumericWaveToList(size1, ", ", trailSep = 0) + sprintf msg, "%s: wave size mismatch [%s] vs [%s]", opShort, size0Str, size1Str + + SFH_ASSERT(ret, msg) +End + static Function/WAVE SF_OperationMinus(variable jsonId, string jsonPath, string graph) WAVE output = SF_IndexOverDataSetsForPrimitiveOperation(jsonId, jsonpath, graph, SF_OPSHORT_MINUS) @@ -3296,7 +3317,7 @@ static Function/WAVE SF_OperationMinusImplDataSets(WAVE/Z data0, WAVE/Z data1) CopyScales data1, result return result endif - SFH_ASSERT(EqualWaves(data0, data1, EQWAVES_DIMSIZE), "minus: wave size mismatch") + SF_AssertOnMismatchedWaves(data0, data1, SF_OPSHORT_MINUS) MatrixOp/FREE result = data0 - data1 CopyScales data0, result @@ -3331,7 +3352,7 @@ static Function/WAVE SF_OperationPlusImplDataSets(WAVE/Z data0, WAVE/Z data1) CopyScales data1, result return result endif - SFH_ASSERT(EqualWaves(data0, data1, EQWAVES_DIMSIZE), "plus: wave size mismatch") + SF_AssertOnMismatchedWaves(data0, data1, SF_OPSHORT_PLUS) MatrixOp/FREE result = data0 + data1 CopyScales data0, result @@ -3466,7 +3487,7 @@ static Function/WAVE SF_OperationDivImplDataSets(WAVE/Z data0, WAVE/Z data1) CopyScales data1, result return result endif - SFH_ASSERT(EqualWaves(data0, data1, EQWAVES_DIMSIZE), "div: wave size mismatch") + SF_AssertOnMismatchedWaves(data0, data1, SF_OPSHORT_DIV) MatrixOp/FREE result = data0 / data1 CopyScales data0, result @@ -3501,7 +3522,7 @@ static Function/WAVE SF_OperationMultImplDataSets(WAVE/Z data0, WAVE/Z data1) CopyScales data1, result return result endif - SFH_ASSERT(EqualWaves(data0, data1, EQWAVES_DIMSIZE), "mult: wave size mismatch") + SF_AssertOnMismatchedWaves(data0, data1, SF_OPSHORT_MULT) MatrixOp/FREE result = data0 * data1 CopyScales data0, result diff --git a/Packages/tests/Basic/UTF_SweepFormula_Operations.ipf b/Packages/tests/Basic/UTF_SweepFormula_Operations.ipf index aae0e0282c..787b4b416c 100644 --- a/Packages/tests/Basic/UTF_SweepFormula_Operations.ipf +++ b/Packages/tests/Basic/UTF_SweepFormula_Operations.ipf @@ -2411,3 +2411,39 @@ static Function TPWithModelCell() Make/D/FREE ref = {17.3667394014963} CHECK_EQUAL_WAVES(ref, results, mode = WAVE_DATA) End + +// IUTF_TD_GENERATOR DataGenerators#GetBasicMathOperations +static Function BasicMathMismatchedWaves([string str]) + + string code, win, opShort, error + + win = GetDataBrowserWithData() + + sprintf code, "[1, 2] %s [[1, 2]]", str + try + WAVE/WAVE output = SF_ExecuteFormula(code, win, useVariables = 0) + FAIL() + catch + CHECK_NO_RTE() + endtry + + strswitch(str) + case "*": + opShort = "mult" + break + case "/": + opShort = "div" + break + case "+": + opShort = "plus" + break + case "-": + opShort = "minus" + break + default: + FAIL() + endswitch + + error = ROStr(GetSweepFormulaParseErrorMessage()) + CHECK_EQUAL_STR(error, opShort + ": wave size mismatch [2, 0, 0, 0] vs [1, 2, 0, 0]") +End diff --git a/Packages/tests/UTF_DataGenerators.ipf b/Packages/tests/UTF_DataGenerators.ipf index 6b1a74e6f1..6dd8dedcd8 100644 --- a/Packages/tests/UTF_DataGenerators.ipf +++ b/Packages/tests/UTF_DataGenerators.ipf @@ -868,3 +868,11 @@ static Function/WAVE GetDifferentGraphs() return wv End + +static Function/WAVE GetBasicMathOperations() + Make/FREE/T op = {"+", "-", "*", "/"} + + SetDimensionLabels(OP, "plus;minus;mult;div;", ROWS) + + return op +End