diff --git a/Packages/MIES/MIES_AmplifierInteraction.ipf b/Packages/MIES/MIES_AmplifierInteraction.ipf index 52325a5f18..2a4319e517 100644 --- a/Packages/MIES/MIES_AmplifierInteraction.ipf +++ b/Packages/MIES/MIES_AmplifierInteraction.ipf @@ -439,6 +439,9 @@ static Function AI_UpdateAmpModel(string device, variable headStage, [string ctr rowLabel = AI_MapFunctionConstantToName(func, clampMode) AmpStorageWave[%$rowLabel][0][i] = value + + PUB_AmplifierSettingChange(device, i, clampMode, func, value) + AI_UpdateAmpModel(device, i, ctrl = "setvar_DataAcq_RsCorr", value = AmpStorageWave[%$rowLabel][0][i], selectAmp = 0) break case MCC_NO_AUTOBIAS_V_FUNC: @@ -448,6 +451,8 @@ static Function AI_UpdateAmpModel(string device, variable headStage, [string ctr rowLabel = AI_MapFunctionConstantToName(func, clampMode) AmpStorageWave[%$rowLabel][0][i] = value + + PUB_AmplifierSettingChange(device, i, clampMode, func, value) break case MCC_AUTOBRIDGEBALANCE_FUNC: clampMode = I_CLAMP_MODE @@ -1101,6 +1106,94 @@ threadsafe Function/S AI_MapFunctionConstantToName(variable func, variable clamp endswitch End +/// @brief Map human readable names to functions constants from @ref AI_SendToAmpConstants +threadsafe Function AI_MapNameToFunctionConstant(string name) + + strswitch(name) + // begin AmpStorageWave row labels + case "BiasCurrent": + case "HoldingPotential": + return MCC_HOLDING_FUNC + case "BiasCurrentEnable": + case "HoldingPotentialEnable": + return MCC_HOLDINGENABLE_FUNC + case "WholeCellCap": + return MCC_WHOLECELLCOMPCAP_FUNC + case "WholeCellRes": + return MCC_WHOLECELLCOMPRESIST_FUNC + case "WholeCellEnable": + return MCC_WHOLECELLCOMPENABLE_FUNC + case "Correction": + return MCC_RSCOMPCORRECTION_FUNC + case "Prediction": + return MCC_RSCOMPPREDICTION_FUNC + case "RsCompEnable": + return MCC_RSCOMPENABLE_FUNC + case "PipetteOffsetVC": + case "PipetteOffsetIC": + return MCC_PIPETTEOFFSET_FUNC + case "FastCapacitanceComp": + return MCC_AUTOFASTCOMP_FUNC + case "SlowCapacitanceComp": + return MCC_AUTOSLOWCOMP_FUNC + case "BridgeBalance": + return MCC_BRIDGEBALRESIST_FUNC + case "BridgeBalanceEnable": + return MCC_BRIDGEBALENABLE_FUNC + case "CapNeut": + return MCC_NEUTRALIZATIONCAP_FUNC + case "CapNeutEnable": + return MCC_NEUTRALIZATIONENABL_FUNC + // end AmpStorageWave row labels + // begin others + case "RsCompBandWidth": + return MCC_RSCOMPBANDWIDTH_FUNC + case "OscKillerEnable": + return MCC_OSCKILLERENABLE_FUNC + case "AutoPipetteOffset": + return MCC_AUTOPIPETTEOFFSET_FUNC + case "FastCompCap": + return MCC_FASTCOMPCAP_FUNC + case "FastCompTau": + return MCC_FASTCOMPTAU_FUNC + case "SlowCompCap": + return MCC_SLOWCOMPCAP_FUNC + case "SlowCompTau": + return MCC_SLOWCOMPTAU_FUNC + case "SlowCompTauX20": + return MCC_SLOWCOMPTAUX20ENAB_FUNC + case "SlowCurrentInjectEnable": + return MCC_SLOWCURRENTINJENABL_FUNC + case "SlowCurrentInjectLevel": + return MCC_SLOWCURRENTINJLEVEL_FUNC + case "SlowCurrentInjectSettleTime": + return MCC_SLOWCURRENTINJSETLT_FUNC + case "SetPrimarySignalGain": + return MCC_PRIMARYSIGNALGAIN_FUNC + case "SetSecondaySignalGain": + return MCC_SECONDARYSIGNALGAIN_FUNC + case "SetPrimarySignalHPF": + return MCC_PRIMARYSIGNALHPF_FUNC + case "SetPrimarySignalLPF": + return MCC_PRIMARYSIGNALLPF_FUNC + case "SetSecondaySignalLPF": + return MCC_SECONDARYSIGNALLPF_FUNC + case "RSCompChaining": + return MCC_NO_AMPCHAIN_FUNC + case "AutoBiasVcom": + return MCC_NO_AUTOBIAS_V_FUNC + case "AutoBiasVcomVariance": + return MCC_NO_AUTOBIAS_VRANGE_FUNC + case "AutoBiasIbiasmax": + return MCC_NO_AUTOBIAS_IBIASMAX_FUNC + case "AutoBiasEnable": + return MCC_NO_AUTOBIAS_ENABLE_FUNC + // end others + default: + ASSERT_TS(0, "Invalid name: " + name) + endswitch +End + /// @brief Return the truthness that the ctrl belongs to the clamp mode Function AI_IsControlFromClampMode(string ctrl, variable clampMode) @@ -1657,6 +1750,10 @@ static Function AI_SendToAmp(string device, variable headStage, variable mode, v endif endswitch + if(accessType == MCC_WRITE) + PUB_AmplifierSettingChange(device, headstage, mode, func, value) + endif + if(!IsFinite(ret)) print "Amp communication error. Check associations in hardware tab and/or use Query connected amps button" ControlWindowToFront() diff --git a/Packages/MIES/MIES_Configuration.ipf b/Packages/MIES/MIES_Configuration.ipf index 6bc81d05ab..3d246919ce 100644 --- a/Packages/MIES/MIES_Configuration.ipf +++ b/Packages/MIES/MIES_Configuration.ipf @@ -512,6 +512,9 @@ Function CONF_RestoreWindow(string fName, [string rigFile]) Abort endif endtry + + PUB_ConfigurationFinished(wName, panelType, fName, rigFile) + JSON_Release(jsonID) End diff --git a/Packages/MIES/MIES_Constants.ipf b/Packages/MIES/MIES_Constants.ipf index d8233ffc32..7e0c9f2f74 100644 --- a/Packages/MIES/MIES_Constants.ipf +++ b/Packages/MIES/MIES_Constants.ipf @@ -1883,11 +1883,11 @@ StrConstant LOGBOOK_WAVE_TEMP_FOLDER = "Temp" /// @name All available ZeroMQ message filters /// @anchor ZeroMQMessageFilters ///@{ -StrConstant IVS_PUB_FILTER = "ivscc" StrConstant PRESSURE_STATE_FILTER = "pressure:state" StrConstant PRESSURE_SEALED_FILTER = "pressure:sealed" StrConstant PRESSURE_BREAKIN_FILTER = "pressure:break in" StrConstant AUTO_TP_FILTER = "testpulse:autotune result" +StrConstant TESTPULSE_SET_VALUE_FILTER = "testpulse:set value" StrConstant ZMQ_FILTER_TPRESULT_NOW = "testpulse:results live" StrConstant ZMQ_FILTER_TPRESULT_1S = "testpulse:results 1s update" StrConstant ZMQ_FILTER_TPRESULT_5S = "testpulse:results 5s update" @@ -1895,11 +1895,13 @@ StrConstant ZMQ_FILTER_TPRESULT_10S = "testpulse:results 10s update" StrConstant ZMQ_FILTER_TPRESULT_NOW_WITH_DATA = "testpulse:results live with data" StrConstant AMPLIFIER_CLAMP_MODE_FILTER = "amplifier:clamp mode" StrConstant AMPLIFIER_AUTO_BRIDGE_BALANCE = "amplifier:auto bridge balance" +StrConstant AMPLIFIER_SET_VALUE = "amplifier:set value" StrConstant ANALYSIS_FUNCTION_PB = "analysis function:pipette in bath" StrConstant ANALYSIS_FUNCTION_SE = "analysis function:seal evaluation" StrConstant ANALYSIS_FUNCTION_VM = "analysis function:true resting membrane potential" StrConstant DAQ_TP_STATE_CHANGE_FILTER = "data acquisition:state change" StrConstant ANALYSIS_FUNCTION_AR = "analysis function:access resistance smoke" +StrConstant CONFIG_FINISHED_FILTER = "configuration:finished" ///@} /// which is sufficient to represent each sample point time with a distinctive number up to rates of 10 MHz. diff --git a/Packages/MIES/MIES_DAEphys.ipf b/Packages/MIES/MIES_DAEphys.ipf index f73d032034..924c2bf1b9 100644 --- a/Packages/MIES/MIES_DAEphys.ipf +++ b/Packages/MIES/MIES_DAEphys.ipf @@ -5513,11 +5513,47 @@ static Function/S DAP_TPControlToLabel(string ctrl) endswitch End +/// @brief Get the physical unit for the control name +static Function/S DAP_TPControlToUnit(string ctrl) + + strswitch(ctrl) + case "SetVar_DataAcq_TPDuration": + return "ms" + case "SetVar_DataAcq_TPBaselinePerc": + return "%" + case "SetVar_DataAcq_TPAmplitude": + return "pA" + case "SetVar_DataAcq_TPAmplitudeIC": + return "mV" + case "setvar_Settings_TPBuffer": + return "a.u." + case "setvar_Settings_TP_RTolerance": + return "MΩ" + case "check_DataAcq_AutoTP": + return "On/Off" + case "setvar_DataAcq_IinjMax": + return "pA" + case "setvar_DataAcq_targetVoltage": + return "mV" + case "setvar_DataAcq_targetVoltageRange": + return "mV" + case "Check_TP_SendToAllHS": + return "On/Off" + case "setvar_Settings_autoTP_perc": + return "%" + case "setvar_Settings_autoTP_int": + return "s" + default: + ASSERT(0, "invalid control") + break + endswitch +End + /// @brief Write a new TP setting value to the wave static Function DAP_TPGUISettingToWave(string device, string ctrl, variable val) - string lbl, entry - variable first, last, TPState, needsTPRestart + string lbl, entry, unit + variable first, last, TPState, needsTPRestart, headstage, i needsTPRestart = WhichListItem(ctrl, DAEPHYS_TP_CONTROLS_NO_RESTART) == -1 @@ -5546,6 +5582,12 @@ static Function DAP_TPGUISettingToWave(string device, string ctrl, variable val) TPSettings[%$lbl][first, last] = val + unit = DAP_TPControlToUnit(ctrl) + for(i = first; i <= last; i += 1) + headstage = IsValidHeadstage(i) ? i : NaN + PUB_TPSettingChange(device, headstage, lbl, val, unit) + endfor + if(!cmpstr(lbl, "autoTPEnable")) TP_AutoTPGenerateNewCycleID(device, first = first, last = last) DAP_AdaptAutoTPColorAndDependent(device) diff --git a/Packages/MIES/MIES_ForeignFunctionInterface.ipf b/Packages/MIES/MIES_ForeignFunctionInterface.ipf index e88f47be75..a661ad7706 100644 --- a/Packages/MIES/MIES_ForeignFunctionInterface.ipf +++ b/Packages/MIES/MIES_ForeignFunctionInterface.ipf @@ -60,15 +60,46 @@ End /// /// See also @ref ZeroMQMessageFilters. /// -/// @sa PUB_GetJSONTemplate +/// Description of all messages: +/// +/// \rst +/// +/// ============================================ ==================================================== ============================================= +/// Name Description Publish function +/// ============================================ ==================================================== ============================================= +/// :cpp:var:ZeroMQ_HEARTBEAT Every 5s for alive check None +/// :cpp:var:PRESSURE_STATE_FILTER Every pressure method change :cpp:func:PUB_PressureMethodChange +/// :cpp:var:PRESSURE_SEALED_FILTER Pressure seal reached :cpp:func:PUB_PressureSealedState +/// :cpp:var:PRESSURE_BREAKIN_FILTER Pressure breakin :cpp:func:PUB_PressureBreakin +/// :cpp:var:AUTO_TP_FILTER Auto TP has finished :cpp:func:PUB_AutoTPResult +/// :cpp:var:AMPLIFIER_CLAMP_MODE_FILTER Clamp mode has changed :cpp:func:PUB_ClampModeChange +/// :cpp:var:AMPLIFIER_AUTO_BRIDGE_BALANCE Amplifier auto bridge balance was activated :cpp:func:PUB_AutoBridgeBalance +/// :cpp:var:ANALYSIS_FUNCTION_PB Pipette in bath analysis function has finished :cpp:func:PUB_PipetteInBath +/// :cpp:var:ANALYSIS_FUNCTION_SE Seal evaluation analysis function has finished :cpp:func:PUB_SealEvaluation +/// :cpp:var:ANALYSIS_FUNCTION_VM True resting memb. potential function is finished :cpp:func:PUB_TrueRestingMembranePotential +/// :cpp:var:DAQ_TP_STATE_CHANGE_FILTER Data acquisition/Test pulse started or stopped :cpp:func:PUB_DAQStateChange +/// :cpp:var:ANALYSIS_FUNCTION_AR Access resistance smoke ana. function has finished :cpp:func:PUB_AccessResistanceSmoke +/// :cpp:var:ZMQ_FILTER_TPRESULT_NOW TP evaluation result (all TPs) :cpp:func:PUB_TPResult +/// :cpp:var:ZMQ_FILTER_TPRESULT_1s TP evaluation result (every 1s) :cpp:func:PUB_TPResult +/// :cpp:var:ZMQ_FILTER_TPRESULT_5s TP evaluation result (every 5s) :cpp:func:PUB_TPResult +/// :cpp:var:ZMQ_FILTER_TPRESULT_10s TP evaluation result (every 10s) :cpp:func:PUB_TPResult +/// :cpp:var:ZMQ_FILTER_TPRESULT_NOW_WITH_DATA TP evaluation result with AD data (all TPs) :cpp:func:PUB_TPResult +/// :cpp:var:CONFIG_FINISHED_FILTER JSON configuration for panel has finished :cpp:func:PUB_ConfigurationFinished +/// :cpp:var:AMPLIFIER_SET_VALUE Amplifier setting was changed through MIES :cpp:func:PUB_AmplifierSettingChange +/// :cpp:var:TESTPULSE_SET_VALUE_FILTER Testpulse setting change :cpp:func:PUB_TPSettingChange +/// ============================================ ==================================================== ============================================= +/// +/// \endrst +/// Function/WAVE FFI_GetAvailableMessageFilters() - Make/FREE/T wv = {ZeroMQ_HEARTBEAT, IVS_PUB_FILTER, PRESSURE_STATE_FILTER, PRESSURE_SEALED_FILTER, \ - PRESSURE_BREAKIN_FILTER, AUTO_TP_FILTER, AMPLIFIER_CLAMP_MODE_FILTER, \ - AMPLIFIER_AUTO_BRIDGE_BALANCE, ANALYSIS_FUNCTION_PB, ANALYSIS_FUNCTION_SE, \ - ANALYSIS_FUNCTION_VM, DAQ_TP_STATE_CHANGE_FILTER, \ - ANALYSIS_FUNCTION_AR, ZMQ_FILTER_TPRESULT_NOW, ZMQ_FILTER_TPRESULT_1S, \ - ZMQ_FILTER_TPRESULT_5S, ZMQ_FILTER_TPRESULT_10S, ZMQ_FILTER_TPRESULT_NOW_WITH_DATA} + Make/FREE/T wv = {ZeroMQ_HEARTBEAT, PRESSURE_STATE_FILTER, PRESSURE_SEALED_FILTER, \ + PRESSURE_BREAKIN_FILTER, AUTO_TP_FILTER, AMPLIFIER_CLAMP_MODE_FILTER, \ + AMPLIFIER_AUTO_BRIDGE_BALANCE, ANALYSIS_FUNCTION_PB, ANALYSIS_FUNCTION_SE, \ + ANALYSIS_FUNCTION_VM, DAQ_TP_STATE_CHANGE_FILTER, \ + ANALYSIS_FUNCTION_AR, ZMQ_FILTER_TPRESULT_NOW, ZMQ_FILTER_TPRESULT_1S, \ + ZMQ_FILTER_TPRESULT_5S, ZMQ_FILTER_TPRESULT_10S, ZMQ_FILTER_TPRESULT_NOW_WITH_DATA, \ + CONFIG_FINISHED_FILTER, AMPLIFIER_SET_VALUE, TESTPULSE_SET_VALUE_FILTER} Note/K wv, "Heartbeat is sent every 5 seconds." diff --git a/Packages/MIES/MIES_Publish.ipf b/Packages/MIES/MIES_Publish.ipf index 47eac0516a..3cb970ee37 100644 --- a/Packages/MIES/MIES_Publish.ipf +++ b/Packages/MIES/MIES_Publish.ipf @@ -16,10 +16,17 @@ static Function PUB_GetJSONTemplate(string device, variable headstage) jsonID = JSON_New() JSON_AddTreeObject(jsonID, "") - JSON_AddString(jsonID, "device", device) + + if(IsEmpty(device)) + JSON_AddNull(jsonID, "device") + JSON_AddVariable(jsonID, "sweep number", NaN) + else + JSON_AddString(jsonID, "device", device) + JSON_AddVariable(jsonID, "sweep number", AS_GetSweepNumber(device, allowFallback = 1)) + endif + JSON_AddVariable(jsonID, "headstage", headstage) JSON_AddString(jsonID, "timestamp", GetISO8601TimeStamp()) - JSON_AddVariable(jsonID, "sweep number", AS_GetSweepNumber(device, allowFallback = 1)) return jsonID End @@ -906,3 +913,94 @@ threadsafe static Function PUB_CheckPublishingTime(string pubFilter, variable pe return 0 End + +/// Filter: #CONFIG_FINISHED_FILTER +/// +/// Example: +/// +/// \rst +/// .. code-block:: json +/// +/// { +/// "device": null, +/// "fileName": "fileA", +/// "headstage": "NaN", +/// "panelType": "DataBrowser", +/// "rigFileName": "fileB", +/// "sweep number": "NaN", +/// "timestamp": "2025-02-25T15:06:19Z", +/// "window": "Databrowser" +/// } +/// +/// \endrst +Function PUB_ConfigurationFinished(string windowName, string panelType, string fileName, string rigfileName) + + variable jsonID + + jsonID = PUB_GetJSONTemplate("", NaN) + + JSON_AddString(jsonID, "window", windowName) + JSON_AddString(jsonID, "panelType", panelType) + JSON_AddString(jsonID, "fileName", fileName) + JSON_AddString(jsonID, "rigFileName", rigFileName) + + PUB_Publish(jsonID, CONFIG_FINISHED_FILTER) +End + +/// Filter: #AMPLIFIER_SET_VALUE +/// +/// The available names are listed in AI_MapFunctionConstantToName(). +/// +/// Example: +/// +/// \rst +/// .. code-block:: json +/// +/// { +/// "amplifier action": { +/// "HoldingPotentialEnable": { +/// "unit": "On/Off", +/// "value": 1 +/// } +/// }, +/// "clamp mode": "V_CLAMP_MODE", +/// "device": "my_device", +/// "headstage": 1, +/// "sweep number": "NaN", +/// "timestamp": "2025-03-25T16:42:21Z" +/// } +/// +/// \endrst +Function PUB_AmplifierSettingChange(string device, variable headstage, variable mode, variable func, variable value) + + variable jsonID + string path, unit, name + + jsonID = PUB_GetJSONTemplate(device, headstage) + + JSON_AddString(jsonID, "clamp mode", ConvertAmplifierModeToString(mode)) + + path = "/amplifier action" + JSON_AddTreeObject(jsonID, path) + + unit = AI_GetUnitForFunctionConstant(func, mode) + name = AI_MapFunctionConstantToName(func, mode) + PUB_AddValueWithUnit(jsonID, path + "/" + name, value, unit) + + PUB_Publish(jsonID, AMPLIFIER_SET_VALUE) +End + +Function PUB_TPSettingChange(string device, variable headstage, string name, variable value, string unit) + + variable jsonID + string path + + jsonID = PUB_GetJSONTemplate(device, headstage) + + path = "/testpulse setting" + JSON_AddTreeObject(jsonID, path) + + PUB_AddValueWithUnit(jsonID, path + "/" + name, value, unit) + + PUB_Publish(jsonID, TESTPULSE_SET_VALUE_FILTER) +End diff --git a/Packages/tests/Basic/UTF_Amplifier.ipf b/Packages/tests/Basic/UTF_Amplifier.ipf index d5bf5775e0..ab3f611fb5 100644 --- a/Packages/tests/Basic/UTF_Amplifier.ipf +++ b/Packages/tests/Basic/UTF_Amplifier.ipf @@ -41,6 +41,10 @@ static Function TestFuncMapping() name = AI_MapFunctionConstantToName(func, clampMode) CHECK_PROPER_STR(name) + INFO("entry: %s, ctrl: %s, name: %s", s0 = entry, s1 = ctrl, s2 = name) + funcBack = AI_MapNameToFunctionConstant(name) + CHECK_EQUAL_VAR(func, funcBack) + CHECK_EQUAL_STR(MIES_AI#AI_AmpStorageControlToRowLabel(ctrl), AI_MapFunctionConstantToName(func, clampMode)) [funcBack, modeBack] = AI_MapControlNameToFunctionConstant(ctrl) diff --git a/Packages/tests/Basic/UTF_Configuration.ipf b/Packages/tests/Basic/UTF_Configuration.ipf index 2e9351dcf5..570c28b1ef 100644 --- a/Packages/tests/Basic/UTF_Configuration.ipf +++ b/Packages/tests/Basic/UTF_Configuration.ipf @@ -31,6 +31,10 @@ static Function TEST_CASE_END_OVERRIDE(string testCase) KillVariables/Z priorityFlag TestCaseEndCommon(testCase) + + if(DoExpensiveChecks()) + CheckPubMessagesHeartbeatOnly() + endif End Window MainPanel() : Panel @@ -191,6 +195,11 @@ End /// @brief Change Test Panel and Load, then save and check against reference template static Function TCONF_Load() + variable jsonID + string actual, expected + + PrepareForPublishTest() + string fName1 = "ConfigurationTest_compare1.txt" variable/G setvarTest @@ -206,6 +215,11 @@ static Function TCONF_Load() TCONF_CompareTextFiles(fName1, REF_CONFIG_FILE) + jsonID = FetchAndParseMessage(CONFIG_FINISHED_FILTER) + expected = "MainPanel" + actual = JSON_GetString(jsonID, "window") + CHECK_EQUAL_STR(actual, expected) + KillVariables setvarTest End @@ -323,7 +337,10 @@ static Function TCONF_SaveNotebookAndRestore() string fName = "NotebookTest.json" string nbTextRef = "This is fine." string nbTextRef2 = "This is not fine." - string nbText + string nbText, expected, actual + variable jsonID + + PrepareForPublishTest() DoWindow/K $wName NewNotebook/N=$wName/F=0 @@ -334,6 +351,11 @@ static Function TCONF_SaveNotebookAndRestore() nbText = GetNotebookText(wName, mode = 2) CHECK_EQUAL_STR(nbTextRef, nbText) + jsonID = FetchAndParseMessage(CONFIG_FINISHED_FILTER) + expected = wName + actual = JSON_GetString(jsonID, "window") + CHECK_EQUAL_STR(actual, expected) + ReplaceNotebookText(wName, nbTextRef) SetWindow $wName, userdata($EXPCONFIG_UDATA_EXCLUDE_RESTORE)="1" SetWindow $wName, userdata($EXPCONFIG_UDATA_EXCLUDE_SAVE)="1" @@ -342,6 +364,11 @@ static Function TCONF_SaveNotebookAndRestore() CONF_RestoreWindow(PrependExperimentFolder_IGNORE(fName)) nbText = GetNotebookText(wName, mode = 2) CHECK_EQUAL_STR(nbTextRef2, nbText) + + jsonID = FetchAndParseMessage(CONFIG_FINISHED_FILTER) + expected = wName + actual = JSON_GetString(jsonID, "window") + CHECK_EQUAL_STR(actual, expected) End /// @brief Checks if every (qualified) panel has a panel type set diff --git a/Packages/tests/Basic/UTF_ZeroMQPublishing.ipf b/Packages/tests/Basic/UTF_ZeroMQPublishing.ipf index 873672db25..3ffd1aff60 100644 --- a/Packages/tests/Basic/UTF_ZeroMQPublishing.ipf +++ b/Packages/tests/Basic/UTF_ZeroMQPublishing.ipf @@ -631,3 +631,145 @@ static Function CheckTPPublishingWithData() JSON_Release(jsonID) End + +static Function CheckConfigurationFinished() + + string windowName, file, rigFile, panelType, actual, expected + variable jsonID + + windowName = "Databrowser" + file = "fileA" + rigFile = "fileB" + panelType = PANELTAG_DATABROWSER + + PUB_ConfigurationFinished(windowName, panelType, file, rigFile) + + jsonID = FetchAndParseMessage(CONFIG_FINISHED_FILTER) + + actual = JSON_GetString(jsonID, "/window") + expected = windowName + CHECK_EQUAL_STR(actual, expected) + + actual = JSON_GetString(jsonID, "/panelType") + expected = panelType + CHECK_EQUAL_STR(actual, expected) + + actual = JSON_GetString(jsonID, "/fileName") + expected = file + CHECK_EQUAL_STR(actual, expected) + + actual = JSON_GetString(jsonID, "/rigFileName") + expected = rigFile + CHECK_EQUAL_STR(actual, expected) + + JSON_Release(jsonID) +End + +static Function CheckAmplifierSettingChange() + + string device, actual, expected, name, unit, path + variable jsonID, valActual, valExpected, headstage, mode, value, func + + device = "my_device" + headstage = 1 + mode = V_CLAMP_MODE + func = MCC_HOLDINGENABLE_FUNC + name = "HoldingPotentialEnable" + unit = "On/Off" + value = 1 + + PUB_AmplifierSettingChange(device, headstage, mode, func, value) + + jsonID = FetchAndParseMessage(AMPLIFIER_SET_VALUE) + + actual = JSON_GetString(jsonID, "/device") + expected = device + CHECK_EQUAL_STR(actual, expected) + + valActual = JSON_GetVariable(jsonID, "/headstage") + valExpected = headstage + CHECK_EQUAL_VAR(valActual, valExpected) + + actual = JSON_GetString(jsonID, "/clamp mode") + expected = ConvertAmplifierModeToString(mode) + CHECK_EQUAL_STR(actual, expected) + + path = "/amplifier action/" + name + valActual = JSON_GetType(jsonID, path) + valExpected = JSON_OBJECT + CHECK_EQUAL_VAR(valActual, valExpected) + + CHECK_EQUAL_STR(actual, expected) + + valActual = JSON_GetVariable(jsonID, path + "/value") + valExpected = value + CHECK_EQUAL_VAR(valActual, valExpected) + + actual = JSON_GetString(jsonID, path + "/unit") + expected = unit + CHECK_EQUAL_STR(actual, expected) + + JSON_Release(jsonID) +End + +/// Filter: #TESTPULSE_SET_VALUE_FILTER +/// +/// Example: +/// +/// \rst +/// .. code-block:: json +/// +/// { +/// "device": "my_device", +/// "headstage": 1, +/// "sweep number": "NaN", +/// "testpulse setting": { +/// "my name": { +/// "unit": "On/Off", +/// "value": 1 +/// } +/// }, +/// "timestamp": "2025-04-25T20:26:44Z" +/// } +/// +/// \endrst +static Function CheckTestpulseSettingChange() + + string device, name, unit, actual, expected, path + variable value, headstage, jsonID, valActual, valExpected + + device = "my_device" + headstage = 1 + name = "my name" + unit = "On/Off" + value = 1 + + PUB_TPSettingChange(device, headstage, name, value, unit) + + jsonID = FetchAndParseMessage(TESTPULSE_SET_VALUE_FILTER) + + actual = JSON_GetString(jsonID, "/device") + expected = device + CHECK_EQUAL_STR(actual, expected) + + valActual = JSON_GetVariable(jsonID, "/headstage") + valExpected = headstage + CHECK_EQUAL_VAR(valActual, valExpected) + + path = "/testpulse setting/" + name + valActual = JSON_GetType(jsonID, path) + valExpected = JSON_OBJECT + CHECK_EQUAL_VAR(valActual, valExpected) + + CHECK_EQUAL_STR(actual, expected) + + valActual = JSON_GetVariable(jsonID, path + "/value") + valExpected = value + CHECK_EQUAL_VAR(valActual, valExpected) + + actual = JSON_GetString(jsonID, path + "/unit") + expected = unit + CHECK_EQUAL_STR(actual, expected) + + JSON_Release(jsonID) +End diff --git a/Packages/tests/HardwareBasic/UTF_ConfigurationHardware.ipf b/Packages/tests/HardwareBasic/UTF_ConfigurationHardware.ipf index 314dd01f41..dfea2094c2 100644 --- a/Packages/tests/HardwareBasic/UTF_ConfigurationHardware.ipf +++ b/Packages/tests/HardwareBasic/UTF_ConfigurationHardware.ipf @@ -100,9 +100,11 @@ End // UTF_TD_GENERATOR DeviceNameGeneratorMD1 static Function CheckIfConfigurationRestoresMCCFilterGain([string str]) - string rewrittenConfig, fName + string rewrittenConfig, fName, path variable val, gain, filterFreq, headStage, jsonID + PrepareForPublishTest() + fName = PrependExperimentFolder_IGNORE("CheckIfConfigurationRestoresMCCFilterGain.json") STRUCT DAQSettings s @@ -119,6 +121,13 @@ static Function CheckIfConfigurationRestoresMCCFilterGain([string str]) AI_WriteToAmplifier(str, headStage + 1, I_CLAMP_MODE, MCC_PRIMARYSIGNALLPF_FUNC, filterFreq) AI_WriteToAmplifier(str, headStage + 1, I_CLAMP_MODE, MCC_PRIMARYSIGNALGAIN_FUNC, gain) + jsonID = FetchAndParseMessage(AMPLIFIER_SET_VALUE) + CHECK_EQUAL_VAR(JSON_GetVariable(jsonID, "/headstage"), headStage) + path = "/amplifier action/SetPrimarySignalLPF" + CHECK_EQUAL_STR(JSON_GetString(jsonID, path + "/unit"), "kHz") + CHECK_EQUAL_VAR(JSON_GetVariable(jsonID, path + "/value"), filterFreq) + JSON_Release(jsonID) + PGC_SetAndActivateControl(str, "check_Settings_SyncMiesToMCC", val = 1) CONF_SaveWindow(fName) diff --git a/Packages/tests/HardwareBasic/UTF_TestPulseAndTPDuringDAQ.ipf b/Packages/tests/HardwareBasic/UTF_TestPulseAndTPDuringDAQ.ipf index f2c131e02b..e3da045ea7 100644 --- a/Packages/tests/HardwareBasic/UTF_TestPulseAndTPDuringDAQ.ipf +++ b/Packages/tests/HardwareBasic/UTF_TestPulseAndTPDuringDAQ.ipf @@ -125,7 +125,20 @@ End static Function CheckTPEntriesFromLBN_PreAcq(string device) + variable jsonID + string path + + PrepareForPublishTest() + PGC_SetAndActivateControl(device, "setvar_Settings_TP_RTolerance", val = 2) + + jsonID = FetchAndParseMessage(TESTPULSE_SET_VALUE_FILTER) + CHECK_EQUAL_VAR(JSON_GetVariable(jsonID, "/headstage"), NaN) + path = "/testpulse setting/resistanceTol" + CHECK_EQUAL_STR(JSON_GetString(jsonID, path + "/unit"), "MΩ") + CHECK_EQUAL_VAR(JSON_GetVariable(jsonID, path + "/value"), 2) + JSON_Release(jsonID) + PGC_SetAndActivateControl(device, "setvar_Settings_TPBuffer", val = 3) // turn off send to all HS diff --git a/Packages/tests/UTF_HelperFunctions.ipf b/Packages/tests/UTF_HelperFunctions.ipf index 95e185d19a..848dfa7e41 100644 --- a/Packages/tests/UTF_HelperFunctions.ipf +++ b/Packages/tests/UTF_HelperFunctions.ipf @@ -13,7 +13,7 @@ #include "UTF_Constants" #include "UTF_DataGenerators" -// #define OUTPUT_DOCUMENTATION_JSON_DUMP +#define OUTPUT_DOCUMENTATION_JSON_DUMP /// @file UTF_HelperFunctions.ipf /// @brief This file holds helper functions for the tests @@ -251,6 +251,7 @@ static Function CheckMessageFilters_IGNORE(string filter) WAVE/Z/T allFilters = FFI_GetAvailableMessageFilters() CHECK_WAVE(allFilters, TEXT_WAVE) + INFO("FFI_GetAvailableMessageFilters() needs updating as %s is missing.", s0 = filter) FindValue/TXOP=4/TEXT=(filter) allFilters CHECK_GE_VAR(V_Value, 0) End