Skip to content

Commit

Permalink
Merge pull request #2210 from AllenInstitute/bugfix/2210-prevent-non-…
Browse files Browse the repository at this point in the history
…finite-values-in-stimset

Don't allow non-finite values in stimsets
  • Loading branch information
t-b authored Sep 1, 2024
2 parents 455d5b7 + 019de97 commit 31e4327
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 8 deletions.
4 changes: 4 additions & 0 deletions Packages/MIES/MIES_DAEphys.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -2913,6 +2913,10 @@ static Function DAP_CheckStimset(device, channelType, channel, headstage)
printf "(%s) The stim set %s of headstage %g is empty, but must have at least one row.\r", device, setName, headstage
ControlWindowToFront()
return 1
elseif(HasOneNonFiniteEntry(stimSet))
printf "(%s) The stim set %s of headstage %g has at least one NaN/Inf/-Inf. Please remove them.\r", device, setName, headstage
ControlWindowToFront()
return 1
endif

// non fatal errors which we fix ourselves
Expand Down
15 changes: 15 additions & 0 deletions Packages/MIES/MIES_Utilities_Checks.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,21 @@ threadsafe Function HasOneFiniteEntry(WAVE wv)
ASSERT_TS(0, "Unsupported wave type")
End

/// @brief Return true if wave has one infinite entry (Inf, -Inf or NaN)
threadsafe Function HasOneNonFiniteEntry(WAVE wv)

if(IsFloatingPointWave(wv))
if(!numpnts(wv))
return 0
endif

WaveStats/Q/M=1 wv
return V_numNaNs != 0 || V_numINFs != 0
endif

ASSERT_TS(0, "Unsupported wave type")
End

/// @brief Checks if a string ends with a specific suffix. The check is case-insensitive.
///
/// @param[in] str string to check for suffix
Expand Down
15 changes: 15 additions & 0 deletions Packages/MIES/MIES_WaveBuilder.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -2654,6 +2654,10 @@ Function/S WB_SaveStimSet(string baseName, variable stimulusType, WAVE SegWvType
return ""
endif

if(WB_CheckStimsetContents(stimset))
return ""
endif

// we now know that the stimset is valid
// let's save it under the desired name and delete the temporary one
WB_SaveStimSetParameterWaves(setName, SegWvType, WP, WPT, stimulusType)
Expand Down Expand Up @@ -2688,6 +2692,17 @@ Function/WAVE WB_GetEpochLengths(string setName)
return epochLengths
End

static Function WB_CheckStimsetContents(WAVE stimset)

if(HasOneNonFiniteEntry(stimset))
printf "The stimset contains at least one NaN/Inf/-Inf. Please remove them.\r"
ControlWindowToFront()
return 1
endif

return 0
End

static Function WB_CheckForEmptyEpochs(string setname)

variable idx
Expand Down
Binary file modified Packages/tests/Basic/Basic.pxp
Binary file not shown.
40 changes: 40 additions & 0 deletions Packages/tests/Basic/UTF_Utils_Checks.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,46 @@ End

/// @}

/// HasOneNonFiniteEntry
/// @{

static Function HasOneNonFiniteEntry_AssertsOnInvalidType()

Make/B/FREE wv
try
HasOneNonFiniteEntry(wv)
FAIL()
catch
PASS()
endtry
End

static Function HasOneNonFiniteEntry_Works1()

Make/FREE/D wv = {1, 2, 3}
CHECK(!HasOneNonFiniteEntry(wv))
End

static Function HasOneNonFiniteEntry_Works2()

Make/FREE/D wv = {Inf, 0}
CHECK(HasOneNonFiniteEntry(wv))

Make/FREE/D wv = {-Inf, 1}
CHECK(HasOneNonFiniteEntry(wv))

Make/FREE/D wv = {NaN, 3}
CHECK(HasOneNonFiniteEntry(wv))
End

static Function HasOneNonFiniteEntry_Works3()

Make/FREE/D/N=0 wv
CHECK(!HasOneNonFiniteEntry(wv))
End

/// @}

/// EqualValuesOrBothNaN
/// @{

Expand Down
33 changes: 25 additions & 8 deletions Packages/tests/Basic/UTF_WaveBuilderRegression.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,26 @@ static Function TEST_CASE_END_OVERRIDE(testCase)
CheckForBugMessages()
End

// Copy stimset parameter waves into our own permanent location
Function CopyParamWaves_IGNORE()
// Copy stimset parameter waves and data waves into our own permanent location
Function CopyParamWavesAndWaves_IGNORE()

string entry

KillDataFolder/Z root:wavebuilder_misc:DAParameterWaves
DuplicateDataFolder/O=2 $GetWBSvdStimSetParamDAPathAS(), root:wavebuilder_misc:DAParameterWaves
End

// Copy stimsets into our own permanent location
Function CopyWaves_IGNORE()
// recreate all stimsets
DFREF dfr = GetWBSvdStimSetDAPath()
KillDataFolder/Z dfr

WAVE/T stimsets = ListToTextWave(ST_GetStimsetList(), ";")
for(entry : stimsets)
WB_CreateAndGetStimSet(entry)
endfor

KillDataFolder/Z root:wavebuilder_misc:DAWaves
DuplicateDataFolder/O=2 $GetWBSvdStimSetDAPathAsString(), root:wavebuilder_misc:DAWaves
DFREF dfr = GetWBSvdStimSetDAPath()
DuplicateDataFolder/O=2 dfr, root:wavebuilder_misc:DAWaves
End

Function/WAVE WB_FetchRefWave_IGNORE(string name)
Expand Down Expand Up @@ -81,6 +91,9 @@ Function WB_RegressionTest([string stimset])
WAVE/Z wv = WB_CreateAndGetStimSet(stimset)
CHECK_WAVE(wv, NUMERIC_WAVE, minorType = FLOAT_WAVE)

INFO("Stimset %s needs to only have finite entries.", s0 = stimset)
CHECK(!HasOneNonFiniteEntry(wv))

// parameter waves were upgraded
WAVE WP = WB_GetWaveParamForSet(stimset)
CHECK_EQUAL_VAR(MIES_WAVEGETTERS#GetWaveVersion(WP), MIES_WAVEGETTERS#GetWPVersion())
Expand All @@ -93,8 +106,12 @@ Function WB_RegressionTest([string stimset])

// check against our stimset generated with earlier versions
WAVE refWave = WB_FetchRefWave_IGNORE(stimset)
DUplicate/O refwave, root:refwave
duplicate/O wv, root:wv

#ifdef AUTOMATED_TESTING_DEBUGGING
Duplicate/O refwave, root:refwave
Duplicate/O wv, root:wv
#endif // AUTOMATED_TESTING_DEBUGGING

CHECK_EQUAL_WAVES(refWave, wv, mode = WAVE_DATA, tol = 1e-12)

text = note(wv)
Expand Down

0 comments on commit 31e4327

Please sign in to comment.