Skip to content

Commit d5bf06c

Browse files
committed
FFI: Add functions for clamp and headstage control
Added the following functions: FFI_GetClampState returns a wave with the current clamp control values FFI_SetClampMode FFI_SetHoldingPotential - allowed only in VC mode FFI_SetBiasCurrent - allowed only in IC mode FFI_SetAutoBias - allowed only in IC mode FFI_SetHeadstageActive - allowed only when no DAQ is running FFI_TriggerAutoClampControl - wraps Pipette, Capacitance and Bridge Balance auto setting in a single call
1 parent dbb1795 commit d5bf06c

File tree

2 files changed

+263
-1
lines changed

2 files changed

+263
-1
lines changed

Packages/MIES/MIES_AmplifierInteraction.ipf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ Function AI_IsControlFromClampMode(string ctrl, variable clampMode)
12161216
End
12171217

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

12211221
strswitch(ctrl)
12221222
// V-Clamp controls

Packages/MIES/MIES_ForeignFunctionInterface.ipf

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
/// @file MIES_ForeignFunctionInterface.ipf
1010
/// @brief __FFI__ ACQ4/ZeroMQ accessible functions
1111

12+
/// @name Auto Clamp Ctrls enum for FFI_TriggerAutoClampControl
13+
/// @anchor FFI_AutoClampCtrls
14+
///@{
15+
static Constant AUTO_PIPETTE = 1
16+
static Constant AUTO_CAPACITANCE = 2
17+
static Constant AUTO_BRIDGEBALANCE = 3
18+
///@}
19+
1220
/// @brief Function to return Peak Resistance, Steady State Resistance to ACQ4 (Neurophysiology Acquisition and Analysis System.
1321
/// See http://acq4.org/ for more details)
1422
///
@@ -323,3 +331,257 @@ Function FFI_TestPulseMDSingleResult(string device, variable action)
323331

