Skip to content

Commit b5db391

Browse files
authored
Merge pull request #2481 from AllenInstitute/bugfix/2481-color-groups-across-with-statements
Fix colorgroups across with statements
2 parents 6f50942 + a2a8e6e commit b5db391

File tree

7 files changed

+197
-52
lines changed

7 files changed

+197
-52
lines changed

Packages/MIES/MIES_SweepFormula.ipf

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ static Function/WAVE SF_GenerateTraceColors(WAVE colorGroups)
315315
for(i = 0; i < numUniqueColors; i += 1)
316316
[STRUCT RGBColor s] = GetTraceColorAlternative(i)
317317

318-
lbl = num2str(uniqueColorGroups[i])
318+
lbl = num2istr(uniqueColorGroups[i])
319319
SetDimLabel ROWS, i, $lbl, traceColors
320320

321321
traceColors[i][%Red] = s.red
@@ -326,34 +326,40 @@ static Function/WAVE SF_GenerateTraceColors(WAVE colorGroups)
326326
return traceColors
327327
End
328328

329-
/// @brief Return an Nx3 wave with one color triplett for each unique trace color group
330-
static Function/WAVE SF_GetGroupColors(WAVE/WAVE formulaResults)
329+
/// @brief Add the color groups from the formulaResults to colorGroups and return it
330+
static Function/WAVE SF_GetColorGroups(WAVE/WAVE formulaResults, WAVE/Z colorGroups)
331331

332332
variable numFormulas, i, numUniqueColors, refColorGroup, constantChannelNumAndType
333333
string lbl
334334

335335
numFormulas = DimSize(formulaResults, ROWS)
336336

337337
if(numFormulas == 0)
338-
return $""
338+
return colorGroups
339339
endif
340340

341341
WAVE/Z data = formulaResults[0][%FORMULAY]
342342

343343
if(!WaveExists(data))
344-
return $""
344+
return colorGroups
345345
endif
346346

347347
refColorGroup = JWN_GetNumberFromWaveNote(data, SF_META_COLOR_GROUP)
348348

349349
if(IsNaN(refColorGroup))
350-
return $""
350+
return colorGroups
351351
endif
352352

353-
Make/FREE/N=(numFormulas)/D colorGroups = JWN_GetNumberFromWaveNote(formulaResults[p][%FORMULAY], SF_META_COLOR_GROUP)
353+
Make/FREE/N=(numFormulas)/D newColorGroups = JWN_GetNumberFromWaveNote(formulaResults[p][%FORMULAY], SF_META_COLOR_GROUP)
354+
355+
if(WaveExists(colorGroups))
356+
Concatenate/FREE/NP=(ROWS) {colorGroups, newColorGroups}, allColorGroups
357+
else
358+
WAVE allColorGroups = newColorGroups
359+
endif
354360

355361
if(numFormulas == 1)
356-
return SF_GenerateTraceColors(colorGroups)
362+
return allColorGroups
357363
endif
358364

359365
// check if the data in the y formulas is from the same channel type and number
@@ -364,18 +370,20 @@ static Function/WAVE SF_GetGroupColors(WAVE/WAVE formulaResults)
364370
&& IsConstant(channelTypes, channelTypes[0], ignoreNaN = 0)
365371

366372
if(!constantChannelNumAndType)
367-
return $""
373+
return colorGroups
368374
endif
369375

370-
return SF_GenerateTraceColors(colorGroups)
376+
return allColorGroups
371377
End
372378

373-
Function [STRUCT RGBColor s] SF_GetTraceColor(string graph, string opStack, WAVE data, WAVE/Z traceGroupColors)
379+
Function [STRUCT RGBColor s] SF_GetTraceColor(string graph, string opStack, WAVE data, WAVE/Z colorGroups)
374380

375381
variable i, channelNumber, channelType, sweepNo, headstage, numDoInh, minVal, isAveraged, mapIndex
376382
variable colorGroup, idx
377383

