Skip to content

AB: Add column in experiment information list box for sweep time #2407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
50 changes: 45 additions & 5 deletions Packages/MIES/MIES_AnalysisBrowser.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,42 @@ static Function/S AB_GetSettingNumFiniteVals(WAVE wv, string device, variable sw
return num2str(V_npnts)
End

/// @brief Returns the Session Start Time as ISO8601 timestamp string
/// The required data must have been loaded before.
///
/// @param device device name
/// @param firstSweepNo first sweep number of experiment
/// @param dataFolder dataFolder reference of the specific loaded experiment data in AB
/// @param fileType file type @ref AnalysisBrowserFileTypes
///
/// @returns session Start Time as ISO8601 timestamp string, an empty string if this information is not present
static Function/S AB_GetSessionStartTime(string device, variable firstSweepNo, string dataFolder, string fileType)

string sessionStartTime

strswitch(fileType)
case ANALYSISBROWSER_FILE_TYPE_IGOR:
WAVE textualValues = GetAnalysLBTextualValues(dataFolder, device)
sessionStartTime = GetLastSettingTextIndep(textualValues, firstSweepNo, HIGH_PREC_SWEEP_START_KEY, DATA_ACQUISITION_MODE)
if(IsEmpty(sessionStartTime))
WAVE/I sweeps = GetAnalysisChannelSweepWave(dataFolder, device)
if(!DimSize(sweeps, ROWS))
return ""
endif
DFREF sweepConfigDFR = GetAnalysisDeviceConfigFolder(dataFolder, device)
WAVE firstSweepConfig = sweepConfigDFR:$GetConfigWaveName(sweeps[0])
sessionStartTime = GetISO8601TimeStamp(secondsSinceIgorEpoch = LocalTimeToUTC(CreationDate(firstSweepConfig)))
endif
return sessionStartTime
case ANALYSISBROWSER_FILE_TYPE_NWBv1:
case ANALYSISBROWSER_FILE_TYPE_NWBv2: // intended fallthrough
sessionStartTime = ROStr(GetAnalysisExpSessionStartTime(dataFolder))
return sessionStartTime
default:
ASSERT(0, "invalid file type")
endswitch
End

/// @brief Creates list-view for AnalysisBrowser
///
/// Depends on LabNoteBook to be loaded prior to call.
Expand Down Expand Up @@ -497,16 +533,17 @@ static Function AB_FillListWave(string diskLocation, string fileName, string dev

ASSERT(WaveExists(sweepNums), "sweepNums wave is empty.")

WAVE numericalValues = GetAnalysLBNumericalValues(dataFolder, device)
WAVE textualValues = GetAnalysLBTextualValues(dataFolder, device)

EnsureLargeEnoughWave(list, indexShouldExist = index, dimension = ROWS)
list[index][%device][0] = device

numWaves = GetNumberFromWaveNote(sweepNums, NOTE_INDEX)

list[index][%'#sweeps'][0] = num2istr(numWaves)
index += 1

WAVE numericalValues = GetAnalysLBNumericalValues(dataFolder, device)
WAVE textualValues = GetAnalysLBTextualValues(dataFolder, device)
list[index][%'#sweeps'][0] = num2istr(numWaves)
list[index][%'start time'][0] = AB_GetSessionStartTime(device, sweepNums[0], dataFolder, fileType)
index += 1

for(i = 0; i < numWaves; i += 1)
EnsureLargeEnoughWave(list, indexShouldExist = index, dimension = ROWS)
Expand Down Expand Up @@ -754,6 +791,9 @@ static Function AB_LoadSweepsConfigFromNWB(string discLocation, string dataFolde
WAVE/T stimulus = GetAnalysisChannelStimWave(dataFolder, device)
AB_StoreChannelsBySweep(h5_fileID, nwbVersion, channelList, sweeps, stimulus)

SVAR sessionStartTime = $GetAnalysisExpSessionStartTime(dataFolder)
sessionStartTime = NWB_ReadSessionStartTimeImpl(h5_fileID)

// close hdf5 file
H5_CloseFile(h5_fileID)
End
Expand Down
79 changes: 38 additions & 41 deletions Packages/MIES/MIES_AnalysisBrowser_Macro.ipf

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Packages/MIES/MIES_Constants.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Constant DAQ_CONFIG_WAVE_VERSION = 3
Constant DA_EPHYS_PANEL_VERSION = 66
Constant DATA_SWEEP_BROWSER_PANEL_VERSION = 52
Constant WAVEBUILDER_PANEL_VERSION = 14
Constant ANALYSISBROWSER_PANEL_VERSION = 8
Constant ANALYSISBROWSER_PANEL_VERSION = 9
Constant PSX_PLOT_PANEL_VERSION = 1

/// Version of the stimset wave note
Expand Down
6 changes: 6 additions & 0 deletions Packages/MIES/MIES_GlobalStringAndVariableAccess.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,12 @@ Function/S GetNI_TTLTaskID(string device)
return GetNVARAsString(GetDevicePath(device), "NI_TTL_taskID", initialValue = NaN)
End

/// @brief Return the Analysis Browser experiment session start time (only used for NWB type experiments)
Function/S GetAnalysisExpSessionStartTime(string dataFolder)

return GetSVARAsString(GetAnalysisExpFolder(dataFolder), "sessionStartTime", initialValue = "")
End

/// @brief Return the experiment session start time in NWB-speech
///
/// This is the time when the last device was locked.
Expand Down
4 changes: 2 additions & 2 deletions Packages/MIES/MIES_LogbookViewer.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1228,8 +1228,8 @@ static Function LBV_LimitXRangeToSelected(string browser)
endif

// convert to local time zone
first += date2secs(-1, -1, -1)
last += date2secs(-1, -1, -1)
first = UTCTimeToLocal(first)
last = UTCTimeToLocal(last)

ASSERT(IsFinite(first) && IsFinite(last), "Invalid first/last")
else
Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_MiesUtilities_Sweep.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ threadsafe static Function UpgradeSweepWave(WAVE sweepWave, WAVE/T componentName
// we also have to preserve the original modification time
ASSERT_TS(!CmpStr(WaveUnits(sweepWave, ROWS), "ms"), "Expected ms as wave units")
modTimeStr = StringByKeY("MODTIME", WaveInfo(sweepWave, 0))
sweepCreationTimeUTC = str2num(modTimeStr) - date2secs(-1, -1, -1)
sweepCreationTimeUTC = LocalTimeToUTC(str2num(modTimeStr))
sweepCreationTimeUTC -= DimSize(sweepWave, ROWS) * DimDelta(sweepWave, ROWS) * MILLI_TO_ONE

oldSweepName = UniqueWaveName(sweepWaveDFR, sweepWaveName + "_preUpgrade")
Expand Down
16 changes: 14 additions & 2 deletions Packages/MIES/MIES_NeuroDataWithoutBorders.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,23 @@ static Function NWB_AddSpecifications(variable fileID, variable nwbVersion)
WriteSpecifications(fileID)
End

Function/S NWB_ReadSessionStartTimeImpl(variable fileID)

string str

str = ReadTextDataSetAsString(fileID, "/session_start_time")
if(!CmpStr(str, IPNWB_PLACEHOLDER))
return ""
endif

return str
End

static Function NWB_ReadSessionStartTime(variable fileID)

string str = ReadTextDataSetAsString(fileID, "/session_start_time")
string str = NWB_ReadSessionStartTimeImpl(fileID)

ASSERT(cmpstr(str, IPNWB_PLACEHOLDER), "Could not read session_start_time back from the NWB file")
ASSERT(!IsEmpty(str), "Could not read session_start_time back from the NWB file")

return ParseISO8601TimeStamp(str)
End
Expand Down
14 changes: 13 additions & 1 deletion Packages/MIES/MIES_Utilities_Time.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,22 @@ Function/S GetTimeStamp([variable secondsSinceIgorEpoch, variable humanReadable]
return Secs2Date(secondsSinceIgorEpoch, -2, "_") + "_" + ReplaceString(":", Secs2Time(secondsSinceIgorEpoch, 3), "")
End

/// @brief Convert UTC time in Local time
threadsafe Function UTCTimeToLocal(variable utcTime)

return utcTime + date2secs(-1, -1, -1)
End

/// @brief Convert Local time in secs to UTC
threadsafe Function LocalTimeToUTC(variable localTime)

return localTime - date2secs(-1, -1, -1)
End

/// @brief Return the seconds, including fractional part, since Igor Pro epoch (1/1/1904) in UTC time zone
threadsafe Function DateTimeInUTC()

return DateTime - date2secs(-1, -1, -1)
return LocalTimeToUTC(DateTime)
End

/// @brief Return a string in ISO 8601 format with timezone UTC
Expand Down
8 changes: 6 additions & 2 deletions Packages/MIES/MIES_WaveDataFolderGetters.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
/// The latter ones are only useful if you need to know if the folder exists.
/// - Modifying wave getter functions might require to introduce wave versioning, see @ref WaveVersioningSupport

static Constant ANALYSIS_BROWSER_LISTBOX_WAVE_VERSION = 1
static Constant ANALYSIS_BROWSER_LISTBOX_WAVE_VERSION = 2
static Constant ANALYSIS_BROWSER_FOLDER_LISTBOX_WAVE_VERSION = 1
static Constant ANALYSIS_BROWSER_FOLDERCOL_LISTBOX_WAVE_VERSION = 1
static Constant ANALYSIS_BROWSER_FOLDERSEL_LISTBOX_WAVE_VERSION = 1
static Constant NUM_COLUMNS_LIST_WAVE = 12
static Constant NUM_COLUMNS_LIST_WAVE = 14
static StrConstant WAVE_NOTE_LAYOUT_KEY = "WAVE_LAYOUT_VERSION"

static Constant WAVE_TYPE_NUMERICAL = 0x1
Expand Down Expand Up @@ -5760,6 +5760,10 @@ Function/WAVE GetExperimentBrowserGUIList()
SetDimLabel COLS, 9, 'set count', wv
SetDimLabel COLS, 10, '#DAC', wv
SetDimLabel COLS, 11, '#ADC', wv
SetDimLabel COLS, 12, 'start time', wv
// the last columns is a dummy column that reserves space
// where the scrollbar appears in the listbox. Otherwise the scrollbar covers data.
SetDimLabel COLS, 13, $"", wv

SetNumberInWaveNote(wv, NOTE_INDEX, 0)
SetWaveVersion(wv, versionOfWave)
Expand Down
Loading