diff --git a/Packages/MIES/MIES_SweepFormula_Helpers.ipf b/Packages/MIES/MIES_SweepFormula_Helpers.ipf index 01813c8d55..6d2e349681 100644 --- a/Packages/MIES/MIES_SweepFormula_Helpers.ipf +++ b/Packages/MIES/MIES_SweepFormula_Helpers.ipf @@ -1120,6 +1120,7 @@ Function [WAVE selectData, WAVE range] SFH_ParseToSelectDataWaveAndRange(WAVE sw selectData[0][%SWEEP] = JWN_GetNumberFromWaveNote(sweepData, SF_META_SWEEPNO) selectData[0][%CHANNELTYPE] = JWN_GetNumberFromWaveNote(sweepData, SF_META_CHANNELTYPE) selectData[0][%CHANNELNUMBER] = JWN_GetNumberFromWaveNote(sweepData, SF_META_CHANNELNUMBER) + selectData[0][%SWEEPMAPINDEX] = JWN_GetNumberFromWaveNote(sweepData, SF_META_SWEEPMAPINDEX) return [selectData, range] End diff --git a/Packages/MIES/MIES_SweepFormula_PSX.ipf b/Packages/MIES/MIES_SweepFormula_PSX.ipf index c3f2ffefce..a2ef1a036a 100644 --- a/Packages/MIES/MIES_SweepFormula_PSX.ipf +++ b/Packages/MIES/MIES_SweepFormula_PSX.ipf @@ -1027,10 +1027,10 @@ static Function/S PSX_BuildSweepEquivKey(variable chanType, variable chanNr) return str End -/// @brief Return the triplett channel number, channel type and sweep number from the sweep equivalence wave located in the given channelNumberType and sweepIndex coordinates -static Function [variable chanNr, variable chanType, variable sweepNo] PSX_GetSweepEquivKeyAndSweep(WAVE sweepEquiv, variable channelNumberType, variable sweepIndex) +/// @brief Return the quartett of channel number, channel type, sweep number and map index from the sweep equivalence wave located in the given channelNumberType and column coordinates +static Function [variable chanNr, variable chanType, variable sweepNo, variable mapIndex] PSX_GetSweepEquivKeyAndValue(WAVE/T sweepEquiv, variable channelNumberType, variable sweepIndex) - string str, chanTypeStr, chanNrStr + string str, chanTypeStr, chanNrStr, entry, sweepNoStr, mapIndexStr str = GetDimLabel(sweepEquiv, ROWS, channelNumberType) ASSERT(strlen(str) > 0, "Unexpected empty channelNumberType label") @@ -1040,9 +1040,25 @@ static Function [variable chanNr, variable chanType, variable sweepNo] PSX_GetSw chanType = str2num(chanTypeStr) chanNr = str2num(chanNrStr) - return [chanNr, chanType, sweepEquiv[channelNumberType][sweepIndex]] + entry = sweepEquiv[channelNumberType][sweepIndex] + + SplitString/E="(?i)SweepNo([[:digit:]]+)_MapIndex([[:digit:]]+|NaN)" entry, sweepNoStr, mapIndexStr + + sweepNo = str2num(sweepNoStr) + mapIndex = str2num(mapIndexStr) + + return [chanNr, chanType, sweepNo, mapIndex] End +/// @brief Build the column data used for the sweep equivalence wave +static Function/S PSX_BuildSweepEquivValue(variable sweepNo, variable mapIndex) + + string str + + sprintf str, "SweepNo%d_MapIndex%g", sweepNo, mapIndex + + return str +End /// @brief Generate the equivalence classes of selectData /// /// All selections which have the same channel number and type are in one equivalence class. @@ -1057,7 +1073,7 @@ static Function/WAVE PSX_GenerateSweepEquiv(WAVE selectData) numSelect = DimSize(selectData, ROWS) ASSERT(numSelect > 0, "Expected at least one entry in sweepData") - Make/N=(numSelect, numSelect)/FREE=1 sweepEquiv = NaN + Make/N=(numSelect, numSelect)/FREE=1/T sweepEquiv for(i = 0; i < numSelect; i += 1) key = PSX_BuildSweepEquivKey(selectData[i][%CHANNELTYPE], selectData[i][%CHANNELNUMBER]) @@ -1069,11 +1085,11 @@ static Function/WAVE PSX_GenerateSweepEquiv(WAVE selectData) nextFreeRow += 1 endif - FindValue/FNAN/RMD=[idx][] sweepEquiv + FindValue/TXOP=4/TEXT=""/RMD=[idx][] sweepEquiv ASSERT(V_col >= 0, "Not enough space") maxCol = max(maxCol, V_col) - sweepEquiv[idx][V_col] = selectData[i][%SWEEP] + sweepEquiv[idx][V_col] = PSX_BuildSweepEquivValue(selectData[i][%SWEEP], selectData[i][%SWEEPMAPINDEX]) endfor ASSERT(nextFreeRow > 0, "Could not build sweep equivalence classes") @@ -1086,17 +1102,17 @@ End /// @brief Collect all resolved ranges in allResolvedRanges together with a hash of the select data Function PSX_CollectResolvedRanges(string graph, WAVE range, WAVE singleSelectData, WAVE allResolvedRanges, WAVE/T allSelectHashes) - variable sweepNo, chanNr, chanType, numRows + variable sweepNo, chanNr, chanType, numRows, mapIndex sweepNo = singleSelectData[0][%SWEEP] chanNr = singleSelectData[0][%CHANNELNUMBER] chanType = singleSelectData[0][%CHANNELTYPE] + mapIndex = singleSelectData[0][%SWEEPMAPINDEX] - WAVE/Z numericalValues = BSP_GetLogbookWave(graph, LBT_LABNOTEBOOK, LBN_NUMERICAL_VALUES, sweepNumber = sweepNo) - WAVE/Z textualValues = BSP_GetLogbookWave(graph, LBT_LABNOTEBOOK, LBN_TEXTUAL_VALUES, sweepNumber = sweepNo) + [WAVE numericalValues, WAVE textualValues] = SFH_GetLabNoteBooksForSweep(graph, sweepNo, mapIndex) SFH_ASSERT(WaveExists(textualValues) && WaveExists(numericalValues), "LBN not found for sweep " + num2istr(sweepNo)) - [WAVE resolvedRanges, WAVE/T epochRangeNames] = SFH_GetNumericRangeFromEpoch(graph, numericalValues, textualValues, range, sweepNo, chanType, chanNr) + [WAVE resolvedRanges, WAVE/T epochRangeNames] = SFH_GetNumericRangeFromEpoch(graph, numericalValues, textualValues, range, sweepNo, chanType, chanNr, mapIndex) ASSERT(DimSize(resolvedRanges, COLS) == 1, "psxStats does not support epoch wildcards") numRows = DimSize(allSelectHashes, ROWS) @@ -1146,7 +1162,7 @@ static Function/WAVE PSX_OperationStatsImpl(string graph, string id, WAVE/WAVE r string propLabelAxis, comboKey variable numRows, numCols, i, j, k, index, sweepNo, chanNr, chanType, state, numRanges, lowerBoundary, upperBoundary, temp, err - variable refMarker, idx + variable refMarker, idx, mapIndex WAVE/WAVE output = SFH_CreateSFRefWave(graph, SF_OP_PSX_STATS, MINIMUM_WAVE_SIZE) @@ -1175,7 +1191,7 @@ static Function/WAVE PSX_OperationStatsImpl(string graph, string id, WAVE/WAVE r for(k = 0; k < numCols; k += 1) - [chanNr, chanType, sweepNo] = PSX_GetSweepEquivKeyAndSweep(selectDataEquiv, i, k) + [chanNr, chanType, sweepNo, mapIndex] = PSX_GetSweepEquivKeyAndValue(selectDataEquiv, i, k) if(!IsValidSweepNumber(sweepNo)) break @@ -1186,6 +1202,7 @@ static Function/WAVE PSX_OperationStatsImpl(string graph, string id, WAVE/WAVE r singleSelectData[0][%SWEEP] = sweepNo singleSelectData[0][%CHANNELNUMBER] = chanNr singleSelectData[0][%CHANNELTYPE] = chanType + singleSelectData[0][%SWEEPMAPINDEX] = mapIndex comboKey = PSX_GenerateComboKey(graph, singleSelectData, range) @@ -2943,27 +2960,29 @@ End /// to the wave note of `psxEvent`. static Function/S PSX_GenerateComboKey(string graph, WAVE selectData, WAVE range) - variable sweepNo, channel, chanType - string device, key, datafolder, rangeStr + variable sweepNo, channel, chanType, mapIndex, isDataBrowser + string device, key, rangeStr, experiment + + isDataBrowser = BSP_IsDataBrowser(graph) ASSERT(DimSize(selectData, ROWS) == 1, "Expected selectData with only one entry") sweepNo = selectData[0][%SWEEP] channel = selectData[0][%CHANNELNUMBER] chanType = selectData[0][%CHANNELTYPE] + mapIndex = selectData[0][%SWEEPMAPINDEX] - WAVE/T textualValues = BSP_GetLogbookWave(graph, LBT_LABNOTEBOOK, LBN_TEXTUAL_VALUES, sweepNumber = sweepNo) + [WAVE numericalValues, WAVE textualValues] = SFH_GetLabNoteBooksForSweep(graph, sweepNo, mapIndex) // Introduced in 7e903ed8 (GetSweepSettingsTextWave: Add device as entry, 2023-01-03) device = GetLastSettingTextIndep(textualValues, sweepNo, "Device", DATA_ACQUISITION_MODE) if(IsEmpty(device)) - if(BSP_IsDataBrowser(graph)) + if(isDataBrowser) device = BSP_GetDevice(graph) else - // datafolder looks like: root:MIES:Analysis:my_experiment:ITC18USB_Dev_0:labnotebook - datafolder = GetWavesDataFolder(textualValues, 1) - device = StringFromList(4, datafolder, ":") + WAVE/T sweepMap = SB_GetSweepMap(graph) + device = sweepMap[mapIndex][%Device] endif endif @@ -2979,7 +2998,15 @@ static Function/S PSX_GenerateComboKey(string graph, WAVE selectData, WAVE range ASSERT(0, "Unexpected wave type") endif - sprintf key, "Range[%s], Sweep [%d], Channel [%s%d], Device [%s]", rangeStr, sweepNo, StringFromList(chanType, XOP_CHANNEL_NAMES), channel, device + if(isDataBrowser) + experiment = GetExperimentName() + else + experiment = sweepMap[mapIndex][%FileName] + endif + + ASSERT(!IsEmpty(experiment), "Could not find the experiment of the given selectData") + + sprintf key, "Range[%s], Sweep [%d], Channel [%s%d], Device [%s], Experiment [%s]", rangeStr, sweepNo, StringFromList(chanType, XOP_CHANNEL_NAMES), channel, device, experiment ASSERT(strsearch(key, ":", 0) == -1, "Can't use a colon") return key diff --git a/Packages/tests/Basic/UTF_SweepFormula_PSX.ipf b/Packages/tests/Basic/UTF_SweepFormula_PSX.ipf index 1f3059bc4e..890520af5f 100644 --- a/Packages/tests/Basic/UTF_SweepFormula_PSX.ipf +++ b/Packages/tests/Basic/UTF_SweepFormula_PSX.ipf @@ -361,44 +361,58 @@ End static Function CheckSweepEquiv() - variable sweepNo, chanType, chanNr + variable sweepNo, chanType, chanNr, mapIndex - WAVE selectData = SFH_NewSelectDataWave(5, 1) + WAVE selectData = SFH_NewSelectDataWave(6, 1) selectData[0][%SWEEP] = 1 selectData[1][%SWEEP] = 2 selectData[2][%SWEEP] = 3 selectData[3][%SWEEP] = 4 selectData[4][%SWEEP] = 5 + selectData[5][%SWEEP] = 5 + + selectData[0][%SWEEPMAPINDEX] = 0 + selectData[1][%SWEEPMAPINDEX] = 1 + selectData[2][%SWEEPMAPINDEX] = 2 + selectData[3][%SWEEPMAPINDEX] = 3 + selectData[4][%SWEEPMAPINDEX] = 4 + // different mapIndex but same sweepNo + selectData[5][%SWEEPMAPINDEX] = 5 selectData[0][%CHANNELNUMBER] = 10 selectData[1][%CHANNELNUMBER] = 30 selectData[2][%CHANNELNUMBER] = 10 selectData[3][%CHANNELNUMBER] = 20 // same sweep but different channel number selectData[4][%CHANNELNUMBER] = 10 + selectData[5][%CHANNELNUMBER] = 10 selectData[0][%CHANNELTYPE] = XOP_CHANNEL_TYPE_ADC selectData[1][%CHANNELTYPE] = XOP_CHANNEL_TYPE_ADC selectData[2][%CHANNELTYPE] = XOP_CHANNEL_TYPE_TTL // same sweep bug different channel type selectData[3][%CHANNELTYPE] = XOP_CHANNEL_TYPE_ADC selectData[4][%CHANNELTYPE] = XOP_CHANNEL_TYPE_ADC + selectData[5][%CHANNELTYPE] = XOP_CHANNEL_TYPE_ADC // sweep 1 and 5 are a group the rest is separate WAVE/Z selectDataEquiv = MIES_PSX#PSX_GenerateSweepEquiv(selectData) - CHECK_WAVE(selectDataEquiv, NUMERIC_WAVE, minorType = FLOAT_WAVE) + CHECK_WAVE(selectDataEquiv, TEXT_WAVE | FREE_WAVE) - Make/FREE ref = {{1, 2, 3, 4}, {5, NaN, NaN, NaN}} + Make/FREE/T ref = {{"SweepNo1_MapIndex0", "SweepNo2_MapIndex1", "SweepNo3_MapIndex2", "SweepNo4_MapIndex3"}, \ + {"SweepNo5_MapIndex4", "", "", ""}, \ + {"SweepNo5_MapIndex5", "", "", ""}} CHECK_EQUAL_WAVES(selectDataEquiv, ref, mode = WAVE_DATA) Make/T/N=(4)/FREE refLabels = MIES_PSX#PSX_BuildSweepEquivKey(selectData[p][%CHANNELTYPE], selectData[p][%CHANNELNUMBER]) Make/T/N=(4)/FREE labels = GetDimLabel(selectDataEquiv, ROWS, p) CHECK_EQUAL_WAVES(refLabels, labels, mode = WAVE_DATA) - [chanNr, chanType, sweepNo] = MIES_PSX#PSX_GetSweepEquivKeyAndSweep(selectDataEquiv, 0, 1) + [chanNr, chanType, sweepNo, mapIndex] = MIES_PSX#PSX_GetSweepEquivKeyAndValue(selectDataEquiv, 0, 1) CHECK_EQUAL_VAR(sweepNo, 5) CHECK_EQUAL_VAR(chanType, XOP_CHANNEL_TYPE_ADC) CHECK_EQUAL_VAR(chanNr, 10) + CHECK_EQUAL_VAR(mapIndex, 4) End Function [WAVE range, WAVE selectData] GetFakeRangeAndSelectData() @@ -410,6 +424,7 @@ Function [WAVE range, WAVE selectData] GetFakeRangeAndSelectData() selectData[0][%SWEEP] = 1 selectData[0][%CHANNELTYPE] = XOP_CHANNEL_TYPE_ADC selectData[0][%CHANNELNUMBER] = 3 + selectData[0][%SWEEPMAPINDEX] = NaN return [range, selectData] End @@ -664,7 +679,7 @@ static Function StatsWorksWithResults([STRUCT IUTF_mData &m]) Redimension/N=(10, -1) psxEvent comboKey = MIES_PSX#PSX_GenerateComboKey(browser, selectData, range) - ref = "Range[100, 200], Sweep [1], Channel [AD3], Device [ITC16_Dev_0]" + ref = "Range[100, 200], Sweep [1], Channel [AD3], Device [ITC16_Dev_0], Experiment [Basic]" CHECK_EQUAL_STR(comboKey, ref) id = "myID" @@ -1144,8 +1159,8 @@ static Function TestOperationPSX([STRUCT IUTF_mData &m]) kernelAmp = m.v0 - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) // all decay fits are successfull @@ -1206,7 +1221,7 @@ static Function TestOperationPSXTooLargeDecayTau() string win, device, str variable jsonID - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(2, combos) // all decay fits are successfull @@ -1309,8 +1324,8 @@ static Function MouseSelectionPSX() string browser, device, code, psxPlot, win - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) overrideResults[][][%$"Fit Result"] = 1 @@ -1468,8 +1483,8 @@ static Function MouseSelectionPSXStats([STRUCT IUTF_mData &m]) string win, browser, code, psxGraph, psxStatsGraph, postProc variable numEvents, logMode - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) overrideResults[][][%$"Fit Result"] = 1 @@ -1555,8 +1570,8 @@ static Function MouseSelectionStatsPostProcNonFinite() string browser, code, psxGraph, win, mainWindow, psxStatsGraph, trace, tracenames - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) overrideResults[1][%$combos[0]][%$"Fit Result"] = 1 @@ -2124,8 +2139,8 @@ static Function KeyboardInteractions() string browser, code, psxGraph, win, mainWindow, psxStatsGraph, trace, tracenames - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) overrideResults[][][%$"Fit Result"] = 1 @@ -2340,8 +2355,8 @@ static Function KeyboardInteractionsStats() string browser, code, psxGraph, win, mainWindow, psxStatsGraph, trace, tracenames - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) overrideResults[][][%$"Fit Result"] = 1 @@ -2567,8 +2582,8 @@ static Function KeyboardInteractionsStatsSpecial() string browser, code, psxGraph, win, mainWindow, psxStatsGraph, trace, tracenames - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) overrideResults[][][%$"Fit Result"] = 1 @@ -2633,8 +2648,8 @@ static Function KeyboardInteractionsStatsPostProcNonFinite() string browser, code, psxGraph, win, mainWindow, psxStatsGraph, trace, tracenames - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) overrideResults[1][%$combos[0]][%$"Fit Result"] = 1 @@ -3008,8 +3023,8 @@ static Function TestStoreAndLoad() string browser, code, psxGraph, win, mainWindow, specialEventPanel, extAllGraph, bsPanel - Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0]", \ - "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0]"} + Make/FREE/T combos = {"Range[50, 150], Sweep [0], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]", \ + "Range[50, 150], Sweep [2], Channel [AD6], Device [ITC16_Dev_0], Experiment [Basic]"} WAVE overrideResults = MIES_PSX#PSX_CreateOverrideResults(4, combos) overrideResults[][][%$"Fit Result"] = 1