378-
if(WaveExists(traceGroupColors))
384+
if(WaveExists(colorGroups))
385+
WAVE traceGroupColors = SF_GenerateTraceColors(colorGroups)
386+
379387
// Operations with trace group color support:
380388
// - data/epochs/tp/psxKernel (via SFH_GetSweepsForFormula)
381389
// - labnotebook
@@ -384,7 +392,7 @@ Function [STRUCT RGBColor s] SF_GetTraceColor(string graph, string opStack, WAVE
384392
colorGroup = JWN_GetNumberFromWaveNote(data, SF_META_COLOR_GROUP)
385393
ASSERT(IsFinite(colorGroup), "Invalid color group")
386394

387-
idx = FindDimLabel(traceGroupColors, ROWS, num2str(colorGroup))
395+
idx = FindDimLabel(traceGroupColors, ROWS, num2istr(colorGroup))
388396
ASSERT(idx >= 0, "Invalid color group index")
389397

390398
s.red = traceGroupColors[idx][%Red]
@@ -820,7 +828,8 @@ static Function SF_FormulaPlotter(string graph, string formula, [variable dmMode
820828
postPlotPSX = 0
821829
showLegend = 1
822830
formulaCounter = 0
823-
WAVE/Z wvX = $""
831+
WAVE/Z wvX = $""
832+
WAVE/Z colorGroups = $""
824833

825834
Make/FREE/T/N=0 xAxisLabels, yAxisLabels
826835

@@ -865,7 +874,12 @@ static Function SF_FormulaPlotter(string graph, string formula, [variable dmMode
865874

866875
SF_FormulaPlotterExtendResultsIfCompatible(formulaResults)
867876

868-
WAVE/Z traceGroupColors = SF_GetGroupColors(formulaResults)
877+
if(WaveExists(colorGroups))
878+
Duplicate/FREE colorGroups, previousColorGroups
879+
else
880+
WAVE/ZZ previousColorGroups
881+
endif
882+
WAVE/Z colorGroups = SF_GetColorGroups(formulaResults, previousColorGroups)
869883

870884
numData = DimSize(formulaResults, ROWS)
871885
for(k = 0; k < numData; k += 1)
@@ -881,7 +895,7 @@ static Function SF_FormulaPlotter(string graph, string formula, [variable dmMode
881895

882896
SFH_ASSERT(!(IsTextWave(wvResultY) && WaveDims(wvResultY) > 1), "Plotter got 2d+ text wave as y data.")
883897

884-
[color] = SF_GetTraceColor(graph, plotMetaData.opStack, wvResultY, traceGroupColors)
898+
[color] = SF_GetTraceColor(graph, plotMetaData.opStack, wvResultY, colorGroups)
885899

886900
if(!WaveExists(wvResultX) && !IsEmpty(plotMetaData.xAxisLabel))
887901
WAVE/Z wvResultX = JWN_GetNumericWaveFromWaveNote(wvResultY, SF_META_XVALUES)

Packages/MIES/MIES_Utilities_Conversions.ipf

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,3 +905,61 @@ Function/WAVE UTF8StringToTextWave(string str)
905905

906906
return wv
907907
End
908+
909+
/// @brief Extract a numeric wave from a keyword list
910+
///
911+
/// \rst
912+
///
913+
/// .. code-block:: igorpro
914+
///
915+
/// WAVE wv = NumericWaveByKey("kb", "ka:va;kb:[1,2,3]")
916+
/// // wv contains {1, 2, 3}
917+
///
918+
/// \endrst
919+
///
920+
/// @param key key
921+
/// @param kwList keyword-value list
922+
/// @param keySep [optional, defaults to `:`] separator between keyword and values
923+
/// @param listSep [optional, defaults to `;`] separator between keyword-value items
924+
/// @param wvListSep [optional, defaults to `,`] separator between wave values
925+
/// @param matchCase [optional, defaults to false] match the case of the key (1) or not (0)
926+
/// @param wvType [optional, defaults to IGOR_TYPE_64BIT_FLOAT] type of the created wave
927+
Function/WAVE NumericWaveByKey(string key, string kwList, [string keySep, string listSep, string wvListSep, variable matchCase, variable wvType])
928+
929+
string value
930+
variable length
931+
932+
if(ParamIsDefault(keySep))
933+
keySep = ":"
934+
endif
935+
936+
if(ParamIsDefault(listSep))
937+
listSep = ";"
938+
endif
939+
940+
if(ParamIsDefault(wvListSep))
941+
wvListSep = ","
942+
endif
943+
944+
if(ParamIsDefault(matchCase))
945+
matchCase = 0
946+
else
947+
matchCase = !!matchCase
948+
endif
949+
950+
if(ParamIsDefault(wvType))
951+
wvType = IGOR_TYPE_64BIT_FLOAT
952+
endif
953+
954+
value = StringByKey(key, kwList, keySep, listSep, matchCase)
955+
length = strlen(value)
956+
957+
if(length <= 2)
958+
return $""
959+
endif
960+
961+
// drop surrounding parantheses
962+
value = value[1, length - 2]
963+
964+
return ListToNumericWave(value, wvListSep, type = wvType)
965+
End

Packages/tests/Basic/UTF_SweepFormula.ipf

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,7 +2051,7 @@ static Function TestVariablePlottingDoesNotModifyData()
20512051
graphBase = BSP_GetFormulaGraph(win)
20522052
graph = graphBase + "_#Graph" + "0"
20532053

2054-
ExecuteSweepFormulaInDB(code, win)
2054+
ExecuteSweepFormulaCode(win, code)
20552055
REQUIRE_EQUAL_VAR(WindowExists(graph), 1)
20562056

20572057
WAVE/WAVE varStorage = GetSFVarStorage(win)
@@ -2077,7 +2077,7 @@ static Function TestVariablePlottingDifferentSubsequentBaseTypes()
20772077
graphBase = BSP_GetFormulaGraph(win)
20782078
graph = graphBase + "_#Graph" + "0"
20792079

2080-
ExecuteSweepFormulaInDB(code, win)
2080+
ExecuteSweepFormulaCode(win, code)
20812081
REQUIRE_EQUAL_VAR(WindowExists(graph), 1)
20822082
WAVE/WAVE varStorage = GetSFVarStorage(win)
20832083
WAVE/WAVE dataRef = SFH_AttemptDatasetResolve(WaveText(WaveRef(varStorage, row = FindDimLabel(varStorage, ROWS, "data")), row = 0))
@@ -2090,7 +2090,7 @@ static Function TestVariablePlottingDifferentSubsequentBaseTypes()
20902090
Make/N=3 root:testData = p
20912091

20922092
code = "data=wave(root:testData)\r$data"
2093-
ExecuteSweepFormulaInDB(code, win)
2093+
ExecuteSweepFormulaCode(win, code)
20942094

20952095
WAVE/WAVE varStorage = GetSFVarStorage(win)
20962096
WAVE/WAVE dataRef = SFH_AttemptDatasetResolve(WaveText(WaveRef(varStorage, row = FindDimLabel(varStorage, ROWS, "data")), row = 0))
@@ -2114,7 +2114,7 @@ static Function TestVariableReadOnly()
21142114
Make/N=100 root:testData = p + offset
21152115

21162116
code = "data=wave(root:testData)\rpowerspectrum($data)"
2117-
ExecuteSweepFormulaInDB(code, win)
2117+
ExecuteSweepFormulaCode(win, code)
21182118

21192119
WAVE/WAVE varStorage = GetSFVarStorage(win)
21202120
WAVE/WAVE dataRef = SFH_AttemptDatasetResolve(WaveText(WaveRef(varStorage, row = FindDimLabel(varStorage, ROWS, "data")), row = 0))
@@ -2144,7 +2144,7 @@ static Function TestKeepsUnitsWhenMappingMultipleYToOne()
21442144
SetScale/P y, 0, 1, "y2", data2
21452145

21462146
code = "dataset(wave(data1), wave(data1)) vs dataset(wave(data2))"
2147-
ExecuteSweepFormulaInDB(code, win)
2147+
ExecuteSweepFormulaCode(win, code)
21482148
yAxis = AxisLabel(graph, "left")
21492149
CHECK_EQUAL_STR(yAxis, "(y1)")
21502150
xAxis = AxisLabel(graph, "bottom")
@@ -2175,11 +2175,63 @@ static Function TestAxisLabelGathering()
21752175
code = "wave(data1)\r" + \
21762176
"with \r" + \
21772177
"wave(data2) vs wave(data3)\r"
2178-
ExecuteSweepFormulaInDB(code, win)
2178+
ExecuteSweepFormulaCode(win, code)
21792179
yAxis = AxisLabel(graph, "left")
21802180
CHECK_EQUAL_STR(yAxis, "(y1) / (y2)")
21812181
xAxis = AxisLabel(graph, "bottom")
21822182
CHECK_EQUAL_STR(xAxis, "(x1) / (x3)")
21832183

21842184
KillWaves/Z data1, data2, data3
21852185
End
2186+
2187+
static Function TestTraceColor(string graph, string traces, variable index, WAVE colors)
2188+
2189+
string info, trace
2190+
2191+
trace = StringFromList(index, traces)
2192+
CHECK_PROPER_STR(trace)
2193+
2194+
info = TraceInfo(graph, trace, 0)
2195+
CHECK_PROPER_STR(info)
2196+
2197+
WAVE traceColors = NumericWaveByKey("rgb(x)", info, keySep = "=", listSep = ";")
2198+
CHECK_EQUAL_WAVES(traceColors, colors, mode = WAVE_DATA)
2199+
End
2200+
2201+
static Function TestTraceColors()
2202+
2203+
string win, device, code, graph, winBase, traces, trace, info
2204+
2205+
[win, device] = CreateEmptyUnlockedDataBrowserWindow()
2206+
2207+
win = CreateFakeSweepData(win, device, sweepNo = 0)
2208+
win = CreateFakeSweepData(win, device, sweepNo = 1)
2209+
2210+
code = "data()"
2211+
winBase = ExecuteSweepFormulaCode(win, code)
2212+
2213+
graph = winBase + "#Graph0"
2214+
2215+
traces = TraceNameList(graph, ";", 1 + 2)
2216+
CHECK_EQUAL_VAR(ItemsInList(traces), 2)
2217+
2218+
// these are the per headstage colors
2219+
TestTraceColor(graph, traces, 0, {7967, 7710, 7710})
2220+
TestTraceColor(graph, traces, 1, {60395, 52685, 15934})
2221+
2222+
code = "data(select(selchannels(AD6)))\r with\r data(select(selchannels(AD6)))"
2223+
winBase = ExecuteSweepFormulaCode(win, code)
2224+
2225+
graph = winBase + "#Graph0"
2226+
2227+
traces = TraceNameList(graph, ";", 1 + 2)
2228+
CHECK_EQUAL_VAR(ItemsInList(traces), 2)
2229+
2230+
// color groups:
2231+
// black
2232+
TestTraceColor(graph, traces, 0, {0, 0, 0})
2233+
2234+
// and
2235+
// yellow
2236+
TestTraceColor(graph, traces, 1, {59110, 40863, 0})
2237+
End

Packages/tests/Basic/UTF_SweepFormula_Operations.ipf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ static Function StoreChecksParameters([string str])
175175

176176
win = GetDataBrowserWithData()
177177

178-
CHECK(!ExecuteSweepFormulaInDB(str, win))
178+
ExecuteSweepFormulaCode(win, str, expectFailure = 1)
179179

180180
WAVE textualResultsValues = GetLogbookWaves(LBT_RESULTS, LBN_TEXTUAL_VALUES)
181181
CHECK_EQUAL_VAR(GetNumberFromWaveNote(textualResultsValues, NOTE_INDEX), 0)
@@ -194,7 +194,7 @@ static Function StoreWorks([WAVE wv])
194194
ref = "store(\"ABCD\", " + JSON_Dump(array) + " ) vs 0"
195195
JSON_Release(array)
196196

197-
CHECK(ExecuteSweepFormulaInDB(ref, win))
197+
ExecuteSweepFormulaCode(win, ref)
198198

199199
WAVE textualResultsValues = GetLogbookWaves(LBT_RESULTS, LBN_TEXTUAL_VALUES)
200200

@@ -240,7 +240,7 @@ static Function StoreWorksWithMultipleDataSets()
240240
[numSweeps, numChannels, WAVE/U/I channels] = FillFakeDatabrowserWindow(win, device, XOP_CHANNEL_TYPE_ADC, textKey, textValue)
241241

242242
str = "store(\"ABCD\", data(select(selrange(), selchannels(), selsweeps())))"
243-
CHECK(ExecuteSweepFormulaInDB(str, win))
243+
ExecuteSweepFormulaCode(win, str)
244244

245245
WAVE textualResultsValues = GetLogbookWaves(LBT_RESULTS, LBN_TEXTUAL_VALUES)
246246

@@ -3317,7 +3317,7 @@ static Function TPWithModelCell()
33173317

33183318
win = DB_GetBoundDataBrowser(device)
33193319

3320-
CHECK(ExecuteSweepFormulaInDB("store(\"inst\",tp(tpinst()))\n and \nstore(\"ss\",tp(tpss()))", win))
3320+
ExecuteSweepFormulaCode(win, "store(\"inst\",tp(tpinst()))\n and \nstore(\"ss\",tp(tpss()))")
33213321

33223322
WAVE textualResultsValues = GetLogbookWaves(LBT_RESULTS, LBN_TEXTUAL_VALUES)
33233323

Packages/tests/Basic/UTF_SweepFormula_PSX.ipf

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,7 +1703,7 @@ End
17031703

17041704
static Function CheckTraceColors(string win, WAVE/T traces, variable state)
17051705

1706-
string tInfo, rgbValue, trace
1706+
string tInfo, trace
17071707
variable numEntries
17081708

17091709
[WAVE acceptColors, WAVE rejectColors, WAVE undetColors] = MIES_PSX#PSX_GetEventColors()
@@ -1727,11 +1727,10 @@ static Function CheckTraceColors(string win, WAVE/T traces, variable state)
17271727
endswitch
17281728

17291729
for(trace : traces)
1730-
tInfo = TraceInfo(win, trace, 0)
1731-
rgbValue = StringByKey("rgb(x)", tInfo, "=", ";")
1732-
WAVE traceColors = ListToNumericWave(rgbValue[1, strlen(rgbValue) - 2], ",")
1730+
tInfo = TraceInfo(win, trace, 0)
1731+
WAVE traceColors = NumericWaveByKey("rgb(x)", tInfo, keySep = "=", listSep = ";")
17331732

1734-
INFO("trace %s, state %s, rgbValue \"%s\"", s0 = trace, s1 = MIES_PSX#PSX_StateToString(state), s2 = rgbValue)
1733+
INFO("trace %s, state %s, traceColors (%s)", s0 = trace, s1 = MIES_PSX#PSX_StateToString(state), s2 = NumericWaveToList(traceColors, ";"))
17351734

17361735
// average waves don't have alpha set
17371736
numEntries = DimSize(traceColors, ROWS)
@@ -2887,7 +2886,7 @@ static Function NoEventsAtAll()
28872886

28882887
code = "psx(psxKernel(select(selrange([50, 150]), selchannels(AD6), selsweeps([0, 2]), selvis(all))), 100, 100, 0)"
28892888

2890-
win = ExecuteSweepFormulaCode(browser, code)
2889+
win = ExecuteSweepFormulaCode(browser, code, expectFailure = 1)
28912890

28922891
try
28932892
psxGraph = MIES_PSX#PSX_GetPSXGraph(win)

Packages/tests/Basic/UTF_Utils_Conversions.ipf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,3 +1062,29 @@ Function GMC_SomeVariants()
10621062

10631063
CHECK_EQUAL_VAR(MICRO_TO_TERA, 1e-18)
10641064
End
1065+
1066+
Function TestNumericWaveByKey()
1067+
1068+
// all defaults
1069+
WAVE/Z wv = NumericWaveByKey("kb", "ka:va;kb:[1,2,3]")
1070+
CHECK_WAVE(wv, NUMERIC_WAVE, minorType = IGOR_TYPE_64BIT_FLOAT)
1071+
CHECK_EQUAL_WAVES(wv, {1, 2, 3}, mode = WAVE_DATA)
1072+
1073+
// no content
1074+
WAVE/Z wv = NumericWaveByKey("ka", "ka:[];kb:[1,2,3]")
1075+
CHECK_WAVE(wv, NULL_WAVE)
1076+
1077+
// ignores case
1078+
WAVE/Z wv = NumericWaveByKey("KB", "ka:va;kb:[1,2,3]")
1079+
CHECK_WAVE(wv, NUMERIC_WAVE, minorType = IGOR_TYPE_64BIT_FLOAT)
1080+
CHECK_EQUAL_WAVES(wv, {1, 2, 3}, mode = WAVE_DATA)
1081+
1082+
// respect case
1083+
WAVE/Z wv = NumericWaveByKey("KB", "ka:va;kb:[1,2,3]", matchCase = 1)
1084+
CHECK_WAVE(wv, NULL_WAVE)
1085+
1086+
// custom delimiters and wave type
1087+
WAVE/Z wv = NumericWaveByKey("KB", "ka=va|kb=[1;2;3]", keySep = "=", listSep = "|", wvListSep = ";", wvType = IGOR_TYPE_8BIT_INT)
1088+
CHECK_WAVE(wv, NUMERIC_WAVE, minorType = IGOR_TYPE_8BIT_INT)
1089+
CHECK_EQUAL_WAVES(wv, {1, 2, 3}, mode = WAVE_DATA)
1090+
End

0 commit comments

Comments
 (0)