324332
return ret
325333
End
334+
335+
/// @brief Returns the clamp state of a headstage of a locked device
336+
///
337+
/// - if the requested head stage is not active then a null wave is returned
338+
/// The clamp state wave is DP numeric wave:
339+
///
340+
/// For VC
341+
///
342+
/// \rst
343+
/// +------------------------+-----------------------+---------+
344+
/// | Dimension Label | Value description | Units |
345+
/// +========================+=======================+=========+
346+
/// | HoldingPotential | | mV |
347+
/// +------------------------+-----------------------+---------+
348+
/// | RSCompChaining | | On/Off |
349+
/// +------------------------+-----------------------+---------+
350+
/// | HoldingPotentialEnable | | On/Off |
351+
/// +------------------------+-----------------------+---------+
352+
/// | WholeCellCap | 1 : On 0 : Off | pF |
353+
/// +------------------------+-----------------------+---------+
354+
/// | WholeCellRes | | MΩ |
355+
/// +------------------------+-----------------------+---------+
356+
/// | WholeCellEnable | 1 : On 0 : Off | On/Off |
357+
/// +------------------------+-----------------------+---------+
358+
/// | Correction | | % |
359+
/// +------------------------+-----------------------+---------+
360+
/// | Prediction | | % |
361+
/// +------------------------+-----------------------+---------+
362+
/// | RsCompEnable | | On/Off |
363+
/// +------------------------+-----------------------+---------+
364+
/// | PipetteOffsetVC | 1 : On 0 : Off | mV |
365+
/// +------------------------+-----------------------+---------+
366+
/// | WholeCellCap | | a.u. |
367+
/// +------------------------+-----------------------+---------+
368+
/// | ClampMode | 0 : VC | |
369+
/// +------------------------+-----------------------+---------+
370+
/// \endrst
371+
///
372+
///
373+
/// For IC
374+
///
375+
/// \rst
376+
/// +----------------------+-----------------------+---------+
377+
/// | Dimension Label | Value description | Units |
378+
/// +======================+=======================+=========+
379+
/// | BiasCurrent | | pA |
380+
/// +----------------------+-----------------------+---------+
381+
/// | BiasCurrentEnable | | On/Off |
382+
/// +----------------------+-----------------------+---------+
383+
/// | BridgeBalance | | MΩ |
384+
/// +----------------------+-----------------------+---------+
385+
/// | BridgeBalanceEnable | 1 : On 0 : Off | On/Off |
386+
/// +----------------------+-----------------------+---------+
387+
/// | CapNeut | | pF |
388+
/// +----------------------+-----------------------+---------+
389+
/// | CapNeutEnable | 1 : On 0 : Off | On/Off |
390+
/// +----------------------+-----------------------+---------+
391+
/// | AutoBiasVcom | | mV |
392+
/// +----------------------+-----------------------+---------+
393+
/// | AutoBiasVcomVariance | | mV |
394+
/// +----------------------+-----------------------+---------+
395+
/// | AutoBiasIbiasmax | | pA |
396+
/// +----------------------+-----------------------+---------+
397+
/// | AutoBiasEnable | 1 : On 0 : Off | On/Off |
398+
/// +----------------------+-----------------------+---------+
399+
/// | PipetteOffsetIC | | mV |
400+
/// +----------------------+-----------------------+---------+
401+
/// | ClampMode | 1 : IC | |
402+
/// +----------------------+-----------------------+---------+
403+
/// \endrst
404+
///
405+
///
406+
/// For I=0
407+
///
408+
/// \rst
409+
/// +----------------------+-----------------------+---------+
410+
/// | Dimension Label | Value description | Units |
411+
/// +======================+=======================+=========+
412+
/// | ClampMode | 2 : I=0 | |
413+
/// +----------------------+-----------------------+---------+
414+
/// \endrst
415+
///
416+
/// @param[in] device Device title, e.g. "Dev1"
417+
/// @param[in] headstage headstage number
418+
/// @returns wave with clamp state
419+
Function/WAVE FFI_GetClampState(string device, variable headstage)
420+
421+
variable clampMode, numFuncs, i, j
422+
string lbl
423+
424+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
425+
if(!DAG_GetHeadstageState(device, headstage))
426+
return $""
427+
endif
428+
429+
WAVE AmpStorageWave = GetAmplifierParamStorageWave(device)
430+
431+
clampMode = DAG_GetHeadstageMode(device, headstage)
432+
if(clampMode == I_EQUAL_ZERO_MODE)
433+
Make/FREE/D clampState = {I_EQUAL_ZERO_MODE}
434+
SetDimLabel ROWS, j, ClampMode, clampState
435+
return clampState
436+
endif
437+
438+
WAVE aiFuncs = AI_GetFunctionConstantForClampMode(clampMode)
439+
numFuncs = DimSize(aiFuncs, ROWS)
440+
Make/FREE/T/N=(numFuncs) ctrlNames, ampLabels
441+
442+
ctrlNames[] = AI_MapFunctionConstantToControl(aiFuncs[p], clampMode)
443+
ampLabels[] = AI_AmpStorageControlToRowLabel(ctrlNames[p])
444+
445+
Make/FREE/D/N=(numFuncs + 1) clampState
446+
for(i = 0; i < numFuncs; i += 1)
447+
if(IsEmpty(ampLabels[i]))
448+
continue
449+
endif
450+
clampState[j] = AmpStorageWave[%$ampLabels[i]][0][headStage]
451+
lbl = AI_MapFunctionConstantToName(aiFuncs[i], clampMode)
452+
SetDimLabel ROWS, j, $lbl, clampState
453+
j += 1
454+
endfor
455+
clampState[j] = clampMode
456+
SetDimLabel ROWS, j, ClampMode, clampState
457+
Redimension/N=(j + 1) clampState
458+
459+
return clampState
460+
End
461+
462+
/// @brief Triggers an auto clamp control
463+
///
464+
/// @param[in] device Device title, e.g. "Dev1"
465+
/// @param[in] headstage headstage number
466+
/// @param[in] autoCtrl auto control number @ref FFI_AutoClampCtrls
467+
Function FFI_TriggerAutoClampControl(string device, variable headstage, variable autoCtrl)
468+
469+
variable clampMode
470+
471+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
472+
473+
clampMode = DAG_GetHeadstageMode(device, headstage)
474+
475+
if(autoCtrl == AUTO_PIPETTE)
476+
AI_WriteToAmplifier(device, headstage, clampMode, MCC_AUTOPIPETTEOFFSET_FUNC, 1, GUIWrite = 1)
477+
elseif(autoCtrl == AUTO_CAPACITANCE)
478+
AI_WriteToAmplifier(device, headstage, V_CLAMP_MODE, MCC_AUTOWHOLECELLCOMP_FUNC, 1, GUIWrite = 1)
479+
elseif(autoCtrl == AUTO_BRIDGEBALANCE)
480+
AI_WriteToAmplifier(device, headstage, I_CLAMP_MODE, MCC_AUTOBRIDGEBALANCE_FUNC, 1, GUIWrite = 1)
481+
else
482+
FATAL_ERROR("Unknown auto clamp control")
483+
endif
484+
End
485+
486+
/// @brief Sets clamp mode
487+
///
488+
/// @param[in] device Device title, e.g. "Dev1"
489+
/// @param[in] headstage headstage number
490+
/// @param[in] clampMode clamp mode @ref AmplifierClampModes
491+
Function FFI_SetClampMode(string device, variable headstage, variable clampMode)
492+
493+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
494+
ASSERT(AI_IsValidClampMode(clampMode), "Invalid clamp mode: " + num2istr(clampMode))
495+
496+
DAP_SetClampMode(device, headstage, clampMode)
497+
End
498+
499+
/// @brief Sets Holding Potential
500+
///
501+
/// @param[in] device Device title, e.g. "Dev1"
502+
/// @param[in] headstage headstage number
503+
/// @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
504+
Function FFI_SetHoldingPotential(string device, variable headstage, variable potential)
505+
506+
variable clampMode
507+
508+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
509+
510+
clampMode = DAG_GetHeadstageMode(device, headstage)
511+
ASSERT(clampMode == V_CLAMP_MODE, "Attempt to set holding potential but current clamp mode is not VC !")
512+
ASSERT(!IsNaN(potential), "potential argument is NaN")
513+
514+
FFI_SetHolding(device, headstage, clampMode, potential)
515+
End
516+
517+
/// @brief Sets Bias Current
518+
///
519+
/// @param[in] device Device title, e.g. "Dev1"
520+
/// @param[in] headstage headstage number
521+
/// @param[in] biasCurrent bias current in pA
522+
Function FFI_SetBiasCurrent(string device, variable headstage, variable biasCurrent)
523+
524+
variable clampMode
525+
526+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
527+
528+
clampMode = DAG_GetHeadstageMode(device, headstage)
529+
ASSERT(clampMode == I_CLAMP_MODE, "Attempt to set holding potential but current clamp mode is not IC !")
530+
ASSERT(!IsNaN(biasCurrent), "bias current argument is NaN")
531+
532+
FFI_SetHolding(device, headstage, clampMode, biasCurrent)
533+
End
534+
535+
static Function FFI_SetHolding(string device, variable headstage, variable clampMode, variable value)
536+
537+
AI_WriteToAmplifier(device, headstage, clampMode, MCC_HOLDING_FUNC, value, GUIWrite = 1)
538+
End
539+
540+
static Function FFI_CheckValidDeviceAndHeadstage(string device, variable headstage)
541+
542+
ASSERT(!DAP_DeviceIsUnlocked(device), "Target device is not locked:" + device)
543+
ASSERT(IsValidHeadstage(headstage), "Invalid headStage index: " + num2str(headstage))
544+
End
545+
546+
/// @brief Sets Auto Bias
547+
///
548+
/// @param[in] device Device title, e.g. "Dev1"
549+
/// @param[in] headstage headstage number
550+
/// @param[in] potential Vm in mV in the range -99 mV to 99 mV
551+
/// @param[in] enable when set to 1 then auto bias gets enabled, 0 disabled
552+
Function FFI_SetAutoBias(string device, variable headstage, variable potential, variable enable)
553+
554+
variable clampMode
555+
556+
enable = !!enable
557+
558+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
559+
560+
clampMode = DAG_GetHeadstageMode(device, headstage)
561+
ASSERT(clampMode == I_CLAMP_MODE, "Attempt to set auto bias but current clamp mode is not IC !")
562+
563+
AI_WriteToAmplifier(device, headstage, clampMode, MCC_NO_AUTOBIAS_V_FUNC, potential, GUIWrite = 1)
564+
AI_WriteToAmplifier(device, headstage, clampMode, MCC_NO_AUTOBIAS_ENABLE_FUNC, enable, GUIWrite = 1)
565+
End
566+
567+
/// @brief Enables/Disables a headstage
568+
///
569+
/// The headstage state can not be changed while a data acquisition is running
570+
///
571+
/// @param[in] device Device title, e.g. "Dev1"
572+
/// @param[in] headstage headstage number
573+
/// @param[in] enable when set to 1 the headstage gets enabled, 0 disabled
574+
/// @returns 0 when successful
575+
Function FFI_SetHeadstageActive(string device, variable headstage, variable enable)
576+
577+
string ctrlName
578+
579+
enable = !!enable
580+
581+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
582+
583+
ctrlName = GetPanelControl(headstage, CHANNEL_TYPE_HEADSTAGE, CHANNEL_CONTROL_CHECK)
584+
PGC_SetAndActivateControl(device, ctrlName, val = enable)
585+
586+
return 0
587+
End

0 commit comments

Comments
 (0)