Skip to content

Commit

Permalink
Merge pull request #1915 from AllenInstitute/bugfix/1915-combine-stim…
Browse files Browse the repository at this point in the history
…sets-backport

Propagate changed stimsets better
  • Loading branch information
t-b authored Oct 17, 2023
2 parents a94288e + 8ef7854 commit 89aadde
Show file tree
Hide file tree
Showing 12 changed files with 241 additions and 73 deletions.
7 changes: 4 additions & 3 deletions Packages/MIES/MIES_DAEphys.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,7 @@ Function DAP_PopMenuChkProc_StimSetList(pa) : PopupMenuControl
// is not yet reflected in the user data
list = GetUserData(device, ctrl, USER_DATA_MENU_EXP)
if(FindListItem(stimSet, list) == -1)
DAP_UpdateDaEphysStimulusSetPopups()
WB_UpdateChangedStimsets()
endif
endif

Expand Down Expand Up @@ -4456,7 +4456,7 @@ Function DAP_LockDevice(string win)
DAP_UpdateDAQControls(deviceLocked, REASON_STIMSET_CHANGE | REASON_HEADSTAGE_CHANGE)
// create the amplifier settings waves
GetAmplifierParamStorageWave(deviceLocked)
DAP_UpdateDaEphysStimulusSetPopups(device=deviceLocked)
WB_UpdateChangedStimsets(device=deviceLocked)
DAP_UnlockCommentNotebook(deviceLocked)
DAP_ToggleAcquisitionButton(deviceLocked, DATA_ACQ_BUTTON_TO_DAQ)
SI_CalculateMinSampInterval(deviceLocked, DATA_ACQUISITION_MODE)
Expand Down Expand Up @@ -5339,6 +5339,7 @@ Function DAP_DeleteStimulusSet(string setName, [string device])
if(ParamIsDefault(device))
WB_KillParameterWaves(setName)
WB_KillStimset(setName)
WB_UpdateChangedStimsets()
return NaN
endif

Expand All @@ -5351,7 +5352,7 @@ Function DAP_DeleteStimulusSet(string setName, [string device])
WB_KillParameterWaves(setName)
WB_KillStimset(setName)

DAP_UpdateDaEphysStimulusSetPopups(device = device)
WB_UpdateChangedStimsets(device = device)
End

/// @brief Write all TP settings from the data acquisition/settings tab to the settings wave
Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_DataBrowser_Macro.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ Window DataBrowser() : Graph
SetVariable setvar_pulseAver_startPulse,limits={0,inf,1},value=_NUM:0
CheckBox check_pulseAver_multGraphs,pos={234.00,165.00},size={121.00,15.00},disable=1,proc=PA_CheckProc_Common
CheckBox check_pulseAver_multGraphs,title="Use multiple graphs"
CheckBox check_pulseAver_multGraphs,help={"Show the single pulses in multiple graphs or only one graph with mutiple axis."}
CheckBox check_pulseAver_multGraphs,help={"Show the single pulses in multiple graphs or only one graph with multiple axis."}
CheckBox check_pulseAver_multGraphs,userdata(tabnum)="4"
CheckBox check_pulseAver_multGraphs,userdata(tabcontrol)="Settings"
CheckBox check_pulseAver_multGraphs,userdata(ResizeControlsInfo)=A"!!,H%!!#A4!!#@V!!#<(z!!#`-A7TLfzzzzzzzzzzzzzz!!#r+D.OhkBk2=!z"
Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_NeuroDataWithoutBorders.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1634,7 +1634,7 @@ Function NWB_LoadAllStimsets([overwrite, fileName, loadOnlyBuiltins])
HDF5CloseGroup/Z groupID
H5_CloseFile(fileID)

DAP_UpdateDaEphysStimulusSetPopups()
WB_UpdateChangedStimsets()

LOG_AddEntry(PACKAGE_MIES, "end")

Expand Down
58 changes: 40 additions & 18 deletions Packages/MIES/MIES_Utilities.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ End
/// @param upsampleFactor positive non-zero integer by which the wave should
/// be upsampled
/// @param mode decimation mode, one of @ref DECIMATION_BY_OMISSION,
/// @ref DECIMATION_BY_AVERAGING
/// @ref DECIMATION_BY_AVERAGING
/// or @ref DECIMATION_BY_SMOOTHING.
/// @param winFunction Windowing function for @ref DECIMATION_BY_SMOOTHING mode,
/// must be one of @ref FFT_WINF.
Expand Down Expand Up @@ -2116,13 +2116,14 @@ threadsafe Function/S RemoveEndingRegExp(str, endingRegExp)
string str, endingRegExp

