1 #include "otsdaq/TablePlugins/ARTDAQTableBase/ARTDAQTableBase.h"
8 #include "otsdaq/Macros/CoutMacros.h"
9 #define TRACE_NAME "ARTDAQTableBase"
11 #include <fhiclcpp/ParameterSet.h>
12 #include <fhiclcpp/detail/print_mode.h>
13 #include <fhiclcpp/intermediate_table.h>
14 #include <fhiclcpp/parse.h>
16 #include "otsdaq/ProgressBar/ProgressBar.h"
17 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
22 #define __MF_SUBJECT__ "ARTDAQTableBase"
26 #define FCL_COMMENT_POSITION 65
30 #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();}
32 #define OUTC(X,C) OUTCF(X,C,"")
34 #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();}
36 #define OUTCL(X,C) OUTCLF(X,C,"")
38 #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();}
40 #define OUTCL2(X,C) OUTCL2F(X,C,"")
45 const std::string ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH =
46 (((getenv(
"SERVICE_DATA_PATH") == NULL)
47 ? (std::string(getenv(
"USER_DATA")) +
"/ServiceData")
48 : std::string(getenv(
"SERVICE_DATA_PATH")))) +
49 "/ConfigurationGUI_artdaqLayouts/";
50 const bool ARTDAQTableBase::ARTDAQ_DONOTWRITE_FCL = ((getenv(
"OTS_FCL_DONOTWRITE") == NULL) ?
false :
true);
52 const std::string ARTDAQTableBase::ARTDAQ_SUPERVISOR_CLASS =
"ots::ARTDAQSupervisor";
53 const std::string ARTDAQTableBase::ARTDAQ_SUPERVISOR_TABLE =
"ARTDAQSupervisorTable";
55 const std::string ARTDAQTableBase::ARTDAQ_READER_TABLE =
"ARTDAQBoardReaderTable";
56 const std::string ARTDAQTableBase::ARTDAQ_BUILDER_TABLE =
"ARTDAQEventBuilderTable";
57 const std::string ARTDAQTableBase::ARTDAQ_LOGGER_TABLE =
"ARTDAQDataLoggerTable";
58 const std::string ARTDAQTableBase::ARTDAQ_DISPATCHER_TABLE =
"ARTDAQDispatcherTable";
59 const std::string ARTDAQTableBase::ARTDAQ_MONITOR_TABLE =
"ARTDAQMonitorTable";
60 const std::string ARTDAQTableBase::ARTDAQ_ROUTER_TABLE =
"ARTDAQRoutingManagerTable";
62 const std::string ARTDAQTableBase::ARTDAQ_SUBSYSTEM_TABLE =
"ARTDAQSubsystemTable";
63 const std::string ARTDAQTableBase::ARTDAQ_DAQ_TABLE =
"ARTDAQDaqTable";
64 const std::string ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE =
"ARTDAQDaqParameterTable";
65 const std::string ARTDAQTableBase::ARTDAQ_ART_TABLE =
"ARTDAQArtTable";
67 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME =
"ExecutionHostname";
68 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS =
"AllowedProcessors";
69 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK =
"SubsystemLink";
70 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID =
"SubsystemLinkUID";
73 const int ARTDAQTableBase::NULL_SUBSYSTEM_DESTINATION = 0;
74 const std::string ARTDAQTableBase::NULL_SUBSYSTEM_DESTINATION_LABEL =
"nullDestinationSubsystem";
98 std::string* accumulatedExceptions )
99 :
TableBase(tableName, accumulatedExceptions)
111 std::cout <<
"ARTDAQTableBase Before traceTID=" << traceTID << __E__;
113 traceInit(trace_name(TRACE_NAME, __TRACE_FILE__, buf,
sizeof(buf)), 0);
114 std::cout <<
"ARTDAQTableBase After traceTID=" << traceTID << __E__;
115 __COUT__ <<
"ARTDAQTableBase TRACE reinit and Constructed." << __E__;
125 __SS__ <<
"Should not call void constructor, table type is lost!" << __E__;
130 ARTDAQTableBase::~ARTDAQTableBase(
void) {}
146 __COUT_INFO__ <<
"ARTDAQ Supervisor is disabled, so skipping fcl handling."
161 const std::string& ARTDAQTableBase::getTypeString(ARTDAQAppType type)
165 case ARTDAQAppType::EventBuilder:
167 case ARTDAQAppType::DataLogger:
169 case ARTDAQAppType::Dispatcher:
171 case ARTDAQAppType::BoardReader:
173 case ARTDAQAppType::Monitor:
175 case ARTDAQAppType::RoutingManager:
179 __SS__ <<
"Illegal translation attempt for type '" << (
unsigned int)type <<
"'"
185 std::string ARTDAQTableBase::getFHICLFilename(ARTDAQAppType type,
const std::string& name)
190 std::string uid = name;
191 for(
unsigned int i = 0; i < uid.size(); ++i)
192 if((uid[i] >=
'a' && uid[i] <=
'z') || (uid[i] >=
'A' && uid[i] <=
'Z') ||
193 (uid[i] >=
'0' && uid[i] <=
'9'))
204 std::string ARTDAQTableBase::getFlatFHICLFilename(ARTDAQAppType type,
205 const std::string& name)
210 std::string uid = name;
211 for(
unsigned int i = 0; i < uid.size(); ++i)
212 if((uid[i] >=
'a' && uid[i] <=
'z') || (uid[i] >=
'A' && uid[i] <=
'Z') ||
213 (uid[i] >=
'0' && uid[i] <=
'9'))
216 filename +=
"_flattened.fcl";
224 void ARTDAQTableBase::flattenFHICL(ARTDAQAppType type,
225 const std::string& name,
226 std::string* returnFcl )
228 std::chrono::steady_clock::time_point startClock = std::chrono::steady_clock::now();
229 __COUTS__(3) <<
"flattenFHICL()" << __ENV__(
"FHICL_FILE_PATH") << __E__;
233 std::string inFile = getFHICLFilename(type, name);
234 std::string outFile = getFlatFHICLFilename(type, name);
236 __COUTVS__(3, inFile);
237 __COUTVS__(3, outFile);
239 cet::filepath_lookup_nonabsolute policy(
"FHICL_FILE_PATH");
240 fhicl::ParameterSet pset;
244 __COUT_INFO__ <<
"parsing document: " << inFile;
247 pset = fhicl::ParameterSet::make(inFile, policy);
248 __COUTT__ <<
"document: " << inFile <<
" parsed";
249 __COUTT__ <<
"got pset from table:";
251 std::ofstream ofs{outFile};
254 __SS__ <<
"Failed to open fhicl output file '" << outFile <<
"!'" << __E__;
257 std::ostringstream out;
258 out << pset.to_indented_string(
262 *returnFcl = out.str();
263 __COUTVS__(21, returnFcl);
267 catch(cet::exception
const& e)
269 __SS__ <<
"Failed to parse fhicl into output file '" << outFile
270 <<
"' - here is the error: " << e.what() << __E__;
273 if(std::string(e.what()).find(
"TriggerEpilogs") != std::string::npos)
275 <<
"The Trigger Epilogs are located at "
276 "$USER_DATA/TriggerConfigurations/TriggerEpilogs. "
277 <<
"Please check that the Trigger Epilogs were properly generated, or "
278 "copy them from a previously working area."
284 <<
" Flatten Clock time = " << artdaq::TimeUtils::GetElapsedTime(startClock)
297 std::string& commentStr,
298 const std::string& parentPath,
300 const std::string& parameterPreamble,
301 bool onlyInsertAtTableParameters ,
302 bool includeAtTableParameters )
308 auto otherParameters = parameterGroupLink.
getChildren();
313 __COUTVS__(3, otherParameters.size());
314 __COUTVS__(3, onlyInsertAtTableParameters);
315 __COUTVS__(3, includeAtTableParameters);
317 size_t paramCount = 0;
318 for(
auto& parameter : otherParameters)
320 key = parameter.second.getNode(parameterPreamble +
"Key").getValue();
322 std::string localParentPath =
324 parameter.second.getTableName() +
":" +
326 parameterGroupLink.
getParentLinkID() +
"/" + parameter.second.getValue();
330 if(key.find(
"@table::") != std::string::npos)
333 if(onlyInsertAtTableParameters || includeAtTableParameters)
336 if(!parameter.second.status())
339 __COUTT__ <<
"Inserting parameter... " << localParentPath << __E__;
342 OUTCL(key << parameter.second.getNode(parameterPreamble +
"Value")
344 parameter.second.hasComment() ? parameter.second.getComment()
347 if(!parameter.second.status())
356 if(onlyInsertAtTableParameters)
360 if(!parameter.second.status())
363 __COUTT__ <<
"Inserting parameter... " << localParentPath << __E__;
366 if(key.size() && key.find(
"#include") == std::string::npos)
371 parameter.second.getNode(parameterPreamble +
"Value").getValue();
374 if(value.size() > 2 && value[0] ==
'@' && value[1] ==
'@')
377 <<
"Checking for getFclValueForARTDAQ @@ indicator from value = "
379 std::string potentialTable = value.substr(2);
380 __COUTTV__(potentialTable);
385 ->getFclValueForARTDAQ(cfgMgr, key);
387 catch(
const std::runtime_error& e)
389 __SS__ <<
"getFclValueForARTDAQ @@ indicator from value = "
390 << value <<
" corresponds to table '" << potentialTable
391 <<
"'... however fcl value failed to load: " << e.what();
395 __COUTT__ <<
"Value from getFclValueForARTDAQ: value = " << value
398 std::string localParentPath2 =
"/" + potentialTable;
399 OUTCL2(key <<
": " << value,
400 parameter.second.hasComment() ? parameter.second.getComment()
406 << parameter.second.getNode(parameterPreamble +
"Value")
408 parameter.second.hasComment() ? parameter.second.getComment()
414 OUTCL(parameter.second.getNode(parameterPreamble +
"Value").getValue(),
415 parameter.second.hasComment() ? parameter.second.getComment() :
"");
419 OUTCL(
"# comment for #include below:",
420 parameter.second.hasComment() ? parameter.second.getComment() :
"");
422 << parameter.second.getNode(parameterPreamble +
"Value").getValue()
426 if(!parameter.second.status())
432 __COUTS__(3) <<
"Empty parameter set found onlyInsertAtTableParameters="
433 << onlyInsertAtTableParameters << __E__;
434 std::string localParentPath =
437 if(onlyInsertAtTableParameters)
439 OUTCL(
"# no @table parameters found",
"" );
443 OUTCL(
"# empty parameter set found",
"" );
449 __COUTS__(3) <<
"No parameters found" << __E__;
450 std::string localParentPath =
452 OUTCL(
"# no parameters inserted",
"" );
462 std::string& commentStr,
463 const std::string& parentPath,
466 std::string value = moduleTypeNode.
getValue();
467 __COUTTV__(parentPath);
468 OUTCF((value.find(
"@table::") == std::string::npos ?
"module_type: " :
"") << value,
478 std::string& commentStr,
479 const std::string& parentPath,
482 auto metricsGroup = daqNode.
getNode(
"daqMetricsLink");
485 OUTCF(
"metrics: {",
"", metricsGroup.getParentLinkColumnName());
487 if(!metricsGroup.isDisconnected())
489 auto metrics = metricsGroup.getChildren();
490 bool sendSystemMetrics(
false), sendProcessMetrics(
false);
491 for(
auto& metric : metrics)
493 if(!metric.second.status())
496 __COUTT__ <<
"Inserting metric... " << parentPath << __E__;
497 std::string localParentPath =
498 parentPath +
"/" + metricsGroup.getParentLinkColumnName() +
":" +
499 metric.second.getTableName() +
":" + metricsGroup.getParentLinkIndex() +
500 ":" + metricsGroup.getParentLinkID() +
"/" + metric.second.getValue();
501 __COUTT__ <<
"Inserting metric... " << localParentPath << __E__;
503 OUTCL(metric.second.getNode(
"metricKey").getValue() <<
": {",
504 metric.second.hasComment() ? metric.second.getComment() :
"");
507 if(metric.second.getNode(
"sendSystemMetrics").getValue<
bool>())
509 sendSystemMetrics =
true;
511 if(metric.second.getNode(
"sendProcessMetrics").getValue<
bool>())
513 sendProcessMetrics =
true;
516 OUTCLF(
"metricPluginType: "
517 << metric.second.getNode(
"metricPluginType").getValue(),
521 "level_string: " << metric.second.getNode(
"metricLevelString").getValue(),
523 "metricLevelString");
525 auto metricParametersGroup = metric.second.getNode(
"metricParametersLink");
526 if(!metricParametersGroup.isDisconnected())
528 auto metricParameters = metricParametersGroup.getChildren();
529 for(
auto& metricParameter : metricParameters)
531 if(!metricParameter.second.status())
534 __COUTT__ <<
"Inserting metric... " << localParentPath << __E__;
535 std::string localParentPath2 =
536 localParentPath +
"/" +
537 metricParametersGroup.getParentLinkColumnName() +
":" +
538 metricParameter.second.getTableName() +
":" +
539 metricParametersGroup.getParentLinkIndex() +
":" +
540 metricParametersGroup.getParentLinkID() +
"/" +
541 metricParameter.second.getValue();
542 __COUTT__ <<
"Inserting metric... " << localParentPath2 << __E__;
543 OUTCL2(metricParameter.second.getNode(
"metricParameterKey").getValue()
545 << metricParameter.second.getNode(
"metricParameterValue")
547 metricParameter.second.hasComment()
548 ? metricParameter.second.getComment()
551 if(!metricParameter.second.status())
556 OUT <<
"} # end " << metric.second.getNode(
"metricKey").getValue()
559 if(!metric.second.status())
563 __COUTT__ <<
"Inserting metric send... " << parentPath << __E__;
564 std::string localParentPath =
565 parentPath +
"/" + metricsGroup.getParentLinkColumnName() +
":" +
566 metricsGroup.getTableName() +
":" + metricsGroup.getParentLinkIndex() +
":" +
567 metricsGroup.getParentLinkID();
568 if(sendSystemMetrics)
570 __COUTT__ <<
"Inserting send_system_metrics... " << localParentPath << __E__;
571 OUTCLF(
"send_system_metrics: true ",
572 "true, if any children are true",
573 "*/sendSystemMetrics");
576 OUTCLF(
"# send_system_metrics: false ",
577 "true, if any children are true",
578 "*/sendSystemMetrics");
580 if(sendProcessMetrics)
582 __COUTT__ <<
"Inserting send_process_metrics... " << localParentPath << __E__;
583 OUTCLF(
"send_process_metrics: true ",
584 "true, if any children are true",
585 "*/sendProcessMetrics");
588 OUTCLF(
"# send_process_metrics: false ",
589 "true, if any children are true",
590 "*/sendProcessMetrics");
594 __COUTS__(3) <<
"No metrics found" << __E__;
595 std::string localParentPath =
596 parentPath +
"/" + metricsGroup.getParentLinkColumnName();
597 OUTCL(
"# no metrics found",
"" );
601 OUT <<
"} # end metrics\n\n";
605 void ARTDAQTableBase::outputBoardReaderFHICL(
608 size_t routingTimeoutMs ,
609 size_t routingRetryCount )
611 if(ARTDAQ_DONOTWRITE_FCL)
613 __COUT__ <<
"Skipping fcl generation." << __E__;
742 std::string filename =
743 getFHICLFilename(ARTDAQAppType::BoardReader, boardReaderNode.
getValue());
749 std::string tabStr =
"";
750 std::string commentStr =
"";
753 out.open(filename, std::fstream::out | std::fstream::trunc);
756 __SS__ <<
"Failed to open ARTDAQ BoardReader fcl file: " << filename << __E__;
764 OUT <<
"###########################################################" << __E__;
766 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::BoardReader)
767 <<
" fcl configuration file produced by otsdaq." << __E__;
770 OUT <<
"# Original filename: \t" << filename << __E__;
771 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(ARTDAQAppType::BoardReader)
772 <<
" UID:\t" << boardReaderNode.
getValue() << __E__;
774 OUT <<
"###########################################################" << __E__;
788 catch(
const std::runtime_error&)
790 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
795 std::string parentPath =
798 OUTC(
"# start of " << getTypeString(ARTDAQAppType::BoardReader) <<
" '"
799 << boardReaderNode.
getValue() <<
"' fcl",
804 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
805 <<
" preamble parameters... " << parentPath << __E__;
811 boardReaderNode.
getNode(
"preambleParametersLink"),
818 __COUTT__ <<
"Generating daq block..." << __E__;
825 OUT <<
"fragment_receiver: {\n";
832 "daq generator plug-in type" ,
833 "daqGeneratorPluginType" );
834 OUTCF(
"fragment_type"
837 "generator data fragment type" ,
838 "daqGeneratorFragmentType" );
840 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
841 <<
" DAQ Parameters... " << parentPath << __E__;
847 boardReaderNode.
getNode(
"daqParametersLink"),
852 auto fragmentId = boardReaderNode.
getNode(
"daqFragmentIDs");
853 std::string value = fragmentId.
getValue();
854 if(value.size() < 2 || value[0] !=
'[' || value[value.size() - 1] !=
']')
856 __SS__ <<
"Invalid 'daqFragmentIDs' - the value must be a valid fcl "
857 "array with starting and ending square brackets: [ ]"
861 __COUTS__(20) <<
"fragment_ids: " << fragmentId.getValue() << __E__;
862 OUTCF(
"fragment_ids: " << fragmentId.getValue(),
868 __COUTT__ <<
"Ignoring missing daqFragmentIDs column associated with "
869 "fragment_ids for Board Reader."
872 OUTCF(
"# fragment_ids not specified, but could be",
"",
"daqFragmentIDs");
878 OUT <<
"destinations: { # empty placeholder, '"
879 << getTypeString(ARTDAQAppType::BoardReader)
880 <<
"' destinations handled by artdaq interface\n";
883 OUT <<
"routing_table_config: {\n";
886 auto readerSubsystemID = 1;
887 auto readerSubsystemLink = boardReaderNode.
getNode(
"SubsystemLink");
888 if(!readerSubsystemLink.isDisconnected())
890 readerSubsystemID = getSubsytemId(readerSubsystemLink);
892 if(info_.subsystems[readerSubsystemID].hasRoutingManager)
894 std::string localParentPath =
895 parentPath +
"/" + readerSubsystemLink.getParentLinkColumnName() +
":" +
896 readerSubsystemLink.getTableName() +
"/" + readerSubsystemLink.getValue();
897 __COUTT__ <<
"Inserting routing manager... " << localParentPath << __E__;
898 OUTCL(
"use_routing_manager: true",
899 "auto-generated because subsystem '" +
900 std::to_string(readerSubsystemID) +
"' has Routing Manager added");
902 OUTCLF(
"routing_manager_hostname: \""
903 << info_.subsystems[readerSubsystemID].routingManagerHost <<
"\"",
905 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
906 OUT <<
"table_update_port: 0\n";
907 OUT <<
"table_update_address: \"0.0.0.0\"\n";
908 OUT <<
"table_update_multicast_interface: \"0.0.0.0\"\n";
909 OUT <<
"table_acknowledge_port : 0\n";
910 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
911 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
915 OUTCF(
"use_routing_manager: false",
916 "auto-generated if subsystem '" + std::to_string(readerSubsystemID) +
917 "' has Routing Manager added",
918 readerSubsystemLink.getParentLinkColumnName());
925 OUT <<
"} # end fragment_receiver\n";
930 OUT <<
"} # end daq\n\n";
935 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
936 <<
" add-on parameters... " << parentPath << __E__;
941 boardReaderNode.
getNode(
"addOnParametersLink"),
946 OUTC(
"# end of " << getTypeString(ARTDAQAppType::BoardReader) <<
" '"
947 << boardReaderNode.
getValue() <<
"' fcl",
949 __COUTT__ <<
"outputBoardReaderFHICL DONE" << __E__;
953 __SS__ <<
"\n\nError while generating FHiCL for "
954 << getTypeString(ARTDAQAppType::BoardReader) <<
" node at filename '"
955 << filename <<
"'" << __E__;
960 catch(
const std::runtime_error& e)
962 ss <<
" Here is the error: " << e.what() << __E__;
964 catch(
const std::exception& e)
966 ss <<
" Here is the error: " << e.what() << __E__;
982 ARTDAQAppType appType,
984 size_t routingTimeoutMs ,
985 size_t routingRetryCount ,
986 std::string* returnFcl )
988 if(ARTDAQ_DONOTWRITE_FCL)
990 __COUT__ <<
"Skipping fcl generation." << __E__;
994 std::string filename = getFHICLFilename(appType, receiverNode.
getValue());
999 std::ostringstream out;
1001 std::string tabStr =
"";
1002 std::string commentStr =
"";
1004 __COUTV__(filename);
1005 outf.open(filename, std::fstream::out | std::fstream::trunc);
1008 __SS__ <<
"Failed to open ARTDAQ fcl file: " << filename << __E__;
1016 OUT <<
"###########################################################" << __E__;
1017 OUT <<
"#" << __E__;
1018 OUT <<
"# artdaq " << getTypeString(appType)
1019 <<
" fcl configuration file produced by otsdaq." << __E__;
1020 OUT <<
"# Creation time: \t"
1022 OUT <<
"# Original filename: \t" << filename << __E__;
1023 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(appType) <<
" UID:\t"
1024 << receiverNode.
getValue() << __E__;
1025 OUT <<
"#" << __E__;
1026 OUT <<
"###########################################################" << __E__;
1038 *returnFcl = out.str();
1039 __COUTVS__(21, *returnFcl);
1046 catch(
const std::runtime_error&)
1048 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
1053 std::string parentPath =
1056 OUTC(
"# start of " << getTypeString(appType) <<
" '" << receiverNode.
getValue()
1062 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" preamble parameters... "
1063 << parentPath << __E__;
1069 receiverNode.
getNode(
"preambleParametersLink"),
1076 __COUTT__ <<
"Generating daq block..." << __E__;
1078 auto daq = receiverNode.
getNode(
"daqLink");
1079 if(!daq.isDisconnected())
1082 OUTCF(
"daq: {",
"" , daq.getParentLinkColumnName());
1085 if(appType == ARTDAQAppType::EventBuilder)
1086 OUT <<
"event_builder: {\n";
1088 OUT <<
"aggregator: {\n";
1093 std::stringstream outSs;
1094 if(appType == ARTDAQAppType::DataLogger)
1095 outSs <<
"is_datalogger: true";
1096 else if(appType == ARTDAQAppType::Dispatcher)
1097 outSs <<
"is_dispatcher: true";
1098 if(outSs.str().size())
1100 addCommentWhitespace(
1102 tabStr.size() * TABSZ + commentStr.size() + outSs.str().size());
1103 outSs <<
"auto-generated based on app type '"
1104 << getTypeString(appType) <<
"'\n";
1111 std::string parentPath = daq.getParentTableName() +
"/" +
1112 daq.getParentRecordName() +
"/" +
1113 daq.getParentLinkColumnName() +
":" +
1114 daq.getTableName() +
"/" + daq.getValue();
1115 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" DAQ Parameters... "
1116 << parentPath << __E__;
1121 daq.getNode(
"daqParametersLink"),
1126 if(appType == ARTDAQAppType::EventBuilder)
1129 OUT <<
"routing_token_config: {\n";
1132 auto builderSubsystemID = 1;
1133 auto builderSubsystemLink = receiverNode.
getNode(
"SubsystemLink");
1134 if(!builderSubsystemLink.isDisconnected())
1136 builderSubsystemID = getSubsytemId(builderSubsystemLink);
1138 if(info_.subsystems[builderSubsystemID].hasRoutingManager)
1140 std::string localParentPath =
1142 builderSubsystemLink.getParentLinkColumnName() +
":" +
1143 builderSubsystemLink.getTableName() +
"/" +
1144 builderSubsystemLink.getValue();
1145 __COUTT__ <<
"Inserting routing manager... " << localParentPath
1147 OUTCL(
"use_routing_manager: true",
1148 "auto-generated because subsystem '" +
1149 std::to_string(builderSubsystemID) +
1150 "' has Routing Manager added");
1152 OUTCLF(
"routing_manager_hostname: \""
1153 << info_.subsystems[builderSubsystemID].routingManagerHost
1156 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
1157 OUT <<
"routing_token_port: 0\n";
1161 OUTCF(
"use_routing_manager: false",
1162 "auto-generated if subsystem '" +
1163 std::to_string(builderSubsystemID) +
1164 "' has Routing Manager added",
1165 builderSubsystemLink.getParentLinkColumnName());
1171 __COUTT__ <<
"Adding sources placeholder" << __E__;
1173 OUT <<
"sources: { # empty placeholder, '" << getTypeString(appType)
1174 <<
"' sources handled by artdaq interface\n";
1179 if(appType == ARTDAQAppType::EventBuilder)
1180 OUT <<
"} # end event_builder\n";
1182 OUT <<
"} # end aggregator\n";
1187 OUT <<
"} # end daq\n\n";
1191 __COUTS__(3) <<
"No daq found" << __E__;
1192 std::string localParentPath =
1193 parentPath +
"/" + daq.getParentLinkColumnName();
1194 OUTCL(
"# no daq found",
"" );
1199 __COUTT__ <<
"Filling art block..." << __E__;
1202 receiverNode.
getNode(ARTDAQTableBase::colARTDAQNotReader_.colLinkToArt_);
1203 if(!art.isDisconnected())
1205 std::string localParentPath = parentPath +
"/" +
1207 art.getTableName() +
"/" + art.getValue();
1208 OUTCF(
"art: {",
"" , art.getParentLinkColumnName());
1217 receiverNode.
getNode(
"SubsystemLink"),
1222 OUT <<
"} # end art\n\n";
1226 __COUTS__(3) <<
"No art found" << __E__;
1227 std::string localParentPath =
1228 parentPath +
"/" + art.getParentLinkColumnName();
1229 OUTCL(
"# no art found",
"" );
1234 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" add-on parameters... "
1235 << parentPath << __E__;
1240 receiverNode.
getNode(
"addOnParametersLink"),
1246 OUTC(
"# end of " << getTypeString(appType) <<
" '" << receiverNode.
getValue()
1249 __COUTT__ <<
"outputDataReceiverFHICL DONE" << __E__;
1253 __SS__ <<
"\n\nError while generating FHiCL for " << getTypeString(appType)
1254 <<
" node at filename '" << filename <<
"'" << __E__;
1259 catch(
const std::runtime_error& e)
1261 ss <<
" Here is the error: " << e.what() << __E__;
1263 catch(
const std::exception& e)
1265 ss <<
" Here is the error: " << e.what() << __E__;
1270 *returnFcl = out.str();
1271 __COUTVS__(21, *returnFcl);
1280 *returnFcl = out.str();
1281 __COUTVS__(21, *returnFcl);
1292 if(ARTDAQ_DONOTWRITE_FCL)
1294 __COUT__ <<
"Skipping fcl generation." << __E__;
1298 std::string filename =
1299 getFHICLFilename(ARTDAQAppType::Monitor, monitorNode.
getValue());
1305 std::string tabStr =
"";
1306 std::string commentStr =
"";
1308 __COUTV__(filename);
1309 out.open(filename, std::fstream::out | std::fstream::trunc);
1312 __SS__ <<
"Failed to open ARTDAQ fcl file: " << filename << __E__;
1320 OUT <<
"###########################################################" << __E__;
1321 OUT <<
"#" << __E__;
1322 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::Monitor)
1323 <<
" fcl configuration file produced by otsdaq." << __E__;
1324 OUT <<
"# Creation time: \t"
1326 OUT <<
"# Original filename: \t" << filename << __E__;
1327 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(ARTDAQAppType::Monitor) <<
" UID:\t"
1328 << monitorNode.
getValue() << __E__;
1329 OUT <<
"#" << __E__;
1330 OUT <<
"###########################################################" << __E__;
1344 catch(
const std::runtime_error&)
1346 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
1353 std::string parentPath =
1357 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::Monitor)
1358 <<
" preamble parameters... " << parentPath << __E__;
1363 monitorNode.
getNode(
"preambleParametersLink"),
1372 monitorNode.
getNode(ARTDAQTableBase::colARTDAQNotReader_.colLinkToArt_);
1373 if(!art.isDisconnected())
1376 OUT <<
"services.message: { "
1377 << artdaq::generateMessageFacilityConfiguration(
1378 mf::GetApplicationName().c_str(),
true,
false)
1380 OUT <<
"services.message.destinations.file: {type: \"GenFile\" threshold: "
1381 "\"INFO\" seperator: \"-\""
1382 <<
" pattern: \"" << monitorNode.
getValue() <<
"-%?H%t-%p.log"
1384 <<
" timestamp_pattern: \"%Y%m%d%H%M%S\""
1385 <<
" directory: \"" << __ENV__(
"OTSDAQ_LOG_ROOT") <<
"/"
1387 <<
" append : false }\n";
1390 auto dispatcherLink = monitorNode.
getNode(
"dispatcherLink");
1391 if(!dispatcherLink.isDisconnected())
1393 std::string monitorHost =
1394 monitorNode.
getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
1396 std::string dispatcherHost =
1397 dispatcherLink.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
1398 .getValueWithDefault(
"localhost");
1399 OUT <<
"source.dispatcherHost: \"" << dispatcherHost <<
"\"\n";
1400 int dispatcherPort = dispatcherLink.getNode(
"DispatcherPort").getValue<
int>();
1401 OUT <<
"source.dispatcherPort: " << dispatcherPort <<
"\n";
1402 OUT <<
"source.commanderPluginType: xmlrpc\n";
1405 int om_tcp_listen_port =
1407 int disp_fake_rank =
1408 dispatcherLink.getNode(
"DispatcherID").getValueWithDefault<
int>(200);
1410 size_t max_fragment_size = monitorNode.
getNode(
"max_fragment_size_words")
1412 std::string transfer_plugin_type = monitorNode.
getNode(
"transfer_plugin_type")
1415 OUT <<
"TransferPluginConfig: {\n";
1417 OUT <<
"transferPluginType: " << transfer_plugin_type <<
"\n";
1418 OUT <<
"host_map: [{ rank: " << disp_fake_rank <<
" host: \""
1419 << dispatcherHost <<
"\"}, { rank: " << om_rank <<
" host: \""
1420 << monitorHost <<
"\"}]\n";
1421 OUT <<
"max_fragment_size_words: " << max_fragment_size <<
"\n";
1422 OUT <<
"source_rank: " << disp_fake_rank <<
"\n";
1423 OUT <<
"destination_rank: " << om_rank <<
"\n";
1424 OUT <<
"port: " << om_tcp_listen_port <<
"\n";
1425 OUT <<
"unique_label: " << monitorNode.
getValue() <<
"_to_"
1426 << dispatcherLink.getValue() <<
"\n";
1429 OUT <<
"source.transfer_plugin: @local::TransferPluginConfig \n";
1430 auto dispatcherArt = monitorNode.
getNode(
"dispatcherArtLink");
1431 if(!dispatcherArt.isDisconnected())
1433 OUT <<
"source.dispatcher_config: {\n";
1439 OUT <<
"filter_paths: [\n";
1443 auto filterPathsLink = monitorNode.
getNode(
"filterPathsLink");
1444 if(!filterPathsLink.isDisconnected())
1451 for(
auto& filterPath : filterPaths)
1457 if(!filterPath.second.status())
1460 OUT <<
"name: " << filterPath.second.getNode(
"Name").getValue()
1462 OUT <<
"path: " << filterPath.second.getNode(
"Path").getValue()
1466 if(!filterPath.second.status())
1475 OUT <<
"unique_label: " << monitorNode.
getValue() <<
"\n";
1489 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::Monitor)
1490 <<
" add-on parameters... " << parentPath << __E__;
1495 monitorNode.
getNode(
"addOnParametersLink"),
1500 __COUTT__ <<
"outputOnlineMonitorFHICL DONE" << __E__;
1504 __SS__ <<
"\n\nError while generating FHiCL for "
1505 << getTypeString(ARTDAQAppType::Monitor) <<
" node at filename '"
1506 << filename <<
"'" << __E__;
1511 catch(
const std::runtime_error& e)
1513 ss <<
" Here is the error: " << e.what() << __E__;
1515 catch(
const std::exception& e)
1517 ss <<
" Here is the error: " << e.what() << __E__;
1531 std::string& tabStr,
1532 std::string& commentStr,
1533 const std::string& parentPath,
1536 size_t routingTimeoutMs,
1537 size_t routingRetryCount)
1541 __COUTT__ <<
"Filling art.services parentPath =" << parentPath << __E__;
1542 auto services = art.
getNode(
"servicesLink");
1543 if(!services.isDisconnected())
1545 std::string localParentPath =
1547 services.getTableName() +
"/" +
1548 services.getValue();
1549 __COUTT__ <<
"Inserting services... " << localParentPath << __E__;
1550 OUTCL(
"services: {", services.hasComment() ? services.getComment() :
"");
1555 __COUTT__ <<
"Inserting services parameters... " << localParentPath << __E__;
1560 services.getNode(
"ServicesParametersLink"),
1566 OUT <<
"ArtdaqSharedMemoryServiceInterface: {\n";
1568 OUT <<
"service_provider: "
1569 "ArtdaqSharedMemoryService \n";
1571 OUTCLF(
"waiting_time: " << services.getNode(
"sharedMemoryWaitingTime").getValue(),
1573 "sharedMemoryWaitingTime");
1574 OUTCLF(
"resume_after_timeout: "
1575 << (services.getNode(
"sharedMemoryResumeAfterTimeout").getValue<
bool>()
1579 "sharedMemoryResumeAfterTimeout");
1581 OUT <<
"} # end ArtdaqSharedMemoryServiceInterface\n\n";
1583 OUT <<
"ArtdaqFragmentNamingServiceInterface: {\n";
1585 OUT <<
"service_provider: "
1586 "ArtdaqFragmentNamingService \n";
1587 OUTCLF(
"helper_plugin: "
1588 << services.getNode(
"fragmentNamingServiceProvider").getValue(),
1590 "fragmentNamingServiceProvider");
1592 OUT <<
"} # end ArtdaqFragmentNamingServiceInterface\n\n";
1596 __COUTT__ <<
"Inserting services parameters... " << localParentPath << __E__;
1601 services.getNode(
"ServicesParametersLink"),
1607 OUT <<
"} # end services\n\n";
1611 __COUTS__(3) <<
"No services found" << __E__;
1612 std::string localParentPath =
1613 parentPath +
"/" + services.getParentLinkColumnName();
1614 OUTCL(
"# no services found",
"" );
1619 __COUTT__ <<
"Filling art.outputs parentPath =" << parentPath << __E__;
1620 auto outputs = art.
getNode(
"outputsLink");
1621 if(!outputs.isDisconnected())
1623 std::string localParentPath =
1626 __COUTT__ <<
"Inserting output... " << localParentPath << __E__;
1627 OUTCL(
"outputs: {",
"" );
1630 auto outputPlugins = outputs.getChildren();
1631 for(
auto& outputPlugin : outputPlugins)
1633 if(!outputPlugin.second.status())
1636 __COUTT__ <<
"Inserting output parameters... " << localParentPath << __E__;
1637 std::string localParentPath2 =
1638 localParentPath +
":" + outputPlugin.second.getTableName() +
":" +
1639 outputs.getParentLinkIndex() +
":" + outputs.getParentLinkID() +
"/" +
1640 outputPlugin.second.getValue();
1641 __COUTT__ <<
"Inserting output... " << localParentPath2 << __E__;
1643 outputPlugin.second.getNode(
"outputKey").getValue() <<
": {",
1644 outputPlugin.second.hasComment() ? outputPlugin.second.getComment() :
"",
1648 __COUTT__ <<
"insertModuleType... " << localParentPath2 << __E__;
1649 std::string moduleType =
1654 outputPlugin.second.getNode(
"outputModuleType"));
1658 __COUTT__ <<
"Inserting output parameters... " << localParentPath << __E__;
1663 outputPlugin.second.getNode(
"outputModuleParameterLink"),
1668 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1669 "BinaryNetOutput" ||
1670 outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1673 OUT <<
"destinations: { # empty placeholder, '"
1674 << outputPlugin.second.getNode(
"outputModuleType").getValue()
1675 <<
"' destinations handled by artdaq interface\n";
1678 OUT <<
"routing_table_config: {\n";
1681 auto mySubsystemID = 1;
1682 auto destinationSubsystemID = 1;
1685 mySubsystemID = getSubsytemId(subsystemLink);
1687 destinationSubsystemID = info_.subsystems[mySubsystemID].destination;
1688 if(info_.subsystems[destinationSubsystemID].hasRoutingManager)
1690 std::string localParentPath =
1693 __COUTT__ <<
"Inserting routing manager... " << localParentPath
1695 OUTCL(
"use_routing_manager: true",
1696 "auto-generated because subsystem '" +
1697 std::to_string(destinationSubsystemID) +
1698 "' has Routing Manager added");
1701 "routing_manager_hostname: \""
1702 << info_.subsystems[destinationSubsystemID].routingManagerHost
1705 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
1706 OUT <<
"table_update_port: 0\n";
1707 OUT <<
"table_update_address: \"0.0.0.0\"\n";
1708 OUT <<
"table_update_multicast_interface: \"0.0.0.0\"\n";
1709 OUT <<
"table_acknowledge_port : 0\n";
1710 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
1711 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
1715 OUTCF(
"use_routing_manager: false",
1716 "auto-generated if subsystem '" +
1717 std::to_string(destinationSubsystemID) +
1718 "' has Routing Manager added",
1722 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1725 info_.subsystems[mySubsystemID].eventMode =
true;
1731 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1733 outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1734 "TransferOutputReliable")
1736 OUT <<
"transfer_plugin: @local::TransferPluginConfig \n";
1740 OUT <<
"} # end " << outputPlugin.second.getNode(
"outputKey").getValue()
1743 if(!outputPlugin.second.status())
1748 OUT <<
"} # end outputs\n\n";
1752 __COUTS__(3) <<
"No outputs found" << __E__;
1753 std::string localParentPath =
1754 parentPath +
"/" + outputs.getParentLinkColumnName();
1755 OUTCL(
"# no outputs found",
"" );
1760 __COUTT__ <<
"Filling art.physics parentPath =" << parentPath << __E__;
1761 auto physics = art.
getNode(
"physicsLink");
1762 if(!physics.isDisconnected())
1764 __COUTT__ <<
"Inserting physics... " << parentPath << __E__;
1765 std::string localParentPath = parentPath +
"/" +
1766 physics.getParentLinkColumnName() +
":" +
1767 physics.getTableName() +
"/" +
1771 OUTCL(
"physics: {", physics.hasComment() ? services.getComment() :
"");
1777 __COUTT__ <<
"Inserting physics other parameters... " << localParentPath << __E__;
1782 physics.getNode(
"physicsOtherParametersLink"),
1783 "physicsParameter" ,
1787 auto analyzers = physics.getNode(
"analyzersLink");
1788 if(!analyzers.isDisconnected())
1790 __COUTT__ <<
"Inserting art.physics.analyzers... " << localParentPath
1792 std::string localParentPath2 =
1793 localParentPath +
"/" + analyzers.getParentLinkColumnName();
1794 __COUTT__ <<
"Inserting art.physics.analyzers... " << localParentPath2
1799 OUTCL2(
"analyzers: {",
"" );
1803 auto modules = analyzers.getChildren();
1804 for(
auto& module : modules)
1806 if(!module.second.status())
1813 auto analyzerNodeParameterLink =
1814 module.second.getNode(
"analyzerModuleParameterLink");
1817 __COUTT__ <<
"Inserting analyzer @table parameters... "
1818 << localParentPath2 << __E__;
1819 std::string localParentPath3 =
1820 localParentPath2 +
":" + module.second.getTableName() +
":" +
1821 analyzers.getParentLinkIndex() +
":" + analyzers.getParentLinkID() +
1822 "/" + module.second.getValue();
1823 __COUTT__ <<
"Inserting analyzer @table parameters... "
1824 << localParentPath3 << __E__;
1829 analyzerNodeParameterLink,
1830 "analyzerParameter" ,
1834 OUT << module.second.getNode(
"analyzerKey").getValue() <<
": {\n";
1840 module.second.getNode(
"analyzerModuleType"));
1844 __COUTT__ <<
"Inserting analayzer not @table parameters... "
1845 << localParentPath3 << __E__;
1850 analyzerNodeParameterLink,
1851 "analyzerParameter" ,
1858 if(!module.second.status())
1862 OUT <<
"} # end physics.analyzers\n\n";
1866 __COUTS__(3) <<
"No analyzers found" << __E__;
1867 std::string localParentPath2 =
1868 localParentPath +
"/" + analyzers.getParentLinkColumnName();
1869 OUTCL2(
"# no analyzers found",
"" );
1872 auto producers = physics.getNode(
"producersLink");
1873 if(!producers.isDisconnected())
1875 __COUTT__ <<
"Inserting art.physics.producers... " << localParentPath
1877 std::string localParentPath2 =
1878 localParentPath +
"/" + producers.getParentLinkColumnName();
1882 OUTCL2(
"producers: {",
"" );
1886 auto modules = producers.getChildren();
1887 for(
auto& module : modules)
1889 if(!module.second.status())
1896 auto producerNodeParameterLink =
1897 module.second.getNode(
"producerModuleParameterLink");
1900 __COUTT__ <<
"Inserting producer @table parameters... "
1901 << localParentPath2 << __E__;
1902 std::string localParentPath3 =
1903 localParentPath2 +
":" + module.second.getTableName() +
":" +
1904 producers.getParentLinkIndex() +
":" + producers.getParentLinkID() +
1905 "/" + module.second.getValue();
1906 __COUTT__ <<
"Inserting producer @table parameters... "
1907 << localParentPath3 << __E__;
1912 producerNodeParameterLink,
1913 "producerParameter" ,
1917 if(module.second.status() &&
1918 module.second.getNode(
"producerModuleType").getValue() ==
"")
1920 std::string tmp = localParentPath2;
1921 localParentPath2 = localParentPath3;
1922 OUTCL2F(
"# skipping '" << module.second.getValue()
1923 <<
"' with empty module type",
1925 "producerModuleType");
1926 localParentPath2 = tmp;
1930 OUT << module.second.getNode(
"producerKey").getValue() <<
": {\n";
1937 module.second.getNode(
"producerModuleType"));
1941 __COUTT__ <<
"Inserting producer not @table parameters... "
1942 << localParentPath3 << __E__;
1947 producerNodeParameterLink,
1948 "producerParameter" ,
1955 if(!module.second.status())
1959 OUT <<
"} # end physics.producers\n\n";
1963 __COUTS__(3) <<
"No producers found" << __E__;
1964 std::string localParentPath2 =
1965 localParentPath +
"/" + producers.getParentLinkColumnName();
1966 OUTCL2(
"# no producers found",
"" );
1969 auto filters = physics.getNode(
"filtersLink");
1970 if(!filters.isDisconnected())
1972 __COUTT__ <<
"Inserting art.physics.filters... " << localParentPath << __E__;
1973 std::string localParentPath2 =
1974 localParentPath +
"/" + filters.getParentLinkColumnName();
1978 OUTCL2(
"filters: {",
"" );
1982 auto modules = filters.getChildren();
1983 for(
auto& module : modules)
1985 if(!module.second.status())
1992 auto filterNodeParameterLink =
1993 module.second.getNode(
"filterModuleParameterLink");
1996 __COUTT__ <<
"Inserting filter @table parameters... " << localParentPath2
1998 std::string localParentPath3 =
1999 localParentPath2 +
":" + module.second.getTableName() +
":" +
2000 filters.getParentLinkIndex() +
":" + filters.getParentLinkID() +
"/" +
2001 module.second.getValue();
2002 __COUTT__ <<
"Inserting filter @table parameters... " << localParentPath3
2008 filterNodeParameterLink,
2012 if(module.second.status() &&
2013 module.second.getNode(
"filterModuleType").getValue() ==
"")
2015 std::string tmp = localParentPath2;
2016 localParentPath2 = localParentPath3;
2017 OUTCL2F(
"# skipping '" << module.second.getValue()
2018 <<
"' with empty module type",
2020 "filterModuleType");
2021 localParentPath2 = tmp;
2025 OUT << module.second.getNode(
"filterKey").getValue() <<
": {\n";
2032 module.second.getNode(
"filterModuleType"));
2036 __COUTT__ <<
"Inserting filter not @table parameters... "
2037 << localParentPath3 << __E__;
2042 filterNodeParameterLink,
2050 if(!module.second.status())
2054 OUT <<
"} # end physics.filters\n\n";
2058 __COUTS__(3) <<
"No filters found" << __E__;
2059 std::string localParentPath2 =
2060 localParentPath +
"/" + services.getParentLinkColumnName();
2061 OUTCL2(
"# no filters found",
"" );
2066 __COUTT__ <<
"Inserting art.physics not @table parameters... " << localParentPath
2072 physics.getNode(
"physicsOtherParametersLink"),
2073 "physicsParameter" ,
2078 OUT <<
"} # end physics\n\n";
2082 __COUTS__(3) <<
"No physics found" << __E__;
2083 std::string localParentPath =
2084 parentPath +
"/" + physics.getParentLinkColumnName();
2085 OUTCL(
"# no physics found",
"" );
2090 __COUTT__ <<
"Filling art.source" << __E__;
2091 auto source = art.
getNode(
"sourceLink");
2092 if(!source.isDisconnected())
2094 __COUTT__ <<
"Inserting source... " << parentPath << __E__;
2095 std::string localParentPath = parentPath +
"/" +
2096 source.getParentLinkColumnName() +
":" +
2097 source.getTableName() +
"/" +
2099 OUTCL(
"source: {", source.hasComment() ? source.getComment() :
"");
2102 out, tabStr, commentStr, parentPath, source.getNode(
"sourceModuleType"));
2108 std::string localParentPath = parentPath +
"/" + source.getParentLinkColumnName();
2109 OUTCL(
"source: { # auto-generated default, to change provide a source link",
2112 OUT <<
"module_type: ArtdaqInput";
2119 __COUTT__ <<
"Writing art.process_name" << __E__;
2120 OUTCF(
"process_name: " << art.
getNode(ARTDAQTableBase::colARTDAQArt_.colProcessName_),
2122 ARTDAQTableBase::colARTDAQArt_.colProcessName_);
2126 __COUTT__ <<
"Inserting art @table parameters... " << parentPath << __E__;
2131 art.
getNode(
"AddOnParametersLink"),
2139 void ARTDAQTableBase::outputRoutingManagerFHICL(
2141 size_t routingTimeoutMs ,
2142 size_t routingRetryCount )
2144 if(ARTDAQ_DONOTWRITE_FCL)
2146 __COUT__ <<
"Skipping fcl generation." << __E__;
2150 std::string filename =
2151 getFHICLFilename(ARTDAQAppType::RoutingManager, routingManagerNode.
getValue());
2157 std::string tabStr =
"";
2158 std::string commentStr =
"";
2160 __COUTV__(filename);
2161 out.open(filename, std::fstream::out | std::fstream::trunc);
2164 __SS__ <<
"Failed to open ARTDAQ RoutingManager fcl file: " << filename << __E__;
2172 OUT <<
"###########################################################" << __E__;
2173 OUT <<
"#" << __E__;
2174 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::RoutingManager)
2175 <<
" fcl configuration file produced by otsdaq." << __E__;
2176 OUT <<
"# Creation time: \t"
2178 OUT <<
"# Original filename: \t" << filename << __E__;
2179 OUT <<
"# otsdaq-ARTDAQ RoutingManager UID:\t" << routingManagerNode.
getValue()
2181 OUT <<
"#" << __E__;
2182 OUT <<
"###########################################################" << __E__;
2196 catch(
const std::runtime_error&)
2208 OUT <<
"policy: {\n";
2212 if(policyName ==
"DEFAULT")
2213 policyName =
"NoOp";
2214 OUT <<
"policy: " << policyName <<
"\n";
2215 OUT <<
"receiver_ranks: []\n";
2218 auto parametersLink = routingManagerNode.
getNode(
"routingPolicyParametersLink");
2219 if(!parametersLink.isDisconnected())
2222 for(
auto& parameter : parameters)
2224 if(!parameter.second.status())
2235 parameter.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT);
2236 OUT << parameter.second.getNode(
"daqParameterKey").getValue() <<
": "
2237 << parameter.second.getNode(
"daqParameterValue").getValue()
2238 << (comment.isDefaultValue() ?
"" : (
"\t # " + comment.getValue()))
2241 if(!parameter.second.status())
2249 OUT <<
"use_routing_manager: true\n";
2251 auto routingManagerSubsystemID = 1;
2252 auto routingManagerSubsystemLink = routingManagerNode.
getNode(
"SubsystemLink");
2253 std::string rmHost =
"localhost";
2254 if(!routingManagerSubsystemLink.isDisconnected())
2256 routingManagerSubsystemID = getSubsytemId(routingManagerSubsystemLink);
2257 rmHost = info_.subsystems[routingManagerSubsystemID].routingManagerHost;
2259 if(rmHost ==
"localhost" || rmHost ==
"127.0.0.1")
2261 char hostbuf[HOST_NAME_MAX + 1];
2262 gethostname(hostbuf, HOST_NAME_MAX);
2263 rmHost = std::string(hostbuf);
2267 OUT <<
"routing_manager_hostname: \"" << rmHost <<
"\"\n";
2268 OUT <<
"sender_ranks: []\n";
2269 OUT <<
"table_update_port: 0\n";
2270 OUT <<
"table_update_address: \"0.0.0.0\"\n";
2271 OUT <<
"table_acknowledge_port: 0\n";
2272 OUT <<
"token_receiver: {\n";
2275 OUT <<
"routing_token_port: 0\n";
2281 auto tableUpdateIntervalMs =
2283 if(tableUpdateIntervalMs !=
"DEFAULT")
2285 OUT <<
"table_update_interval_ms: " << tableUpdateIntervalMs <<
"\n";
2287 auto tableAckRetryCount =
2289 if(tableAckRetryCount !=
"DEFAULT")
2291 OUT <<
"table_ack_retry_count: " << tableAckRetryCount <<
"\n";
2294 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
2295 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
2306 __COUTT__ <<
"outputReaderFHICL DONE" << __E__;
2310 __SS__ <<
"\n\nError while generating FHiCL for "
2311 << getTypeString(ARTDAQAppType::RoutingManager) <<
" node at filename '"
2312 << filename <<
"'" << __E__;
2317 catch(
const std::runtime_error& e)
2319 ss <<
" Here is the error: " << e.what() << __E__;
2321 catch(
const std::exception& e)
2323 ss <<
" Here is the error: " << e.what() << __E__;
2335 bool getStatusFalseNodes ,
2337 size_t maxFragmentSizeBytes ,
2338 size_t routingTimeoutMs ,
2339 size_t routingRetryCount ,
2343 progressBar->
step();
2346 info_.subsystems.clear();
2347 info_.processes.clear();
2350 progressBar->
step();
2352 info_.subsystems[NULL_SUBSYSTEM_DESTINATION].id = NULL_SUBSYSTEM_DESTINATION;
2353 info_.subsystems[NULL_SUBSYSTEM_DESTINATION].label = NULL_SUBSYSTEM_DESTINATION_LABEL;
2358 __COUT__ <<
"artdaqSupervisorNode is disconnected." << __E__;
2363 extractRoutingManagersInfo(artdaqSupervisorNode,
2364 getStatusFalseNodes,
2368 __COUT__ <<
"artdaqSupervisorNode RoutingManager size: "
2369 << info_.processes.at(ARTDAQAppType::RoutingManager).size() << __E__;
2372 progressBar->
step();
2374 extractBoardReadersInfo(artdaqSupervisorNode,
2375 getStatusFalseNodes,
2377 maxFragmentSizeBytes,
2380 __COUT__ <<
"artdaqSupervisorNode BoardReader size: "
2381 << info_.processes.at(ARTDAQAppType::BoardReader).size() << __E__;
2384 progressBar->
step();
2386 extractEventBuildersInfo(
2387 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2388 __COUT__ <<
"artdaqSupervisorNode EventBuilder size: "
2389 << info_.processes.at(ARTDAQAppType::EventBuilder).size() << __E__;
2392 progressBar->
step();
2394 extractDataLoggersInfo(
2395 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2396 __COUT__ <<
"artdaqSupervisorNode DataLogger size: "
2397 << info_.processes.at(ARTDAQAppType::DataLogger).size() << __E__;
2400 progressBar->
step();
2402 extractDispatchersInfo(
2403 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2404 __COUT__ <<
"artdaqSupervisorNode Dispatcher size: "
2405 << info_.processes.at(ARTDAQAppType::Dispatcher).size() << __E__;
2408 progressBar->
step();
2414 void ARTDAQTableBase::extractRoutingManagersInfo(
ConfigurationTree artdaqSupervisorNode,
2415 bool getStatusFalseNodes,
2417 size_t routingTimeoutMs,
2418 size_t routingRetryCount)
2420 __COUT__ <<
"Checking for Routing Managers..." << __E__;
2421 info_.processes[ARTDAQAppType::RoutingManager].clear();
2424 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToRoutingManagers_);
2427 std::vector<std::pair<std::string, ConfigurationTree>> routingManagers =
2430 __COUT__ <<
"There are " << routingManagers.size()
2431 <<
" configured Routing Managers" << __E__;
2433 for(
auto& routingManager : routingManagers)
2435 const std::string& rmUID = routingManager.first;
2437 if(getStatusFalseNodes || routingManager.second.status())
2439 std::string rmHost =
2440 routingManager.second
2441 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2442 .getValueWithDefault(
"localhost");
2443 if(rmHost ==
"localhost" || rmHost ==
"127.0.0.1")
2445 char hostbuf[HOST_NAME_MAX + 1];
2446 gethostname(hostbuf, HOST_NAME_MAX);
2447 rmHost = std::string(hostbuf);
2451 routingManager.second
2452 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2453 .getValueWithDefault(
"");
2455 int routingManagerSubsystemID = 1;
2457 routingManager.second.
getNode(
2458 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2461 routingManagerSubsystemID =
2462 getSubsytemId(routingManagerSubsystemLink);
2465 info_.subsystems[routingManagerSubsystemID].id =
2466 routingManagerSubsystemID;
2468 const std::string& routingManagerSubsystemName =
2472 info_.subsystems[routingManagerSubsystemID].label =
2473 routingManagerSubsystemName;
2475 if(info_.subsystems[routingManagerSubsystemID].hasRoutingManager)
2477 __SS__ <<
"Error: You cannot have multiple Routing Managers in a "
2483 auto routingManagerSubsystemDestinationLink =
2484 routingManagerSubsystemLink.
getNode(
2485 colARTDAQSubsystem_.colLinkToDestination_);
2486 if(routingManagerSubsystemDestinationLink.isDisconnected())
2489 info_.subsystems[routingManagerSubsystemID].destination = 0;
2494 info_.subsystems[routingManagerSubsystemID].destination =
2495 getSubsytemId(routingManagerSubsystemDestinationLink);
2501 if(!info_.subsystems.count(
2502 info_.subsystems[routingManagerSubsystemID].destination) ||
2504 .subsystems[info_.subsystems[routingManagerSubsystemID]
2506 .sources.count(routingManagerSubsystemID))
2509 .subsystems[info_.subsystems[routingManagerSubsystemID]
2511 .sources.insert(routingManagerSubsystemID);
2516 __COUT__ <<
"Found Routing Manager with UID " << rmUID
2517 <<
", DAQInterface Hostname " << rmHost <<
", and Subsystem "
2518 << routingManagerSubsystemID << __E__;
2519 info_.processes[ARTDAQAppType::RoutingManager].emplace_back(
2523 routingManagerSubsystemID,
2524 ARTDAQAppType::RoutingManager,
2525 routingManager.second.status());
2527 info_.subsystems[routingManagerSubsystemID].hasRoutingManager =
true;
2528 info_.subsystems[routingManagerSubsystemID].routingManagerHost = rmHost;
2532 outputRoutingManagerFHICL(
2533 routingManager.second, routingTimeoutMs, routingRetryCount);
2535 flattenFHICL(ARTDAQAppType::RoutingManager,
2536 routingManager.second.getValue());
2541 __COUT__ <<
"Routing Manager " << rmUID <<
" is disabled." << __E__;
2548 void ARTDAQTableBase::extractBoardReadersInfo(
ConfigurationTree artdaqSupervisorNode,
2549 bool getStatusFalseNodes,
2551 size_t maxFragmentSizeBytes,
2552 size_t routingTimeoutMs,
2553 size_t routingRetryCount)
2555 __COUT__ <<
"Checking for Board Readers..." << __E__;
2556 info_.processes[ARTDAQAppType::BoardReader].clear();
2559 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToBoardReaders_);
2562 std::vector<std::pair<std::string, ConfigurationTree>> readers =
2564 __COUT__ <<
"There are " << readers.size() <<
" configured Board Readers."
2567 for(
auto& reader : readers)
2569 const std::string& readerUID = reader.first;
2571 if(getStatusFalseNodes || reader.second.status())
2573 std::string readerHost =
2574 reader.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2575 .getValueWithDefault(
"localhost");
2576 std::string readerAP =
2578 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2579 .getValueWithDefault(
"");
2581 int readerSubsystemID = 1;
2583 reader.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2586 readerSubsystemID = getSubsytemId(readerSubsystemLink);
2588 info_.subsystems[readerSubsystemID].id = readerSubsystemID;
2590 const std::string& readerSubsystemName =
2594 info_.subsystems[readerSubsystemID].label = readerSubsystemName;
2596 auto readerSubsystemDestinationLink = readerSubsystemLink.
getNode(
2597 colARTDAQSubsystem_.colLinkToDestination_);
2598 if(readerSubsystemDestinationLink.isDisconnected())
2601 info_.subsystems[readerSubsystemID].destination = 0;
2606 info_.subsystems[readerSubsystemID].destination =
2607 getSubsytemId(readerSubsystemDestinationLink);
2613 if(!info_.subsystems.count(
2614 info_.subsystems[readerSubsystemID].destination) ||
2615 !info_.subsystems[info_.subsystems[readerSubsystemID].destination]
2616 .sources.count(readerSubsystemID))
2618 info_.subsystems[info_.subsystems[readerSubsystemID].destination]
2619 .sources.insert(readerSubsystemID);
2624 __COUT__ <<
"Found Board Reader with UID " << readerUID
2625 <<
", DAQInterface Hostname " << readerHost <<
", and Subsystem "
2626 << readerSubsystemID << __E__;
2627 info_.processes[ARTDAQAppType::BoardReader].emplace_back(
2632 ARTDAQAppType::BoardReader,
2633 reader.second.status());
2637 outputBoardReaderFHICL(reader.second,
2638 maxFragmentSizeBytes,
2642 flattenFHICL(ARTDAQAppType::BoardReader, reader.second.getValue());
2647 __COUT__ <<
"Board Reader " << readerUID <<
" is disabled." << __E__;
2653 __COUT_WARN__ <<
"There should be at least one Board Reader!";
2660 void ARTDAQTableBase::extractEventBuildersInfo(
ConfigurationTree artdaqSupervisorNode,
2661 bool getStatusFalseNodes,
2663 size_t maxFragmentSizeBytes)
2665 __COUT__ <<
"Checking for Event Builders..." << __E__;
2666 info_.processes[ARTDAQAppType::EventBuilder].clear();
2669 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToEventBuilders_);
2672 std::vector<std::pair<std::string, ConfigurationTree>> builders =
2675 std::string lastBuilderFcl[2],
2676 flattenedLastFclParts
2678 for(
auto& builder : builders)
2680 const std::string& builderUID = builder.first;
2681 __COUTV__(builderUID);
2683 if(getStatusFalseNodes || builder.second.status())
2685 std::string builderHost =
2686 builder.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2687 .getValueWithDefault(
"localhost");
2688 std::string builderAP =
2690 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2691 .getValueWithDefault(
"");
2693 int builderSubsystemID = 1;
2695 builder.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2698 builderSubsystemID = getSubsytemId(builderSubsystemLink);
2701 info_.subsystems[builderSubsystemID].id = builderSubsystemID;
2703 const std::string& builderSubsystemName =
2707 info_.subsystems[builderSubsystemID].label = builderSubsystemName;
2709 auto builderSubsystemDestinationLink = builderSubsystemLink.
getNode(
2710 colARTDAQSubsystem_.colLinkToDestination_);
2711 if(builderSubsystemDestinationLink.isDisconnected())
2714 info_.subsystems[builderSubsystemID].destination = 0;
2719 info_.subsystems[builderSubsystemID].destination =
2720 getSubsytemId(builderSubsystemDestinationLink);
2726 if(!info_.subsystems.count(
2727 info_.subsystems[builderSubsystemID].destination) ||
2728 !info_.subsystems[info_.subsystems[builderSubsystemID].destination]
2729 .sources.count(builderSubsystemID))
2731 info_.subsystems[info_.subsystems[builderSubsystemID].destination]
2732 .sources.insert(builderSubsystemID);
2737 __COUT__ <<
"Found Event Builder with UID " << builderUID
2738 <<
", on Hostname " << builderHost <<
", in Subsystem "
2739 << builderSubsystemID << __E__;
2740 info_.processes[ARTDAQAppType::EventBuilder].emplace_back(
2745 ARTDAQAppType::EventBuilder,
2746 builder.second.status());
2750 std::string returnFcl, processName;
2751 bool needToFlatten =
true;
2752 bool captureAsLastFcl =
2755 (&builder != &builders.back());
2757 ARTDAQAppType::EventBuilder,
2758 maxFragmentSizeBytes,
2759 DEFAULT_ROUTING_TIMEOUT_MS,
2760 DEFAULT_ROUTING_RETRY_COUNT,
2761 captureAsLastFcl ? &returnFcl :
nullptr);
2768 auto cmi = returnFcl.find(
2769 "# otsdaq-ARTDAQ builder UID:");
2770 if(cmi != std::string::npos)
2771 cmi = returnFcl.find(
'\n', cmi);
2772 if(cmi != std::string::npos)
2774 size_t pnj = std::string::npos;
2776 returnFcl.find(
"\tprocess_name: ", cmi);
2777 if(pni != std::string::npos)
2779 pni += std::string(
"\tprocess_name: ")
2781 pnj = returnFcl.find(
'\n', pni);
2783 if(pnj != std::string::npos)
2785 processName = returnFcl.substr(pni, pnj - pni);
2786 __COUT__ <<
"Found process name = " << processName << __E__;
2788 bool sameFirst =
false;
2790 std::string newPiece = returnFcl.substr(cmi, pni - cmi);
2791 if(flattenedLastFclParts[0].size() &&
2792 lastBuilderFcl[0].size() && lastBuilderFcl[0] == newPiece)
2794 __COUT__ <<
"Same first fcl" << __E__;
2799 __COUTVS__(20, lastBuilderFcl[0]);
2800 __COUTVS__(20, newPiece);
2801 for(
size_t i = 0, j = 0;
2802 i < lastBuilderFcl[0].size() && j < newPiece.size();
2805 if(lastBuilderFcl[0][i] != newPiece[j])
2809 __COUTVS__(20, lastBuilderFcl[0].substr(i, 30));
2810 __COUTVS__(20, newPiece.substr(j, 30));
2815 if(captureAsLastFcl)
2816 lastBuilderFcl[0] = newPiece;
2819 newPiece = returnFcl.substr(pnj);
2820 if(lastBuilderFcl[0].size() && lastBuilderFcl[1] == newPiece)
2822 __COUT__ <<
"Same second fcl" << __E__;
2825 std::chrono::steady_clock::time_point startClock =
2826 std::chrono::steady_clock::now();
2827 __COUT__ <<
"Found fcl match! Reuse for "
2828 << builderUID << __E__;
2831 needToFlatten =
false;
2834 std::string outFile = getFlatFHICLFilename(
2835 ARTDAQAppType::EventBuilder, builderUID);
2836 __COUTVS__(3, outFile);
2837 std::ofstream ofs{outFile};
2840 __SS__ <<
"Failed to open fhicl output file '"
2841 << outFile <<
"!'" << __E__;
2844 ofs << flattenedLastFclParts[0] <<
"process_name: \""
2845 << processName <<
"\""
2846 << flattenedLastFclParts[1];
2848 << builderUID <<
" Flatten Clock time = "
2849 << artdaq::TimeUtils::GetElapsedTime(startClock)
2854 if(captureAsLastFcl)
2855 lastBuilderFcl[1] = newPiece;
2860 ARTDAQTableBase::flattenFHICL(
2861 ARTDAQAppType::EventBuilder,
2863 captureAsLastFcl ? &returnFcl :
nullptr);
2865 __COUT__ <<
"Skipping full flatten for " << builderUID << __E__;
2868 __COUTV__(captureAsLastFcl);
2869 if(captureAsLastFcl)
2871 size_t pnj = std::string::npos;
2872 auto pni = returnFcl.find(
"process_name:");
2873 if(pni != std::string::npos)
2877 (returnFcl[pni - 1] ==
' ' || returnFcl[pni - 1] ==
'\n' ||
2878 returnFcl[pni - 1] ==
'\t'))
2879 pnj = returnFcl.find(
'\n', pni);
2881 if(pnj != std::string::npos)
2884 <<
"Found flattened '"
2885 << returnFcl.substr(pni, pnj - pni) <<
"' at pos " << pni
2886 <<
" of " << returnFcl.size() << __E__;
2887 flattenedLastFclParts[0] = returnFcl.substr(0, pni);
2888 flattenedLastFclParts[1] = returnFcl.substr(pnj);
2892 __COUT_WARN__ <<
"Failed to capture fcl for " << processName
2900 __COUT__ <<
"Event Builder " << builderUID <<
" is disabled." << __E__;
2906 __COUT_WARN__ <<
"There should be at least one Event Builder!";
2913 void ARTDAQTableBase::extractDataLoggersInfo(
ConfigurationTree artdaqSupervisorNode,
2914 bool getStatusFalseNodes,
2916 size_t maxFragmentSizeBytes)
2918 __COUT__ <<
"Checking for Data Loggers..." << __E__;
2919 info_.processes[ARTDAQAppType::DataLogger].clear();
2922 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToDataLoggers_);
2925 std::vector<std::pair<std::string, ConfigurationTree>> dataloggers =
2928 for(
auto& datalogger : dataloggers)
2930 const std::string& loggerUID = datalogger.first;
2932 if(getStatusFalseNodes || datalogger.second.status())
2934 std::string loggerHost =
2935 datalogger.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2936 .getValueWithDefault(
"localhost");
2937 std::string loggerAP =
2939 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2940 .getValueWithDefault(
"");
2942 int loggerSubsystemID = 1;
2944 datalogger.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2947 loggerSubsystemID = getSubsytemId(loggerSubsystemLink);
2949 info_.subsystems[loggerSubsystemID].id = loggerSubsystemID;
2951 const std::string& loggerSubsystemName =
2955 info_.subsystems[loggerSubsystemID].label = loggerSubsystemName;
2957 auto loggerSubsystemDestinationLink = loggerSubsystemLink.
getNode(
2958 colARTDAQSubsystem_.colLinkToDestination_);
2959 if(loggerSubsystemDestinationLink.isDisconnected())
2962 info_.subsystems[loggerSubsystemID].destination = 0;
2967 info_.subsystems[loggerSubsystemID].destination =
2968 getSubsytemId(loggerSubsystemDestinationLink);
2974 if(!info_.subsystems.count(
2975 info_.subsystems[loggerSubsystemID].destination) ||
2976 !info_.subsystems[info_.subsystems[loggerSubsystemID].destination]
2977 .sources.count(loggerSubsystemID))
2979 info_.subsystems[info_.subsystems[loggerSubsystemID].destination]
2980 .sources.insert(loggerSubsystemID);
2985 __COUT__ <<
"Found Data Logger with UID " << loggerUID
2986 <<
", DAQInterface Hostname " << loggerHost <<
", and Subsystem "
2987 << loggerSubsystemID << __E__;
2988 info_.processes[ARTDAQAppType::DataLogger].emplace_back(
2993 ARTDAQAppType::DataLogger,
2994 datalogger.second.status());
2999 ARTDAQAppType::DataLogger,
3000 maxFragmentSizeBytes);
3002 flattenFHICL(ARTDAQAppType::DataLogger, datalogger.second.getValue());
3007 __COUT__ <<
"Data Logger " << loggerUID <<
" is disabled." << __E__;
3013 __COUT_WARN__ <<
"There were no Data Loggers found!";
3018 void ARTDAQTableBase::extractDispatchersInfo(
ConfigurationTree artdaqSupervisorNode,
3019 bool getStatusFalseNodes,
3021 size_t maxFragmentSizeBytes)
3023 __COUT__ <<
"Checking for Dispatchers..." << __E__;
3024 info_.processes[ARTDAQAppType::Dispatcher].clear();
3027 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToDispatchers_);
3030 std::vector<std::pair<std::string, ConfigurationTree>> dispatchers =
3033 for(
auto& dispatcher : dispatchers)
3035 const std::string& dispatcherUID = dispatcher.first;
3037 if(getStatusFalseNodes || dispatcher.second.status())
3039 std::string dispatcherHost =
3040 dispatcher.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
3041 .getValueWithDefault(
"localhost");
3042 std::string dispatcherAP =
3044 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
3045 .getValueWithDefault(
"");
3046 int dispatcherPort =
3047 dispatcher.second.getNode(
"DispatcherPort").getValue<
int>();
3049 auto dispatcherSubsystemID = 1;
3051 dispatcher.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
3054 dispatcherSubsystemID = getSubsytemId(dispatcherSubsystemLink);
3056 info_.subsystems[dispatcherSubsystemID].id = dispatcherSubsystemID;
3058 const std::string& dispatcherSubsystemName =
3062 info_.subsystems[dispatcherSubsystemID].label =
3063 dispatcherSubsystemName;
3065 auto dispatcherSubsystemDestinationLink =
3066 dispatcherSubsystemLink.
getNode(
3067 colARTDAQSubsystem_.colLinkToDestination_);
3068 if(dispatcherSubsystemDestinationLink.isDisconnected())
3071 info_.subsystems[dispatcherSubsystemID].destination = 0;
3076 info_.subsystems[dispatcherSubsystemID].destination =
3077 getSubsytemId(dispatcherSubsystemDestinationLink);
3083 if(!info_.subsystems.count(
3084 info_.subsystems[dispatcherSubsystemID].destination) ||
3086 .subsystems[info_.subsystems[dispatcherSubsystemID]
3088 .sources.count(dispatcherSubsystemID))
3091 .subsystems[info_.subsystems[dispatcherSubsystemID]
3093 .sources.insert(dispatcherSubsystemID);
3097 __COUT__ <<
"Found Dispatcher with UID " << dispatcherUID
3098 <<
", DAQInterface Hostname " << dispatcherHost
3099 <<
", and Subsystem " << dispatcherSubsystemID << __E__;
3100 info_.processes[ARTDAQAppType::Dispatcher].emplace_back(
3104 dispatcherSubsystemID,
3105 ARTDAQAppType::Dispatcher,
3106 dispatcher.second.status(),
3112 ARTDAQAppType::Dispatcher,
3113 maxFragmentSizeBytes);
3115 flattenFHICL(ARTDAQAppType::Dispatcher, dispatcher.second.getValue());
3120 __COUT__ <<
"Dispatcher " << dispatcherUID <<
" is disabled." << __E__;
3126 __COUT_WARN__ <<
"There were no Dispatchers found!";
3136 for(
auto context : contexts)
3138 if(!context.second.isEnabled())
3141 auto apps = context.second
3142 .getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
3144 for(
auto app : apps)
3147 if(app.second.getNode(XDAQContextTable::colApplication_.colClass_)
3148 .getValue() == ARTDAQ_SUPERVISOR_CLASS &&
3149 app.second.isEnabled())
3167 std::map<std::string ,
3168 std::map<std::string , std::vector<std::string /*property*/>>>&
3169 nodeTypeToObjectMap,
3170 std::map<std::string /*subsystemName*/, std::string /*destinationSubsystemName*/>&
3172 std::vector<std::string /*property*/>& artdaqSupervisoInfo)
3174 __COUT__ <<
"getARTDAQSystem()" << __E__;
3176 artdaqSupervisoInfo.clear();
3187 return ARTDAQTableBase::info_;
3189 __COUTV__(artdaqContext->contextUID_);
3190 __COUTV__(artdaqContext->applications_.size());
3193 std::map<std::string , std::set<std::string >> nodeLayoutNames;
3195 const std::string& finalContextGroupName =
3196 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE);
3198 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE);
3199 const std::string& finalConfigGroupName = cfgMgr->getActiveGroupName(
3200 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
3201 const TableGroupKey& finalConfigGroupKey = cfgMgr->getActiveGroupKey(
3202 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
3207 std::stringstream layoutPath;
3208 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3209 << finalContextGroupName <<
"_" << finalContextGroupKey <<
"."
3210 << finalConfigGroupName <<
"_" << finalConfigGroupKey <<
".dat";
3212 fp = fopen(layoutPath.str().c_str(),
"r");
3215 __COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
3216 << finalContextGroupKey <<
") + " << finalConfigGroupName <<
"("
3217 << finalConfigGroupKey <<
")': " << layoutPath.
str() << __E__;
3221 __COUTV__(layoutPath.str());
3225 std::stringstream layoutPath;
3226 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3227 << finalContextGroupName <<
"_" << finalContextGroupKey <<
".dat";
3228 __COUTV__(layoutPath.str());
3230 fp = fopen(layoutPath.str().c_str(),
"r");
3233 __COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
3234 << finalContextGroupKey <<
")': " << layoutPath.str() << __E__;
3237 __COUTV__(layoutPath.str());
3243 struct dirent* entry;
3248 float bestScore = 0, score;
3249 std::string bestName =
"";
3251 if(!(pDIR = opendir((ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH).c_str())))
3253 __SS__ <<
"Path '" << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3254 <<
"' could not be opened!" << __E__;
3259 while((entry = readdir(pDIR)))
3261 name = std::string(entry->d_name);
3262 type = int(entry->d_type);
3264 __COUTS__(2) << type <<
" " << name <<
"\n" << std::endl;
3266 if(name[0] !=
'.' &&
3276 if(type == 0 || type == 10)
3279 DIR* pTmpDIR = opendir(
3280 (ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH +
"/" + name)
3288 __COUTS__(2) <<
"Unable to open path as directory: "
3289 << (ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH +
3301 __COUTS__(2) <<
"Directory: " << type <<
" " << name << __E__;
3305 __COUTS__(2) <<
"File: " << type <<
" " << name <<
"\n"
3307 if(name.find(
".dat") !=
3311 __COUTS__(2) <<
"Contender: " << name <<
"\n" << std::endl;
3316 if(nameSplit.size() > 1)
3319 auto keyi = nameSplit[1].rfind(
'_');
3320 if(keyi != std::string::npos)
3324 .substr(keyi, nameSplit[1].size() - 4 - keyi)
3328 finalConfigGroupKey.key() -
3334 __COUTVS__(2, tmpscore);
3338 __COUTVS__(2, tmpscore);
3341 std::string nameToCompare = nameSplit[1].substr(0, keyi);
3342 __COUTVS__(2, nameToCompare);
3343 size_t i = 0, j = 0;
3345 for(; i < nameToCompare.size() &&
3346 j < finalConfigGroupName.size();
3349 if(nameToCompare[i] == finalConfigGroupName[j])
3355 __COUTVS__(2, tmpscore);
3357 for(; i < nameToCompare.size() &&
3358 j < finalConfigGroupName.size();
3361 if(nameToCompare[i] == finalConfigGroupName[j])
3367 __COUTVS__(2, tmpscore);
3370 __COUTVS__(2, score);
3372 if(nameSplit.size() > 0)
3375 auto keyi = nameSplit[0].rfind(
'_');
3376 if(keyi != std::string::npos)
3380 .substr(keyi, nameSplit[0].size() - 4 - keyi)
3384 finalContextGroupKey.key() -
3390 __COUTVS__(2, tmpscore);
3394 __COUTVS__(2, tmpscore);
3397 std::string nameToCompare = nameSplit[0].substr(0, keyi);
3398 __COUTVS__(2, nameToCompare);
3399 size_t i = 0, j = 0;
3401 for(; i < nameToCompare.size() &&
3402 j < finalContextGroupName.size();
3405 if(nameToCompare[i] == finalContextGroupName[j])
3411 __COUTVS__(2, tmpscore);
3413 for(; i < nameToCompare.size() &&
3414 j < finalContextGroupName.size();
3417 if(nameToCompare[i] == finalContextGroupName[j])
3423 __COUTVS__(2, tmpscore);
3426 __COUTVS__(2, score);
3429 if(score > bestScore)
3433 __COUTVS__(2, bestName);
3441 __COUT__ <<
"Found closest layout file name: " << bestName <<
".dat"
3443 std::stringstream layoutPath;
3444 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << bestName
3446 __COUTV__(layoutPath.str());
3447 fp = fopen(layoutPath.str().c_str(),
"r");
3450 __COUT__ <<
"Closest layout file not found for '" << bestName <<
"'"
3460 __COUT__ <<
"Extract info from layout file.." << __E__;
3466 const size_t maxLineSz = 1000;
3467 char line[maxLineSz];
3468 if(!fgets(line, maxLineSz, fp))
3471 __COUT__ <<
"No layout naming info found." << __E__;
3477 char name[maxLineSz];
3478 char type[maxLineSz];
3480 while(fgets(line, maxLineSz, fp))
3483 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
3484 nodeLayoutNames[type].emplace(name);
3499 for(
auto& artdaqApp : artdaqContext->applications_)
3501 if(artdaqApp.class_ != ARTDAQ_SUPERVISOR_CLASS)
3504 __COUTV__(artdaqApp.applicationUID_);
3505 artdaqSupervisoInfo.push_back(artdaqApp.applicationUID_);
3506 artdaqSupervisoInfo.push_back(
3507 (artdaqContext->status_ && artdaqApp.status_) ?
"1" :
"0");
3508 artdaqSupervisoInfo.push_back(artdaqContext->address_);
3509 artdaqSupervisoInfo.push_back(std::to_string(artdaqContext->port_));
3512 XDAQContextTable::getSupervisorConfigNode(
3514 artdaqContext->contextUID_,
3515 artdaqApp.applicationUID_),
3518 __COUT__ <<
"========== "
3519 <<
"Found " << info.subsystems.size() <<
" subsystems." << __E__;
3522 for(
auto& subsystem : info.subsystems)
3523 subsystemObjectMap.emplace(std::make_pair(
3524 subsystem.second.label, std::to_string(subsystem.second.destination)));
3526 __COUT__ <<
"========== "
3527 <<
"Found " << info.processes.size() <<
" process types." << __E__;
3531 const std::string& typeString = nameTypePair.first;
3532 __COUTV__(typeString);
3534 nodeTypeToObjectMap.emplace(
3535 std::make_pair(typeString,
3536 std::map<std::string ,
3537 std::vector<std::string /*property*/>>()));
3539 auto it = info.processes.find(nameTypePair.second);
3540 if(it == info.processes.end())
3543 <<
"Found 0 " << typeString << __E__;
3547 <<
"Found " << it->second.size() <<
" " << typeString <<
"(s)"
3553 __SS__ <<
"Invalid artdaq node type '" << typeString <<
"' attempted!"
3557 __COUTV__(tableIt->second);
3560 std::stringstream ss;
3561 cfgMgr->getTableByName(tableIt->second)->getView().print(ss);
3562 __COUT_MULTI__(1, ss.str());
3572 const std::set<std::string > skipColumns(
3573 {ARTDAQ_TYPE_TABLE_HOSTNAME,
3574 ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS,
3575 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK,
3577 .colDaqFragmentIDs_,
3578 TableViewColumnInfo::COL_NAME_COMMENT,
3579 TableViewColumnInfo::COL_NAME_AUTHOR,
3580 TableViewColumnInfo::
3581 COL_NAME_CREATION});
3583 if(TTEST(1) && nodeLayoutNames.find(typeString) != nodeLayoutNames.end())
3589 for(
auto& artdaqNode : it->second)
3592 if(skipSet.find(StringMacros::encodeURIComponent(artdaqNode.label)) !=
3597 <<
"Found '" << artdaqNode.label <<
"' " << typeString << __E__;
3599 std::string nodeName = artdaqNode.label;
3600 bool status = artdaqNode.status;
3601 std::string hostname = artdaqNode.hostname;
3602 std::string subsystemId = std::to_string(artdaqNode.subsystem);
3603 std::string subsystemName =
3604 info.subsystems.at(artdaqNode.subsystem).label;
3615 std::vector<std::string> multiNodeNames, hostnameArray;
3620 StringMacros::encodeURIComponent(nodeName));
3622 __COUTV__(allNodes.size());
3623 for(
auto& otherNode : allNodes)
3625 if(skipSet.find(StringMacros::encodeURIComponent(otherNode.first)) !=
3627 otherNode.second.status() != status)
3631 if(nodeName.find(
"_clone") != std::string::npos ||
3632 otherNode.first.find(
"_clone") != std::string::npos)
3639 otherNode.second.getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID)
3648 auto otherNodeColumns = otherNode.second.getChildren();
3650 bool isMultiNode =
true;
3651 for(
unsigned int i = 0;
3652 i < thisNodeColumns.size() && i < otherNodeColumns.size();
3656 if(skipColumns.find(thisNodeColumns[i].first) !=
3657 skipColumns.end() ||
3658 thisNodeColumns[i].second.isLinkNode())
3669 if(thisNodeColumns[i].second.getValue() !=
3670 otherNodeColumns[i].second.getValue())
3672 __COUT__ <<
"Mismatch, not multi-node member." << __E__;
3673 isMultiNode =
false;
3680 __COUT__ <<
"Found '" << nodeName
3681 <<
"' multi-node member candidate '"
3682 << otherNode.first <<
"'" << __E__;
3685 if(!multiNodeNames.size())
3687 multiNodeNames.push_back(
3688 StringMacros::encodeURIComponent(nodeName));
3689 hostnameArray.push_back(
3690 StringMacros::encodeURIComponent(hostname));
3692 multiNodeNames.push_back(
3693 StringMacros::encodeURIComponent(otherNode.first));
3694 hostnameArray.push_back(StringMacros::encodeURIComponent(
3695 otherNode.second.getNode(ARTDAQ_TYPE_TABLE_HOSTNAME)
3698 __COUTV__(hostnameArray.back());
3700 StringMacros::encodeURIComponent(otherNode.first));
3705 unsigned int nodeFixedWildcardLength = 0, hostFixedWildcardLength = 0;
3706 std::string multiNodeString =
"", hostArrayString =
"";
3708 __COUTV__(nodeName);
3710 if(multiNodeNames.size() > 1)
3712 __COUT__ <<
"Handling multi-node printer syntax" << __E__;
3719 if(nodeLayoutNames.find(typeString) != nodeLayoutNames.end())
3727 std::string bestNodeLayoutName =
"";
3728 size_t bestNodeLayoutMatchCount =
3729 multiNodeNames.size() + 1;
3731 for(
const auto& layoutNameFull : nodeLayoutNames.at(typeString))
3733 __COUTTV__(layoutNameFull);
3734 size_t statusPos = layoutNameFull.find(
";status=");
3735 std::string layoutName = layoutNameFull.substr(0, statusPos);
3736 bool layoutStatus =
true;
3740 layoutStatus = status;
3742 layoutNameFull.substr(statusPos +
3743 std::string(
";status=").size()))
3744 layoutStatus =
false;
3746 __COUTTV__(layoutStatus);
3748 if(layoutStatus != status)
3750 __COUTT__ <<
"Status mismatch for template" << __E__;
3758 bool exactMatch =
true;
3760 for(
const auto& layoutSeg : layoutSplit)
3761 if((pos = nodeName.find(layoutSeg, pos)) ==
3764 __COUTT__ <<
"Did not find '" << layoutSeg <<
"' in '"
3765 << nodeName <<
"'" << __E__;
3770 __COUTTV__(exactMatch);
3773 size_t nodeLayoutMatchCount = 1;
3775 __COUT__ <<
"Found layout template name match! '"
3776 << layoutName <<
"' for node '" << nodeName
3777 <<
".' Trimming multinode candidates to match..."
3780 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3782 __COUTTV__(multiNodeNames[i]);
3783 std::string multiNodeName =
3786 __COUTTV__(multiNodeName);
3787 bool exactMatch =
true;
3789 for(
const auto& layoutSeg : layoutSplit)
3790 if((pos = multiNodeName.find(layoutSeg, pos)) ==
3793 __COUTT__ <<
"Did not find '" << layoutSeg
3794 <<
"' in '" << multiNodeName <<
"'"
3802 ++nodeLayoutMatchCount;
3803 __COUTT__ <<
"Found '" << layoutName <<
"' in '"
3804 << multiNodeName <<
"'" << __E__;
3809 __COUTTV__(nodeLayoutMatchCount);
3810 if(nodeLayoutMatchCount < bestNodeLayoutMatchCount)
3812 bestNodeLayoutName = layoutNameFull;
3813 bestNodeLayoutMatchCount = nodeLayoutMatchCount;
3814 __COUTTV__(bestNodeLayoutName);
3815 __COUTTV__(bestNodeLayoutMatchCount);
3820 __COUTV__(nodeName);
3826 if(bestNodeLayoutMatchCount > 0)
3828 __COUTV__(bestNodeLayoutName);
3829 std::string layoutNameFull = bestNodeLayoutName;
3830 __COUTTV__(layoutNameFull);
3831 size_t statusPos = layoutNameFull.find(
";status=");
3832 std::string layoutName = layoutNameFull.substr(0, statusPos);
3838 __COUT__ <<
"Found layout template name match! '"
3839 << layoutName <<
"' for node '" << nodeName
3840 <<
".' Trimming multinode candidates to match..."
3843 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3845 __COUTTV__(multiNodeNames[i]);
3846 std::string multiNodeName =
3848 __COUTTV__(multiNodeName);
3849 bool exactMatch =
true;
3851 for(
const auto& layoutSeg : layoutSplit)
3852 if((pos = multiNodeName.find(layoutSeg, pos)) ==
3855 __COUTT__ <<
"Did not find '" << layoutSeg
3856 <<
"' in '" << multiNodeName <<
"'"
3864 __COUT__ <<
"Trimming multinode candidate '"
3865 << multiNodeName <<
"'" << __E__;
3866 skipSet.erase(multiNodeNames[i]);
3867 multiNodeNames.erase(multiNodeNames.begin() + i);
3868 hostnameArray.erase(hostnameArray.begin() + i);
3875 __COUTV__(nodeName);
3880 std::vector<std::string>
3884 unsigned int maxScore = 0;
3886 unsigned int minScore = -1;
3887 std::vector<unsigned int> scoreVector;
3888 scoreVector.push_back(-1);
3889 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3893 __COUTS__(3) << multiNodeNames[0] <<
" vs "
3894 << multiNodeNames[i] << __E__;
3897 for(
unsigned int j = 0, k = 0; j < multiNodeNames[0].size() &&
3898 k < multiNodeNames[i].size();
3901 while(j < multiNodeNames[0].size() &&
3902 !(multiNodeNames[0][j] >=
'a' &&
3903 multiNodeNames[0][j] <=
'z') &&
3904 !(multiNodeNames[0][j] >=
'A' &&
3905 multiNodeNames[0][j] <=
'Z'))
3907 while(k < multiNodeNames[i].size() &&
3908 !(multiNodeNames[i][k] >=
'a' &&
3909 multiNodeNames[i][k] <=
'z') &&
3910 !(multiNodeNames[i][k] >=
'A' &&
3911 multiNodeNames[i][k] <=
'Z'))
3914 while(k < multiNodeNames[i].size() &&
3915 multiNodeNames[0][j] != multiNodeNames[i][k])
3919 << j <<
"-" << k <<
" of " << multiNodeNames[0].size()
3920 <<
"-" << multiNodeNames[i].size() << __E__;
3922 if(j < multiNodeNames[0].size() &&
3923 k < multiNodeNames[i].size())
3927 __COUTVS__(3, score);
3930 for(
unsigned int j = multiNodeNames[0].size() - 1,
3931 k = multiNodeNames[i].size() - 1;
3932 j < multiNodeNames[0].size() &&
3933 k < multiNodeNames[i].size();
3936 while(j < multiNodeNames[0].size() &&
3937 !(multiNodeNames[0][j] >=
'a' &&
3938 multiNodeNames[0][j] <=
'z') &&
3939 !(multiNodeNames[0][j] >=
'A' &&
3940 multiNodeNames[0][j] <=
'Z'))
3942 while(k < multiNodeNames[i].size() &&
3943 !(multiNodeNames[i][k] >=
'a' &&
3944 multiNodeNames[i][k] <=
'z') &&
3945 !(multiNodeNames[i][k] >=
'A' &&
3946 multiNodeNames[i][k] <=
'Z'))
3949 while(k < multiNodeNames[i].size() &&
3950 multiNodeNames[0][j] != multiNodeNames[i][k])
3953 __COUTS__(3) <<
"BACK" << j <<
"-" << k <<
" of "
3954 << multiNodeNames[0].size() <<
"-"
3955 << multiNodeNames[i].size() << __E__;
3957 if(j < multiNodeNames[0].size() &&
3958 k < multiNodeNames[i].size())
3962 __COUTVS__(3, score / 2.0);
3964 scoreVector.push_back(score);
3966 if(score > maxScore)
3971 if(score < minScore)
3978 __COUTVS__(2, minScore);
3979 __COUTVS__(2, maxScore);
3981 __COUT__ <<
"Trimming multi-node members with low match score..."
3986 for(
unsigned int i = multiNodeNames.size() - 1;
3987 i > 0 && i < multiNodeNames.size();
3992 if(maxScore > multiNodeNames[0].size() &&
3993 scoreVector[i] >= maxScore)
3997 __COUT__ <<
"Trimming low score match " << multiNodeNames[i]
3998 <<
" for node name " << nodeName << __E__;
4000 trimmedNodeNames.push_back(multiNodeNames[i]);
4001 skipSet.erase(multiNodeNames[i]);
4002 multiNodeNames.erase(multiNodeNames.begin() + i);
4003 hostnameArray.erase(hostnameArray.begin() + i);
4014 if(multiNodeNames.size() > 2)
4016 bool sameLengths =
true;
4017 size_t nameLen = multiNodeNames[0].size();
4018 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4019 if(multiNodeNames[i].size() != nameLen)
4021 sameLengths =
false;
4025 if(sameLengths && nameLen > 0)
4027 std::vector<bool> varies(nameLen,
false);
4028 for(
unsigned int pos = 0; pos < nameLen; ++pos)
4029 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4030 if(multiNodeNames[i][pos] != multiNodeNames[0][pos])
4038 unsigned int start, end;
4041 std::vector<VaryRun> runs;
4042 for(
unsigned int pos = 0; pos < nameLen;)
4049 unsigned int rStart = pos;
4050 bool runAllDigit =
true;
4051 while(pos < nameLen && varies[pos])
4053 for(
unsigned int i = 0;
4054 i < multiNodeNames.size() && runAllDigit;
4056 if(!(multiNodeNames[i][pos] >=
'0' &&
4057 multiNodeNames[i][pos] <=
'9'))
4058 runAllDigit =
false;
4061 runs.push_back({rStart, pos, runAllDigit});
4070 for(
auto& run : runs)
4074 while(run.start > 0)
4076 bool allDigitAtPrev =
true;
4077 for(
unsigned int i = 0;
4078 i < multiNodeNames.size() && allDigitAtPrev;
4080 if(!(multiNodeNames[i][run.start - 1] >=
'0' &&
4081 multiNodeNames[i][run.start - 1] <=
'9'))
4082 allDigitAtPrev =
false;
4089 unsigned int numDigitRuns = 0;
4090 for(
const auto& run : runs)
4094 if(numDigitRuns > 1 && numDigitRuns == runs.size())
4097 <<
"Numeric wildcard refinement: found "
4099 <<
" separate digit-varying groups in '" << nodeName
4100 <<
"'. Splitting to favor numeric-only wildcards."
4109 unsigned int bestRunToFix = 0;
4110 unsigned int fewestUnique = (
unsigned int)-1;
4111 unsigned int lowestHostCorr = (
unsigned int)-1;
4112 for(
unsigned int r = 0; r < runs.size(); ++r)
4114 std::set<std::string> uniqueVals;
4115 for(
unsigned int i = 0; i < multiNodeNames.size();
4117 uniqueVals.insert(multiNodeNames[i].substr(
4118 runs[r].start, runs[r].end - runs[r].start));
4122 std::map<std::string, std::set<std::string>>
4124 for(
unsigned int i = 0; i < multiNodeNames.size();
4127 std::string dv = multiNodeNames[i].substr(
4128 runs[r].start, runs[r].end - runs[r].start);
4129 valToHosts[dv].insert(hostnameArray[i]);
4134 unsigned int hostCorr = 0;
4135 if(valToHosts.size() > 1)
4138 std::set<std::string> allHostSets;
4139 for(
const auto& [dv, hosts] : valToHosts)
4141 std::string hostKey;
4142 for(
const auto& h : hosts)
4144 allHostSets.insert(hostKey);
4146 hostCorr = allHostSets.size();
4149 __COUTT__ <<
"Digit run " << r <<
" ["
4150 << runs[r].start <<
"-" << (runs[r].end - 1)
4151 <<
"]: uniqueVals=" << uniqueVals.size()
4152 <<
" hostCorr=" << hostCorr << __E__;
4158 if(uniqueVals.size() < fewestUnique ||
4159 (uniqueVals.size() == fewestUnique &&
4160 hostCorr < lowestHostCorr))
4162 fewestUnique = uniqueVals.size();
4163 lowestHostCorr = hostCorr;
4168 std::string keepVal = multiNodeNames[0].substr(
4169 runs[bestRunToFix].start,
4170 runs[bestRunToFix].end - runs[bestRunToFix].start);
4172 __COUTT__ <<
"Fixing digit group at positions "
4173 << runs[bestRunToFix].start <<
"-"
4174 << (runs[bestRunToFix].end - 1) <<
" to value '"
4176 <<
"' (fewest unique=" << fewestUnique <<
")"
4179 for(
unsigned int i = multiNodeNames.size() - 1;
4180 i > 0 && i < multiNodeNames.size();
4183 std::string val = multiNodeNames[i].substr(
4184 runs[bestRunToFix].start,
4185 runs[bestRunToFix].end -
4186 runs[bestRunToFix].start);
4189 __COUTT__ <<
"Numeric refinement trim: "
4190 << multiNodeNames[i]
4191 <<
" (digit group '" << val <<
"' != '"
4192 << keepVal <<
"')" << __E__;
4193 trimmedNodeNames.push_back(multiNodeNames[i]);
4194 skipSet.erase(multiNodeNames[i]);
4195 multiNodeNames.erase(multiNodeNames.begin() + i);
4196 hostnameArray.erase(hostnameArray.begin() + i);
4199 __COUT__ <<
"After numeric refinement: "
4200 << multiNodeNames.size() <<
" nodes remain for '"
4201 << nodeName <<
"'." << __E__;
4212 if(multiNodeNames.size() > 1)
4220 auto matchesCommonChunksPattern =
4221 [](
const std::string& name,
4222 const std::vector<std::string>& chunks,
4223 const std::vector<std::string>& wildcards) ->
bool {
4225 bool wildcardsAllNumeric = !wildcards.empty();
4226 for(
const auto& w : wildcards)
4229 w.find_first_not_of(
"0123456789") != std::string::npos)
4231 wildcardsAllNumeric =
false;
4237 for(
unsigned int c = 0; c < chunks.size(); ++c)
4239 if(chunks[c].empty())
4243 found = (name.size() >= chunks[c].size() &&
4245 0, chunks[c].size(), chunks[c]) == 0)
4247 : std::string::npos;
4250 found = name.find(chunks[c], pos);
4253 if(wildcardsAllNumeric && found != std::string::npos)
4255 std::string gap = name.substr(pos, found - pos);
4257 gap.find_first_not_of(
"0123456789") !=
4262 if(found == std::string::npos)
4264 pos = found + chunks[c].size();
4267 if(wildcardsAllNumeric && pos < name.size())
4269 std::string trailingGap = name.substr(pos);
4270 if(trailingGap.find_first_not_of(
"0123456789") !=
4277 bool collisionRetry =
true;
4278 while(collisionRetry && multiNodeNames.size() > 1)
4280 collisionRetry =
false;
4283 std::vector<std::string> trialCommonChunks;
4284 std::vector<std::string> trialWildcards;
4285 unsigned int trialFixedLen = 0;
4291 __COUT__ <<
"Collision check: trialCommonChunks = "
4296 bool collisionFound =
false;
4297 for(
const auto& trimmedNode : trimmedNodeNames)
4299 if(matchesCommonChunksPattern(
4300 trimmedNode, trialCommonChunks, trialWildcards))
4302 __COUT__ <<
"Collision detected: trimmed node '"
4304 <<
"' matches base pattern from commonChunks"
4306 collisionFound =
true;
4316 std::string currentStatusStr = status ?
"1" :
"0";
4317 for(
const auto& existingEntry :
4318 nodeTypeToObjectMap.at(typeString))
4320 std::string existingBaseName = existingEntry.first;
4321 size_t statusPos = existingBaseName.find(
";status=");
4322 if(statusPos != std::string::npos)
4325 if(existingBaseName.substr(
4327 std::string(
";status=").size()) !=
4331 existingBaseName.substr(0, statusPos);
4334 if(matchesCommonChunksPattern(existingBaseName,
4344 std::string existingGap;
4345 if(trialCommonChunks.size() == 1 &&
4346 existingBaseName.size() >
4347 trialCommonChunks[0].size())
4348 existingGap = existingBaseName.substr(
4349 trialCommonChunks[0].size());
4350 else if(trialCommonChunks.size() >= 2)
4352 size_t suffixLen = 0;
4354 ci < trialCommonChunks.size();
4356 suffixLen += trialCommonChunks[ci].size();
4357 if(existingBaseName.size() >
4358 trialCommonChunks[0].size() + suffixLen)
4359 existingGap = existingBaseName.substr(
4360 trialCommonChunks[0].size(),
4361 existingBaseName.size() -
4362 trialCommonChunks[0].size() -
4366 if(!existingGap.empty())
4368 bool gapInWildcards =
false;
4369 for(
const auto& w : trialWildcards)
4370 if(w == existingGap)
4372 gapInWildcards =
true;
4378 <<
"Existing entry '"
4379 << existingEntry.first
4380 <<
"' matches pattern but gap '"
4382 <<
"' is not in multinode wildcards"
4383 " - not a collision"
4390 <<
"Collision detected: existing map entry '"
4391 << existingEntry.first
4392 <<
"' matches base pattern from commonChunks"
4394 collisionFound =
true;
4404 __COUT__ <<
"Re-scoring remaining multi-node members with "
4405 "full character matching to resolve collision..."
4408 unsigned int fullMaxScore = 0;
4409 std::vector<unsigned int> fullScoreVector;
4410 fullScoreVector.push_back(-1);
4412 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4414 unsigned int fscore = 0;
4416 for(
unsigned int j = 0; j < multiNodeNames[0].size() &&
4417 j < multiNodeNames[i].size();
4420 if(multiNodeNames[0][j] == multiNodeNames[i][j])
4425 fullScoreVector.push_back(fscore);
4426 if(fscore > fullMaxScore)
4427 fullMaxScore = fscore;
4430 __COUT__ <<
"Full char rescore: maxScore = " << fullMaxScore
4434 bool anyTrimmed =
false;
4435 for(
unsigned int i = multiNodeNames.size() - 1;
4436 i > 0 && i < multiNodeNames.size();
4439 if(fullScoreVector[i] >= fullMaxScore)
4442 __COUT__ <<
"Collision trim: removing "
4443 << multiNodeNames[i] <<
" (score "
4444 << fullScoreVector[i] <<
" < " << fullMaxScore
4445 <<
") for node name " << nodeName << __E__;
4447 trimmedNodeNames.push_back(multiNodeNames[i]);
4448 skipSet.erase(multiNodeNames[i]);
4449 multiNodeNames.erase(multiNodeNames.begin() + i);
4450 hostnameArray.erase(hostnameArray.begin() + i);
4452 collisionRetry =
true;
4460 __COUT__ <<
"Cannot narrow multi-node group further to "
4461 "resolve collision. Abandoning multi-node "
4464 <<
"' - remaining members will be "
4465 "processed individually."
4469 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4470 skipSet.erase(multiNodeNames[i]);
4471 multiNodeNames.resize(1);
4472 hostnameArray.resize(1);
4477 __COUT__ <<
"After collision resolution:" << __E__;
4478 __COUTV__(nodeName);
4484 __COUTV__(nodeName);
4491 __COUT__ <<
"Reorganizing multinode '" << nodeName
4492 <<
"' alphabetically..." << __E__;
4494 std::pair<std::string , std::string >>
4496 for(
unsigned int i = 0; i < multiNodeNames.size(); ++i)
4498 std::make_pair(multiNodeNames[i], hostnameArray[i]));
4503 multiNodeNames.clear();
4504 hostnameArray.clear();
4505 for(
const auto& orderedPair : reorderSet)
4507 multiNodeNames.push_back(orderedPair.first);
4508 hostnameArray.push_back(orderedPair.second);
4512 __COUTV__(nodeName);
4517 auto expandNumericWildcards =
4518 [](std::vector<std::string>& commonChunks,
4519 std::vector<std::string>& wildcards,
4520 const std::string& logPrefix) {
4521 bool allDigitWC =
true;
4522 for(
const auto& wc : wildcards)
4524 if(wc.empty() || wc.find_first_not_of(
"0123456789") !=
4531 if(allDigitWC && !commonChunks.empty() &&
4532 !commonChunks[0].empty())
4534 size_t trailingDigits = 0;
4535 for(
int ci = (
int)commonChunks[0].size() - 1; ci >= 0;
4538 if(commonChunks[0][ci] >=
'0' &&
4539 commonChunks[0][ci] <=
'9')
4544 if(trailingDigits > 0 &&
4545 trailingDigits < commonChunks[0].size())
4547 std::string prefix = commonChunks[0].substr(
4548 commonChunks[0].size() - trailingDigits);
4549 commonChunks[0] = commonChunks[0].substr(
4550 0, commonChunks[0].size() - trailingDigits);
4551 for(
auto& wc : wildcards)
4555 << logPrefix <<
"moved '" << prefix
4556 <<
"' from commonChunk prefix into wildcards."
4563 if(multiNodeNames.size() > 1)
4565 std::vector<std::string> commonChunks;
4566 std::vector<std::string> wildcards;
4570 bool wildcardsNeeded =
4574 nodeFixedWildcardLength);
4576 if(!wildcardsNeeded || wildcards.size() != multiNodeNames.size())
4579 <<
"Impossible extractCommonChunks result! Please notify "
4580 "admins or try to simplify record naming convention."
4592 expandNumericWildcards(
4593 commonChunks, wildcards,
"Expanded numeric wildcards: ");
4599 for(
auto& commonChunk : commonChunks)
4601 nodeName += (!first ?
"*" :
"") + commonChunk;
4605 if(commonChunks.size() == 1)
4608 __COUTV__(nodeName);
4615 bool allIntegers =
true;
4616 for(
auto& wildcard : wildcards)
4619 else if(wildcard.size() == 0)
4621 allIntegers =
false;
4625 for(
unsigned int i = 0; i < wildcard.size(); ++i)
4626 if(!(wildcard[i] >=
'0' && wildcard[i] <=
'9'))
4628 allIntegers =
false;
4632 __COUTV__(allIntegers);
4638 std::vector<unsigned int> intWildcards;
4639 for(
auto& wildcard : wildcards)
4640 intWildcards.push_back(strtol(wildcard.c_str(), 0, 10));
4644 unsigned int hyphenLo = -1;
4645 bool isFirst =
true;
4646 for(
unsigned int i = 0; i < intWildcards.size(); ++i)
4648 if(i + 1 < intWildcards.size() &&
4649 intWildcards[i] + 1 == intWildcards[i + 1])
4661 (isFirst ?
"" :
",") +
4662 std::to_string(intWildcards[i]);
4667 if(intWildcards[hyphenLo] + 1 == intWildcards[i])
4669 (isFirst ?
"" :
",") +
4670 std::to_string(intWildcards[hyphenLo]) +
4671 "," + std::to_string(intWildcards[i]);
4674 (isFirst ?
"" :
",") +
4675 std::to_string(intWildcards[hyphenLo]) +
4676 "-" + std::to_string(intWildcards[i]);
4686 nodeFixedWildcardLength =
4690 __COUTV__(multiNodeString);
4691 __COUTV__(nodeFixedWildcardLength);
4694 if(hostnameArray.size() > 1)
4696 std::vector<std::string> commonChunks;
4697 std::vector<std::string> wildcards;
4701 bool wildcardsNeeded =
4705 hostFixedWildcardLength);
4707 __COUTV__(wildcardsNeeded);
4719 expandNumericWildcards(
4722 "Expanded numeric wildcards for hostname: ");
4728 for(
auto& commonChunk : commonChunks)
4730 hostname += (!first ?
"*" :
"") + commonChunk;
4734 if(wildcardsNeeded && commonChunks.size() == 1)
4737 __COUTV__(hostname);
4747 bool allIntegers =
true;
4748 for(
auto& wildcard : wildcards)
4749 for(
unsigned int i = 0; i < wildcard.size(); ++i)
4750 if(!(wildcard[i] >=
'0' && wildcard[i] <=
'9'))
4752 allIntegers =
false;
4756 __COUTV__(allIntegers);
4763 std::vector<unsigned int> intWildcards;
4764 for(
auto& wildcard : wildcards)
4765 intWildcards.push_back(
4766 strtol(wildcard.c_str(), 0, 10));
4770 unsigned int hyphenLo = -1;
4771 bool isFirst =
true;
4772 for(
unsigned int i = 0; i < intWildcards.size(); ++i)
4774 if(i + 1 < intWildcards.size() &&
4775 intWildcards[i] + 1 == intWildcards[i + 1])
4787 (isFirst ?
"" :
",") +
4788 std::to_string(intWildcards[i]);
4793 if(intWildcards[hyphenLo] + 1 ==
4796 (isFirst ?
"" :
",") +
4798 intWildcards[hyphenLo]) +
4799 "," + std::to_string(intWildcards[i]);
4802 (isFirst ?
"" :
",") +
4804 intWildcards[hyphenLo]) +
4805 "-" + std::to_string(intWildcards[i]);
4815 hostFixedWildcardLength =
4819 __COUTV__(hostArrayString);
4820 __COUTV__(hostFixedWildcardLength);
4830 auto result = nodeTypeToObjectMap.at(typeString)
4831 .emplace(std::make_pair(
4832 nodeName, std::vector<std::string /*property*/>()));
4836 __SS__ <<
"Here is the current nodeTypeToObjectMap:" << __E__;
4837 for(
const auto& typePair : nodeTypeToObjectMap)
4839 ss <<
"\tType: " << typePair.first << __E__;
4840 for(
const auto& nodePair : typePair.second)
4842 ss <<
"\t\tNode: " << nodePair.first << __E__;
4843 for(
const auto& property : nodePair.second)
4844 ss <<
"\t\t\tProperty: " <<
property << __E__;
4847 __COUT__ << ss.str() << __E__;
4853 <<
"Collision detected for node '" << nodeName <<
"' of type '"
4855 <<
"' when inserting into nodeTypeToObjectMap. This likely means "
4856 "that two nodes have the same name and status, and if so, "
4857 "they would be indistinguishable in printer syntax. "
4858 <<
"Please notify admins or try to simplify record naming "
4862 __SS__ <<
"Impossible printer syntax handling result! Collision of "
4863 "base names. Please notify "
4864 "admins or try to simplify record naming convention."
4869 nodeTypeToObjectMap.at(typeString)
4871 .push_back(status ?
"1" :
"0");
4873 nodeTypeToObjectMap.at(typeString).at(nodeName).push_back(hostname);
4875 nodeTypeToObjectMap.at(typeString).at(nodeName).push_back(subsystemId);
4876 if(multiNodeNames.size() > 1)
4878 nodeTypeToObjectMap.at(typeString)
4880 .push_back(multiNodeString);
4882 nodeTypeToObjectMap.at(typeString)
4884 .push_back(std::to_string(nodeFixedWildcardLength));
4886 if(hostnameArray.size() > 1)
4888 nodeTypeToObjectMap.at(typeString)
4890 .push_back(hostArrayString);
4892 nodeTypeToObjectMap.at(typeString)
4894 .push_back(std::to_string(hostFixedWildcardLength));
4898 __COUTV__(multiNodeString);
4900 __COUTV__(hostArrayString);
4901 __COUT__ <<
"Done with extraction of node '" << nodeName <<
"'" << __E__;
4907 __COUT__ <<
"Done getting artdaq nodes." << __E__;
4909 return ARTDAQTableBase::info_;
4923 const std::map<std::string ,
4924 std::map<std::string ,
4925 std::vector<std::string /*property*/>>>& nodeTypeToObjectMap,
4926 const std::map<std::string ,
4927 std::string >& subsystemObjectMap)
4929 __COUT__ <<
"setAndActivateARTDAQSystem()" << __E__;
4931 const std::string& author = cfgMgr->
getUsername();
4942 GroupEditStruct configGroupEdit(ConfigurationManager::GroupType::CONFIGURATION_TYPE,
4945 unsigned int artdaqSupervisorRow = TableView::INVALID;
4952 bool needArtdaqSupervisorParents =
true;
4953 bool needArtdaqSupervisorCreation =
false;
4955 __COUTV__(artdaqContext);
4960 const std::string& activeContextGroupName =
4961 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE);
4963 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE);
4964 const std::string& activeConfigGroupName = cfgMgr->getActiveGroupName(
4965 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
4966 const TableGroupKey& activeConfigGroupKey = cfgMgr->getActiveGroupKey(
4967 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
4969 __COUTV__(activeContextGroupName);
4970 __COUTV__(activeContextGroupKey);
4971 __COUTV__(activeConfigGroupName);
4972 __COUTV__(activeConfigGroupKey);
4973 __COUTV__(cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
4974 .
getNode(artdaqContext->contextUID_)
4977 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
4978 .
getNode(artdaqContext->contextUID_)
4979 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
4982 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
4983 .
getNode(artdaqContext->contextUID_)
4984 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
4985 .
getNode(artdaqContext->applications_[0].applicationUID_)
4987 __COUTV__(artdaqContext->applications_[0].applicationUID_);
4988 __COUTV__(XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
4990 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
4991 .
getNode(artdaqContext->contextUID_)
4992 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
4993 .
getNode(artdaqContext->applications_[0].applicationUID_)
4994 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_)
4998 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
4999 .
getNode(artdaqContext->contextUID_)
5000 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5001 .
getNode(artdaqContext->applications_[0].applicationUID_)
5002 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
5007 needArtdaqSupervisorCreation =
true;
5009 artdaqSupervisorRow = artdaqSupervisorNode.
getRow();
5011 needArtdaqSupervisorParents =
false;
5015 needArtdaqSupervisorCreation =
true;
5017 __COUTV__(needArtdaqSupervisorCreation);
5020 if(!artdaqContext || needArtdaqSupervisorCreation)
5022 __COUT__ <<
"No artdaq Supervisor found! Creating..." << __E__;
5023 __COUTV__(needArtdaqSupervisorParents);
5025 std::string artdaqSupervisorUID;
5034 ARTDAQ_SUPERVISOR_TABLE,
true );
5038 std::stringstream ss;
5039 artdaqSupervisorTable.tableView_->print(ss);
5040 __COUT_MULTI__(0, ss.str());
5044 row = artdaqSupervisorTable.tableView_->
addRow(
5045 author,
true ,
"artdaqSupervisor");
5048 artdaqSupervisorUID =
5049 artdaqSupervisorTable.tableView_
5050 ->getDataView()[row][artdaqSupervisorTable.tableView_->
getColUID()];
5051 artdaqSupervisorRow = row;
5053 __COUTV__(artdaqSupervisorRow);
5054 __COUTV__(artdaqSupervisorUID);
5060 artdaqSupervisorTable.tableView_->
findCol(
5061 colARTDAQSupervisor_.colDAQInterfaceDebugLevel_));
5064 "${MRB_BUILDDIR}/../setup_ots.sh",
5066 artdaqSupervisorTable.tableView_->
findCol(
5067 colARTDAQSupervisor_.colDAQSetupScript_));
5071 ARTDAQ_READER_TABLE,
5073 artdaqSupervisorTable.tableView_->
findCol(
5074 colARTDAQSupervisor_.colLinkToBoardReaders_));
5078 artdaqSupervisorTable.tableView_->
findCol(
5079 colARTDAQSupervisor_.colLinkToBoardReadersGroupID_),
5080 artdaqSupervisorUID +
5084 ARTDAQ_BUILDER_TABLE,
5086 artdaqSupervisorTable.tableView_->
findCol(
5087 colARTDAQSupervisor_.colLinkToEventBuilders_));
5090 artdaqSupervisorTable.tableView_->
findCol(
5091 colARTDAQSupervisor_.colLinkToEventBuildersGroupID_),
5092 artdaqSupervisorUID +
5096 ARTDAQ_LOGGER_TABLE,
5098 artdaqSupervisorTable.tableView_->
findCol(
5099 colARTDAQSupervisor_.colLinkToDataLoggers_));
5102 artdaqSupervisorTable.tableView_->
findCol(
5103 colARTDAQSupervisor_.colLinkToDataLoggersGroupID_),
5104 artdaqSupervisorUID +
5108 ARTDAQ_DISPATCHER_TABLE,
5110 artdaqSupervisorTable.tableView_->
findCol(
5111 colARTDAQSupervisor_.colLinkToDispatchers_));
5114 artdaqSupervisorTable.tableView_->
findCol(
5115 colARTDAQSupervisor_.colLinkToDispatchersGroupID_),
5116 artdaqSupervisorUID +
5121 ARTDAQ_ROUTER_TABLE,
5123 artdaqSupervisorTable.tableView_->
findCol(
5124 colARTDAQSupervisor_.colLinkToRoutingManagers_));
5127 artdaqSupervisorTable.tableView_->
findCol(
5128 colARTDAQSupervisor_.colLinkToRoutingManagersGroupID_),
5129 artdaqSupervisorUID +
5134 std::stringstream ss;
5135 artdaqSupervisorTable.tableView_->print(ss);
5136 __COUT_MULTI__(0, ss.str());
5143 ConfigurationManager::GroupType::CONTEXT_TYPE, cfgMgr);
5146 ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME,
true );
5148 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME,
true );
5150 ConfigurationManager::XDAQ_APP_PROPERTY_TABLE_NAME,
5157 std::string contextUID;
5158 std::string contextAppGroupID;
5160 if(needArtdaqSupervisorParents)
5163 row = contextTable.tableView_->
addRow(
5164 author,
true ,
"artdaqContext");
5170 contextTable.tableView_
5171 ->getDataView()[row][contextTable.tableView_->
getColUID()];
5174 __COUTV__(contextUID);
5178 "http://${HOSTNAME}",
5180 contextTable.tableView_->
findCol(
5181 XDAQContextTable::colContext_.colAddress_));
5184 contextTable.tableView_->
findCol(
5185 XDAQContextTable::colContext_.colPort_),
5191 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME,
5193 contextTable.tableView_->
findCol(
5194 XDAQContextTable::colContext_.colLinkToApplicationTable_));
5197 contextTable.tableView_->
findCol(
5198 XDAQContextTable::colContext_.colLinkToApplicationGroupID_),
5199 "artdaqContextApps");
5201 __COUTV__(contextAppGroupID);
5205 std::string appPropertiesGroupID;
5211 if(needArtdaqSupervisorParents)
5215 unsigned int c = appTable.tableView_->
findCol(
5216 XDAQContextTable::colApplication_.colClass_);
5217 for(
unsigned int r = 0;
5218 r < appTable.tableView_->getNumberOfRows();
5220 if(appTable.tableView_->getDataView()[r][c] ==
5221 ARTDAQ_SUPERVISOR_CLASS)
5224 <<
"Found partially existing artdaq Supervisor "
5226 << appTable.tableView_->getDataView()
5228 <<
"'... Disabling it." << __E__;
5235 row = appTable.tableView_->
addRow(
5236 author,
true ,
"artdaqSupervisor");
5243 ->getDataView()[row][appTable.tableView_->
getColUID()];
5250 ARTDAQ_SUPERVISOR_CLASS,
5253 XDAQContextTable::colApplication_.colClass_));
5256 "${OTSDAQ_LIB}/libARTDAQSupervisor.so",
5259 XDAQContextTable::colApplication_.colModule_));
5264 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5265 .colApplicationGroupID_));
5269 ConfigurationManager::XDAQ_APP_PROPERTY_TABLE_NAME,
5271 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5272 .colLinkToPropertyTable_));
5275 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5276 .colLinkToPropertyGroupID_),
5277 appUID +
"Properties");
5279 __COUTV__(appPropertiesGroupID);
5283 __COUT__ <<
"Getting row of existing parent supervisor." << __E__;
5287 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5288 .
getNode(artdaqContext->contextUID_)
5289 .
getNode(XDAQContextTable::colContext_
5290 .colLinkToApplicationTable_)
5291 .
getNode(artdaqContext->applications_[0].applicationUID_)
5300 ARTDAQ_SUPERVISOR_TABLE,
5303 XDAQContextTable::colApplication_.colLinkToSupervisorTable_));
5305 artdaqSupervisorUID,
5308 XDAQContextTable::colApplication_.colLinkToSupervisorUID_));
5313 if(needArtdaqSupervisorParents)
5317 const std::vector<std::string> propertyUIDs = {
"Partition0",
5320 "BoardReaderTimeout",
5321 "EventBuilderTimeout",
5322 "DataLoggerTimeout",
5323 "DispatcherTimeout"};
5324 const std::vector<std::string> propertyNames = {
5326 "productsdir_for_bash_scripts",
5327 "max_fragment_size_bytes",
5328 "boardreader_timeout",
5329 "eventbuilder_timeout",
5330 "datalogger_timeout",
5331 "dispatcher_timeout"
5333 const std::vector<std::string> propertyValues = {
5343 for(
unsigned int i = 0; i < propertyNames.size(); ++i)
5346 row = appPropertyTable.tableView_->
addRow(
5349 appUID + propertyUIDs[i]);
5352 "1", row, appPropertyTable.tableView_->
getColStatus());
5356 "ots::SupervisorProperty",
5358 appPropertyTable.tableView_->
findCol(
5359 XDAQContextTable::colAppProperty_.colPropertyType_));
5364 appPropertyTable.tableView_->
findCol(
5365 XDAQContextTable::colAppProperty_.colPropertyName_));
5370 appPropertyTable.tableView_->
findCol(
5371 XDAQContextTable::colAppProperty_.colPropertyValue_));
5374 appPropertiesGroupID,
5376 appPropertyTable.tableView_->
findCol(
5377 XDAQContextTable::colAppProperty_.colPropertyGroupID_));
5382 std::stringstream ss;
5383 contextTable.tableView_->print(ss);
5384 __COUT_MULTI__(0, ss.str());
5387 std::stringstream ss;
5388 appTable.tableView_->print(ss);
5389 __COUT_MULTI__(0, ss.str());
5392 std::stringstream ss;
5393 appPropertyTable.tableView_->print(ss);
5394 __COUT_MULTI__(0, ss.str());
5397 contextTable.tableView_
5399 appTable.tableView_->
init();
5400 appPropertyTable.tableView_
5406 <<
"Table errors while creating ARTDAQ Supervisor. Erasing all newly "
5407 "created table versions."
5412 __COUT_INFO__ <<
"Edits complete for new artdaq Supervisor! Created '"
5413 << appUID <<
"'" << __E__;
5417 __SS__ <<
"DEBUG blocking artdaq supervisor save!" << __E__;
5421 contextGroupEdit.saveChanges(contextGroupEdit.originalGroupName_,
5433 artdaqSupervisorRow =
5434 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5435 .
getNode(artdaqContext->contextUID_)
5436 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5437 .
getNode(artdaqContext->applications_[0].applicationUID_)
5438 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_)
5442 __COUT__ <<
"------------------------- artdaq nodes to save:" << __E__;
5443 for(
auto& subsystemPair : subsystemObjectMap)
5445 __COUTV__(subsystemPair.first);
5449 for(
auto& nodeTypePair : nodeTypeToObjectMap)
5451 __COUTV__(nodeTypePair.first);
5453 for(
auto& nodePair : nodeTypePair.second)
5455 __COUTV__(nodePair.first);
5459 __COUT__ <<
"------------------------- end artdaq nodes to save." << __E__;
5463 __COUTV__(artdaqSupervisorRow);
5464 if(artdaqSupervisorRow >= TableView::INVALID)
5466 __SS__ <<
"Invalid artdaq Supervisor row " << artdaqSupervisorRow <<
" found!"
5481 ARTDAQ_SUPERVISOR_TABLE,
true );
5485 std::string artdaqSupervisorUID =
5486 artdaqSupervisorTable.tableView_
5487 ->getDataView()[artdaqSupervisorRow]
5488 [artdaqSupervisorTable.tableView_->
getColUID()];
5491 if(artdaqSupervisorTable.tableView_
5492 ->getDataView()[artdaqSupervisorRow]
5493 [artdaqSupervisorTable.tableView_->
findCol(
5494 colARTDAQSupervisor_.colLinkToBoardReaders_)] ==
5495 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5497 __COUT__ <<
"Fixing missing link to Readers" << __E__;
5499 ARTDAQ_READER_TABLE,
5500 artdaqSupervisorRow,
5501 artdaqSupervisorTable.tableView_->
findCol(
5502 colARTDAQSupervisor_.colLinkToBoardReaders_));
5504 artdaqSupervisorRow,
5505 artdaqSupervisorTable.tableView_->
findCol(
5506 colARTDAQSupervisor_.colLinkToBoardReadersGroupID_),
5507 artdaqSupervisorUID +
5512 if(artdaqSupervisorTable.tableView_
5513 ->getDataView()[artdaqSupervisorRow]
5514 [artdaqSupervisorTable.tableView_->
findCol(
5515 colARTDAQSupervisor_.colLinkToEventBuilders_)] ==
5516 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5518 __COUT__ <<
"Fixing missing link to Builders" << __E__;
5520 ARTDAQ_BUILDER_TABLE,
5521 artdaqSupervisorRow,
5522 artdaqSupervisorTable.tableView_->
findCol(
5523 colARTDAQSupervisor_.colLinkToEventBuilders_));
5525 artdaqSupervisorRow,
5526 artdaqSupervisorTable.tableView_->
findCol(
5527 colARTDAQSupervisor_.colLinkToEventBuildersGroupID_),
5528 artdaqSupervisorUID +
5533 if(artdaqSupervisorTable.tableView_
5534 ->getDataView()[artdaqSupervisorRow]
5535 [artdaqSupervisorTable.tableView_->
findCol(
5536 colARTDAQSupervisor_.colLinkToDataLoggers_)] ==
5537 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5539 __COUT__ <<
"Fixing missing link to Loggers" << __E__;
5541 ARTDAQ_LOGGER_TABLE,
5542 artdaqSupervisorRow,
5543 artdaqSupervisorTable.tableView_->
findCol(
5544 colARTDAQSupervisor_.colLinkToDataLoggers_));
5546 artdaqSupervisorRow,
5547 artdaqSupervisorTable.tableView_->
findCol(
5548 colARTDAQSupervisor_.colLinkToDataLoggersGroupID_),
5549 artdaqSupervisorUID +
5554 if(artdaqSupervisorTable.tableView_
5555 ->getDataView()[artdaqSupervisorRow]
5556 [artdaqSupervisorTable.tableView_->
findCol(
5557 colARTDAQSupervisor_.colLinkToDispatchers_)] ==
5558 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5560 __COUT__ <<
"Fixing missing link to Dispatchers" << __E__;
5562 ARTDAQ_DISPATCHER_TABLE,
5563 artdaqSupervisorRow,
5564 artdaqSupervisorTable.tableView_->
findCol(
5565 colARTDAQSupervisor_.colLinkToDispatchers_));
5567 artdaqSupervisorRow,
5568 artdaqSupervisorTable.tableView_->
findCol(
5569 colARTDAQSupervisor_.colLinkToDispatchersGroupID_),
5570 artdaqSupervisorUID +
5575 if(artdaqSupervisorTable.tableView_
5576 ->getDataView()[artdaqSupervisorRow]
5577 [artdaqSupervisorTable.tableView_->
findCol(
5578 colARTDAQSupervisor_.colLinkToRoutingManagers_)] ==
5579 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5581 __COUT__ <<
"Fixing missing link to Routers" << __E__;
5583 ARTDAQ_ROUTER_TABLE,
5584 artdaqSupervisorRow,
5585 artdaqSupervisorTable.tableView_->
findCol(
5586 colARTDAQSupervisor_.colLinkToRoutingManagers_));
5588 artdaqSupervisorRow,
5589 artdaqSupervisorTable.tableView_->
findCol(
5590 colARTDAQSupervisor_.colLinkToRoutingManagersGroupID_),
5591 artdaqSupervisorUID +
5596 std::stringstream ss;
5597 artdaqSupervisorTable.tableView_->print(ss);
5598 __COUT_MULTI__(0, ss.str());
5604 ARTDAQ_SUBSYSTEM_TABLE,
true );
5607 artdaqSubsystemTable.tableView_->deleteAllRows();
5609 for(
auto& subsystemPair : subsystemObjectMap)
5611 __COUTV__(subsystemPair.first);
5612 __COUTV__(subsystemPair.second);
5615 row = artdaqSubsystemTable.tableView_->
addRow(
5616 author,
true , subsystemPair.first);
5618 if(subsystemPair.second !=
"" &&
5619 subsystemPair.second != TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
5620 subsystemPair.second != TableViewColumnInfo::DATATYPE_STRING_ALT_DEFAULT &&
5621 subsystemPair.second != NULL_SUBSYSTEM_DESTINATION_LABEL)
5625 ARTDAQ_SUBSYSTEM_TABLE,
5627 artdaqSubsystemTable.tableView_->
findCol(
5628 colARTDAQSubsystem_.colLinkToDestination_));
5630 subsystemPair.second,
5632 artdaqSubsystemTable.tableView_->
findCol(
5633 colARTDAQSubsystem_.colLinkToDestinationUID_));
5640 for(
auto& nodeTypePair : nodeTypeToObjectMap)
5642 __COUTV__(nodeTypePair.first);
5646 auto it =
processTypes_.mapToTable_.find(nodeTypePair.first);
5649 __SS__ <<
"Invalid artdaq node type '" << nodeTypePair.first
5650 <<
"' attempted!" << __E__;
5653 __COUTV__(it->second);
5663 if(nodeTypePair.second.size())
5666 __COUT__ <<
"Ignoring missing table '" << it->second
5667 <<
"' since there were no user records attempted of type '"
5668 << nodeTypePair.first <<
".'" << __E__;
5675 bool hasArtProcessName =
false;
5676 unsigned int artProcessNameCol = -1;
5680 __COUT__ <<
"Identified non-Reader, no-Router type '"
5681 << nodeTypePair.first
5682 <<
"' that has an art link and thus Process Name, so creating "
5683 "table edit structure to ART table."
5686 ARTDAQTableBase::ARTDAQ_ART_TABLE,
true );
5689 std::stringstream ss;
5690 artTable->tableView_->print(ss);
5691 __COUT_MULTI__(1, ss.str());
5693 artProcessNameCol = artTable->tableView_->
findCol(
5694 ARTDAQTableBase::colARTDAQArt_.colProcessName_);
5695 __COUTTV__(artProcessNameCol);
5697 hasArtProcessName =
true;
5699 __COUTV__(hasArtProcessName);
5701 const unsigned int commentCol =
5702 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_COMMENT);
5703 const unsigned int authorCol =
5704 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_AUTHOR);
5705 const unsigned int timestampCol =
5706 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
5709 std::map<
unsigned int ,
bool > deleteRecordMap;
5710 unsigned int maxRowToDelete = typeTable.tableView_->getNumberOfRows();
5711 for(
unsigned int r = 0; r < typeTable.tableView_->getNumberOfRows(); ++r)
5712 deleteRecordMap.emplace(std::make_pair(
5715 __COUTTV__(maxRowToDelete);
5721 const unsigned int ORIG_MAP_ART_PROC_NAME_COL = -1;
5722 std::map<std::string ,
5723 std::map<
unsigned int , std::string >>
5724 originalMultinodeValues;
5725 std::map<std::string ,
5726 std::map<
unsigned int ,
5729 originalMultinodeSameSiblingValues;
5732 std::map<
unsigned int ,
5734 std::vector<std::string >>>>
5735 originalMultinodeAllSiblingEmbeddedName;
5738 std::map<
unsigned int ,
5740 std::vector<std::string >>>>
5741 originalMultinodeAllSiblingEmbeddedPrinterIndex;
5744 for(
auto& nodePair : nodeTypePair.second)
5746 __COUTV__(nodePair.first);
5749 std::vector<std::string> nodeIndices, hostnameIndices;
5750 unsigned int hostnameFixedWidth = 0, nodeNameFixedWidth = 0;
5751 std::string hostname;
5758 for(
unsigned int i = 0; i < nodePair.second.size(); ++i)
5760 __COUTV__(nodePair.second[i]);
5764 std::string nodeName;
5770 if(nodePair.second[i][0] ==
':')
5772 __COUT__ <<
"Handling original multi-node." << __E__;
5777 std::string lastOriginalName;
5778 std::vector<std::string> originalParameterArr =
5780 &(nodePair.second[i].c_str()[1]),
5783 if(originalParameterArr.size() != 3)
5785 __SS__ <<
"Illegal original name parameter string '"
5786 << nodePair.second[i] <<
"!'" << __E__;
5792 unsigned int fixedWidth;
5793 sscanf(originalParameterArr[0].c_str(),
"%u", &fixedWidth);
5794 __COUTV__(fixedWidth);
5796 std::vector<std::string> printerSyntaxArr =
5801 std::vector<std::string> originalNodeIndices;
5802 for(
auto& printerSyntaxValue : printerSyntaxArr)
5804 __COUTV__(printerSyntaxValue);
5806 std::vector<std::string> printerSyntaxRange =
5808 printerSyntaxValue, {
'-'} );
5810 if(printerSyntaxRange.size() == 0 ||
5811 printerSyntaxRange.size() > 2)
5813 __SS__ <<
"Illegal multi-node printer syntax string '"
5814 << printerSyntaxValue <<
"!'" << __E__;
5817 else if(printerSyntaxRange.size() == 1)
5819 __COUTV__(printerSyntaxRange[0]);
5820 originalNodeIndices.push_back(printerSyntaxRange[0]);
5824 unsigned int lo, hi;
5825 sscanf(printerSyntaxRange[0].c_str(),
"%u", &lo);
5826 sscanf(printerSyntaxRange[1].c_str(),
"%u", &hi);
5830 sscanf(printerSyntaxRange[0].c_str(),
"%u", &hi);
5832 for(; lo <= hi; ++lo)
5835 originalNodeIndices.push_back(std::to_string(lo));
5840 __COUTTV__(originalParameterArr[2]);
5842 originalParameterArr[2] = originalParameterArr[2].substr(
5843 0, originalParameterArr[2].find(
";status="));
5844 __COUTV__(originalParameterArr[2]);
5845 std::vector<std::string> originalNamePieces =
5850 if(originalNamePieces.size() < 2)
5852 __SS__ <<
"Illegal original multi-node name template - "
5853 "please use * to indicate where the multi-node "
5854 "index should be inserted!"
5861 std::stringstream ss;
5862 typeTable.tableView_->print(ss);
5863 __COUT_MULTI__(1, ss.str());
5868 <<
"originalMultinodeSameSiblingValues init col map for "
5869 << nodePair.first << __E__;
5870 originalMultinodeSameSiblingValues.emplace(std::make_pair(
5876 __COUT__ <<
"originalMultinodeAllSiblingEmbeddedName init "
5878 << nodePair.first << __E__;
5879 originalMultinodeAllSiblingEmbeddedName.emplace(std::make_pair(
5888 __COUT__ <<
"originalMultinodeAllSiblingEmbeddedPrinterIndex "
5890 << nodePair.first << __E__;
5891 originalMultinodeAllSiblingEmbeddedPrinterIndex.emplace(
5904 unsigned int originalRow = TableView::INVALID,
5905 lastOriginalRow = TableView::INVALID,
5906 lastArtProcessRow = TableView::INVALID;
5907 for(
unsigned int i = 0; i < originalNodeIndices.size(); ++i)
5909 std::string originalName = originalNamePieces[0];
5910 std::string nodeNameIndex;
5911 for(
unsigned int p = 1; p < originalNamePieces.size();
5914 nodeNameIndex = originalNodeIndices[i];
5917 if(nodeNameIndex.size() > fixedWidth)
5919 __SS__ <<
"Illegal original node name index '"
5921 <<
"' - length is longer than fixed "
5922 "width requirement of "
5923 << fixedWidth <<
"!" << __E__;
5928 while(nodeNameIndex.size() < fixedWidth)
5929 nodeNameIndex =
"0" + nodeNameIndex;
5932 originalName += nodeNameIndex + originalNamePieces[p];
5934 __COUTTV__(originalName);
5935 originalRow = typeTable.tableView_->
findRow(
5940 __COUTTV__(originalRow);
5944 auto result = originalMultinodeValues.emplace(
5945 std::make_pair(originalName,
5946 std::map<
unsigned int ,
5950 <<
"originalName '" << originalName
5951 <<
"' already in original multinode value cache."
5955 __COUT__ <<
"Saving multinode value " << originalName
5956 <<
"[" << originalRow
5957 <<
"][*] with row count = "
5958 << typeTable.tableView_->getNumberOfRows()
5962 for(
unsigned int col = 0;
5963 col < typeTable.tableView_->getNumberOfColumns();
5966 if(typeTable.tableView_->getColumnInfo(col)
5969 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK ||
5970 typeTable.tableView_->getColumnInfo(col)
5973 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID ||
5974 typeTable.tableView_->getColumnInfo(col)
5977 ARTDAQ_TYPE_TABLE_HOSTNAME ||
5978 typeTable.tableView_->getColumnInfo(col)
5981 typeTable.tableView_->getColumnInfo(col)
5983 col == timestampCol ||
5990 <<
"Caching node value: " << originalName
5991 <<
"[" << originalRow <<
"][" << col
5993 << typeTable.tableView_
5994 ->getColumnInfo(col)
5997 << typeTable.tableView_
5998 ->getDataView()[originalRow][col]
6000 originalMultinodeValues.at(originalName)
6001 .emplace(std::make_pair(
6003 typeTable.tableView_
6004 ->getDataView()[originalRow]
6009 for(
const auto& pair :
6010 originalMultinodeSameSiblingValues)
6011 __COUTT__ <<
"originalMultinodeSameSiblin"
6013 << pair.first <<
"]" << __E__;
6015 originalMultinodeSameSiblingValues
6017 .emplace(std::make_pair(
6022 typeTable.tableView_
6024 [originalRow][col])));
6026 for(
const auto& pair :
6027 originalMultinodeAllSiblingEmbeddedName)
6028 __COUTT__ <<
"originalMultinodeAllSibling"
6030 << pair.first <<
"]" << __E__;
6031 originalMultinodeAllSiblingEmbeddedName
6033 .emplace(std::make_pair(
6036 typeTable.tableView_
6039 .find(originalName) !=
6042 std::vector<std::string>())));
6044 for(
const auto& pair :
6045 originalMultinodeAllSiblingEmbeddedPrinterIndex)
6046 __COUTT__ <<
"originalMultinodeAllSibling"
6047 "EmbeddedPrinterIndex["
6048 << pair.first <<
"]" << __E__;
6049 originalMultinodeAllSiblingEmbeddedPrinterIndex
6051 .emplace(std::make_pair(
6054 typeTable.tableView_
6057 .find(nodeNameIndex) !=
6060 std::vector<std::string>())));
6066 originalMultinodeSameSiblingValues
6072 originalMultinodeAllSiblingEmbeddedName
6076 if(originalMultinodeAllSiblingEmbeddedName
6082 <<
"Determine string splits for "
6085 const std::string& val =
6086 typeTable.tableView_
6087 ->getDataView()[originalRow]
6089 size_t pos = val.find(originalName);
6090 originalMultinodeAllSiblingEmbeddedName
6094 val.substr(0, pos));
6095 originalMultinodeAllSiblingEmbeddedName
6098 .second.push_back(val.substr(
6099 pos + originalName.size()));
6101 originalMultinodeAllSiblingEmbeddedName
6107 originalMultinodeAllSiblingEmbeddedPrinterIndex
6111 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6116 __COUTT__ <<
"Determine string "
6117 "splits for embedded "
6118 "printer syntax index: "
6119 << nodeNameIndex << __E__;
6120 const std::string& val =
6121 typeTable.tableView_
6122 ->getDataView()[originalRow]
6124 size_t pos = val.find(nodeNameIndex);
6125 originalMultinodeAllSiblingEmbeddedPrinterIndex
6129 val.substr(0, pos));
6130 originalMultinodeAllSiblingEmbeddedPrinterIndex
6133 .second.push_back(val.substr(
6134 pos + nodeNameIndex.size()));
6136 originalMultinodeAllSiblingEmbeddedPrinterIndex
6144 if(originalMultinodeSameSiblingValues
6149 __COUTT__ <<
"Checking sibling same "
6151 << nodePair.first << __E__;
6152 if(typeTable.tableView_
6153 ->getDataView()[originalRow]
6155 typeTable.tableView_->getDataView()
6156 [lastOriginalRow][col])
6159 <<
"Found different sibling "
6162 << nodePair.first << __E__;
6163 originalMultinodeSameSiblingValues
6169 if(originalMultinodeAllSiblingEmbeddedName
6174 __COUTT__ <<
"Checking sibling "
6175 "embedded name... for "
6176 << nodePair.first <<
":"
6177 << originalName << __E__;
6178 if(typeTable.tableView_
6179 ->getDataView()[originalRow]
6181 .find(originalName) ==
6184 __COUT__ <<
"Found no embedded "
6186 << col <<
" looking for "
6187 << originalName << __E__;
6188 originalMultinodeAllSiblingEmbeddedName
6194 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6200 <<
"Checking sibling embedded "
6201 "printer syntax index... for "
6202 << nodePair.first <<
":"
6203 << nodeNameIndex << __E__;
6204 if(typeTable.tableView_
6205 ->getDataView()[originalRow]
6207 .find(nodeNameIndex) ==
6210 __COUT__ <<
"Found no embedded "
6213 << col <<
" looking for "
6216 originalMultinodeAllSiblingEmbeddedPrinterIndex
6225 <<
"originalMultinodeSameSiblingValues["
6226 << nodePair.first <<
"][" << col <<
"] = "
6227 << originalMultinodeSameSiblingValues
6233 <<
"originalMultinodeAllSiblingEmbeddedNa"
6235 << nodePair.first <<
"][" << col <<
"] = "
6236 << originalMultinodeAllSiblingEmbeddedName
6242 <<
"originalMultinodeAllSiblingEmbeddedPr"
6244 << nodePair.first <<
"][" << col <<
"] = "
6245 << originalMultinodeAllSiblingEmbeddedPrinterIndex
6251 if(hasArtProcessName && artTable &&
6252 typeTable.tableView_->getColumnInfo(col)
6254 ARTDAQTableBase::colARTDAQNotReader_
6259 <<
"Checking ART Process Name... for "
6261 << originalName <<
"' / "
6262 << typeTable.tableView_
6263 ->getDataView()[originalRow]
6266 unsigned int artRow =
6267 artTable->tableView_->
findRow(
6270 typeTable.tableView_
6271 ->getDataView()[originalRow]
6276 <<
"Found ART Process Name = "
6277 << artTable->tableView_->getDataView()
6278 [artRow][artProcessNameCol]
6282 originalMultinodeValues.at(originalName)
6283 .emplace(std::make_pair(
6284 ORIG_MAP_ART_PROC_NAME_COL,
6285 artTable->tableView_
6288 [artProcessNameCol]));
6290 originalMultinodeValues
6292 .at(ORIG_MAP_ART_PROC_NAME_COL));
6295 originalMultinodeSameSiblingValues
6297 .emplace(std::make_pair(
6298 ORIG_MAP_ART_PROC_NAME_COL,
6302 artTable->tableView_
6305 [artProcessNameCol])));
6306 originalMultinodeAllSiblingEmbeddedName
6308 .emplace(std::make_pair(
6309 ORIG_MAP_ART_PROC_NAME_COL,
6311 artTable->tableView_
6315 .find(originalName) !=
6318 std::vector<std::string>())));
6319 originalMultinodeAllSiblingEmbeddedPrinterIndex
6321 .emplace(std::make_pair(
6322 ORIG_MAP_ART_PROC_NAME_COL,
6324 artTable->tableView_
6332 std::vector<std::string>())));
6338 originalMultinodeSameSiblingValues
6340 .at(ORIG_MAP_ART_PROC_NAME_COL)
6344 originalMultinodeAllSiblingEmbeddedName
6346 .at(ORIG_MAP_ART_PROC_NAME_COL)
6348 if(originalMultinodeAllSiblingEmbeddedName
6350 .at(ORIG_MAP_ART_PROC_NAME_COL)
6354 <<
"Determine string splits "
6357 const std::string& val =
6358 artTable->tableView_
6361 [artProcessNameCol];
6363 val.find(originalName);
6364 originalMultinodeAllSiblingEmbeddedName
6366 .at(ORIG_MAP_ART_PROC_NAME_COL)
6368 val.substr(0, pos));
6369 originalMultinodeAllSiblingEmbeddedName
6371 .at(ORIG_MAP_ART_PROC_NAME_COL)
6372 .second.push_back(val.substr(
6374 originalName.size()));
6376 originalMultinodeAllSiblingEmbeddedName
6378 .at(ORIG_MAP_ART_PROC_NAME_COL)
6382 originalMultinodeAllSiblingEmbeddedPrinterIndex
6384 .at(ORIG_MAP_ART_PROC_NAME_COL)
6386 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6388 .at(ORIG_MAP_ART_PROC_NAME_COL)
6392 <<
"Determine string splits "
6393 "for embedded printer "
6395 << nodeNameIndex << __E__;
6396 const std::string& val =
6397 artTable->tableView_
6400 [artProcessNameCol];
6402 val.find(nodeNameIndex);
6403 originalMultinodeAllSiblingEmbeddedPrinterIndex
6405 .at(ORIG_MAP_ART_PROC_NAME_COL)
6407 val.substr(0, pos));
6408 originalMultinodeAllSiblingEmbeddedPrinterIndex
6410 .at(ORIG_MAP_ART_PROC_NAME_COL)
6411 .second.push_back(val.substr(
6413 nodeNameIndex.size()));
6415 originalMultinodeAllSiblingEmbeddedPrinterIndex
6417 .at(ORIG_MAP_ART_PROC_NAME_COL)
6423 if(originalMultinodeSameSiblingValues
6425 .at(ORIG_MAP_ART_PROC_NAME_COL)
6428 __COUTT__ <<
"Checking sibling "
6429 "same values... for "
6432 if(artTable->tableView_
6435 [artProcessNameCol] !=
6436 artTable->tableView_
6439 [artProcessNameCol])
6442 <<
"Found different "
6444 "at artProcessNameCol="
6445 << artProcessNameCol
6449 originalMultinodeSameSiblingValues
6451 .at(ORIG_MAP_ART_PROC_NAME_COL)
6455 if(originalMultinodeAllSiblingEmbeddedName
6457 .at(ORIG_MAP_ART_PROC_NAME_COL)
6461 <<
"Checking sibling "
6462 "embedded name... for "
6463 << nodePair.first <<
":"
6464 << originalName << __E__;
6465 if(artTable->tableView_
6469 .find(originalName) ==
6473 <<
"Found no embedded "
6475 "artProcessNameCol="
6476 << artProcessNameCol
6478 << originalName << __E__;
6479 originalMultinodeAllSiblingEmbeddedName
6481 .at(ORIG_MAP_ART_PROC_NAME_COL)
6485 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6487 .at(ORIG_MAP_ART_PROC_NAME_COL)
6491 <<
"Checking sibling "
6492 "embedded printer syntax "
6494 << nodePair.first <<
":"
6495 << nodeNameIndex << __E__;
6496 if(artTable->tableView_
6500 .find(nodeNameIndex) ==
6504 <<
"Found no embedded "
6505 "printer syntax index "
6506 "at artProcessNameCol="
6507 << artProcessNameCol
6509 << nodeNameIndex << __E__;
6510 originalMultinodeAllSiblingEmbeddedPrinterIndex
6512 .at(ORIG_MAP_ART_PROC_NAME_COL)
6519 <<
"originalMultinodeSameSiblingValue"
6521 << nodePair.first <<
"]["
6522 << ORIG_MAP_ART_PROC_NAME_COL
6524 << originalMultinodeSameSiblingValues
6526 .at(ORIG_MAP_ART_PROC_NAME_COL)
6530 <<
"originalMultinodeAllSiblingEmbedd"
6532 << nodePair.first <<
"]["
6533 << ORIG_MAP_ART_PROC_NAME_COL
6535 << originalMultinodeAllSiblingEmbeddedName
6537 .at(ORIG_MAP_ART_PROC_NAME_COL)
6541 <<
"originalMultinodeAllSiblingEmbedd"
6543 << nodePair.first <<
"]["
6544 << ORIG_MAP_ART_PROC_NAME_COL
6546 << originalMultinodeAllSiblingEmbeddedPrinterIndex
6548 .at(ORIG_MAP_ART_PROC_NAME_COL)
6553 <<
"Checking ART Process Name "
6554 "complete for originalName='"
6555 << originalName <<
"' / "
6556 << typeTable.tableView_
6557 ->getDataView()[originalRow]
6571 lastOriginalRow = originalRow;
6573 __COUTTV__(lastOriginalRow);
6574 lastOriginalName = originalName;
6577 for(
const auto& pair :
6578 originalMultinodeSameSiblingValues.at(nodePair.first))
6579 __COUTT__ <<
"originalMultinodeSameSiblingValues["
6580 << nodePair.first <<
"][" << pair.first
6581 <<
"] = " << pair.second.first << __E__;
6582 for(
const auto& pair :
6583 originalMultinodeAllSiblingEmbeddedName.at(
6585 __COUTT__ <<
"originalMultinodeAllSiblingEmbeddedName["
6586 << nodePair.first <<
"][" << pair.first
6587 <<
"] = " << pair.second.first << __E__;
6588 for(
const auto& pair :
6589 originalMultinodeAllSiblingEmbeddedPrinterIndex.at(
6592 <<
"originalMultinodeAllSiblingEmbeddedPrinterIndex["
6593 << nodePair.first <<
"][" << pair.first
6594 <<
"] = " << pair.second.first << __E__;
6596 __COUTTV__(lastOriginalRow);
6597 row = lastOriginalRow;
6602 std::string originalName = nodePair.second[i].substr(
6603 0, nodePair.second[i].find(
";status="));
6604 __COUTV__(originalName);
6607 row = typeTable.tableView_->
findRow(
6617 nodeName = nodePair.first;
6618 __COUTV__(nodeName);
6620 nodeName = nodeName.substr(0, nodeName.find(
";status="));
6623 std::string tmpNodeName = nodeName;
6625 for(
size_t c = 0; c < tmpNodeName.size(); ++c)
6626 if(tmpNodeName[c] !=
'*')
6627 nodeName += tmpNodeName[c];
6630 __COUTV__(nodeName);
6631 if(row == TableView::INVALID)
6634 row = typeTable.tableView_->
addRow(
6635 author,
true , nodeName);
6640 __COUT__ <<
"Handling new " << nodeTypePair.first
6641 <<
" defaults!" << __E__;
6644 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6649 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6651 typeTable.tableView_->
findCol(
6652 ARTDAQTableBase::colARTDAQReader_
6653 .colLinkToDaqParameters_));
6654 std::string daqParameterGroupID =
6657 typeTable.tableView_->
findCol(
6658 ARTDAQTableBase::colARTDAQReader_
6659 .colLinkToDaqParametersGroupID_),
6660 nodeName +
"DaqParameters");
6663 std::stringstream ss;
6664 typeTable.tableView_->print(ss);
6665 __COUT_MULTI__(1, ss.str());
6669 const std::vector<std::string> parameterUIDs = {
6670 "BoardID",
"FragmentID"};
6672 const std::vector<std::string> parameterNames = {
6676 const std::vector<std::string> parameterValues = {
6681 unsigned int parameterRow;
6682 for(
unsigned int i = 0; i < parameterNames.size(); ++i)
6685 parameterRow = daqParameterTable.tableView_->
addRow(
6688 nodeName + parameterUIDs[i]);
6699 daqParameterTable.tableView_->
findCol(
6700 ARTDAQTableBase::colARTDAQDaqParameter_
6701 .colDaqParameterKey_));
6706 daqParameterTable.tableView_->
findCol(
6707 ARTDAQTableBase::colARTDAQDaqParameter_
6708 .colDaqParameterValue_));
6711 daqParameterGroupID,
6713 daqParameterTable.tableView_->
findCol(
6714 ARTDAQTableBase::colARTDAQDaqParameter_
6715 .colDaqParameterGroupID_));
6719 daqParameterTable.tableView_
6727 __COUT__ <<
"Handling new " << nodeTypePair.first
6728 <<
" defaults!" << __E__;
6733 ARTDAQTableBase::ARTDAQ_DAQ_TABLE,
6736 unsigned int daqRecordRow = daqTable.tableView_->
addRow(
6740 std::string daqRecordUID =
6742 ->getDataView()[daqRecordRow]
6747 ARTDAQTableBase::ARTDAQ_DAQ_TABLE,
6749 typeTable.tableView_->
findCol(
6750 ARTDAQTableBase::colARTDAQNotReader_
6755 typeTable.tableView_->
findCol(
6756 ARTDAQTableBase::colARTDAQNotReader_
6757 .colLinkToDaqUID_));
6761 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6765 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6768 ARTDAQTableBase::colARTDAQDaq_
6769 .colLinkToDaqParameters_));
6770 std::string daqParameterGroupID =
6774 ARTDAQTableBase::colARTDAQDaq_
6775 .colLinkToDaqParametersGroupID_),
6776 nodeName +
"DaqParameters");
6779 const std::vector<std::string> parameterUIDs = {
6780 "BufferCount",
"FragmentsPerEvent"};
6782 const std::vector<std::string> parameterNames = {
6784 "expected_fragments_per_event"
6786 const std::vector<std::string> parameterValues = {
6791 unsigned int parameterRow;
6792 for(
unsigned int i = 0; i < parameterNames.size(); ++i)
6795 parameterRow = daqParameterTable.tableView_->
addRow(
6798 nodeName + parameterUIDs[i]);
6809 daqParameterTable.tableView_->
findCol(
6810 ARTDAQTableBase::colARTDAQDaqParameter_
6811 .colDaqParameterKey_));
6816 daqParameterTable.tableView_->
findCol(
6817 ARTDAQTableBase::colARTDAQDaqParameter_
6818 .colDaqParameterValue_));
6821 daqParameterGroupID,
6823 daqParameterTable.tableView_->
findCol(
6824 ARTDAQTableBase::colARTDAQDaqParameter_
6825 .colDaqParameterGroupID_));
6831 daqParameterTable.tableView_
6839 <<
"Reusing row " << row <<
" current-UID="
6840 << typeTable.tableView_
6841 ->getDataView()[row]
6843 <<
" as (temporarily to basename if multinode) new-UID="
6844 << nodeName << __E__;
6845 typeTable.tableView_
6854 if(row < maxRowToDelete)
6855 deleteRecordMap[row] =
false;
6862 artdaqSupervisorTable.tableView_
6863 ->getDataView()[artdaqSupervisorRow]
6864 [artdaqSupervisorTable.tableView_->
findCol(
6866 .at(nodeTypePair.first))],
6868 typeTable.tableView_->
findCol(
6870 nodeTypePair.first)));
6883 hostname = nodePair.second[i];
6887 typeTable.tableView_->
findCol(ARTDAQ_TYPE_TABLE_HOSTNAME));
6892 if(nodePair.second[i] !=
"" &&
6893 nodePair.second[i] !=
6894 TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
6895 nodePair.second[i] !=
6896 TableViewColumnInfo::DATATYPE_STRING_ALT_DEFAULT)
6899 if(subsystemObjectMap.find(nodePair.second[i]) ==
6900 subsystemObjectMap.end())
6902 __SS__ <<
"Illegal subsystem '" << nodePair.second[i]
6903 <<
"' mismatch!" << __E__;
6908 ARTDAQ_SUBSYSTEM_TABLE,
6910 typeTable.tableView_->
findCol(
6911 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK));
6915 typeTable.tableView_->
findCol(
6916 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID));
6921 TableViewColumnInfo::DATATYPE_LINK_DEFAULT,
6923 typeTable.tableView_->
findCol(
6924 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK));
6928 i == 4 || i == 5 || i == 6 ||
6935 __COUT__ <<
"Handling printer syntax i=" << i << __E__;
6937 std::vector<std::string> printerSyntaxArr =
6941 if(printerSyntaxArr.size() == 2)
6943 if(printerSyntaxArr[0] ==
6946 sscanf(printerSyntaxArr[1].c_str(),
6948 &nodeNameFixedWidth);
6949 __COUTV__(nodeNameFixedWidth);
6952 else if(printerSyntaxArr[0] ==
6955 sscanf(printerSyntaxArr[1].c_str(),
6957 &hostnameFixedWidth);
6958 __COUTV__(hostnameFixedWidth);
6964 for(
auto& printerSyntaxValue : printerSyntaxArr)
6966 __COUTV__(printerSyntaxValue);
6968 std::vector<std::string> printerSyntaxRange =
6971 if(printerSyntaxRange.size() == 0 ||
6972 printerSyntaxRange.size() > 2)
6974 __SS__ <<
"Illegal multi-node printer syntax string '"
6975 << printerSyntaxValue <<
"!'" << __E__;
6978 else if(printerSyntaxRange.size() == 1)
6981 __COUTV__(printerSyntaxRange[0]);
6986 nodeIndices.push_back(printerSyntaxRange[0]);
6988 hostnameIndices.push_back(printerSyntaxRange[0]);
6992 unsigned int lo, hi;
6993 sscanf(printerSyntaxRange[0].c_str(),
"%u", &lo);
6994 sscanf(printerSyntaxRange[1].c_str(),
"%u", &hi);
6998 sscanf(printerSyntaxRange[0].c_str(),
"%u", &hi);
7000 for(; lo <= hi; ++lo)
7004 nodeIndices.push_back(std::to_string(lo));
7006 hostnameIndices.push_back(std::to_string(lo));
7013 __SS__ <<
"Unexpected parameter[" << i <<
" '"
7014 << nodePair.second[i] <<
"' for node " << nodePair.first
7020 __COUTV__(nodeIndices.size());
7021 __COUTV__(hostnameIndices.size());
7023 if(hostnameIndices.size())
7025 if(hostnameIndices.size() != nodeIndices.size())
7027 __SS__ <<
"Illegal associated hostname array has count "
7028 << hostnameIndices.size()
7029 <<
" which is not equal to the node count "
7030 << nodeIndices.size() <<
"!" << __E__;
7035 if(nodeIndices.size())
7037 unsigned int hostnameCol =
7038 typeTable.tableView_->
findCol(ARTDAQ_TYPE_TABLE_HOSTNAME);
7043 std::vector<std::string> namePieces =
7045 nodePair.first.substr(0, nodePair.first.find(
";status=")),
7049 if(namePieces.size() < 2)
7052 <<
"Illegal multi-node name template - please use * to "
7053 "indicate where the multi-node index should be inserted!"
7058 std::vector<std::string> hostnamePieces;
7059 if(hostnameIndices.size())
7065 if(hostnamePieces.size() < 2)
7068 <<
"Illegal hostname array template - please use * to "
7069 "indicate where the hostname index should be inserted!"
7075 bool isFirst =
true;
7076 unsigned int lastArtRow = TableView::INVALID;
7077 for(
unsigned int i = 0; i < nodeIndices.size(); ++i)
7079 std::string name = namePieces[0];
7080 std::string nodeNameIndex;
7081 for(
unsigned int p = 1; p < namePieces.size(); ++p)
7083 nodeNameIndex = nodeIndices[i];
7084 if(nodeNameFixedWidth > 1)
7086 if(nodeNameIndex.size() > nodeNameFixedWidth)
7089 if(nodeNameIndex.find(
"_clone") == std::string::npos)
7091 __SS__ <<
"Illegal node name index '"
7093 <<
"' - length is longer than fixed width "
7095 << nodeNameFixedWidth <<
"!" << __E__;
7101 while(nodeNameIndex.size() < nodeNameFixedWidth)
7102 nodeNameIndex =
"0" + nodeNameIndex;
7105 name += nodeNameIndex + namePieces[p];
7109 if(hostnamePieces.size())
7111 hostname = hostnamePieces[0];
7112 std::string hostnameIndex;
7113 for(
unsigned int p = 1; p < hostnamePieces.size(); ++p)
7115 hostnameIndex = hostnameIndices[i];
7116 if(hostnameFixedWidth > 1)
7118 if(hostnameIndex.size() > hostnameFixedWidth)
7121 if(hostnameIndex.find(
"_clone") ==
7124 __SS__ <<
"Illegal hostname index '"
7126 <<
"' - length is longer than fixed "
7129 << hostnameFixedWidth <<
"!" << __E__;
7135 while(hostnameIndex.size() < hostnameFixedWidth)
7136 hostnameIndex =
"0" + hostnameIndex;
7139 hostname += hostnameIndex + hostnamePieces[p];
7141 __COUTV__(hostname);
7148 << author <<
"... Replacing row UID '"
7149 << typeTable.tableView_
7150 ->getDataView()[row]
7152 <<
"' with UID '" << name <<
"'" << __E__;
7155 if(row < maxRowToDelete)
7156 deleteRecordMap[row] =
false;
7161 << author <<
"... Copying row UID '"
7162 << typeTable.tableView_
7163 ->getDataView()[row]
7165 <<
"' to UID '" << name <<
"'" << __E__;
7166 unsigned int copyRow = typeTable.tableView_->
copyRows(
7168 *(typeTable.tableView_),
7175 if(row < maxRowToDelete)
7176 deleteRecordMap[copyRow] =
false;
7181 name, row, typeTable.tableView_->
getColUID());
7183 hostname, row, hostnameCol);
7186 TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT,
7190 typeTable.tableView_->
setValue(time(0), row, timestampCol);
7192 __COUTTV__(typeTable
7194 ->getDataView()[row][commentCol]);
7195 __COUTTV__(typeTable
7197 ->getDataView()[row][authorCol]);
7198 __COUTTV__(typeTable
7200 ->getDataView()[row][timestampCol]);
7210 <<
"Looking for best original node match for row=" << row
7211 <<
" UID='" << name <<
"'" << __E__;
7212 size_t bestScore = 0;
7213 std::string bestOriginalNodeName;
7214 for(
const auto& originalNodePair : originalMultinodeValues)
7216 if(originalNodePair.second.find(
7217 ORIG_MAP_ART_PROC_NAME_COL) !=
7218 originalNodePair.second.end())
7219 __COUTTV__(originalNodePair.second.at(
7220 ORIG_MAP_ART_PROC_NAME_COL));
7222 for(
size_t c = 0, d = 0;
7223 c < originalNodePair.first.size() && d < name.size();
7226 if(name[d] == originalNodePair.first[c])
7228 else if(d + 1 < name.size() &&
7229 name[d + 1] == originalNodePair.first[c])
7231 else if(c + 1 < originalNodePair.first.size() &&
7232 name[d] == originalNodePair.first[c + 1])
7235 if(originalNodePair.first.size() == name.size())
7237 __COUTVS__(2, score);
7238 if(score > bestScore)
7240 bestOriginalNodeName = originalNodePair.first;
7242 __COUTVS__(2, bestOriginalNodeName);
7243 __COUTVS__(2, bestScore);
7247 bool exactMatch = (bestOriginalNodeName == name);
7248 bool needToHandleArtProcessName =
false;
7249 std::string artProcessName;
7252 originalMultinodeValues.find(bestOriginalNodeName) !=
7253 originalMultinodeValues.end())
7255 __COUT__ <<
"Populating original multinode value from '"
7256 << bestOriginalNodeName <<
"' into '" << name
7259 for(
const auto& valuePair :
7260 originalMultinodeValues.at(bestOriginalNodeName))
7263 if(!exactMatch && (valuePair.first == commentCol ||
7264 valuePair.first == authorCol ||
7265 valuePair.first == timestampCol))
7268 <<
"Not exact node name match, so keeping "
7269 "default meta info for node: "
7270 << name <<
"[" << row <<
"]["
7272 <<
"] /= " << valuePair.second <<
" keep= "
7273 << typeTable.tableView_
7274 ->getDataView()[row][valuePair.first]
7279 __COUTT__ <<
"Customizing node: " << name <<
"["
7280 << row <<
"][" << valuePair.first
7281 <<
"] = " << valuePair.second << __E__;
7283 if(valuePair.first == ORIG_MAP_ART_PROC_NAME_COL)
7285 __COUTT__ <<
"NEED Special art Process Name "
7287 << valuePair.second << __E__;
7288 needToHandleArtProcessName =
true;
7289 artProcessName = valuePair.second;
7292 valuePair.second, row, artProcessNameCol);
7296 valuePair.second, row, valuePair.first);
7300 __COUT__ <<
"Did not find '" << name
7301 <<
"' in original value cache. Looking for "
7302 "bestOriginalNodeName="
7303 << bestOriginalNodeName << __E__;
7305 __COUTV__(exactMatch);
7308 if(originalMultinodeSameSiblingValues.find(
7310 originalMultinodeSameSiblingValues.end())
7312 __COUT__ <<
"Applying multinode sibling same value "
7314 << row <<
" UID='" << name <<
"'" << __E__;
7315 for(
const auto& sameValuePair :
7316 originalMultinodeSameSiblingValues.at(
7319 if(!sameValuePair.second.first)
7322 <<
"Found originalMultinodeSameSiblingValues["
7323 << nodePair.first <<
"]["
7324 << sameValuePair.first <<
"] = "
7325 << sameValuePair.second.first <<
" --> "
7326 << sameValuePair.second.second << __E__;
7329 if(sameValuePair.first ==
7330 ORIG_MAP_ART_PROC_NAME_COL)
7332 __COUTT__ <<
"NEED Special art Process Name "
7334 << sameValuePair.second.second
7336 needToHandleArtProcessName =
true;
7337 artProcessName = sameValuePair.second.second;
7340 sameValuePair.second.second,
7346 sameValuePair.second.second,
7348 sameValuePair.first);
7353 if(originalMultinodeAllSiblingEmbeddedPrinterIndex.find(
7355 originalMultinodeAllSiblingEmbeddedPrinterIndex.end())
7357 __COUT__ <<
"Applying multinode sibling embbeded "
7358 "printer syntax index rules for row="
7359 << row <<
" UID='" << name
7360 <<
"' and printer index='" << nodeNameIndex
7362 for(
const auto& embedValuePair :
7363 originalMultinodeAllSiblingEmbeddedPrinterIndex
7364 .at(nodePair.first))
7366 if(!embedValuePair.second.first ||
7367 embedValuePair.second.second.size() < 2)
7371 "originalMultinodeAllSiblingEmbeddedPrinte"
7373 << nodePair.first <<
"]["
7374 << embedValuePair.first <<
"] = "
7375 << embedValuePair.second.first <<
" --> "
7377 embedValuePair.second.second)
7379 std::string embedValue =
7381 embedValuePair.second.second,
7383 __COUTTV__(embedValue);
7386 if(embedValuePair.first ==
7387 ORIG_MAP_ART_PROC_NAME_COL)
7389 __COUTT__ <<
"NEED Special art Process Name "
7391 << embedValue << __E__;
7392 needToHandleArtProcessName =
true;
7393 artProcessName = embedValue;
7396 embedValue, row, artProcessNameCol);
7400 embedValue, row, embedValuePair.first);
7404 if(originalMultinodeAllSiblingEmbeddedName.find(
7406 originalMultinodeAllSiblingEmbeddedName.end())
7408 __COUT__ <<
"Applying multinode sibling embbeded "
7409 "name rules for row="
7410 << row <<
" UID='" << name <<
"'" << __E__;
7411 for(
const auto& embedValuePair :
7412 originalMultinodeAllSiblingEmbeddedName.at(
7415 if(!embedValuePair.second.first ||
7416 embedValuePair.second.second.size() < 2)
7420 "originalMultinodeAllSiblingEmbeddedName["
7421 << nodePair.first <<
"]["
7422 << embedValuePair.first <<
"] = "
7423 << embedValuePair.second.first <<
" --> "
7425 embedValuePair.second.second)
7427 std::string embedValue =
7429 embedValuePair.second.second, name);
7430 __COUTTV__(embedValue);
7433 if(embedValuePair.first ==
7434 ORIG_MAP_ART_PROC_NAME_COL)
7436 __COUTT__ <<
"NEED Special art Process Name "
7438 << embedValue << __E__;
7439 needToHandleArtProcessName =
true;
7440 artProcessName = embedValue;
7443 embedValue, row, artProcessNameCol);
7447 embedValue, row, embedValuePair.first);
7451 __COUTV__(needToHandleArtProcessName);
7452 if(needToHandleArtProcessName)
7454 __COUTT__ <<
"Special art Process Name column value: "
7455 << artProcessName << __E__;
7457 std::string artRecord =
7458 typeTable.tableView_->getDataView()
7459 [row][typeTable.tableView_->
findCol(
7460 ARTDAQTableBase::colARTDAQNotReader_
7461 .colLinkToArtUID_)];
7462 __COUTTV__(artRecord);
7464 const unsigned int artCommentCol =
7466 TableViewColumnInfo::TYPE_COMMENT);
7467 const unsigned int artAuthorCol =
7469 TableViewColumnInfo::TYPE_AUTHOR);
7470 const unsigned int artTimestampCol =
7472 TableViewColumnInfo::TYPE_TIMESTAMP);
7474 unsigned int artRow = artTable->tableView_->
findRow(
7480 if(artRow == TableView::INVALID)
7482 __COUTT__ <<
"Need to make art Process record... "
7484 << artRecord << __E__;
7488 __COUTTV__(bestOriginalNodeName);
7489 const unsigned int bestMatchRow =
7490 typeTable.tableView_->
findRow(
7492 bestOriginalNodeName);
7493 __COUTTV__(bestMatchRow);
7495 std::string bestMatchArtRecord =
7496 typeTable.tableView_->getDataView()
7498 [typeTable.tableView_->
findCol(
7501 .colLinkToArtUID_)];
7502 __COUTTV__(bestMatchArtRecord);
7504 unsigned int bestMatchArtRow =
7505 artTable->tableView_->
findRow(
7510 __COUTTV__(bestMatchArtRow);
7511 if(bestMatchArtRow !=
7516 __COUTTV__(lastArtRow);
7519 if(lastArtRow != TableView::INVALID)
7521 __COUTT__ <<
"Copying art Process record... "
7523 << lastArtRow << __E__;
7524 unsigned int copyRow =
7527 *(artTable->tableView_),
7541 DATATYPE_COMMENT_DEFAULT,
7545 author, artRow, artAuthorCol);
7547 time(0), artRow, artTimestampCol);
7551 __COUTT__ <<
"Creating art Process record... "
7553 << artRecord << __E__;
7555 artRow = artTable->tableView_->
addRow(
7561 <<
"Made art Process record... artRecord="
7562 << artRecord << __E__;
7565 __COUTT__ <<
"Modify art Process record based on "
7566 "sibling rules... artRecord="
7568 <<
" artProcessName=" << artProcessName
7572 artProcessName, artRow, artProcessNameCol);
7573 lastArtRow = artRow;
7577 needToHandleArtProcessName)
7579 std::string artRecord =
7580 typeTable.tableView_->getDataView()
7581 [row][typeTable.tableView_->
findCol(
7582 ARTDAQTableBase::colARTDAQNotReader_
7583 .colLinkToArtUID_)];
7584 __COUTTV__(artRecord);
7585 unsigned int artRow = artTable->tableView_->
findRow(
7593 lastArtRow = artRow;
7596 __COUTTV__(lastArtRow);
7601 if(row < maxRowToDelete)
7602 __COUTTV__(deleteRecordMap[row]);
7604 __COUTTV__(typeTable
7606 ->getDataView()[row][commentCol]);
7607 __COUTTV__(typeTable
7609 ->getDataView()[row][authorCol]);
7610 __COUTTV__(typeTable
7612 ->getDataView()[row][timestampCol]);
7622 __COUT__ <<
"Deleting '" << nodeTypePair.first
7623 <<
"' records not specified..." << __E__;
7626 std::set<unsigned int> orderedRowSet;
7627 for(
auto& deletePair : deleteRecordMap)
7629 if(!deletePair.second)
7631 __COUTT__ <<
"Row keep = " << deletePair.first << __E__;
7635 __COUTT__ <<
"Row delete = " << deletePair.first << __E__;
7636 orderedRowSet.emplace(deletePair.first);
7640 for(std::set<unsigned int>::reverse_iterator rit = orderedRowSet.rbegin();
7641 rit != orderedRowSet.rend();
7647 if(TTEST(1) && artTable)
7649 std::stringstream ss;
7650 artTable->tableView_->print(ss);
7651 __COUT_MULTI__(1, ss.str());
7654 if(hasArtProcessName && artTable)
7655 artTable->tableView_
7660 std::stringstream ss;
7661 typeTable.tableView_->print(ss);
7662 __COUT_MULTI__(1, ss.str());
7665 typeTable.tableView_->
init();
7672 std::stringstream ss;
7673 artdaqSupervisorTable.tableView_->print(ss);
7674 __COUT_MULTI__(1, ss.str());
7677 std::stringstream ss;
7678 artdaqSubsystemTable.tableView_->print(ss);
7679 __COUT_MULTI__(1, ss.str());
7683 artdaqSupervisorTable.tableView_
7685 artdaqSubsystemTable.tableView_
7690 __COUT__ <<
"Table errors while creating ARTDAQ nodes. Erasing all newly "
7691 "created table versions."
7696 __COUT__ <<
"Edits complete for artdaq nodes and subsystems.. now save and activate "
7697 "groups, and update aliases!"
7703 __SS__ <<
"DEBUG blocking save!" << __E__;
7707 std::string localAccumulatedWarnings;
7708 configGroupEdit.saveChanges(configGroupEdit.originalGroupName_,
7709 newConfigurationGroupKey,
7716 &localAccumulatedWarnings);
7732 void ARTDAQTableBase::addCommentWhitespace(std::ostream& os,
size_t lineLength)
7734 for(
size_t i = 0;
true; i += 20)
7736 if(lineLength < FCL_COMMENT_POSITION + i)
7738 os << std::string(FCL_COMMENT_POSITION + i - lineLength,
' ');
7746 std::string ARTDAQTableBase::getStructureAsJSON(
7749 if(fclMap_.size() == 0)
7751 std::stringstream oss;
7753 oss <<
"{" << __E__;
7755 if(fclMap_.size() > 1)
7758 bool firstType =
true;
7759 for(
const auto& typePairMap : fclMap_)
7763 oss <<
"\t\"" << getTypeString(typePairMap.first) <<
"\": {" << __E__;
7765 bool firstEntry =
true;
7766 for(
const auto& fclPair : typePairMap.second)
7770 oss <<
"\t\t\"" << fclPair.first <<
"\": \""
7776 oss <<
"\t}" << __E__;
7783 bool firstEntry =
true;
7784 for(
const auto& typePairMap : fclMap_)
7786 for(
const auto& fclPair : typePairMap.second)
7790 oss <<
"\t\"" << fclPair.first <<
"\": \""
7798 oss <<
"}" << __E__;
7807 size_t maxFragmentSizeBytes,
7808 size_t routingTimeoutMs,
7809 size_t routingRetryCount,
7814 __SS__ <<
"ARTDAQ Supervisor node is disconnected while generating boot.txt "
7815 <<
"content." << __E__;
7819 const ARTDAQInfo& info = extractARTDAQInfo(artdaqSupervisorNode,
7822 maxFragmentSizeBytes,
7828 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colDAQInterfaceDebugLevel_)
7830 std::string setupScript =
7831 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colDAQSetupScript_).
getValue();
7840 const std::string& setupScript,
7843 std::stringstream o;
7845 o <<
"DAQ setup script: " << setupScript << std::endl;
7846 o <<
"debug level: " << debugLevel << std::endl;
7849 if(info.subsystems.size() > 1)
7851 for(
auto& ss : info.subsystems)
7855 o <<
"Subsystem id: " << ss.first << std::endl;
7856 if(ss.second.destination != 0)
7858 o <<
"Subsystem destination: " << ss.second.destination << std::endl;
7860 for(
auto& sss : ss.second.sources)
7862 o <<
"Subsystem source: " << sss << std::endl;
7864 if(ss.second.eventMode)
7866 o <<
"Subsystem fragmentMode: False" << std::endl;
7872 for(
auto& builder : info.processes.at(ARTDAQAppType::EventBuilder))
7874 o <<
"EventBuilder host: " << builder.hostname << std::endl;
7875 o <<
"EventBuilder label: " << builder.label << std::endl;
7876 if(builder.subsystem != 1)
7878 o <<
"EventBuilder subsystem: " << builder.subsystem << std::endl;
7880 if(builder.allowed_processors !=
"")
7882 o <<
"EventBuilder allowed_processors: " << builder.allowed_processors
7888 for(
auto& logger : info.processes.at(ARTDAQAppType::DataLogger))
7890 o <<
"DataLogger host: " << logger.hostname << std::endl;
7891 o <<
"DataLogger label: " << logger.label << std::endl;
7892 if(logger.subsystem != 1)
7894 o <<
"DataLogger subsystem: " << logger.subsystem << std::endl;
7896 if(logger.allowed_processors !=
"")
7898 o <<
"DataLogger allowed_processors: " << logger.allowed_processors
7904 for(
auto& dispatcher : info.processes.at(ARTDAQAppType::Dispatcher))
7906 o <<
"Dispatcher host: " << dispatcher.hostname << std::endl;
7907 o <<
"Dispatcher label: " << dispatcher.label << std::endl;
7908 if(dispatcher.port != 0)
7910 o <<
"Dispatcher port: " << dispatcher.port << std::endl;
7912 if(dispatcher.subsystem != 1)
7914 o <<
"Dispatcher subsystem: " << dispatcher.subsystem << std::endl;
7916 if(dispatcher.allowed_processors !=
"")
7918 o <<
"Dispatcher allowed_processors: " << dispatcher.allowed_processors
7924 for(
auto& rm : info.processes.at(ARTDAQAppType::RoutingManager))
7926 o <<
"RoutingManager host: " << rm.hostname << std::endl;
7927 o <<
"RoutingManager label: " << rm.label << std::endl;
7928 if(rm.subsystem != 1)
7930 o <<
"RoutingManager subsystem: " << rm.subsystem << std::endl;
7932 if(rm.allowed_processors !=
"")
7934 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 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)
static void insertMetricsBlock(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree daqNode)
insertMetricsBlock
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)