Skip to content

Commit

Permalink
MIES_JSONWaveNotes.ipf: Add read/write support for wave reference waves
Browse files Browse the repository at this point in the history
  • Loading branch information
t-b committed Jan 31, 2024
1 parent 66018eb commit 6956624
Show file tree
Hide file tree
Showing 2 changed files with 252 additions and 2 deletions.
88 changes: 86 additions & 2 deletions Packages/MIES/MIES_JSONWaveNotes.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,65 @@ threadsafe Function/WAVE JWN_GetTextWaveFromWaveNote(WAVE wv, string jsonPath)
return textWave
End

/// @brief Return the wave reference wave at jsonPath found in the wave note
///
/// All contained waves must be numeric.
///
/// @param wv wave reference where the WaveNote is taken from
/// @param jsonPath path to array
///
/// @returns the wave on success. null wave is returned if it could not be found
threadsafe Function/WAVE JWN_GetWaveRefNumericFromWaveNote(WAVE wv, string jsonPath)

return JWN_GetWaveRefFromWaveNote_Impl(wv, jsonPath, IGOR_TYPE_NUMERIC_WAVE)
End

/// @brief Return the wave reference wave at jsonPath found in the wave note
///
/// All contained waves must be text.
///
/// @param wv wave reference where the WaveNote is taken from
/// @param jsonPath path to array
///
/// @returns the wave on success. null wave is returned if it could not be found
threadsafe Function/WAVE JWN_GetWaveRefTextFromWaveNote(WAVE wv, string jsonPath)

return JWN_GetWaveRefFromWaveNote_Impl(wv, jsonPath, IGOR_TYPE_TEXT_WAVE)
End

threadsafe static Function/WAVE JWN_GetWaveRefFromWaveNote_Impl(WAVE wv, string jsonPath, variable type)
variable jsonID, numRows

jsonID = JWN_GetWaveNoteAsJSON(wv)
ASSERT_TS(JSON_GetType(jsonID, jsonPath, ignoreErr = 1) == JSON_ARRAY, "Expected array at jsonPath")
WAVE/Z maxArraySizes = JSON_GetMaxArraySize(jsonID, jsonPath, ignoreErr = 1)
ASSERT_TS(WaveExists(maxArraySizes) , "Could not query array size")

numRows = maxArraySizes[ROWS]
if(numRows == 0)
return $""
endif

Make/FREE/WAVE/N=(numRows) container

switch(type)
case IGOR_TYPE_NUMERIC_WAVE:
container[] = JSON_GetWave(jsonID, jsonPath + "/" + num2str(p), ignoreErr = 1, waveMode = 1)
break
case IGOR_TYPE_TEXT_WAVE:
container[] = JSON_GetTextWave(jsonID, jsonPath + "/" + num2str(p), ignoreErr = 1)
break
default:
ASSERT_TS(0, "Invalid type")
endswitch

JSON_Release(jsonID)

ASSERT_TS(IsNaN(GetRowIndex(container, refWave = $"")), "Encountered invalid waves in the container")

return container
End

/// @brief Return the string value at jsonPath found in the wave note
///
/// @param wv wave reference where the WaveNote is taken from
Expand Down Expand Up @@ -194,13 +253,38 @@ End
/// @param noteWave new wave value
threadsafe Function JWN_SetWaveInWaveNote(WAVE wv, string jsonPath, WAVE noteWave)

variable jsonID
variable jsonID, idx
string jsonPathArray

ASSERT_TS(WaveExists(wv), "Missing wave")
ASSERT_TS(WaveExists(noteWave), "Missing noteWave")

ASSERT_TS(!IsEmpty(jsonPath), "Empty jsonPath")
ASSERT_TS(IsNumericWave(noteWave) || IsTextWave(noteWave), "Only numeric and text waves are supported as JSON wave note entry.")

ASSERT_TS(IsWaveRefWave(noteWave) || IsNumericWave(noteWave) || IsTextWave(noteWave), \
"Only wave references waves, numeric and text waves are supported as JSON wave note entry.")

if(IsWaveRefWave(noteWave))
ASSERT_TS(DimSize(noteWave, COLS) <= 1, "Expected only a 1D wave reference wave")

// create an array at jsonPath with noteWave ROWS entries
jsonID = JWN_GetWaveNoteAsJSON(wv)
Make/FREE/N=(DimSize(noteWave, ROWS)) junk
JSON_SetWave(jsonID, jsonPath, junk)
JWN_WriteWaveNote(wv, JWN_GetWaveNoteHeader(wv), jsonID)

WAVE/WAVE waveRef = noteWave

for(WAVE/Z elem : waveRef)
ASSERT_TS(WaveExists(elem), "Contained wave must exist")
// and now write at each array index the contained wave
jsonPathArray = jsonPath + "/" + num2str(idx)
JWN_SetWaveInWaveNote(wv, jsonPathArray, elem)
idx += 1
endfor

return NaN
endif

jsonID = JWN_GetWaveNoteAsJSON(wv)
JSON_SetWave(jsonID, jsonPath, noteWave)
Expand Down
166 changes: 166 additions & 0 deletions Packages/tests/Basic/UTF_JSONWaveNotes.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,172 @@ static Function TestSetWaveInJSONWaveNote()
CHECK_WAVE(data, NULL_WAVE)
End

static Function Test_WaveRefNumeric()

Make/FREE wv
Make/FREE/N=10 wvData0

wvData0[0] = NaN
wvData0[1] = Inf
wvData0[2] = -Inf
wvData0[3] = -10

Make/FREE wvData1 = {1, 2, 3, 4}
Make/FREE/N=0 wvData2
Make/N=(1, 2)/FREE wvData3 = p + q
Make/FREE/WAVE wvRef = {wvData0, wvData1, wvData2, wvData3}
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)

