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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Packages/MIES/MIES_AnalysisFunctions_PatchSeq.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -3031,7 +3031,7 @@ static Function [WAVE data, variable emptySCI] PSQ_DS_GetLabnotebookData(WAVE nu
WAVE/Z dataCurrentSCI = GetLastSettingIndepEachSCI(numericalValues, sweepNo, key, headstage, UNKNOWN_MODE)
break
default:
FATAL_ERROR("Unsupported headstageContigencyMode")
FATAL_ERROR("Unsupported headstageContingencyMode")
endswitch
break
endswitch
Expand All @@ -3056,7 +3056,7 @@ static Function [WAVE data, variable emptySCI] PSQ_DS_GetLabnotebookData(WAVE nu
idx = INDEP_HEADSTAGE
break
default:
FATAL_ERROR("Unsupported headstageContigencyMode")
FATAL_ERROR("Unsupported headstageContingencyMode")
endswitch

WAVE dataRhSuAd = ListToNumericWave(dataRhSuAdLBN[idx], ";")
Expand Down
18 changes: 18 additions & 0 deletions Packages/MIES/MIES_Cache.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,24 @@ threadsafe Function/S CA_GenKeyGetActiveChannels(WAVE numericalValues, WAVE text
return num2istr(crc) + version
End

/// @brief Cache key generator for LBN index cache
threadsafe Function/S CA_CreateLBIndexCacheKey(WAVE values)

string name = GetWavesDataFolder(values, 2)
ASSERT_TS(!isEmpty(name), "Invalid path to wave, free waves won't work.")

return name + "_IndexCache"
End

/// @brief Cache key generator for LBN row cache
threadsafe Function/S CA_CreateLBRowCacheKey(WAVE values)

string name = GetWavesDataFolder(values, 2)
ASSERT_TS(!isEmpty(name), "Invalid path to wave, free waves won't work.")

return name + "_RowCache"
End

/// @brief Cache key generator for Logbook sortedKeyWave
threadsafe Function/S CA_GenKeyLogbookSortedKeys(WAVE keys)

Expand Down
33 changes: 17 additions & 16 deletions Packages/MIES/MIES_Constants.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -979,22 +979,23 @@ Constant DA_EPHYS_PANEL_PRESSURE_AUTO = 0
Constant DA_EPHYS_PANEL_PRESSURE_MANUAL = 1
Constant DA_EPHYS_PANEL_PRESSURE_USER = 2

StrConstant PULSE_START_TIMES_KEY = "Pulse Train Pulses"
StrConstant PULSE_TO_PULSE_LENGTH_KEY = "Pulse To Pulse Length"
StrConstant HIGH_PREC_SWEEP_START_KEY = "High precision sweep start"
StrConstant STIMSET_SCALE_FACTOR_KEY = "Stim Scale Factor"
StrConstant STIMSET_WAVE_NOTE_KEY = "Stim Wave Note"
StrConstant EPOCHS_ENTRY_KEY = "Epochs"
StrConstant CLAMPMODE_ENTRY_KEY = "Clamp Mode"
StrConstant TP_AMPLITUDE_VC_ENTRY_KEY = "TP Amplitude VC"
StrConstant TP_AMPLITUDE_IC_ENTRY_KEY = "TP Amplitude IC"
StrConstant PULSE_START_INDICES_KEY = "Pulse Train Pulse Start Indices"
StrConstant PULSE_END_INDICES_KEY = "Pulse Train Pulse End Indices"
StrConstant INFLECTION_POINTS_INDEX_KEY = "Inflection Points Indices"
StrConstant EPOCH_LENGTH_INDEX_KEY = "Epoch Length Indices"
StrConstant STIMSET_SIZE_KEY = "Stimset Size"
StrConstant STIMSET_ERROR_KEY = "Wavebuilder Error"
StrConstant AUTOBIAS_PERC_KEY = "Autobias %"
StrConstant PULSE_START_TIMES_KEY = "Pulse Train Pulses"
StrConstant PULSE_TO_PULSE_LENGTH_KEY = "Pulse To Pulse Length"
StrConstant HIGH_PREC_SWEEP_START_KEY = "High precision sweep start"
StrConstant STIMSET_SCALE_FACTOR_KEY = "Stim Scale Factor"
StrConstant STIMSET_WAVE_NOTE_KEY = "Stim Wave Note"
StrConstant EPOCHS_ENTRY_KEY = "Epochs"
StrConstant CLAMPMODE_ENTRY_KEY = "Clamp Mode"
StrConstant TP_AMPLITUDE_VC_ENTRY_KEY = "TP Amplitude VC"
StrConstant TP_AMPLITUDE_IC_ENTRY_KEY = "TP Amplitude IC"
StrConstant PULSE_START_INDICES_KEY = "Pulse Train Pulse Start Indices"
StrConstant PULSE_END_INDICES_KEY = "Pulse Train Pulse End Indices"
StrConstant INFLECTION_POINTS_INDEX_KEY = "Inflection Points Indices"
StrConstant EPOCH_LENGTH_INDEX_KEY = "Epoch Length Indices"
StrConstant STIMSET_SIZE_KEY = "Stimset Size"
StrConstant STIMSET_ERROR_KEY = "Wavebuilder Error"
StrConstant AUTOBIAS_PERC_KEY = "Autobias %"
StrConstant SWEEP_EPOCH_VERSION_ENTRY_KEY = "Epochs Version"

Constant WAVEBUILDER_STATUS_ERROR = 1

Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_DAEphys.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -4025,7 +4025,7 @@ static Function DAP_AddUserComment(string device)
return NaN
endif

comment = DAG_GetTextualValue(device, "SetVar_DataAcq_Comment")
comment = GetSetVariableString(device, "SetVar_DataAcq_Comment")

if(isEmpty(comment))
return NaN
Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_Epochs.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ Function EP_WriteEpochInfoIntoSweepSettings(string device, variable sweepNo, var
endif
endfor

DC_DocumentChannelProperty(device, "Epochs Version", INDEP_HEADSTAGE, NaN, NaN, var = SWEEP_EPOCH_VERSION)
DC_DocumentChannelProperty(device, SWEEP_EPOCH_VERSION_ENTRY_KEY, INDEP_HEADSTAGE, NaN, NaN, var = SWEEP_EPOCH_VERSION)
End

/// @brief Convert the epochs wave layer given by `channel` and `channelType` to a string suitable for storing the labnotebook
Expand Down
137 changes: 106 additions & 31 deletions Packages/MIES/MIES_ExperimentDocumentation.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,56 @@

/// @brief Add numerical/textual entries to the labnotebook
///
/// This function adds one or more new entries to the LBN.
/// The new entries are given through a vals, keys combination. Depending on the type of
/// vals the textual or numerical LBN is targeted. The function determines the correct
/// target LBN automatically through sweepNo and device.
///
/// The entrySourceType specifies to which logical block of the LBN the entries get added
///
/// Specification of vals and keys:
/// Multiple entries can be written with one call.
/// vals: text or numerical WAVE of size (1, numberOfNewEntries, LABNOTEBOOK_LAYER_COUNT)
/// The layers index the target headstage or INDEP_HEADSTAGE.
/// The elements of the wave must be filled with the values that should be written.
/// Based on the column number key/value pairs are defined from vals/keys.
/// numeric vals waves must be initialized with NaN
/// keys: text WAVE in one of three possible layouts:
/// - size (1, numberOfNewEntries)
/// one key is specified per column
/// - size (3, numberOfNewEntries)
/// row 0: key
/// row 1: LBN unit
/// row 2: LNB tolerance
/// - size (6, numberOfNewEntries)
/// row 0: key
/// row 1: unit
/// row 2: tolerance
/// row 3: description
/// row 4: Headstage Contingency
/// row 5: ClampMode
/// optionally the keys wave may have a layer size of 1.
///
/// Key specification:
/// Duplicated keys are not allowed and will give an error.
///
/// Correct filling of entry keys and corresponding values:
/// for associated DA/AD channels use the regular key and the headstage as layer for vals
/// for unassociated DA/AD channels create the correct key with CreateLBNUnassocKey with
/// layer INDEP_HEADSTAGE in vals
/// for some TTL channels the correct key is created through CreateTTLChannelLBNKey with layer INDEP_HEADSTAGE in vals
///
/// In the LBN one new row is added at the end where all entries that should be written are placed.
/// (As no keys are duplicated, all data can be written to one row)
/// LBN columns for new keys are created automatically.
///
/// If insertAsPostProc is set to 1:
/// Instead of the above: In the LBN a new row is inserted after the block specified by sweepNo/entrySourceType.
/// The new entries are placed in this row and implicitly an entry with key "PostProcessed"
/// and value "1" or 1 respectively is set in the same row.
///
/// It is recommended to gather all entries to be written in keys/values and call ED_AddEntriesToLabnotebook then once.
///
/// @see ED_createTextNotes, ED_createWaveNote
Function ED_AddEntriesToLabnotebook(WAVE vals, WAVE/T keys, variable sweepNo, string device, variable entrySourceType)

Expand All @@ -37,12 +87,59 @@ End

static Function ED_CheckValuesAndKeys(WAVE vals, WAVE keys)

string msg

ASSERT(DimSize(vals, ROWS) == 1, "Mismatched row count")
ASSERT(DimSize(vals, COLS) == DimSize(keys, COLS), "Mismatched column count")
ASSERT(DimSize(vals, LAYERS) <= LABNOTEBOOK_LAYER_COUNT, "Mismatched layer count")

ASSERT(DimSize(keys, ROWS) == 1 || DimSize(keys, ROWS) == 3 || DimSize(keys, ROWS) == 6, "Mismatched row count")
ASSERT(DimSize(keys, LAYERS) <= 1, "Mismatched layer count")

if(DimSize(keys, COLS) == 1)
return NaN
endif
Duplicate/FREE/RMD=[0][][0][0] keys, checkKeysForDupes
Redimension/N=(DimSize(checkKeysForDupes, COLS))/E=1 checkKeysForDupes
if(SearchForDuplicates(checkKeysForDupes))
FindDuplicates/Z/FREE/DT=dups checkKeysForDupes
wfprintf msg, "%s", dups
sprintf msg, "Keywave contains duplicate keys: %s", msg
FATAL_ERROR(msg)
endif
End

static Function ED_InitNewRow(WAVE values, variable rowIndex, variable sweepNo, variable entrySourceType, variable acqState)

variable timestamp
string timestampStr

if(IsTextWave(values))
WAVE/T valuesT = values
valuesT[rowIndex][0][] = num2istr(sweepNo)
valuesT[rowIndex][3][] = num2istr(entrySourceType)

valuesT[rowIndex][4][] = num2istr(acqState)

// store the current time in a variable first
// so that all layers have the same timestamp
timestampStr = num2strHighPrec(DateTime, precision = 3)
valuesT[rowIndex][1][] = timestampStr
timestampStr = num2strHighPrec(DateTimeInUTC(), precision = 3)
valuesT[rowIndex][2][] = timestampStr
else
values[rowIndex][0][] = sweepNo
values[rowIndex][3][] = entrySourceType

values[rowIndex][4][] = acqState

// store the current time in a variable first
// so that all layers have the same timestamp
timestamp = DateTime
values[rowIndex][1][] = timestamp
timestamp = DateTimeInUTC()
values[rowIndex][2][] = timestamp
endif
End

/// @brief Add textual entries to the logbook
Expand All @@ -62,7 +159,6 @@ End
static Function ED_createTextNotes(WAVE/T incomingTextualValues, WAVE/T incomingTextualKeys, variable sweepNo, variable entrySourceType, variable logbookType, [string device])

variable rowIndex, numCols, i, lastValidIncomingLayer, state
string timestamp

if(ParamIsDefault(device))
ASSERT(logbookType == LBT_RESULTS, "Invalid logbook type")
Expand All @@ -80,17 +176,7 @@ static Function ED_createTextNotes(WAVE/T incomingTextualValues, WAVE/T incoming
[WAVE indizes, rowIndex] = ED_FindIndizesAndRedimension(incomingTextualKeys, incomingTextualValues, keys, values, logbookType)
ASSERT(WaveExists(indizes), "Missing indizes")

values[rowIndex][0][] = num2istr(sweepNo)
values[rowIndex][3][] = num2istr(entrySourceType)

values[rowIndex][4][] = num2istr(state)

// store the current time in a variable first
// so that all layers have the same timestamp
timestamp = num2strHighPrec(DateTime, precision = 3)
values[rowIndex][1][] = timestamp
timestamp = num2strHighPrec(DateTimeInUTC(), precision = 3)
values[rowIndex][2][] = timestamp
ED_InitNewRow(values, rowIndex, sweepNo, entrySourceType, state)

WAVE valuesDat = ExtractLogbookSliceTimeStamp(values)
EnsureLargeEnoughWave(valuesDat, indexShouldExist = rowIndex, dimension = ROWS)
Expand All @@ -113,7 +199,7 @@ static Function ED_createTextNotes(WAVE/T incomingTextualValues, WAVE/T incoming
SetNumberInWaveNote(values, NOTE_INDEX, rowIndex + 1)
End

static Function ED_ParseHeadstageContigencyMode(string str)
static Function ED_ParseHeadstageContingencyMode(string str)

if(!cmpstr(str, "ALL"))
return (HCM_DEPEND | HCM_INDEP)
Expand All @@ -126,7 +212,7 @@ static Function ED_ParseHeadstageContigencyMode(string str)
return HCM_EMPTY
End

static Function/S ED_HeadstageContigencyModeToString(variable mode)
static Function/S ED_HeadstageContingencyModeToString(variable mode)

switch(mode)
case HCM_INDEP:
Expand All @@ -142,7 +228,7 @@ static Function/S ED_HeadstageContigencyModeToString(variable mode)
endswitch
End

/// @brief Return the headstage contigency mode for values
/// @brief Return the headstage contingency mode for values
static Function ED_GetHeadstageContingency(WAVE values)

if(IsTextWave(values))
Expand Down Expand Up @@ -182,7 +268,7 @@ End
/// @param logbookType one of @ref LogbookTypes
static Function ED_createWaveNotes(WAVE incomingNumericalValues, WAVE/T incomingNumericalKeys, variable sweepNo, variable entrySourceType, variable logbookType, [string device])

variable rowIndex, numCols, lastValidIncomingLayer, i, timestamp, state
variable rowIndex, numCols, lastValidIncomingLayer, i, state

if(ParamIsDefault(device))
ASSERT(logbookType == LBT_RESULTS, "Invalid logbook type")
Expand All @@ -201,17 +287,7 @@ static Function ED_createWaveNotes(WAVE incomingNumericalValues, WAVE/T incoming
[WAVE indizes, rowIndex] = ED_FindIndizesAndRedimension(incomingNumericalKeys, incomingNumericalValues, keys, values, logbookType)
ASSERT(WaveExists(indizes), "Missing indizes")

values[rowIndex][0][] = sweepNo
values[rowIndex][3][] = entrySourceType

values[rowIndex][4][] = state

// store the current time in a variable first
// so that all layers have the same timestamp
timestamp = DateTime
values[rowIndex][1][] = timestamp
timestamp = DateTimeInUTC()
values[rowIndex][2][] = timestamp
ED_InitNewRow(values, rowIndex, sweepNo, entrySourceType, state)

WAVE valuesDat = ExtractLogbookSliceTimeStamp(values)
EnsureLargeEnoughWave(valuesDat, indexShouldExist = rowIndex, dimension = ROWS, initialValue = NaN)
Expand Down Expand Up @@ -493,11 +569,10 @@ End
/// @retval rowIndex returns the row index into values at which the new values should be written
static Function [WAVE colIndizes, variable rowIndex] ED_FindIndizesAndRedimension(WAVE/T incomingKey, WAVE incomingValues, WAVE/T key, WAVE values, variable logbookType)

variable numCols, numKeyRows, numKeyCols, i, j, numAdditions, idx
variable numCols, numKeyCols, i, j, numAdditions, idx
variable lastValidIncomingKeyRow, descIndex, isUserEntry, headstageCont, headstageContDesc, isUnAssoc
string msg, searchStr

numKeyRows = DimSize(key, ROWS)
numKeyCols = DimSize(key, COLS)
lastValidIncomingKeyRow = DimSize(incomingKey, ROWS) - 1

Expand Down Expand Up @@ -596,14 +671,14 @@ static Function [WAVE colIndizes, variable rowIndex] ED_FindIndizesAndRedimensio
// check for correct headstage contingency
Duplicate/FREE/RMD=[0][i][*] incomingValues, valuesSlice
headstageCont = ED_GetHeadstageContingency(valuesSlice)
headstageContDesc = ED_ParseHeadstageContigencyMode(desc[%HeadstageContingency][descIndex])
headstageContDesc = ED_ParseHeadstageContingencyMode(desc[%HeadstageContingency][descIndex])

if(isUnAssoc)
headstageContDesc = HCM_INDEP
endif

if(headstageCont != HCM_EMPTY && !(headstageCont & headstageContDesc))
sprintf msg, "Headstage contingency for entry \"%s\": stock: \"%s\", incoming: \"%s\"", searchStr, desc[%HeadstageContingency][descIndex], ED_HeadstageContigencyModeToString(headstageCont)
sprintf msg, "Headstage contingency for entry \"%s\": stock: \"%s\", incoming: \"%s\"", searchStr, desc[%HeadstageContingency][descIndex], ED_HeadstageContingencyModeToString(headstageCont)
BUG(msg)
endif

Expand Down
11 changes: 6 additions & 5 deletions Packages/MIES/MIES_LogbookViewer.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,16 @@ Function/WAVE LBV_GetAllLogbookParamNames(WAVE/Z/T textualValues, WAVE/Z/T numer

key = CA_GetLabnotebookNamesKey(textualValues, numericalValues)

WAVE/Z result = CA_TryFetchingEntryFromCache(key)
WAVE/Z/WAVE resultEncap = CA_TryFetchingEntryFromCache(key)

if(!WaveExists(result))
WAVE result = LBV_GetAllLogbookParamNames_NoCache(textualValues, numericalValues)
if(!WaveExists(resultEncap))
WAVE/Z result = LBV_GetAllLogbookParamNames_NoCache(textualValues, numericalValues)
Make/FREE/WAVE resultEncap = {result}

CA_StoreEntryIntoCache(key, result)
CA_StoreEntryIntoCache(key, resultEncap)
endif

return result
return resultEncap[0]
End

static Function/WAVE LBV_GetAllLogbookParamNames_NoCache(WAVE/Z/T textualValues, WAVE/Z/T numericalValues)
Expand Down
Loading