diff --git a/Packages/MIES/MIES_Epochs.ipf b/Packages/MIES/MIES_Epochs.ipf index 563bddd354..19f5af5050 100644 --- a/Packages/MIES/MIES_Epochs.ipf +++ b/Packages/MIES/MIES_Epochs.ipf @@ -310,7 +310,7 @@ static Function EP_AddEpochsFromStimSetNote(string device, STRUCT DataConfigurat variable epochCount, totalDuration, poissonDistribution, cycleNr variable epochNr, pulseNr, numPulses, epochType, flipping, pulseToPulseLength, stimEpochAmplitude, amplitude, i, j variable logicalPulseOffset - variable stimsetSize + variable stimsetSize, stimepochOffset, logicalStimepochOffset variable pulseDuration, halfCycleNr, hasFullCycle, hasIncompleteCycleAtStart, hasIncompleteCycleAtEnd variable subsubEpochBegin, subsubEpochEnd, numInflectionPoints, incompleteCycleNr string type @@ -320,6 +320,9 @@ static Function EP_AddEpochsFromStimSetNote(string device, STRUCT DataConfigurat string shortNameEpTypePTBaseline string stimNote = note(stimset) + WAVE/WAVE dataWave = GetDAQDataWave(device, DATA_ACQUISITION_MODE) + WAVE data = dataWave[0] + ASSERT(!IsEmpty(stimNote), "Stimset note is empty.") stopCollectionPoint = ROVar(GetStopCollectionPoint(device)) @@ -327,29 +330,58 @@ static Function EP_AddEpochsFromStimSetNote(string device, STRUCT DataConfigurat scale = channelType == XOP_CHANNEL_TYPE_TTL ? 1 : scale stimsetSize = DimSize(stimset, ROWS) - stimsetEnd = min(stimsetBegin + setLength, (stopCollectionPoint - 1) * s.samplingInterval) - epSweepTags = ReplaceStringByKey(EPOCH_TYPE_KEY, "", "Stimset", STIMSETKEYNAME_SEP, EPOCHNAME_SEP) - EP_AddEpoch(device, channel, channelType, stimsetBegin, stimsetEnd, epSweepTags, EPOCH_SN_STIMSET, 0) - epochCount = WB_GetWaveNoteEntryAsNumber(stimNote, STIMSET_ENTRY, key="Epoch Count") ASSERT(IsFinite(epochCount), "Could not find Epoch Count in stimset wave note.") + flipping = WB_GetWaveNoteEntryAsNumber(stimNote, STIMSET_ENTRY, key = "Flip") - Make/FREE/D/N=(epochCount) duration, sweepOffset + Make/FREE/D/N=(epochCount) stimepochDuration, stimepochOffsetTime, stimEpochLength + stimepochLength[] = WB_GetWaveNoteEntryAsNumber(stimNote, EPOCH_ENTRY, sweep = sweep, epoch = p, key = EPOCH_LENGTH_INDEX_KEY) + for(epochNr = 0; epochNr < epochCount; epochNr += 1) + logicalStimepochOffset = flipping ? stimsetSize - stimepochOffset - stimepochLength[epochNr] : stimepochOffset + stimepochOffsetTime[epochNr] = limit(IndexAfterDecimation(logicalStimepochOffset, s.decimationFactor) + 1, 0, Inf) * s.samplingInterval + stimepochOffset += stimepochLength[epochNr] + endfor - duration[] = WB_GetWaveNoteEntryAsNumber(stimNote, EPOCH_ENTRY, key="Duration", sweep=sweep, epoch=p) - duration *= MILLI_TO_MICRO - totalDuration = sum(duration) + for(epochNr = 0; epochNr < epochCount; epochNr += 1) + if(flipping) + if(epochNr > 0) + stimepochDuration[epochNr] = stimepochOffsetTime[epochNr - 1] - stimepochOffsetTime[epochNr] + else + stimepochDuration[epochNr] = (IndexAfterDecimation(stimepochLength[epochNr] + 0.5, s.decimationFactor) + 0) * s.samplingInterval + endif + else + if(epochNr < epochCount - 1) + stimepochDuration[epochNr] = stimepochOffsetTime[epochNr + 1] - stimepochOffsetTime[epochNr] + else + stimepochDuration[epochNr] = (IndexAfterDecimation(stimepochOffset, s.decimationFactor) + 1) * s.samplingInterval - stimepochOffsetTime[epochNr] + endif + endif + ASSERT(stimepochDuration[epochNr] > 0, "Epoch duration must be greater than zero") + endfor + totalDuration = sum(stimepochDuration) ASSERT(IsFinite(totalDuration), "Expected finite totalDuration") ASSERT(IsFinite(stimsetBegin), "Expected finite stimsetBegin") + stimsetEndLogical = stimsetBegin + totalDuration + stimsetEnd = min(stimsetBegin + setLength, stopCollectionPoint * s.samplingInterval) +// This assertion should be valid if the acquisition was not aborted early. +// ASSERT(stimsetEndLogical == stimsetEnd, "Logical stimset end is inconsistent with actual stimset end") - if(epochCount > 1) - sweepOffset[0] = 0 - sweepOffset[1,] = sweepOffset[p - 1] + duration[p - 1] - endif + epSweepTags = ReplaceStringByKey(EPOCH_TYPE_KEY, "", "Stimset", STIMSETKEYNAME_SEP, EPOCHNAME_SEP) + EP_AddEpoch(device, channel, channelType, stimsetBegin, stimsetEnd, epSweepTags, EPOCH_SN_STIMSET, 0) - flipping = WB_GetWaveNoteEntryAsNumber(stimNote, STIMSET_ENTRY, key = "Flip") + // If decimationFactor < 1 then stimsetEndLogical < stimsetEnd (if acquisition was not stopped early) + // because the round function in the decimation shifts effectively the stimset by 0.5 * WAVEBUILDER_MIN_SAMPINT to the left. + // Thus, after decimation the end is shifted to the left as well, potentially leaving remaining sample points in the DA wave. + // + // Case 2: stimsets with multiple sweeps where each sweep has a different length (due to delta mechanism) + // result in 2D stimset waves where all sweeps have the same length + // therefore we must add a baseline epoch after all defined epochs + if(stimsetEnd > stimsetEndLogical) + tags = ReplaceStringByKey(EPOCH_TYPE_KEY, "", EPOCH_BASELINE_REGION_KEY, STIMSETKEYNAME_SEP, EPOCHNAME_SEP) + EP_AddEpoch(device, channel, channelType, stimsetEndLogical, stimsetEnd, tags, EPOCH_SN_STIMSET + "_" + EPOCH_SN_STIMSETBLTRAIL, 1) + endif epSweepTags = ReplaceStringByKey(EPOCH_TYPE_KEY, "", "Epoch", STIMSETKEYNAME_SEP, EPOCHNAME_SEP) @@ -358,14 +390,9 @@ static Function EP_AddEpochsFromStimSetNote(string device, STRUCT DataConfigurat epochType = WB_ToEpochType(type) stimEpochAmplitude = WB_GetWaveNoteEntryAsNumber(stimNote, EPOCH_ENTRY, key="Amplitude", sweep=sweep, epoch=epochNr) amplitude = scale * stimEpochAmplitude - if(flipping) - // in case of oodDAQ cutOff stimsetEndLogical can be greater than stimsetEnd, thus epochEnd can be greater than stimsetEnd - epochEnd = stimsetEndLogical - sweepOffset[epochNr] - epochBegin = epochEnd - duration[epochNr] - else - epochBegin = sweepOffset[epochNr] + stimsetBegin - epochEnd = epochBegin + duration[epochNr] - endif + + epochBegin = stimepochOffsetTime[epochNr] + stimsetBegin + epochEnd = epochBegin + stimepochDuration[epochNr] if(epochBegin >= stimsetEnd) // sweep epoch starts beyond stimset end @@ -595,14 +622,6 @@ static Function EP_AddEpochsFromStimSetNote(string device, STRUCT DataConfigurat endif endfor - - // stimsets with multiple sweeps where each sweep has a different length (due to delta mechanism) - // result in 2D stimset waves where all sweeps have the same length - // therefore we must add a baseline epoch after all defined epochs - if(stimsetEnd > stimsetEndLogical) - tags = ReplaceStringByKey(EPOCH_TYPE_KEY, "", EPOCH_BASELINE_REGION_KEY, STIMSETKEYNAME_SEP, EPOCHNAME_SEP) - EP_AddEpoch(device, channel, channelType, stimsetEndLogical, stimsetEnd, tags, EPOCH_SN_STIMSET + "_" + EPOCH_SN_STIMSETBLTRAIL, 1) - endif End /// @brief Sorts all epochs per channel number / channel type in EpochsWave