WAVE/Z data = JWN_GetNumericWaveFromWaveNote(wv, "refWave/0")
CHECK_EQUAL_WAVES(data, wvData0, mode = WAVE_DATA)

WAVE/Z data = JWN_GetNumericWaveFromWaveNote(wv, "refWave/1")
CHECK_EQUAL_WAVES(data, wvData1, mode = WAVE_DATA)

WAVE/Z data = JWN_GetNumericWaveFromWaveNote(wv, "refWave/2")
CHECK_EQUAL_WAVES(data, wvData2, mode = WAVE_DATA)

WAVE/Z data = JWN_GetNumericWaveFromWaveNote(wv, "refWave/3")
CHECK_EQUAL_WAVES(data, wvData3, mode = WAVE_DATA)

WAVE/WAVE/Z container = JWN_GetWaveRefNumericFromWaveNote(wv, "refWave")
CHECK_EQUAL_VAR(DimSize(container, ROWS), 4)
CHECK_EQUAL_VAR(DimSize(container, COLS), 0)

CHECK_EQUAL_WAVES(wvRef[0], container[0], mode = WAVE_DATA)
CHECK_EQUAL_WAVES(wvRef[1], container[1], mode = WAVE_DATA)
CHECK_EQUAL_WAVES(wvRef[2], container[2], mode = WAVE_DATA)
CHECK_EQUAL_WAVES(wvRef[3], container[3], mode = WAVE_DATA)

// empty wave ref wave
Note/K wv
Make/FREE/WAVE/N=0 wvRef
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)
WAVE/Z container = JWN_GetWaveRefTextFromWaveNote(wv, "refWave")
CHECK_WAVE(container, NULL_WAVE)

Note/K wv
Make/FREE/WAVE wvRef = {wvData0}
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)

WAVE/Z data = JWN_GetNumericWaveFromWaveNote(wv, "refWave/0")
CHECK_EQUAL_WAVES(data, wvData0, mode = WAVE_DATA)

// no array
Note/K wv
JWN_SetNumberInWaveNote(wv, "num", 123)

try
WAVE/Z container = JWN_GetWaveRefNumericFromWaveNote(wv, "num")
FAIL()
catch
PASS()
endtry

// null wave
Note/K wv
Make/FREE/WAVE/N=1 wvRef

try
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)
FAIL()
catch
PASS()
endtry

// wrong type
Note/K wv
Make/N=1/T txtWave = "abcd"
Make/FREE/WAVE/N=1 wvRef = {txtWave}
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)

try
WAVE/Z container = JWN_GetWaveRefNumericFromWaveNote(wv, "refWave")
FAIL()
catch
PASS()
endtry
End

static Function Test_WaveRefText()

Make/FREE wv
Make/FREE/N=10/T wvData0

wvData0[0] = "abcd"
wvData0[1] = "efg"
wvData0[2] = "1234"

Make/FREE/T wvData1 = {"a", "b", "c", "d"}
Make/FREE/N=0 wvData2
Make/N=(1, 2)/FREE/T wvData3 = num2str(p + q)
Make/FREE/WAVE wvRef = {wvData0, wvData1, wvData2, wvData3}
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)

WAVE/Z data = JWN_GetTextWaveFromWaveNote(wv, "refWave/0")
CHECK_EQUAL_WAVES(data, wvData0, mode = WAVE_DATA)

WAVE/Z data = JWN_GetTextWaveFromWaveNote(wv, "refWave/1")
CHECK_EQUAL_WAVES(data, wvData1, mode = WAVE_DATA)

WAVE/Z data = JWN_GetTextWaveFromWaveNote(wv, "refWave/2")
CHECK_EQUAL_WAVES(data, wvData2, mode = WAVE_DATA)

WAVE/Z data = JWN_GetTextWaveFromWaveNote(wv, "refWave/3")
CHECK_EQUAL_WAVES(data, wvData3, mode = WAVE_DATA)

WAVE/WAVE/Z container = JWN_GetWaveRefTextFromWaveNote(wv, "refWave")
CHECK_EQUAL_VAR(DimSize(container, ROWS), 4)
CHECK_EQUAL_VAR(DimSize(container, COLS), 0)

CHECK_EQUAL_WAVES(wvRef[0], container[0], mode = WAVE_DATA)
CHECK_EQUAL_WAVES(wvRef[1], container[1], mode = WAVE_DATA)
CHECK_EQUAL_WAVES(wvRef[2], container[2], mode = WAVE_DATA)
CHECK_EQUAL_WAVES(wvRef[3], container[3], mode = WAVE_DATA)

// empty wave ref wave
Note/K wv
Make/FREE/WAVE/N=0 wvRef
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)
WAVE/Z container = JWN_GetWaveRefTextFromWaveNote(wv, "refWave")
CHECK_WAVE(container, NULL_WAVE)

// no array
Note/K wv
JWN_SetNumberInWaveNote(wv, "num", 123)

try
WAVE/Z container = JWN_GetWaveRefTextFromWaveNote(wv, "num")
FAIL()
catch
PASS()
endtry

// null wave
Note/K wv
Make/FREE/WAVE/N=1 wvRef

try
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)
FAIL()
catch
PASS()
endtry

// wrong type
Note/K wv
Make/N=1 waveDataNum = 1
Make/FREE/WAVE/N=1 wvRef = {waveDataNum}
JWN_SetWaveInWaveNote(wv, "refWave", wvRef)

try
WAVE/Z container = JWN_GetWaveRefTextFromWaveNote(wv, "refWave")
FAIL()
catch
PASS()
endtry
End

static Function TestJSONWaveNoteCombinations()

string str
Expand Down

0 comments on commit 6956624

Please sign in to comment.