1 #include "otsdaq/TablePlugins/ARTDAQTableBase/ARTDAQTableBase.h"
11 #include "otsdaq/Macros/CoutMacros.h"
12 #define TRACE_NAME "ARTDAQTableBase"
14 #include <fhiclcpp/ParameterSet.h>
15 #include <fhiclcpp/detail/print_mode.h>
16 #include <fhiclcpp/intermediate_table.h>
17 #include <fhiclcpp/parse.h>
19 #include "otsdaq/ProgressBar/ProgressBar.h"
20 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
25 #define __MF_SUBJECT__ "ARTDAQTableBase"
37 static size_t fhiclFlattenCount_ = 0;
38 static double fhiclFlattenSeconds_ = 0;
39 static size_t fhiclFlattenCountCumulative_ = 0;
40 static double fhiclFlattenSecondsCumulative_ = 0;
41 static size_t extractInvocation_ = 0;
45 static std::mutex fhiclFlattenStatsMutex_;
52 static std::chrono::steady_clock::time_point fhiclTraceLastActivity_{};
53 static const double FHICL_TRACE_RESET_GAP_S = 30.0;
58 static void maybeResetFHiCLTimingTrace()
60 std::lock_guard<std::mutex> lock(fhiclFlattenStatsMutex_);
61 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
62 if(fhiclFlattenCountCumulative_ > 0 || extractInvocation_ > 0)
64 double gap = std::chrono::duration<double>(now - fhiclTraceLastActivity_).count();
65 if(gap > FHICL_TRACE_RESET_GAP_S)
67 fhiclFlattenCountCumulative_ = 0;
68 fhiclFlattenSecondsCumulative_ = 0;
69 extractInvocation_ = 0;
72 fhiclTraceLastActivity_ = now;
77 #define FCL_COMMENT_POSITION 65
81 #define OUTCF(X,C,F) { std::stringstream outSs; outSs << X; addCommentWhitespace(outSs, tabStr.size()*TABSZ + commentStr.size() + outSs.str().size()); outSs << (C) << (std::string(C).size()?" - ":"") << "from config-tree: " << parentPath << (std::string(F).size()?(std::string("/") + std::string(F)):std::string("")) << "\n"; OUT << outSs.str();}
83 #define OUTC(X,C) OUTCF(X,C,"")
85 #define OUTCLF(X,C,F) { std::stringstream outSs; outSs << X; addCommentWhitespace(outSs, tabStr.size()*TABSZ + commentStr.size() + outSs.str().size()); outSs << (C) << (std::string(C).size()?" - ":"") << "from config-tree: " << localParentPath << std::string(std::string(F).size()?("/" + std::string(F)):std::string("")) << "\n"; OUT << outSs.str();}
87 #define OUTCL(X,C) OUTCLF(X,C,"")
89 #define OUTCL2F(X,C,F) { std::stringstream outSs; outSs << X; addCommentWhitespace(outSs, tabStr.size()*TABSZ + commentStr.size() + outSs.str().size()); outSs << (C) << (std::string(C).size()?" - ":"") << "from config-tree: " << localParentPath2 << (std::string(F).size()?(std::string("/") + std::string(F)):std::string("")) << "\n"; OUT << outSs.str();}
91 #define OUTCL2(X,C) OUTCL2F(X,C,"")
96 const std::string ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH =
97 (((getenv(
"SERVICE_DATA_PATH") == NULL)
98 ? (std::string(getenv(
"USER_DATA")) +
"/ServiceData")
99 : std::string(getenv(
"SERVICE_DATA_PATH")))) +
100 "/ConfigurationGUI_artdaqLayouts/";
101 const bool ARTDAQTableBase::ARTDAQ_DONOTWRITE_FCL = ((getenv(
"OTS_FCL_DONOTWRITE") == NULL) ?
false :
true);
103 const std::string ARTDAQTableBase::ARTDAQ_SUPERVISOR_CLASS =
"ots::ARTDAQSupervisor";
104 const std::string ARTDAQTableBase::ARTDAQ_SUPERVISOR_TABLE =
"ARTDAQSupervisorTable";
106 const std::string ARTDAQTableBase::ARTDAQ_READER_TABLE =
"ARTDAQBoardReaderTable";
107 const std::string ARTDAQTableBase::ARTDAQ_BUILDER_TABLE =
"ARTDAQEventBuilderTable";
108 const std::string ARTDAQTableBase::ARTDAQ_LOGGER_TABLE =
"ARTDAQDataLoggerTable";
109 const std::string ARTDAQTableBase::ARTDAQ_DISPATCHER_TABLE =
"ARTDAQDispatcherTable";
110 const std::string ARTDAQTableBase::ARTDAQ_MONITOR_TABLE =
"ARTDAQMonitorTable";
111 const std::string ARTDAQTableBase::ARTDAQ_ROUTER_TABLE =
"ARTDAQRoutingManagerTable";
113 const std::string ARTDAQTableBase::ARTDAQ_SUBSYSTEM_TABLE =
"ARTDAQSubsystemTable";
114 const std::string ARTDAQTableBase::ARTDAQ_DAQ_TABLE =
"ARTDAQDaqTable";
115 const std::string ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE =
"ARTDAQDaqParameterTable";
116 const std::string ARTDAQTableBase::ARTDAQ_ART_TABLE =
"ARTDAQArtTable";
118 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME =
"ExecutionHostname";
119 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS =
"AllowedProcessors";
120 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK =
"SubsystemLink";
121 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID =
"SubsystemLinkUID";
124 const int ARTDAQTableBase::NULL_SUBSYSTEM_DESTINATION = 0;
125 const std::string ARTDAQTableBase::NULL_SUBSYSTEM_DESTINATION_LABEL =
"nullDestinationSubsystem";
149 std::string* accumulatedExceptions )
150 :
TableBase(tableName, accumulatedExceptions)
162 std::cout <<
"ARTDAQTableBase Before traceTID=" << traceTID << __E__;
164 traceInit(trace_name(TRACE_NAME, __TRACE_FILE__, buf,
sizeof(buf)), 0);
165 std::cout <<
"ARTDAQTableBase After traceTID=" << traceTID << __E__;
166 __COUT__ <<
"ARTDAQTableBase TRACE reinit and Constructed." << __E__;
176 __SS__ <<
"Should not call void constructor, table type is lost!" << __E__;
181 ARTDAQTableBase::~ARTDAQTableBase(
void) {}
197 __COUT_INFO__ <<
"ARTDAQ Supervisor is disabled, so skipping fcl handling."
212 const std::string& ARTDAQTableBase::getTypeString(ARTDAQAppType type)
216 case ARTDAQAppType::EventBuilder:
218 case ARTDAQAppType::DataLogger:
220 case ARTDAQAppType::Dispatcher:
222 case ARTDAQAppType::BoardReader:
224 case ARTDAQAppType::Monitor:
226 case ARTDAQAppType::RoutingManager:
230 __SS__ <<
"Illegal translation attempt for type '" << (
unsigned int)type <<
"'"
236 std::string ARTDAQTableBase::getFHICLFilename(ARTDAQAppType type,
const std::string& name)
241 std::string uid = name;
242 for(
unsigned int i = 0; i < uid.size(); ++i)
243 if((uid[i] >=
'a' && uid[i] <=
'z') || (uid[i] >=
'A' && uid[i] <=
'Z') ||
244 (uid[i] >=
'0' && uid[i] <=
'9'))
255 std::string ARTDAQTableBase::getFlatFHICLFilename(ARTDAQAppType type,
256 const std::string& name)
261 std::string uid = name;
262 for(
unsigned int i = 0; i < uid.size(); ++i)
263 if((uid[i] >=
'a' && uid[i] <=
'z') || (uid[i] >=
'A' && uid[i] <=
'Z') ||
264 (uid[i] >=
'0' && uid[i] <=
'9'))
267 filename +=
"_flattened.fcl";
275 void ARTDAQTableBase::flattenFHICL(ARTDAQAppType type,
276 const std::string& name,
277 std::string* returnFcl )
279 maybeResetFHiCLTimingTrace();
280 std::chrono::steady_clock::time_point startClock = std::chrono::steady_clock::now();
281 __COUTS__(3) <<
"flattenFHICL()" << __ENV__(
"FHICL_FILE_PATH") << __E__;
285 std::string inFile = getFHICLFilename(type, name);
286 std::string outFile = getFlatFHICLFilename(type, name);
288 __COUTVS__(3, inFile);
289 __COUTVS__(3, outFile);
291 cet::filepath_lookup_nonabsolute policy(
"FHICL_FILE_PATH");
292 fhicl::ParameterSet pset;
296 __COUT_INFO__ <<
"parsing document: " << inFile;
299 pset = fhicl::ParameterSet::make(inFile, policy);
300 __COUTT__ <<
"document: " << inFile <<
" parsed";
301 __COUTT__ <<
"got pset from table:";
303 std::ofstream ofs{outFile};
306 __SS__ <<
"Failed to open fhicl output file '" << outFile <<
"!'" << __E__;
309 std::ostringstream out;
310 out << pset.to_indented_string(
314 *returnFcl = out.str();
315 __COUTVS__(21, returnFcl);
319 catch(cet::exception
const& e)
321 __SS__ <<
"Failed to parse fhicl into output file '" << outFile
322 <<
"' - here is the error: " << e.what() << __E__;
325 if(std::string(e.what()).find(
"TriggerEpilogs") != std::string::npos)
327 <<
"The Trigger Epilogs are located at "
328 "$USER_DATA/TriggerConfigurations/TriggerEpilogs. "
329 <<
"Please check that the Trigger Epilogs were properly generated, or "
330 "copy them from a previously working area."
335 double flattenElapsed = artdaq::TimeUtils::GetElapsedTime(startClock);
337 std::lock_guard<std::mutex> lock(fhiclFlattenStatsMutex_);
338 ++fhiclFlattenCount_;
339 fhiclFlattenSeconds_ += flattenElapsed;
340 ++fhiclFlattenCountCumulative_;
341 fhiclFlattenSecondsCumulative_ += flattenElapsed;
344 __COUTT__ << name <<
" Flatten Clock time = " << flattenElapsed << __E__;
354 void ARTDAQTableBase::flattenFHICLInParallel(
356 const std::vector<std::pair<std::string, std::string*>>& namesAndReturnFcls)
358 if(namesAndReturnFcls.empty())
363 size_t threadCap = 8;
364 if(
const char* threadsOverride = getenv(
"OTS_FHICL_FLATTEN_THREADS"))
366 int overrideValue = atoi(threadsOverride);
367 if(overrideValue > 0)
368 threadCap =
static_cast<size_t>(overrideValue);
370 size_t threadCount = std::min<size_t>(threadCap, namesAndReturnFcls.size());
373 for(
auto& nameAndReturnFcl : namesAndReturnFcls)
374 flattenFHICL(type, nameAndReturnFcl.first, nameAndReturnFcl.second);
378 std::chrono::steady_clock::time_point startClock = std::chrono::steady_clock::now();
380 std::atomic<size_t> nextIndex(0);
381 std::exception_ptr firstError =
nullptr;
382 std::mutex errorMutex;
383 std::vector<std::thread> workers;
393 std::vector<std::thread>& workers;
396 for(
auto& worker : workers)
397 if(worker.joinable())
400 } workerJoiner{workers};
402 for(
size_t i = 0; i < threadCount; ++i)
403 workers.emplace_back([&]() {
406 size_t index = nextIndex.fetch_add(1);
407 if(index >= namesAndReturnFcls.size())
412 namesAndReturnFcls[index].first,
413 namesAndReturnFcls[index].second);
417 std::lock_guard<std::mutex> lock(errorMutex);
419 firstError = std::current_exception();
424 for(
auto& worker : workers)
425 if(worker.joinable())
429 std::rethrow_exception(firstError);
431 __COUT_INFO__ <<
"Parallel flatten of " << namesAndReturnFcls.size() <<
" "
432 << getTypeString(type) <<
" fcl document(s) with " << threadCount
433 <<
" threads took " << artdaq::TimeUtils::GetElapsedTime(startClock)
444 void ARTDAQTableBase::insertParameters(std::ostream& out,
446 std::string& commentStr,
447 const std::string& parentPath,
449 const std::string& parameterPreamble,
450 bool onlyInsertAtTableParameters ,
451 bool includeAtTableParameters )
457 auto otherParameters = parameterGroupLink.
getChildren();
462 __COUTVS__(3, otherParameters.size());
463 __COUTVS__(3, onlyInsertAtTableParameters);
464 __COUTVS__(3, includeAtTableParameters);
466 size_t paramCount = 0;
467 for(
auto& parameter : otherParameters)
469 key = parameter.second.getNode(parameterPreamble +
"Key").getValue();
471 std::string localParentPath =
473 parameter.second.getTableName() +
":" +
475 parameterGroupLink.
getParentLinkID() +
"/" + parameter.second.getValue();
479 if(key.find(
"@table::") != std::string::npos)
482 if(onlyInsertAtTableParameters || includeAtTableParameters)
485 if(!parameter.second.status())
488 __COUTT__ <<
"Inserting parameter... " << localParentPath << __E__;
491 OUTCL(key << parameter.second.getNode(parameterPreamble +
"Value")
493 parameter.second.hasComment() ? parameter.second.getComment()
496 if(!parameter.second.status())
505 if(onlyInsertAtTableParameters)
509 if(!parameter.second.status())
512 __COUTT__ <<
"Inserting parameter... " << localParentPath << __E__;
515 if(key.size() && key.find(
"#include") == std::string::npos)
520 parameter.second.getNode(parameterPreamble +
"Value").getValue();
523 if(value.size() > 2 && value[0] ==
'@' && value[1] ==
'@')
526 <<
"Checking for getFclValueForARTDAQ @@ indicator from value = "
528 std::string potentialTable = value.substr(2);
529 __COUTTV__(potentialTable);
534 ->getFclValueForARTDAQ(cfgMgr, key);
536 catch(
const std::runtime_error& e)
538 __SS__ <<
"getFclValueForARTDAQ @@ indicator from value = "
539 << value <<
" corresponds to table '" << potentialTable
540 <<
"'... however fcl value failed to load: " << e.what();
544 __COUTT__ <<
"Value from getFclValueForARTDAQ: value = " << value
547 std::string localParentPath2 =
"/" + potentialTable;
548 OUTCL2(key <<
": " << value,
549 parameter.second.hasComment() ? parameter.second.getComment()
555 << parameter.second.getNode(parameterPreamble +
"Value")
557 parameter.second.hasComment() ? parameter.second.getComment()
563 OUTCL(parameter.second.getNode(parameterPreamble +
"Value").getValue(),
564 parameter.second.hasComment() ? parameter.second.getComment() :
"");
568 OUTCL(
"# comment for #include below:",
569 parameter.second.hasComment() ? parameter.second.getComment() :
"");
571 << parameter.second.getNode(parameterPreamble +
"Value").getValue()
575 if(!parameter.second.status())
581 __COUTS__(3) <<
"Empty parameter set found onlyInsertAtTableParameters="
582 << onlyInsertAtTableParameters << __E__;
583 std::string localParentPath =
586 if(onlyInsertAtTableParameters)
588 OUTCL(
"# no @table parameters found",
"" );
592 OUTCL(
"# empty parameter set found",
"" );
598 __COUTS__(3) <<
"No parameters found" << __E__;
599 std::string localParentPath =
601 OUTCL(
"# no parameters inserted",
"" );
611 std::string& commentStr,
612 const std::string& parentPath,
615 std::string value = moduleTypeNode.
getValue();
616 __COUTTV__(parentPath);
617 OUTCF((value.find(
"@table::") == std::string::npos ?
"module_type: " :
"") << value,
627 std::string& commentStr,
628 const std::string& parentPath,
631 auto metricsGroup = daqNode.
getNode(
"daqMetricsLink");
634 OUTCF(
"metrics: {",
"", metricsGroup.getParentLinkColumnName());
636 if(!metricsGroup.isDisconnected())
638 auto metrics = metricsGroup.getChildren();
639 bool sendSystemMetrics(
false), sendProcessMetrics(
false);
640 for(
auto& metric : metrics)
642 if(!metric.second.status())
645 __COUTT__ <<
"Inserting metric... " << parentPath << __E__;
646 std::string localParentPath =
647 parentPath +
"/" + metricsGroup.getParentLinkColumnName() +
":" +
648 metric.second.getTableName() +
":" + metricsGroup.getParentLinkIndex() +
649 ":" + metricsGroup.getParentLinkID() +
"/" + metric.second.getValue();
650 __COUTT__ <<
"Inserting metric... " << localParentPath << __E__;
652 OUTCL(metric.second.getNode(
"metricKey").getValue() <<
": {",
653 metric.second.hasComment() ? metric.second.getComment() :
"");
656 if(metric.second.getNode(
"sendSystemMetrics").getValue<
bool>())
658 sendSystemMetrics =
true;
660 if(metric.second.getNode(
"sendProcessMetrics").getValue<
bool>())
662 sendProcessMetrics =
true;
665 OUTCLF(
"metricPluginType: "
666 << metric.second.getNode(
"metricPluginType").getValue(),
670 "level_string: " << metric.second.getNode(
"metricLevelString").getValue(),
672 "metricLevelString");
674 auto metricParametersGroup = metric.second.getNode(
"metricParametersLink");
675 if(!metricParametersGroup.isDisconnected())
677 auto metricParameters = metricParametersGroup.getChildren();
678 for(
auto& metricParameter : metricParameters)
680 if(!metricParameter.second.status())
683 __COUTT__ <<
"Inserting metric... " << localParentPath << __E__;
684 std::string localParentPath2 =
685 localParentPath +
"/" +
686 metricParametersGroup.getParentLinkColumnName() +
":" +
687 metricParameter.second.getTableName() +
":" +
688 metricParametersGroup.getParentLinkIndex() +
":" +
689 metricParametersGroup.getParentLinkID() +
"/" +
690 metricParameter.second.getValue();
691 __COUTT__ <<
"Inserting metric... " << localParentPath2 << __E__;
692 OUTCL2(metricParameter.second.getNode(
"metricParameterKey").getValue()
694 << metricParameter.second.getNode(
"metricParameterValue")
696 metricParameter.second.hasComment()
697 ? metricParameter.second.getComment()
700 if(!metricParameter.second.status())
705 OUT <<
"} # end " << metric.second.getNode(
"metricKey").getValue()
708 if(!metric.second.status())
712 __COUTT__ <<
"Inserting metric send... " << parentPath << __E__;
713 std::string localParentPath =
714 parentPath +
"/" + metricsGroup.getParentLinkColumnName() +
":" +
715 metricsGroup.getTableName() +
":" + metricsGroup.getParentLinkIndex() +
":" +
716 metricsGroup.getParentLinkID();
717 if(sendSystemMetrics)
719 __COUTT__ <<
"Inserting send_system_metrics... " << localParentPath << __E__;
720 OUTCLF(
"send_system_metrics: true ",
721 "true, if any children are true",
722 "*/sendSystemMetrics");
725 OUTCLF(
"# send_system_metrics: false ",
726 "true, if any children are true",
727 "*/sendSystemMetrics");
729 if(sendProcessMetrics)
731 __COUTT__ <<
"Inserting send_process_metrics... " << localParentPath << __E__;
732 OUTCLF(
"send_process_metrics: true ",
733 "true, if any children are true",
734 "*/sendProcessMetrics");
737 OUTCLF(
"# send_process_metrics: false ",
738 "true, if any children are true",
739 "*/sendProcessMetrics");
743 __COUTS__(3) <<
"No metrics found" << __E__;
744 std::string localParentPath =
745 parentPath +
"/" + metricsGroup.getParentLinkColumnName();
746 OUTCL(
"# no metrics found",
"" );
750 OUT <<
"} # end metrics\n\n";
754 void ARTDAQTableBase::outputBoardReaderFHICL(
757 size_t routingTimeoutMs ,
758 size_t routingRetryCount )
760 if(ARTDAQ_DONOTWRITE_FCL)
762 __COUT__ <<
"Skipping fcl generation." << __E__;
891 std::string filename =
892 getFHICLFilename(ARTDAQAppType::BoardReader, boardReaderNode.
getValue());
898 std::string tabStr =
"";
899 std::string commentStr =
"";
902 out.open(filename, std::fstream::out | std::fstream::trunc);
905 __SS__ <<
"Failed to open ARTDAQ BoardReader fcl file: " << filename << __E__;
913 OUT <<
"###########################################################" << __E__;
915 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::BoardReader)
916 <<
" fcl configuration file produced by otsdaq." << __E__;
919 OUT <<
"# Original filename: \t" << filename << __E__;
920 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(ARTDAQAppType::BoardReader)
921 <<
" UID:\t" << boardReaderNode.
getValue() << __E__;
923 OUT <<
"###########################################################" << __E__;
937 catch(
const std::runtime_error&)
939 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
944 std::string parentPath =
947 OUTC(
"# start of " << getTypeString(ARTDAQAppType::BoardReader) <<
" '"
948 << boardReaderNode.
getValue() <<
"' fcl",
953 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
954 <<
" preamble parameters... " << parentPath << __E__;
960 boardReaderNode.
getNode(
"preambleParametersLink"),
967 __COUTT__ <<
"Generating daq block..." << __E__;
974 OUT <<
"fragment_receiver: {\n";
981 "daq generator plug-in type" ,
982 "daqGeneratorPluginType" );
983 OUTCF(
"fragment_type"
986 "generator data fragment type" ,
987 "daqGeneratorFragmentType" );
989 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
990 <<
" DAQ Parameters... " << parentPath << __E__;
996 boardReaderNode.
getNode(
"daqParametersLink"),
1001 auto fragmentId = boardReaderNode.
getNode(
"daqFragmentIDs");
1002 std::string value = fragmentId.
getValue();
1003 if(value.size() < 2 || value[0] !=
'[' || value[value.size() - 1] !=
']')
1005 __SS__ <<
"Invalid 'daqFragmentIDs' - the value must be a valid fcl "
1006 "array with starting and ending square brackets: [ ]"
1010 __COUTS__(20) <<
"fragment_ids: " << fragmentId.getValue() << __E__;
1011 OUTCF(
"fragment_ids: " << fragmentId.getValue(),
1017 __COUTT__ <<
"Ignoring missing daqFragmentIDs column associated with "
1018 "fragment_ids for Board Reader."
1021 OUTCF(
"# fragment_ids not specified, but could be",
"",
"daqFragmentIDs");
1027 OUT <<
"destinations: { # empty placeholder, '"
1028 << getTypeString(ARTDAQAppType::BoardReader)
1029 <<
"' destinations handled by artdaq interface\n";
1032 OUT <<
"routing_table_config: {\n";
1035 auto readerSubsystemID = 1;
1036 auto readerSubsystemLink = boardReaderNode.
getNode(
"SubsystemLink");
1037 if(!readerSubsystemLink.isDisconnected())
1039 readerSubsystemID = getSubsytemId(readerSubsystemLink);
1041 if(info_.subsystems[readerSubsystemID].hasRoutingManager)
1043 std::string localParentPath =
1044 parentPath +
"/" + readerSubsystemLink.getParentLinkColumnName() +
":" +
1045 readerSubsystemLink.getTableName() +
"/" + readerSubsystemLink.getValue();
1046 __COUTT__ <<
"Inserting routing manager... " << localParentPath << __E__;
1047 OUTCL(
"use_routing_manager: true",
1048 "auto-generated because subsystem '" +
1049 std::to_string(readerSubsystemID) +
"' has Routing Manager added");
1051 OUTCLF(
"routing_manager_hostname: \""
1052 << info_.subsystems[readerSubsystemID].routingManagerHost <<
"\"",
1054 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
1055 OUT <<
"table_update_port: 0\n";
1056 OUT <<
"table_update_address: \"0.0.0.0\"\n";
1057 OUT <<
"table_update_multicast_interface: \"0.0.0.0\"\n";
1058 OUT <<
"table_acknowledge_port : 0\n";
1059 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
1060 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
1064 OUTCF(
"use_routing_manager: false",
1065 "auto-generated if subsystem '" + std::to_string(readerSubsystemID) +
1066 "' has Routing Manager added",
1067 readerSubsystemLink.getParentLinkColumnName());
1074 OUT <<
"} # end fragment_receiver\n";
1079 OUT <<
"} # end daq\n\n";
1084 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
1085 <<
" add-on parameters... " << parentPath << __E__;
1090 boardReaderNode.
getNode(
"addOnParametersLink"),
1095 OUTC(
"# end of " << getTypeString(ARTDAQAppType::BoardReader) <<
" '"
1096 << boardReaderNode.
getValue() <<
"' fcl",
1098 __COUTT__ <<
"outputBoardReaderFHICL DONE" << __E__;
1102 __SS__ <<
"\n\nError while generating FHiCL for "
1103 << getTypeString(ARTDAQAppType::BoardReader) <<
" node at filename '"
1104 << filename <<
"'" << __E__;
1109 catch(
const std::runtime_error& e)
1111 ss <<
" Here is the error: " << e.what() << __E__;
1113 catch(
const std::exception& e)
1115 ss <<
" Here is the error: " << e.what() << __E__;
1131 ARTDAQAppType appType,
1133 size_t routingTimeoutMs ,
1134 size_t routingRetryCount ,
1135 std::string* returnFcl )
1137 if(ARTDAQ_DONOTWRITE_FCL)
1139 __COUT__ <<
"Skipping fcl generation." << __E__;
1143 std::string filename = getFHICLFilename(appType, receiverNode.
getValue());
1148 std::ostringstream out;
1150 std::string tabStr =
"";
1151 std::string commentStr =
"";
1153 __COUTV__(filename);
1154 outf.open(filename, std::fstream::out | std::fstream::trunc);
1157 __SS__ <<
"Failed to open ARTDAQ fcl file: " << filename << __E__;
1165 OUT <<
"###########################################################" << __E__;
1166 OUT <<
"#" << __E__;
1167 OUT <<
"# artdaq " << getTypeString(appType)
1168 <<
" fcl configuration file produced by otsdaq." << __E__;
1169 OUT <<
"# Creation time: \t"
1171 OUT <<
"# Original filename: \t" << filename << __E__;
1172 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(appType) <<
" UID:\t"
1173 << receiverNode.
getValue() << __E__;
1174 OUT <<
"#" << __E__;
1175 OUT <<
"###########################################################" << __E__;
1187 *returnFcl = out.str();
1188 __COUTVS__(21, *returnFcl);
1195 catch(
const std::runtime_error&)
1197 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
1202 std::string parentPath =
1205 OUTC(
"# start of " << getTypeString(appType) <<
" '" << receiverNode.
getValue()
1211 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" preamble parameters... "
1212 << parentPath << __E__;
1218 receiverNode.
getNode(
"preambleParametersLink"),
1225 __COUTT__ <<
"Generating daq block..." << __E__;
1227 auto daq = receiverNode.
getNode(
"daqLink");
1228 if(!daq.isDisconnected())
1231 OUTCF(
"daq: {",
"" , daq.getParentLinkColumnName());
1234 if(appType == ARTDAQAppType::EventBuilder)
1235 OUT <<
"event_builder: {\n";
1237 OUT <<
"aggregator: {\n";
1242 std::stringstream outSs;
1243 if(appType == ARTDAQAppType::DataLogger)
1244 outSs <<
"is_datalogger: true";
1245 else if(appType == ARTDAQAppType::Dispatcher)
1246 outSs <<
"is_dispatcher: true";
1247 if(outSs.str().size())
1249 addCommentWhitespace(
1251 tabStr.size() * TABSZ + commentStr.size() + outSs.str().size());
1252 outSs <<
"auto-generated based on app type '"
1253 << getTypeString(appType) <<
"'\n";
1260 std::string parentPath = daq.getParentTableName() +
"/" +
1261 daq.getParentRecordName() +
"/" +
1262 daq.getParentLinkColumnName() +
":" +
1263 daq.getTableName() +
"/" + daq.getValue();
1264 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" DAQ Parameters... "
1265 << parentPath << __E__;
1270 daq.getNode(
"daqParametersLink"),
1275 if(appType == ARTDAQAppType::EventBuilder)
1278 OUT <<
"routing_token_config: {\n";
1281 auto builderSubsystemID = 1;
1282 auto builderSubsystemLink = receiverNode.
getNode(
"SubsystemLink");
1283 if(!builderSubsystemLink.isDisconnected())
1285 builderSubsystemID = getSubsytemId(builderSubsystemLink);
1287 if(info_.subsystems[builderSubsystemID].hasRoutingManager)
1289 std::string localParentPath =
1291 builderSubsystemLink.getParentLinkColumnName() +
":" +
1292 builderSubsystemLink.getTableName() +
"/" +
1293 builderSubsystemLink.getValue();
1294 __COUTT__ <<
"Inserting routing manager... " << localParentPath
1296 OUTCL(
"use_routing_manager: true",
1297 "auto-generated because subsystem '" +
1298 std::to_string(builderSubsystemID) +
1299 "' has Routing Manager added");
1301 OUTCLF(
"routing_manager_hostname: \""
1302 << info_.subsystems[builderSubsystemID].routingManagerHost
1305 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
1306 OUT <<
"routing_token_port: 0\n";
1310 OUTCF(
"use_routing_manager: false",
1311 "auto-generated if subsystem '" +
1312 std::to_string(builderSubsystemID) +
1313 "' has Routing Manager added",
1314 builderSubsystemLink.getParentLinkColumnName());
1320 __COUTT__ <<
"Adding sources placeholder" << __E__;
1322 OUT <<
"sources: { # empty placeholder, '" << getTypeString(appType)
1323 <<
"' sources handled by artdaq interface\n";
1328 if(appType == ARTDAQAppType::EventBuilder)
1329 OUT <<
"} # end event_builder\n";
1331 OUT <<
"} # end aggregator\n";
1336 OUT <<
"} # end daq\n\n";
1340 __COUTS__(3) <<
"No daq found" << __E__;
1341 std::string localParentPath =
1342 parentPath +
"/" + daq.getParentLinkColumnName();
1343 OUTCL(
"# no daq found",
"" );
1348 __COUTT__ <<
"Filling art block..." << __E__;
1351 receiverNode.
getNode(ARTDAQTableBase::colARTDAQNotReader_.colLinkToArt_);
1352 if(!art.isDisconnected())
1354 std::string localParentPath = parentPath +
"/" +
1356 art.getTableName() +
"/" + art.getValue();
1357 OUTCF(
"art: {",
"" , art.getParentLinkColumnName());
1366 receiverNode.
getNode(
"SubsystemLink"),
1371 OUT <<
"} # end art\n\n";
1375 __COUTS__(3) <<
"No art found" << __E__;
1376 std::string localParentPath =
1377 parentPath +
"/" + art.getParentLinkColumnName();
1378 OUTCL(
"# no art found",
"" );
1383 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" add-on parameters... "
1384 << parentPath << __E__;
1389 receiverNode.
getNode(
"addOnParametersLink"),
1395 OUTC(
"# end of " << getTypeString(appType) <<
" '" << receiverNode.
getValue()
1398 __COUTT__ <<
"outputDataReceiverFHICL DONE" << __E__;
1402 __SS__ <<
"\n\nError while generating FHiCL for " << getTypeString(appType)
1403 <<
" node at filename '" << filename <<
"'" << __E__;
1408 catch(
const std::runtime_error& e)
1410 ss <<
" Here is the error: " << e.what() << __E__;
1412 catch(
const std::exception& e)
1414 ss <<
" Here is the error: " << e.what() << __E__;
1419 *returnFcl = out.str();
1420 __COUTVS__(21, *returnFcl);
1429 *returnFcl = out.str();
1430 __COUTVS__(21, *returnFcl);
1441 if(ARTDAQ_DONOTWRITE_FCL)
1443 __COUT__ <<
"Skipping fcl generation." << __E__;
1447 std::string filename =
1448 getFHICLFilename(ARTDAQAppType::Monitor, monitorNode.
getValue());
1454 std::string tabStr =
"";
1455 std::string commentStr =
"";
1457 __COUTV__(filename);
1458 out.open(filename, std::fstream::out | std::fstream::trunc);
1461 __SS__ <<
"Failed to open ARTDAQ fcl file: " << filename << __E__;
1469 OUT <<
"###########################################################" << __E__;
1470 OUT <<
"#" << __E__;
1471 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::Monitor)
1472 <<
" fcl configuration file produced by otsdaq." << __E__;
1473 OUT <<
"# Creation time: \t"
1475 OUT <<
"# Original filename: \t" << filename << __E__;
1476 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(ARTDAQAppType::Monitor) <<
" UID:\t"
1477 << monitorNode.
getValue() << __E__;
1478 OUT <<
"#" << __E__;
1479 OUT <<
"###########################################################" << __E__;
1493 catch(
const std::runtime_error&)
1495 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
1502 std::string parentPath =
1506 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::Monitor)
1507 <<
" preamble parameters... " << parentPath << __E__;
1512 monitorNode.
getNode(
"preambleParametersLink"),
1521 monitorNode.
getNode(ARTDAQTableBase::colARTDAQNotReader_.colLinkToArt_);
1522 if(!art.isDisconnected())
1525 OUT <<
"services.message: { "
1526 << artdaq::generateMessageFacilityConfiguration(
1527 mf::GetApplicationName().c_str(),
true,
false)
1529 OUT <<
"services.message.destinations.file: {type: \"GenFile\" threshold: "
1530 "\"INFO\" seperator: \"-\""
1531 <<
" pattern: \"" << monitorNode.
getValue() <<
"-%?H%t-%p.log"
1533 <<
" timestamp_pattern: \"%Y%m%d%H%M%S\""
1534 <<
" directory: \"" << __ENV__(
"OTSDAQ_LOG_ROOT") <<
"/"
1536 <<
" append : false }\n";
1539 auto dispatcherLink = monitorNode.
getNode(
"dispatcherLink");
1540 if(!dispatcherLink.isDisconnected())
1542 std::string monitorHost =
1543 monitorNode.
getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
1545 std::string dispatcherHost =
1546 dispatcherLink.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
1547 .getValueWithDefault(
"localhost");
1548 OUT <<
"source.dispatcherHost: \"" << dispatcherHost <<
"\"\n";
1549 int dispatcherPort = dispatcherLink.getNode(
"DispatcherPort").getValue<
int>();
1550 OUT <<
"source.dispatcherPort: " << dispatcherPort <<
"\n";
1551 OUT <<
"source.commanderPluginType: xmlrpc\n";
1554 int om_tcp_listen_port =
1556 int disp_fake_rank =
1557 dispatcherLink.getNode(
"DispatcherID").getValueWithDefault<
int>(200);
1559 size_t max_fragment_size = monitorNode.
getNode(
"max_fragment_size_words")
1561 std::string transfer_plugin_type = monitorNode.
getNode(
"transfer_plugin_type")
1564 OUT <<
"TransferPluginConfig: {\n";
1566 OUT <<
"transferPluginType: " << transfer_plugin_type <<
"\n";
1567 OUT <<
"host_map: [{ rank: " << disp_fake_rank <<
" host: \""
1568 << dispatcherHost <<
"\"}, { rank: " << om_rank <<
" host: \""
1569 << monitorHost <<
"\"}]\n";
1570 OUT <<
"max_fragment_size_words: " << max_fragment_size <<
"\n";
1571 OUT <<
"source_rank: " << disp_fake_rank <<
"\n";
1572 OUT <<
"destination_rank: " << om_rank <<
"\n";
1573 OUT <<
"port: " << om_tcp_listen_port <<
"\n";
1574 OUT <<
"unique_label: " << monitorNode.
getValue() <<
"_to_"
1575 << dispatcherLink.getValue() <<
"\n";
1578 OUT <<
"source.transfer_plugin: @local::TransferPluginConfig \n";
1579 auto dispatcherArt = monitorNode.
getNode(
"dispatcherArtLink");
1580 if(!dispatcherArt.isDisconnected())
1582 OUT <<
"source.dispatcher_config: {\n";
1588 OUT <<
"filter_paths: [\n";
1592 auto filterPathsLink = monitorNode.
getNode(
"filterPathsLink");
1593 if(!filterPathsLink.isDisconnected())
1600 for(
auto& filterPath : filterPaths)
1606 if(!filterPath.second.status())
1609 OUT <<
"name: " << filterPath.second.getNode(
"Name").getValue()
1611 OUT <<
"path: " << filterPath.second.getNode(
"Path").getValue()
1615 if(!filterPath.second.status())
1624 OUT <<
"unique_label: " << monitorNode.
getValue() <<
"\n";
1638 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::Monitor)
1639 <<
" add-on parameters... " << parentPath << __E__;
1644 monitorNode.
getNode(
"addOnParametersLink"),
1649 __COUTT__ <<
"outputOnlineMonitorFHICL DONE" << __E__;
1653 __SS__ <<
"\n\nError while generating FHiCL for "
1654 << getTypeString(ARTDAQAppType::Monitor) <<
" node at filename '"
1655 << filename <<
"'" << __E__;
1660 catch(
const std::runtime_error& e)
1662 ss <<
" Here is the error: " << e.what() << __E__;
1664 catch(
const std::exception& e)
1666 ss <<
" Here is the error: " << e.what() << __E__;
1680 std::string& tabStr,
1681 std::string& commentStr,
1682 const std::string& parentPath,
1685 size_t routingTimeoutMs,
1686 size_t routingRetryCount)
1690 __COUTT__ <<
"Filling art.services parentPath =" << parentPath << __E__;
1691 auto services = art.
getNode(
"servicesLink");
1692 if(!services.isDisconnected())
1694 std::string localParentPath =
1696 services.getTableName() +
"/" +
1697 services.getValue();
1698 __COUTT__ <<
"Inserting services... " << localParentPath << __E__;
1699 OUTCL(
"services: {", services.hasComment() ? services.getComment() :
"");
1704 __COUTT__ <<
"Inserting services parameters... " << localParentPath << __E__;
1709 services.getNode(
"ServicesParametersLink"),
1715 OUT <<
"ArtdaqSharedMemoryServiceInterface: {\n";
1717 OUT <<
"service_provider: "
1718 "ArtdaqSharedMemoryService \n";
1720 OUTCLF(
"waiting_time: " << services.getNode(
"sharedMemoryWaitingTime").getValue(),
1722 "sharedMemoryWaitingTime");
1723 OUTCLF(
"resume_after_timeout: "
1724 << (services.getNode(
"sharedMemoryResumeAfterTimeout").getValue<
bool>()
1728 "sharedMemoryResumeAfterTimeout");
1730 OUT <<
"} # end ArtdaqSharedMemoryServiceInterface\n\n";
1732 OUT <<
"ArtdaqFragmentNamingServiceInterface: {\n";
1734 OUT <<
"service_provider: "
1735 "ArtdaqFragmentNamingService \n";
1736 OUTCLF(
"helper_plugin: "
1737 << services.getNode(
"fragmentNamingServiceProvider").getValue(),
1739 "fragmentNamingServiceProvider");
1743 std::string enabledFragmentTypes;
1746 enabledFragmentTypes = services.getNode(
"enabledFragmentTypes")
1747 .getValueWithDefault(std::string(
""));
1751 __COUTT__ <<
"No enabledFragmentTypes column in services table; skipping."
1754 if(!enabledFragmentTypes.empty())
1755 OUTCLF(
"enabled_fragment_types: " << enabledFragmentTypes,
1757 "enabledFragmentTypes");
1760 OUT <<
"} # end ArtdaqFragmentNamingServiceInterface\n\n";
1764 __COUTT__ <<
"Inserting services parameters... " << localParentPath << __E__;
1769 services.getNode(
"ServicesParametersLink"),
1775 OUT <<
"} # end services\n\n";
1779 __COUTS__(3) <<
"No services found" << __E__;
1780 std::string localParentPath =
1781 parentPath +
"/" + services.getParentLinkColumnName();
1782 OUTCL(
"# no services found",
"" );
1787 __COUTT__ <<
"Filling art.outputs parentPath =" << parentPath << __E__;
1788 auto outputs = art.
getNode(
"outputsLink");
1789 if(!outputs.isDisconnected())
1791 std::string localParentPath =
1794 __COUTT__ <<
"Inserting output... " << localParentPath << __E__;
1795 OUTCL(
"outputs: {",
"" );
1798 auto outputPlugins = outputs.getChildren();
1799 for(
auto& outputPlugin : outputPlugins)
1801 if(!outputPlugin.second.status())
1804 __COUTT__ <<
"Inserting output parameters... " << localParentPath << __E__;
1805 std::string localParentPath2 =
1806 localParentPath +
":" + outputPlugin.second.getTableName() +
":" +
1807 outputs.getParentLinkIndex() +
":" + outputs.getParentLinkID() +
"/" +
1808 outputPlugin.second.getValue();
1809 __COUTT__ <<
"Inserting output... " << localParentPath2 << __E__;
1811 outputPlugin.second.getNode(
"outputKey").getValue() <<
": {",
1812 outputPlugin.second.hasComment() ? outputPlugin.second.getComment() :
"",
1816 __COUTT__ <<
"insertModuleType... " << localParentPath2 << __E__;
1817 std::string moduleType =
1822 outputPlugin.second.getNode(
"outputModuleType"));
1826 __COUTT__ <<
"Inserting output parameters... " << localParentPath << __E__;
1831 outputPlugin.second.getNode(
"outputModuleParameterLink"),
1836 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1837 "BinaryNetOutput" ||
1838 outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1841 OUT <<
"destinations: { # empty placeholder, '"
1842 << outputPlugin.second.getNode(
"outputModuleType").getValue()
1843 <<
"' destinations handled by artdaq interface\n";
1846 OUT <<
"routing_table_config: {\n";
1849 auto mySubsystemID = 1;
1850 auto destinationSubsystemID = 1;
1853 mySubsystemID = getSubsytemId(subsystemLink);
1855 destinationSubsystemID = info_.subsystems[mySubsystemID].destination;
1856 if(info_.subsystems[destinationSubsystemID].hasRoutingManager)
1858 std::string localParentPath =
1861 __COUTT__ <<
"Inserting routing manager... " << localParentPath
1863 OUTCL(
"use_routing_manager: true",
1864 "auto-generated because subsystem '" +
1865 std::to_string(destinationSubsystemID) +
1866 "' has Routing Manager added");
1869 "routing_manager_hostname: \""
1870 << info_.subsystems[destinationSubsystemID].routingManagerHost
1873 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
1874 OUT <<
"table_update_port: 0\n";
1875 OUT <<
"table_update_address: \"0.0.0.0\"\n";
1876 OUT <<
"table_update_multicast_interface: \"0.0.0.0\"\n";
1877 OUT <<
"table_acknowledge_port : 0\n";
1878 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
1879 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
1883 OUTCF(
"use_routing_manager: false",
1884 "auto-generated if subsystem '" +
1885 std::to_string(destinationSubsystemID) +
1886 "' has Routing Manager added",
1890 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1893 info_.subsystems[mySubsystemID].eventMode =
true;
1899 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1901 outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1902 "TransferOutputReliable")
1904 OUT <<
"transfer_plugin: @local::TransferPluginConfig \n";
1908 OUT <<
"} # end " << outputPlugin.second.getNode(
"outputKey").getValue()
1911 if(!outputPlugin.second.status())
1916 OUT <<
"} # end outputs\n\n";
1920 __COUTS__(3) <<
"No outputs found" << __E__;
1921 std::string localParentPath =
1922 parentPath +
"/" + outputs.getParentLinkColumnName();
1923 OUTCL(
"# no outputs found",
"" );
1928 __COUTT__ <<
"Filling art.physics parentPath =" << parentPath << __E__;
1929 auto physics = art.
getNode(
"physicsLink");
1930 if(!physics.isDisconnected())
1932 __COUTT__ <<
"Inserting physics... " << parentPath << __E__;
1933 std::string localParentPath = parentPath +
"/" +
1934 physics.getParentLinkColumnName() +
":" +
1935 physics.getTableName() +
"/" +
1939 OUTCL(
"physics: {", physics.hasComment() ? services.getComment() :
"");
1945 __COUTT__ <<
"Inserting physics other parameters... " << localParentPath << __E__;
1950 physics.getNode(
"physicsOtherParametersLink"),
1951 "physicsParameter" ,
1955 auto analyzers = physics.getNode(
"analyzersLink");
1956 if(!analyzers.isDisconnected())
1958 __COUTT__ <<
"Inserting art.physics.analyzers... " << localParentPath
1960 std::string localParentPath2 =
1961 localParentPath +
"/" + analyzers.getParentLinkColumnName();
1962 __COUTT__ <<
"Inserting art.physics.analyzers... " << localParentPath2
1967 OUTCL2(
"analyzers: {",
"" );
1971 auto modules = analyzers.getChildren();
1972 for(
auto& module : modules)
1974 if(!module.second.status())
1981 auto analyzerNodeParameterLink =
1982 module.second.getNode(
"analyzerModuleParameterLink");
1985 __COUTT__ <<
"Inserting analyzer @table parameters... "
1986 << localParentPath2 << __E__;
1987 std::string localParentPath3 =
1988 localParentPath2 +
":" + module.second.getTableName() +
":" +
1989 analyzers.getParentLinkIndex() +
":" + analyzers.getParentLinkID() +
1990 "/" + module.second.getValue();
1991 __COUTT__ <<
"Inserting analyzer @table parameters... "
1992 << localParentPath3 << __E__;
1997 analyzerNodeParameterLink,
1998 "analyzerParameter" ,
2002 OUT << module.second.getNode(
"analyzerKey").getValue() <<
": {\n";
2008 module.second.getNode(
"analyzerModuleType"));
2012 __COUTT__ <<
"Inserting analayzer not @table parameters... "
2013 << localParentPath3 << __E__;
2018 analyzerNodeParameterLink,
2019 "analyzerParameter" ,
2026 if(!module.second.status())
2030 OUT <<
"} # end physics.analyzers\n\n";
2034 __COUTS__(3) <<
"No analyzers found" << __E__;
2035 std::string localParentPath2 =
2036 localParentPath +
"/" + analyzers.getParentLinkColumnName();
2037 OUTCL2(
"# no analyzers found",
"" );
2040 auto producers = physics.getNode(
"producersLink");
2041 if(!producers.isDisconnected())
2043 __COUTT__ <<
"Inserting art.physics.producers... " << localParentPath
2045 std::string localParentPath2 =
2046 localParentPath +
"/" + producers.getParentLinkColumnName();
2050 OUTCL2(
"producers: {",
"" );
2054 auto modules = producers.getChildren();
2055 for(
auto& module : modules)
2057 if(!module.second.status())
2064 auto producerNodeParameterLink =
2065 module.second.getNode(
"producerModuleParameterLink");
2068 __COUTT__ <<
"Inserting producer @table parameters... "
2069 << localParentPath2 << __E__;
2070 std::string localParentPath3 =
2071 localParentPath2 +
":" + module.second.getTableName() +
":" +
2072 producers.getParentLinkIndex() +
":" + producers.getParentLinkID() +
2073 "/" + module.second.getValue();
2074 __COUTT__ <<
"Inserting producer @table parameters... "
2075 << localParentPath3 << __E__;
2080 producerNodeParameterLink,
2081 "producerParameter" ,
2085 if(module.second.status() &&
2086 module.second.getNode(
"producerModuleType").getValue() ==
"")
2088 std::string tmp = localParentPath2;
2089 localParentPath2 = localParentPath3;
2090 OUTCL2F(
"# skipping '" << module.second.getValue()
2091 <<
"' with empty module type",
2093 "producerModuleType");
2094 localParentPath2 = tmp;
2098 OUT << module.second.getNode(
"producerKey").getValue() <<
": {\n";
2105 module.second.getNode(
"producerModuleType"));
2109 __COUTT__ <<
"Inserting producer not @table parameters... "
2110 << localParentPath3 << __E__;
2115 producerNodeParameterLink,
2116 "producerParameter" ,
2123 if(!module.second.status())
2127 OUT <<
"} # end physics.producers\n\n";
2131 __COUTS__(3) <<
"No producers found" << __E__;
2132 std::string localParentPath2 =
2133 localParentPath +
"/" + producers.getParentLinkColumnName();
2134 OUTCL2(
"# no producers found",
"" );
2137 auto filters = physics.getNode(
"filtersLink");
2138 if(!filters.isDisconnected())
2140 __COUTT__ <<
"Inserting art.physics.filters... " << localParentPath << __E__;
2141 std::string localParentPath2 =
2142 localParentPath +
"/" + filters.getParentLinkColumnName();
2146 OUTCL2(
"filters: {",
"" );
2150 auto modules = filters.getChildren();
2151 for(
auto& module : modules)
2153 if(!module.second.status())
2160 auto filterNodeParameterLink =
2161 module.second.getNode(
"filterModuleParameterLink");
2164 __COUTT__ <<
"Inserting filter @table parameters... " << localParentPath2
2166 std::string localParentPath3 =
2167 localParentPath2 +
":" + module.second.getTableName() +
":" +
2168 filters.getParentLinkIndex() +
":" + filters.getParentLinkID() +
"/" +
2169 module.second.getValue();
2170 __COUTT__ <<
"Inserting filter @table parameters... " << localParentPath3
2176 filterNodeParameterLink,
2180 if(module.second.status() &&
2181 module.second.getNode(
"filterModuleType").getValue() ==
"")
2183 std::string tmp = localParentPath2;
2184 localParentPath2 = localParentPath3;
2185 OUTCL2F(
"# skipping '" << module.second.getValue()
2186 <<
"' with empty module type",
2188 "filterModuleType");
2189 localParentPath2 = tmp;
2193 OUT << module.second.getNode(
"filterKey").getValue() <<
": {\n";
2200 module.second.getNode(
"filterModuleType"));
2204 __COUTT__ <<
"Inserting filter not @table parameters... "
2205 << localParentPath3 << __E__;
2210 filterNodeParameterLink,
2218 if(!module.second.status())
2222 OUT <<
"} # end physics.filters\n\n";
2226 __COUTS__(3) <<
"No filters found" << __E__;
2227 std::string localParentPath2 =
2228 localParentPath +
"/" + services.getParentLinkColumnName();
2229 OUTCL2(
"# no filters found",
"" );
2234 __COUTT__ <<
"Inserting art.physics not @table parameters... " << localParentPath
2240 physics.getNode(
"physicsOtherParametersLink"),
2241 "physicsParameter" ,
2246 OUT <<
"} # end physics\n\n";
2250 __COUTS__(3) <<
"No physics found" << __E__;
2251 std::string localParentPath =
2252 parentPath +
"/" + physics.getParentLinkColumnName();
2253 OUTCL(
"# no physics found",
"" );
2258 __COUTT__ <<
"Filling art.source" << __E__;
2259 auto source = art.
getNode(
"sourceLink");
2260 if(!source.isDisconnected())
2262 __COUTT__ <<
"Inserting source... " << parentPath << __E__;
2263 std::string localParentPath = parentPath +
"/" +
2264 source.getParentLinkColumnName() +
":" +
2265 source.getTableName() +
"/" +
2267 OUTCL(
"source: {", source.hasComment() ? source.getComment() :
"");
2270 out, tabStr, commentStr, parentPath, source.getNode(
"sourceModuleType"));
2276 std::string localParentPath = parentPath +
"/" + source.getParentLinkColumnName();
2277 OUTCL(
"source: { # auto-generated default, to change provide a source link",
2280 OUT <<
"module_type: ArtdaqInput";
2287 __COUTT__ <<
"Writing art.process_name" << __E__;
2288 OUTCF(
"process_name: " << art.
getNode(ARTDAQTableBase::colARTDAQArt_.colProcessName_),
2290 ARTDAQTableBase::colARTDAQArt_.colProcessName_);
2294 __COUTT__ <<
"Inserting art @table parameters... " << parentPath << __E__;
2299 art.
getNode(
"AddOnParametersLink"),
2307 void ARTDAQTableBase::outputRoutingManagerFHICL(
2309 size_t routingTimeoutMs ,
2310 size_t routingRetryCount )
2312 if(ARTDAQ_DONOTWRITE_FCL)
2314 __COUT__ <<
"Skipping fcl generation." << __E__;
2318 std::string filename =
2319 getFHICLFilename(ARTDAQAppType::RoutingManager, routingManagerNode.
getValue());
2325 std::string tabStr =
"";
2326 std::string commentStr =
"";
2328 __COUTV__(filename);
2329 out.open(filename, std::fstream::out | std::fstream::trunc);
2332 __SS__ <<
"Failed to open ARTDAQ RoutingManager fcl file: " << filename << __E__;
2340 OUT <<
"###########################################################" << __E__;
2341 OUT <<
"#" << __E__;
2342 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::RoutingManager)
2343 <<
" fcl configuration file produced by otsdaq." << __E__;
2344 OUT <<
"# Creation time: \t"
2346 OUT <<
"# Original filename: \t" << filename << __E__;
2347 OUT <<
"# otsdaq-ARTDAQ RoutingManager UID:\t" << routingManagerNode.
getValue()
2349 OUT <<
"#" << __E__;
2350 OUT <<
"###########################################################" << __E__;
2364 catch(
const std::runtime_error&)
2376 OUT <<
"policy: {\n";
2380 if(policyName ==
"DEFAULT")
2381 policyName =
"NoOp";
2382 OUT <<
"policy: " << policyName <<
"\n";
2383 OUT <<
"receiver_ranks: []\n";
2386 auto parametersLink = routingManagerNode.
getNode(
"routingPolicyParametersLink");
2387 if(!parametersLink.isDisconnected())
2390 for(
auto& parameter : parameters)
2392 if(!parameter.second.status())
2403 parameter.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT);
2404 OUT << parameter.second.getNode(
"daqParameterKey").getValue() <<
": "
2405 << parameter.second.getNode(
"daqParameterValue").getValue()
2406 << (comment.isDefaultValue() ?
"" : (
"\t # " + comment.getValue()))
2409 if(!parameter.second.status())
2417 OUT <<
"use_routing_manager: true\n";
2419 auto routingManagerSubsystemID = 1;
2420 auto routingManagerSubsystemLink = routingManagerNode.
getNode(
"SubsystemLink");
2421 std::string rmHost =
"localhost";
2422 if(!routingManagerSubsystemLink.isDisconnected())
2424 routingManagerSubsystemID = getSubsytemId(routingManagerSubsystemLink);
2425 rmHost = info_.subsystems[routingManagerSubsystemID].routingManagerHost;
2427 if(rmHost ==
"localhost" || rmHost ==
"127.0.0.1")
2429 char hostbuf[HOST_NAME_MAX + 1];
2430 gethostname(hostbuf, HOST_NAME_MAX);
2431 rmHost = std::string(hostbuf);
2435 OUT <<
"routing_manager_hostname: \"" << rmHost <<
"\"\n";
2436 OUT <<
"sender_ranks: []\n";
2437 OUT <<
"table_update_port: 0\n";
2438 OUT <<
"table_update_address: \"0.0.0.0\"\n";
2439 OUT <<
"table_acknowledge_port: 0\n";
2440 OUT <<
"token_receiver: {\n";
2443 OUT <<
"routing_token_port: 0\n";
2449 auto tableUpdateIntervalMs =
2451 if(tableUpdateIntervalMs !=
"DEFAULT")
2453 OUT <<
"table_update_interval_ms: " << tableUpdateIntervalMs <<
"\n";
2455 auto tableAckRetryCount =
2457 if(tableAckRetryCount !=
"DEFAULT")
2459 OUT <<
"table_ack_retry_count: " << tableAckRetryCount <<
"\n";
2462 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
2463 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
2474 __COUTT__ <<
"outputReaderFHICL DONE" << __E__;
2478 __SS__ <<
"\n\nError while generating FHiCL for "
2479 << getTypeString(ARTDAQAppType::RoutingManager) <<
" node at filename '"
2480 << filename <<
"'" << __E__;
2485 catch(
const std::runtime_error& e)
2487 ss <<
" Here is the error: " << e.what() << __E__;
2489 catch(
const std::exception& e)
2491 ss <<
" Here is the error: " << e.what() << __E__;
2503 bool getStatusFalseNodes ,
2505 size_t maxFragmentSizeBytes ,
2506 size_t routingTimeoutMs ,
2507 size_t routingRetryCount ,
2511 progressBar->
step();
2514 info_.subsystems.clear();
2515 info_.processes.clear();
2518 progressBar->
step();
2520 info_.subsystems[NULL_SUBSYSTEM_DESTINATION].id = NULL_SUBSYSTEM_DESTINATION;
2521 info_.subsystems[NULL_SUBSYSTEM_DESTINATION].label = NULL_SUBSYSTEM_DESTINATION_LABEL;
2526 __COUT__ <<
"artdaqSupervisorNode is disconnected." << __E__;
2532 std::chrono::steady_clock::time_point extractStartClock =
2533 std::chrono::steady_clock::now();
2534 std::chrono::steady_clock::time_point stageClock = extractStartClock;
2535 std::vector<std::pair<std::string, double>> stageTimes;
2537 maybeResetFHiCLTimingTrace();
2538 fhiclFlattenCount_ = 0;
2539 fhiclFlattenSeconds_ = 0;
2540 size_t thisInvocation = ++extractInvocation_;
2542 auto recordStageTime = [&](
const std::string& stageName) {
2543 stageTimes.emplace_back(stageName, artdaq::TimeUtils::GetElapsedTime(stageClock));
2544 stageClock = std::chrono::steady_clock::now();
2548 extractRoutingManagersInfo(artdaqSupervisorNode,
2549 getStatusFalseNodes,
2553 recordStageTime(
"RoutingManagers");
2554 __COUT__ <<
"artdaqSupervisorNode RoutingManager size: "
2555 << info_.processes.at(ARTDAQAppType::RoutingManager).size() << __E__;
2558 progressBar->
step();
2560 extractBoardReadersInfo(artdaqSupervisorNode,
2561 getStatusFalseNodes,
2563 maxFragmentSizeBytes,
2566 __COUT__ <<
"artdaqSupervisorNode BoardReader size: "
2567 << info_.processes.at(ARTDAQAppType::BoardReader).size() << __E__;
2568 recordStageTime(
"BoardReaders");
2571 progressBar->
step();
2573 extractEventBuildersInfo(
2574 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2575 __COUT__ <<
"artdaqSupervisorNode EventBuilder size: "
2576 << info_.processes.at(ARTDAQAppType::EventBuilder).size() << __E__;
2577 recordStageTime(
"EventBuilders");
2580 progressBar->
step();
2582 extractDataLoggersInfo(
2583 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2584 __COUT__ <<
"artdaqSupervisorNode DataLogger size: "
2585 << info_.processes.at(ARTDAQAppType::DataLogger).size() << __E__;
2586 recordStageTime(
"DataLoggers");
2589 progressBar->
step();
2591 extractDispatchersInfo(
2592 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2593 __COUT__ <<
"artdaqSupervisorNode Dispatcher size: "
2594 << info_.processes.at(ARTDAQAppType::Dispatcher).size() << __E__;
2595 recordStageTime(
"Dispatchers");
2598 progressBar->
step();
2606 std::stringstream summary;
2607 summary <<
"FHiCL TIMING TRACE: extractARTDAQInfo call #" << thisInvocation
2608 <<
" (doWriteFHiCL=" << (doWriteFHiCL ?
"true" :
"false") <<
") total "
2609 << artdaq::TimeUtils::GetElapsedTime(extractStartClock) <<
"s"
2610 <<
", of which flattenFHICL was " << fhiclFlattenCount_ <<
" file(s) in "
2611 << fhiclFlattenSeconds_ <<
"s"
2612 <<
"; this-config cumulative flattenFHICL (all passes): "
2613 << fhiclFlattenCountCumulative_ <<
" file(s) in "
2614 << fhiclFlattenSecondsCumulative_ <<
"s";
2615 for(
const auto& stageTime : stageTimes)
2616 summary <<
"\n " << stageTime.first <<
": " << stageTime.second <<
"s";
2617 __COUT_INFO__ << summary.str() << __E__;
2624 void ARTDAQTableBase::extractRoutingManagersInfo(
ConfigurationTree artdaqSupervisorNode,
2625 bool getStatusFalseNodes,
2627 size_t routingTimeoutMs,
2628 size_t routingRetryCount)
2630 __COUT__ <<
"Checking for Routing Managers..." << __E__;
2631 info_.processes[ARTDAQAppType::RoutingManager].clear();
2634 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToRoutingManagers_);
2637 std::vector<std::pair<std::string, ConfigurationTree>> routingManagers =
2640 __COUT__ <<
"There are " << routingManagers.size()
2641 <<
" configured Routing Managers" << __E__;
2643 for(
auto& routingManager : routingManagers)
2645 const std::string& rmUID = routingManager.first;
2647 if(getStatusFalseNodes || routingManager.second.status())
2649 std::string rmHost =
2650 routingManager.second
2651 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2652 .getValueWithDefault(
"localhost");
2653 if(rmHost ==
"localhost" || rmHost ==
"127.0.0.1")
2655 char hostbuf[HOST_NAME_MAX + 1];
2656 gethostname(hostbuf, HOST_NAME_MAX);
2657 rmHost = std::string(hostbuf);
2661 routingManager.second
2662 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2663 .getValueWithDefault(
"");
2665 int routingManagerSubsystemID = 1;
2667 routingManager.second.
getNode(
2668 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2671 routingManagerSubsystemID =
2672 getSubsytemId(routingManagerSubsystemLink);
2675 info_.subsystems[routingManagerSubsystemID].id =
2676 routingManagerSubsystemID;
2678 const std::string& routingManagerSubsystemName =
2682 info_.subsystems[routingManagerSubsystemID].label =
2683 routingManagerSubsystemName;
2685 if(info_.subsystems[routingManagerSubsystemID].hasRoutingManager)
2687 __SS__ <<
"Error: You cannot have multiple Routing Managers in a "
2693 auto routingManagerSubsystemDestinationLink =
2694 routingManagerSubsystemLink.
getNode(
2695 colARTDAQSubsystem_.colLinkToDestination_);
2696 if(routingManagerSubsystemDestinationLink.isDisconnected())
2699 info_.subsystems[routingManagerSubsystemID].destination = 0;
2704 info_.subsystems[routingManagerSubsystemID].destination =
2705 getSubsytemId(routingManagerSubsystemDestinationLink);
2711 if(!info_.subsystems.count(
2712 info_.subsystems[routingManagerSubsystemID].destination) ||
2714 .subsystems[info_.subsystems[routingManagerSubsystemID]
2716 .sources.count(routingManagerSubsystemID))
2719 .subsystems[info_.subsystems[routingManagerSubsystemID]
2721 .sources.insert(routingManagerSubsystemID);
2726 __COUT__ <<
"Found Routing Manager with UID " << rmUID
2727 <<
", DAQInterface Hostname " << rmHost <<
", and Subsystem "
2728 << routingManagerSubsystemID << __E__;
2729 info_.processes[ARTDAQAppType::RoutingManager].emplace_back(
2733 routingManagerSubsystemID,
2734 ARTDAQAppType::RoutingManager,
2735 routingManager.second.status());
2737 info_.subsystems[routingManagerSubsystemID].hasRoutingManager =
true;
2738 info_.subsystems[routingManagerSubsystemID].routingManagerHost = rmHost;
2742 outputRoutingManagerFHICL(
2743 routingManager.second, routingTimeoutMs, routingRetryCount);
2745 flattenFHICL(ARTDAQAppType::RoutingManager,
2746 routingManager.second.getValue());
2751 __COUT__ <<
"Routing Manager " << rmUID <<
" is disabled." << __E__;
2758 void ARTDAQTableBase::extractBoardReadersInfo(
ConfigurationTree artdaqSupervisorNode,
2759 bool getStatusFalseNodes,
2761 size_t maxFragmentSizeBytes,
2762 size_t routingTimeoutMs,
2763 size_t routingRetryCount)
2765 __COUT__ <<
"Checking for Board Readers..." << __E__;
2766 info_.processes[ARTDAQAppType::BoardReader].clear();
2769 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToBoardReaders_);
2772 std::vector<std::pair<std::string, ConfigurationTree>> readers =
2774 __COUT__ <<
"There are " << readers.size() <<
" configured Board Readers."
2777 for(
auto& reader : readers)
2779 const std::string& readerUID = reader.first;
2781 if(getStatusFalseNodes || reader.second.status())
2783 std::string readerHost =
2784 reader.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2785 .getValueWithDefault(
"localhost");
2786 std::string readerAP =
2788 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2789 .getValueWithDefault(
"");
2791 int readerSubsystemID = 1;
2793 reader.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2796 readerSubsystemID = getSubsytemId(readerSubsystemLink);
2798 info_.subsystems[readerSubsystemID].id = readerSubsystemID;
2800 const std::string& readerSubsystemName =
2804 info_.subsystems[readerSubsystemID].label = readerSubsystemName;
2806 auto readerSubsystemDestinationLink = readerSubsystemLink.
getNode(
2807 colARTDAQSubsystem_.colLinkToDestination_);
2808 if(readerSubsystemDestinationLink.isDisconnected())
2811 info_.subsystems[readerSubsystemID].destination = 0;
2816 info_.subsystems[readerSubsystemID].destination =
2817 getSubsytemId(readerSubsystemDestinationLink);
2823 if(!info_.subsystems.count(
2824 info_.subsystems[readerSubsystemID].destination) ||
2825 !info_.subsystems[info_.subsystems[readerSubsystemID].destination]
2826 .sources.count(readerSubsystemID))
2828 info_.subsystems[info_.subsystems[readerSubsystemID].destination]
2829 .sources.insert(readerSubsystemID);
2834 __COUT__ <<
"Found Board Reader with UID " << readerUID
2835 <<
", DAQInterface Hostname " << readerHost <<
", and Subsystem "
2836 << readerSubsystemID << __E__;
2837 info_.processes[ARTDAQAppType::BoardReader].emplace_back(
2842 ARTDAQAppType::BoardReader,
2843 reader.second.status());
2847 outputBoardReaderFHICL(reader.second,
2848 maxFragmentSizeBytes,
2852 flattenFHICL(ARTDAQAppType::BoardReader, reader.second.getValue());
2857 __COUT__ <<
"Board Reader " << readerUID <<
" is disabled." << __E__;
2863 __COUT_WARN__ <<
"There should be at least one Board Reader!";
2870 void ARTDAQTableBase::extractEventBuildersInfo(
ConfigurationTree artdaqSupervisorNode,
2871 bool getStatusFalseNodes,
2873 size_t maxFragmentSizeBytes)
2875 __COUT__ <<
"Checking for Event Builders..." << __E__;
2876 info_.processes[ARTDAQAppType::EventBuilder].clear();
2879 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToEventBuilders_);
2882 std::vector<std::pair<std::string, ConfigurationTree>> builders =
2888 std::vector<std::pair<std::string, std::string*>> buildersToFlatten;
2889 for(
auto& builder : builders)
2891 const std::string& builderUID = builder.first;
2892 __COUTV__(builderUID);
2894 if(getStatusFalseNodes || builder.second.status())
2896 std::string builderHost =
2897 builder.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2898 .getValueWithDefault(
"localhost");
2899 std::string builderAP =
2901 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2902 .getValueWithDefault(
"");
2904 int builderSubsystemID = 1;
2906 builder.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2909 builderSubsystemID = getSubsytemId(builderSubsystemLink);
2912 info_.subsystems[builderSubsystemID].id = builderSubsystemID;
2914 const std::string& builderSubsystemName =
2918 info_.subsystems[builderSubsystemID].label = builderSubsystemName;
2920 auto builderSubsystemDestinationLink = builderSubsystemLink.
getNode(
2921 colARTDAQSubsystem_.colLinkToDestination_);
2922 if(builderSubsystemDestinationLink.isDisconnected())
2925 info_.subsystems[builderSubsystemID].destination = 0;
2930 info_.subsystems[builderSubsystemID].destination =
2931 getSubsytemId(builderSubsystemDestinationLink);
2937 if(!info_.subsystems.count(
2938 info_.subsystems[builderSubsystemID].destination) ||
2939 !info_.subsystems[info_.subsystems[builderSubsystemID].destination]
2940 .sources.count(builderSubsystemID))
2942 info_.subsystems[info_.subsystems[builderSubsystemID].destination]
2943 .sources.insert(builderSubsystemID);
2948 __COUT__ <<
"Found Event Builder with UID " << builderUID
2949 <<
", on Hostname " << builderHost <<
", in Subsystem "
2950 << builderSubsystemID << __E__;
2951 info_.processes[ARTDAQAppType::EventBuilder].emplace_back(
2956 ARTDAQAppType::EventBuilder,
2957 builder.second.status());
2962 ARTDAQAppType::EventBuilder,
2963 maxFragmentSizeBytes,
2964 DEFAULT_ROUTING_TIMEOUT_MS,
2965 DEFAULT_ROUTING_RETRY_COUNT);
2967 buildersToFlatten.emplace_back(builderUID,
nullptr);
2972 __COUT__ <<
"Event Builder " << builderUID <<
" is disabled." << __E__;
2976 if(buildersToFlatten.size())
2977 flattenFHICLInParallel(ARTDAQAppType::EventBuilder, buildersToFlatten);
2981 __COUT_WARN__ <<
"There should be at least one Event Builder!";
2988 void ARTDAQTableBase::extractDataLoggersInfo(
ConfigurationTree artdaqSupervisorNode,
2989 bool getStatusFalseNodes,
2991 size_t maxFragmentSizeBytes)
2993 __COUT__ <<
"Checking for Data Loggers..." << __E__;
2994 info_.processes[ARTDAQAppType::DataLogger].clear();
2997 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToDataLoggers_);
3000 std::vector<std::pair<std::string, ConfigurationTree>> dataloggers =
3003 for(
auto& datalogger : dataloggers)
3005 const std::string& loggerUID = datalogger.first;
3007 if(getStatusFalseNodes || datalogger.second.status())
3009 std::string loggerHost =
3010 datalogger.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
3011 .getValueWithDefault(
"localhost");
3012 std::string loggerAP =
3014 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
3015 .getValueWithDefault(
"");
3017 int loggerSubsystemID = 1;
3019 datalogger.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
3022 loggerSubsystemID = getSubsytemId(loggerSubsystemLink);
3024 info_.subsystems[loggerSubsystemID].id = loggerSubsystemID;
3026 const std::string& loggerSubsystemName =
3030 info_.subsystems[loggerSubsystemID].label = loggerSubsystemName;
3032 auto loggerSubsystemDestinationLink = loggerSubsystemLink.
getNode(
3033 colARTDAQSubsystem_.colLinkToDestination_);
3034 if(loggerSubsystemDestinationLink.isDisconnected())
3037 info_.subsystems[loggerSubsystemID].destination = 0;
3042 info_.subsystems[loggerSubsystemID].destination =
3043 getSubsytemId(loggerSubsystemDestinationLink);
3049 if(!info_.subsystems.count(
3050 info_.subsystems[loggerSubsystemID].destination) ||
3051 !info_.subsystems[info_.subsystems[loggerSubsystemID].destination]
3052 .sources.count(loggerSubsystemID))
3054 info_.subsystems[info_.subsystems[loggerSubsystemID].destination]
3055 .sources.insert(loggerSubsystemID);
3060 __COUT__ <<
"Found Data Logger with UID " << loggerUID
3061 <<
", DAQInterface Hostname " << loggerHost <<
", and Subsystem "
3062 << loggerSubsystemID << __E__;
3063 info_.processes[ARTDAQAppType::DataLogger].emplace_back(
3068 ARTDAQAppType::DataLogger,
3069 datalogger.second.status());
3074 ARTDAQAppType::DataLogger,
3075 maxFragmentSizeBytes);
3077 flattenFHICL(ARTDAQAppType::DataLogger, datalogger.second.getValue());
3082 __COUT__ <<
"Data Logger " << loggerUID <<
" is disabled." << __E__;
3088 __COUT_WARN__ <<
"There were no Data Loggers found!";
3093 void ARTDAQTableBase::extractDispatchersInfo(
ConfigurationTree artdaqSupervisorNode,
3094 bool getStatusFalseNodes,
3096 size_t maxFragmentSizeBytes)
3098 __COUT__ <<
"Checking for Dispatchers..." << __E__;
3099 info_.processes[ARTDAQAppType::Dispatcher].clear();
3102 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToDispatchers_);
3105 std::vector<std::pair<std::string, ConfigurationTree>> dispatchers =
3108 for(
auto& dispatcher : dispatchers)
3110 const std::string& dispatcherUID = dispatcher.first;
3112 if(getStatusFalseNodes || dispatcher.second.status())
3114 std::string dispatcherHost =
3115 dispatcher.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
3116 .getValueWithDefault(
"localhost");
3117 std::string dispatcherAP =
3119 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
3120 .getValueWithDefault(
"");
3121 int dispatcherPort =
3122 dispatcher.second.getNode(
"DispatcherPort").getValue<
int>();
3124 auto dispatcherSubsystemID = 1;
3126 dispatcher.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
3129 dispatcherSubsystemID = getSubsytemId(dispatcherSubsystemLink);
3131 info_.subsystems[dispatcherSubsystemID].id = dispatcherSubsystemID;
3133 const std::string& dispatcherSubsystemName =
3137 info_.subsystems[dispatcherSubsystemID].label =
3138 dispatcherSubsystemName;
3140 auto dispatcherSubsystemDestinationLink =
3141 dispatcherSubsystemLink.
getNode(
3142 colARTDAQSubsystem_.colLinkToDestination_);
3143 if(dispatcherSubsystemDestinationLink.isDisconnected())
3146 info_.subsystems[dispatcherSubsystemID].destination = 0;
3151 info_.subsystems[dispatcherSubsystemID].destination =
3152 getSubsytemId(dispatcherSubsystemDestinationLink);
3158 if(!info_.subsystems.count(
3159 info_.subsystems[dispatcherSubsystemID].destination) ||
3161 .subsystems[info_.subsystems[dispatcherSubsystemID]
3163 .sources.count(dispatcherSubsystemID))
3166 .subsystems[info_.subsystems[dispatcherSubsystemID]
3168 .sources.insert(dispatcherSubsystemID);
3172 __COUT__ <<
"Found Dispatcher with UID " << dispatcherUID
3173 <<
", DAQInterface Hostname " << dispatcherHost
3174 <<
", and Subsystem " << dispatcherSubsystemID << __E__;
3175 info_.processes[ARTDAQAppType::Dispatcher].emplace_back(
3179 dispatcherSubsystemID,
3180 ARTDAQAppType::Dispatcher,
3181 dispatcher.second.status(),
3187 ARTDAQAppType::Dispatcher,
3188 maxFragmentSizeBytes);
3190 flattenFHICL(ARTDAQAppType::Dispatcher, dispatcher.second.getValue());
3195 __COUT__ <<
"Dispatcher " << dispatcherUID <<
" is disabled." << __E__;
3201 __COUT_WARN__ <<
"There were no Dispatchers found!";
3211 for(
auto context : contexts)
3213 if(!context.second.isEnabled())
3216 auto apps = context.second
3217 .getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
3219 for(
auto app : apps)
3222 if(app.second.getNode(XDAQContextTable::colApplication_.colClass_)
3223 .getValue() == ARTDAQ_SUPERVISOR_CLASS &&
3224 app.second.isEnabled())
3242 std::map<std::string ,
3243 std::map<std::string , std::vector<std::string /*property*/>>>&
3244 nodeTypeToObjectMap,
3245 std::map<std::string /*subsystemName*/, std::string /*destinationSubsystemName*/>&
3247 std::vector<std::string /*property*/>& artdaqSupervisoInfo,
3248 bool suppressMultiNode )
3250 __COUT__ <<
"getARTDAQSystem() suppressMultiNode=" << suppressMultiNode << __E__;
3252 artdaqSupervisoInfo.clear();
3263 return ARTDAQTableBase::info_;
3265 __COUTV__(artdaqContext->contextUID_);
3266 __COUTV__(artdaqContext->applications_.size());
3269 std::map<std::string , std::set<std::string >> nodeLayoutNames;
3271 const std::string& finalContextGroupName =
3272 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE);
3274 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE);
3275 const std::string& finalConfigGroupName = cfgMgr->getActiveGroupName(
3276 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
3277 const TableGroupKey& finalConfigGroupKey = cfgMgr->getActiveGroupKey(
3278 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
3283 std::stringstream layoutPath;
3284 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3285 << finalContextGroupName <<
"_" << finalContextGroupKey <<
"."
3286 << finalConfigGroupName <<
"_" << finalConfigGroupKey <<
".dat";
3288 fp = fopen(layoutPath.str().c_str(),
"r");
3291 __COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
3292 << finalContextGroupKey <<
") + " << finalConfigGroupName <<
"("
3293 << finalConfigGroupKey <<
")': " << layoutPath.
str() << __E__;
3297 __COUTV__(layoutPath.str());
3301 std::stringstream layoutPath;
3302 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3303 << finalContextGroupName <<
"_" << finalContextGroupKey <<
".dat";
3304 __COUTV__(layoutPath.str());
3306 fp = fopen(layoutPath.str().c_str(),
"r");
3309 __COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
3310 << finalContextGroupKey <<
")': " << layoutPath.str() << __E__;
3313 __COUTV__(layoutPath.str());
3319 struct dirent* entry;
3324 float bestScore = 0, score;
3325 std::string bestName =
"";
3327 if(!(pDIR = opendir((ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH).c_str())))
3329 __SS__ <<
"Path '" << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3330 <<
"' could not be opened!" << __E__;
3335 while((entry = readdir(pDIR)))
3337 name = std::string(entry->d_name);
3338 type = int(entry->d_type);
3340 __COUTS__(2) << type <<
" " << name <<
"\n" << std::endl;
3342 if(name[0] !=
'.' &&
3352 if(type == 0 || type == 10)
3355 DIR* pTmpDIR = opendir(
3356 (ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH +
"/" + name)
3364 __COUTS__(2) <<
"Unable to open path as directory: "
3365 << (ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH +
3377 __COUTS__(2) <<
"Directory: " << type <<
" " << name << __E__;
3381 __COUTS__(2) <<
"File: " << type <<
" " << name <<
"\n"
3383 if(name.find(
".dat") !=
3387 __COUTS__(2) <<
"Contender: " << name <<
"\n" << std::endl;
3392 if(nameSplit.size() > 1)
3395 auto keyi = nameSplit[1].rfind(
'_');
3396 if(keyi != std::string::npos)
3400 .substr(keyi, nameSplit[1].size() - 4 - keyi)
3404 finalConfigGroupKey.key() -
3410 __COUTVS__(2, tmpscore);
3414 __COUTVS__(2, tmpscore);
3417 std::string nameToCompare = nameSplit[1].substr(0, keyi);
3418 __COUTVS__(2, nameToCompare);
3419 size_t i = 0, j = 0;
3421 for(; i < nameToCompare.size() &&
3422 j < finalConfigGroupName.size();
3425 if(nameToCompare[i] == finalConfigGroupName[j])
3431 __COUTVS__(2, tmpscore);
3433 for(; i < nameToCompare.size() &&
3434 j < finalConfigGroupName.size();
3437 if(nameToCompare[i] == finalConfigGroupName[j])
3443 __COUTVS__(2, tmpscore);
3446 __COUTVS__(2, score);
3448 if(nameSplit.size() > 0)
3451 auto keyi = nameSplit[0].rfind(
'_');
3452 if(keyi != std::string::npos)
3456 .substr(keyi, nameSplit[0].size() - 4 - keyi)
3460 finalContextGroupKey.key() -
3466 __COUTVS__(2, tmpscore);
3470 __COUTVS__(2, tmpscore);
3473 std::string nameToCompare = nameSplit[0].substr(0, keyi);
3474 __COUTVS__(2, nameToCompare);
3475 size_t i = 0, j = 0;
3477 for(; i < nameToCompare.size() &&
3478 j < finalContextGroupName.size();
3481 if(nameToCompare[i] == finalContextGroupName[j])
3487 __COUTVS__(2, tmpscore);
3489 for(; i < nameToCompare.size() &&
3490 j < finalContextGroupName.size();
3493 if(nameToCompare[i] == finalContextGroupName[j])
3499 __COUTVS__(2, tmpscore);
3502 __COUTVS__(2, score);
3505 if(score > bestScore)
3509 __COUTVS__(2, bestName);
3517 __COUT__ <<
"Found closest layout file name: " << bestName <<
".dat"
3519 std::stringstream layoutPath;
3520 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << bestName
3522 __COUTV__(layoutPath.str());
3523 fp = fopen(layoutPath.str().c_str(),
"r");
3526 __COUT__ <<
"Closest layout file not found for '" << bestName <<
"'"
3536 __COUT__ <<
"Extract info from layout file.." << __E__;
3542 const size_t maxLineSz = 1000;
3543 char line[maxLineSz];
3544 if(!fgets(line, maxLineSz, fp))
3547 __COUT__ <<
"No layout naming info found." << __E__;
3553 char name[maxLineSz];
3554 char type[maxLineSz];
3556 while(fgets(line, maxLineSz, fp))
3559 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
3560 nodeLayoutNames[type].emplace(name);
3575 for(
auto& artdaqApp : artdaqContext->applications_)
3577 if(artdaqApp.class_ != ARTDAQ_SUPERVISOR_CLASS)
3580 __COUTV__(artdaqApp.applicationUID_);
3581 artdaqSupervisoInfo.push_back(artdaqApp.applicationUID_);
3582 artdaqSupervisoInfo.push_back(
3583 (artdaqContext->status_ && artdaqApp.status_) ?
"1" :
"0");
3584 artdaqSupervisoInfo.push_back(artdaqContext->address_);
3585 artdaqSupervisoInfo.push_back(std::to_string(artdaqContext->port_));
3588 XDAQContextTable::getSupervisorConfigNode(
3590 artdaqContext->contextUID_,
3591 artdaqApp.applicationUID_),
3594 __COUT__ <<
"========== "
3595 <<
"Found " << info.subsystems.size() <<
" subsystems." << __E__;
3598 for(
auto& subsystem : info.subsystems)
3599 subsystemObjectMap.emplace(std::make_pair(
3600 subsystem.second.label, std::to_string(subsystem.second.destination)));
3602 __COUT__ <<
"========== "
3603 <<
"Found " << info.processes.size() <<
" process types." << __E__;
3607 const std::string& typeString = nameTypePair.first;
3608 __COUTV__(typeString);
3610 nodeTypeToObjectMap.emplace(
3611 std::make_pair(typeString,
3612 std::map<std::string ,
3613 std::vector<std::string /*property*/>>()));
3615 auto it = info.processes.find(nameTypePair.second);
3616 if(it == info.processes.end())
3619 <<
"Found 0 " << typeString << __E__;
3623 <<
"Found " << it->second.size() <<
" " << typeString <<
"(s)"
3629 __SS__ <<
"Invalid artdaq node type '" << typeString <<
"' attempted!"
3633 __COUTV__(tableIt->second);
3636 std::stringstream ss;
3637 cfgMgr->getTableByName(tableIt->second)->getView().print(ss);
3638 __COUT_MULTI__(1, ss.str());
3648 const std::set<std::string > skipColumns(
3649 {ARTDAQ_TYPE_TABLE_HOSTNAME,
3650 ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS,
3651 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK,
3653 .colDaqFragmentIDs_,
3654 TableViewColumnInfo::COL_NAME_COMMENT,
3655 TableViewColumnInfo::COL_NAME_AUTHOR,
3656 TableViewColumnInfo::
3657 COL_NAME_CREATION});
3659 if(TTEST(1) && nodeLayoutNames.find(typeString) != nodeLayoutNames.end())
3665 for(
auto& artdaqNode : it->second)
3668 if(skipSet.find(StringMacros::encodeURIComponent(artdaqNode.label)) !=
3673 <<
"Found '" << artdaqNode.label <<
"' " << typeString << __E__;
3675 std::string nodeName = artdaqNode.label;
3676 bool status = artdaqNode.status;
3677 std::string hostname = artdaqNode.hostname;
3678 std::string subsystemId = std::to_string(artdaqNode.subsystem);
3679 std::string subsystemName =
3680 info.subsystems.at(artdaqNode.subsystem).label;
3691 std::vector<std::string> multiNodeNames, hostnameArray;
3696 StringMacros::encodeURIComponent(nodeName));
3698 __COUTV__(allNodes.size());
3699 if(!suppressMultiNode)
3700 for(
auto& otherNode : allNodes)
3702 if(skipSet.find(StringMacros::encodeURIComponent(
3703 otherNode.first)) != skipSet.end() ||
3704 otherNode.second.status() !=
3709 if(nodeName.find(
"_clone") != std::string::npos ||
3710 otherNode.first.find(
"_clone") != std::string::npos)
3717 otherNode.second.getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID)
3726 auto otherNodeColumns = otherNode.second.getChildren();
3728 bool isMultiNode =
true;
3729 for(
unsigned int i = 0;
3730 i < thisNodeColumns.size() && i < otherNodeColumns.size();
3734 if(skipColumns.find(thisNodeColumns[i].first) !=
3735 skipColumns.end() ||
3736 thisNodeColumns[i].second.isLinkNode())
3747 if(thisNodeColumns[i].second.getValueAsString() !=
3748 otherNodeColumns[i].second.getValueAsString())
3750 __COUT__ <<
"Mismatch, not multi-node member."
3752 isMultiNode =
false;
3759 __COUT__ <<
"Found '" << nodeName
3760 <<
"' multi-node member candidate '"
3761 << otherNode.first <<
"'" << __E__;
3764 if(!multiNodeNames.size())
3766 multiNodeNames.push_back(
3767 StringMacros::encodeURIComponent(nodeName));
3768 hostnameArray.push_back(
3769 StringMacros::encodeURIComponent(hostname));
3771 multiNodeNames.push_back(
3772 StringMacros::encodeURIComponent(otherNode.first));
3773 hostnameArray.push_back(StringMacros::encodeURIComponent(
3774 otherNode.second.getNode(ARTDAQ_TYPE_TABLE_HOSTNAME)
3777 __COUTV__(hostnameArray.back());
3779 StringMacros::encodeURIComponent(otherNode.first));
3784 unsigned int nodeFixedWildcardLength = 0, hostFixedWildcardLength = 0;
3785 std::string multiNodeString =
"", hostArrayString =
"";
3787 __COUTV__(nodeName);
3789 if(multiNodeNames.size() > 1)
3791 __COUT__ <<
"Handling multi-node printer syntax" << __E__;
3798 if(nodeLayoutNames.find(typeString) != nodeLayoutNames.end())
3806 std::string bestNodeLayoutName =
"";
3807 size_t bestNodeLayoutMatchCount =
3808 multiNodeNames.size() + 1;
3810 for(
const auto& layoutNameFull : nodeLayoutNames.at(typeString))
3812 __COUTTV__(layoutNameFull);
3813 size_t statusPos = layoutNameFull.find(
";status=");
3814 std::string layoutName = layoutNameFull.substr(0, statusPos);
3815 bool layoutStatus =
true;
3819 layoutStatus = status;
3821 layoutNameFull.substr(statusPos +
3822 std::string(
";status=").size()))
3823 layoutStatus =
false;
3825 __COUTTV__(layoutStatus);
3827 if(layoutStatus != status)
3829 __COUTT__ <<
"Status mismatch for template" << __E__;
3837 bool exactMatch =
true;
3839 for(
const auto& layoutSeg : layoutSplit)
3840 if((pos = nodeName.find(layoutSeg, pos)) ==
3843 __COUTT__ <<
"Did not find '" << layoutSeg <<
"' in '"
3844 << nodeName <<
"'" << __E__;
3849 __COUTTV__(exactMatch);
3852 size_t nodeLayoutMatchCount = 1;
3854 __COUT__ <<
"Found layout template name match! '"
3855 << layoutName <<
"' for node '" << nodeName
3856 <<
".' Trimming multinode candidates to match..."
3859 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3861 __COUTTV__(multiNodeNames[i]);
3862 std::string multiNodeName =
3865 __COUTTV__(multiNodeName);
3866 bool exactMatch =
true;
3868 for(
const auto& layoutSeg : layoutSplit)
3869 if((pos = multiNodeName.find(layoutSeg, pos)) ==
3872 __COUTT__ <<
"Did not find '" << layoutSeg
3873 <<
"' in '" << multiNodeName <<
"'"
3881 ++nodeLayoutMatchCount;
3882 __COUTT__ <<
"Found '" << layoutName <<
"' in '"
3883 << multiNodeName <<
"'" << __E__;
3888 __COUTTV__(nodeLayoutMatchCount);
3889 if(nodeLayoutMatchCount < bestNodeLayoutMatchCount)
3891 bestNodeLayoutName = layoutNameFull;
3892 bestNodeLayoutMatchCount = nodeLayoutMatchCount;
3893 __COUTTV__(bestNodeLayoutName);
3894 __COUTTV__(bestNodeLayoutMatchCount);
3899 __COUTV__(nodeName);
3905 if(bestNodeLayoutMatchCount > 0)
3907 __COUTV__(bestNodeLayoutName);
3908 std::string layoutNameFull = bestNodeLayoutName;
3909 __COUTTV__(layoutNameFull);
3910 size_t statusPos = layoutNameFull.find(
";status=");
3911 std::string layoutName = layoutNameFull.substr(0, statusPos);
3917 __COUT__ <<
"Found layout template name match! '"
3918 << layoutName <<
"' for node '" << nodeName
3919 <<
".' Trimming multinode candidates to match..."
3922 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3924 __COUTTV__(multiNodeNames[i]);
3925 std::string multiNodeName =
3927 __COUTTV__(multiNodeName);
3928 bool exactMatch =
true;
3930 for(
const auto& layoutSeg : layoutSplit)
3931 if((pos = multiNodeName.find(layoutSeg, pos)) ==
3934 __COUTT__ <<
"Did not find '" << layoutSeg
3935 <<
"' in '" << multiNodeName <<
"'"
3943 __COUT__ <<
"Trimming multinode candidate '"
3944 << multiNodeName <<
"'" << __E__;
3945 skipSet.erase(multiNodeNames[i]);
3946 multiNodeNames.erase(multiNodeNames.begin() + i);
3947 hostnameArray.erase(hostnameArray.begin() + i);
3954 __COUTV__(nodeName);
3959 std::vector<std::string>
3963 unsigned int maxScore = 0;
3965 unsigned int minScore = -1;
3966 std::vector<unsigned int> scoreVector;
3967 scoreVector.push_back(-1);
3968 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3972 __COUTS__(3) << multiNodeNames[0] <<
" vs "
3973 << multiNodeNames[i] << __E__;
3976 for(
unsigned int j = 0, k = 0; j < multiNodeNames[0].size() &&
3977 k < multiNodeNames[i].size();
3980 while(j < multiNodeNames[0].size() &&
3981 !(multiNodeNames[0][j] >=
'a' &&
3982 multiNodeNames[0][j] <=
'z') &&
3983 !(multiNodeNames[0][j] >=
'A' &&
3984 multiNodeNames[0][j] <=
'Z'))
3986 while(k < multiNodeNames[i].size() &&
3987 !(multiNodeNames[i][k] >=
'a' &&
3988 multiNodeNames[i][k] <=
'z') &&
3989 !(multiNodeNames[i][k] >=
'A' &&
3990 multiNodeNames[i][k] <=
'Z'))
3993 while(k < multiNodeNames[i].size() &&
3994 multiNodeNames[0][j] != multiNodeNames[i][k])
3998 << j <<
"-" << k <<
" of " << multiNodeNames[0].size()
3999 <<
"-" << multiNodeNames[i].size() << __E__;
4001 if(j < multiNodeNames[0].size() &&
4002 k < multiNodeNames[i].size())
4006 __COUTVS__(3, score);
4009 for(
unsigned int j = multiNodeNames[0].size() - 1,
4010 k = multiNodeNames[i].size() - 1;
4011 j < multiNodeNames[0].size() &&
4012 k < multiNodeNames[i].size();
4015 while(j < multiNodeNames[0].size() &&
4016 !(multiNodeNames[0][j] >=
'a' &&
4017 multiNodeNames[0][j] <=
'z') &&
4018 !(multiNodeNames[0][j] >=
'A' &&
4019 multiNodeNames[0][j] <=
'Z'))
4021 while(k < multiNodeNames[i].size() &&
4022 !(multiNodeNames[i][k] >=
'a' &&
4023 multiNodeNames[i][k] <=
'z') &&
4024 !(multiNodeNames[i][k] >=
'A' &&
4025 multiNodeNames[i][k] <=
'Z'))
4028 while(k < multiNodeNames[i].size() &&
4029 multiNodeNames[0][j] != multiNodeNames[i][k])
4032 __COUTS__(3) <<
"BACK" << j <<
"-" << k <<
" of "
4033 << multiNodeNames[0].size() <<
"-"
4034 << multiNodeNames[i].size() << __E__;
4036 if(j < multiNodeNames[0].size() &&
4037 k < multiNodeNames[i].size())
4041 __COUTVS__(3, score / 2.0);
4043 scoreVector.push_back(score);
4045 if(score > maxScore)
4050 if(score < minScore)
4057 __COUTVS__(2, minScore);
4058 __COUTVS__(2, maxScore);
4060 __COUT__ <<
"Trimming multi-node members with low match score..."
4065 for(
unsigned int i = multiNodeNames.size() - 1;
4066 i > 0 && i < multiNodeNames.size();
4071 if(maxScore > multiNodeNames[0].size() &&
4072 scoreVector[i] >= maxScore)
4076 __COUT__ <<
"Trimming low score match " << multiNodeNames[i]
4077 <<
" for node name " << nodeName << __E__;
4079 trimmedNodeNames.push_back(multiNodeNames[i]);
4080 skipSet.erase(multiNodeNames[i]);
4081 multiNodeNames.erase(multiNodeNames.begin() + i);
4082 hostnameArray.erase(hostnameArray.begin() + i);
4093 if(multiNodeNames.size() > 2)
4095 bool sameLengths =
true;
4096 size_t nameLen = multiNodeNames[0].size();
4097 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4098 if(multiNodeNames[i].size() != nameLen)
4100 sameLengths =
false;
4104 if(sameLengths && nameLen > 0)
4106 std::vector<bool> varies(nameLen,
false);
4107 for(
unsigned int pos = 0; pos < nameLen; ++pos)
4108 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4109 if(multiNodeNames[i][pos] != multiNodeNames[0][pos])
4117 unsigned int start, end;
4120 std::vector<VaryRun> runs;
4121 for(
unsigned int pos = 0; pos < nameLen;)
4128 unsigned int rStart = pos;
4129 bool runAllDigit =
true;
4130 while(pos < nameLen && varies[pos])
4132 for(
unsigned int i = 0;
4133 i < multiNodeNames.size() && runAllDigit;
4135 if(!(multiNodeNames[i][pos] >=
'0' &&
4136 multiNodeNames[i][pos] <=
'9'))
4137 runAllDigit =
false;
4140 runs.push_back({rStart, pos, runAllDigit});
4149 for(
auto& run : runs)
4153 while(run.start > 0)
4155 bool allDigitAtPrev =
true;
4156 for(
unsigned int i = 0;
4157 i < multiNodeNames.size() && allDigitAtPrev;
4159 if(!(multiNodeNames[i][run.start - 1] >=
'0' &&
4160 multiNodeNames[i][run.start - 1] <=
'9'))
4161 allDigitAtPrev =
false;
4168 unsigned int numDigitRuns = 0;
4169 for(
const auto& run : runs)
4173 if(numDigitRuns > 1 && numDigitRuns == runs.size())
4176 <<
"Numeric wildcard refinement: found "
4178 <<
" separate digit-varying groups in '" << nodeName
4179 <<
"'. Splitting to favor numeric-only wildcards."
4188 unsigned int bestRunToFix = 0;
4189 unsigned int fewestUnique = (
unsigned int)-1;
4190 unsigned int lowestHostCorr = (
unsigned int)-1;
4191 for(
unsigned int r = 0; r < runs.size(); ++r)
4193 std::set<std::string> uniqueVals;
4194 for(
unsigned int i = 0; i < multiNodeNames.size();
4196 uniqueVals.insert(multiNodeNames[i].substr(
4197 runs[r].start, runs[r].end - runs[r].start));
4201 std::map<std::string, std::set<std::string>>
4203 for(
unsigned int i = 0; i < multiNodeNames.size();
4206 std::string dv = multiNodeNames[i].substr(
4207 runs[r].start, runs[r].end - runs[r].start);
4208 valToHosts[dv].insert(hostnameArray[i]);
4213 unsigned int hostCorr = 0;
4214 if(valToHosts.size() > 1)
4217 std::set<std::string> allHostSets;
4218 for(
const auto& [dv, hosts] : valToHosts)
4220 std::string hostKey;
4221 for(
const auto& h : hosts)
4223 allHostSets.insert(hostKey);
4225 hostCorr = allHostSets.size();
4228 __COUTT__ <<
"Digit run " << r <<
" ["
4229 << runs[r].start <<
"-" << (runs[r].end - 1)
4230 <<
"]: uniqueVals=" << uniqueVals.size()
4231 <<
" hostCorr=" << hostCorr << __E__;
4237 if(uniqueVals.size() < fewestUnique ||
4238 (uniqueVals.size() == fewestUnique &&
4239 hostCorr < lowestHostCorr))
4241 fewestUnique = uniqueVals.size();
4242 lowestHostCorr = hostCorr;
4247 std::string keepVal = multiNodeNames[0].substr(
4248 runs[bestRunToFix].start,
4249 runs[bestRunToFix].end - runs[bestRunToFix].start);
4251 __COUTT__ <<
"Fixing digit group at positions "
4252 << runs[bestRunToFix].start <<
"-"
4253 << (runs[bestRunToFix].end - 1) <<
" to value '"
4255 <<
"' (fewest unique=" << fewestUnique <<
")"
4258 for(
unsigned int i = multiNodeNames.size() - 1;
4259 i > 0 && i < multiNodeNames.size();
4262 std::string val = multiNodeNames[i].substr(
4263 runs[bestRunToFix].start,
4264 runs[bestRunToFix].end -
4265 runs[bestRunToFix].start);
4268 __COUTT__ <<
"Numeric refinement trim: "
4269 << multiNodeNames[i]
4270 <<
" (digit group '" << val <<
"' != '"
4271 << keepVal <<
"')" << __E__;
4272 trimmedNodeNames.push_back(multiNodeNames[i]);
4273 skipSet.erase(multiNodeNames[i]);
4274 multiNodeNames.erase(multiNodeNames.begin() + i);
4275 hostnameArray.erase(hostnameArray.begin() + i);
4278 __COUT__ <<
"After numeric refinement: "
4279 << multiNodeNames.size() <<
" nodes remain for '"
4280 << nodeName <<
"'." << __E__;
4291 if(multiNodeNames.size() > 1)
4299 auto matchesCommonChunksPattern =
4300 [](
const std::string& name,
4301 const std::vector<std::string>& chunks,
4302 const std::vector<std::string>& wildcards) ->
bool {
4304 bool wildcardsAllNumeric = !wildcards.empty();
4305 for(
const auto& w : wildcards)
4308 w.find_first_not_of(
"0123456789") != std::string::npos)
4310 wildcardsAllNumeric =
false;
4316 for(
unsigned int c = 0; c < chunks.size(); ++c)
4318 if(chunks[c].empty())
4322 found = (name.size() >= chunks[c].size() &&
4324 0, chunks[c].size(), chunks[c]) == 0)
4326 : std::string::npos;
4329 found = name.find(chunks[c], pos);
4332 if(wildcardsAllNumeric && found != std::string::npos)
4334 std::string gap = name.substr(pos, found - pos);
4336 gap.find_first_not_of(
"0123456789") !=
4341 if(found == std::string::npos)
4343 pos = found + chunks[c].size();
4346 if(wildcardsAllNumeric && pos < name.size())
4348 std::string trailingGap = name.substr(pos);
4349 if(trailingGap.find_first_not_of(
"0123456789") !=
4356 bool collisionRetry =
true;
4357 while(collisionRetry && multiNodeNames.size() > 1)
4359 collisionRetry =
false;
4362 std::vector<std::string> trialCommonChunks;
4363 std::vector<std::string> trialWildcards;
4364 unsigned int trialFixedLen = 0;
4370 __COUT__ <<
"Collision check: trialCommonChunks = "
4375 bool collisionFound =
false;
4376 for(
const auto& trimmedNode : trimmedNodeNames)
4378 if(matchesCommonChunksPattern(
4379 trimmedNode, trialCommonChunks, trialWildcards))
4381 __COUT__ <<
"Collision detected: trimmed node '"
4383 <<
"' matches base pattern from commonChunks"
4385 collisionFound =
true;
4395 std::string currentStatusStr = status ?
"1" :
"0";
4396 for(
const auto& existingEntry :
4397 nodeTypeToObjectMap.at(typeString))
4399 std::string existingBaseName = existingEntry.first;
4400 size_t statusPos = existingBaseName.find(
";status=");
4401 if(statusPos != std::string::npos)
4404 if(existingBaseName.substr(
4406 std::string(
";status=").size()) !=
4410 existingBaseName.substr(0, statusPos);
4413 if(matchesCommonChunksPattern(existingBaseName,
4423 std::string existingGap;
4424 if(trialCommonChunks.size() == 1 &&
4425 existingBaseName.size() >
4426 trialCommonChunks[0].size())
4427 existingGap = existingBaseName.substr(
4428 trialCommonChunks[0].size());
4429 else if(trialCommonChunks.size() >= 2)
4431 size_t suffixLen = 0;
4433 ci < trialCommonChunks.size();
4435 suffixLen += trialCommonChunks[ci].size();
4436 if(existingBaseName.size() >
4437 trialCommonChunks[0].size() + suffixLen)
4438 existingGap = existingBaseName.substr(
4439 trialCommonChunks[0].size(),
4440 existingBaseName.size() -
4441 trialCommonChunks[0].size() -
4445 if(!existingGap.empty())
4447 bool gapInWildcards =
false;
4448 for(
const auto& w : trialWildcards)
4449 if(w == existingGap)
4451 gapInWildcards =
true;
4457 <<
"Existing entry '"
4458 << existingEntry.first
4459 <<
"' matches pattern but gap '"
4461 <<
"' is not in multinode wildcards"
4462 " - not a collision"
4469 <<
"Collision detected: existing map entry '"
4470 << existingEntry.first
4471 <<
"' matches base pattern from commonChunks"
4473 collisionFound =
true;
4483 __COUT__ <<
"Re-scoring remaining multi-node members with "
4484 "full character matching to resolve collision..."
4487 unsigned int fullMaxScore = 0;
4488 std::vector<unsigned int> fullScoreVector;
4489 fullScoreVector.push_back(-1);
4491 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4493 unsigned int fscore = 0;
4495 for(
unsigned int j = 0; j < multiNodeNames[0].size() &&
4496 j < multiNodeNames[i].size();
4499 if(multiNodeNames[0][j] == multiNodeNames[i][j])
4504 fullScoreVector.push_back(fscore);
4505 if(fscore > fullMaxScore)
4506 fullMaxScore = fscore;
4509 __COUT__ <<
"Full char rescore: maxScore = " << fullMaxScore
4513 bool anyTrimmed =
false;
4514 for(
unsigned int i = multiNodeNames.size() - 1;
4515 i > 0 && i < multiNodeNames.size();
4518 if(fullScoreVector[i] >= fullMaxScore)
4521 __COUT__ <<
"Collision trim: removing "
4522 << multiNodeNames[i] <<
" (score "
4523 << fullScoreVector[i] <<
" < " << fullMaxScore
4524 <<
") for node name " << nodeName << __E__;
4526 trimmedNodeNames.push_back(multiNodeNames[i]);
4527 skipSet.erase(multiNodeNames[i]);
4528 multiNodeNames.erase(multiNodeNames.begin() + i);
4529 hostnameArray.erase(hostnameArray.begin() + i);
4531 collisionRetry =
true;
4539 __COUT__ <<
"Cannot narrow multi-node group further to "
4540 "resolve collision. Abandoning multi-node "
4543 <<
"' - remaining members will be "
4544 "processed individually."
4548 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4549 skipSet.erase(multiNodeNames[i]);
4550 multiNodeNames.resize(1);
4551 hostnameArray.resize(1);
4556 __COUT__ <<
"After collision resolution:" << __E__;
4557 __COUTV__(nodeName);
4563 __COUTV__(nodeName);
4570 __COUT__ <<
"Reorganizing multinode '" << nodeName
4571 <<
"' alphabetically..." << __E__;
4573 std::pair<std::string , std::string >>
4575 for(
unsigned int i = 0; i < multiNodeNames.size(); ++i)
4577 std::make_pair(multiNodeNames[i], hostnameArray[i]));
4582 multiNodeNames.clear();
4583 hostnameArray.clear();
4584 for(
const auto& orderedPair : reorderSet)
4586 multiNodeNames.push_back(orderedPair.first);
4587 hostnameArray.push_back(orderedPair.second);
4591 __COUTV__(nodeName);
4596 auto expandNumericWildcards =
4597 [](std::vector<std::string>& commonChunks,
4598 std::vector<std::string>& wildcards,
4599 const std::string& logPrefix) {
4600 bool allDigitWC =
true;
4601 for(
const auto& wc : wildcards)
4603 if(wc.empty() || wc.find_first_not_of(
"0123456789") !=
4610 if(allDigitWC && !commonChunks.empty() &&
4611 !commonChunks[0].empty())
4613 size_t trailingDigits = 0;
4614 for(
int ci = (
int)commonChunks[0].size() - 1; ci >= 0;
4617 if(commonChunks[0][ci] >=
'0' &&
4618 commonChunks[0][ci] <=
'9')
4623 if(trailingDigits > 0 &&
4624 trailingDigits < commonChunks[0].size())
4626 std::string prefix = commonChunks[0].substr(
4627 commonChunks[0].size() - trailingDigits);
4628 commonChunks[0] = commonChunks[0].substr(
4629 0, commonChunks[0].size() - trailingDigits);
4630 for(
auto& wc : wildcards)
4634 << logPrefix <<
"moved '" << prefix
4635 <<
"' from commonChunk prefix into wildcards."
4642 if(multiNodeNames.size() > 1)
4644 std::vector<std::string> commonChunks;
4645 std::vector<std::string> wildcards;
4649 bool wildcardsNeeded =
4653 nodeFixedWildcardLength);
4655 if(!wildcardsNeeded || wildcards.size() != multiNodeNames.size())
4658 <<
"Impossible extractCommonChunks result! Please notify "
4659 "admins or try to simplify record naming convention."
4671 expandNumericWildcards(
4672 commonChunks, wildcards,
"Expanded numeric wildcards: ");
4678 for(
auto& commonChunk : commonChunks)
4680 nodeName += (!first ?
"*" :
"") + commonChunk;
4684 if(commonChunks.size() == 1)
4687 __COUTV__(nodeName);
4694 bool allIntegers =
true;
4695 for(
auto& wildcard : wildcards)
4698 else if(wildcard.size() == 0)
4700 allIntegers =
false;
4704 for(
unsigned int i = 0; i < wildcard.size(); ++i)
4705 if(!(wildcard[i] >=
'0' && wildcard[i] <=
'9'))
4707 allIntegers =
false;
4711 __COUTV__(allIntegers);
4717 std::vector<unsigned int> intWildcards;
4718 for(
auto& wildcard : wildcards)
4719 intWildcards.push_back(strtol(wildcard.c_str(), 0, 10));
4723 unsigned int hyphenLo = -1;
4724 bool isFirst =
true;
4725 for(
unsigned int i = 0; i < intWildcards.size(); ++i)
4727 if(i + 1 < intWildcards.size() &&
4728 intWildcards[i] + 1 == intWildcards[i + 1])
4740 (isFirst ?
"" :
",") +
4741 std::to_string(intWildcards[i]);
4746 if(intWildcards[hyphenLo] + 1 == intWildcards[i])
4748 (isFirst ?
"" :
",") +
4749 std::to_string(intWildcards[hyphenLo]) +
4750 "," + std::to_string(intWildcards[i]);
4753 (isFirst ?
"" :
",") +
4754 std::to_string(intWildcards[hyphenLo]) +
4755 "-" + std::to_string(intWildcards[i]);
4765 nodeFixedWildcardLength =
4769 __COUTV__(multiNodeString);
4770 __COUTV__(nodeFixedWildcardLength);
4773 if(hostnameArray.size() > 1)
4775 std::vector<std::string> commonChunks;
4776 std::vector<std::string> wildcards;
4780 bool wildcardsNeeded =
4784 hostFixedWildcardLength);
4786 __COUTV__(wildcardsNeeded);
4798 expandNumericWildcards(
4801 "Expanded numeric wildcards for hostname: ");
4807 for(
auto& commonChunk : commonChunks)
4809 hostname += (!first ?
"*" :
"") + commonChunk;
4813 if(wildcardsNeeded && commonChunks.size() == 1)
4816 __COUTV__(hostname);
4826 bool allIntegers =
true;
4827 for(
auto& wildcard : wildcards)
4828 for(
unsigned int i = 0; i < wildcard.size(); ++i)
4829 if(!(wildcard[i] >=
'0' && wildcard[i] <=
'9'))
4831 allIntegers =
false;
4835 __COUTV__(allIntegers);
4842 std::vector<unsigned int> intWildcards;
4843 for(
auto& wildcard : wildcards)
4844 intWildcards.push_back(
4845 strtol(wildcard.c_str(), 0, 10));
4849 unsigned int hyphenLo = -1;
4850 bool isFirst =
true;
4851 for(
unsigned int i = 0; i < intWildcards.size(); ++i)
4853 if(i + 1 < intWildcards.size() &&
4854 intWildcards[i] + 1 == intWildcards[i + 1])
4866 (isFirst ?
"" :
",") +
4867 std::to_string(intWildcards[i]);
4872 if(intWildcards[hyphenLo] + 1 ==
4875 (isFirst ?
"" :
",") +
4877 intWildcards[hyphenLo]) +
4878 "," + std::to_string(intWildcards[i]);
4881 (isFirst ?
"" :
",") +
4883 intWildcards[hyphenLo]) +
4884 "-" + std::to_string(intWildcards[i]);
4894 hostFixedWildcardLength =
4898 __COUTV__(hostArrayString);
4899 __COUTV__(hostFixedWildcardLength);
4909 auto result = nodeTypeToObjectMap.at(typeString)
4910 .emplace(std::make_pair(
4911 nodeName, std::vector<std::string /*property*/>()));
4915 __SS__ <<
"Here is the current nodeTypeToObjectMap:" << __E__;
4916 for(
const auto& typePair : nodeTypeToObjectMap)
4918 ss <<
"\tType: " << typePair.first << __E__;
4919 for(
const auto& nodePair : typePair.second)
4921 ss <<
"\t\tNode: " << nodePair.first << __E__;
4922 for(
const auto& property : nodePair.second)
4923 ss <<
"\t\t\tProperty: " <<
property << __E__;
4926 __COUT__ << ss.str() << __E__;
4932 <<
"Collision detected for node '" << nodeName <<
"' of type '"
4934 <<
"' when inserting into nodeTypeToObjectMap. This likely means "
4935 "that two nodes have the same name and status, and if so, "
4936 "they would be indistinguishable in printer syntax. "
4937 <<
"Please notify admins or try to simplify record naming "
4941 __SS__ <<
"Impossible printer syntax handling result! Collision of "
4942 "base names. Please notify "
4943 "admins or try to simplify record naming convention."
4948 nodeTypeToObjectMap.at(typeString)
4950 .push_back(status ?
"1" :
"0");
4952 nodeTypeToObjectMap.at(typeString).at(nodeName).push_back(hostname);
4954 nodeTypeToObjectMap.at(typeString).at(nodeName).push_back(subsystemId);
4955 if(multiNodeNames.size() > 1)
4957 nodeTypeToObjectMap.at(typeString)
4959 .push_back(multiNodeString);
4961 nodeTypeToObjectMap.at(typeString)
4963 .push_back(std::to_string(nodeFixedWildcardLength));
4965 if(hostnameArray.size() > 1)
4967 nodeTypeToObjectMap.at(typeString)
4969 .push_back(hostArrayString);
4971 nodeTypeToObjectMap.at(typeString)
4973 .push_back(std::to_string(hostFixedWildcardLength));
4977 __COUTV__(multiNodeString);
4979 __COUTV__(hostArrayString);
4980 __COUT__ <<
"Done with extraction of node '" << nodeName <<
"'" << __E__;
4986 __COUT__ <<
"Done getting artdaq nodes." << __E__;
4988 return ARTDAQTableBase::info_;
5002 const std::map<std::string ,
5003 std::map<std::string ,
5004 std::vector<std::string /*property*/>>>& nodeTypeToObjectMap,
5005 const std::map<std::string ,
5006 std::string >& subsystemObjectMap)
5008 __COUT__ <<
"setAndActivateARTDAQSystem()" << __E__;
5010 const std::string& author = cfgMgr->
getUsername();
5021 GroupEditStruct configGroupEdit(ConfigurationManager::GroupType::CONFIGURATION_TYPE,
5024 unsigned int artdaqSupervisorRow = TableView::INVALID;
5031 bool needArtdaqSupervisorParents =
true;
5032 bool needArtdaqSupervisorCreation =
false;
5034 __COUTV__(artdaqContext);
5039 const std::string& activeContextGroupName =
5040 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE);
5042 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE);
5043 const std::string& activeConfigGroupName = cfgMgr->getActiveGroupName(
5044 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
5045 const TableGroupKey& activeConfigGroupKey = cfgMgr->getActiveGroupKey(
5046 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
5048 __COUTV__(activeContextGroupName);
5049 __COUTV__(activeContextGroupKey);
5050 __COUTV__(activeConfigGroupName);
5051 __COUTV__(activeConfigGroupKey);
5052 __COUTV__(cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5053 .
getNode(artdaqContext->contextUID_)
5056 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5057 .
getNode(artdaqContext->contextUID_)
5058 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5061 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5062 .
getNode(artdaqContext->contextUID_)
5063 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5064 .
getNode(artdaqContext->applications_[0].applicationUID_)
5066 __COUTV__(artdaqContext->applications_[0].applicationUID_);
5067 __COUTV__(XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
5069 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5070 .
getNode(artdaqContext->contextUID_)
5071 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5072 .
getNode(artdaqContext->applications_[0].applicationUID_)
5073 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_)
5077 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5078 .
getNode(artdaqContext->contextUID_)
5079 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5080 .
getNode(artdaqContext->applications_[0].applicationUID_)
5081 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
5086 needArtdaqSupervisorCreation =
true;
5088 artdaqSupervisorRow = artdaqSupervisorNode.
getRow();
5090 needArtdaqSupervisorParents =
false;
5094 needArtdaqSupervisorCreation =
true;
5096 __COUTV__(needArtdaqSupervisorCreation);
5099 if(!artdaqContext || needArtdaqSupervisorCreation)
5101 __COUT__ <<
"No artdaq Supervisor found! Creating..." << __E__;
5102 __COUTV__(needArtdaqSupervisorParents);
5104 std::string artdaqSupervisorUID;
5113 ARTDAQ_SUPERVISOR_TABLE,
true );
5117 std::stringstream ss;
5118 artdaqSupervisorTable.tableView_->print(ss);
5119 __COUT_MULTI__(0, ss.str());
5123 row = artdaqSupervisorTable.tableView_->
addRow(
5124 author,
true ,
"artdaqSupervisor");
5127 artdaqSupervisorUID =
5128 artdaqSupervisorTable.tableView_
5129 ->getDataView()[row][artdaqSupervisorTable.tableView_->
getColUID()];
5130 artdaqSupervisorRow = row;
5132 __COUTV__(artdaqSupervisorRow);
5133 __COUTV__(artdaqSupervisorUID);
5139 artdaqSupervisorTable.tableView_->
findCol(
5140 colARTDAQSupervisor_.colDAQInterfaceDebugLevel_));
5143 "${MRB_BUILDDIR}/../setup_ots.sh",
5145 artdaqSupervisorTable.tableView_->
findCol(
5146 colARTDAQSupervisor_.colDAQSetupScript_));
5150 ARTDAQ_READER_TABLE,
5152 artdaqSupervisorTable.tableView_->
findCol(
5153 colARTDAQSupervisor_.colLinkToBoardReaders_));
5157 artdaqSupervisorTable.tableView_->
findCol(
5158 colARTDAQSupervisor_.colLinkToBoardReadersGroupID_),
5159 artdaqSupervisorUID +
5163 ARTDAQ_BUILDER_TABLE,
5165 artdaqSupervisorTable.tableView_->
findCol(
5166 colARTDAQSupervisor_.colLinkToEventBuilders_));
5169 artdaqSupervisorTable.tableView_->
findCol(
5170 colARTDAQSupervisor_.colLinkToEventBuildersGroupID_),
5171 artdaqSupervisorUID +
5175 ARTDAQ_LOGGER_TABLE,
5177 artdaqSupervisorTable.tableView_->
findCol(
5178 colARTDAQSupervisor_.colLinkToDataLoggers_));
5181 artdaqSupervisorTable.tableView_->
findCol(
5182 colARTDAQSupervisor_.colLinkToDataLoggersGroupID_),
5183 artdaqSupervisorUID +
5187 ARTDAQ_DISPATCHER_TABLE,
5189 artdaqSupervisorTable.tableView_->
findCol(
5190 colARTDAQSupervisor_.colLinkToDispatchers_));
5193 artdaqSupervisorTable.tableView_->
findCol(
5194 colARTDAQSupervisor_.colLinkToDispatchersGroupID_),
5195 artdaqSupervisorUID +
5200 ARTDAQ_ROUTER_TABLE,
5202 artdaqSupervisorTable.tableView_->
findCol(
5203 colARTDAQSupervisor_.colLinkToRoutingManagers_));
5206 artdaqSupervisorTable.tableView_->
findCol(
5207 colARTDAQSupervisor_.colLinkToRoutingManagersGroupID_),
5208 artdaqSupervisorUID +
5213 std::stringstream ss;
5214 artdaqSupervisorTable.tableView_->print(ss);
5215 __COUT_MULTI__(0, ss.str());
5222 ConfigurationManager::GroupType::CONTEXT_TYPE, cfgMgr);
5225 ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME,
true );
5227 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME,
true );
5229 ConfigurationManager::XDAQ_APP_PROPERTY_TABLE_NAME,
5236 std::string contextUID;
5237 std::string contextAppGroupID;
5239 if(needArtdaqSupervisorParents)
5242 row = contextTable.tableView_->
addRow(
5243 author,
true ,
"artdaqContext");
5249 contextTable.tableView_
5250 ->getDataView()[row][contextTable.tableView_->
getColUID()];
5253 __COUTV__(contextUID);
5257 "http://${HOSTNAME}",
5259 contextTable.tableView_->
findCol(
5260 XDAQContextTable::colContext_.colAddress_));
5263 contextTable.tableView_->
findCol(
5264 XDAQContextTable::colContext_.colPort_),
5270 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME,
5272 contextTable.tableView_->
findCol(
5273 XDAQContextTable::colContext_.colLinkToApplicationTable_));
5276 contextTable.tableView_->
findCol(
5277 XDAQContextTable::colContext_.colLinkToApplicationGroupID_),
5278 "artdaqContextApps");
5280 __COUTV__(contextAppGroupID);
5284 std::string appPropertiesGroupID;
5290 if(needArtdaqSupervisorParents)
5294 unsigned int c = appTable.tableView_->
findCol(
5295 XDAQContextTable::colApplication_.colClass_);
5296 for(
unsigned int r = 0;
5297 r < appTable.tableView_->getNumberOfRows();
5299 if(appTable.tableView_->getDataView()[r][c] ==
5300 ARTDAQ_SUPERVISOR_CLASS)
5303 <<
"Found partially existing artdaq Supervisor "
5305 << appTable.tableView_->getDataView()
5307 <<
"'... Disabling it." << __E__;
5314 row = appTable.tableView_->
addRow(
5315 author,
true ,
"artdaqSupervisor");
5322 ->getDataView()[row][appTable.tableView_->
getColUID()];
5329 ARTDAQ_SUPERVISOR_CLASS,
5332 XDAQContextTable::colApplication_.colClass_));
5335 "${OTSDAQ_LIB}/libARTDAQSupervisor.so",
5338 XDAQContextTable::colApplication_.colModule_));
5343 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5344 .colApplicationGroupID_));
5348 ConfigurationManager::XDAQ_APP_PROPERTY_TABLE_NAME,
5350 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5351 .colLinkToPropertyTable_));
5354 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5355 .colLinkToPropertyGroupID_),
5356 appUID +
"Properties");
5358 __COUTV__(appPropertiesGroupID);
5362 __COUT__ <<
"Getting row of existing parent supervisor." << __E__;
5366 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5367 .
getNode(artdaqContext->contextUID_)
5368 .
getNode(XDAQContextTable::colContext_
5369 .colLinkToApplicationTable_)
5370 .
getNode(artdaqContext->applications_[0].applicationUID_)
5379 ARTDAQ_SUPERVISOR_TABLE,
5382 XDAQContextTable::colApplication_.colLinkToSupervisorTable_));
5384 artdaqSupervisorUID,
5387 XDAQContextTable::colApplication_.colLinkToSupervisorUID_));
5392 if(needArtdaqSupervisorParents)
5396 const std::vector<std::string> propertyUIDs = {
"Partition0",
5399 "BoardReaderTimeout",
5400 "EventBuilderTimeout",
5401 "DataLoggerTimeout",
5402 "DispatcherTimeout"};
5403 const std::vector<std::string> propertyNames = {
5405 "productsdir_for_bash_scripts",
5406 "max_fragment_size_bytes",
5407 "boardreader_timeout",
5408 "eventbuilder_timeout",
5409 "datalogger_timeout",
5410 "dispatcher_timeout"
5412 const std::vector<std::string> propertyValues = {
5422 for(
unsigned int i = 0; i < propertyNames.size(); ++i)
5425 row = appPropertyTable.tableView_->
addRow(
5428 appUID + propertyUIDs[i]);
5431 "1", row, appPropertyTable.tableView_->
getColStatus());
5435 "ots::SupervisorProperty",
5437 appPropertyTable.tableView_->
findCol(
5438 XDAQContextTable::colAppProperty_.colPropertyType_));
5443 appPropertyTable.tableView_->
findCol(
5444 XDAQContextTable::colAppProperty_.colPropertyName_));
5449 appPropertyTable.tableView_->
findCol(
5450 XDAQContextTable::colAppProperty_.colPropertyValue_));
5453 appPropertiesGroupID,
5455 appPropertyTable.tableView_->
findCol(
5456 XDAQContextTable::colAppProperty_.colPropertyGroupID_));
5461 std::stringstream ss;
5462 contextTable.tableView_->print(ss);
5463 __COUT_MULTI__(0, ss.str());
5466 std::stringstream ss;
5467 appTable.tableView_->print(ss);
5468 __COUT_MULTI__(0, ss.str());
5471 std::stringstream ss;
5472 appPropertyTable.tableView_->print(ss);
5473 __COUT_MULTI__(0, ss.str());
5476 contextTable.tableView_
5478 appTable.tableView_->
init();
5479 appPropertyTable.tableView_
5485 <<
"Table errors while creating ARTDAQ Supervisor. Erasing all newly "
5486 "created table versions."
5491 __COUT_INFO__ <<
"Edits complete for new artdaq Supervisor! Created '"
5492 << appUID <<
"'" << __E__;
5496 __SS__ <<
"DEBUG blocking artdaq supervisor save!" << __E__;
5500 contextGroupEdit.saveChanges(contextGroupEdit.originalGroupName_,
5512 artdaqSupervisorRow =
5513 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5514 .
getNode(artdaqContext->contextUID_)
5515 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5516 .
getNode(artdaqContext->applications_[0].applicationUID_)
5517 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_)
5521 __COUT__ <<
"------------------------- artdaq nodes to save:" << __E__;
5522 for(
auto& subsystemPair : subsystemObjectMap)
5524 __COUTV__(subsystemPair.first);
5528 for(
auto& nodeTypePair : nodeTypeToObjectMap)
5530 __COUTV__(nodeTypePair.first);
5532 for(
auto& nodePair : nodeTypePair.second)
5534 __COUTV__(nodePair.first);
5538 __COUT__ <<
"------------------------- end artdaq nodes to save." << __E__;
5542 __COUTV__(artdaqSupervisorRow);
5543 if(artdaqSupervisorRow >= TableView::INVALID)
5545 __SS__ <<
"Invalid artdaq Supervisor row " << artdaqSupervisorRow <<
" found!"
5560 ARTDAQ_SUPERVISOR_TABLE,
true );
5564 std::string artdaqSupervisorUID =
5565 artdaqSupervisorTable.tableView_
5566 ->getDataView()[artdaqSupervisorRow]
5567 [artdaqSupervisorTable.tableView_->
getColUID()];
5570 if(artdaqSupervisorTable.tableView_
5571 ->getDataView()[artdaqSupervisorRow]
5572 [artdaqSupervisorTable.tableView_->
findCol(
5573 colARTDAQSupervisor_.colLinkToBoardReaders_)] ==
5574 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5576 __COUT__ <<
"Fixing missing link to Readers" << __E__;
5578 ARTDAQ_READER_TABLE,
5579 artdaqSupervisorRow,
5580 artdaqSupervisorTable.tableView_->
findCol(
5581 colARTDAQSupervisor_.colLinkToBoardReaders_));
5583 artdaqSupervisorRow,
5584 artdaqSupervisorTable.tableView_->
findCol(
5585 colARTDAQSupervisor_.colLinkToBoardReadersGroupID_),
5586 artdaqSupervisorUID +
5591 if(artdaqSupervisorTable.tableView_
5592 ->getDataView()[artdaqSupervisorRow]
5593 [artdaqSupervisorTable.tableView_->
findCol(
5594 colARTDAQSupervisor_.colLinkToEventBuilders_)] ==
5595 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5597 __COUT__ <<
"Fixing missing link to Builders" << __E__;
5599 ARTDAQ_BUILDER_TABLE,
5600 artdaqSupervisorRow,
5601 artdaqSupervisorTable.tableView_->
findCol(
5602 colARTDAQSupervisor_.colLinkToEventBuilders_));
5604 artdaqSupervisorRow,
5605 artdaqSupervisorTable.tableView_->
findCol(
5606 colARTDAQSupervisor_.colLinkToEventBuildersGroupID_),
5607 artdaqSupervisorUID +
5612 if(artdaqSupervisorTable.tableView_
5613 ->getDataView()[artdaqSupervisorRow]
5614 [artdaqSupervisorTable.tableView_->
findCol(
5615 colARTDAQSupervisor_.colLinkToDataLoggers_)] ==
5616 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5618 __COUT__ <<
"Fixing missing link to Loggers" << __E__;
5620 ARTDAQ_LOGGER_TABLE,
5621 artdaqSupervisorRow,
5622 artdaqSupervisorTable.tableView_->
findCol(
5623 colARTDAQSupervisor_.colLinkToDataLoggers_));
5625 artdaqSupervisorRow,
5626 artdaqSupervisorTable.tableView_->
findCol(
5627 colARTDAQSupervisor_.colLinkToDataLoggersGroupID_),
5628 artdaqSupervisorUID +
5633 if(artdaqSupervisorTable.tableView_
5634 ->getDataView()[artdaqSupervisorRow]
5635 [artdaqSupervisorTable.tableView_->
findCol(
5636 colARTDAQSupervisor_.colLinkToDispatchers_)] ==
5637 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5639 __COUT__ <<
"Fixing missing link to Dispatchers" << __E__;
5641 ARTDAQ_DISPATCHER_TABLE,
5642 artdaqSupervisorRow,
5643 artdaqSupervisorTable.tableView_->
findCol(
5644 colARTDAQSupervisor_.colLinkToDispatchers_));
5646 artdaqSupervisorRow,
5647 artdaqSupervisorTable.tableView_->
findCol(
5648 colARTDAQSupervisor_.colLinkToDispatchersGroupID_),
5649 artdaqSupervisorUID +
5654 if(artdaqSupervisorTable.tableView_
5655 ->getDataView()[artdaqSupervisorRow]
5656 [artdaqSupervisorTable.tableView_->
findCol(
5657 colARTDAQSupervisor_.colLinkToRoutingManagers_)] ==
5658 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5660 __COUT__ <<
"Fixing missing link to Routers" << __E__;
5662 ARTDAQ_ROUTER_TABLE,
5663 artdaqSupervisorRow,
5664 artdaqSupervisorTable.tableView_->
findCol(
5665 colARTDAQSupervisor_.colLinkToRoutingManagers_));
5667 artdaqSupervisorRow,
5668 artdaqSupervisorTable.tableView_->
findCol(
5669 colARTDAQSupervisor_.colLinkToRoutingManagersGroupID_),
5670 artdaqSupervisorUID +
5675 std::stringstream ss;
5676 artdaqSupervisorTable.tableView_->print(ss);
5677 __COUT_MULTI__(0, ss.str());
5683 ARTDAQ_SUBSYSTEM_TABLE,
true );
5686 artdaqSubsystemTable.tableView_->deleteAllRows();
5688 for(
auto& subsystemPair : subsystemObjectMap)
5690 __COUTV__(subsystemPair.first);
5691 __COUTV__(subsystemPair.second);
5694 row = artdaqSubsystemTable.tableView_->
addRow(
5695 author,
true , subsystemPair.first);
5697 if(subsystemPair.second !=
"" &&
5698 subsystemPair.second != TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
5699 subsystemPair.second != TableViewColumnInfo::DATATYPE_STRING_ALT_DEFAULT &&
5700 subsystemPair.second != NULL_SUBSYSTEM_DESTINATION_LABEL)
5704 ARTDAQ_SUBSYSTEM_TABLE,
5706 artdaqSubsystemTable.tableView_->
findCol(
5707 colARTDAQSubsystem_.colLinkToDestination_));
5709 subsystemPair.second,
5711 artdaqSubsystemTable.tableView_->
findCol(
5712 colARTDAQSubsystem_.colLinkToDestinationUID_));
5719 for(
auto& nodeTypePair : nodeTypeToObjectMap)
5721 __COUTV__(nodeTypePair.first);
5725 auto it =
processTypes_.mapToTable_.find(nodeTypePair.first);
5728 __SS__ <<
"Invalid artdaq node type '" << nodeTypePair.first
5729 <<
"' attempted!" << __E__;
5732 __COUTV__(it->second);
5742 if(nodeTypePair.second.size())
5745 __COUT__ <<
"Ignoring missing table '" << it->second
5746 <<
"' since there were no user records attempted of type '"
5747 << nodeTypePair.first <<
".'" << __E__;
5754 bool hasArtProcessName =
false;
5755 unsigned int artProcessNameCol = -1;
5759 __COUT__ <<
"Identified non-Reader, no-Router type '"
5760 << nodeTypePair.first
5761 <<
"' that has an art link and thus Process Name, so creating "
5762 "table edit structure to ART table."
5765 ARTDAQTableBase::ARTDAQ_ART_TABLE,
true );
5768 std::stringstream ss;
5769 artTable->tableView_->print(ss);
5770 __COUT_MULTI__(1, ss.str());
5772 artProcessNameCol = artTable->tableView_->
findCol(
5773 ARTDAQTableBase::colARTDAQArt_.colProcessName_);
5774 __COUTTV__(artProcessNameCol);
5776 hasArtProcessName =
true;
5778 __COUTV__(hasArtProcessName);
5780 const unsigned int commentCol =
5781 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_COMMENT);
5782 const unsigned int authorCol =
5783 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_AUTHOR);
5784 const unsigned int timestampCol =
5785 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
5788 std::map<
unsigned int ,
bool > deleteRecordMap;
5789 unsigned int maxRowToDelete = typeTable.tableView_->getNumberOfRows();
5790 for(
unsigned int r = 0; r < typeTable.tableView_->getNumberOfRows(); ++r)
5791 deleteRecordMap.emplace(std::make_pair(
5794 __COUTTV__(maxRowToDelete);
5800 const unsigned int ORIG_MAP_ART_PROC_NAME_COL = -1;
5801 std::map<std::string ,
5802 std::map<
unsigned int , std::string >>
5803 originalMultinodeValues;
5804 std::map<std::string ,
5805 std::map<
unsigned int ,
5808 originalMultinodeSameSiblingValues;
5811 std::map<
unsigned int ,
5813 std::vector<std::string >>>>
5814 originalMultinodeAllSiblingEmbeddedName;
5817 std::map<
unsigned int ,
5819 std::vector<std::string >>>>
5820 originalMultinodeAllSiblingEmbeddedPrinterIndex;
5823 for(
auto& nodePair : nodeTypePair.second)
5825 __COUTV__(nodePair.first);
5828 std::vector<std::string> nodeIndices, hostnameIndices;
5829 unsigned int hostnameFixedWidth = 0, nodeNameFixedWidth = 0;
5830 std::string hostname;
5837 for(
unsigned int i = 0; i < nodePair.second.size(); ++i)
5839 __COUTV__(nodePair.second[i]);
5843 std::string nodeName;
5849 if(nodePair.second[i][0] ==
':')
5851 __COUT__ <<
"Handling original multi-node." << __E__;
5856 std::string lastOriginalName;
5857 std::vector<std::string> originalParameterArr =
5859 &(nodePair.second[i].c_str()[1]),
5862 if(originalParameterArr.size() != 3)
5864 __SS__ <<
"Illegal original name parameter string '"
5865 << nodePair.second[i] <<
"!'" << __E__;
5871 unsigned int fixedWidth;
5872 sscanf(originalParameterArr[0].c_str(),
"%u", &fixedWidth);
5873 __COUTV__(fixedWidth);
5875 std::vector<std::string> printerSyntaxArr =
5880 std::vector<std::string> originalNodeIndices;
5881 for(
auto& printerSyntaxValue : printerSyntaxArr)
5883 __COUTV__(printerSyntaxValue);
5885 std::vector<std::string> printerSyntaxRange =
5887 printerSyntaxValue, {
'-'} );
5889 if(printerSyntaxRange.size() == 0 ||
5890 printerSyntaxRange.size() > 2)
5892 __SS__ <<
"Illegal multi-node printer syntax string '"
5893 << printerSyntaxValue <<
"!'" << __E__;
5896 else if(printerSyntaxRange.size() == 1)
5898 __COUTV__(printerSyntaxRange[0]);
5899 originalNodeIndices.push_back(printerSyntaxRange[0]);
5903 unsigned int lo, hi;
5904 sscanf(printerSyntaxRange[0].c_str(),
"%u", &lo);
5905 sscanf(printerSyntaxRange[1].c_str(),
"%u", &hi);
5909 sscanf(printerSyntaxRange[0].c_str(),
"%u", &hi);
5911 for(; lo <= hi; ++lo)
5914 originalNodeIndices.push_back(std::to_string(lo));
5919 __COUTTV__(originalParameterArr[2]);
5921 originalParameterArr[2] = originalParameterArr[2].substr(
5922 0, originalParameterArr[2].find(
";status="));
5923 __COUTV__(originalParameterArr[2]);
5924 std::vector<std::string> originalNamePieces =
5929 if(originalNamePieces.size() < 2)
5931 __SS__ <<
"Illegal original multi-node name template - "
5932 "please use * to indicate where the multi-node "
5933 "index should be inserted!"
5940 std::stringstream ss;
5941 typeTable.tableView_->print(ss);
5942 __COUT_MULTI__(1, ss.str());
5947 <<
"originalMultinodeSameSiblingValues init col map for "
5948 << nodePair.first << __E__;
5949 originalMultinodeSameSiblingValues.emplace(std::make_pair(
5955 __COUT__ <<
"originalMultinodeAllSiblingEmbeddedName init "
5957 << nodePair.first << __E__;
5958 originalMultinodeAllSiblingEmbeddedName.emplace(std::make_pair(
5967 __COUT__ <<
"originalMultinodeAllSiblingEmbeddedPrinterIndex "
5969 << nodePair.first << __E__;
5970 originalMultinodeAllSiblingEmbeddedPrinterIndex.emplace(
5983 unsigned int originalRow = TableView::INVALID,
5984 lastOriginalRow = TableView::INVALID,
5985 lastArtProcessRow = TableView::INVALID;
5986 for(
unsigned int i = 0; i < originalNodeIndices.size(); ++i)
5988 std::string originalName = originalNamePieces[0];
5989 std::string nodeNameIndex;
5990 for(
unsigned int p = 1; p < originalNamePieces.size();
5993 nodeNameIndex = originalNodeIndices[i];
5996 if(nodeNameIndex.size() > fixedWidth)
5998 __SS__ <<
"Illegal original node name index '"
6000 <<
"' - length is longer than fixed "
6001 "width requirement of "
6002 << fixedWidth <<
"!" << __E__;
6007 while(nodeNameIndex.size() < fixedWidth)
6008 nodeNameIndex =
"0" + nodeNameIndex;
6011 originalName += nodeNameIndex + originalNamePieces[p];
6013 __COUTTV__(originalName);
6014 originalRow = typeTable.tableView_->
findRow(
6019 __COUTTV__(originalRow);
6023 auto result = originalMultinodeValues.emplace(
6024 std::make_pair(originalName,
6025 std::map<
unsigned int ,
6029 <<
"originalName '" << originalName
6030 <<
"' already in original multinode value cache."
6034 __COUT__ <<
"Saving multinode value " << originalName
6035 <<
"[" << originalRow
6036 <<
"][*] with row count = "
6037 << typeTable.tableView_->getNumberOfRows()
6041 for(
unsigned int col = 0;
6042 col < typeTable.tableView_->getNumberOfColumns();
6045 if(typeTable.tableView_->getColumnInfo(col)
6048 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK ||
6049 typeTable.tableView_->getColumnInfo(col)
6052 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID ||
6053 typeTable.tableView_->getColumnInfo(col)
6056 ARTDAQ_TYPE_TABLE_HOSTNAME ||
6057 typeTable.tableView_->getColumnInfo(col)
6060 typeTable.tableView_->getColumnInfo(col)
6062 col == timestampCol ||
6069 <<
"Caching node value: " << originalName
6070 <<
"[" << originalRow <<
"][" << col
6072 << typeTable.tableView_
6073 ->getColumnInfo(col)
6076 << typeTable.tableView_
6077 ->getDataView()[originalRow][col]
6079 originalMultinodeValues.at(originalName)
6080 .emplace(std::make_pair(
6082 typeTable.tableView_
6083 ->getDataView()[originalRow]
6088 for(
const auto& pair :
6089 originalMultinodeSameSiblingValues)
6090 __COUTT__ <<
"originalMultinodeSameSiblin"
6092 << pair.first <<
"]" << __E__;
6094 originalMultinodeSameSiblingValues
6096 .emplace(std::make_pair(
6101 typeTable.tableView_
6103 [originalRow][col])));
6105 for(
const auto& pair :
6106 originalMultinodeAllSiblingEmbeddedName)
6107 __COUTT__ <<
"originalMultinodeAllSibling"
6109 << pair.first <<
"]" << __E__;
6110 originalMultinodeAllSiblingEmbeddedName
6112 .emplace(std::make_pair(
6115 typeTable.tableView_
6118 .find(originalName) !=
6121 std::vector<std::string>())));
6123 for(
const auto& pair :
6124 originalMultinodeAllSiblingEmbeddedPrinterIndex)
6125 __COUTT__ <<
"originalMultinodeAllSibling"
6126 "EmbeddedPrinterIndex["
6127 << pair.first <<
"]" << __E__;
6128 originalMultinodeAllSiblingEmbeddedPrinterIndex
6130 .emplace(std::make_pair(
6133 typeTable.tableView_
6136 .find(nodeNameIndex) !=
6139 std::vector<std::string>())));
6145 originalMultinodeSameSiblingValues
6151 originalMultinodeAllSiblingEmbeddedName
6155 if(originalMultinodeAllSiblingEmbeddedName
6161 <<
"Determine string splits for "
6164 const std::string& val =
6165 typeTable.tableView_
6166 ->getDataView()[originalRow]
6168 size_t pos = val.find(originalName);
6169 originalMultinodeAllSiblingEmbeddedName
6173 val.substr(0, pos));
6174 originalMultinodeAllSiblingEmbeddedName
6177 .second.push_back(val.substr(
6178 pos + originalName.size()));
6180 originalMultinodeAllSiblingEmbeddedName
6186 originalMultinodeAllSiblingEmbeddedPrinterIndex
6190 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6195 __COUTT__ <<
"Determine string "
6196 "splits for embedded "
6197 "printer syntax index: "
6198 << nodeNameIndex << __E__;
6199 const std::string& val =
6200 typeTable.tableView_
6201 ->getDataView()[originalRow]
6203 size_t pos = val.find(nodeNameIndex);
6204 originalMultinodeAllSiblingEmbeddedPrinterIndex
6208 val.substr(0, pos));
6209 originalMultinodeAllSiblingEmbeddedPrinterIndex
6212 .second.push_back(val.substr(
6213 pos + nodeNameIndex.size()));
6215 originalMultinodeAllSiblingEmbeddedPrinterIndex
6223 if(originalMultinodeSameSiblingValues
6228 __COUTT__ <<
"Checking sibling same "
6230 << nodePair.first << __E__;
6231 if(typeTable.tableView_
6232 ->getDataView()[originalRow]
6234 typeTable.tableView_->getDataView()
6235 [lastOriginalRow][col])
6238 <<
"Found different sibling "
6241 << nodePair.first << __E__;
6242 originalMultinodeSameSiblingValues
6248 if(originalMultinodeAllSiblingEmbeddedName
6253 __COUTT__ <<
"Checking sibling "
6254 "embedded name... for "
6255 << nodePair.first <<
":"
6256 << originalName << __E__;
6257 if(typeTable.tableView_
6258 ->getDataView()[originalRow]
6260 .find(originalName) ==
6263 __COUT__ <<
"Found no embedded "
6265 << col <<
" looking for "
6266 << originalName << __E__;
6267 originalMultinodeAllSiblingEmbeddedName
6273 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6279 <<
"Checking sibling embedded "
6280 "printer syntax index... for "
6281 << nodePair.first <<
":"
6282 << nodeNameIndex << __E__;
6283 if(typeTable.tableView_
6284 ->getDataView()[originalRow]
6286 .find(nodeNameIndex) ==
6289 __COUT__ <<
"Found no embedded "
6292 << col <<
" looking for "
6295 originalMultinodeAllSiblingEmbeddedPrinterIndex
6304 <<
"originalMultinodeSameSiblingValues["
6305 << nodePair.first <<
"][" << col <<
"] = "
6306 << originalMultinodeSameSiblingValues
6312 <<
"originalMultinodeAllSiblingEmbeddedNa"
6314 << nodePair.first <<
"][" << col <<
"] = "
6315 << originalMultinodeAllSiblingEmbeddedName
6321 <<
"originalMultinodeAllSiblingEmbeddedPr"
6323 << nodePair.first <<
"][" << col <<
"] = "
6324 << originalMultinodeAllSiblingEmbeddedPrinterIndex
6330 if(hasArtProcessName && artTable &&
6331 typeTable.tableView_->getColumnInfo(col)
6333 ARTDAQTableBase::colARTDAQNotReader_
6338 <<
"Checking ART Process Name... for "
6340 << originalName <<
"' / "
6341 << typeTable.tableView_
6342 ->getDataView()[originalRow]
6345 unsigned int artRow =
6346 artTable->tableView_->
findRow(
6349 typeTable.tableView_
6350 ->getDataView()[originalRow]
6355 <<
"Found ART Process Name = "
6356 << artTable->tableView_->getDataView()
6357 [artRow][artProcessNameCol]
6361 originalMultinodeValues.at(originalName)
6362 .emplace(std::make_pair(
6363 ORIG_MAP_ART_PROC_NAME_COL,
6364 artTable->tableView_
6367 [artProcessNameCol]));
6369 originalMultinodeValues
6371 .at(ORIG_MAP_ART_PROC_NAME_COL));
6374 originalMultinodeSameSiblingValues
6376 .emplace(std::make_pair(
6377 ORIG_MAP_ART_PROC_NAME_COL,
6381 artTable->tableView_
6384 [artProcessNameCol])));
6385 originalMultinodeAllSiblingEmbeddedName
6387 .emplace(std::make_pair(
6388 ORIG_MAP_ART_PROC_NAME_COL,
6390 artTable->tableView_
6394 .find(originalName) !=
6397 std::vector<std::string>())));
6398 originalMultinodeAllSiblingEmbeddedPrinterIndex
6400 .emplace(std::make_pair(
6401 ORIG_MAP_ART_PROC_NAME_COL,
6403 artTable->tableView_
6411 std::vector<std::string>())));
6417 originalMultinodeSameSiblingValues
6419 .at(ORIG_MAP_ART_PROC_NAME_COL)
6423 originalMultinodeAllSiblingEmbeddedName
6425 .at(ORIG_MAP_ART_PROC_NAME_COL)
6427 if(originalMultinodeAllSiblingEmbeddedName
6429 .at(ORIG_MAP_ART_PROC_NAME_COL)
6433 <<
"Determine string splits "
6436 const std::string& val =
6437 artTable->tableView_
6440 [artProcessNameCol];
6442 val.find(originalName);
6443 originalMultinodeAllSiblingEmbeddedName
6445 .at(ORIG_MAP_ART_PROC_NAME_COL)
6447 val.substr(0, pos));
6448 originalMultinodeAllSiblingEmbeddedName
6450 .at(ORIG_MAP_ART_PROC_NAME_COL)
6451 .second.push_back(val.substr(
6453 originalName.size()));
6455 originalMultinodeAllSiblingEmbeddedName
6457 .at(ORIG_MAP_ART_PROC_NAME_COL)
6461 originalMultinodeAllSiblingEmbeddedPrinterIndex
6463 .at(ORIG_MAP_ART_PROC_NAME_COL)
6465 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6467 .at(ORIG_MAP_ART_PROC_NAME_COL)
6471 <<
"Determine string splits "
6472 "for embedded printer "
6474 << nodeNameIndex << __E__;
6475 const std::string& val =
6476 artTable->tableView_
6479 [artProcessNameCol];
6481 val.find(nodeNameIndex);
6482 originalMultinodeAllSiblingEmbeddedPrinterIndex
6484 .at(ORIG_MAP_ART_PROC_NAME_COL)
6486 val.substr(0, pos));
6487 originalMultinodeAllSiblingEmbeddedPrinterIndex
6489 .at(ORIG_MAP_ART_PROC_NAME_COL)
6490 .second.push_back(val.substr(
6492 nodeNameIndex.size()));
6494 originalMultinodeAllSiblingEmbeddedPrinterIndex
6496 .at(ORIG_MAP_ART_PROC_NAME_COL)
6502 if(originalMultinodeSameSiblingValues
6504 .at(ORIG_MAP_ART_PROC_NAME_COL)
6507 __COUTT__ <<
"Checking sibling "
6508 "same values... for "
6511 if(artTable->tableView_
6514 [artProcessNameCol] !=
6515 artTable->tableView_
6518 [artProcessNameCol])
6521 <<
"Found different "
6523 "at artProcessNameCol="
6524 << artProcessNameCol
6528 originalMultinodeSameSiblingValues
6530 .at(ORIG_MAP_ART_PROC_NAME_COL)
6534 if(originalMultinodeAllSiblingEmbeddedName
6536 .at(ORIG_MAP_ART_PROC_NAME_COL)
6540 <<
"Checking sibling "
6541 "embedded name... for "
6542 << nodePair.first <<
":"
6543 << originalName << __E__;
6544 if(artTable->tableView_
6548 .find(originalName) ==
6552 <<
"Found no embedded "
6554 "artProcessNameCol="
6555 << artProcessNameCol
6557 << originalName << __E__;
6558 originalMultinodeAllSiblingEmbeddedName
6560 .at(ORIG_MAP_ART_PROC_NAME_COL)
6564 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6566 .at(ORIG_MAP_ART_PROC_NAME_COL)
6570 <<
"Checking sibling "
6571 "embedded printer syntax "
6573 << nodePair.first <<
":"
6574 << nodeNameIndex << __E__;
6575 if(artTable->tableView_
6579 .find(nodeNameIndex) ==
6583 <<
"Found no embedded "
6584 "printer syntax index "
6585 "at artProcessNameCol="
6586 << artProcessNameCol
6588 << nodeNameIndex << __E__;
6589 originalMultinodeAllSiblingEmbeddedPrinterIndex
6591 .at(ORIG_MAP_ART_PROC_NAME_COL)
6598 <<
"originalMultinodeSameSiblingValue"
6600 << nodePair.first <<
"]["
6601 << ORIG_MAP_ART_PROC_NAME_COL
6603 << originalMultinodeSameSiblingValues
6605 .at(ORIG_MAP_ART_PROC_NAME_COL)
6609 <<
"originalMultinodeAllSiblingEmbedd"
6611 << nodePair.first <<
"]["
6612 << ORIG_MAP_ART_PROC_NAME_COL
6614 << originalMultinodeAllSiblingEmbeddedName
6616 .at(ORIG_MAP_ART_PROC_NAME_COL)
6620 <<
"originalMultinodeAllSiblingEmbedd"
6622 << nodePair.first <<
"]["
6623 << ORIG_MAP_ART_PROC_NAME_COL
6625 << originalMultinodeAllSiblingEmbeddedPrinterIndex
6627 .at(ORIG_MAP_ART_PROC_NAME_COL)
6632 <<
"Checking ART Process Name "
6633 "complete for originalName='"
6634 << originalName <<
"' / "
6635 << typeTable.tableView_
6636 ->getDataView()[originalRow]
6650 lastOriginalRow = originalRow;
6652 __COUTTV__(lastOriginalRow);
6653 lastOriginalName = originalName;
6656 for(
const auto& pair :
6657 originalMultinodeSameSiblingValues.at(nodePair.first))
6658 __COUTT__ <<
"originalMultinodeSameSiblingValues["
6659 << nodePair.first <<
"][" << pair.first
6660 <<
"] = " << pair.second.first << __E__;
6661 for(
const auto& pair :
6662 originalMultinodeAllSiblingEmbeddedName.at(
6664 __COUTT__ <<
"originalMultinodeAllSiblingEmbeddedName["
6665 << nodePair.first <<
"][" << pair.first
6666 <<
"] = " << pair.second.first << __E__;
6667 for(
const auto& pair :
6668 originalMultinodeAllSiblingEmbeddedPrinterIndex.at(
6671 <<
"originalMultinodeAllSiblingEmbeddedPrinterIndex["
6672 << nodePair.first <<
"][" << pair.first
6673 <<
"] = " << pair.second.first << __E__;
6675 __COUTTV__(lastOriginalRow);
6676 row = lastOriginalRow;
6681 std::string originalName = nodePair.second[i].substr(
6682 0, nodePair.second[i].find(
";status="));
6683 __COUTV__(originalName);
6686 row = typeTable.tableView_->
findRow(
6696 nodeName = nodePair.first;
6697 __COUTV__(nodeName);
6699 nodeName = nodeName.substr(0, nodeName.find(
";status="));
6702 std::string tmpNodeName = nodeName;
6704 for(
size_t c = 0; c < tmpNodeName.size(); ++c)
6705 if(tmpNodeName[c] !=
'*')
6706 nodeName += tmpNodeName[c];
6709 __COUTV__(nodeName);
6710 if(row == TableView::INVALID)
6713 row = typeTable.tableView_->
addRow(
6714 author,
true , nodeName);
6719 __COUT__ <<
"Handling new " << nodeTypePair.first
6720 <<
" defaults!" << __E__;
6723 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6728 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6730 typeTable.tableView_->
findCol(
6731 ARTDAQTableBase::colARTDAQReader_
6732 .colLinkToDaqParameters_));
6733 std::string daqParameterGroupID =
6736 typeTable.tableView_->
findCol(
6737 ARTDAQTableBase::colARTDAQReader_
6738 .colLinkToDaqParametersGroupID_),
6739 nodeName +
"DaqParameters");
6742 std::stringstream ss;
6743 typeTable.tableView_->print(ss);
6744 __COUT_MULTI__(1, ss.str());
6748 const std::vector<std::string> parameterUIDs = {
6749 "BoardID",
"FragmentID"};
6751 const std::vector<std::string> parameterNames = {
6755 const std::vector<std::string> parameterValues = {
6760 unsigned int parameterRow;
6761 for(
unsigned int i = 0; i < parameterNames.size(); ++i)
6764 parameterRow = daqParameterTable.tableView_->
addRow(
6767 nodeName + parameterUIDs[i]);
6778 daqParameterTable.tableView_->
findCol(
6779 ARTDAQTableBase::colARTDAQDaqParameter_
6780 .colDaqParameterKey_));
6785 daqParameterTable.tableView_->
findCol(
6786 ARTDAQTableBase::colARTDAQDaqParameter_
6787 .colDaqParameterValue_));
6790 daqParameterGroupID,
6792 daqParameterTable.tableView_->
findCol(
6793 ARTDAQTableBase::colARTDAQDaqParameter_
6794 .colDaqParameterGroupID_));
6798 daqParameterTable.tableView_
6806 __COUT__ <<
"Handling new " << nodeTypePair.first
6807 <<
" defaults!" << __E__;
6812 ARTDAQTableBase::ARTDAQ_DAQ_TABLE,
6815 unsigned int daqRecordRow = daqTable.tableView_->
addRow(
6819 std::string daqRecordUID =
6821 ->getDataView()[daqRecordRow]
6826 ARTDAQTableBase::ARTDAQ_DAQ_TABLE,
6828 typeTable.tableView_->
findCol(
6829 ARTDAQTableBase::colARTDAQNotReader_
6834 typeTable.tableView_->
findCol(
6835 ARTDAQTableBase::colARTDAQNotReader_
6836 .colLinkToDaqUID_));
6840 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6844 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6847 ARTDAQTableBase::colARTDAQDaq_
6848 .colLinkToDaqParameters_));
6849 std::string daqParameterGroupID =
6853 ARTDAQTableBase::colARTDAQDaq_
6854 .colLinkToDaqParametersGroupID_),
6855 nodeName +
"DaqParameters");
6858 const std::vector<std::string> parameterUIDs = {
6859 "BufferCount",
"FragmentsPerEvent"};
6861 const std::vector<std::string> parameterNames = {
6863 "expected_fragments_per_event"
6865 const std::vector<std::string> parameterValues = {
6870 unsigned int parameterRow;
6871 for(
unsigned int i = 0; i < parameterNames.size(); ++i)
6874 parameterRow = daqParameterTable.tableView_->
addRow(
6877 nodeName + parameterUIDs[i]);
6888 daqParameterTable.tableView_->
findCol(
6889 ARTDAQTableBase::colARTDAQDaqParameter_
6890 .colDaqParameterKey_));
6895 daqParameterTable.tableView_->
findCol(
6896 ARTDAQTableBase::colARTDAQDaqParameter_
6897 .colDaqParameterValue_));
6900 daqParameterGroupID,
6902 daqParameterTable.tableView_->
findCol(
6903 ARTDAQTableBase::colARTDAQDaqParameter_
6904 .colDaqParameterGroupID_));
6910 daqParameterTable.tableView_
6918 <<
"Reusing row " << row <<
" current-UID="
6919 << typeTable.tableView_
6920 ->getDataView()[row]
6922 <<
" as (temporarily to basename if multinode) new-UID="
6923 << nodeName << __E__;
6924 typeTable.tableView_
6933 if(row < maxRowToDelete)
6934 deleteRecordMap[row] =
false;
6941 artdaqSupervisorTable.tableView_
6942 ->getDataView()[artdaqSupervisorRow]
6943 [artdaqSupervisorTable.tableView_->
findCol(
6945 .at(nodeTypePair.first))],
6947 typeTable.tableView_->
findCol(
6949 nodeTypePair.first)));
6962 hostname = nodePair.second[i];
6966 typeTable.tableView_->
findCol(ARTDAQ_TYPE_TABLE_HOSTNAME));
6971 if(nodePair.second[i] !=
"" &&
6972 nodePair.second[i] !=
6973 TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
6974 nodePair.second[i] !=
6975 TableViewColumnInfo::DATATYPE_STRING_ALT_DEFAULT)
6978 if(subsystemObjectMap.find(nodePair.second[i]) ==
6979 subsystemObjectMap.end())
6981 __SS__ <<
"Illegal subsystem '" << nodePair.second[i]
6982 <<
"' mismatch!" << __E__;
6987 ARTDAQ_SUBSYSTEM_TABLE,
6989 typeTable.tableView_->
findCol(
6990 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK));
6994 typeTable.tableView_->
findCol(
6995 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID));
7000 TableViewColumnInfo::DATATYPE_LINK_DEFAULT,
7002 typeTable.tableView_->
findCol(
7003 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK));
7007 i == 4 || i == 5 || i == 6 ||
7014 __COUT__ <<
"Handling printer syntax i=" << i << __E__;
7016 std::vector<std::string> printerSyntaxArr =
7020 if(printerSyntaxArr.size() == 2)
7022 if(printerSyntaxArr[0] ==
7025 sscanf(printerSyntaxArr[1].c_str(),
7027 &nodeNameFixedWidth);
7028 __COUTV__(nodeNameFixedWidth);
7031 else if(printerSyntaxArr[0] ==
7034 sscanf(printerSyntaxArr[1].c_str(),
7036 &hostnameFixedWidth);
7037 __COUTV__(hostnameFixedWidth);
7043 for(
auto& printerSyntaxValue : printerSyntaxArr)
7045 __COUTV__(printerSyntaxValue);
7047 std::vector<std::string> printerSyntaxRange =
7050 if(printerSyntaxRange.size() == 0 ||
7051 printerSyntaxRange.size() > 2)
7053 __SS__ <<
"Illegal multi-node printer syntax string '"
7054 << printerSyntaxValue <<
"!'" << __E__;
7057 else if(printerSyntaxRange.size() == 1)
7060 __COUTV__(printerSyntaxRange[0]);
7065 nodeIndices.push_back(printerSyntaxRange[0]);
7067 hostnameIndices.push_back(printerSyntaxRange[0]);
7071 unsigned int lo, hi;
7072 sscanf(printerSyntaxRange[0].c_str(),
"%u", &lo);
7073 sscanf(printerSyntaxRange[1].c_str(),
"%u", &hi);
7077 sscanf(printerSyntaxRange[0].c_str(),
"%u", &hi);
7079 for(; lo <= hi; ++lo)
7083 nodeIndices.push_back(std::to_string(lo));
7085 hostnameIndices.push_back(std::to_string(lo));
7092 __SS__ <<
"Unexpected parameter[" << i <<
" '"
7093 << nodePair.second[i] <<
"' for node " << nodePair.first
7099 __COUTV__(nodeIndices.size());
7100 __COUTV__(hostnameIndices.size());
7102 if(hostnameIndices.size())
7104 if(hostnameIndices.size() != nodeIndices.size())
7106 __SS__ <<
"Illegal associated hostname array has count "
7107 << hostnameIndices.size()
7108 <<
" which is not equal to the node count "
7109 << nodeIndices.size() <<
"!" << __E__;
7114 if(nodeIndices.size())
7116 unsigned int hostnameCol =
7117 typeTable.tableView_->
findCol(ARTDAQ_TYPE_TABLE_HOSTNAME);
7122 std::vector<std::string> namePieces =
7124 nodePair.first.substr(0, nodePair.first.find(
";status=")),
7128 if(namePieces.size() < 2)
7131 <<
"Illegal multi-node name template - please use * to "
7132 "indicate where the multi-node index should be inserted!"
7137 std::vector<std::string> hostnamePieces;
7138 if(hostnameIndices.size())
7144 if(hostnamePieces.size() < 2)
7147 <<
"Illegal hostname array template - please use * to "
7148 "indicate where the hostname index should be inserted!"
7154 bool isFirst =
true;
7155 unsigned int lastArtRow = TableView::INVALID;
7156 for(
unsigned int i = 0; i < nodeIndices.size(); ++i)
7158 std::string name = namePieces[0];
7159 std::string nodeNameIndex;
7160 for(
unsigned int p = 1; p < namePieces.size(); ++p)
7162 nodeNameIndex = nodeIndices[i];
7163 if(nodeNameFixedWidth > 1)
7165 if(nodeNameIndex.size() > nodeNameFixedWidth)
7168 if(nodeNameIndex.find(
"_clone") == std::string::npos)
7170 __SS__ <<
"Illegal node name index '"
7172 <<
"' - length is longer than fixed width "
7174 << nodeNameFixedWidth <<
"!" << __E__;
7180 while(nodeNameIndex.size() < nodeNameFixedWidth)
7181 nodeNameIndex =
"0" + nodeNameIndex;
7184 name += nodeNameIndex + namePieces[p];
7188 if(hostnamePieces.size())
7190 hostname = hostnamePieces[0];
7191 std::string hostnameIndex;
7192 for(
unsigned int p = 1; p < hostnamePieces.size(); ++p)
7194 hostnameIndex = hostnameIndices[i];
7195 if(hostnameFixedWidth > 1)
7197 if(hostnameIndex.size() > hostnameFixedWidth)
7200 if(hostnameIndex.find(
"_clone") ==
7203 __SS__ <<
"Illegal hostname index '"
7205 <<
"' - length is longer than fixed "
7208 << hostnameFixedWidth <<
"!" << __E__;
7214 while(hostnameIndex.size() < hostnameFixedWidth)
7215 hostnameIndex =
"0" + hostnameIndex;
7218 hostname += hostnameIndex + hostnamePieces[p];
7220 __COUTV__(hostname);
7227 << author <<
"... Replacing row UID '"
7228 << typeTable.tableView_
7229 ->getDataView()[row]
7231 <<
"' with UID '" << name <<
"'" << __E__;
7234 if(row < maxRowToDelete)
7235 deleteRecordMap[row] =
false;
7240 << author <<
"... Copying row UID '"
7241 << typeTable.tableView_
7242 ->getDataView()[row]
7244 <<
"' to UID '" << name <<
"'" << __E__;
7245 unsigned int copyRow = typeTable.tableView_->
copyRows(
7247 *(typeTable.tableView_),
7254 if(row < maxRowToDelete)
7255 deleteRecordMap[copyRow] =
false;
7260 name, row, typeTable.tableView_->
getColUID());
7262 hostname, row, hostnameCol);
7265 TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT,
7269 typeTable.tableView_->
setValue(time(0), row, timestampCol);
7271 __COUTTV__(typeTable
7273 ->getDataView()[row][commentCol]);
7274 __COUTTV__(typeTable
7276 ->getDataView()[row][authorCol]);
7277 __COUTTV__(typeTable
7279 ->getDataView()[row][timestampCol]);
7289 <<
"Looking for best original node match for row=" << row
7290 <<
" UID='" << name <<
"'" << __E__;
7291 size_t bestScore = 0;
7292 std::string bestOriginalNodeName;
7293 for(
const auto& originalNodePair : originalMultinodeValues)
7295 if(originalNodePair.second.find(
7296 ORIG_MAP_ART_PROC_NAME_COL) !=
7297 originalNodePair.second.end())
7298 __COUTTV__(originalNodePair.second.at(
7299 ORIG_MAP_ART_PROC_NAME_COL));
7301 for(
size_t c = 0, d = 0;
7302 c < originalNodePair.first.size() && d < name.size();
7305 if(name[d] == originalNodePair.first[c])
7307 else if(d + 1 < name.size() &&
7308 name[d + 1] == originalNodePair.first[c])
7310 else if(c + 1 < originalNodePair.first.size() &&
7311 name[d] == originalNodePair.first[c + 1])
7314 if(originalNodePair.first.size() == name.size())
7316 __COUTVS__(2, score);
7317 if(score > bestScore)
7319 bestOriginalNodeName = originalNodePair.first;
7321 __COUTVS__(2, bestOriginalNodeName);
7322 __COUTVS__(2, bestScore);
7326 bool exactMatch = (bestOriginalNodeName == name);
7327 bool needToHandleArtProcessName =
false;
7328 std::string artProcessName;
7331 originalMultinodeValues.find(bestOriginalNodeName) !=
7332 originalMultinodeValues.end())
7334 __COUT__ <<
"Populating original multinode value from '"
7335 << bestOriginalNodeName <<
"' into '" << name
7338 for(
const auto& valuePair :
7339 originalMultinodeValues.at(bestOriginalNodeName))
7342 if(!exactMatch && (valuePair.first == commentCol ||
7343 valuePair.first == authorCol ||
7344 valuePair.first == timestampCol))
7347 <<
"Not exact node name match, so keeping "
7348 "default meta info for node: "
7349 << name <<
"[" << row <<
"]["
7351 <<
"] /= " << valuePair.second <<
" keep= "
7352 << typeTable.tableView_
7353 ->getDataView()[row][valuePair.first]
7358 __COUTT__ <<
"Customizing node: " << name <<
"["
7359 << row <<
"][" << valuePair.first
7360 <<
"] = " << valuePair.second << __E__;
7362 if(valuePair.first == ORIG_MAP_ART_PROC_NAME_COL)
7364 __COUTT__ <<
"NEED Special art Process Name "
7366 << valuePair.second << __E__;
7367 needToHandleArtProcessName =
true;
7368 artProcessName = valuePair.second;
7371 valuePair.second, row, artProcessNameCol);
7375 valuePair.second, row, valuePair.first);
7379 __COUT__ <<
"Did not find '" << name
7380 <<
"' in original value cache. Looking for "
7381 "bestOriginalNodeName="
7382 << bestOriginalNodeName << __E__;
7384 __COUTV__(exactMatch);
7387 if(originalMultinodeSameSiblingValues.find(
7389 originalMultinodeSameSiblingValues.end())
7391 __COUT__ <<
"Applying multinode sibling same value "
7393 << row <<
" UID='" << name <<
"'" << __E__;
7394 for(
const auto& sameValuePair :
7395 originalMultinodeSameSiblingValues.at(
7398 if(!sameValuePair.second.first)
7401 <<
"Found originalMultinodeSameSiblingValues["
7402 << nodePair.first <<
"]["
7403 << sameValuePair.first <<
"] = "
7404 << sameValuePair.second.first <<
" --> "
7405 << sameValuePair.second.second << __E__;
7408 if(sameValuePair.first ==
7409 ORIG_MAP_ART_PROC_NAME_COL)
7411 __COUTT__ <<
"NEED Special art Process Name "
7413 << sameValuePair.second.second
7415 needToHandleArtProcessName =
true;
7416 artProcessName = sameValuePair.second.second;
7419 sameValuePair.second.second,
7425 sameValuePair.second.second,
7427 sameValuePair.first);
7432 if(originalMultinodeAllSiblingEmbeddedPrinterIndex.find(
7434 originalMultinodeAllSiblingEmbeddedPrinterIndex.end())
7436 __COUT__ <<
"Applying multinode sibling embbeded "
7437 "printer syntax index rules for row="
7438 << row <<
" UID='" << name
7439 <<
"' and printer index='" << nodeNameIndex
7441 for(
const auto& embedValuePair :
7442 originalMultinodeAllSiblingEmbeddedPrinterIndex
7443 .at(nodePair.first))
7445 if(!embedValuePair.second.first ||
7446 embedValuePair.second.second.size() < 2)
7450 "originalMultinodeAllSiblingEmbeddedPrinte"
7452 << nodePair.first <<
"]["
7453 << embedValuePair.first <<
"] = "
7454 << embedValuePair.second.first <<
" --> "
7456 embedValuePair.second.second)
7458 std::string embedValue =
7460 embedValuePair.second.second,
7462 __COUTTV__(embedValue);
7465 if(embedValuePair.first ==
7466 ORIG_MAP_ART_PROC_NAME_COL)
7468 __COUTT__ <<
"NEED Special art Process Name "
7470 << embedValue << __E__;
7471 needToHandleArtProcessName =
true;
7472 artProcessName = embedValue;
7475 embedValue, row, artProcessNameCol);
7479 embedValue, row, embedValuePair.first);
7483 if(originalMultinodeAllSiblingEmbeddedName.find(
7485 originalMultinodeAllSiblingEmbeddedName.end())
7487 __COUT__ <<
"Applying multinode sibling embbeded "
7488 "name rules for row="
7489 << row <<
" UID='" << name <<
"'" << __E__;
7490 for(
const auto& embedValuePair :
7491 originalMultinodeAllSiblingEmbeddedName.at(
7494 if(!embedValuePair.second.first ||
7495 embedValuePair.second.second.size() < 2)
7499 "originalMultinodeAllSiblingEmbeddedName["
7500 << nodePair.first <<
"]["
7501 << embedValuePair.first <<
"] = "
7502 << embedValuePair.second.first <<
" --> "
7504 embedValuePair.second.second)
7506 std::string embedValue =
7508 embedValuePair.second.second, name);
7509 __COUTTV__(embedValue);
7512 if(embedValuePair.first ==
7513 ORIG_MAP_ART_PROC_NAME_COL)
7515 __COUTT__ <<
"NEED Special art Process Name "
7517 << embedValue << __E__;
7518 needToHandleArtProcessName =
true;
7519 artProcessName = embedValue;
7522 embedValue, row, artProcessNameCol);
7526 embedValue, row, embedValuePair.first);
7530 __COUTV__(needToHandleArtProcessName);
7531 if(needToHandleArtProcessName)
7533 __COUTT__ <<
"Special art Process Name column value: "
7534 << artProcessName << __E__;
7536 std::string artRecord =
7537 typeTable.tableView_->getDataView()
7538 [row][typeTable.tableView_->
findCol(
7539 ARTDAQTableBase::colARTDAQNotReader_
7540 .colLinkToArtUID_)];
7541 __COUTTV__(artRecord);
7543 const unsigned int artCommentCol =
7545 TableViewColumnInfo::TYPE_COMMENT);
7546 const unsigned int artAuthorCol =
7548 TableViewColumnInfo::TYPE_AUTHOR);
7549 const unsigned int artTimestampCol =
7551 TableViewColumnInfo::TYPE_TIMESTAMP);
7553 unsigned int artRow = artTable->tableView_->
findRow(
7559 if(artRow == TableView::INVALID)
7561 __COUTT__ <<
"Need to make art Process record... "
7563 << artRecord << __E__;
7567 __COUTTV__(bestOriginalNodeName);
7568 const unsigned int bestMatchRow =
7569 typeTable.tableView_->
findRow(
7571 bestOriginalNodeName);
7572 __COUTTV__(bestMatchRow);
7574 std::string bestMatchArtRecord =
7575 typeTable.tableView_->getDataView()
7577 [typeTable.tableView_->
findCol(
7580 .colLinkToArtUID_)];
7581 __COUTTV__(bestMatchArtRecord);
7583 unsigned int bestMatchArtRow =
7584 artTable->tableView_->
findRow(
7589 __COUTTV__(bestMatchArtRow);
7590 if(bestMatchArtRow !=
7595 __COUTTV__(lastArtRow);
7598 if(lastArtRow != TableView::INVALID)
7600 __COUTT__ <<
"Copying art Process record... "
7602 << lastArtRow << __E__;
7603 unsigned int copyRow =
7606 *(artTable->tableView_),
7620 DATATYPE_COMMENT_DEFAULT,
7624 author, artRow, artAuthorCol);
7626 time(0), artRow, artTimestampCol);
7630 __COUTT__ <<
"Creating art Process record... "
7632 << artRecord << __E__;
7634 artRow = artTable->tableView_->
addRow(
7640 <<
"Made art Process record... artRecord="
7641 << artRecord << __E__;
7644 __COUTT__ <<
"Modify art Process record based on "
7645 "sibling rules... artRecord="
7647 <<
" artProcessName=" << artProcessName
7651 artProcessName, artRow, artProcessNameCol);
7652 lastArtRow = artRow;
7656 needToHandleArtProcessName)
7658 std::string artRecord =
7659 typeTable.tableView_->getDataView()
7660 [row][typeTable.tableView_->
findCol(
7661 ARTDAQTableBase::colARTDAQNotReader_
7662 .colLinkToArtUID_)];
7663 __COUTTV__(artRecord);
7664 unsigned int artRow = artTable->tableView_->
findRow(
7672 lastArtRow = artRow;
7675 __COUTTV__(lastArtRow);
7680 if(row < maxRowToDelete)
7681 __COUTTV__(deleteRecordMap[row]);
7683 __COUTTV__(typeTable
7685 ->getDataView()[row][commentCol]);
7686 __COUTTV__(typeTable
7688 ->getDataView()[row][authorCol]);
7689 __COUTTV__(typeTable
7691 ->getDataView()[row][timestampCol]);
7701 __COUT__ <<
"Deleting '" << nodeTypePair.first
7702 <<
"' records not specified..." << __E__;
7705 std::set<unsigned int> orderedRowSet;
7706 for(
auto& deletePair : deleteRecordMap)
7708 if(!deletePair.second)
7710 __COUTT__ <<
"Row keep = " << deletePair.first << __E__;
7714 __COUTT__ <<
"Row delete = " << deletePair.first << __E__;
7715 orderedRowSet.emplace(deletePair.first);
7719 for(std::set<unsigned int>::reverse_iterator rit = orderedRowSet.rbegin();
7720 rit != orderedRowSet.rend();
7726 if(TTEST(1) && artTable)
7728 std::stringstream ss;
7729 artTable->tableView_->print(ss);
7730 __COUT_MULTI__(1, ss.str());
7733 if(hasArtProcessName && artTable)
7734 artTable->tableView_
7739 std::stringstream ss;
7740 typeTable.tableView_->print(ss);
7741 __COUT_MULTI__(1, ss.str());
7744 typeTable.tableView_->
init();
7751 std::stringstream ss;
7752 artdaqSupervisorTable.tableView_->print(ss);
7753 __COUT_MULTI__(1, ss.str());
7756 std::stringstream ss;
7757 artdaqSubsystemTable.tableView_->print(ss);
7758 __COUT_MULTI__(1, ss.str());
7762 artdaqSupervisorTable.tableView_
7764 artdaqSubsystemTable.tableView_
7769 __COUT__ <<
"Table errors while creating ARTDAQ nodes. Erasing all newly "
7770 "created table versions."
7775 __COUT__ <<
"Edits complete for artdaq nodes and subsystems.. now save and activate "
7776 "groups, and update aliases!"
7782 __SS__ <<
"DEBUG blocking save!" << __E__;
7786 std::string localAccumulatedWarnings;
7787 configGroupEdit.saveChanges(configGroupEdit.originalGroupName_,
7788 newConfigurationGroupKey,
7795 &localAccumulatedWarnings);
7811 void ARTDAQTableBase::addCommentWhitespace(std::ostream& os,
size_t lineLength)
7813 for(
size_t i = 0;
true; i += 20)
7815 if(lineLength < FCL_COMMENT_POSITION + i)
7817 os << std::string(FCL_COMMENT_POSITION + i - lineLength,
' ');
7825 std::string ARTDAQTableBase::getStructureAsJSON(
7828 if(fclMap_.size() == 0)
7830 std::stringstream oss;
7832 oss <<
"{" << __E__;
7834 if(fclMap_.size() > 1)
7837 bool firstType =
true;
7838 for(
const auto& typePairMap : fclMap_)
7842 oss <<
"\t\"" << getTypeString(typePairMap.first) <<
"\": {" << __E__;
7844 bool firstEntry =
true;
7845 for(
const auto& fclPair : typePairMap.second)
7849 oss <<
"\t\t\"" << fclPair.first <<
"\": \""
7855 oss <<
"\t}" << __E__;
7862 bool firstEntry =
true;
7863 for(
const auto& typePairMap : fclMap_)
7865 for(
const auto& fclPair : typePairMap.second)
7869 oss <<
"\t\"" << fclPair.first <<
"\": \""
7877 oss <<
"}" << __E__;
7886 size_t maxFragmentSizeBytes,
7887 size_t routingTimeoutMs,
7888 size_t routingRetryCount,
7893 __SS__ <<
"ARTDAQ Supervisor node is disconnected while generating boot.txt "
7894 <<
"content." << __E__;
7898 const ARTDAQInfo& info = extractARTDAQInfo(artdaqSupervisorNode,
7901 maxFragmentSizeBytes,
7907 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colDAQInterfaceDebugLevel_)
7909 std::string setupScript =
7910 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colDAQSetupScript_).
getValue();
7919 const std::string& setupScript,
7922 std::stringstream o;
7924 o <<
"DAQ setup script: " << setupScript << std::endl;
7925 o <<
"debug level: " << debugLevel << std::endl;
7928 if(info.subsystems.size() > 1)
7930 for(
auto& ss : info.subsystems)
7934 o <<
"Subsystem id: " << ss.first << std::endl;
7935 if(ss.second.destination != 0)
7937 o <<
"Subsystem destination: " << ss.second.destination << std::endl;
7939 for(
auto& sss : ss.second.sources)
7941 o <<
"Subsystem source: " << sss << std::endl;
7943 if(ss.second.eventMode)
7945 o <<
"Subsystem fragmentMode: False" << std::endl;
7951 for(
auto& builder : info.processes.at(ARTDAQAppType::EventBuilder))
7953 o <<
"EventBuilder host: " << builder.hostname << std::endl;
7954 o <<
"EventBuilder label: " << builder.label << std::endl;
7955 if(builder.subsystem != 1)
7957 o <<
"EventBuilder subsystem: " << builder.subsystem << std::endl;
7959 if(builder.allowed_processors !=
"")
7961 o <<
"EventBuilder allowed_processors: " << builder.allowed_processors
7967 for(
auto& logger : info.processes.at(ARTDAQAppType::DataLogger))
7969 o <<
"DataLogger host: " << logger.hostname << std::endl;
7970 o <<
"DataLogger label: " << logger.label << std::endl;
7971 if(logger.subsystem != 1)
7973 o <<
"DataLogger subsystem: " << logger.subsystem << std::endl;
7975 if(logger.allowed_processors !=
"")
7977 o <<
"DataLogger allowed_processors: " << logger.allowed_processors
7983 for(
auto& dispatcher : info.processes.at(ARTDAQAppType::Dispatcher))
7985 o <<
"Dispatcher host: " << dispatcher.hostname << std::endl;
7986 o <<
"Dispatcher label: " << dispatcher.label << std::endl;
7987 if(dispatcher.port != 0)
7989 o <<
"Dispatcher port: " << dispatcher.port << std::endl;
7991 if(dispatcher.subsystem != 1)
7993 o <<
"Dispatcher subsystem: " << dispatcher.subsystem << std::endl;
7995 if(dispatcher.allowed_processors !=
"")
7997 o <<
"Dispatcher allowed_processors: " << dispatcher.allowed_processors
8003 for(
auto& rm : info.processes.at(ARTDAQAppType::RoutingManager))
8005 o <<
"RoutingManager host: " << rm.hostname << std::endl;
8006 o <<
"RoutingManager label: " << rm.label << std::endl;
8007 if(rm.subsystem != 1)
8009 o <<
"RoutingManager subsystem: " << rm.subsystem << std::endl;
8011 if(rm.allowed_processors !=
"")
8013 o <<
"RoutingManager allowed_processors: " << rm.allowed_processors
<virtual so future plugins can inherit from multiple table base classes
static void outputDataReceiverFHICL(const ConfigurationTree &receiverNode, ARTDAQAppType appType, size_t maxFragmentSizeBytes=DEFAULT_MAX_FRAGMENT_SIZE, size_t routingTimeoutMs=DEFAULT_ROUTING_TIMEOUT_MS, size_t routingRetryCount=DEFAULT_ROUTING_RETRY_COUNT, std::string *returnFcl=nullptr)
static void insertArtProcessBlock(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree art, ConfigurationTree subsystemLink=ConfigurationTree(), size_t routingTimeoutMs=DEFAULT_ROUTING_TIMEOUT_MS, size_t routingRetryCount=DEFAULT_ROUTING_RETRY_COUNT)
static const std::string ARTDAQ_FCL_PATH
Tree-path rule is, if the last link in the path is a group link with a specified group ID,...
static std::string insertModuleType(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree moduleTypeNode)
static std::string getBootFileContentFromInfo(const ARTDAQInfo &info, const std::string &setupScript, int debugLevel)
static bool isARTDAQEnabled(const ConfigurationManager *cfgMgr)
isARTDAQEnabled
static void insertParameters(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree parameterLink, const std::string ¶meterPreamble, bool onlyInsertAtTableParameters=false, bool includeAtTableParameters=false)
static void setAndActivateARTDAQSystem(ConfigurationManagerRW *cfgMgr, const std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, const std::map< std::string, std::string > &subsystemObjectMap)
static struct ots::ARTDAQTableBase::ProcessTypes processTypes_
Note!!!! processTypes_ must be instantiate after the static artdaq table names (to construct map in c...
static void outputOnlineMonitorFHICL(const ConfigurationTree &onlineMonitorNode)
std::string getBootFileContent(ConfigurationTree artdaqSupervisorNode, size_t maxFragmentSizeBytes=DEFAULT_MAX_FRAGMENT_SIZE, size_t routingTimeoutMs=DEFAULT_ROUTING_TIMEOUT_MS, size_t routingRetryCount=DEFAULT_ROUTING_RETRY_COUNT, ProgressBar *progressBar=0)
static void insertMetricsBlock(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree daqNode)
insertMetricsBlock
static const ARTDAQInfo & getARTDAQSystem(ConfigurationManagerRW *cfgMgr, std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, std::map< std::string, std::string > &subsystemObjectMap, std::vector< std::string > &artdaqSupervisoInfo, bool suppressMultiNode=false)
when true, skip multi-node "printer syntax" wildcard compression and emit one concrete record per nod...
const std::string & getUsername(void) const
Getters.
bool isOwnerFirstAppInContext(void)
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
const TableBase * getTableByName(const std::string &configurationName) const
void initPrereqsForARTDAQ(void)
loadGroupHistory
const unsigned int & getRow(void) const
getRow
bool isDisconnected(void) const
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
navigating between nodes
const std::string & getTableName(void) const
getTableName
T getValueWithDefault(const T &defaultValue) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
const ConfigurationManager * getConfigurationManager(void) const
extracting information from node
void getValue(T &value) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
std::string getParentLinkIndex(void) const
getParentLinkIndex
const std::string & getUIDAsString(void) const
const unsigned int & getNodeRow(void) const
getNodeRow
const std::string & getFieldName(void) const
alias for getValueName
std::string getParentLinkID(void) const
getParentLinkID
const std::string & getParentTableName(void) const
getParentTableName
const std::string & getParentRecordName(void) const
getParentRecordName
const std::string & getParentLinkColumnName(void) const
getParentLinkColumnName
bool isFirstAppInContext_
for managing things that should only happen once per node (e.g., write files). If used,...
std::string str() const
alternative alias method
bool isUID(void) const
isUID
bool isGroupID(void) const
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
< in included .icc source
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
unsigned int getColStatus(void) const
unsigned int findColByType(const std::string &type, unsigned int startingCol=0) const
unsigned int copyRows(const std::string &author, const TableView &src, unsigned int srcOffsetRow=0, unsigned int srcRowsToCopy=(unsigned int) -1, unsigned int destOffsetRow=(unsigned int) -1, unsigned char generateUniqueDataColumns=false, const std::string &baseNameAutoUID="")
const std::string & setUniqueColumnValue(unsigned int row, unsigned int col, std::string baseValueAsString="", bool doMathAppendStrategy=false, std::string childLinkIndex="", std::string groupId="")
unsigned int getColUID(void) const
unsigned int findCol(const std::string &name) const
void setValue(const T &value, unsigned int row, unsigned int col)
< in included .icc source
unsigned int addRow(const std::string &author="", unsigned char incrementUniqueData=false, const std::string &baseNameAutoUID="", unsigned int rowToAdd=(unsigned int) -1, std::string childLinkIndex="", std::string groupId="")
const XDAQContext * getTheARTDAQSupervisorContext(void) const
artdaq specific get methods
defines used also by OtsConfigurationWizardSupervisor
ARTDAQ DAQ Parameter Column names.
ARTDAQ Builder/Logger/Dispatcher Column names.
ARTDAQ Reader Column names.
ARTDAQ Subsystem Column names.
ARTDAQ Supervisor Column names.
TableEditStruct & getTableEditStruct(const std::string &tableName, bool markModified=false)
Note: if markModified, and table not found in group, this function will try to add it to group.
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static const std::string & trim(std::string &s)
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
vectorToString ~
static std::string escapeJSONStringEntities(const std::string &str)
static bool extractCommonChunks(const std::vector< std::string > &haystack, std::vector< std::string > &commonChunksToReturn, std::vector< std::string > &wildcardStrings, unsigned int &fixedWildcardLength)
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static std::string decodeURIComponent(const std::string &data)
static std::string stackTrace(void)