diff --git a/otsdaq-mu2e/FEInterfaces/CFOFrontEndInterfaceImpl.cc b/otsdaq-mu2e/FEInterfaces/CFOFrontEndInterfaceImpl.cc index 7840e5b3..10f02186 100644 --- a/otsdaq-mu2e/FEInterfaces/CFOFrontEndInterfaceImpl.cc +++ b/otsdaq-mu2e/FEInterfaces/CFOFrontEndInterfaceImpl.cc @@ -157,7 +157,7 @@ void CFOFrontEndInterface::registerFEMacros(void) static_cast( &CFOFrontEndInterface::LoopbackTest), // feMacroFunction std::vector{ // namesOfInputArgs - "Number of Loopback Exponent (Default := 3, which is 8 Loopback Markers sent)", + // "Number of Loopback Exponent (Default := 3, which is 8 Loopback Markers sent)", // as of June 2026 -- defaulting to 0 exponent always (first loopback is somehow different than 2+ loopbacks) "Number of Loopback tests (Default := 1)", "Target Link (-1 for all, Default := -1)", "Target ROC (-1 for all, Default := -1)", @@ -617,10 +617,11 @@ void CFOFrontEndInterface::LoopbackTest(__ARGS__) ostr << std::endl; // parameters - const int numberOfLoopbacksExp = __GET_ARG_IN__( - "Number of Loopback Exponent (Default := 3, which is 8 Loopback Markers sent)", - uint32_t, - 3); + const int numberOfLoopbacksExp = 0; + // __GET_ARG_IN__( + // "Number of Loopback Exponent (Default := 3, which is 8 Loopback Markers sent)", + // uint32_t, + // 3); const int numberOfLoopbackTests = __GET_ARG_IN__("Number of Loopback tests (Default := 1)", uint32_t, 1); const int targetLink = @@ -865,6 +866,43 @@ void CFOFrontEndInterface::LoopbackTest(__ARGS__) } } } + + // build Plotly histogram of delay measurements + { + std::stringstream plotlySs; + plotlySs << R"({"data":[)"; + + bool firstTrace = true; + for(const auto& [map_index, results] : roc_results) + { + const int counts = results.counts; + if(counts <= 0) + continue; + + if(!firstTrace) + plotlySs << ","; + firstTrace = false; + + plotlySs << R"({"x":[)"; + for(int i = 0; i < counts; ++i) + { + if(i > 0) + plotlySs << ","; + plotlySs << results.graph->GetY()[i]; + } + plotlySs << R"(],"type":"histogram","name":"Link )" << (map_index / 100) + << " ROC " << (map_index % 100) << R"(","opacity":0.75})"; + } + + plotlySs << R"(],"layout":{)" + << R"("title":{"text":"CFO Loopback Delay"},)" + << R"("xaxis":{"title":{"text":"Delay [ns]"}},)" + << R"("yaxis":{"title":{"text":"Count"}},)" + << R"("barmode":"overlay"}})"; + + __SET_ARG_OUT__(PLOTLY_PLOT, plotlySs.str()); + } + if(writeFile) { tree->Write(); @@ -933,6 +971,18 @@ void CFOFrontEndInterface::LoopbackTest(__ARGS__) // ostr << std::endl << std::endl; + bool anySuccessful = false; + for(const auto& [map_index, results] : roc_results) + if(results.counts > 0) + { + anySuccessful = true; + break; + } + if(!anySuccessful) + ostr << "No loopback measurements were successful. Check the link status of " + "targeted links." + << std::endl; + __SET_ARG_OUT__("Response", ostr.str()); } // end LoopbackTest() diff --git a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc index 411d3322..de7297f6 100644 --- a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc +++ b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc @@ -630,8 +630,8 @@ void DTCFrontEndInterface::registerFEMacros(void) "Loopback Manual Setup", static_cast( &DTCFrontEndInterface::ManualLoopbackSetup), - std::vector{"setAsPassthrough"}, - std::vector{}, + std::vector{"setAsPassthrough (Default := false)"}, + std::vector{"Result"}, 1, // requiredUserPermissions "*", "Toggles the DTC CFO loopback mode. " @@ -7802,22 +7802,42 @@ void DTCFrontEndInterface::CFOEmulatorLoopbackTests(__ARGS__) __SET_ARG_OUT__("Average", std::format("{:.2f} ns", result)); __SET_ARG_OUT__("Maximum", std::format("{:.2f} ns", max_value)); __SET_ARG_OUT__("Minimum", std::format("{:.2f} ns", min_value)); + + // build Plotly histogram of delay measurements + { + std::stringstream plotlySs; + plotlySs << R"({"data":[{"x":[)"; + for(int i = 0; i < numberOfTests; ++i) + { + if(i > 0) + plotlySs << ","; + plotlySs << results[i]; + } + plotlySs << R"(],"type":"histogram","name":"Loopback Delay","opacity":0.75}])" + << R"(,"layout":{)" + << R"("title":{"text":"CFO Emulator Loopback Delay"},)" + << R"("xaxis":{"title":{"text":"Delay [ns]"}},)" + << R"("yaxis":{"title":{"text":"Count"}}}})"; + + __SET_ARG_OUT__(PLOTLY_PLOT, plotlySs.str()); + } } //end CFOEmulatorLoopbackTests() //======================================================================== void DTCFrontEndInterface::ManualLoopbackSetup(__ARGS__) { - bool setAsPassthrough = __GET_ARG_IN__("setAsPassthrough", bool); + bool setAsPassthrough = __GET_ARG_IN__("setAsPassthrough (Default := false)", bool); __COUTV__(setAsPassthrough); if(setAsPassthrough) { getDTC()->DisableCFOLoopback(); - return; } else getDTC()->EnableCFOLoopback(); + __SET_ARG_OUT__("Result", getDTC()->FormatDTCControl()); + //as of June 2026, do not target one ROC (all done at once) return; @@ -7831,7 +7851,6 @@ void DTCFrontEndInterface::ManualLoopbackSetup(__ARGS__) getDTC()->DisableLink(DTCLib::DTC_ROC_Links[i]); getDTC()->EnableLink(DTCLib::DTC_ROC_Links[ROC_Link]); - } //end ManualLoopbackSetup() //========================================================================