Skip to content

Commit

Permalink
Merge pull request #2290 from AllenInstitute/bugfix/2290-reach-target…
Browse files Browse the repository at this point in the history
…-voltage

Fix ReachTargetVoltage handling for too small resistance
  • Loading branch information
t-b authored Jan 16, 2025
2 parents 60eb0ad + 10f81b5 commit 86bdadf
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 41 deletions.
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
87 changes: 69 additions & 18 deletions Packages/tests/HardwareAnalysisFunctions/UTF_ReachTargetVoltage.ipf
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.

0 comments on commit 86bdadf

Please sign in to comment.