Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Packages/MIES/MIES_AmplifierInteraction.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ static Function AI_UpdateAmpModel(string device, variable headStage, [string ctr
AI_UpdateAmpModel(device, i, ctrl = "setvar_DataAcq_RsCorr", value = AmpStorageWave[%$rowLabel][0][i], selectAmp = 0)
break
case MCC_NO_AUTOBIAS_V_FUNC: // fallthrough
ASSERT(value > -100 && value < 100, "Out of range")
case MCC_NO_AUTOBIAS_VRANGE_FUNC: // fallthrough
case MCC_NO_AUTOBIAS_IBIASMAX_FUNC: // fallthrough
case MCC_NO_AUTOBIAS_ENABLE_FUNC:
Expand Down Expand Up @@ -1215,7 +1216,7 @@ Function AI_IsControlFromClampMode(string ctrl, variable clampMode)
End

/// @brief Convert amplifier controls to row labels for `AmpStorageWave`
static Function/S AI_AmpStorageControlToRowLabel(string ctrl)
Function/S AI_AmpStorageControlToRowLabel(string ctrl)

strswitch(ctrl)
// V-Clamp controls
Expand Down
27 changes: 18 additions & 9 deletions Packages/MIES/MIES_DAEphys.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -3255,15 +3255,7 @@ Function DAP_CheckProc_ClampMode(STRUCT WMCheckboxAction &cba) : CheckBoxControl
device = cba.win
control = cba.ctrlName
DAP_GetInfoFromControl(device, control, mode, headStage)

NVAR dataAcqRunMode = $GetDataAcqRunMode(device)
if(dataAcqRunMode == DAQ_NOT_RUNNING)
DAP_ChangeHeadStageMode(device, mode, headstage, DO_MCC_MIES_SYNCING)
else
WAVE GuiState = GetDA_EphysGuiStateNum(device)
GuiState[headstage][%HSmode_delayed] = mode
DAP_SetAmpModeControls(device, headstage, mode, delayed = 1)
endif
DAP_SetClampMode(device, headstage, mode)
catch
ClearRTError()
SetCheckBoxState(device, control, !cba.checked)
Expand Down Expand Up @@ -5799,3 +5791,20 @@ Function DAP_GetDAScaleMax(string device, variable headstage, string stimsetName

return result
End

/// @brief Sets a new clamp mode
///
/// @param[in] device Device title, e.g. "Dev1"
/// @param[in] headstage headstage number
/// @param[in] mode clamp mode @ref AmplifierClampModes
Function DAP_SetClampMode(string device, variable headstage, variable mode)

NVAR dataAcqRunMode = $GetDataAcqRunMode(device)
if(dataAcqRunMode == DAQ_NOT_RUNNING)
DAP_ChangeHeadStageMode(device, mode, headstage, DO_MCC_MIES_SYNCING)
else
WAVE GuiState = GetDA_EphysGuiStateNum(device)
GuiState[headstage][%HSmode_delayed] = mode
DAP_SetAmpModeControls(device, headstage, mode, delayed = 1)
endif
End
262 changes: 262 additions & 0 deletions Packages/MIES/MIES_ForeignFunctionInterface.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
/// @file MIES_ForeignFunctionInterface.ipf
/// @brief __FFI__ ACQ4/ZeroMQ accessible functions

/// @name Auto Clamp Ctrls enum for FFI_TriggerAutoClampControl
/// @anchor FFI_AutoClampCtrls
///@{
static Constant AUTO_PIPETTE = 1
static Constant AUTO_CAPACITANCE = 2
static Constant AUTO_BRIDGEBALANCE = 3
///@}

/// @brief Function to return Peak Resistance, Steady State Resistance to ACQ4 (Neurophysiology Acquisition and Analysis System.
/// See http://acq4.org/ for more details)
///
Expand Down Expand Up @@ -323,3 +331,257 @@ Function FFI_TestPulseMDSingleResult(string device, variable action)

return ret
End

/// @brief Returns the clamp state of a headstage of a locked device
///
/// - if the requested head stage is not active then a null wave is returned
/// The clamp state wave is DP numeric wave:
///
/// For VC
///
/// \rst
/// +------------------------+-----------------------+---------+
/// | Dimension Label | Value description | Units |
/// +========================+=======================+=========+
/// | HoldingPotential | | mV |
/// +------------------------+-----------------------+---------+
/// | RSCompChaining | | On/Off |
/// +------------------------+-----------------------+---------+
/// | HoldingPotentialEnable | | On/Off |
/// +------------------------+-----------------------+---------+
/// | WholeCellCap | 1 : On 0 : Off | pF |
/// +------------------------+-----------------------+---------+
/// | WholeCellRes | | MΩ |
/// +------------------------+-----------------------+---------+
/// | WholeCellEnable | 1 : On 0 : Off | On/Off |
/// +------------------------+-----------------------+---------+
/// | Correction | | % |
/// +------------------------+-----------------------+---------+
/// | Prediction | | % |
/// +------------------------+-----------------------+---------+
/// | RsCompEnable | | On/Off |
/// +------------------------+-----------------------+---------+
/// | PipetteOffsetVC | 1 : On 0 : Off | mV |
/// +------------------------+-----------------------+---------+
/// | WholeCellCap | | a.u. |
/// +------------------------+-----------------------+---------+
/// | ClampMode | 0 : VC | |
/// +------------------------+-----------------------+---------+
/// \endrst
///
///
/// For IC
///
/// \rst
/// +----------------------+-----------------------+---------+
/// | Dimension Label | Value description | Units |
/// +======================+=======================+=========+
/// | BiasCurrent | | pA |
/// +----------------------+-----------------------+---------+
/// | BiasCurrentEnable | | On/Off |
/// +----------------------+-----------------------+---------+
/// | BridgeBalance | | MΩ |
/// +----------------------+-----------------------+---------+
/// | BridgeBalanceEnable | 1 : On 0 : Off | On/Off |
/// +----------------------+-----------------------+---------+
/// | CapNeut | | pF |
/// +----------------------+-----------------------+---------+
/// | CapNeutEnable | 1 : On 0 : Off | On/Off |
/// +----------------------+-----------------------+---------+
/// | AutoBiasVcom | | mV |
/// +----------------------+-----------------------+---------+
/// | AutoBiasVcomVariance | | mV |
/// +----------------------+-----------------------+---------+
/// | AutoBiasIbiasmax | | pA |
/// +----------------------+-----------------------+---------+
/// | AutoBiasEnable | 1 : On 0 : Off | On/Off |
/// +----------------------+-----------------------+---------+
/// | PipetteOffsetIC | | mV |
/// +----------------------+-----------------------+---------+
/// | ClampMode | 1 : IC | |
/// +----------------------+-----------------------+---------+
/// \endrst
///
///
/// For I=0
///
/// \rst
/// +----------------------+-----------------------+---------+
/// | Dimension Label | Value description | Units |
/// +======================+=======================+=========+
/// | ClampMode | 2 : I=0 | |
/// +----------------------+-----------------------+---------+
/// \endrst
///
/// @param[in] device Device title, e.g. "Dev1"
/// @param[in] headstage headstage number
/// @returns wave with clamp state
Function/WAVE FFI_GetClampState(string device, variable headstage)

variable clampMode, numFuncs, i, j
string lbl

FFI_CheckValidDeviceAndHeadstage(device, headstage)
if(!DAG_GetHeadstageState(device, headstage))
return $""
endif

WAVE AmpStorageWave = GetAmplifierParamStorageWave(device)

clampMode = DAG_GetHeadstageMode(device, headstage)
if(clampMode == I_EQUAL_ZERO_MODE)
Make/FREE/D clampState = {I_EQUAL_ZERO_MODE}
SetDimLabel ROWS, j, ClampMode, clampState
return clampState
endif

WAVE aiFuncs = AI_GetFunctionConstantForClampMode(clampMode)
numFuncs = DimSize(aiFuncs, ROWS)
Make/FREE/T/N=(numFuncs) ctrlNames, ampLabels

ctrlNames[] = AI_MapFunctionConstantToControl(aiFuncs[p], clampMode)
ampLabels[] = AI_AmpStorageControlToRowLabel(ctrlNames[p])

Make/FREE/D/N=(numFuncs + 1) clampState
for(i = 0; i < numFuncs; i += 1)
if(IsEmpty(ampLabels[i]))
continue
endif
clampState[j] = AmpStorageWave[%$ampLabels[i]][0][headStage]
lbl = AI_MapFunctionConstantToName(aiFuncs[i], clampMode)
SetDimLabel ROWS, j, $lbl, clampState
j += 1
endfor
clampState[j] = clampMode
SetDimLabel ROWS, j, ClampMode, clampState
Redimension/N=(j + 1) clampState

return clampState
End

/// @brief Triggers an auto clamp control
///
/// @param[in] device Device title, e.g. "Dev1"
/// @param[in] headstage headstage number
/// @param[in] autoCtrl auto control number @ref FFI_AutoClampCtrls
Function FFI_TriggerAutoClampControl(string device, variable headstage, variable autoCtrl)

variable clampMode

FFI_CheckValidDeviceAndHeadstage(device, headstage)

clampMode = DAG_GetHeadstageMode(device, headstage)

if(autoCtrl == AUTO_PIPETTE)
AI_WriteToAmplifier(device, headstage, clampMode, MCC_AUTOPIPETTEOFFSET_FUNC, 1, GUIWrite = 1)
elseif(autoCtrl == AUTO_CAPACITANCE)
AI_WriteToAmplifier(device, headstage, V_CLAMP_MODE, MCC_AUTOWHOLECELLCOMP_FUNC, 1, GUIWrite = 1)
elseif(autoCtrl == AUTO_BRIDGEBALANCE)
AI_WriteToAmplifier(device, headstage, I_CLAMP_MODE, MCC_AUTOBRIDGEBALANCE_FUNC, 1, GUIWrite = 1)
else
FATAL_ERROR("Unknown auto clamp control")
endif
End

/// @brief Sets clamp mode
///
/// @param[in] device Device title, e.g. "Dev1"
/// @param[in] headstage headstage number
/// @param[in] clampMode clamp mode @ref AmplifierClampModes
Function FFI_SetClampMode(string device, variable headstage, variable clampMode)

FFI_CheckValidDeviceAndHeadstage(device, headstage)
ASSERT(AI_IsValidClampMode(clampMode), "Invalid clamp mode: " + num2istr(clampMode))

DAP_SetClampMode(device, headstage, clampMode)
End

/// @brief Sets Holding Potential
///
/// @param[in] device Device title, e.g. "Dev1"
/// @param[in] headstage headstage number
/// @param[in] potential holding potential in mV when current clamp mode of headstage is VC, bias current in pA when current clamp mode of headstage is IC
Function FFI_SetHoldingPotential(string device, variable headstage, variable potential)

variable clampMode

FFI_CheckValidDeviceAndHeadstage(device, headstage)

clampMode = DAG_GetHeadstageMode(device, headstage)
ASSERT(clampMode == V_CLAMP_MODE, "Attempt to set holding potential but current clamp mode is not VC !")
ASSERT(!IsNaN(potential), "potential argument is NaN")

FFI_SetHolding(device, headstage, clampMode, potential)
End

/// @brief Sets Bias Current
///
/// @param[in] device Device title, e.g. "Dev1"
/// @param[in] headstage headstage number
/// @param[in] biasCurrent bias current in pA
Function FFI_SetBiasCurrent(string device, variable headstage, variable biasCurrent)

variable clampMode

FFI_CheckValidDeviceAndHeadstage(device, headstage)

clampMode = DAG_GetHeadstageMode(device, headstage)
ASSERT(clampMode == I_CLAMP_MODE, "Attempt to set holding potential but current clamp mode is not IC !")
ASSERT(!IsNaN(biasCurrent), "bias current argument is NaN")

FFI_SetHolding(device, headstage, clampMode, biasCurrent)
End

static Function FFI_SetHolding(string device, variable headstage, variable clampMode, variable value)

AI_WriteToAmplifier(device, headstage, clampMode, MCC_HOLDING_FUNC, value, GUIWrite = 1)
End

static Function FFI_CheckValidDeviceAndHeadstage(string device, variable headstage)

ASSERT(!DAP_DeviceIsUnlocked(device), "Target device is not locked:" + device)
ASSERT(IsValidHeadstage(headstage), "Invalid headStage index: " + num2str(headstage))
End

/// @brief Sets Auto Bias
///
/// @param[in] device Device title, e.g. "Dev1"
/// @param[in] headstage headstage number
/// @param[in] potential Vm in mV in the range -99 mV to 99 mV
/// @param[in] enable when set to 1 then auto bias gets enabled, 0 disabled
Function FFI_SetAutoBias(string device, variable headstage, variable potential, variable enable)

variable clampMode

enable = !!enable

FFI_CheckValidDeviceAndHeadstage(device, headstage)

clampMode = DAG_GetHeadstageMode(device, headstage)
ASSERT(clampMode == I_CLAMP_MODE, "Attempt to set auto bias but current clamp mode is not IC !")

AI_WriteToAmplifier(device, headstage, clampMode, MCC_NO_AUTOBIAS_V_FUNC, potential, GUIWrite = 1)
AI_WriteToAmplifier(device, headstage, clampMode, MCC_NO_AUTOBIAS_ENABLE_FUNC, enable, GUIWrite = 1)
End

/// @brief Enables/Disables a headstage
///
/// The headstage state can not be changed while a data acquisition is running
///
/// @param[in] device Device title, e.g. "Dev1"
/// @param[in] headstage headstage number
/// @param[in] enable when set to 1 the headstage gets enabled, 0 disabled
/// @returns 0 when successful
Function FFI_SetHeadstageActive(string device, variable headstage, variable enable)

string ctrlName

enable = !!enable

FFI_CheckValidDeviceAndHeadstage(device, headstage)

ctrlName = GetPanelControl(headstage, CHANNEL_TYPE_HEADSTAGE, CHANNEL_CONTROL_CHECK)
PGC_SetAndActivateControl(device, ctrlName, val = enable)

return 0
End