diff --git a/Packages/MIES/MIES_Constants.ipf b/Packages/MIES/MIES_Constants.ipf index 6a61871fcf..3b5aae5d34 100644 --- a/Packages/MIES/MIES_Constants.ipf +++ b/Packages/MIES/MIES_Constants.ipf @@ -305,12 +305,11 @@ StrConstant NOTE_INDEX = "Index" ///@name Parameters for FindIndizes ///@anchor FindIndizesProps ///@{ -Constant PROP_NON_EMPTY = 0x01 ///< Wave entry is not NaN or "" -Constant PROP_EMPTY = 0x02 ///< Wave entry is NaN or "" -Constant PROP_MATCHES_VAR_BIT_MASK = 0x04 ///< Wave entry matches the bitmask given in var -Constant PROP_NOT_MATCHES_VAR_BIT_MASK = 0x08 ///< Wave entry does not match the bitmask given in var -Constant PROP_GREP = 0x10 ///< Wave entry matches the regular expression given in str -Constant PROP_WILDCARD = 0x20 ///< Wave entry matches the wildcard expression given in str +Constant PROP_NOT = 0x01 ///< Inverts the matching +Constant PROP_EMPTY = 0x02 ///< Wave entry is NaN or "" +Constant PROP_MATCHES_VAR_BIT_MASK = 0x04 ///< Wave entry matches the bitmask given in var +Constant PROP_GREP = 0x08 ///< Wave entry matches the regular expression given in str +Constant PROP_WILDCARD = 0x10 ///< Wave entry matches the wildcard expression given in str ///@} /// @name Parameters for GetPanelControl and IDX_GetSetsInRange, GetSetFolder, GetSetParamFolder and GetChanneListFromITCConfig diff --git a/Packages/MIES/MIES_Debugging.ipf b/Packages/MIES/MIES_Debugging.ipf index acba7d58df..fa515f4422 100644 --- a/Packages/MIES/MIES_Debugging.ipf +++ b/Packages/MIES/MIES_Debugging.ipf @@ -678,7 +678,7 @@ threadsafe static Function/S CheckDimensionLabels(WAVE/Z wv) Multithread results[] = CheckDimensionLabels(waveRef[p]) if(HasOneValidEntry(results)) - WAVE/Z indizes = FindIndizes(results, prop = PROP_NON_EMPTY) + WAVE/Z indizes = FindIndizes(results, prop = PROP_EMPTY | PROP_NOT) numMatches = WaveExists(indizes) ? DimSize(indizes, ROWS) : 0 for(i = 0; i < numMatches; i += 1) diff --git a/Packages/MIES/MIES_Labnotebook.ipf b/Packages/MIES/MIES_Labnotebook.ipf index 79638d66ad..aeae26b94b 100644 --- a/Packages/MIES/MIES_Labnotebook.ipf +++ b/Packages/MIES/MIES_Labnotebook.ipf @@ -110,7 +110,7 @@ End /// at least once, an empty string otherwise threadsafe static Function/S LBV_IsLabnotebookColumnFilled(WAVE values, variable col) - WAVE/Z indizes = FindIndizes(values, col = col, prop = PROP_NON_EMPTY, startLayer = 0, endLayer = LABNOTEBOOK_LAYER_COUNT - 1) + WAVE/Z indizes = FindIndizes(values, col = col, prop = PROP_EMPTY | PROP_NOT, startLayer = 0, endLayer = LABNOTEBOOK_LAYER_COUNT - 1) if(WaveExists(indizes)) return GetDimLabel(values, COLS, col) diff --git a/Packages/MIES/MIES_LogbookViewer.ipf b/Packages/MIES/MIES_LogbookViewer.ipf index deece404a8..970a3afacf 100644 --- a/Packages/MIES/MIES_LogbookViewer.ipf +++ b/Packages/MIES/MIES_LogbookViewer.ipf @@ -682,7 +682,7 @@ static Function LBV_AddTraceToLBGraphTPStorage(string graph, DFREF dfr, string k // ignore completely empty headstages if(!legacyActiveADColumns) searchLayer = FindDimLabel(TPStorage, LAYERS, "Headstage") - WAVE/Z indizes = FindIndizes(TPStorage, col = j, prop = PROP_NON_EMPTY, startLayer = searchLayer, endLayer = searchLayer) + WAVE/Z indizes = FindIndizes(TPStorage, col = j, prop = PROP_EMPTY | PROP_NOT, startLayer = searchLayer, endLayer = searchLayer) if(!WaveExists(indizes)) continue diff --git a/Packages/MIES/MIES_MiesUtilities.ipf b/Packages/MIES/MIES_MiesUtilities.ipf index 3351a638e9..5bc0b4a445 100644 --- a/Packages/MIES/MIES_MiesUtilities.ipf +++ b/Packages/MIES/MIES_MiesUtilities.ipf @@ -577,7 +577,7 @@ threadsafe static Function FindRange(wv, col, val, entrySourceType, first, last) // "TP Peak Resistance" introduced in 666d761a (TP documenting is implemented using David Reid's documenting functions, 2014-07-28) if(FindDimLabel(wv, COLS, "TP Peak Resistance") >= 0) - WAVE/Z indizesDefinitlyTP = FindIndizes(wv, colLabel = "TP Peak Resistance", prop = PROP_NON_EMPTY, startRow = firstRow, endRow = lastRow, startLayer = 0, endLayer = LABNOTEBOOK_LAYER_COUNT - 1) + WAVE/Z indizesDefinitlyTP = FindIndizes(wv, colLabel = "TP Peak Resistance", prop = PROP_EMPTY | PROP_NOT, startRow = firstRow, endRow = lastRow, startLayer = 0, endLayer = LABNOTEBOOK_LAYER_COUNT - 1) if(WaveExists(indizesDefinitlyTP) && WaveExists(indizesSetting)) WAVE/Z indizesSettingRemoved = GetSetDifference(indizesSetting, indizesDefinitlyTP) WAVE/Z indizesSetting = indizesSettingRemoved @@ -586,7 +586,7 @@ threadsafe static Function FindRange(wv, col, val, entrySourceType, first, last) // "TP Baseline Fraction" introduced in 4f4649a2 (Document the testpulse settings in the labnotebook, 2015-07-28) if(FindDimLabel(wv, COLS, "TP Baseline Fraction") >= 0) - WAVE/Z indizesDefinitlyTP = FindIndizes(wv, colLabel = "TP Baseline Fraction", prop = PROP_NON_EMPTY, startRow = firstRow, endRow = lastRow, startLayer = 0, endLayer = LABNOTEBOOK_LAYER_COUNT - 1) + WAVE/Z indizesDefinitlyTP = FindIndizes(wv, colLabel = "TP Baseline Fraction", prop = PROP_EMPTY | PROP_NOT, startRow = firstRow, endRow = lastRow, startLayer = 0, endLayer = LABNOTEBOOK_LAYER_COUNT - 1) if(WaveExists(indizesDefinitlyTP) && WaveExists(indizesSetting)) WAVE/Z indizesSettingRemoved = GetSetDifference(indizesSetting, indizesDefinitlyTP) WAVE/Z indizesSetting = indizesSettingRemoved @@ -1794,7 +1794,7 @@ threadsafe Function/WAVE GetNonEmptyLBNRows(labnotebookValues, setting) return $"" endif - return FindIndizes(labnotebookValues, col = col, prop = PROP_NON_EMPTY, \ + return FindIndizes(labnotebookValues, col = col, prop = PROP_EMPTY | PROP_NOT, \ startLayer = 0, endLayer = DimSize(labnotebookValues, LAYERS) - 1) End @@ -2800,7 +2800,7 @@ static Function [string oodDAQRegionsAll, variable totalXRange] GetOodDAQFullRan // Fixup buggy entries introduced since 88323d8d (Replacement of oodDAQ offset calculation routines, 2019-06-13) // The regions from the second active headstage are duplicated into the // first region in case we had more than two active headstages taking part in oodDAQ. - WAVE/Z indizes = FindIndizes(oodDAQRegions, prop = PROP_NON_EMPTY) + WAVE/Z indizes = FindIndizes(oodDAQRegions, prop = PROP_EMPTY | PROP_NOT) if(WaveExists(indizes) && DimSize(indizes, ROWS) > 2) oodDAQRegions[indizes[0]] = ReplaceString(oodDAQRegions[indizes[1]], oodDAQRegions[indizes[0]], "") endif @@ -7182,10 +7182,12 @@ End /// result contains matches from all layers, and this also means the resulting wave is still 1D. /// /// Exactly one of `var`/`str`/`prop` has to be given except for -/// `prop == PROP_MATCHES_VAR_BIT_MASK` and `prop == PROP_NOT_MATCHES_VAR_BIT_MASK` +/// `prop == PROP_MATCHES_VAR_BIT_MASK` /// which requires a `var`/`str` parameter as well. /// `prop == PROP_GREP` requires `str`. /// `prop == PROP_WILDCARD` requires `str`. +/// `PROP_NOT` can be set by logical ORing it to one of the other PROP_* constants +/// `prop == PROP_NOT` can also be set solely to invert the matching of the default behavior /// /// Exactly one of `col`/`colLabel` has to be given. /// @@ -7209,16 +7211,17 @@ threadsafe Function/WAVE FindIndizes(numericOrTextWave, [col, colLabel, var, str variable startRow, endRow variable startLayer, endLayer - variable numCols, numRows, numLayers + variable numCols, numRows, numLayers, maskedProp string key - ASSERT_TS(ParamIsDefault(prop) + ParamIsDefault(var) + ParamIsDefault(str) == 2 \ - || (!ParamIsDefault(prop) \ - && (((prop == PROP_MATCHES_VAR_BIT_MASK || prop == PROP_NOT_MATCHES_VAR_BIT_MASK) \ - && (ParamIsDefault(var) + ParamIsDefault(str)) == 1) \ - || (prop == PROP_GREP && !ParamIsDefault(str) && ParamIsDefault(var)) \ - || (prop == PROP_WILDCARD && !ParamIsDefault(str) && ParamIsDefault(var)) \ - )), \ + ASSERT_TS(ParamIsDefault(prop) + ParamIsDefault(var) + ParamIsDefault(str) == 2 \ + || (!ParamIsDefault(prop) \ + && ( \ + prop == PROP_NOT \ + || ((prop & PROP_MATCHES_VAR_BIT_MASK) && (ParamIsDefault(var) + ParamIsDefault(str)) == 1) \ + || (prop & PROP_GREP && !ParamIsDefault(str) && ParamIsDefault(var)) \ + || (prop & PROP_WILDCARD && !ParamIsDefault(str) && ParamIsDefault(var)) \ + )), \ "Invalid combination of var/str/prop arguments") ASSERT_TS(WaveExists(numericOrTextWave), "numericOrTextWave does not exist") @@ -7253,22 +7256,23 @@ threadsafe Function/WAVE FindIndizes(numericOrTextWave, [col, colLabel, var, str endif if(!ParamIsDefault(prop)) - ASSERT_TS(prop == PROP_NON_EMPTY \ - || prop == PROP_EMPTY \ - || prop == PROP_MATCHES_VAR_BIT_MASK \ - || prop == PROP_NOT_MATCHES_VAR_BIT_MASK \ - || prop == PROP_GREP \ - || prop == PROP_WILDCARD, \ - "Invalid property") - - if(prop == PROP_MATCHES_VAR_BIT_MASK || prop == PROP_NOT_MATCHES_VAR_BIT_MASK) - if(ParamIsDefault(var)) - var = str2numSafe(str) - elseif(ParamIsDefault(str)) - str = num2str(var) + maskedProp = prop & (PROP_NOT %^ -1) + if(maskedProp) + ASSERT_TS(maskedProp == PROP_EMPTY \ + || maskedProp == PROP_MATCHES_VAR_BIT_MASK \ + || maskedProp == PROP_GREP \ + || maskedProp == PROP_WILDCARD, \ + "Invalid property") + + if(prop & PROP_MATCHES_VAR_BIT_MASK) + if(ParamIsDefault(var)) + var = str2numSafe(str) + elseif(ParamIsDefault(str)) + str = num2str(var) + endif + elseif(prop & PROP_GREP) + ASSERT_TS(IsValidRegexp(str), "Invalid regular expression") endif - elseif(prop == PROP_GREP) - ASSERT_TS(IsValidRegexp(str), "Invalid regular expression") endif elseif(!ParamIsDefault(var)) str = num2str(var) @@ -7326,40 +7330,68 @@ threadsafe Function/WAVE FindIndizes(numericOrTextWave, [col, colLabel, var, str if(WaveExists(wv)) if(!ParamIsDefault(prop)) - if(prop == PROP_EMPTY) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (numtype(wv[p][col][q]) == 2 ? p : -1) - elseif(prop == PROP_NON_EMPTY) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (numtype(wv[p][col][q]) != 2 ? p : -1) - elseif(prop == PROP_MATCHES_VAR_BIT_MASK) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (wv[p][col][q] & var ? p : -1) - elseif(prop == PROP_NOT_MATCHES_VAR_BIT_MASK) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (!(wv[p][col][q] & var) ? p : -1) - elseif(prop == PROP_GREP) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (GrepString(num2strHighPrec(wv[p][col][q]), str) ? p : -1) - elseif(prop == PROP_WILDCARD) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (StringMatch(num2strHighPrec(wv[p][col][q]), str) ? p : -1) + if(prop & PROP_EMPTY) + if(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = numtype(wv[p][col][q]) != 2 ? p : -1 + else + MultiThread matches[startRow, endRow][startLayer, endLayer] = numtype(wv[p][col][q]) == 2 ? p : -1 + endif + elseif(prop & PROP_MATCHES_VAR_BIT_MASK) + if(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = !(wv[p][col][q] & var) ? p : -1 + else + MultiThread matches[startRow, endRow][startLayer, endLayer] = wv[p][col][q] & var ? p : -1 + endif + elseif(prop & PROP_GREP) + if(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = !GrepString(num2strHighPrec(wv[p][col][q]), str) ? p : -1 + else + MultiThread matches[startRow, endRow][startLayer, endLayer] = GrepString(num2strHighPrec(wv[p][col][q]), str) ? p : -1 + endif + elseif(prop & PROP_WILDCARD) + if(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = !StringMatch(num2strHighPrec(wv[p][col][q]), str) ? p : -1 + else + MultiThread matches[startRow, endRow][startLayer, endLayer] = StringMatch(num2strHighPrec(wv[p][col][q]), str) ? p : -1 + endif + elseif(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = (wv[p][col][q] != var) ? p : -1 endif else ASSERT_TS(!IsNaN(var), "Use PROP_EMPTY to search for NaN") - MultiThread matches[startRow, endRow][startLayer, endLayer] = ((wv[p][col][q] == var) ? p : -1) + MultiThread matches[startRow, endRow][startLayer, endLayer] = (wv[p][col][q] == var) ? p : -1 endif else if(!ParamIsDefault(prop)) - if(prop == PROP_EMPTY) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (!cmpstr(wvText[p][col][q], "") ? p : -1) - elseif(prop == PROP_NON_EMPTY) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (cmpstr(wvText[p][col][q], "") ? p : -1) - elseif(prop == PROP_MATCHES_VAR_BIT_MASK) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (str2num(wvText[p][col][q]) & var ? p : -1) - elseif(prop == PROP_NOT_MATCHES_VAR_BIT_MASK) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (!(str2num(wvText[p][col][q]) & var) ? p : -1) - elseif(prop == PROP_GREP) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (GrepString(wvText[p][col][q], str) ? p : -1) - elseif(prop == PROP_WILDCARD) - MultiThread matches[startRow, endRow][startLayer, endLayer] = (StringMatch(wvText[p][col][q], str) ? p : -1) + if(prop & PROP_EMPTY) + if(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = strlen(wvText[p][col][q]) ? p : -1 + else + MultiThread matches[startRow, endRow][startLayer, endLayer] = !strlen(wvText[p][col][q]) ? p : -1 + endif + elseif(prop & PROP_MATCHES_VAR_BIT_MASK) + if(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = !(str2num(wvText[p][col][q]) & var) ? p : -1 + else + MultiThread matches[startRow, endRow][startLayer, endLayer] = str2num(wvText[p][col][q]) & var ? p : -1 + endif + elseif(prop & PROP_GREP) + if(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = !GrepString(wvText[p][col][q], str) ? p : -1 + else + MultiThread matches[startRow, endRow][startLayer, endLayer] = GrepString(wvText[p][col][q], str) ? p : -1 + endif + elseif(prop & PROP_WILDCARD) + if(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = !StringMatch(wvText[p][col][q], str) ? p : -1 + else + MultiThread matches[startRow, endRow][startLayer, endLayer] = StringMatch(wvText[p][col][q], str) ? p : -1 + endif + elseif(prop & PROP_NOT) + MultiThread matches[startRow, endRow][startLayer, endLayer] = CmpStr(wvText[p][col][q], str) ? p : -1 endif else - MultiThread matches[startRow, endRow][startLayer, endLayer] = (!cmpstr(wvText[p][col][q], str) ? p : -1) + MultiThread matches[startRow, endRow][startLayer, endLayer] = !CmpStr(wvText[p][col][q], str) ? p : -1 endif endif @@ -7386,7 +7418,7 @@ Function/S GetLastNonEmptyEntry(wv, colLabel, endRow) string colLabel variable endRow - WAVE/Z indizes = FindIndizes(wv, colLabel = colLabel, prop = PROP_NON_EMPTY, endRow = endRow) + WAVE/Z indizes = FindIndizes(wv, colLabel = colLabel, prop = PROP_EMPTY | PROP_NOT, endRow = endRow) if(!WaveExists(indizes)) return "" diff --git a/Packages/MIES/MIES_NeuroDataWithoutBorders.ipf b/Packages/MIES/MIES_NeuroDataWithoutBorders.ipf index c6ca7f80b6..85b26b8881 100644 --- a/Packages/MIES/MIES_NeuroDataWithoutBorders.ipf +++ b/Packages/MIES/MIES_NeuroDataWithoutBorders.ipf @@ -1083,7 +1083,7 @@ threadsafe static Function NWB_AppendSweepLowLevel(STRUCT NWBAsyncParameters &s) if(!WaveExists(electrodeNames)) Make/FREE/T/N=(NUM_HEADSTAGES) electrodeNames = GetDefaultElectrodeName(p) else - WAVE/Z nonEmptyElectrodes = FindIndizes(electrodeNames, prop = PROP_NON_EMPTY) + WAVE/Z nonEmptyElectrodes = FindIndizes(electrodeNames, prop = PROP_EMPTY | PROP_NOT) if(!WaveExists(nonEmptyElectrodes)) // all are empty electrodeNames[] = GetDefaultElectrodeName(p) endif diff --git a/Packages/MIES/MIES_Utilities.ipf b/Packages/MIES/MIES_Utilities.ipf index a67af83f6f..875ec23311 100644 --- a/Packages/MIES/MIES_Utilities.ipf +++ b/Packages/MIES/MIES_Utilities.ipf @@ -5467,16 +5467,31 @@ End /// @brief Turn a list of entries into a regular expression with alternations. /// /// Can be used for GetListOfObjects() if you know in advance which entries to filter out. -Function/S ConvertListToRegexpWithAlternations(list) - string list +/// +/// @param list semicolon separated list of strings to match +/// @param literal [optional, default = 1] when this flag is cleared the string elements of the list are treated as regular expressions +/// @param sep [optional, default = ";"] separator for list +Function/S ConvertListToRegexpWithAlternations(string list, [variable literal, string sep]) variable i, numEntries - string entry - string regexpList = "" + string regexpList = "" + string literalPrefix = "\\Q" + string literalSuffix = "\\E" - numEntries = ItemsInList(list) + literal = ParamIsDefault(literal) ? 1 : !!literal + if(ParamIsDefault(sep)) + sep = ";" + else + ASSERT(!IsEmpty(sep), "separator can not be empty.") + endif + + if(!literal) + literalPrefix = "" + literalSuffix = "" + endif + numEntries = ItemsInList(list, sep) for(i = 0; i < numEntries; i += 1) - regexpList = AddListItem("\\Q" + StringFromList(i, list) + "\\E", regexpList, "|", Inf) + regexpList = AddListItem(literalPrefix + StringFromList(i, list, sep) + literalSuffix, regexpList, "|", Inf) endfor regexpList = "(?:" + RemoveEnding(regexpList, "|") + ")" diff --git a/Packages/tests/Basic/UTF_Utils.ipf b/Packages/tests/Basic/UTF_Utils.ipf index 422f8883d9..cc956a1611 100644 --- a/Packages/tests/Basic/UTF_Utils.ipf +++ b/Packages/tests/Basic/UTF_Utils.ipf @@ -1124,6 +1124,14 @@ Function FI_NumSearchWithCol1() CHECK_EQUAL_WAVES(indizes, {0, 1, 2}, mode = WAVE_DATA) End +static Function FI_NumSearchWithCol1Inverted() + DFREF dfr = root:FindIndizes + WAVE/SDFR=dfr numeric + + WAVE/Z indizes = FindIndizes(numeric, var = 1, prop = PROP_NOT) + CHECK_EQUAL_WAVES(indizes, {3, 4}, mode = WAVE_DATA) +End + Function FI_NumSearchWithColAndLayer1() DFREF dfr = root:FindIndizes WAVE/SDFR=dfr numeric @@ -1176,7 +1184,7 @@ Function FI_NumSearchWithColAndProp1() DFREF dfr = root:FindIndizes WAVE/SDFR=dfr numeric - WAVE/Z indizes = FindIndizes(numeric, colLabel = "abcd", prop = PROP_NON_EMPTY) + WAVE/Z indizes = FindIndizes(numeric, colLabel = "abcd", prop = PROP_EMPTY | PROP_NOT) CHECK_EQUAL_WAVES(indizes, {0, 1, 2}, mode = WAVE_DATA) End @@ -1200,7 +1208,7 @@ Function FI_NumSearchWithColAndProp4() DFREF dfr = root:FindIndizes WAVE/SDFR=dfr numeric - WAVE/Z indizes = FindIndizes(numeric, col = 1, var = 2, prop = PROP_NOT_MATCHES_VAR_BIT_MASK) + WAVE/Z indizes = FindIndizes(numeric, col = 1, var = 2, prop = PROP_MATCHES_VAR_BIT_MASK | PROP_NOT) CHECK_EQUAL_WAVES(indizes, {0}, mode = WAVE_DATA) End @@ -1212,6 +1220,14 @@ Function FI_NumSearchWithColAndProp5() CHECK_EQUAL_WAVES(indizes, {3}, mode = WAVE_DATA) End +static Function FI_NumSearchWithColAndProp5Inverted() + DFREF dfr = root:FindIndizes + WAVE/SDFR=dfr numeric + + WAVE/Z indizes = FindIndizes(numeric, col = 1, str = "6+", prop = PROP_GREP | PROP_NOT) + CHECK_EQUAL_WAVES(indizes, {0, 1, 2, 4}, mode = WAVE_DATA) +End + Function FI_NumSearchWithColAndProp6() DFREF dfr = root:FindIndizes WAVE/SDFR=dfr numeric @@ -1220,6 +1236,14 @@ Function FI_NumSearchWithColAndProp6() CHECK_EQUAL_WAVES(indizes, {3}, mode = WAVE_DATA) End +static Function FI_NumSearchWithColAndProp6Inverted() + DFREF dfr = root:FindIndizes + WAVE/SDFR=dfr numeric + + WAVE/Z indizes = FindIndizes(numeric, col = 1, str = "6*", prop = PROP_WILDCARD | PROP_NOT) + CHECK_EQUAL_WAVES(indizes, {0, 1, 2, 4}, mode = WAVE_DATA) +End + Function FI_NumSearchWithColAndProp6a() DFREF dfr = root:FindIndizes WAVE/SDFR=dfr numeric @@ -1304,7 +1328,7 @@ Function FI_TextSearchWithColAndProp1() DFREF dfr = root:FindIndizes WAVE/SDFR=dfr text - WAVE/Z indizes = FindIndizes(text, colLabel = "efgh", prop = PROP_NON_EMPTY) + WAVE/Z indizes = FindIndizes(text, colLabel = "efgh", prop = PROP_EMPTY | PROP_NOT) CHECK_EQUAL_WAVES(indizes, {0, 1, 2}, mode = WAVE_DATA) End @@ -1328,7 +1352,7 @@ Function FI_TextSearchWithColAndProp4() DFREF dfr = root:FindIndizes WAVE/SDFR=dfr text - WAVE/Z indizes = FindIndizes(text, col = 1, str = "2", prop = PROP_NOT_MATCHES_VAR_BIT_MASK) + WAVE/Z indizes = FindIndizes(text, col = 1, str = "2", prop = PROP_MATCHES_VAR_BIT_MASK | PROP_NOT) CHECK_EQUAL_WAVES(indizes, {0}, mode = WAVE_DATA) End @@ -8053,3 +8077,27 @@ static Function HWS_Works() CHECK_EQUAL_VAR(HasWildcardSyntax("!a"), 1) CHECK_EQUAL_VAR(HasWildcardSyntax("a*b"), 1) End + +static Function ConvertListToRegexpWithAlternations_Test() + + string str, ref + + str = ConvertListToRegexpWithAlternations("1;2;") + ref = "(?:\\Q1\\E|\\Q2\\E)" + CHECK_EQUAL_STR(ref, str) + + str = ConvertListToRegexpWithAlternations("1;2;", literal = 0) + ref = "(?:1|2)" + CHECK_EQUAL_STR(ref, str) + + str = ConvertListToRegexpWithAlternations("1#2#", literal = 0, sep = "#") + ref = "(?:1|2)" + CHECK_EQUAL_STR(ref, str) + + try + str = ConvertListToRegexpWithAlternations("1#2#", sep = "") + FAIL() + catch + PASS() + endtry +End diff --git a/Packages/tests/HardwareBasic/UTF_Epochs.ipf b/Packages/tests/HardwareBasic/UTF_Epochs.ipf index 61cdb40edf..658042b17b 100644 --- a/Packages/tests/HardwareBasic/UTF_Epochs.ipf +++ b/Packages/tests/HardwareBasic/UTF_Epochs.ipf @@ -66,7 +66,7 @@ static Function [WAVE startT, WAVE endT, WAVE levels, WAVE/T description] Remove WAVE/Z levels = ZapNans(levels_sub) CHECK_WAVE(levels, NUMERIC_WAVE) - WAVE/Z indizes = FindIndizes(description_sub, prop = PROP_NON_EMPTY) + WAVE/Z indizes = FindIndizes(description_sub, prop = PROP_EMPTY | PROP_NOT) if(WaveExists(indizes)) Make/N=(DimSize(indizes, ROWS))/T/FREE description = description_sub[indizes[p]] endif diff --git a/Packages/tests/UTF_HelperFunctions.ipf b/Packages/tests/UTF_HelperFunctions.ipf index 8038df33fb..a1b98e385a 100644 --- a/Packages/tests/UTF_HelperFunctions.ipf +++ b/Packages/tests/UTF_HelperFunctions.ipf @@ -1011,7 +1011,7 @@ Function [string abWin, string sweepBrowsers] OpenAnalysisBrowser(WAVE/T files, WAVE/T expBrowserList = GetExperimentBrowserGUIList() WAVE expBrowserSel = GetExperimentBrowserGUISel() - WAVE/Z indizes = FindIndizes(expBrowserList, colLabel = "file", prop = PROP_NON_EMPTY) + WAVE/Z indizes = FindIndizes(expBrowserList, colLabel = "file", prop = PROP_EMPTY | PROP_NOT) if(loadSweeps) for(idx : indizes) @@ -1145,16 +1145,14 @@ static Function TestEpochRecreationRemoveUnsupportedUserEpochs(WAVE/T epochChann Make/FREE/T tpEpochs = {"^U_TP[[:digit:]]+_B0$", "^U_TP[[:digit:]]+_P$", "^U_TP[[:digit:]]+_B1$", "^U_TP[[:digit:]]+$"} Concatenate/FREE/T/NP {tpEpochs}, supportedUserEpochs endif - supportedUserEpochsRegExp = TextWaveToList(supportedUserEpochs, "|") - supportedUserEpochsRegExp = RemoveEnding(supportedUserEpochsRegExp, "|") - supportedUserEpochsRegExp = "^(?![\s\S]*" + supportedUserEpochsRegExp + ")[\s\S]*$" + supportedUserEpochsRegExp = ConvertListToRegexpWithAlternations(RemoveEnding(TextWaveToList(supportedUserEpochs, ";"), ";"), literal = 0) Make/FREE/T/N=(DimSize(epochChannel, ROWS)) shortnames = EP_GetShortName(epochChannel[p][EPOCH_COL_TAGS]) WAVE/Z userEpochIndices = FindIndizes(shortNames, str = regexpUserEpochs, prop = PROP_GREP) if(!WaveExists(userEpochIndices)) return NaN endif Make/FREE/T/N=(DimSize(userEpochIndices, ROWS)) userEpochShortNames = shortnames[userEpochIndices[p]] - WAVE/Z matches = FindIndizes(userEpochShortNames, str = supportedUserEpochsRegExp, prop = PROP_GREP) + WAVE/Z matches = FindIndizes(userEpochShortNames, str = supportedUserEpochsRegExp, prop = PROP_GREP | PROP_NOT) if(!WaveExists(matches)) return NaN endif