Skip to content

Commit

Permalink
SF_FormulaPlotter: Change how vs is treated
Browse files Browse the repository at this point in the history
Since forever we have treated `vs` as x-formula for all y-formulas
combined with `with` statments.

This makes it impossible to use different x-formulas for different
y-formulas in the same graph.

We now, with a breaking change, treat `vs` as belonging to the single
y-formula left to it.
  • Loading branch information
t-b committed Oct 24, 2023
1 parent 8f1db22 commit 33c166b
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 85 deletions.
79 changes: 40 additions & 39 deletions Packages/MIES/MIES_SweepFormula.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1567,7 +1567,7 @@ static Function SF_FormulaPlotter(string graph, string formula, [DFREF dfr, vari
variable xMxN, yMxN, xPoints, yPoints, keepUserSelection, numAnnotations, formulasAreDifferent, postPlotPSX
variable formulaCounter, gdIndex, markerCode, lineCode, lineStyle, traceToFront, isCategoryAxis
string win, wList, winNameTemplate, exWList, wName, annotation, yAxisLabel, wvName, info, xAxis
string yFormula, yFormulasRemain
string formulasRemain, yAndXFormula, xFormula, yFormula
STRUCT SF_PlotMetaData plotMetaData
STRUCT RGBColor color

Expand All @@ -1579,13 +1579,11 @@ static Function SF_FormulaPlotter(string graph, string formula, [DFREF dfr, vari
endif

WAVE/T graphCode = SF_SplitCodeToGraphs(formula)
WAVE/T/Z formulaPairs = SF_SplitGraphsToFormulas(graphCode)
SFH_ASSERT(WaveExists(formulaPairs), "Could not determine y [vs x] formula pair.")

SVAR lastCode = $GetLastSweepFormulaCode(dfr)
keepUserSelection = !cmpstr(lastCode, formula)

numGraphs = DimSize(formulaPairs, ROWS)
numGraphs = DimSize(graphCode, ROWS)
wList = ""
winNameTemplate = SF_GetFormulaWinNameTemplate(graph)

Expand All @@ -1601,7 +1599,7 @@ static Function SF_FormulaPlotter(string graph, string formula, [DFREF dfr, vari
WAVE/Z wvX = $""
WAVE/T/Z yUnits = $""

yFormulasRemain = formulaPairs[j][%FORMULA_Y]
formulasRemain = graphCode[j]

win = plotGraphs[j]
wList = AddListItem(win, wList)
Expand All @@ -1615,13 +1613,17 @@ static Function SF_FormulaPlotter(string graph, string formula, [DFREF dfr, vari
gdIndex = 0
annotation = ""

SplitString/E=SF_SWEEPFORMULA_WITH_REGEXP yFormulasRemain, yFormula, yFormulasRemain
SplitString/E=SF_SWEEPFORMULA_WITH_REGEXP formulasRemain, yAndXFormula, formulasRemain
if(!V_flag)
break
endif

[xFormula, yFormula] = SF_SplitGraphsToFormula(yAndXFormula)
SFH_ASSERT(!IsEmpty(yFormula), "Could not determine y [vs x] formula pair.")

WAVE/WAVE/Z formulaResults = $""
try
[formulaResults, plotMetaData] = SF_GatherFormulaResults(formulaPairs[j][%FORMULA_X], yFormula, graph)
[formulaResults, plotMetaData] = SF_GatherFormulaResults(xFormula, yFormula, graph)
catch
SF_CleanUpPlotWindowsOnFail(plotGraphs)
Abort
Expand Down Expand Up @@ -2364,7 +2366,7 @@ End
static Function SF_CheckInputCode(string code, string graph)

variable i, numGraphs, jsonIDy, jsonIDx, subFormulaCnt
string jsonPath, xFormula, yFormula, yFormulasRemain, subPath
string jsonPath, xFormula, yFormula, formulasRemain, subPath, yAndXFormula

NVAR jsonID = $GetSweepFormulaJSONid(SF_GetBrowserDF(graph))
JSON_Release(jsonID, ignoreErr = 1)
Expand All @@ -2374,36 +2376,41 @@ static Function SF_CheckInputCode(string code, string graph)
code = SF_CheckVariableAssignments(code, jsonID)

WAVE/T graphCode = SF_SplitCodeToGraphs(SF_PreprocessInput(code))
WAVE/T/Z formulaPairs = SF_SplitGraphsToFormulas(graphCode)
SFH_ASSERT(WaveExists(formulaPairs), "Could not determine y [vs x] formula pair.")

numGraphs = DimSize(formulaPairs, ROWS)
numGraphs = DimSize(graphCode, ROWS)
for(i = 0; i < numGraphs; i += 1)
subFormulaCnt = 0
yFormulasRemain = formulaPairs[i][%FORMULA_Y]
formulasRemain = graphCode[i]
sprintf jsonPath, "/graph_%d", i
JSON_AddObjects(jsonID, jsonPath)

do
SplitString/E=SF_SWEEPFORMULA_WITH_REGEXP yFormulasRemain, yFormula, yFormulasRemain
SplitString/E=SF_SWEEPFORMULA_WITH_REGEXP formulasRemain, yAndXFormula, formulasRemain
if(!V_flag)
break
endif

sprintf subPath, "/formula_y_%d", subFormulaCnt
jsonIdy = SF_ParseFormulaToJSON(yFormula)
JSON_AddJSON(jsonID, jsonPath + subPath, jsonIDy)
[xFormula, yFormula] = SF_SplitGraphsToFormula(yAndXFormula)
SFH_ASSERT(!IsEmpty(yFormula), "Could not determine y [vs x] formula pair.")

sprintf subPath, "%s/pair_%d", jsonPath, subFormulaCnt
JSON_AddTreeObject(jsonID, subPath)

sprintf subPath, "%s/pair_%d/formula_y", jsonPath, subFormulaCnt
jsonIDy = SF_ParseFormulaToJSON(yFormula)
JSON_AddJSON(jsonID, subPath, jsonIDy)
JSON_Release(jsonIDy)

if(!IsEmpty(xFormula))
jsonIDx = SF_ParseFormulaToJSON(xFormula)

sprintf subPath, "%s/pair_%d/formula_x", jsonPath, subFormulaCnt
JSON_AddJSON(jsonID, subPath, jsonIDx)
JSON_Release(jsonIDx)
endif

subFormulaCnt += 1
while(1)

xFormula = formulaPairs[i][%FORMULA_X]
if(!IsEmpty(xFormula))
jsonIdx = SF_ParseFormulaToJSON(xFormula)
JSON_AddJSON(jsonID, jsonPath + "/formula_x", jsonIDx)
JSON_Release(jsonIDx)
endif
endfor
End

Expand Down Expand Up @@ -4833,26 +4840,20 @@ static Function/WAVE SF_SplitCodeToGraphs(string code)
return graphCode
End

static Function/WAVE SF_SplitGraphsToFormulas(WAVE/T graphCode)
static Function [string xFormula, string yFormula] SF_SplitGraphsToFormula(string graphCode)

variable i, numGraphs, numFormulae
string yFormula, xFormula
variable numFormulae

WAVE/T wFormulas = GetYandXFormulas()
SplitString/E=SF_SWEEPFORMULA_REGEXP graphCode, yFormula, xFormula
numFormulae = V_Flag

numGraphs = DimSize(graphCode, ROWS)
Redimension/N=(numGraphs, -1) wFormulas
for(i = 0; i < numGraphs; i += 1)
SplitString/E=SF_SWEEPFORMULA_REGEXP graphCode[i], yFormula, xFormula
numFormulae = V_Flag
if(numFormulae != 1 && numFormulae != 2)
return $""
endif
wFormulas[i][%FORMULA_X] = SelectString(numFormulae == 2, "", xFormula)
wFormulas[i][%FORMULA_Y] = yFormula
endfor
if(numFormulae != 1 && numFormulae != 2)
return ["", ""]
endif

xFormula = SelectString(numFormulae == 2, "", xFormula)

return wFormulas
return [xFormula, yFormula]
End

static Function/S SF_GetFormulaWinNameTemplate(string mainWindow)
Expand Down
Binary file modified Packages/MIES/SweepFormulaHelp.ifn
Binary file not shown.
Binary file removed Packages/doc/ScreenShots/sweepFormulaPlot2.png
Binary file not shown.
Binary file removed Packages/doc/ScreenShots/sweepFormulaPlot3.png
Binary file not shown.
51 changes: 10 additions & 41 deletions Packages/doc/SweepFormula.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1474,37 +1474,6 @@ Note that in this example there are 10 Y-values and only 9 X-values returned by
respective formula part. The resulting graph shows 9 data points and thus does not show
data points where either an X or Y value for the X, Y value pair is missing.
The plotter supports the same X-values for multiple traces:
.. code-block:: bash
[1, 3], [2, 4], [3, 5], [4, 6], [5, 7] vs 1...6
.. figure:: ScreenShots/sweepFormulaPlot2.png
:align: center
This example plots two traces with five data points each against equidistant
X coordinates 1, 2, 3, 4, 5. The first trace is colored blue for demonstration.
This also works for a constant X value and multiple traces.
The same way separate X value series for traces can be set:
.. code-block:: bash
[1, 3], [2, 4], [3, 5], [4, 6], [5, 7] vs [1, 0], [2, 0.5], [3, 1], [4, 1.5], [5, 2]
.. figure:: ScreenShots/sweepFormulaPlot3.png
:align: center
The above example plots two traces with the first one Y series: 1, 2, 3, 4, 5; X series: 1, 2, 3, 4, 5
and the second Y series: 3, 4, 5, 6, 7; X series: 0, 0.5, 1, 1.5, 2.
The first trace is colored blue for demonstration.
There is one special case where given X-values are not applied for every trace. If the following conditions
apply then the n-th value of the given X-values is used for the n-th trace:
- there is the same amount of Y-data-waves as points in the X-wave
- the Y-wave for a trace contains only one data point
.. code-block:: bash
min(data(TP,select(channels(AD0), 4...11,all)))
Expand Down Expand Up @@ -1537,24 +1506,24 @@ The above code creates a panel with three separate graphs arranged vertically ev
Multiple Y-Formulas
"""""""""""""""""""
Several y-formulas can be plotted with the keyword `with`. The `with` must be on an own line between the y-formulas.
If the y-data contains different data units the y-axis will show all data units separated by `/`.
Several y-formulas can be plotted with the keyword `with`. The `with` must be
on an own line between the y-formulas. If the y-data contains different data
units the y-axis will show all data units separated by `/`. The `vs` allows to
set a custom x-formula for the *single* y-formula left to it. Variables, see
next section, can be used to reuse x-formulas for multiple statements without
code duplication.
.. code-block:: bash
xdata = range(10, 100, 10)
0...10
with
20...30
vs range(10, 100, 10)
20...30 vs $xdata
and
10...20
with
30...40
with
40...50
vs range(10, 100, 10)
and
20...30
40...50 vs $xdata
Variables
^^^^^^^^^
Expand Down
10 changes: 5 additions & 5 deletions Packages/tests/Basic/UTF_SweepFormula.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1798,7 +1798,7 @@ static Function TestPlotting()
String strArray0D = "1"
String strCombined = "[1, 2] vs [3, 4]\rand\r[5, 6] vs [7, 8]\rand\r[9, 10]\rand\r"
String strCombinedPartial = "[1, 2] vs [1, 2]\rand\r[1?=*, 2] vs [1, 2]"
string strWith = "[1, 2]\rwith\r[2, 3] vs [3, 4]\rand\r[5, 6]\rwith\r[2, 3]\rwith\r[4, 5] vs [7, 8]\rand\r[9, 10]\rwith\r\rand\r"
string strWith = "[1, 2] vs [3, 4] \rwith\r[2, 3] vs [3, 4]\rand\r[5, 6] vs [7, 8] \rwith\r[2, 3] vs [7, 8] \rwith\r[4, 5] vs [7, 8]\rand\r[9, 10]"

// Reference data waves must be moved out of the working DF for the further tests as
// calling the FormulaPlotter later kills the working DF
Expand Down Expand Up @@ -3554,28 +3554,28 @@ static Function TestInputCodeCheck()
NVAR jsonID = $GetSweepFormulaJSONid(dfr)

formula = "1"
jsonRef = "{\n\"graph_0\": {\n\"formula_y_0\": 1\n}\n}"
jsonRef = "{\n\"graph_0\": {\n\"pair_0\": {\n\"formula_y\": 1\n}\n}\n}"
MIES_SF#SF_CheckInputCode(formula, win)
jsonTxt = JSON_Dump(jsonId)
JSON_Release(jsonId)
CHECK_EQUAL_STR(jsonRef, jsonTxt)

formula = "1 vs 1"
jsonRef = "{\n\"graph_0\": {\n\"formula_x\": 1,\n\"formula_y_0\": 1\n}\n}"
jsonRef = "{\n\"graph_0\": {\n\"pair_0\": {\n\"formula_x\": 1,\n\"formula_y\": 1\n}\n}\n}"
MIES_SF#SF_CheckInputCode(formula, win)
jsonTxt = JSON_Dump(jsonId)
JSON_Release(jsonId)
CHECK_EQUAL_STR(jsonRef, jsonTxt)

formula = "1\rwith\r1 vs 1"
jsonRef = "{\n\"graph_0\": {\n\"formula_x\": 1,\n\"formula_y_0\": 1,\n\"formula_y_1\": 1\n}\n}"
jsonRef = "{\n\"graph_0\": {\n\"pair_0\": {\n\"formula_y\": 1\n},\n\"pair_1\": {\n\"formula_x\": 1,\n\"formula_y\": 1\n}\n}\n}"
MIES_SF#SF_CheckInputCode(formula, win)
jsonTxt = JSON_Dump(jsonId)
JSON_Release(jsonId)
CHECK_EQUAL_STR(jsonRef, jsonTxt)

formula = "v = 1\r1"
jsonRef = "{\n\"graph_0\": {\n\"formula_y_0\": 1\n},\n\"variable:v\": 1\n}"
jsonRef = "{\n\"graph_0\": {\n\"pair_0\": {\n\"formula_y\": 1\n}\n},\n\"variable:v\": 1\n}"
MIES_SF#SF_CheckInputCode(formula, win)
jsonTxt = JSON_Dump(jsonId)
JSON_Release(jsonId)
Expand Down

0 comments on commit 33c166b

Please sign in to comment.