Skip to content

Commit

Permalink
Merge pull request #504 in ENG/mies-igor from ~THOMASB/mies-igor:bugf…
Browse files Browse the repository at this point in the history
…ix/nwb_writing_unassoc_channels to master

* commit 'f83170ca54153cd81a12dd236f9aa6ea5ae92c9e':
  NWB writing: Support unassociated AD channels
  NWB_GetTimeSeriesProperties: Add assertion
  IPNWB#WriteSingleChannel: Use plain TimeSeries for unknown clamp modes
  CreateLBNUnassocKey: Factor out into function

Original-CommitID: 7abbe317b780e5347a36c973cda217f691587b2c
  • Loading branch information
t-b committed Oct 12, 2016
2 parents 370f7d7 + f83170c commit 044ac1c
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 25 deletions.
27 changes: 17 additions & 10 deletions Packages/IPNWB/IPNWB_Writer.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,8 @@ Function InitTimeSeriesProperties(tsp, channelType, clampMode)
// CurrentClampSeries
tsp.missing_fields = "gain;bias_current;bridge_balance;capacitance_compensation"
else
ASSERT(0, "Unknown clamp mode")
// unassociated channel
tsp.missing_fields = ""
endif
elseif(channelType == CHANNEL_TYPE_DAC)
tsp.missing_fields = "gain"
Expand Down Expand Up @@ -438,7 +439,7 @@ Function WriteSingleChannel(locationID, path, p, tsp, [chunkedLayout])
variable chunkedLayout

variable groupID, numPlaces, numEntries, i
string ancestry, str, source, channelTypeStr, group
string ancestry, str, source, channelTypeStr, group, electrodeNumberStr

chunkedLayout = ParamIsDefault(chunkedLayout) ? 0 : !!chunkedLayout

Expand Down Expand Up @@ -479,7 +480,13 @@ Function WriteSingleChannel(locationID, path, p, tsp, [chunkedLayout])
sprintf str, "%s", channelTypeStr
endif

sprintf source, "Device=%s;Sweep=%d;%s;ElectrodeNumber=%d;ElectrodeName=%s", p.device, p.sweep, str, p.electrodeNumber, p.electrodeName
if(IsFinite(p.electrodeNumber))
sprintf electrodeNumberStr, "%d", p.electrodeNumber
else
electrodeNumberStr = "NaN"
endif

sprintf source, "Device=%s;Sweep=%d;%s;ElectrodeNumber=%s;ElectrodeName=%s", p.device, p.sweep, str, electrodeNumberStr, p.electrodeName

if(strlen(p.channelSuffixDesc) > 0 && strlen(p.channelSuffix) > 0)
ASSERT(strsearch(p.channelSuffix, "=", 0) == -1, "channelSuffix must not contain an equals (=) symbol")
Expand All @@ -492,29 +499,29 @@ Function WriteSingleChannel(locationID, path, p, tsp, [chunkedLayout])
H5_WriteTextAttribute(groupID, "comment", group, str=note(p.data), overwrite=1) // human readable version of description
endif

if(p.channelType == CHANNEL_TYPE_ADC)
// only write electrode_name for associated channels
if(IsFinite(p.electrodeNumber) && (p.channelType == CHANNEL_TYPE_DAC || p.channelType == CHANNEL_TYPE_ADC))
sprintf str, "electrode_%s", p.electrodeName
H5_WriteTextDataset(groupID, "electrode_name", str=str, overwrite=1)
endif

if(p.channelType == CHANNEL_TYPE_ADC)
if(p.clampMode == V_CLAMP_MODE)
ancestry = "TimeSeries;PatchClampSeries;VoltageClampSeries"
elseif(p.clampMode == I_CLAMP_MODE)
ancestry = "TimeSeries;PatchClampSeries;CurrentClampSeries"
elseif(p.clampMode == I_EQUAL_ZERO_MODE)
ancestry = "TimeSeries;PatchClampSeries;CurrentClampSeries;IZeroClampSeries"
else
ancestry = "TimeSeries;PatchClampSeries"
ancestry = "TimeSeries"
endif
elseif(p.channelType == CHANNEL_TYPE_DAC)
sprintf str, "electrode_%s", p.electrodeName
H5_WriteTextDataset(groupID, "electrode_name", str=str, overwrite=1)