string endStr
variable err

if(isEmpty(str) || isEmpty(endingRegExp))
return str
endif

SplitString/E="(" + endingRegExp + ")$" str, endStr
ASSERT_TS(V_flag == 0 || V_flag == 1, "Unexpected number of matches")
SplitString/E=("(" + endingRegExp + ")$") str, endStr; err = GetRTError(1)
ASSERT_TS((V_flag == 0 || V_flag == 1) && err == 0, "Unexpected number of matches or invalid regex")

return RemoveEnding(str, endStr)
End
Expand Down Expand Up @@ -2150,20 +2151,38 @@ End
///
/// @return 1 if word was found in str and word was not "". 0 if not.
Function SearchWordInString(string str, string word, [string &prefix, string &suffix])
WAVE/Z/T wv = SearchStringBase(str, "(.*)\\b\\Q" + word + "\\E\\b(.*)")
if(!WaveExists(wv))
return 0

string prefixParam, suffixParam
variable ret

[ret, prefixParam, suffixParam] = SearchRegexInString(str, "\\b\\Q" + word + "\\E\\b")

if(!ret)
return ret
endif

if(!ParamIsDefault(prefix))
prefix = wv[0]
prefix = prefixParam
endif

if(!ParamIsDefault(suffix))
suffix = wv[1]
suffix = suffixParam
endif

return 1
return ret
End

static Function [variable ret, string prefix, string suffix] SearchRegexInString(string str, string regex)

ASSERT(IsValidRegexp(regex), "Empty regex")

WAVE/Z/T wv = SearchStringBase(str, "(.*)" + regex + "(.*)")

if(!WaveExists(wv))
return [0, "", ""]
endif

return [1, wv[0], wv[1]]
End

/// @brief More advanced version of SplitString
Expand Down Expand Up @@ -4056,24 +4075,27 @@ Function/S SortAxisList(graph, list)
return TextWaveToList(axisListWave, ";")
End

/// @brief Replaces all occurences of the string `word`, treated as regexp word,
/// in `str` with `replacement`. Does not ignore case.
Function/S ReplaceWordInString(word, str, replacement)
string word, str, replacement
Function/S ReplaceWordInString(string word, string str, string replacement)

ASSERT(!IsEmpty(word), "Empty regex")

variable ret
string result, prefix, suffix
ASSERT(!IsEmpty(word), "Empty word")

if(!cmpstr(word, replacement, 0))
return str
endif

return ReplaceRegexInString("\\b\\Q" + word + "\\E\\b", str, replacement)
End

/// @brief Replaces all occurences of the regular expression `regex` in `str` with `replacement`
Function/S ReplaceRegexInString(string regex, string str, string replacement)

variable ret
string result, prefix, suffix

result = str

for(;;)
ret = SearchWordInString(result, word, prefix = prefix, suffix = suffix)
[ret, prefix, suffix] = SearchRegexInString(result, regex)

if(!ret)
break
Expand Down
69 changes: 40 additions & 29 deletions Packages/MIES/MIES_WaveBuilder.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1937,12 +1937,9 @@ static Function/WAVE WB_FillWaveFromFormula(formula, channelType, sweep)
STRUCT FormulaProperties fp
string shorthandFormula

// update shorthand -> stimset mapping
WB_UpdateEpochCombineList(channelType)
shorthandFormula = WB_FormulaSwitchToShorthand(channelType, formula)

shorthandFormula = WB_FormulaSwitchToShorthand(formula)

if(WB_ParseCombinerFormula(shorthandFormula, sweep, fp))
if(WB_ParseCombinerFormula(channelType, shorthandFormula, sweep, fp))
return $""
endif

Expand Down Expand Up @@ -1972,7 +1969,7 @@ End
///
/// The rows are sorted by creationDate of the WP/stimset wave to try to keep
/// the shorthands constants even when new stimsets are added.
Function WB_UpdateEpochCombineList(variable channelType)
Function WB_UpdateEpochCombineList(WAVE/T epochCombineList, variable channelType)
string list, setPath, setParamPath, entry
variable numEntries, i

Expand Down Expand Up @@ -2006,7 +2003,6 @@ Function WB_UpdateEpochCombineList(variable channelType)

Sort creationDates, stimsets

Wave/T epochCombineList = GetWBEpochCombineList()
Redimension/N=(numEntries, -1) epochCombineList

epochCombineList[][%StimSet] = stimsets[p]
Expand Down Expand Up @@ -2035,16 +2031,14 @@ End

