Skip to content
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

Fix ReachTargetVoltage handling for too small resistance #2290

Merged
merged 9 commits into from
Jan 16, 2025
15 changes: 6 additions & 9 deletions Packages/MIES/MIES_AnalysisFunctions.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ End
/// the next sweep if the measured resistance is smaller than 20MΩ
Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s)

variable sweepNo, index, i, targetV, prevActiveHS, prevSendToAllAmp
variable index, i, targetV, prevActiveHS, prevSendToAllAmp
variable amps, result
variable autoBiasCheck, holdingPotential, indexing
string msg, name, control
Expand Down Expand Up @@ -1103,26 +1103,21 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s)
return NaN
endif

WAVE/Z sweep = AFH_GetLastSweepWaveAcquired(device)
ASSERT(WaveExists(sweep), "Expected a sweep for evaluation")

sweepNo = ExtractSweepNumber(NameOfWave(sweep))

WAVE numericalValues = GetLBNumericalValues(device)
WAVE textualValues = GetLBTextualValues(device)

WAVE deltaV = LBN_GetNumericWave()
WAVE deltaI = LBN_GetNumericWave()
WAVE resistance = LBN_GetNumericWave()

CalculateTPLikePropsFromSweep(numericalValues, textualValues, sweep, deltaI, deltaV, resistance)
CalculateTPLikePropsFromSweep(numericalValues, textualValues, s.scaledDACWave, deltaI, deltaV, resistance)

ED_AddEntryToLabnotebook(device, LBN_DELTA_I, deltaI, unit = "A")
ED_AddEntryToLabnotebook(device, LBN_DELTA_V, deltaV, unit = "V")

FitResistance(device, s.headstage, showPlot = 1)

WAVE/Z resistanceFitted = GetLastSetting(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT, UNKNOWN_MODE)
WAVE/Z resistanceFitted = GetLastSetting(numericalValues, s.sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT, UNKNOWN_MODE)
ASSERT(WaveExists(resistanceFitted), "Expected fitted resistance data")

for(i = 0; i < NUM_HEADSTAGES; i += 1)
Expand All @@ -1145,8 +1140,10 @@ Function ReachTargetVoltage(string device, STRUCT AnalysisFunction_V3 &s)
continue
endif

WAVE sweeps = AFH_GetSweepsFromSameSCI(numericalValues, s.sweepNo, i)

// check initial response
if(index == 0 && resistanceFitted[i] <= 20e6)
if(DimSize(sweeps, ROWS) == 1 && resistanceFitted[i] <= 20e6)
amps = -100e-12
targetVoltagesIndex[i] = -1
else
Expand Down
2 changes: 1 addition & 1 deletion Packages/MIES/MIES_Constants.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ Constant MAX_COMMANDLINE_LENGTH = 2500
StrConstant WAVEBUILDER_COMBINE_FORMULA_VER = "1"

/// Conversion factor between volts and bits for the AD/DA channels
/// The ITC 16 bit range is +-10.24 V such that a value of 32000 represents exactly 10 V, thus 3200 -> 1 V.
/// The ITC 16 bit range is +/-10.24 V such that a value of 32000 represents exactly 10 V, thus 3200 -> 1 V.
Constant HARDWARE_ITC_BITS_PER_VOLT = 3200

/// @name Trigger modes
Expand Down
6 changes: 4 additions & 2 deletions Packages/MIES/MIES_DAC-Hardware.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -837,12 +837,14 @@ Function HW_GetDAFifoPosition(string device, variable dataAcqOrTP)
endswitch
End

/// @brief Return the minimum/maximum voltage ranges for the given hardware and channel type
/// @brief Return the minimum/maximum values for the given hardware and channel type
///
/// The type is the natural type for the hardware, volts for NI and Sutter, and 16 bit integer values for ITC.
///
/// @param hardwareType One of @ref HardwareDACTypeConstants
/// @param channelType One of @ref XopChannelConstants
/// @param isAssociated For Sutter hardware the voltage range differs for associated channels or unassociated ones
Function [variable minimum, variable maximum] HW_GetVoltageRange(variable hardwareType, variable channelType, variable isAssociated)
Function [variable minimum, variable maximum] HW_GetDataRange(variable hardwareType, variable channelType, variable isAssociated)