if(p.clampMode == V_CLAMP_MODE)
ancestry = "TimeSeries;PatchClampSeries;VoltageClampStimulusSeries"
elseif(p.clampMode == I_CLAMP_MODE)
ancestry = "TimeSeries;PatchClampSeries;CurrentClampStimulusSeries"
else
ancestry = "TimeSeries;PatchClampSeries"
ancestry = "TimeSeries"
endif
else
ancestry = "TimeSeries"
Expand Down Expand Up @@ -556,7 +563,7 @@ Function WriteSingleChannel(locationID, path, p, tsp, [chunkedLayout])
H5_WriteTextAttribute(groupID, "unit", group + "/starting_time", str="Seconds", overwrite=1)
endif

if(p.channelType == CHANNEL_TYPE_ADC || p.channelType == CHANNEL_TYPE_TTL)
if(strlen(p.stimSet) > 0 && (p.channelType == CHANNEL_TYPE_ADC || p.channelType == CHANNEL_TYPE_TTL))
// custom data not specified by NWB spec
H5_WriteTextDataset(groupID, "stimulus_description", str=p.stimSet, overwrite=1)
MarkAsCustomEntry(groupID, "stimulus_description")
Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_DataConfiguratorITC.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ static Function DC_DocumentChannelProperty(panelTitle, entry, headstage, channel
endif

// headstage is not finite, so the channel is unassociated
sprintf ua_entry, "%s UNASSOC_%d", entry, channelNumber
ua_entry = CreateLBNUnassocKey(entry, channelNumber)

if(!ParamIsDefault(var))
colData = FindDimLabel(sweepDataLNB, COLS, ua_entry)
Expand Down
12 changes: 12 additions & 0 deletions Packages/MIES/MIES_MiesUtilities.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -2993,3 +2993,15 @@ Function/S GetDefaultElectrodeName(headstage)

return num2str(headstage)
End

/// @brief Create a labnotebook key for unassociated channels
Function/S CreateLBNUnassocKey(setting, channelNumber)
string setting
variable channelNumber

string key

sprintf key, "%s UNASSOC_%d", setting, channelNumber

return key
End
67 changes: 53 additions & 14 deletions Packages/MIES/MIES_NeuroDataWithoutBorders.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ static Function NWB_AppendSweepLowLevel(locationID, panelTitle, ITCDataWave, ITC
WAVE/T textualValues = GetLBTextualValues(panelTitle)
WAVE/T textualKeys = GetLBTextualKeys(panelTitle)

Make/FREE/N=(DimSize(ITCDataWave, COLS)) writtenDataColumns = 0

// comment denotes the introducing comment of the labnotebook entry
// 9b35fdad (Add the clamp mode to the labnotebook for acquired data, 2015-04-26)
WAVE/Z clampMode = GetLastSetting(numericalValues, sweep, "Clamp Mode")
Expand Down Expand Up @@ -501,11 +503,12 @@ static Function NWB_AppendSweepLowLevel(locationID, panelTitle, ITCDataWave, ITC
params.stimset = stimSets[i]

if(IsFinite(adc))
path = "/acquisition/timeseries"
params.channelNumber = ADCs[i]
params.channelType = ITC_XOP_CHANNEL_TYPE_ADC
col = AFH_GetITCDataColumn(ITCChanConfigWave, params.channelNumber, params.channelType)
WAVE params.data = ExtractOneDimDataFromSweep(ITCChanConfigWave, ITCDataWave, col)
path = "/acquisition/timeseries"
params.channelNumber = ADCs[i]
params.channelType = ITC_XOP_CHANNEL_TYPE_ADC
col = AFH_GetITCDataColumn(ITCChanConfigWave, params.channelNumber, params.channelType)
writtenDataColumns[col] = 1
WAVE params.data = ExtractOneDimDataFromSweep(ITCChanConfigWave, ITCDataWave, col)
NWB_GetTimeSeriesProperties(params, tsp)
params.groupIndex = IsFinite(params.groupIndex) ? params.groupIndex : IPNWB#GetNextFreeGroupIndex(locationID, path)
IPNWB#WriteSingleChannel(locationID, path, params, tsp, chunkedLayout=chunkedLayout)
Expand All @@ -514,11 +517,12 @@ static Function NWB_AppendSweepLowLevel(locationID, panelTitle, ITCDataWave, ITC
DEBUGPRINT_ELAPSED(refTime)

if(IsFinite(dac))
path = "/stimulus/presentation"
params.channelNumber = DACs[i]
params.channelType = ITC_XOP_CHANNEL_TYPE_DAC
col = AFH_GetITCDataColumn(ITCChanConfigWave, params.channelNumber, params.channelType)
WAVE params.data = ExtractOneDimDataFromSweep(ITCChanConfigWave, ITCDataWave, col)
path = "/stimulus/presentation"
params.channelNumber = DACs[i]
params.channelType = ITC_XOP_CHANNEL_TYPE_DAC
col = AFH_GetITCDataColumn(ITCChanConfigWave, params.channelNumber, params.channelType)
writtenDataColumns[col] = 1
WAVE params.data = ExtractOneDimDataFromSweep(ITCChanConfigWave, ITCDataWave, col)
NWB_GetTimeSeriesProperties(params, tsp)
params.groupIndex = IsFinite(params.groupIndex) ? params.groupIndex : IPNWB#GetNextFreeGroupIndex(locationID, path)
IPNWB#WriteSingleChannel(locationID, path, params, tsp, chunkedLayout=chunkedLayout)
Expand All @@ -543,10 +547,11 @@ static Function NWB_AppendSweepLowLevel(locationID, panelTitle, ITCDataWave, ITC

listOfStimsets = GetTTLstimSets(numericalValues, textualValues, sweep, i)

params.clampMode = NaN
params.channelNumber = i
params.channelType = ITC_XOP_CHANNEL_TYPE_TTL
col = AFH_GetITCDataColumn(ITCChanConfigWave, params.channelNumber, params.channelType)
params.clampMode = NaN
params.channelNumber = i
params.channelType = ITC_XOP_CHANNEL_TYPE_TTL
col = AFH_GetITCDataColumn(ITCChanConfigWave, params.channelNumber, params.channelType)
writtenDataColumns[col] = 1

WAVE data = ExtractOneDimDataFromSweep(ITCChanConfigWave, ITCDataWave, col)
DFREF dfr = NewFreeDataFolder()
Expand Down Expand Up @@ -580,6 +585,31 @@ static Function NWB_AppendSweepLowLevel(locationID, panelTitle, ITCDataWave, ITC
endfor

DEBUGPRINT_ELAPSED(refTime)

numEntries = DimSize(writtenDataColumns, ROWS)
for(i = 0; i < numEntries; i += 1)

if(writtenDataColumns[i])
continue
endif

// unassociated channel data
// can currently be ADC only
path = "/acquisition/timeseries"
ASSERT(ITCChanConfigWave[i][0] == ITC_XOP_CHANNEL_TYPE_ADC, "Unexpected channel type")
params.clampMode = NaN
params.electrodeNumber = NaN
params.electrodeName = ""
params.channelType = ITCChanConfigWave[i][0]
params.channelNumber = ITCChanConfigWave[i][1]
params.stimSet = ""
NWB_GetTimeSeriesProperties(params, tsp)
WAVE params.data = ExtractOneDimDataFromSweep(ITCChanConfigWave, ITCDataWave, i)
params.groupIndex = IsFinite(params.groupIndex) ? params.groupIndex : IPNWB#GetNextFreeGroupIndex(locationID, path)
IPNWB#WriteSingleChannel(locationID, path, params, tsp, chunkedLayout=chunkedLayout)
endfor

DEBUGPRINT_ELAPSED(refTime)
End

static Function NWB_WriteStimsetTemplateWaves(locationID, stimSet, chunkedLayout)
Expand Down Expand Up @@ -632,6 +662,15 @@ static Function NWB_GetTimeSeriesProperties(p, tsp)

IPNWB#InitTimeSeriesProperties(tsp, p.channelType, p.clampMode)

// unassociated channel
if(!IsFinite(p.clampMode))
return NaN
endif

if(strlen(tsp.missing_fields) > 0)
ASSERT(IsFinite(p.electrodeNumber), "Expected finite electrode number with non empty \"missing_fields\"")
endif

if(p.channelType == ITC_XOP_CHANNEL_TYPE_ADC)
if(p.clampMode == V_CLAMP_MODE)
// VoltageClampSeries: datasets
Expand Down

0 comments on commit 044ac1c

Please sign in to comment.