/// @brief Parse the formula from the epoch type `Combine`
///
/// @param[in] formula math formula to execute, all operators which Igor can grok are allowed
/// @param sweep current sweep (aka step)
/// @param[out] fp parsed formula structure, with shorthands replaced by stimsets,
/// empty on parse error, ready to be executed by WB_FillWaveFromFormula()
/// @param[in] channelType One of CHANNEL_TYPE_DA or CHANNEL_TYPE_TTL
/// @param[in] formula math formula to execute, all operators which Igor can grok are allowed
/// @param[in] sweep current sweep (aka step)
/// @param[out] fp parsed formula structure, with shorthands replaced by stimsets,
/// empty on parse error, ready to be executed by WB_FillWaveFromFormula()
///
/// @returns 0 on success, 1 on parse errors (currently not many are found)
Function WB_ParseCombinerFormula(formula, sweep, fp)
string formula
variable sweep
struct FormulaProperties &fp
Function WB_ParseCombinerFormula(variable channelType, string formula, variable sweep, STRUCT FormulaProperties &fp)

string dependentStimsets
variable i, numStimsets
Expand All @@ -2054,7 +2048,7 @@ Function WB_ParseCombinerFormula(formula, sweep, fp)

InitFormulaProperties(fp)
InitFormulaProperties(trans)
WB_FormulaSwitchToStimset(formula, trans)
WB_FormulaSwitchToStimset(channelType, formula, trans)

// look for shorthand-like strings not referring to existing stimsets
if(GrepString(trans.formula, "\\b[A-Z][0-9]*\\b"))
Expand Down Expand Up @@ -2100,10 +2094,7 @@ Function WB_ParseCombinerFormula(formula, sweep, fp)
End

/// @brief Replace shorthands with the real stimset names suffixed with `?`
Function WB_FormulaSwitchToStimset(formula, fp)
string formula
struct FormulaProperties &fp

Function WB_FormulaSwitchToStimset(variable channelType, string formula, STRUCT FormulaProperties &fp)
string stimset, shorthand, stimsetSpec, prefix, suffix
variable numSets, i, stimsetFound

Expand All @@ -2113,7 +2104,7 @@ Function WB_FormulaSwitchToStimset(formula, fp)
return NaN
endif

WAVE/T epochCombineList = GetWBEpochCombineList()
WAVE/T epochCombineList = GetWBEpochCombineList(channeltype)

formula = UpperStr(formula)

Expand All @@ -2122,7 +2113,7 @@ Function WB_FormulaSwitchToStimset(formula, fp)
// iterate the stimset list from bottom to top, so that we replace first the shorthands
// with numeric prefix and only later on the ones without
numSets = DimSize(epochCombineList, ROWS)
for(i = numSets - 1; i >= 0; i -= 1)
for(i = numSets - 1; i >= 0 && numSets > 0; i -= 1)
shorthand = epochCombineList[i][%Shorthand]
stimset = epochCombineList[i][%stimset]
stimsetSpec = LowerStr(stimset) + "?"
Expand Down Expand Up @@ -2164,24 +2155,24 @@ static Function WB_PrepareFormulaForExecute(fp, sweep)
End

/// @brief Replace all stimsets suffixed with `?` by their shorthands
Function/S WB_FormulaSwitchToShorthand(formula)
string formula
Function/S WB_FormulaSwitchToShorthand(variable channelType, string formula)

variable numSets, i
string stimset, shorthand
string stimset, shorthand, regex

if(isEmpty(formula))
return ""
endif

WAVE/T epochCombineList = GetWBEpochCombineList()
WAVE/T epochCombineList = GetWBEpochCombineList(channelType)

numSets = DimSize(epochCombineList, ROWS)
for(i = 0; i < numSets; i += 1)
shorthand = epochCombineList[i][%Shorthand]
stimset = epochCombineList[i][%stimset]

formula = ReplaceString(stimset + "?", formula, shorthand)
regex = "\\b\\Q" + LowerStr(stimset) + "\\E\\b\?"
formula = ReplaceRegexInString(regex, formula, shorthand)
endfor