switch(hardwareType)
case HARDWARE_NI_DAC:
Expand Down
14 changes: 7 additions & 7 deletions Packages/MIES/MIES_DataConfigurator.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,7 @@ static Function DC_WriteTTLIntoDAQDataWave(string device, STRUCT DataConfigurati

WAVE config = GetDAQConfigWave(device)

[minLimit, maxLimit] = HW_GetVoltageRange(s.hardwareType, XOP_CHANNEL_TYPE_TTL, 0)
[minLimit, maxLimit] = HW_GetDataRange(s.hardwareType, XOP_CHANNEL_TYPE_TTL, 0)

switch(s.hardwareType)
case HARDWARE_NI_DAC: // intended drop through
Expand Down Expand Up @@ -1355,7 +1355,7 @@ static Function DC_FillDAQDataWaveForTP(string device, STRUCT DataConfigurationR

switch(s.hardwareType)
case HARDWARE_ITC_DAC:
[minLimit, maxLimit] = HW_GetVoltageRange(s.hardwareType, XOP_CHANNEL_TYPE_DAC, 0)
[minLimit, maxLimit] = HW_GetDataRange(s.hardwareType, XOP_CHANNEL_TYPE_DAC, 0)

if(s.multiDevice)
Multithread ITCDataWave[][0, s.numDACEntries - 1] = \
Expand All @@ -1377,7 +1377,7 @@ static Function DC_FillDAQDataWaveForTP(string device, STRUCT DataConfigurationR
CA_StoreEntryIntoCache(key, ITCDataWave)
break
case HARDWARE_NI_DAC:
[minLimit, maxLimit] = HW_GetVoltageRange(s.hardwareType, XOP_CHANNEL_TYPE_DAC, 0)
[minLimit, maxLimit] = HW_GetDataRange(s.hardwareType, XOP_CHANNEL_TYPE_DAC, 0)

for(i = 0; i < s.numDACEntries; i += 1)
WAVE NIChannel = NISUDataWave[i]
Expand All @@ -1397,7 +1397,7 @@ static Function DC_FillDAQDataWaveForTP(string device, STRUCT DataConfigurationR
ASSERT(!mod(DimSize(SUChannel, ROWS), s.testPulseLength), "Sutter TP channel length is not integer multiple of test pulse length")
tpAmp = s.DACAmp[i][%TPAMP] * s.gains[i]

[minLimit, maxLimit] = HW_GetVoltageRange(s.hardwareType, XOP_CHANNEL_TYPE_DAC, !IsNaN(config[i][%HEADSTAGE]))
[minLimit, maxLimit] = HW_GetDataRange(s.hardwareType, XOP_CHANNEL_TYPE_DAC, !IsNaN(config[i][%HEADSTAGE]))
Multithread SUChannel[] = limit(tpAmp * s.testPulse[mod(p, s.testPulseLength)], minLimit, maxLimit); AbortOnRTE
endfor

Expand Down Expand Up @@ -1428,7 +1428,7 @@ static Function DC_FillDAQDataWaveForDAQ(string device, STRUCT DataConfiguration
isUnAssociated = IsNaN(headstage)
tpAmp = s.DACAmp[i][%TPAMP] * s.gains[i]

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

if(config[i][%DAQChannelType] == DAQ_CHANNEL_TYPE_TP)
ASSERT(DimSize(s.testPulse, COLS) <= 1, "Expected a 1D testpulse wave")
Expand Down Expand Up @@ -1890,7 +1890,7 @@ static Function [variable result, variable row, variable column] DC_CheckIfDataW
ASSERT(WaveType(ITCDataWave) == IGOR_TYPE_16BIT_INT, "Unexpected wave type: " + num2str(WaveType(ITCDataWave)))

// border vals are the same for all channels for ITC, so just use first
[minVal, maxVal] = HW_GetVoltageRange(hardwareType, configWave[0][%ChannelType], 1)
[minVal, maxVal] = HW_GetDataRange(hardwareType, configWave[0][%ChannelType], 1)

FindValue/UOFV/I=(minVal) ITCDataWave
if(V_Value != -1)
Expand All @@ -1915,7 +1915,7 @@ static Function [variable result, variable row, variable column] DC_CheckIfDataW
i += 1
continue
endif
[minVal, maxVal] = HW_GetVoltageRange(hardwareType, channelType, !IsNaN(configWave[i][%HEADSTAGE]))
[minVal, maxVal] = HW_GetDataRange(hardwareType, channelType, !IsNaN(configWave[i][%HEADSTAGE]))

FindValue/UOFV/V=(minVal)/T=1E-6 channel
if(V_Value != -1)
Expand Down
5 changes: 2 additions & 3 deletions Packages/tests/Basic/UTF_SweepFormula_Operations.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,9 @@ static Function StoreWorksWithMultipleDataSets()
variable numSweeps, numChannels

device = HW_ITC_BuildDeviceString("ITC18USB", "0")
MarkDeviceAsLocked(device)

SVAR lockedDevices = $GetLockedDevices()
lockedDevices = device
win = DB_GetBoundDataBrowser(device)
win = DB_GetBoundDataBrowser(device)

[numSweeps, numChannels, WAVE/U/I channels] = FillFakeDatabrowserWindow(win, device, XOP_CHANNEL_TYPE_ADC, textKey, textValue)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@
#pragma rtFunctionErrors=1
#pragma ModuleName=ReachTargetVoltageTesting

static Constant HEADSTAGE = 1

static Function [STRUCT DAQSettings s] PS_GetDAQSettings(string device)

InitDAQSettingsFromString(s, "MD1_RA1_I0_L0_BKG1_DB0" + \
"__HS" + num2str(HEADSTAGE) + "_DA1_AD1_CM:IC:_ST:ReachTargetVoltage_DA_0:")
InitDAQSettingsFromString(s, "MD1_RA1_I0_L0_BKG1_DB0" + \
"__HS1_DA1_AD1_CM:IC:_ST:ReachTargetVoltage_DA_0:")

return [s]
End

static Function GlobalPreAcq(string device)

PGC_SetAndActivateControl(device, "slider_DataAcq_ActiveHeadstage", val = HEADSTAGE)
PGC_SetAndActivateControl(device, "slider_DataAcq_ActiveHeadstage", val = 1)

PGC_SetAndActivateControl(device, "check_DataAcq_AutoBias", val = 1)
PGC_SetAndActivateControl(device, "setvar_DataAcq_AutoBiasV", val = -70)
Expand All @@ -26,15 +24,15 @@ static Function GlobalPreInit(string device)
PASS()
End

static Function [WAVE/Z deltaI, WAVE/Z deltaV, WAVE/Z resistance, WAVE/Z resistanceErr, WAVE/Z autobiasFromDialog] GetLBNEntries_IGNORE(string device, variable sweepNo)
static Function [WAVE/Z deltaI, WAVE/Z deltaV, WAVE/Z resistance, WAVE/Z resistanceErr, WAVE/Z autobiasFromDialog] GetLBNEntries_IGNORE(string device, variable sweepNo, variable headstage)

WAVE numericalValues = GetLBNumericalValues(device)

WAVE/Z deltaI = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_DELTA_I, HEADSTAGE, UNKNOWN_MODE)
WAVE/Z deltaV = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_DELTA_V, HEADSTAGE, UNKNOWN_MODE)
WAVE/Z resistance = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT, HEADSTAGE, UNKNOWN_MODE)
WAVE/Z resistanceErr = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT_ERR, HEADSTAGE, UNKNOWN_MODE)
WAVE/Z autobiasFromDialog = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_AUTOBIAS_TARGET_DIAG, HEADSTAGE, UNKNOWN_MODE)
WAVE/Z deltaI = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_DELTA_I, headstage, UNKNOWN_MODE)
WAVE/Z deltaV = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_DELTA_V, headstage, UNKNOWN_MODE)
WAVE/Z resistance = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT, headstage, UNKNOWN_MODE)
WAVE/Z resistanceErr = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_RESISTANCE_FIT_ERR, headstage, UNKNOWN_MODE)
WAVE/Z autobiasFromDialog = GetLastSettingEachSCI(numericalValues, sweepNo, LABNOTEBOOK_USER_PREFIX + LBN_AUTOBIAS_TARGET_DIAG, headstage, UNKNOWN_MODE)
End

