Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add read/write support for wave reference waves in JSON wave notes #1989

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 88 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,11 +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
Loading