return formula
Expand Down Expand Up @@ -2680,8 +2671,7 @@ Function/S WB_SaveStimSet(string baseName, variable stimulusType, WAVE SegWvType
ASSERT(WaveExists(stimset), "Could not recreate stimset")

// propagate the existence of the new set
DAP_UpdateDaEphysStimulusSetPopups()
WB_UpdateEpochCombineList(stimulusType)
WB_UpdateChangedStimsets(stimulusType = stimulusType)

return setName
End
Expand Down Expand Up @@ -2816,3 +2806,24 @@ Function WB_MakeStimsetThirdParty(string setName)
KillOrMoveToTrash(wv=WPT)
KillOrMoveToTrash(wv=SegWvType)
End

/// @brief Propagate added/removed stimsets to DA_Ephys panels and our epoch combine list
Function WB_UpdateChangedStimsets([string device, variable stimulusType])

if(ParamIsDefault(device))
DAP_UpdateDaEphysStimulusSetPopups()
else
DAP_UpdateDaEphysStimulusSetPopups(device = device)
endif

if(ParamIsDefault(stimulusType))
WAVE/T epochCombineList = GetWBEpochCombineList(CHANNEL_TYPE_DAC)
WB_UpdateEpochCombineList(epochCombineList, CHANNEL_TYPE_DAC)

WAVE/T epochCombineList = GetWBEpochCombineList(CHANNEL_TYPE_TTL)
WB_UpdateEpochCombineList(epochCombineList, CHANNEL_TYPE_TTL)
else
WAVE/T epochCombineList = GetWBEpochCombineList(stimulusType)
WB_UpdateEpochCombineList(epochCombineList, stimulusType)
endif
End
22 changes: 14 additions & 8 deletions Packages/MIES/MIES_WaveBuilderPanel.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ Function/S WBP_CreateWaveBuilderPanel()

WBP_ClearFolders()

WB_UpdateChangedStimsets()

Execute "WaveBuilder()"
ListBox listbox_combineEpochMap, listWave=GetWBEpochCombineList()
ListBox listbox_combineEpochMap, listWave=GetWBEpochCombineList(WBP_GetStimulusType())
AddVersionToPanel(panel, WAVEBUILDER_PANEL_VERSION)

NVAR JSONid = $GetSettingsJSONid()
Expand Down Expand Up @@ -403,9 +405,6 @@ static Function WBP_UpdatePanelIfAllowed()
SetSetVariable(panel, "SetVar_WaveBuilder_P8", maxDuration)
endif
break
case EPOCH_TYPE_COMBINE:
WB_UpdateEpochCombineList(WBP_GetStimulusType())
break
default:
// nothing to do
break
Expand Down Expand Up @@ -834,6 +833,8 @@ static Function WBP_ChangeWaveType()
ASSERT(0, "Unknown stimulus type")
endif

ListBox listbox_combineEpochMap, win=$panel, listWave=GetWBEpochCombineList(WBP_GetStimulusType())

WBP_UpdatePanelIfAllowed()
End

Expand Down Expand Up @@ -1426,7 +1427,7 @@ Function WBP_SetVarCombineEpochFormula(sva) : SetVariableControl

struct FormulaProperties fp
string win, formula
variable currentEpoch, lastSweep
variable currentEpoch, lastSweep, channelType

switch(sva.eventCode)
case 1: // mouse up
Expand All @@ -1436,10 +1437,11 @@ Function WBP_SetVarCombineEpochFormula(sva) : SetVariableControl
formula = sva.sval

WAVE/T WPT = GetWaveBuilderWaveTextParam()
channelType = WBP_GetStimulusType()

lastSweep = GetSetVariable(win, "SetVar_WB_SweepCount_S101") - 1

if(WB_ParseCombinerFormula(formula, lastSweep, fp))
if(WB_ParseCombinerFormula(channelType, formula, lastSweep, fp))
break
endif

Expand Down Expand Up @@ -1469,11 +1471,13 @@ static Function/S WBP_TranslateControlContents(control, direction, data)
strswitch(control)
case "setvar_combine_formula_T6":
if(direction == FROM_PANEL_TO_WAVE)
variable channelType = WBP_GetStimulusType()

struct FormulaProperties fp
WB_FormulaSwitchToStimset(data, fp)
WB_FormulaSwitchToStimset(channelType, data, fp)
return fp.formula
elseif(direction == FROM_WAVE_TO_PANEL)
return WB_FormulaSwitchToShorthand(data)
return WB_FormulaSwitchToShorthand(channelType, data)
endif
break
default:
Expand Down Expand Up @@ -2151,6 +2155,8 @@ static Function/WAVE WBP_ListControlsPerStimulusType(variable epochType)
// additional entries which are not covered by the usual naming scheme
if(epochType == EPOCH_TYPE_CUSTOM)
Make/FREE/T additional = {"Custom epoch wave name"}
elseif(epochType == EPOCH_TYPE_COMBINE)
Make/FREE/T additional = {"Combine epoch formula version"}
else
Make/FREE/T/N=(0) additional
endif
Expand Down
Loading

0 comments on commit 89aadde

Please sign in to comment.