static Function RTV_Works_preAcq(string device)
Expand All @@ -53,12 +51,12 @@ static Function RTV_Works_REENTRY([string str])

variable sweepNo

CHECK_EQUAL_VAR(GetSetVariable(str, "SetVar_Sweep"), 5)
CHECK_EQUAL_VAR(GetSetVariable(str, "SetVar_Sweep"), 6)

sweepNo = AFH_GetLastSweepAcquired(str)
CHECK_EQUAL_VAR(sweepNo, 4)
CHECK_EQUAL_VAR(sweepNo, 5)

[WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, sweepNo)
[WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, sweepNo, 1)

CHECK_WAVE(deltaI, NUMERIC_WAVE)
CHECK_WAVE(deltaV, NUMERIC_WAVE)
Expand All @@ -84,19 +82,72 @@ static Function RTV_WorksWithIndexing_REENTRY([string str])

variable sweepNo

CHECK_EQUAL_VAR(GetSetVariable(str, "SetVar_Sweep"), 6)
CHECK_EQUAL_VAR(GetSetVariable(str, "SetVar_Sweep"), 7)

sweepNo = AFH_GetLastSweepAcquired(str)
CHECK_EQUAL_VAR(sweepNo, 5)
CHECK_EQUAL_VAR(sweepNo, 6)

[WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, 0)
[WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, 0, 1)

CHECK_WAVE(deltaI, NUMERIC_WAVE)
CHECK_WAVE(deltaV, NUMERIC_WAVE)
CHECK_WAVE(resistance, NUMERIC_WAVE)
CHECK_WAVE(resistanceErr, NUMERIC_WAVE)
CHECK_WAVE(autobiasFromDialog, NUMERIC_WAVE)

CHECK_EQUAL_WAVES(autobiasFromDialog, {-69, NaN, NaN, NaN, NaN}, mode = WAVE_DATA)
CHECK_EQUAL_WAVES(autobiasFromDialog, {-69, NaN, NaN, NaN, NaN, NaN}, mode = WAVE_DATA)
CHECK_EQUAL_VAR(GetSetVariable(str, "setvar_DataAcq_AutoBiasV"), -69)
End

static Function RTV_WorksWithMultipleHeadstages_preAcq(string device)

AFH_AddAnalysisParameter("ReachTargetVoltage_DA_0", "EnableIndexing", var = 0)

PGC_SetAndActivateControl(device, "slider_DataAcq_ActiveHeadstage", val = 1)

PGC_SetAndActivateControl(device, "check_DataAcq_AutoBias", val = 1)
PGC_SetAndActivateControl(device, "setvar_DataAcq_AutoBiasV", val = -70)

PGC_SetAndActivateControl(device, "slider_DataAcq_ActiveHeadstage", val = 2)

PGC_SetAndActivateControl(device, "check_DataAcq_AutoBias", val = 1)
PGC_SetAndActivateControl(device, "setvar_DataAcq_AutoBiasV", val = -70)
End

// UTF_TD_GENERATOR DeviceNameGeneratorMD1
static Function RTV_WorksWithMultipleHeadstages([string str])

STRUCT DAQSettings s

InitDAQSettingsFromString(s, "MD1_RA1_I0_L0_BKG1_DB0" + \
"__HS2_DA0_AD0_CM:IC:_ST:ReachTargetVoltage_DA_0:" + \
"__HS1_DA1_AD1_CM:IC:_ST:ReachTargetVoltage_DA_0:")

AcquireData_NG(s, str)
End

static Function RTV_WorksWithMultipleHeadstages_REENTRY([string str])

variable sweepNo

CHECK_EQUAL_VAR(GetSetVariable(str, "SetVar_Sweep"), 6)

sweepNo = AFH_GetLastSweepAcquired(str)
CHECK_EQUAL_VAR(sweepNo, 5)

[WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, sweepNo, 1)

CHECK_WAVE(deltaI, NUMERIC_WAVE)
CHECK_WAVE(deltaV, NUMERIC_WAVE)
CHECK_WAVE(resistance, NUMERIC_WAVE)
CHECK_WAVE(resistanceErr, NUMERIC_WAVE)
CHECK_WAVE(autobiasFromDialog, NULL_WAVE)

[WAVE deltaI, WAVE deltaV, WAVE resistance, WAVE resistanceErr, WAVE autobiasFromDialog] = GetLBNEntries_IGNORE(str, sweepNo, 2)

CHECK_WAVE(deltaI, NUMERIC_WAVE)
CHECK_WAVE(deltaV, NUMERIC_WAVE)
CHECK_WAVE(resistance, NUMERIC_WAVE)
CHECK_WAVE(resistanceErr, NUMERIC_WAVE)
CHECK_WAVE(autobiasFromDialog, NULL_WAVE)
End
4 changes: 3 additions & 1 deletion Packages/tests/UTF_HardwareHelperFunctions.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,9 @@ Function InitDAQSettingsFromString(STRUCT DAQSettings &s, string str)
continue
endif

headstage = ParseNumber(elem, "HS")
headstage = ParseNumber(elem, "HS")
REQUIRE(IsValidHeadstage(headstage))

s.hs[headstage] = 1

s.da[headstage] = ParseNumber(elem, "_DA")
Expand Down
8 changes: 8 additions & 0 deletions Packages/tests/UTF_HelperFunctions.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1632,3 +1632,11 @@ Function/S ExecuteSweepFormulaCode(string browser, string code)

return SFH_GetFormulaGraphForBrowser(browser)
End

Function MarkDeviceAsLocked(string device)

REQUIRE_PROPER_STR(device)

SVAR lockedDevices = $GetLockedDevices()
lockedDevices = device
End
Binary file modified Packages/tests/_2017_09_01_192934-compressed.nwb
Binary file not shown.