Skip to content

Commit

Permalink
Merge pull request #2343 from AllenInstitute/feature/2343-prefer-bett…
Browse files Browse the repository at this point in the history
…er-functions-for-headstage-checking

Prefer IsAssociatedChannel and IsValidHeadstage
  • Loading branch information
t-b authored Feb 4, 2025
2 parents 35b2d1f + 9345430 commit afa1072
Show file tree
Hide file tree
Showing 20 changed files with 78 additions and 58 deletions.
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_AnalysisBrowser_SweepBrowser_Export.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static Function SBE_AddMissingADTraceInfo(WAVE/T traceData)
// labnotebook layer where the ADC can be found is the headstage number
headstage = GetRowIndex(ADCs, val = j)

if(!IsFinite(headstage)) // unassociated ADC
if(!IsAssociatedChannel(headstage))
continue
endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static Function/WAVE SC_GetHeadstageQCForSetCount(string device, variable sweepN

setSweepCount = SC_GetSetSweepCount(numericalValues, sweeps[i])

headstageQCTotalPerSweepCount[][setSweepCount] += IsFinite(headstageQCLBN[p]) ? headstageQCLBN[p] : NaN
headstageQCTotalPerSweepCount[][setSweepCount] += IsValidHeadstage(headstageQCLBN[p]) ? headstageQCLBN[p] : NaN
endfor

#ifdef DEBUGGING_ENABLED
Expand Down
12 changes: 6 additions & 6 deletions Packages/MIES/MIES_Browser_Plotter.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ Function CreateTiledChannelGraph(string graph, WAVE config, variable sweepNo, WA
endif

// ignore TP during DAQ channels
if(WaveExists(status) && IsFinite(headstage))
if(WaveExists(status) && IsValidHeadstage(headstage))
if(channelType == XOP_CHANNEL_TYPE_DAC \
&& WaveExists(daChannelType) \
&& daChannelType[headstage] != DAQ_CHANNEL_TYPE_DAQ)
Expand Down Expand Up @@ -531,11 +531,11 @@ Function CreateTiledChannelGraph(string graph, WAVE config, variable sweepNo, WA
endif
endif

TUD_SetUserDataFromWaves(graph, trace, userDataKeys, \
{GetWavesDataFolder(wv, 2), channelID, num2str(chan), num2str(sweepNo), num2str(headstage), \
GetWavesDataFolder(textualValues, 2), GetWavesDataFolder(numericalValues, 2), \
num2str(IsFinite(headstage) ? clampModes[headstage] : NaN), num2str(ttlBit), experiment, "Sweep", \
num2str(k), horizAxis, vertAxis, traceRange, traceColor, num2istr(IsFinite(headstage)), \
TUD_SetUserDataFromWaves(graph, trace, userDataKeys, \
{GetWavesDataFolder(wv, 2), channelID, num2str(chan), num2str(sweepNo), num2str(headstage), \
GetWavesDataFolder(textualValues, 2), GetWavesDataFolder(numericalValues, 2), \
num2str(IsValidHeadstage(headstage) ? clampModes[headstage] : NaN), num2str(ttlBit), experiment, "Sweep", \
num2str(k), horizAxis, vertAxis, traceRange, traceColor, num2istr(IsValidHeadstage(headstage)), \
num2istr(guiChannelNumber), device, num2str(mapIndex)})
endfor
endfor
Expand Down
9 changes: 3 additions & 6 deletions Packages/MIES/MIES_DAC-Hardware.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -3337,8 +3337,7 @@ Function HW_SU_PrepareAcq(variable deviceId, variable mode, [WAVE/Z data, FUNCRE
hwGainTable[inIndex][%GAINFACTOR] = gain[i]
hwGainTable[inIndex][%OFFSET] = 0
input[inIndex][%INPUTWAVE] = GetWavesDataFolder(SUChannel, 2)
if(IsNaN(headStage))
// unassoc ADC
if(!IsAssociatedChannel(headStage))
[inChannel, encodeInfo] = HW_SU_GetEncodeFromUnassocADC(unassocADCIndex)
unassocADCIndex += 1
else
Expand All @@ -3355,8 +3354,7 @@ Function HW_SU_PrepareAcq(variable deviceId, variable mode, [WAVE/Z data, FUNCRE
case XOP_CHANNEL_TYPE_DAC:
EnsureLargeEnoughWave(output, indexShouldExist = outIndex)
output[outIndex][%OUTPUTWAVE] = GetWavesDataFolder(SUChannel, 2)
if(IsNaN(headStage))
// unassoc DAC
if(!IsAssociatedChannel(headStage))
[outChannel, encodeInfo] = HW_SU_GetEncodeFromUnassocDAC(unassocDACIndex)
unassocDACIndex += 1
else
Expand Down Expand Up @@ -3489,8 +3487,7 @@ Function HW_SU_ZeroDAC(variable deviceID, [variable flags])
if(config[i][%ChannelType] == XOP_CHANNEL_TYPE_DAC)
EnsureLargeEnoughWave(output, indexShouldExist = outIndex)
output[outIndex][%OUTPUTWAVE] = GetWavesDataFolder(channelDA, 2)
if(IsNaN(headStage))
// unassoc DAC
if(!IsAssociatedChannel(headStage))
[outChannel, encodeInfo] = HW_SU_GetEncodeFromUnassocDAC(unassocDACIndex)
unassocDACIndex += 1
else
Expand Down
13 changes: 6 additions & 7 deletions Packages/MIES/MIES_DAEphys.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ Function DAP_DACHasExpectedClampMode(string device, variable controlChannelIndex

headstage = AFH_GetHeadstageFromDAC(device, channelNumber)

if(!IsFinite(headstage)) // unassociated AD/DA channels
if(!IsAssociatedChannel(headstage))
return 0
endif

Expand Down Expand Up @@ -1152,8 +1152,7 @@ static Function DAP_AdaptAssocHeadstageState(string device, string checkboxCtrl)
return NaN
endif

// headStage can be NaN for non associated DA/AD channels
if(!IsFinite(headStage))
if(!IsAssociatedChannel(headStage))
if(headStageFromSettingsIC == headStageFromSettingsVC)
// be nice to users and activate the headstage for them
headStage = headStageFromSettingsIC
Expand Down Expand Up @@ -2298,14 +2297,14 @@ Function DAP_CheckSettings(string device, variable mode)

headstage = AFH_GetHeadstageFromDAC(device, i)

if(IsFinite(headstage) && DAG_GetHeadstageMode(device, headstage) == I_EQUAL_ZERO_MODE \
if(IsAssociatedChannel(headstage) && DAG_GetHeadstageMode(device, headstage) == I_EQUAL_ZERO_MODE \
&& !cmpstr(allSetNames[i], STIMSET_TP_WHILE_DAQ))
printf "(%s) When TP while DAQ is used the channel clamp mode for headstage %d can not be I=0.\r", device, headstage
ControlWindowToFront()
return 1
endif

if(IsNaN(headstage)) // unassoc DA
if(!IsAssociatedChannel(headstage))
if(DAP_CheckStimset(device, CHANNEL_TYPE_DAC, i, NaN))
return 1
endif
Expand All @@ -2326,7 +2325,7 @@ Function DAP_CheckSettings(string device, variable mode)

headstage = AFH_GetHeadstageFromADC(device, i)

if(IsNaN(headstage)) // unassoc AD
if(!IsAssociatedChannel(headstage))
if(DAP_CheckChannel(device, CHANNEL_TYPE_ADC, i))
return 1
endif
Expand Down Expand Up @@ -2856,7 +2855,7 @@ static Function DAP_CheckStimset(string device, variable channelType, variable c
setName = stimsets[i]

if(!CmpStr(setName, STIMSET_TP_WHILE_DAQ))
if(IsNaN(headstage))
if(!IsAssociatedChannel(headstage))
printf "(%s) Channel %d is an unassociated DA channel. Selection of the \"Test Pulse\" stimset for TP during DAQ is not allowed on unassociated DA channels.\r", device, channel
ControlWindowToFront()
return 1
Expand Down
37 changes: 18 additions & 19 deletions Packages/MIES/MIES_DataConfigurator.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static Function DC_UpdateHSProperties(string device, WAVE ADCs)
for(i = 0; i < numChannels; i += 1)
headstage = AFH_GetHeadstageFromADC(device, ADCs[i])

if(!IsFinite(headstage))
if(!IsAssociatedChannel(headstage))
continue
endif

Expand Down Expand Up @@ -809,7 +809,7 @@ static Function DC_PlaceDataInDAQConfigWave(string device, variable dataAcqOrTP)
DAQConfigWave[j][%DAQChannelType] = !CmpStr(allSetNames[i], STIMSET_TP_WHILE_DAQ, 1) || dataAcqOrTP == TEST_PULSE_MODE ? DAQ_CHANNEL_TYPE_TP : DAQ_CHANNEL_TYPE_DAQ
headstage = AFH_GetHeadstageFromDAC(device, i)
DAQConfigWave[j][%HEADSTAGE] = headstage
if(IsFinite(headstage))
if(IsAssociatedChannel(headstage))
DAQConfigWave[j][%CLAMPMODE] = DAG_GetHeadstageMode(device, headstage)
endif

Expand All @@ -834,7 +834,7 @@ static Function DC_PlaceDataInDAQConfigWave(string device, variable dataAcqOrTP)

headstage = AFH_GetHeadstageFromADC(device, i)

if(IsFinite(headstage))
if(IsAssociatedChannel(headstage))
// use the same channel type as the DAC
DAQConfigWave[j][%DAQChannelType] = DC_GetChannelTypefromHS(device, headstage)
DAQConfigWave[j][%HEADSTAGE] = headstage
Expand Down Expand Up @@ -1127,7 +1127,7 @@ static Function DC_PrepareLBNEntries(string device, STRUCT DataConfigurationResu
endif

for(j = 0; j < TOTAL_NUM_EVENTS; j += 1)
if(IsFinite(headstage)) // associated channel
if(IsAssociatedChannel(headstage))
func = analysisFunctions[headstage][j]
else
func = ""
Expand All @@ -1144,7 +1144,7 @@ static Function DC_PrepareLBNEntries(string device, STRUCT DataConfigurationResu
DC_DocumentChannelProperty(device, STIM_WAVE_NAME_KEY, headstage, channel, XOP_CHANNEL_TYPE_DAC, str = s.setName[i])
DC_DocumentChannelProperty(device, STIMSET_WAVE_NOTE_KEY, headstage, channel, XOP_CHANNEL_TYPE_DAC, str = NormalizeToEOL(RemoveEnding(note(s.stimSet[i]), "\r"), "\n"))

if(IsFinite(headstage)) // associated channel
if(IsAssociatedChannel(headstage))
str = analysisFunctions[headstage][ANALYSIS_FUNCTION_PARAMS]
else
str = ""
Expand All @@ -1171,7 +1171,7 @@ static Function DC_PrepareLBNEntries(string device, STRUCT DataConfigurationResu
endif

if(s.dataAcqOrTP == DATA_ACQUISITION_MODE)
isoodDAQMember = (s.distributedDAQOptOv && config[i][%DAQChannelType] == DAQ_CHANNEL_TYPE_DAQ && IsFinite(headstage))
isoodDAQMember = (s.distributedDAQOptOv && config[i][%DAQChannelType] == DAQ_CHANNEL_TYPE_DAQ && IsAssociatedChannel(headstage))
DC_DocumentChannelProperty(device, "oodDAQ member", headstage, channel, XOP_CHANNEL_TYPE_DAC, var = isoodDAQMember)
endif

Expand Down Expand Up @@ -1412,7 +1412,7 @@ End
static Function DC_FillDAQDataWaveForDAQ(string device, STRUCT DataConfigurationResult &s)

variable i, tpAmp, cutOff, channel, headstage, DAScale, singleSetLength, stimsetCol, startOffset
variable lastValidRow, isUnAssociated, maxLimit, minLimit
variable lastValidRow, isAssociated, maxLimit, minLimit

WAVE config = GetDAQConfigWave(device)

Expand All @@ -1424,16 +1424,16 @@ static Function DC_FillDAQDataWaveForDAQ(string device, STRUCT DataConfiguration
// The resample method picks the closest sample point in the stimSet by using round()
// The decimation factor can be < 1 (picking stimset samples one or multiple times) and > 1 (picking stimset samples or skipping it)
for(i = 0; i < s.numDACEntries; i += 1)
channel = s.DACList[i]
headstage = s.headstageDAC[i]
isUnAssociated = IsNaN(headstage)
tpAmp = s.DACAmp[i][%TPAMP] * s.gains[i]
channel = s.DACList[i]
headstage = s.headstageDAC[i]
isAssociated = IsAssociatedChannel(headstage)
tpAmp = s.DACAmp[i][%TPAMP] * s.gains[i]

[minLimit, maxLimit] = HW_GetDataRange(s.hardwareType, XOP_CHANNEL_TYPE_DAC, !isUnAssociated)
[minLimit, maxLimit] = HW_GetDataRange(s.hardwareType, XOP_CHANNEL_TYPE_DAC, isAssociated)

if(config[i][%DAQChannelType] == DAQ_CHANNEL_TYPE_TP)
ASSERT(DimSize(s.testPulse, COLS) <= 1, "Expected a 1D testpulse wave")
ASSERT(!isUnAssociated, "DA channel must be associated for DAQ_CHANNEL_TYPE_TP")
ASSERT(isAssociated, "DA channel must be associated for DAQ_CHANNEL_TYPE_TP")

switch(s.hardwareType)
case HARDWARE_ITC_DAC:
Expand Down Expand Up @@ -1473,7 +1473,7 @@ static Function DC_FillDAQDataWaveForDAQ(string device, STRUCT DataConfiguration
minLimit, \
maxLimit); AbortOnRTE

if(s.globalTPInsert && !isUnAssociated)
if(s.globalTPInsert && isAssociated)
// space in ITCDataWave for the testpulse is allocated via an automatic increase
// of the onset delay
MultiThread ITCDataWave[0, s.testPulseLength - 1][i] = \
Expand All @@ -1498,7 +1498,7 @@ static Function DC_FillDAQDataWaveForDAQ(string device, STRUCT DataConfiguration
minLimit, \
maxLimit); AbortOnRTE

if(s.globalTPInsert && !isUnAssociated)
if(s.globalTPInsert && isAssociated)
// space in ITCDataWave for the testpulse is allocated via an automatic increase
// of the onset delay
MultiThread NIChannel[0, s.testPulseLength - 1] = \
Expand Down Expand Up @@ -1632,7 +1632,7 @@ static Function [STRUCT DataConfigurationResult s] DC_GetConfiguration(string de
s.setCycleCount[i] = setCycleCountLocal
endif

if(IsFinite(headstage))
if(IsAssociatedChannel(headstage))
channelMode = ChannelClampMode[channel][%DAC][%ClampMode]
if(channelMode == V_CLAMP_MODE)
s.DACAmp[i][%TPAMP] = TPSettings[%amplitudeVC][headstage]
Expand All @@ -1641,7 +1641,7 @@ static Function [STRUCT DataConfigurationResult s] DC_GetConfiguration(string de
else
ASSERT(0, "Unknown clamp mode")
endif
else // unassoc channel
else
channelMode = NaN
s.DACAmp[i][%TPAMP] = NaN
endif
Expand Down Expand Up @@ -1978,7 +1978,7 @@ Function DC_DocumentChannelProperty(string device, string entry, variable headst
ASSERT(colData >= 0, "Could not find entry in the labnotebook input waves")
ASSERT(colKey >= 0, "Could not find entry in the labnotebook input key waves")

if(IsFinite(headstage))
if(IsAssociatedChannel(headstage) || headstage == INDEP_HEADSTAGE)
if(!ParamIsDefault(var))
sweepDataLNB[0][%$entry][headstage] = var
elseif(!ParamIsDefault(str))
Expand All @@ -1987,7 +1987,6 @@ Function DC_DocumentChannelProperty(string device, string entry, variable headst
return NaN
endif

// headstage is not finite, so the channel is unassociated
ua_entry = CreateLBNUnassocKey(entry, channelNumber, channelType)

if(!ParamIsDefault(var))
Expand Down
6 changes: 3 additions & 3 deletions Packages/MIES/MIES_LogbookViewer.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ static Function LBV_UpdateLBGraphLegend(string graph, [string traceList])

headstage = str2num(TUD_GetUserData(graph, trace, LBV_UD_HEADSTAGE))

if(IsFinite(headstage))
if(IsAssociatedChannel(headstage))
if(hsMarker[headstage])
continue
endif
Expand Down Expand Up @@ -680,15 +680,15 @@ static Function LBV_AddTraceToLBGraphTPStorage(string graph, DFREF dfr, string k
if(legacyActiveADColumns)
headstage = AFH_GetHeadstageFromActiveADC(statusADC, j)

if(IsNaN(headstage))
if(!IsValidHeadstage(headstage))
BUG("Could not derive headstage from active ADC")
headstage = j
endif
else
headstage = j
endif

if(IsFinite(headstage) && !channelSel[headstage][%HEADSTAGE])
if(IsValidHeadstage(headstage) && !channelSel[headstage][%HEADSTAGE])
continue
endif

Expand Down
8 changes: 8 additions & 0 deletions Packages/MIES/MIES_MiesUtilities_Checks.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@ threadsafe Function IsValidHeadstage(variable headstage)

return IsInteger(headstage) && headstage >= 0 && headstage < NUM_HEADSTAGES
End

/// @brief Check if the given headstage index belongs to an associated channel
///
/// UTF_NOINSTRUMENTATION
threadsafe Function IsAssociatedChannel(variable headstage)

return IsValidHeadstage(headstage)
End
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_MiesUtilities_GUI.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Function [STRUCT RGBColor s] GetHeadstageColor(variable headstage, [variable cha

isSplitted = ParamIsDefault(isSplitted) ? 1 : !!isSplitted

if(IsFinite(headstage))
if(IsValidHeadstage(headstage))
colorIndex = headstage
elseif(!ParamIsDefault(channelType) && channelType == XOP_CHANNEL_TYPE_TTL)
// The mapping is based on ITC hardware with unsplitted and splitted TTL channels in the following index order
Expand Down
5 changes: 2 additions & 3 deletions Packages/MIES/MIES_MiesUtilities_Logbook.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,7 @@ threadsafe static Function [WAVE/Z wv, variable index] GetLastSettingChannelInte
if(WaveExists(activeChannels))
headstage = GetRowIndex(activeChannels, val = channelNumber)

if(IsFinite(headstage))
// given channel was associated and active
if(IsAssociatedChannel(headstage))

WAVE/Z settings = GetLastSetting(values, sweepNo, setting, entrySourceType)

Expand Down Expand Up @@ -1912,7 +1911,7 @@ Function [variable type, variable waMode, variable headstage] GetAnalysisFunctio
anaFuncName = WaveText(settings, row = index)

headstage = GetHeadStageForChannel(numericalValues, sweepNo, channelType, channelNumber, DATA_ACQUISITION_MODE)
if(IsNaN(headstage))
if(!IsAssociatedChannel(headstage))
return [NaN, NaN, NaN]
endif

Expand Down
4 changes: 2 additions & 2 deletions Packages/MIES/MIES_Oscilloscope.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ Function SCOPE_CreateGraph(string device, variable dataAcqOrTP)
AppendToGraph/W=$graph/R=$rightAxis/T=$AXIS_SCOPE_TP_TIME TPStorage[][headstage][%SteadyStateResistance]/TN=$steadyStateTrace vs TPStorage[][headstage][%DeltaTimeInSeconds]
SetAxis/W=$graph/A=2/N=1 $rightAxis
ModifyGraph/W=$graph fSize($rightAxis)=10, grid($rightAxis)=1, gridStyle($rightAxis)=4, gridRGB($rightAxis)=(0, 0, 0, 3277)
ASSERT(isFinite(headStage), "invalid headStage")
ASSERT(IsValidHeadstage(headStage), "invalid headStage")
if(isFinite(PressureData[headStage][%DAC_DevID])) // Check if pressure is enabled
ModifyGraph/W=$graph marker($steadyStateTrace)=19, mode($steadyStateTrace)=4
ModifyGraph/W=$graph msize($steadyStateTrace)=1, gaps($steadyStateTrace)=0
Expand Down Expand Up @@ -408,7 +408,7 @@ Function SCOPE_SetADAxisLabel(string device, variable dataAcqOrTP, variable acti
endif

headStage = AFH_GetHeadstageFromADC(device, adc)
if(isFinite(headStage))
if(IsAssociatedChannel(headStage))
labelStr = "HS" + num2str(headstage)
else
labelStr = AXIS_SCOPE_AD + num2str(adc)
Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_OverlaySweeps.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Function OVS_IgnoreHeadstageInOverlay()

headstage = str2num(TUD_GetUserData(graph, trace, "headstage"))

if(!IsFinite(headstage))
if(!IsAssociatedChannel(headstage))
printf "Ignoring trace \"%s\" as it is not associated with a headstage.\r", trace
ControlWindowToFront()
return NaN
Expand Down
4 changes: 2 additions & 2 deletions Packages/MIES/MIES_PulseAveraging.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -3162,7 +3162,7 @@ static Function PA_AddColorScales(string win, STRUCT PulseAverageSettings &pa, S
endif
// assume that all pulses are from the same headstage
headstage = properties[setIndizes[0]][PA_PROPERTIES_INDEX_HEADSTAGE]
ASSERT(IsFinite(headstage), "Invalid headstage")
ASSERT(IsValidHeadstage(headstage), "Invalid headstage")

name = "colorScale_AD_" + num2str(channelNumber)
text = "HS" + num2str(headstage) + " (\\U)"
Expand Down Expand Up @@ -3214,7 +3214,7 @@ static Function PA_AddColorScales(string win, STRUCT PulseAverageSettings &pa, S
continue
endif
headstage = properties[setIndizes[0]][PA_PROPERTIES_INDEX_HEADSTAGE]
ASSERT(IsFinite(headstage), "Invalid headstage")
ASSERT(IsValidHeadstage(headstage), "Invalid headstage")

WAVE img = GetPulseAverageSetImageWave(pasi.pulseAverageDFR, channelNumber, region)
traceName = NameOfWave(img)
Expand Down
4 changes: 2 additions & 2 deletions Packages/MIES/MIES_SweepFormula.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -3316,7 +3316,7 @@ static Function/WAVE SF_OperationTPImpl(string graph, WAVE/WAVE mode, WAVE/Z sel
endif

headstage = GetHeadstageForChannel(numericalValues, sweepNo, chanType, chanNr, DATA_ACQUISITION_MODE)
SFH_ASSERT(IsFinite(headstage), "Associated headstage must not be NaN")
SFH_ASSERT(IsAssociatedChannel(headstage), "Associated headstage must not be NaN")
[WAVE settings, settingsIndex] = GetLastSettingChannel(numericalValues, textualValues, sweepNo, "DAC", chanNr, chanType, DATA_ACQUISITION_MODE)
SFH_ASSERT(WaveExists(settings), "Failed to retrieve DAC channels from LBN")
dacChannelNr = settings[headstage]
Expand Down Expand Up @@ -5617,7 +5617,7 @@ static Function/WAVE SF_GetAdditionalSweepsWithSameSCIorRAC(WAVE numericalValues

if(mode == SELECTDATA_MODE_SCI)
headstage = GetHeadstageForChannel(numericalValues, sweepNo, channelType, channelNumber, DATA_ACQUISITION_MODE)
if(IsNaN(headstage))
if(!IsValidHeadstage(headstage))
return $""
endif
WAVE/Z additionalSweeps = AFH_GetSweepsFromSameSCI(numericalValues, sweepNo, headstage)
Expand Down
Loading

0 comments on commit afa1072

Please sign in to comment.