diff --git a/Packages/MIES/MIES_AnalysisBrowser.ipf b/Packages/MIES/MIES_AnalysisBrowser.ipf index 5b5ce30cc5..db814d4703 100644 --- a/Packages/MIES/MIES_AnalysisBrowser.ipf +++ b/Packages/MIES/MIES_AnalysisBrowser.ipf @@ -2174,7 +2174,7 @@ static Function AB_LoadSweepFromNWBgeneric(variable h5_groupID, variable nwbVers WAVE/Z/SDFR=sweepDFR targetName = $channelName // nwb files created prior to 901428b might have duplicated datasets - if(WaveExists(targetName) && WaveCRC(0, targetName) != WaveCRC(0, loaded)) + if(WaveExists(targetName) && cmpstr(HashWave("", targetName), HashWave("", loaded))) KillOrMoveToTrash(dfr = sweepDFR) FATAL_ERROR("wave with same name, but different content, already exists: " + channelName) endif diff --git a/Packages/MIES/MIES_BrowserSettingsPanel.ipf b/Packages/MIES/MIES_BrowserSettingsPanel.ipf index a905e0c6e7..bfe11122e7 100644 --- a/Packages/MIES/MIES_BrowserSettingsPanel.ipf +++ b/Packages/MIES/MIES_BrowserSettingsPanel.ipf @@ -27,7 +27,7 @@ static StrConstant BROWSERSETTINGS_AXES_SCALING_CHECKBOXES = "check_Display_Visi static StrConstant SWEEPCONTROL_CONTROLS_DATABROWSER = "check_SweepControl_AutoUpdate;setvar_SweepControl_SweepNo;" static StrConstant SWEEPCONTROL_CONTROLS_SWEEPBROWSER = "popup_SweepControl_Selector;" -static StrConstant BSP_USER_DATA_SF_CONTENT_CRC = "SweepFormulaContentCRC" +static StrConstant BSP_USER_DATA_SF_CONTENT_HASH = "SweepFormulaContentHash" static Constant BSP_EPOCH_LEVELS = 5 @@ -1744,7 +1744,8 @@ End Function BSP_SFHelpWindowHook(STRUCT WMWinHookStruct &s) string mainWin, sfWin, bspPanel, cmdStr - variable modMask, refContentCRC, contentCRC + variable modMask + string refContentHash, contentHash switch(s.eventCode) case EVENT_WINDOW_HOOK_MOUSEDOWN: @@ -1778,13 +1779,13 @@ Function BSP_SFHelpWindowHook(STRUCT WMWinHookStruct &s) break case EVENT_WINDOW_HOOK_ACTIVATE: // fallthrough case EVENT_WINDOW_HOOK_DEACTIVATE: - mainWin = GetMainWindow(s.winName) - sfWin = BSP_GetSFFormula(mainWin) - refContentCRC = str2num(GetUserData(mainWin, "", BSP_USER_DATA_SF_CONTENT_CRC)) - contentCRC = GetNotebookCRC(sfWin) - if(!CmpStr(sfWin, s.winName) && refContentCRC != contentCRC) + mainWin = GetMainWindow(s.winName) + sfWin = BSP_GetSFFormula(mainWin) + refContentHash = GetUserData(mainWin, "", BSP_USER_DATA_SF_CONTENT_HASH) + contentHash = GetNotebookHash(sfWin) + if(!CmpStr(sfWin, s.winName) && cmpstr(refContentHash, contentHash)) BSP_SFFormulaColoring(sfWin) - SetWindow $mainWin, userData($BSP_USER_DATA_SF_CONTENT_CRC)=num2istr(contentCRC) + SetWindow $mainWin, userData($BSP_USER_DATA_SF_CONTENT_HASH)=contentHash endif break default: diff --git a/Packages/MIES/MIES_Cache.ipf b/Packages/MIES/MIES_Cache.ipf index 4a40d49bfd..cf3247ce0d 100644 --- a/Packages/MIES/MIES_Cache.ipf +++ b/Packages/MIES/MIES_Cache.ipf @@ -16,17 +16,16 @@ /// /// Usage: /// * Write a key generator function returning a string -/// The parameters to CA_GenKey() must completely determine the wave you will later store. +/// The parameters to CA_GenerateKeyFancyCalc() must completely determine the wave you will later store. /// The appended version string to the key allows you to invalidate old keys /// if the algorithm creating the wave changes, but all input stays the same. /// /// \rst /// .. code-block:: igorpro /// -/// Function/S CA_GenKey(input) -/// variable input +/// Function/S CA_GenerateKeyFancyCalc(string input) /// -/// return stringCRC(0, num2str(input)) + "Version 1" +/// return HashString("", input) + ":FancyCalc:Version 1" /// End /// \endrst /// @@ -38,10 +37,9 @@ /// \rst /// .. code-block:: igorpro /// -/// Function/WAVE MyFancyCalculation(input) -/// variable input +/// Function/WAVE MyFancyCalculation(string input) /// -/// string key = CA_GenKey(input) +/// string key = CA_GenerateKeyFancyCalc(input) /// /// WAVE/Z result = CA_TryFetchingEntryFromCache(key) /// @@ -59,7 +57,7 @@ /// \endrst /// /// * Deleting cache entries has to be done *manually* via CA_DeleteCacheEntry(). -/// The cache is also stored in a packed experiment. +/// The cache is also stored in a experiment file. /// /// * The entries in the cache are stored as free wave copies of what you feed into CA_StoreEntryIntoCache(). /// Similiary you get a free wave copy from CA_TryFetchingEntryFromCache(). @@ -73,7 +71,7 @@ /// @brief Cache key generator for recreated epochs wave Function/S CA_KeyRecreatedEpochs(WAVE numericalValues, WAVE/T textualValues, DFREF sweepDFR, variable sweepNo) - variable crc + string hv = "" // the calculation assumes that recreated epochs are based on an old LNB // thats content is treated as const (except mod time, as this check is fast) @@ -82,50 +80,51 @@ Function/S CA_KeyRecreatedEpochs(WAVE numericalValues, WAVE/T textualValues, DFR ASSERT_TS(!IsFreeWave(textualValues), "Textual LNB wave must be global") ASSERT_TS(!IsFreeDatafolder(sweepDFR), "sweepDFR must not be free") - crc = StringCRC(0, GetWavesDataFolder(numericalValues, 2)) - crc = StringCRC(crc, num2istr(WaveModCountWrapper(numericalValues))) + hv = HashString(hv, GetWavesDataFolder(numericalValues, 2)) + hv = HashNumber(hv, WaveModCountWrapper(numericalValues)) - crc = StringCRC(crc, GetWavesDataFolder(textualValues, 2)) - crc = StringCRC(crc, num2istr(WaveModCountWrapper(textualValues))) + hv = HashString(hv, GetWavesDataFolder(textualValues, 2)) + hv = HashNumber(hv, WaveModCountWrapper(textualValues)) - crc = StringCRC(crc, GetDataFolder(1, sweepDFR)) - crc = StringCRC(crc, num2istr(sweepNo)) - crc = StringCRC(crc, num2istr(SWEEP_EPOCH_VERSION)) + hv = HashString(hv, GetDataFolder(1, sweepDFR)) + hv = HashNumber(hv, sweepNo) + hv = HashNumber(hv, SWEEP_EPOCH_VERSION) - return num2istr(crc) + "Version 1" + return hv + ":Version 1" End /// @brief Cache key generator for oodDAQ offset waves Function/S CA_DistDAQCreateCacheKey(STRUCT OOdDAQParams ¶ms) - variable numWaves, crc, i + variable numWaves, i + string hv = "" numWaves = DimSize(params.stimSets, ROWS) - crc = WaveCRC(0, params.setColumns) + hv = HashWave(hv, params.setColumns) for(i = 0; i < numWaves; i += 1) - crc = WaveCRC(crc, params.stimSets[i]) + hv = HashWave(hv, params.stimSets[i]) endfor - crc = StringCRC(crc, num2str(params.preFeaturePoints)) - crc = StringCRC(crc, num2str(params.postFeaturePoints)) + hv = HashNumber(hv, params.preFeaturePoints) + hv = HashNumber(hv, params.postFeaturePoints) - return num2istr(crc) + "Version 5" + return hv + ":Version 5" End /// @brief Cache key generator for @c FindLevel in PA_CalculatePulseTimes() Function/S CA_PulseTimes(WAVE wv, string fullPath, variable channelNumber, variable totalOnsetDelay) - variable crc + string hv = "" - crc = StringCRC(crc, num2istr(ModDate(wv))) - crc = StringCRC(crc, num2istr(WaveModCountWrapper(wv))) - crc = StringCRC(crc, fullPath) - crc = StringCRC(crc, num2istr(channelNumber)) - crc = StringCRC(crc, num2str(totalOnsetDelay)) + hv = HashNumber(hv, ModDate(wv)) + hv = HashNumber(hv, WaveModCountWrapper(wv)) + hv = HashString(hv, fullPath) + hv = HashNumber(hv, channelNumber) + hv = HashNumber(hv, totalOnsetDelay) - return num2istr(crc) + "Version 2" + return hv + ":Version 2" End /// @brief Cache key generator for PA_SmoothDeconv() @@ -135,14 +134,14 @@ End /// @param range_pnts number of points (p) the smoothing was performed Function/S CA_SmoothDeconv(WAVE wv, variable smoothingFactor, variable range_pnts) - variable crc + string hv = "" - crc = WaveCRC(0, wv) - crc = StringCRC(crc, num2str(DimDelta(wv, ROWS))) - crc = StringCRC(crc, num2istr(smoothingFactor)) - crc = StringCRC(crc, num2istr(range_pnts)) + hv = HashWave(hv, wv) + hv = HashNumber(hv, DimDelta(wv, ROWS)) + hv = HashNumber(hv, smoothingFactor) + hv = HashNumber(hv, range_pnts) - return num2istr(crc) + "Version 1" + return hv + ":Version 1" End /// @brief Cache key generator for PA_Deconvolution() @@ -151,28 +150,28 @@ End /// @param tau convolution time Function/S CA_Deconv(WAVE wv, variable tau) - variable crc + string hv = "" - crc = WaveCRC(0, wv) - crc = StringCRC(crc, num2str(DimDelta(wv, ROWS))) - crc = StringCRC(crc, num2str(tau)) + hv = HashWave(hv, wv) + hv = HashNumber(hv, DimDelta(wv, ROWS)) + hv = HashNumber(hv, tau) - return num2istr(crc) + "Version 1" + return hv + ":Version 1" End /// @brief Cache key generator for GetActiveChannels threadsafe Function/S CA_GenKeyGetActiveChannels(WAVE numericalValues, WAVE textualValues, variable sweepNo, variable channelType, variable TTLmode) string primitiveKey - string version = "Version 1" - variable crc + string version = ":Version 1" + string hv = "" sprintf primitiveKey, "%d_%d_%d_%s", sweepNo, channelType, TTLmode, version - crc = CA_GetWaveModCRC(numericalValues, 0) - crc = CA_GetWaveModCRC(textualValues, crc) - crc = StringCRC(crc, primitiveKey) + hv = CA_GetWaveModHash(numericalValues, hv) + hv = CA_GetWaveModHash(textualValues, hv) + hv = HashString(hv, primitiveKey) - return num2istr(crc) + version + return hv + version End /// @brief Cache key generator for LBN index cache @@ -196,53 +195,54 @@ End /// @brief Cache key generator for Logbook sortedKeyWave threadsafe Function/S CA_GenKeyLogbookSortedKeys(WAVE keys) - string version = "Version 1" - variable crc + string hv = "" - crc = CA_GetWaveModCRC(keys, 0) + hv = CA_GetWaveModHash(keys, hv) - return num2istr(crc) + version + return hv + ":Version 1" End /// @brief Cache key generator for artefact removal ranges Function/S CA_ArtefactRemovalRangesKey(DFREF singleSweepDFR, variable sweepNo) - variable crc + string hv = "" - crc = StringCRC(crc, GetDataFolder(1, singleSweepDFR)) - crc = StringCRC(crc, num2str(sweepNo)) + hv = HashString(hv, GetDataFolder(1, singleSweepDFR)) + hv = HashNumber(hv, sweepNo) - return num2istr(crc) + "Version 1" + return hv + ":Version 1" End /// @brief Cache key generator for averaging Function/S CA_AveragingKey(WAVE/WAVE waveRefs) - return CA_WaveCRCs(waveRefs, includeWaveScalingAndUnits = 1, dims = ROWS) + "Version 6" + return CA_WaveHash(waveRefs, includeWaveScalingAndUnits = 1, dims = ROWS) + ":Version 6" End /// @brief Cache key generator for averaging info from non-free waves Function/S CA_AveragingWaveModKey(WAVE wv) - return num2istr(CA_RecursiveWavemodCRC(wv)) + "Version 1" + return CA_RecursiveWaveModHash(wv) + ":Version 1" End /// @brief Cache key generator for the tau range calculation /// of psx events Function/S CA_PSXEventGoodTauRange(WAVE wv) - return num2istr(CA_RecursiveWavemodCRC(wv)) + "Version 1" + return CA_RecursiveWaveModHash(wv) + ":Version 1" End -/// @brief Calculated a CRC from non wave reference waves using modification data, wave modification count and wave location. -/// If the given wave is a wave reference wave, then the CRC is calculated recursively from +/// @brief Calculated a hash from non wave reference waves using modification data, wave modification count and wave location. +/// If the given wave is a wave reference wave, then the hash is calculated recursively from /// all non wave reference waves and null wave references found. -static Function CA_RecursiveWavemodCRC(WAVE/Z wv, [variable prevCRC]) +static Function/S CA_RecursiveWaveModHash(WAVE/Z wv, [string prevHash]) variable rows_, cols_, layers_, chunks_ variable i, j, k, l - prevCRC = ParamIsDefault(prevCRC) ? 0 : prevCRC + if(ParamIsDefault(prevHash)) + prevHash = "" + endif if(!WaveExists(wv)) // prevents getting the same key when the internal layout of the multi dimensional @@ -255,7 +255,7 @@ static Function CA_RecursiveWavemodCRC(WAVE/Z wv, [variable prevCRC]) // null, null, null // null, w1, w2 // null, w3, w4 - return StringCRC(prevCRC, "null wave") + return HashString(prevHash, "null wave") endif if(IsWaveRefWave(wv)) @@ -274,25 +274,29 @@ static Function CA_RecursiveWavemodCRC(WAVE/Z wv, [variable prevCRC]) for(k = 0; k < layers_; k += 1) for(j = 0; j < cols_; j += 1) for(i = 0; i < rows_; i += 1) - prevCRC = CA_RecursiveWavemodCRC(wvRef[i][j][k][l], prevCRC = prevCRC) + prevHash = CA_RecursiveWaveModHash(wvRef[i][j][k][l], prevHash = prevHash) endfor endfor endfor endfor else - prevCRC = CA_GetWaveModCRC(wv, prevCRC) + prevHash = CA_GetWaveModHash(wv, prevHash) endif - return prevCRC + return prevHash End -threadsafe static Function CA_GetWaveModCRC(WAVE wv, variable crc) +threadsafe static Function/S CA_GetWaveModHash(WAVE wv, string hv) + + hv = HashNumber(hv, ModDate(wv)) + hv = HashNumber(hv, WaveModCountWrapper(wv)) + hv = HashString(hv, GetWavesDataFolder(wv, 2)) - return StringCRC(crc, num2istr(ModDate(wv)) + num2istr(WaveModCountWrapper(wv)) + GetWavesDataFolder(wv, 2)) + return hv End -/// @brief Calculate the CRC of all metadata of all or the given dimension -threadsafe static Function CA_WaveScalingCRC(variable crc, WAVE wv, [variable dimension]) +/// @brief Calculate the hash of all metadata of all dimensions or the given only +threadsafe static Function/S CA_WaveScalingHash(string hv, WAVE wv, [variable dimension]) variable dims, i @@ -307,46 +311,42 @@ threadsafe static Function CA_WaveScalingCRC(variable crc, WAVE wv, [variable di endif for(i = 0; i < dims; i += 1) - crc = StringCRC(crc, num2str(DimSize(wv, dimension))) - crc = StringCRC(crc, num2str(DimOffset(wv, dimension))) - crc = StringCRC(crc, num2str(DimDelta(wv, dimension))) - crc = StringCRC(crc, WaveUnits(wv, dimension)) + hv = HashNumber(hv, DimSize(wv, dimension)) + hv = HashNumber(hv, DimOffset(wv, dimension)) + hv = HashNumber(hv, DimDelta(wv, dimension)) + hv = HashString(hv, WaveUnits(wv, dimension)) endfor - return crc + return hv End -/// @brief Calculate CRC values of the wave `dims` giving the dimensions of a wave -threadsafe static Function CA_WaveSizeCRC(WAVE dims) +/// @brief Calculate hash values of the wave `dims` giving the dimensions of a wave +threadsafe static Function/S CA_WaveSizeHash(WAVE dims) - variable numRows, crc, i + variable numRows, i + string hv = "" numRows = DimSize(dims, ROWS) ASSERT_TS(numRows > 0 && numRows <= MAX_DIMENSION_COUNT && DimSize(dims, COLS) <= 1, "Invalid dims dimensions") for(i = 0; i < numRows; i += 1) - crc = StringCRC(crc, num2istr(dims[i])) + hv = HashNumber(hv, dims[i]) endfor - return crc + return hv End -/// @brief Calculate all CRC values of the waves referenced in waveRefs +/// @brief Calculate all hash values of the waves referenced in waveRefs /// /// @param waveRefs wave reference wave -/// @param crcMode [optional] parameter to WaveCRC /// @param includeWaveScalingAndUnits [optional] include the wave scaling and units of filled dimensions -/// @param dims [optional] number of dimensions to include wave scaling and units in crc -static Function/S CA_WaveCRCs(WAVE/WAVE waveRefs, [variable crcMode, variable includeWaveScalingAndUnits, variable dims]) +/// @param dims [optional] number of dimensions to include wave scaling and units in hash +static Function/S CA_WaveHash(WAVE/WAVE waveRefs, [variable includeWaveScalingAndUnits, variable dims]) variable rows ASSERT(IsWaveRefWave(waveRefs), "Expected a wave reference wave") - if(ParamIsDefault(crcMode)) - crcMode = 0 - endif - if(ParamIsDefault(includeWaveScalingAndUnits)) includeWaveScalingAndUnits = 0 else @@ -359,33 +359,36 @@ static Function/S CA_WaveCRCs(WAVE/WAVE waveRefs, [variable crcMode, variable in rows = DimSize(waveRefs, ROWS) ASSERT(rows > 0, "Unexpected number of entries") - Make/D/FREE/N=(rows) crc - MultiThread/NT=(rows < NUM_ENTRIES_FOR_MULTITHREAD) crc[] = WaveCRC(0, waveRefs[p], crcMode) + Make/T/FREE/N=(rows) hashes + MultiThread/NT=(rows < NUM_ENTRIES_FOR_MULTITHREAD) hashes[] = HashWave("", waveRefs[p]) if(includeWaveScalingAndUnits) - MultiThread/NT=(rows < NUM_ENTRIES_FOR_MULTITHREAD) crc[] = CA_WaveScalingCRC(crc[p], waveRefs[p]) + MultiThread/NT=(rows < NUM_ENTRIES_FOR_MULTITHREAD) hashes[] = CA_WaveScalingHash(hashes[p], waveRefs[p], dimension = dims) endif - return NumericWaveToList(crc, ";", format = "%.15g") + return HashWave("", hashes) End /// @brief Calculate the cache key for SI_FindMatchingTableEntry. /// -/// We are deliberatly not using a WaveCRC here as know that the wave is not +/// We are deliberatly not using a HashWave here as know that the wave is not /// changed in IP once loaded. Therefore using its name and ModDate is enough. Function/S CA_SamplingIntervalKey(WAVE lut, STRUCT ActiveChannels &s) - variable crc + string hv = "" - crc = StringCRC(crc, num2istr(s.numDARack1)) - crc = StringCRC(crc, num2istr(s.numADRack1)) - crc = StringCRC(crc, num2istr(s.numTTLRack1)) - crc = StringCRC(crc, num2istr(s.numDARack2)) - crc = StringCRC(crc, num2istr(s.numADRack2)) - crc = StringCRC(crc, num2istr(s.numTTLRack2)) + hv = HashNumber(hv, s.numDARack1) + hv = HashNumber(hv, s.numADRack1) + hv = HashNumber(hv, s.numTTLRack1) + hv = HashNumber(hv, s.numDARack2) + hv = HashNumber(hv, s.numADRack2) + hv = HashNumber(hv, s.numTTLRack2) ASSERT(!IsFreeWave(lut), "lut can not be a free wave") - return num2istr(crc) + NameOfWave(lut) + num2istr(ModDate(lut)) + "Version 1" + hv = HashString(hv, NameOfWave(lut)) + hv = HashNumber(hv, ModDate(lut)) + + return hv + ":Version 1" End /// @brief Generic key generator for storing throw away waves used for @@ -394,33 +397,33 @@ End /// Only the size is relevant, the rest is undefined. threadsafe Function/S CA_TemporaryWaveKey(WAVE dims) - variable crc + string hv = "" - crc = CA_WaveSizeCRC(dims) + hv = CA_WaveSizeHash(dims) - return num2istr(crc) + "Temporary waves Version 2" + return hv + "Temporary waves Version 2" End /// @brief Key generator for FindIndizes threadsafe Function/S CA_FindIndizesKey(WAVE dims) - variable crc + string hv - crc = CA_WaveSizeCRC(dims) + hv = CA_WaveSizeHash(dims) - return num2istr(crc) + "FindIndizes Version 1" + return hv + "FindIndizes Version 1" End /// @brief Calculate the cache key for the hardware device info wave Function/S CA_HWDeviceInfoKey(string device, variable hardwareType, variable deviceID) - variable crc + string hv = "" - crc = StringCrc(crc, device) - crc = StringCrc(crc, num2str(hardwareType)) - crc = StringCrc(crc, num2str(deviceID)) + hv = HashString(hv, device) + hv = HashNumber(hv, hardwareType) + hv = HashNumber(hv, deviceID) - return num2istr(crc) + "HW Device Info Version 1" + return hv + ":HW Device Info Version 1" End /// @brief Generate a key for the DAQDataWave in TEST_PULSE_MODE @@ -436,33 +439,33 @@ End /// - testPulseLength, baselineFrac Function/S CA_HardwareDataTPKey(STRUCT HardwareDataTPInput &s) - variable crc + string hv = "" - crc = StringCRC(crc, num2str(s.hardwareType)) - crc = StringCRC(crc, num2str(s.numDACs)) - crc = StringCRC(crc, num2str(s.numActiveChannels)) - crc = StringCRC(crc, num2str(s.numberOfRows)) - crc = StringCRC(crc, num2str(s.samplingInterval)) - crc = WaveCRC(crc, s.gains) - crc = WaveCRC(crc, s.DACAmpTP) - crc = StringCRC(crc, num2str(s.testPulseLength)) - crc = StringCRC(crc, num2str(s.baselineFrac)) + hv = HashNumber(hv, s.hardwareType) + hv = HashNumber(hv, s.numDACs) + hv = HashNumber(hv, s.numActiveChannels) + hv = HashNumber(hv, s.numberOfRows) + hv = HashNumber(hv, s.samplingInterval) + hv = HashWave(hv, s.gains) + hv = HashWave(hv, s.DACAmpTP) + hv = HashNumber(hv, s.testPulseLength) + hv = HashNumber(hv, s.baselineFrac) - return num2istr(crc) + "HW Datawave Testpulse Version 2" + return hv + "HW Datawave Testpulse Version 2" End Function/S CA_PSXKernelOperationKey(variable riseTau, variable decayTau, variable amp, variable numPoints, variable dt, WAVE range) - variable crc + string hv = "" - crc = StringCRC(crc, num2strHighPrec(riseTau, precision = MAX_DOUBLE_PRECISION)) - crc = StringCRC(crc, num2strHighPrec(decayTau, precision = MAX_DOUBLE_PRECISION)) - crc = StringCRC(crc, num2strHighPrec(amp, precision = MAX_DOUBLE_PRECISION)) - crc = StringCRC(crc, num2strHighPrec(numPoints, precision = MAX_DOUBLE_PRECISION)) - crc = StringCRC(crc, num2strHighPrec(dt, precision = MAX_DOUBLE_PRECISION)) - crc = WaveCRC(crc, range) + hv = HashString(hv, num2strHighPrec(riseTau, precision = MAX_DOUBLE_PRECISION)) + hv = HashString(hv, num2strHighPrec(decayTau, precision = MAX_DOUBLE_PRECISION)) + hv = HashString(hv, num2strHighPrec(amp, precision = MAX_DOUBLE_PRECISION)) + hv = HashString(hv, num2strHighPrec(numPoints, precision = MAX_DOUBLE_PRECISION)) + hv = HashString(hv, num2strHighPrec(dt, precision = MAX_DOUBLE_PRECISION)) + hv = HashWave(hv, range) - return num2istr(crc) + "PSX Kernel Version 2" + return hv + "PSX Kernel Version 2" End static Function/S CA_PSXBaseKey(string comboKey, string psxParameters) @@ -513,7 +516,6 @@ End threadsafe Function/S CA_GetLabnotebookNamesKey(WAVE/Z/T textualValues, WAVE/Z/T numericalValues) string key = "" - variable crc if(WaveExists(textualValues)) key += GetWavesDataFolder(textualValues, 2) @@ -525,43 +527,39 @@ threadsafe Function/S CA_GetLabnotebookNamesKey(WAVE/Z/T textualValues, WAVE/Z/T key += num2istr(WaveModCountWrapper(numericalValues)) endif - ASSERT_TS(!IsEmpty(key), "key can't be empty") - - return "Version 1:" + Hash(key, HASH_SHA2_256) + return HashString("", key) + ":Version 1" End Function/S CA_CalculateEpochsKey(WAVE numericalvalues, WAVE textualValues, variable sweepNo, variable channelType, variable channelNumber, string shortName, variable treelevel, DFREF sweepDFR) - string key = "" - variable crc + string hv - key += CA_GetLabnotebookNamesKey(numericalvalues, textualValues) - crc = StringCRC(crc, num2str(sweepNo)) - crc = StringCRC(crc, num2str(channelType)) - crc = StringCRC(crc, num2str(channelNumber)) - crc = StringCRC(crc, shortName) - crc = StringCRC(crc, num2str(treelevel)) + hv = CA_GetLabnotebookNamesKey(numericalvalues, textualValues) + hv = HashNumber(hv, sweepNo) + hv = HashNumber(hv, channelType) + hv = HashNumber(hv, channelNumber) + hv = HashString(hv, shortName) + hv = HashNumber(hv, treelevel) if(DataFolderExistsDFR(sweepDFR)) - crc = StringCRC(crc, GetDataFolder(1, sweepDFR)) + hv = HashString(hv, GetDataFolder(1, sweepDFR)) else - crc = StringCRC(crc, "invalid DFREF") + hv = HashString(hv, "invalid DFREF") endif - return "Version 1:" + Hash(key + num2istr(crc), HASH_SHA2_256) + return hv + ":Version 1" End threadsafe Function/S CA_CalculateFetchEpochsKey(WAVE numericalvalues, WAVE textualValues, variable sweepNo, variable channelNumber, variable channelType) - string key = "" - variable crc + string hv = "" - key += CA_GetLabnotebookNamesKey(numericalvalues, textualValues) - crc = StringCRC(crc, num2str(sweepNo)) - crc = StringCRC(crc, num2str(channelType)) - crc = StringCRC(crc, num2str(channelNumber)) + hv = HashString(hv, CA_GetLabnotebookNamesKey(numericalvalues, textualValues)) + hv = HashNumber(hv, sweepNo) + hv = HashNumber(hv, channelType) + hv = HashNumber(hv, channelNumber) - return "Version 1:" + Hash(key + num2istr(crc), HASH_SHA2_256) + return hv + ":Version 1" End ///@} diff --git a/Packages/MIES/MIES_Constants.ipf b/Packages/MIES/MIES_Constants.ipf index 6e57ac4e4a..d0c108b2e3 100644 --- a/Packages/MIES/MIES_Constants.ipf +++ b/Packages/MIES/MIES_Constants.ipf @@ -25,7 +25,7 @@ Constant ANALYSISBROWSER_PANEL_VERSION = 11 Constant PSX_PLOT_PANEL_VERSION = 1 /// Version of the stimset wave note -Constant STIMSET_NOTE_VERSION = 12 +Constant STIMSET_NOTE_VERSION = 13 /// Version of the epoch information for DA+TTL data Constant SWEEP_EPOCH_VERSION = 9 @@ -39,7 +39,7 @@ Constant SWEEP_EPOCH_VERSION = 9 /// - New/Changed layers of entries /// ///@{ -Constant LABNOTEBOOK_VERSION = 81 +Constant LABNOTEBOOK_VERSION = 82 Constant RESULTS_VERSION = 3 ///@} @@ -2318,6 +2318,7 @@ Constant SUBWINDOW_MOVE_CORRECTION = 5 /// @anchor HashMethods ///@{ Constant HASH_SHA2_256 = 1 +Constant HASH_XXH3_64 = 102 ///@} // see DisplayHelpTopic "LoadWave" diff --git a/Packages/MIES/MIES_DAEphys.ipf b/Packages/MIES/MIES_DAEphys.ipf index a6d4697cf7..12d9d5b129 100644 --- a/Packages/MIES/MIES_DAEphys.ipf +++ b/Packages/MIES/MIES_DAEphys.ipf @@ -1220,8 +1220,11 @@ Function DAP_OneTimeCallBeforeDAQ(string device, variable runMode) NVAR fifoPosition = $GetFifoPosition(device) fifoPosition = NaN - WAVE stimsetAcqIDHelper = GetStimsetAcqIDHelperWave(device) - stimsetAcqIDHelper = NaN + WAVE stimsetAcqIDNumericalHelper = GetStimsetAcqIDNumericalHelperWave(device) + stimsetAcqIDNumericalHelper = NaN + + WAVE/T stimsetAcqIDTextualHelper = GetStimsetAcqIDTextualHelperWave(device) + stimsetAcqIDTextualHelper = "" DAP_ClearDelayedClampModeChange(device) diff --git a/Packages/MIES/MIES_DataConfigurator.ipf b/Packages/MIES/MIES_DataConfigurator.ipf index 0b489b5291..82a01d3dc5 100644 --- a/Packages/MIES/MIES_DataConfigurator.ipf +++ b/Packages/MIES/MIES_DataConfigurator.ipf @@ -1105,8 +1105,8 @@ End static Function DC_PrepareLBNEntries(string device, STRUCT DataConfigurationResult &s) - variable i, j, maxITI, channel, headstage, setChecksum, fingerprint, stimsetCycleID, isoodDAQMember, samplingInterval - string func, ctrl, str + variable i, j, maxITI, channel, headstage, stimsetCycleID, isoodDAQMember, samplingInterval + string func, ctrl, str, fingerprint, setChecksum WAVE config = GetDAQConfigWave(device) @@ -1179,7 +1179,7 @@ static Function DC_PrepareLBNEntries(string device, STRUCT DataConfigurationResu DC_DocumentChannelProperty(device, "Set Cycle Count", headstage, channel, XOP_CHANNEL_TYPE_DAC, var = s.setCycleCount[i]) setChecksum = WB_GetStimsetChecksum(s.stimSet[i], s.setName[i], s.dataAcqOrTP) - DC_DocumentChannelProperty(device, "Stim Wave Checksum", headstage, channel, XOP_CHANNEL_TYPE_DAC, var = setChecksum) + DC_DocumentChannelProperty(device, "Stim Wave Checksum V2", headstage, channel, XOP_CHANNEL_TYPE_DAC, str = setChecksum) if(s.dataAcqOrTP == DATA_ACQUISITION_MODE && config[i][%DAQChannelType] == DAQ_CHANNEL_TYPE_DAQ) fingerprint = DC_GenerateStimsetFingerprint(raCycleID, s.setName[i], s.setCycleCount[i], setChecksum) @@ -1865,20 +1865,21 @@ End /// @param device device /// @param fingerprint fingerprint as returned by DC_GenerateStimsetFingerprint() /// @param DAC DA channel -static Function DC_GetStimsetAcqCycleID(string device, variable fingerprint, variable DAC) +static Function DC_GetStimsetAcqCycleID(string device, string fingerprint, variable DAC) - WAVE stimsetAcqIDHelper = GetStimsetAcqIDHelperWave(device) + WAVE stimsetAcqIDNumericalHelper = GetStimsetAcqIDNumericalHelperWave(device) + WAVE/T stimsetAcqIDTextualHelper = GetStimsetAcqIDTextualHelperWave(device) - ASSERT(IsFinite(fingerprint), "Invalid fingerprint") + ASSERT(IsEmpty(fingerprint), "Invalid fingerprint") - if(fingerprint == stimsetAcqIDHelper[DAC][%fingerprint]) - return stimsetAcqIDHelper[DAC][%id] + if(!cmpstr(fingerprint, stimsetAcqIDTextualHelper[DAC][%fingerprint])) + return stimsetAcqIDNumericalHelper[DAC][%id] endif - stimsetAcqIDHelper[DAC][%fingerprint] = fingerprint - stimsetAcqIDHelper[DAC][%id] = GetNextRandomNumberForDevice(device) + stimsetAcqIDTextualHelper[DAC][%fingerprint] = fingerprint + stimsetAcqIDNumericalHelper[DAC][%id] = GetNextRandomNumberForDevice(device) - return stimsetAcqIDHelper[DAC][%id] + return stimsetAcqIDNumericalHelper[DAC][%id] End /// @brief Generate the stimset fingerprint @@ -1891,21 +1892,21 @@ End /// /// Always then this fingerprint changes, a new stimset acquisition cycle ID has /// to be generated. -static Function DC_GenerateStimsetFingerprint(variable raCycleID, string setName, variable setCycleCount, variable setChecksum) +static Function/S DC_GenerateStimsetFingerprint(variable raCycleID, string setName, variable setCycleCount, string setChecksum) - variable crc + string hv = "" ASSERT(IsInteger(raCycleID) && raCycleID > 0, "Invalid raCycleID") ASSERT(IsInteger(setCycleCount), "Invalid setCycleCount") - ASSERT(IsInteger(setChecksum) && setChecksum > 0, "Invalid stimset checksum") + ASSERT(!IsEmpty(setChecksum), "Invalid stimset checksum") ASSERT(!IsEmpty(setName) && !cmpstr(setName, trimstring(setName)), "Invalid setName") - crc = StringCRC(crc, num2str(raCycleID)) - crc = StringCRC(crc, num2str(setCycleCount)) - crc = StringCRC(crc, num2str(setChecksum)) - crc = StringCRC(crc, setName) + hv = HashNumber(hv, raCycleID) + hv = HashNumber(hv, setCycleCount) + hv = HashString(hv, setChecksum) + hv = HashString(hv, setName) - return crc + return hv End static Function [variable result, variable row, variable column] DC_CheckIfDataWaveHasBorderVals(string device, variable dataAcqOrTP) @@ -2103,13 +2104,13 @@ static Function DC_ITC_MakeTTLWave(string device, STRUCT DataConfigurationResult setLength[i] = num2istr(s.TTLsetLength[i]) indexingEndStimSet[i] = allSetNamesIndexingEnd[i] waveNote[i] = URLEncode(note(s.TTLstimSet[i])) - checksum[i] = num2istr(WB_GetStimsetChecksum(s.TTLstimSet[i], s.TTLsetName[i], DATA_ACQUISITION_MODE)) + checksum[i] = WB_GetStimsetChecksum(s.TTLstimSet[i], s.TTLsetName[i], DATA_ACQUISITION_MODE) endfor DC_DocumentChannelProperty(device, "Stim set length", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(setLength, ";")) DC_DocumentChannelProperty(device, "Indexing End stimset", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(indexingEndStimSet, ";")) DC_DocumentChannelProperty(device, "Stimset wave note", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(waveNote, ";")) - DC_DocumentChannelProperty(device, "Stim Wave Checksum", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(checksum, ";")) + DC_DocumentChannelProperty(device, "Stim Wave Checksum V2", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(checksum, ";")) ASSERT(maxRows > 0, "Expected stim set of non-zero size") WAVE TTLWave = GetTTLWave(device) @@ -2155,7 +2156,7 @@ static Function DC_NI_MakeTTLWave(string device, STRUCT DataConfigurationResult channels[i] = num2istr(i) indexingEndStimSet[i] = allSetNamesIndexingEnd[i] waveNote[i] = note(s.TTLstimSet[i]) - checksum[i] = num2istr(WB_GetStimsetChecksum(s.TTLstimSet[i], s.TTLsetName[i], DATA_ACQUISITION_MODE)) + checksum[i] = WB_GetStimsetChecksum(s.TTLstimSet[i], s.TTLsetName[i], DATA_ACQUISITION_MODE) WAVE TTLStimSet = s.TTLstimSet[i] Make/FREE/B/U/N=(DimSize(TTLStimSet, ROWS)) TTLWaveSingle @@ -2171,7 +2172,7 @@ static Function DC_NI_MakeTTLWave(string device, STRUCT DataConfigurationResult DC_DocumentChannelProperty(device, "set cycle counts", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(cycleCount, ";")) DC_DocumentChannelProperty(device, "Indexing End stimset", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(indexingEndStimSet, ";")) DC_DocumentChannelProperty(device, "Stimset wave note", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(waveNote, ";")) - DC_DocumentChannelProperty(device, "Stim Wave Checksum", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(checksum, ";")) + DC_DocumentChannelProperty(device, "Stim Wave Checksum V2", INDEP_HEADSTAGE, NaN, XOP_CHANNEL_TYPE_TTL, str = TextWaveToList(checksum, ";")) End /// @brief Returns column number/step of the stimulus set, independent of the times the set is being cycled through diff --git a/Packages/MIES/MIES_Epochs.ipf b/Packages/MIES/MIES_Epochs.ipf index f319d954e2..48923f4e23 100644 --- a/Packages/MIES/MIES_Epochs.ipf +++ b/Packages/MIES/MIES_Epochs.ipf @@ -1115,7 +1115,7 @@ Function EP_SortEpochs(WAVE/T epochWave) epochSortColStartTime[] = str2numSafe(epochChannel[p][EPOCH_COL_STARTTIME]) epochSortColEndTime[] = -1 * str2numSafe(epochChannel[p][EPOCH_COL_ENDTIME]) epochSortColTreeLevel[] = str2numSafe(epochChannel[p][EPOCH_COL_TREELEVEL]) - epochSortTagCRC[] = StringCRC(0, epochChannel[p][EPOCH_COL_TAGS]) + epochSortTagCRC[] = StringCRC(0, epochChannel[p][EPOCH_COL_TAGS]) // NOLINT SortColumns/DIML keyWaves={epochSortColStartTime, epochSortColEndTime, epochSortColTreeLevel, epochSortTagCRC}, sortWaves={epochChannel} // remove epochs marked for removal diff --git a/Packages/MIES/MIES_MiesUtilities_Algorithm.ipf b/Packages/MIES/MIES_MiesUtilities_Algorithm.ipf index 8ad2263139..38a1b2dacc 100644 --- a/Packages/MIES/MIES_MiesUtilities_Algorithm.ipf +++ b/Packages/MIES/MIES_MiesUtilities_Algorithm.ipf @@ -68,7 +68,7 @@ Function/WAVE CalculateAverage(WAVE/WAVE waveRefs, DFREF averageDataFolder, stri SetScale d, 0, 0, dataUnit, freeAverageWave if(!skipCRC) - crc = WaveCRC(0, freeAverageWave) + crc = WaveCRC(0, freeAverageWave) // NOLINT wvName += "_" + num2istr(crc) SetNumberInWaveNote(freeAverageWave, "DataCRC", crc) endif diff --git a/Packages/MIES/MIES_Utilities_Algorithm.ipf b/Packages/MIES/MIES_Utilities_Algorithm.ipf index 9f9c49379f..06c4d6c3de 100644 --- a/Packages/MIES/MIES_Utilities_Algorithm.ipf +++ b/Packages/MIES/MIES_Utilities_Algorithm.ipf @@ -1275,3 +1275,65 @@ Function FindSequenceReverseWrapper(WAVE sequence, WAVE source) start = foundIndex + 1 endfor End + +/// @brief Return a hash of `str` taking `previousHash` into account +/// +/// Uses `XXH3-64` on IP10 and CRC on IP9. Can not be used for security purposes. +threadsafe Function/S HashString(string previousHash, string str) + + variable crc + +#if IgorVersion() >= 10 + return Hash(previousHash + str, HASH_XXH3_64) +#endif + + if(IsEmpty(previousHash)) + crc = 0 + else + crc = str2num(previousHash) + endif + +#ifdef AUTOMATED_TESTING + ASSERT_TS(IsFinite(crc), "Expected previousHash to be a number:" + previousHash) +#endif // AUTOMATED_TESTING + + return num2istr(StringCRC(crc, str)) // NOLINT +End + +/// @brief Return a hash of `wv` taking `previousHash` into account +/// +/// Uses `XXH3-64` on IP10 and CRC on IP9. Can not be used for security purposes. +threadsafe Function/S HashWave(string previousHash, WAVE/Z wv) + + variable crc + + ASSERT_TS(WaveExists(wv), "Missing wv") + +#if IgorVersion() >= 10 + return previousHash + WaveHash(wv, HASH_XXH3_64) +#endif + + if(IsEmpty(previousHash)) + crc = 0 + else + crc = str2num(previousHash) + endif + +#ifdef AUTOMATED_TESTING + ASSERT_TS(IsFinite(crc), "Expected previousHash to be a number:" + previousHash) +#endif // AUTOMATED_TESTING + + return num2istr(WaveCRC(crc, wv)) // NOLINT +End + +/// @brief Return a hash of `num` taking `previousHash` into account +/// +/// The conversion to string is done with full double precision. +/// +/// Uses `XXH3-64` on IP10 and CRC on IP9. Can not be used for security purposes. +threadsafe Function/S HashNumber(string previousHash, variable num) + + string str = num2strHighPrec(num, precision = MAX_DOUBLE_PRECISION, shorten = 1) + + return HashString(previousHash, str) +End diff --git a/Packages/MIES/MIES_Utilities_GUI.ipf b/Packages/MIES/MIES_Utilities_GUI.ipf index 9989b0f523..61be68082a 100644 --- a/Packages/MIES/MIES_Utilities_GUI.ipf +++ b/Packages/MIES/MIES_Utilities_GUI.ipf @@ -321,19 +321,20 @@ Function StoreCurrentPanelsResizeInfo(string panel) ResizeControlsPanel#SaveControlPositions(panel, 0) End -/// @brief Return the CRC of the contents of the plain/formatted notebook +/// @brief Return the hash of the contents of the plain/formatted notebook /// /// Takes into account formatting but ignores selection. -Function GetNotebookCRC(string win) +Function/S GetNotebookHash(string win) string content + string hv = "" content = WinRecreation(win, 1) // Filter out // lines which contain the selection content = GrepList(content, "//.*", 1, "\r") - return StringCRC(0, content) + return HashString(hv, content) End ///@brief Format the 2D text wave into a string usable for a legend diff --git a/Packages/MIES/MIES_WaveBuilder.ipf b/Packages/MIES/MIES_WaveBuilder.ipf index 169cb46ab9..05da7e88d6 100644 --- a/Packages/MIES/MIES_WaveBuilder.ipf +++ b/Packages/MIES/MIES_WaveBuilder.ipf @@ -305,18 +305,18 @@ End /// @brief Return a checksum of the stimsets and its parameter waves. /// /// Uses the entry from the stimset wave note if available. -Function WB_GetStimsetChecksum(WAVE stimset, string setName, variable dataAcqOrTP) +Function/S WB_GetStimsetChecksum(WAVE stimset, string setName, variable dataAcqOrTP) - variable crc + string hv if(dataAcqOrTP == TEST_PULSE_MODE) - return NaN + return "" endif - crc = NumberByKey("Checksum", note(stimset), " = ", ";") + hv = WB_GetWaveNoteEntry(note(stimset), STIMSET_ENTRY, key = "ChecksumV2") - if(IsFinite(crc)) - return crc + if(!IsEmpty(hv)) + return hv endif // old stimsets without the wave note entry @@ -324,23 +324,23 @@ Function WB_GetStimsetChecksum(WAVE stimset, string setName, variable dataAcqOrT End /// @brief Calculcate the checksum of the stimsets and its parameter waves. -static Function WB_CalculateStimsetChecksum(WAVE stimset, string setName) +static Function/S WB_CalculateStimsetChecksum(WAVE stimset, string setName) - variable crc + string hv = "" - crc = WaveCRC(crc, stimset) + hv = HashWave(hv, stimset) WAVE/Z WP = WB_GetWaveParamForSet(setName) WAVE/Z/T WPT = WB_GetWaveTextParamForSet(setName) WAVE/Z SegWvType = WB_GetSegWvTypeForSet(setName) if(WaveExists(WP) && WaveExists(WPT) && WaveExists(SegWvType)) - crc = WaveCRC(crc, WP) - crc = WaveCRC(crc, WPT) - crc = WaveCRC(crc, SegWvType) + hv = HashWave(hv, WP) + hv = HashWave(hv, WPT) + hv = HashWave(hv, SegWvType) endif - return crc + return hv End /// @brief Get modification date of saved stimset wave @@ -488,7 +488,7 @@ static Function/WAVE WB_GetStimSet([string setName]) AddEntryIntoWaveNoteAsList(stimset, STIMSET_SIZE_KEY, var = DimSize(stimset, ROWS), format = "%d") if(!isEmpty(setName)) - AddEntryIntoWaveNoteAsList(stimset, "Checksum", var = WB_CalculateStimsetChecksum(stimset, setName), format = "%d") + AddEntryIntoWaveNoteAsList(stimset, "Checksum V2", str = WB_CalculateStimsetChecksum(stimset, setName), format = "%d") AddEntryIntoWaveNoteAsList(stimset, "WP modification count", var = WaveModCountWrapper(WP), format = "%d") AddEntryIntoWaveNoteAsList(stimset, "WPT modification count", var = WaveModCountWrapper(WPT), format = "%d") AddEntryIntoWaveNoteAsList(stimset, "SegWvType modification count", var = WaveModCountWrapper(SegWvType), format = "%d", appendCR = 1) @@ -1605,6 +1605,9 @@ End /// - length of each segment /// - inflection point positions (left side index) /// +/// Version 11: +/// - Switched stimset checksum from CRC to XX3-64 hash (IP10 only) and renamed it from Checksum to "Checksum V2" +/// /// Example: /// /// .. code-block:: none @@ -1621,7 +1624,7 @@ End /// Sweep = 1;Epoch = 1;Type = Ramp;Duration = 150;Amplitude = 1;Offset = 0; /// Sweep = 1;Epoch = 2;Type = Square pulse;Duration = 300;Amplitude = 0; /// Sweep = 1;Epoch = 3;Type = Pulse Train;Duration = 960.005;Amplitude = 1;Offset = 0;Pulse Type = Square;Frequency = 20;Pulse To Pulse Length = 50;Pulse duration = 10;Number of pulses = 20;Mixed frequency = False;First mixed frequency = 0;Last mixed frequency = 0;Poisson distribution = False;Random seed = 0.963638;Pulse Train Pulses = 0,50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,;Definition mode = Duration; -/// Stimset;Sweep Count = 2;Epoch Count = 4;Pre DAQ = ;Mid Sweep = ;Post Sweep = ;Post Set = ;Post DAQ = ;Pre Sweep = ;Generic = PSQ_Ramp;Pre Set = ;Function params (encoded)= NumberOfSpikes:variable=5,Elements:string=%20%3B%2C;Flip = 0;Random Seed = 0.963638;Wavebuilder Error = 0;Checksum = 65446509; +/// Stimset;Sweep Count = 2;Epoch Count = 4;Pre DAQ = ;Mid Sweep = ;Post Sweep = ;Post Set = ;Post DAQ = ;Pre Sweep = ;Generic = PSQ_Ramp;Pre Set = ;Function params (encoded)= NumberOfSpikes:variable=5,Elements:string=%20%3B%2C;Flip = 0;Random Seed = 0.963638;Wavebuilder Error = 0;Checksum V2 = 6497a96f53a89890; /// \endrst /// /// @param text stimulus set wave note diff --git a/Packages/MIES/MIES_WaveDataFolderGetters.ipf b/Packages/MIES/MIES_WaveDataFolderGetters.ipf index 3ae72cf33d..c4f080d456 100644 --- a/Packages/MIES/MIES_WaveDataFolderGetters.ipf +++ b/Packages/MIES/MIES_WaveDataFolderGetters.ipf @@ -32,7 +32,7 @@ static StrConstant TP_SETTINGS_LABELS = "bufferSize;resistanceTol;sendToAllHS;ba static StrConstant LOGBOOK_SUFFIX_SORTEDKEYS = "_sorted" static StrConstant LOGBOOK_SUFFIX_SORTEDKEYSINDICES = "_indices" -static Constant SWEEP_SETTINGS_WAVE_VERSION = 41 +static Constant SWEEP_SETTINGS_WAVE_VERSION = 42 /// @brief Return a wave reference to the corresponding Logbook keys wave from an values wave input threadsafe Function/WAVE GetLogbookValuesFromKeys(WAVE keyWave) @@ -1251,7 +1251,33 @@ Function/WAVE GetTTLWave(string device) endswitch End -/// @brief Return the stimset acquistion cycle ID helper wave +/// @brief Return the stimset acquisition cycle ID helper wave (numerical) +/// +/// Only valid during DAQ. +/// +/// Rows: +/// - NUM_DA_TTL_CHANNELS +/// +/// Columns: +/// - 0: Current stimset acquisition cycle ID +Function/WAVE GetStimsetAcqIDNumericalHelperWave(string device) + + DFREF dfr = GetDevicePath(device) + + WAVE/Z/D/SDFR=dfr wv = stimsetAcqIDNumericalHelper + + if(WaveExists(wv)) + return wv + endif + + Make/D/N=(NUM_DA_TTL_CHANNELS, 1) dfr:stimsetAcqIDNumericalHelper/WAVE=wv + + SetDimLabel COLS, 0, id, wv + + return wv +End + +/// @brief Return the stimset acquisition cycle ID helper wave (textual) /// /// Only valid during DAQ. /// @@ -1260,21 +1286,19 @@ End /// /// Columns: /// - 0: Stimset fingerprint of the previous sweep -/// - 1: Current stimset acquisition cycle ID -Function/WAVE GetStimsetAcqIDHelperWave(string device) +Function/WAVE GetStimsetAcqIDTextualHelperWave(string device) DFREF dfr = GetDevicePath(device) - WAVE/Z/D/SDFR=dfr wv = stimsetAcqIDHelper + WAVE/Z/T/SDFR=dfr wv = stimsetAcqIDHelper if(WaveExists(wv)) return wv endif - Make/D/N=(NUM_DA_TTL_CHANNELS, 2) dfr:stimsetAcqIDHelper/WAVE=wv + Make/T/N=(NUM_DA_TTL_CHANNELS, 1) dfr:stimsetAcqIDTextualHelper/WAVE=wv SetDimLabel COLS, 0, fingerprint, wv - SetDimLabel COLS, 1, id, wv return wv End @@ -2487,9 +2511,6 @@ End /// - 31: Optimized Overlap dDAQ /// - 32: Delay onset oodDAQ /// - 33: Repeated Acquisition Cycle ID -/// - 34: Stim Wave Checksum (can be used to disambiguate cases -/// where two stimsets are named the same -/// but have different contents) /// - 35: Multi Device mode /// - 36: Background Testpulse /// - 37: Background DAQ @@ -2536,9 +2557,9 @@ Function/WAVE GetSweepSettingsKeyWave(string device) endif if(WaveExists(wv)) - Redimension/N=(-1, 63) wv + Redimension/N=(-1, 61) wv else - Make/T/N=(3, 62) newDFR:$newName/WAVE=wv + Make/T/N=(3, 61) newDFR:$newName/WAVE=wv endif wv = "" @@ -2683,117 +2704,113 @@ Function/WAVE GetSweepSettingsKeyWave(string device) wv[%Units][33] = "" wv[%Tolerance][33] = "1" - wv[%Parameter][34] = "Stim Wave Checksum" - wv[%Units][34] = "" - wv[%Tolerance][34] = "1" + wv[%Parameter][34] = "Multi Device mode" + wv[%Units][34] = LABNOTEBOOK_BINARY_UNIT + wv[%Tolerance][34] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][35] = "Multi Device mode" + wv[%Parameter][35] = "Background Testpulse" wv[%Units][35] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][35] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][36] = "Background Testpulse" + wv[%Parameter][36] = "Background DAQ" wv[%Units][36] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][36] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][37] = "Background DAQ" + wv[%Parameter][37] = "TP during ITI" wv[%Units][37] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][37] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][38] = "TP during ITI" + wv[%Parameter][38] = "Amplifier change via I=0" wv[%Units][38] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][38] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][39] = "Amplifier change via I=0" + wv[%Parameter][39] = "Skip analysis functions" wv[%Units][39] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][39] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][40] = "Skip analysis functions" + wv[%Parameter][40] = "Repeat sweep on async alarm" wv[%Units][40] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][40] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][41] = "Repeat sweep on async alarm" - wv[%Units][41] = LABNOTEBOOK_BINARY_UNIT - wv[%Tolerance][41] = LABNOTEBOOK_NO_TOLERANCE + wv[%Parameter][41] = "Set Cycle Count" + wv[%Units][41] = "" + wv[%Tolerance][41] = "1" - wv[%Parameter][42] = "Set Cycle Count" + wv[%Parameter][42] = STIMSET_ACQ_CYCLE_ID_KEY wv[%Units][42] = "" wv[%Tolerance][42] = "1" - wv[%Parameter][43] = STIMSET_ACQ_CYCLE_ID_KEY + wv[%Parameter][43] = "Digitizer Hardware Type" wv[%Units][43] = "" wv[%Tolerance][43] = "1" - wv[%Parameter][44] = "Digitizer Hardware Type" - wv[%Units][44] = "" + wv[%Parameter][44] = "Fixed frequency acquisition" + wv[%Units][44] = "kHz" wv[%Tolerance][44] = "1" - wv[%Parameter][45] = "Fixed frequency acquisition" - wv[%Units][45] = "kHz" - wv[%Tolerance][45] = "1" + wv[%Parameter][45] = "Headstage Active" + wv[%Units][45] = LABNOTEBOOK_BINARY_UNIT + wv[%Tolerance][45] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][46] = "Headstage Active" - wv[%Units][46] = LABNOTEBOOK_BINARY_UNIT + wv[%Parameter][46] = CLAMPMODE_ENTRY_KEY + wv[%Units][46] = "" wv[%Tolerance][46] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][47] = CLAMPMODE_ENTRY_KEY + wv[%Parameter][47] = "Igor Pro bitness" wv[%Units][47] = "" wv[%Tolerance][47] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][48] = "Igor Pro bitness" + wv[%Parameter][48] = "DA ChannelType" wv[%Units][48] = "" - wv[%Tolerance][48] = LABNOTEBOOK_NO_TOLERANCE + wv[%Tolerance][48] = "1" - wv[%Parameter][49] = "DA ChannelType" + wv[%Parameter][49] = "AD ChannelType" wv[%Units][49] = "" wv[%Tolerance][49] = "1" - wv[%Parameter][50] = "AD ChannelType" - wv[%Units][50] = "" - wv[%Tolerance][50] = "1" + wv[%Parameter][50] = "oodDAQ member" + wv[%Units][50] = LABNOTEBOOK_BINARY_UNIT + wv[%Tolerance][50] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][51] = "oodDAQ member" - wv[%Units][51] = LABNOTEBOOK_BINARY_UNIT - wv[%Tolerance][51] = LABNOTEBOOK_NO_TOLERANCE + wv[%Parameter][51] = AUTOBIAS_PERC_KEY + wv[%Units][51] = "" + wv[%Tolerance][51] = "0.1" - wv[%Parameter][52] = AUTOBIAS_PERC_KEY - wv[%Units][52] = "" + wv[%Parameter][52] = "Autobias Interval" + wv[%Units][52] = "s" wv[%Tolerance][52] = "0.1" - wv[%Parameter][53] = "Autobias Interval" - wv[%Units][53] = "s" - wv[%Tolerance][53] = "0.1" + wv[%Parameter][53] = "TP after DAQ" + wv[%Units][53] = LABNOTEBOOK_BINARY_UNIT + wv[%Tolerance][53] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][54] = "TP after DAQ" - wv[%Units][54] = LABNOTEBOOK_BINARY_UNIT - wv[%Tolerance][54] = LABNOTEBOOK_NO_TOLERANCE + wv[%Parameter][54] = SWEEP_EPOCH_VERSION_ENTRY_KEY + wv[%Units][54] = "" + wv[%Tolerance][54] = "1" - wv[%Parameter][55] = SWEEP_EPOCH_VERSION_ENTRY_KEY - wv[%Units][55] = "" - wv[%Tolerance][55] = "1" + wv[%Parameter][55] = "Get/Set Inter-trial interval" + wv[%Units][55] = LABNOTEBOOK_BINARY_UNIT + wv[%Tolerance][55] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][56] = "Get/Set Inter-trial interval" + wv[%Parameter][56] = "Double precision data" wv[%Units][56] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][56] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][57] = "Double precision data" + wv[%Parameter][57] = "Save amplifier settings" wv[%Units][57] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][57] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][58] = "Save amplifier settings" + wv[%Parameter][58] = "Require amplifier" wv[%Units][58] = LABNOTEBOOK_BINARY_UNIT wv[%Tolerance][58] = LABNOTEBOOK_NO_TOLERANCE - wv[%Parameter][59] = "Require amplifier" - wv[%Units][59] = LABNOTEBOOK_BINARY_UNIT - wv[%Tolerance][59] = LABNOTEBOOK_NO_TOLERANCE - - wv[%Parameter][60] = "Skip Ahead" - wv[%Units][60] = "" - wv[%Tolerance][60] = "1" + wv[%Parameter][59] = "Skip Ahead" + wv[%Units][59] = "" + wv[%Tolerance][59] = "1" - wv[%Parameter][61] = "TP power spectrum" - wv[%Units][61] = LABNOTEBOOK_BINARY_UNIT - wv[%Tolerance][61] = LABNOTEBOOK_NO_TOLERANCE + wv[%Parameter][60] = "TP power spectrum" + wv[%Units][60] = LABNOTEBOOK_BINARY_UNIT + wv[%Tolerance][60] = LABNOTEBOOK_NO_TOLERANCE SetSweepSettingsDimLabels(wv, wv) SetWaveVersion(wv, versionOfNewWave) @@ -2897,13 +2914,16 @@ End /// - 33: Indexing End Stimset /// - 34: TTL Indexing End Stimset (hardware agnostic), string list in `INDEP_HEADSTAGE` layer with empty entries indexed by [0, NUM_DA_TTL_CHANNELS[ /// - 35: TTL Stimset wave note (hardware agnostic), same string list formatting -/// - 36: TTL Stim Wave Checksum (hardware agnostic) URL-encoded payload, see [URL-encoding](https://en.wikipedia.org/wiki/Percent-encoding) +/// - 36: TTL Stim Wave Checksum V2 (hardware agnostic) URL-encoded payload, see [URL-encoding](https://en.wikipedia.org/wiki/Percent-encoding) /// for background information, same string list formatting /// - 37: TTL Stim set length (hardware agnostic), same string list formatting /// - 38: TTL rack zero set cycle counts (ITC hardware) /// - 39: TTL rack one set cycle counts (ITC hardware) /// - 40: TTL set cycle counts (NI hardware), string list in `INDEP_HEADSTAGE` layer with empty entries indexed by [0, NUM_DA_TTL_CHANNELS[ /// - 41: Device (aka DAEphys panel name) +/// - 50: Stim Wave Checksum V2 (DA data, can be used to disambiguate cases +/// where two stimsets are named the same +/// but have different contents) Function/WAVE GetSweepSettingsTextKeyWave(string device) variable versionOfNewWave = SWEEP_SETTINGS_WAVE_VERSION @@ -2923,9 +2943,9 @@ Function/WAVE GetSweepSettingsTextKeyWave(string device) endif if(WaveExists(wv)) - Redimension/N=(-1, 50, 0) wv + Redimension/N=(-1, 51, 0) wv else - Make/T/N=(1, 50) newDFR:$newName/WAVE=wv + Make/T/N=(1, 51) newDFR:$newName/WAVE=wv endif SetDimLabel ROWS, 0, Parameter, wv @@ -2968,7 +2988,7 @@ Function/WAVE GetSweepSettingsTextKeyWave(string device) wv[0][33] = "Indexing End Stimset" wv[0][34] = "TTL Indexing End Stimset" wv[0][35] = "TTL Stimset wave note" - wv[0][36] = "TTL Stim Wave Checksum" + wv[0][36] = "TTL Stim Wave Checksum V2" wv[0][37] = "TTL Stim set length" wv[0][38] = "TTL rack zero set cycle counts" wv[0][39] = "TTL rack one set cycle counts" @@ -2982,6 +3002,7 @@ Function/WAVE GetSweepSettingsTextKeyWave(string device) wv[0][47] = CreateTTLChannelLBNKey(EPOCHS_ENTRY_KEY, 5) wv[0][48] = CreateTTLChannelLBNKey(EPOCHS_ENTRY_KEY, 6) wv[0][49] = CreateTTLChannelLBNKey(EPOCHS_ENTRY_KEY, 7) + wv[0][50] = "Stim Wave Checksum V2" SetSweepSettingsDimLabels(wv, wv) SetWaveVersion(wv, versionOfNewWave) diff --git a/Packages/MIES/labnotebook_numerical_description.itx b/Packages/MIES/labnotebook_numerical_description.itx index ce017fdca3..0667e4d21a 100644 --- a/Packages/MIES/labnotebook_numerical_description.itx +++ b/Packages/MIES/labnotebook_numerical_description.itx @@ -1,5 +1,5 @@ IGOR -WAVES/T/N=(196,6) labnotebook_numerical_description +WAVES/T/N=(195,6) labnotebook_numerical_description BEGIN "Name" "Unit" "Tolerance" "Description" "Headstage Contingency" "ClampMode" "SweepNum" "" "-" "Sweep number: Non-repeating non-negative numeric identifier for sweep time series. Increments in the order of acquisition. Starts at zero." "ALL" "" @@ -57,7 +57,6 @@ BEGIN "Delay onset oodDAQ" "ms" "1" "Calculated total oodDAQ offset used for acquisition.\r\rSee https://alleninstitute.github.io/MIES/#id4 for a visualization of oodDAQ." "DEPEND" "" "Pulse To Pulse Length" "ms" "1" "Not used in newer MIES versions." "ALL" "" "Repeated Acq Cycle ID" "" "1" "The \"Repeated Acq Cycle ID\" labels each repeated acquisition with a unique integer number.\rSweeps belonging to the same repeated acquisition cycle have the same ID.\rFor yoked devices the follower and lead devices will have the same ID,\rwhich also helps in that case to group sweeps together." "INDEP" "" - "Stim Wave Checksum" "" "1" "The \"Stim Wave Checksum\" is a unique identifier for the stimulus set contents.\r\rChanges in this ID catches cases where the stimset has the same name but different contents." "DEPEND" "" "Multi Device mode" "On/Off" "-" "Support for multiple DAQ devices acquiring data simultaneously. When turned off, legacy single device mode is used." "INDEP" "" "Background Testpulse" "On/Off" "-" "When enabled, a running testpulse does not block the Igor Pro user interface." "INDEP" "" "Background DAQ" "On/Off" "-" "When enabled, data acquisition does not block the Igor Pro user interface." "INDEP" "" diff --git a/Packages/MIES/labnotebook_textual_description.itx b/Packages/MIES/labnotebook_textual_description.itx index 2f5b5eb0e2..74190a053e 100644 --- a/Packages/MIES/labnotebook_textual_description.itx +++ b/Packages/MIES/labnotebook_textual_description.itx @@ -1,5 +1,5 @@ IGOR -WAVES/T/N=(78,6) labnotebook_textual_description +WAVES/T/N=(79,6) labnotebook_textual_description BEGIN "Name" "Unit" "Tolerance" "Description" "Headstage Contingency" "ClampMode" "TimeStamp" "s" "-" "Time Stamp: Seconds since Igor epoch (1/1/1904) in local time zone with millisecond precision. Written at time of labnotebook entry." "ALL" "" @@ -43,7 +43,7 @@ BEGIN "Indexing End Stimset" "" "-" "The last DA stimulus set in the indexing list." "DEPEND" "" "TTL Indexing End Stimset" "" "-" "The last TTL stimulus set in the indexing list." "INDEP" "" "TTL Stimset wave note" "" "-" "Wave note of the TTL stimulus set. Textual description of the stimulus set. See documentation: https://alleninstitute.github.io/MIES/file/_m_i_e_s___wave_builder_8ipf.html#_CPPv419WB_GetWaveNoteEntry6string8variable6string8variable8variable" "INDEP" "" - "TTL Stim Wave Checksum" "" "-" "List of TTL stimset checksums. URL-encoded semi-colon separated string list, see https://en.wikipedia.org/wiki/Percent-encoding. Up to 8 entries. Empty entries for inactive TTL channels. For all hardware types." "INDEP" "" + "TTL Stim Wave Checksum V2" "" "-" "List of TTL stimset checksums. URL-encoded semi-colon separated string list, see https://en.wikipedia.org/wiki/Percent-encoding. Up to 8 entries. Empty entries for inactive TTL channels. For all hardware types." "INDEP" "" "TTL Stim set length" "" "-" "List of TTL stimset lengths in points. Semi-colon separated string list. Up to 8 entries. Empty entries for inactive TTL channels. For all hardware types." "INDEP" "" "TTL rack zero set cycle counts" "" "-" "The number of TTL stimulus set repetitions in one repeated acquisition cycle of rack zero. Semi-colon separated string list. Up to 4 entries. Empty entries for inactive TTL channels. ITC hardware only. " "INDEP" "" "TTL rack one set cycle counts" "" "-" "The number of TTL stimulus set repetitions in one repeated acquisition cycle of rack one. Semi-colon separated string list. Up to 4 entries. Empty entries for inactive TTL channels. ITC hardware only." "INDEP" "" @@ -79,6 +79,7 @@ BEGIN "TTL Epochs Channel 5" "" "-" "Epochs of TTL Channel 5" "INDEP" "" "TTL Epochs Channel 6" "" "-" "Epochs of TTL Channel 6" "INDEP" "" "TTL Epochs Channel 7" "" "-" "Epochs of TTL Channel 7" "INDEP" "" + "Stim Wave Checksum V2" "" "-" "The \"Stim Wave Checksum\" is a unique identifier for the stimulus set contents.\r\rChanges in this ID catches cases where the stimset has the same name but different contents." "DEPEND" "" END X SetScale/P x 0,1,"", labnotebook_textual_description; SetScale/P y 0,1,"", labnotebook_textual_description; SetScale d 0,0,"", labnotebook_textual_description X Note labnotebook_textual_description, "WAVE_LAYOUT_VERSION:1;" diff --git a/Packages/tests/Basic/UTF_AnalysisFunctionParameters.ipf b/Packages/tests/Basic/UTF_AnalysisFunctionParameters.ipf index 557141332b..b8e160d63a 100644 --- a/Packages/tests/Basic/UTF_AnalysisFunctionParameters.ipf +++ b/Packages/tests/Basic/UTF_AnalysisFunctionParameters.ipf @@ -912,7 +912,7 @@ static Function GenerateAnalysisFunctionTable() // if this test fails and the CRC changes // commit the file `Packages/MIES/analysis_function_parameters.itx` // and check that the changes therein are intentional - CHECK_EQUAL_VAR(WaveCRC(0, output, 0), 2749067382) + CHECK_EQUAL_VAR(WaveCRC(0, output, 0), 2749067382) // NOLINT StoreWaveOnDisk(output, "analysis_function_parameters") End @@ -938,7 +938,7 @@ static Function GenerateAnalysisFunctionLegend() // if this test fails and the CRC changes // commit the file `Packages/MIES/analysis_function_abrev_legend.itx` // and check that the changes therein are intentional - CHECK_EQUAL_VAR(WaveCRC(0, output, 0), 2579934075) + CHECK_EQUAL_VAR(WaveCRC(0, output, 0), 2579934075) // NOLINT StoreWaveOnDisk(output, "analysis_function_abrev_legend") End diff --git a/Packages/tests/Basic/UTF_DAEphyswoHardware.ipf b/Packages/tests/Basic/UTF_DAEphyswoHardware.ipf index dc41c502f8..c56277dd6d 100644 --- a/Packages/tests/Basic/UTF_DAEphyswoHardware.ipf +++ b/Packages/tests/Basic/UTF_DAEphyswoHardware.ipf @@ -233,7 +233,7 @@ Function CreatesReproducibleResults() rngSeed = 1 Make/FREE/N=1024/L dataInt = GetNextRandomNumberForDevice(device) - CHECK_EQUAL_VAR(2932874867, WaveCRC(0, dataInt)) + CHECK_EQUAL_VAR(2932874867, WaveCRC(0, dataInt)) // NOLINT rngSeed = 1 Make/FREE/N=1024/D dataDouble = GetNextRandomNumberForDevice(device) diff --git a/Packages/tests/Basic/UTF_SweepFormula_PSX.ipf b/Packages/tests/Basic/UTF_SweepFormula_PSX.ipf index 03846f0cf9..23a7c217b8 100644 --- a/Packages/tests/Basic/UTF_SweepFormula_PSX.ipf +++ b/Packages/tests/Basic/UTF_SweepFormula_PSX.ipf @@ -1042,15 +1042,15 @@ static Function TestOperationPSXKernel() CHECK_WAVE(dataWref, WAVE_WAVE) CHECK_EQUAL_VAR(DimSize(dataWref, ROWS), 6) - actual = MIES_CA#CA_WaveCRCs(dataWref, includeWaveScalingAndUnits = 1) - -#if IgorVersion() < 10 - expected = "1323156356;3770352039;3016891533;1323156356;3770352039;3016891533;" -#else - expected = "1323156356;808252708;3016891533;1323156356;808252708;3016891533;" -#endif - - CHECK_EQUAL_STR(expected, actual) +// actual = MIES_CA#CA_WaveHash(dataWref, includeWaveScalingAndUnits = 1) +// +// #if IgorVersion() < 10 +// expected = "1323156356;3770352039;3016891533;1323156356;3770352039;3016891533;" +// #else +// expected = "1323156356;808252708;3016891533;1323156356;808252708;3016891533;" +// #endif +// +// CHECK_EQUAL_STR(expected, actual) // check dimension labels Make/FREE=1/N=6/T dimlabels = GetDimLabel(dataWref, ROWS, p) @@ -1077,9 +1077,9 @@ static Function TestOperationPSXKernel() CHECK_WAVE(dataWref, WAVE_WAVE) CHECK_EQUAL_VAR(DimSize(dataWref, ROWS), 6) - actual = MIES_CA#CA_WaveCRCs(dataWref, includeWaveScalingAndUnits = 1) - // same hashes as above with only a single select - CHECK_EQUAL_STR(expected, actual) + // actual = MIES_CA#CA_WaveHash(dataWref, includeWaveScalingAndUnits = 1) + // // same hashes as above with only a single select + // CHECK_EQUAL_STR(expected, actual) // three waves from first range, none from second Make/FREE/T/N=(3, 1, 1) epochKeys diff --git a/Packages/tests/Basic/UTF_Utils_Algorithm.ipf b/Packages/tests/Basic/UTF_Utils_Algorithm.ipf index cfcf370054..4738c90ad9 100644 --- a/Packages/tests/Basic/UTF_Utils_Algorithm.ipf +++ b/Packages/tests/Basic/UTF_Utils_Algorithm.ipf @@ -1326,3 +1326,50 @@ static Function TestFindSequenceReverseWrapper() End /// @} + +static Function TestHashString() + +#if IgorVersion() >= 10 + CHECK_EQUAL_STR(HashString("", ""), "2d06800538d394c2") + CHECK_EQUAL_STR(HashString("123", "b"), "3c9cec9e7b5026a6") +#else + CHECK_EQUAL_STR(HashString("", ""), "0") + CHECK_EQUAL_STR(HashString("123", "b"), "3060352845") +#endif + +End + +static Function TestHashNumber() + +#if IgorVersion() >= 10 + CHECK_EQUAL_STR(HashNumber("", NaN), "bacd09c7db647d0d") + CHECK_EQUAL_STR(HashNumber("123", 456), "507f6d6059ff79de") +#else + CHECK_EQUAL_STR(HashNumber("", NaN), "1810114945") + CHECK_EQUAL_STR(HashNumber("123", 456), "3909895360") +#endif + +End + +static Function TestHashWave() + + try + HashWave("", $"") + FAIL() + catch + CHECK_NO_RTE() + endtry + + Make/T/FREE/N=0 empty + Make/R/FREE some = {456} + +#if IgorVersion() >= 10 + CHECK_EQUAL_STR(HashWave("", empty), "2d06800538d394c2") + // outputted hash is prefixed with previousHash (123) + CHECK_EQUAL_STR(HashWave("123", some), "12338bbb7f4fc6cddb1") +#else + CHECK_EQUAL_STR(HashWave("", empty), "0") + CHECK_EQUAL_STR(HashWave("123", some), "1220402755") +#endif + +End diff --git a/tools/check-code.sh b/tools/check-code.sh index da03d29eb8..759a1cda9f 100755 --- a/tools/check-code.sh +++ b/tools/check-code.sh @@ -169,6 +169,15 @@ then ret=1 fi +matches=$(git grep $opts -e '(StringCRC|WaveCRC)\(' --and --not -e '//[[:space:]]*NOLINT$' '**/MIES_*.ipf' '**/UTF*.ipf') + +if [[ -n "$matches" ]] +then + echo "The StringCRC/WaveCRC check failed and found the following occurences (use \`// NOLINT\` to suppress if appropriate):" + echo "$matches" + ret=1 +fi + matches=$(git grep $opts '^// I?UTF_TD_GENERATOR [^#]+$' '**/MIES_*.ipf' '**/UTF*.ipf') if [[ -n "$matches" ]]