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"
32 static size_t fhiclFlattenCount_ = 0;
33 static double fhiclFlattenSeconds_ = 0;
34 static size_t fhiclFlattenCountCumulative_ = 0;
35 static double fhiclFlattenSecondsCumulative_ = 0;
36 static size_t extractInvocation_ = 0;
43 static std::chrono::steady_clock::time_point fhiclTraceLastActivity_{};
44 static const double FHICL_TRACE_RESET_GAP_S = 30.0;
49 static void maybeResetFHiCLTimingTrace()
51 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
52 if(fhiclFlattenCountCumulative_ > 0 || extractInvocation_ > 0)
54 double gap = std::chrono::duration<double>(now - fhiclTraceLastActivity_).count();
55 if(gap > FHICL_TRACE_RESET_GAP_S)
57 fhiclFlattenCountCumulative_ = 0;
58 fhiclFlattenSecondsCumulative_ = 0;
59 extractInvocation_ = 0;
62 fhiclTraceLastActivity_ = now;
67 #define FCL_COMMENT_POSITION 65
71 #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();}
73 #define OUTC(X,C) OUTCF(X,C,"")
75 #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();}
77 #define OUTCL(X,C) OUTCLF(X,C,"")
79 #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();}
81 #define OUTCL2(X,C) OUTCL2F(X,C,"")
86 const std::string ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH =
87 (((getenv(
"SERVICE_DATA_PATH") == NULL)
88 ? (std::string(getenv(
"USER_DATA")) +
"/ServiceData")
89 : std::string(getenv(
"SERVICE_DATA_PATH")))) +
90 "/ConfigurationGUI_artdaqLayouts/";
91 const bool ARTDAQTableBase::ARTDAQ_DONOTWRITE_FCL = ((getenv(
"OTS_FCL_DONOTWRITE") == NULL) ?
false :
true);
93 const std::string ARTDAQTableBase::ARTDAQ_SUPERVISOR_CLASS =
"ots::ARTDAQSupervisor";
94 const std::string ARTDAQTableBase::ARTDAQ_SUPERVISOR_TABLE =
"ARTDAQSupervisorTable";
96 const std::string ARTDAQTableBase::ARTDAQ_READER_TABLE =
"ARTDAQBoardReaderTable";
97 const std::string ARTDAQTableBase::ARTDAQ_BUILDER_TABLE =
"ARTDAQEventBuilderTable";
98 const std::string ARTDAQTableBase::ARTDAQ_LOGGER_TABLE =
"ARTDAQDataLoggerTable";
99 const std::string ARTDAQTableBase::ARTDAQ_DISPATCHER_TABLE =
"ARTDAQDispatcherTable";
100 const std::string ARTDAQTableBase::ARTDAQ_MONITOR_TABLE =
"ARTDAQMonitorTable";
101 const std::string ARTDAQTableBase::ARTDAQ_ROUTER_TABLE =
"ARTDAQRoutingManagerTable";
103 const std::string ARTDAQTableBase::ARTDAQ_SUBSYSTEM_TABLE =
"ARTDAQSubsystemTable";
104 const std::string ARTDAQTableBase::ARTDAQ_DAQ_TABLE =
"ARTDAQDaqTable";
105 const std::string ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE =
"ARTDAQDaqParameterTable";
106 const std::string ARTDAQTableBase::ARTDAQ_ART_TABLE =
"ARTDAQArtTable";
108 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME =
"ExecutionHostname";
109 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS =
"AllowedProcessors";
110 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK =
"SubsystemLink";
111 const std::string ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID =
"SubsystemLinkUID";
114 const int ARTDAQTableBase::NULL_SUBSYSTEM_DESTINATION = 0;
115 const std::string ARTDAQTableBase::NULL_SUBSYSTEM_DESTINATION_LABEL =
"nullDestinationSubsystem";
139 std::string* accumulatedExceptions )
140 :
TableBase(tableName, accumulatedExceptions)
152 std::cout <<
"ARTDAQTableBase Before traceTID=" << traceTID << __E__;
154 traceInit(trace_name(TRACE_NAME, __TRACE_FILE__, buf,
sizeof(buf)), 0);
155 std::cout <<
"ARTDAQTableBase After traceTID=" << traceTID << __E__;
156 __COUT__ <<
"ARTDAQTableBase TRACE reinit and Constructed." << __E__;
166 __SS__ <<
"Should not call void constructor, table type is lost!" << __E__;
171 ARTDAQTableBase::~ARTDAQTableBase(
void) {}
187 __COUT_INFO__ <<
"ARTDAQ Supervisor is disabled, so skipping fcl handling."
202 const std::string& ARTDAQTableBase::getTypeString(ARTDAQAppType type)
206 case ARTDAQAppType::EventBuilder:
208 case ARTDAQAppType::DataLogger:
210 case ARTDAQAppType::Dispatcher:
212 case ARTDAQAppType::BoardReader:
214 case ARTDAQAppType::Monitor:
216 case ARTDAQAppType::RoutingManager:
220 __SS__ <<
"Illegal translation attempt for type '" << (
unsigned int)type <<
"'"
226 std::string ARTDAQTableBase::getFHICLFilename(ARTDAQAppType type,
const std::string& name)
231 std::string uid = name;
232 for(
unsigned int i = 0; i < uid.size(); ++i)
233 if((uid[i] >=
'a' && uid[i] <=
'z') || (uid[i] >=
'A' && uid[i] <=
'Z') ||
234 (uid[i] >=
'0' && uid[i] <=
'9'))
245 std::string ARTDAQTableBase::getFlatFHICLFilename(ARTDAQAppType type,
246 const std::string& name)
251 std::string uid = name;
252 for(
unsigned int i = 0; i < uid.size(); ++i)
253 if((uid[i] >=
'a' && uid[i] <=
'z') || (uid[i] >=
'A' && uid[i] <=
'Z') ||
254 (uid[i] >=
'0' && uid[i] <=
'9'))
257 filename +=
"_flattened.fcl";
265 void ARTDAQTableBase::flattenFHICL(ARTDAQAppType type,
266 const std::string& name,
267 std::string* returnFcl )
269 maybeResetFHiCLTimingTrace();
270 std::chrono::steady_clock::time_point startClock = std::chrono::steady_clock::now();
271 __COUTS__(3) <<
"flattenFHICL()" << __ENV__(
"FHICL_FILE_PATH") << __E__;
275 std::string inFile = getFHICLFilename(type, name);
276 std::string outFile = getFlatFHICLFilename(type, name);
278 __COUTVS__(3, inFile);
279 __COUTVS__(3, outFile);
281 cet::filepath_lookup_nonabsolute policy(
"FHICL_FILE_PATH");
282 fhicl::ParameterSet pset;
286 __COUT_INFO__ <<
"parsing document: " << inFile;
289 pset = fhicl::ParameterSet::make(inFile, policy);
290 __COUTT__ <<
"document: " << inFile <<
" parsed";
291 __COUTT__ <<
"got pset from table:";
293 std::ofstream ofs{outFile};
296 __SS__ <<
"Failed to open fhicl output file '" << outFile <<
"!'" << __E__;
299 std::ostringstream out;
300 out << pset.to_indented_string(
304 *returnFcl = out.str();
305 __COUTVS__(21, returnFcl);
309 catch(cet::exception
const& e)
311 __SS__ <<
"Failed to parse fhicl into output file '" << outFile
312 <<
"' - here is the error: " << e.what() << __E__;
315 if(std::string(e.what()).find(
"TriggerEpilogs") != std::string::npos)
317 <<
"The Trigger Epilogs are located at "
318 "$USER_DATA/TriggerConfigurations/TriggerEpilogs. "
319 <<
"Please check that the Trigger Epilogs were properly generated, or "
320 "copy them from a previously working area."
325 double flattenElapsed = artdaq::TimeUtils::GetElapsedTime(startClock);
326 ++fhiclFlattenCount_;
327 fhiclFlattenSeconds_ += flattenElapsed;
328 ++fhiclFlattenCountCumulative_;
329 fhiclFlattenSecondsCumulative_ += flattenElapsed;
331 __COUTT__ << name <<
" Flatten Clock time = " << flattenElapsed << __E__;
343 std::string& commentStr,
344 const std::string& parentPath,
346 const std::string& parameterPreamble,
347 bool onlyInsertAtTableParameters ,
348 bool includeAtTableParameters )
354 auto otherParameters = parameterGroupLink.
getChildren();
359 __COUTVS__(3, otherParameters.size());
360 __COUTVS__(3, onlyInsertAtTableParameters);
361 __COUTVS__(3, includeAtTableParameters);
363 size_t paramCount = 0;
364 for(
auto& parameter : otherParameters)
366 key = parameter.second.getNode(parameterPreamble +
"Key").getValue();
368 std::string localParentPath =
370 parameter.second.getTableName() +
":" +
372 parameterGroupLink.
getParentLinkID() +
"/" + parameter.second.getValue();
376 if(key.find(
"@table::") != std::string::npos)
379 if(onlyInsertAtTableParameters || includeAtTableParameters)
382 if(!parameter.second.status())
385 __COUTT__ <<
"Inserting parameter... " << localParentPath << __E__;
388 OUTCL(key << parameter.second.getNode(parameterPreamble +
"Value")
390 parameter.second.hasComment() ? parameter.second.getComment()
393 if(!parameter.second.status())
402 if(onlyInsertAtTableParameters)
406 if(!parameter.second.status())
409 __COUTT__ <<
"Inserting parameter... " << localParentPath << __E__;
412 if(key.size() && key.find(
"#include") == std::string::npos)
417 parameter.second.getNode(parameterPreamble +
"Value").getValue();
420 if(value.size() > 2 && value[0] ==
'@' && value[1] ==
'@')
423 <<
"Checking for getFclValueForARTDAQ @@ indicator from value = "
425 std::string potentialTable = value.substr(2);
426 __COUTTV__(potentialTable);
431 ->getFclValueForARTDAQ(cfgMgr, key);
433 catch(
const std::runtime_error& e)
435 __SS__ <<
"getFclValueForARTDAQ @@ indicator from value = "
436 << value <<
" corresponds to table '" << potentialTable
437 <<
"'... however fcl value failed to load: " << e.what();
441 __COUTT__ <<
"Value from getFclValueForARTDAQ: value = " << value
444 std::string localParentPath2 =
"/" + potentialTable;
445 OUTCL2(key <<
": " << value,
446 parameter.second.hasComment() ? parameter.second.getComment()
452 << parameter.second.getNode(parameterPreamble +
"Value")
454 parameter.second.hasComment() ? parameter.second.getComment()
460 OUTCL(parameter.second.getNode(parameterPreamble +
"Value").getValue(),
461 parameter.second.hasComment() ? parameter.second.getComment() :
"");
465 OUTCL(
"# comment for #include below:",
466 parameter.second.hasComment() ? parameter.second.getComment() :
"");
468 << parameter.second.getNode(parameterPreamble +
"Value").getValue()
472 if(!parameter.second.status())
478 __COUTS__(3) <<
"Empty parameter set found onlyInsertAtTableParameters="
479 << onlyInsertAtTableParameters << __E__;
480 std::string localParentPath =
483 if(onlyInsertAtTableParameters)
485 OUTCL(
"# no @table parameters found",
"" );
489 OUTCL(
"# empty parameter set found",
"" );
495 __COUTS__(3) <<
"No parameters found" << __E__;
496 std::string localParentPath =
498 OUTCL(
"# no parameters inserted",
"" );
508 std::string& commentStr,
509 const std::string& parentPath,
512 std::string value = moduleTypeNode.
getValue();
513 __COUTTV__(parentPath);
514 OUTCF((value.find(
"@table::") == std::string::npos ?
"module_type: " :
"") << value,
524 std::string& commentStr,
525 const std::string& parentPath,
528 auto metricsGroup = daqNode.
getNode(
"daqMetricsLink");
531 OUTCF(
"metrics: {",
"", metricsGroup.getParentLinkColumnName());
533 if(!metricsGroup.isDisconnected())
535 auto metrics = metricsGroup.getChildren();
536 bool sendSystemMetrics(
false), sendProcessMetrics(
false);
537 for(
auto& metric : metrics)
539 if(!metric.second.status())
542 __COUTT__ <<
"Inserting metric... " << parentPath << __E__;
543 std::string localParentPath =
544 parentPath +
"/" + metricsGroup.getParentLinkColumnName() +
":" +
545 metric.second.getTableName() +
":" + metricsGroup.getParentLinkIndex() +
546 ":" + metricsGroup.getParentLinkID() +
"/" + metric.second.getValue();
547 __COUTT__ <<
"Inserting metric... " << localParentPath << __E__;
549 OUTCL(metric.second.getNode(
"metricKey").getValue() <<
": {",
550 metric.second.hasComment() ? metric.second.getComment() :
"");
553 if(metric.second.getNode(
"sendSystemMetrics").getValue<
bool>())
555 sendSystemMetrics =
true;
557 if(metric.second.getNode(
"sendProcessMetrics").getValue<
bool>())
559 sendProcessMetrics =
true;
562 OUTCLF(
"metricPluginType: "
563 << metric.second.getNode(
"metricPluginType").getValue(),
567 "level_string: " << metric.second.getNode(
"metricLevelString").getValue(),
569 "metricLevelString");
571 auto metricParametersGroup = metric.second.getNode(
"metricParametersLink");
572 if(!metricParametersGroup.isDisconnected())
574 auto metricParameters = metricParametersGroup.getChildren();
575 for(
auto& metricParameter : metricParameters)
577 if(!metricParameter.second.status())
580 __COUTT__ <<
"Inserting metric... " << localParentPath << __E__;
581 std::string localParentPath2 =
582 localParentPath +
"/" +
583 metricParametersGroup.getParentLinkColumnName() +
":" +
584 metricParameter.second.getTableName() +
":" +
585 metricParametersGroup.getParentLinkIndex() +
":" +
586 metricParametersGroup.getParentLinkID() +
"/" +
587 metricParameter.second.getValue();
588 __COUTT__ <<
"Inserting metric... " << localParentPath2 << __E__;
589 OUTCL2(metricParameter.second.getNode(
"metricParameterKey").getValue()
591 << metricParameter.second.getNode(
"metricParameterValue")
593 metricParameter.second.hasComment()
594 ? metricParameter.second.getComment()
597 if(!metricParameter.second.status())
602 OUT <<
"} # end " << metric.second.getNode(
"metricKey").getValue()
605 if(!metric.second.status())
609 __COUTT__ <<
"Inserting metric send... " << parentPath << __E__;
610 std::string localParentPath =
611 parentPath +
"/" + metricsGroup.getParentLinkColumnName() +
":" +
612 metricsGroup.getTableName() +
":" + metricsGroup.getParentLinkIndex() +
":" +
613 metricsGroup.getParentLinkID();
614 if(sendSystemMetrics)
616 __COUTT__ <<
"Inserting send_system_metrics... " << localParentPath << __E__;
617 OUTCLF(
"send_system_metrics: true ",
618 "true, if any children are true",
619 "*/sendSystemMetrics");
622 OUTCLF(
"# send_system_metrics: false ",
623 "true, if any children are true",
624 "*/sendSystemMetrics");
626 if(sendProcessMetrics)
628 __COUTT__ <<
"Inserting send_process_metrics... " << localParentPath << __E__;
629 OUTCLF(
"send_process_metrics: true ",
630 "true, if any children are true",
631 "*/sendProcessMetrics");
634 OUTCLF(
"# send_process_metrics: false ",
635 "true, if any children are true",
636 "*/sendProcessMetrics");
640 __COUTS__(3) <<
"No metrics found" << __E__;
641 std::string localParentPath =
642 parentPath +
"/" + metricsGroup.getParentLinkColumnName();
643 OUTCL(
"# no metrics found",
"" );
647 OUT <<
"} # end metrics\n\n";
651 void ARTDAQTableBase::outputBoardReaderFHICL(
654 size_t routingTimeoutMs ,
655 size_t routingRetryCount )
657 if(ARTDAQ_DONOTWRITE_FCL)
659 __COUT__ <<
"Skipping fcl generation." << __E__;
788 std::string filename =
789 getFHICLFilename(ARTDAQAppType::BoardReader, boardReaderNode.
getValue());
795 std::string tabStr =
"";
796 std::string commentStr =
"";
799 out.open(filename, std::fstream::out | std::fstream::trunc);
802 __SS__ <<
"Failed to open ARTDAQ BoardReader fcl file: " << filename << __E__;
810 OUT <<
"###########################################################" << __E__;
812 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::BoardReader)
813 <<
" fcl configuration file produced by otsdaq." << __E__;
816 OUT <<
"# Original filename: \t" << filename << __E__;
817 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(ARTDAQAppType::BoardReader)
818 <<
" UID:\t" << boardReaderNode.
getValue() << __E__;
820 OUT <<
"###########################################################" << __E__;
834 catch(
const std::runtime_error&)
836 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
841 std::string parentPath =
844 OUTC(
"# start of " << getTypeString(ARTDAQAppType::BoardReader) <<
" '"
845 << boardReaderNode.
getValue() <<
"' fcl",
850 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
851 <<
" preamble parameters... " << parentPath << __E__;
857 boardReaderNode.
getNode(
"preambleParametersLink"),
864 __COUTT__ <<
"Generating daq block..." << __E__;
871 OUT <<
"fragment_receiver: {\n";
878 "daq generator plug-in type" ,
879 "daqGeneratorPluginType" );
880 OUTCF(
"fragment_type"
883 "generator data fragment type" ,
884 "daqGeneratorFragmentType" );
886 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
887 <<
" DAQ Parameters... " << parentPath << __E__;
893 boardReaderNode.
getNode(
"daqParametersLink"),
898 auto fragmentId = boardReaderNode.
getNode(
"daqFragmentIDs");
899 std::string value = fragmentId.
getValue();
900 if(value.size() < 2 || value[0] !=
'[' || value[value.size() - 1] !=
']')
902 __SS__ <<
"Invalid 'daqFragmentIDs' - the value must be a valid fcl "
903 "array with starting and ending square brackets: [ ]"
907 __COUTS__(20) <<
"fragment_ids: " << fragmentId.getValue() << __E__;
908 OUTCF(
"fragment_ids: " << fragmentId.getValue(),
914 __COUTT__ <<
"Ignoring missing daqFragmentIDs column associated with "
915 "fragment_ids for Board Reader."
918 OUTCF(
"# fragment_ids not specified, but could be",
"",
"daqFragmentIDs");
924 OUT <<
"destinations: { # empty placeholder, '"
925 << getTypeString(ARTDAQAppType::BoardReader)
926 <<
"' destinations handled by artdaq interface\n";
929 OUT <<
"routing_table_config: {\n";
932 auto readerSubsystemID = 1;
933 auto readerSubsystemLink = boardReaderNode.
getNode(
"SubsystemLink");
934 if(!readerSubsystemLink.isDisconnected())
936 readerSubsystemID = getSubsytemId(readerSubsystemLink);
938 if(info_.subsystems[readerSubsystemID].hasRoutingManager)
940 std::string localParentPath =
941 parentPath +
"/" + readerSubsystemLink.getParentLinkColumnName() +
":" +
942 readerSubsystemLink.getTableName() +
"/" + readerSubsystemLink.getValue();
943 __COUTT__ <<
"Inserting routing manager... " << localParentPath << __E__;
944 OUTCL(
"use_routing_manager: true",
945 "auto-generated because subsystem '" +
946 std::to_string(readerSubsystemID) +
"' has Routing Manager added");
948 OUTCLF(
"routing_manager_hostname: \""
949 << info_.subsystems[readerSubsystemID].routingManagerHost <<
"\"",
951 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
952 OUT <<
"table_update_port: 0\n";
953 OUT <<
"table_update_address: \"0.0.0.0\"\n";
954 OUT <<
"table_update_multicast_interface: \"0.0.0.0\"\n";
955 OUT <<
"table_acknowledge_port : 0\n";
956 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
957 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
961 OUTCF(
"use_routing_manager: false",
962 "auto-generated if subsystem '" + std::to_string(readerSubsystemID) +
963 "' has Routing Manager added",
964 readerSubsystemLink.getParentLinkColumnName());
971 OUT <<
"} # end fragment_receiver\n";
976 OUT <<
"} # end daq\n\n";
981 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::BoardReader)
982 <<
" add-on parameters... " << parentPath << __E__;
987 boardReaderNode.
getNode(
"addOnParametersLink"),
992 OUTC(
"# end of " << getTypeString(ARTDAQAppType::BoardReader) <<
" '"
993 << boardReaderNode.
getValue() <<
"' fcl",
995 __COUTT__ <<
"outputBoardReaderFHICL DONE" << __E__;
999 __SS__ <<
"\n\nError while generating FHiCL for "
1000 << getTypeString(ARTDAQAppType::BoardReader) <<
" node at filename '"
1001 << filename <<
"'" << __E__;
1006 catch(
const std::runtime_error& e)
1008 ss <<
" Here is the error: " << e.what() << __E__;
1010 catch(
const std::exception& e)
1012 ss <<
" Here is the error: " << e.what() << __E__;
1028 ARTDAQAppType appType,
1030 size_t routingTimeoutMs ,
1031 size_t routingRetryCount ,
1032 std::string* returnFcl )
1034 if(ARTDAQ_DONOTWRITE_FCL)
1036 __COUT__ <<
"Skipping fcl generation." << __E__;
1040 std::string filename = getFHICLFilename(appType, receiverNode.
getValue());
1045 std::ostringstream out;
1047 std::string tabStr =
"";
1048 std::string commentStr =
"";
1050 __COUTV__(filename);
1051 outf.open(filename, std::fstream::out | std::fstream::trunc);
1054 __SS__ <<
"Failed to open ARTDAQ fcl file: " << filename << __E__;
1062 OUT <<
"###########################################################" << __E__;
1063 OUT <<
"#" << __E__;
1064 OUT <<
"# artdaq " << getTypeString(appType)
1065 <<
" fcl configuration file produced by otsdaq." << __E__;
1066 OUT <<
"# Creation time: \t"
1068 OUT <<
"# Original filename: \t" << filename << __E__;
1069 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(appType) <<
" UID:\t"
1070 << receiverNode.
getValue() << __E__;
1071 OUT <<
"#" << __E__;
1072 OUT <<
"###########################################################" << __E__;
1084 *returnFcl = out.str();
1085 __COUTVS__(21, *returnFcl);
1092 catch(
const std::runtime_error&)
1094 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
1099 std::string parentPath =
1102 OUTC(
"# start of " << getTypeString(appType) <<
" '" << receiverNode.
getValue()
1108 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" preamble parameters... "
1109 << parentPath << __E__;
1115 receiverNode.
getNode(
"preambleParametersLink"),
1122 __COUTT__ <<
"Generating daq block..." << __E__;
1124 auto daq = receiverNode.
getNode(
"daqLink");
1125 if(!daq.isDisconnected())
1128 OUTCF(
"daq: {",
"" , daq.getParentLinkColumnName());
1131 if(appType == ARTDAQAppType::EventBuilder)
1132 OUT <<
"event_builder: {\n";
1134 OUT <<
"aggregator: {\n";
1139 std::stringstream outSs;
1140 if(appType == ARTDAQAppType::DataLogger)
1141 outSs <<
"is_datalogger: true";
1142 else if(appType == ARTDAQAppType::Dispatcher)
1143 outSs <<
"is_dispatcher: true";
1144 if(outSs.str().size())
1146 addCommentWhitespace(
1148 tabStr.size() * TABSZ + commentStr.size() + outSs.str().size());
1149 outSs <<
"auto-generated based on app type '"
1150 << getTypeString(appType) <<
"'\n";
1157 std::string parentPath = daq.getParentTableName() +
"/" +
1158 daq.getParentRecordName() +
"/" +
1159 daq.getParentLinkColumnName() +
":" +
1160 daq.getTableName() +
"/" + daq.getValue();
1161 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" DAQ Parameters... "
1162 << parentPath << __E__;
1167 daq.getNode(
"daqParametersLink"),
1172 if(appType == ARTDAQAppType::EventBuilder)
1175 OUT <<
"routing_token_config: {\n";
1178 auto builderSubsystemID = 1;
1179 auto builderSubsystemLink = receiverNode.
getNode(
"SubsystemLink");
1180 if(!builderSubsystemLink.isDisconnected())
1182 builderSubsystemID = getSubsytemId(builderSubsystemLink);
1184 if(info_.subsystems[builderSubsystemID].hasRoutingManager)
1186 std::string localParentPath =
1188 builderSubsystemLink.getParentLinkColumnName() +
":" +
1189 builderSubsystemLink.getTableName() +
"/" +
1190 builderSubsystemLink.getValue();
1191 __COUTT__ <<
"Inserting routing manager... " << localParentPath
1193 OUTCL(
"use_routing_manager: true",
1194 "auto-generated because subsystem '" +
1195 std::to_string(builderSubsystemID) +
1196 "' has Routing Manager added");
1198 OUTCLF(
"routing_manager_hostname: \""
1199 << info_.subsystems[builderSubsystemID].routingManagerHost
1202 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
1203 OUT <<
"routing_token_port: 0\n";
1207 OUTCF(
"use_routing_manager: false",
1208 "auto-generated if subsystem '" +
1209 std::to_string(builderSubsystemID) +
1210 "' has Routing Manager added",
1211 builderSubsystemLink.getParentLinkColumnName());
1217 __COUTT__ <<
"Adding sources placeholder" << __E__;
1219 OUT <<
"sources: { # empty placeholder, '" << getTypeString(appType)
1220 <<
"' sources handled by artdaq interface\n";
1225 if(appType == ARTDAQAppType::EventBuilder)
1226 OUT <<
"} # end event_builder\n";
1228 OUT <<
"} # end aggregator\n";
1233 OUT <<
"} # end daq\n\n";
1237 __COUTS__(3) <<
"No daq found" << __E__;
1238 std::string localParentPath =
1239 parentPath +
"/" + daq.getParentLinkColumnName();
1240 OUTCL(
"# no daq found",
"" );
1245 __COUTT__ <<
"Filling art block..." << __E__;
1248 receiverNode.
getNode(ARTDAQTableBase::colARTDAQNotReader_.colLinkToArt_);
1249 if(!art.isDisconnected())
1251 std::string localParentPath = parentPath +
"/" +
1253 art.getTableName() +
"/" + art.getValue();
1254 OUTCF(
"art: {",
"" , art.getParentLinkColumnName());
1263 receiverNode.
getNode(
"SubsystemLink"),
1268 OUT <<
"} # end art\n\n";
1272 __COUTS__(3) <<
"No art found" << __E__;
1273 std::string localParentPath =
1274 parentPath +
"/" + art.getParentLinkColumnName();
1275 OUTCL(
"# no art found",
"" );
1280 __COUTT__ <<
"Inserting " << getTypeString(appType) <<
" add-on parameters... "
1281 << parentPath << __E__;
1286 receiverNode.
getNode(
"addOnParametersLink"),
1292 OUTC(
"# end of " << getTypeString(appType) <<
" '" << receiverNode.
getValue()
1295 __COUTT__ <<
"outputDataReceiverFHICL DONE" << __E__;
1299 __SS__ <<
"\n\nError while generating FHiCL for " << getTypeString(appType)
1300 <<
" node at filename '" << filename <<
"'" << __E__;
1305 catch(
const std::runtime_error& e)
1307 ss <<
" Here is the error: " << e.what() << __E__;
1309 catch(
const std::exception& e)
1311 ss <<
" Here is the error: " << e.what() << __E__;
1316 *returnFcl = out.str();
1317 __COUTVS__(21, *returnFcl);
1326 *returnFcl = out.str();
1327 __COUTVS__(21, *returnFcl);
1338 if(ARTDAQ_DONOTWRITE_FCL)
1340 __COUT__ <<
"Skipping fcl generation." << __E__;
1344 std::string filename =
1345 getFHICLFilename(ARTDAQAppType::Monitor, monitorNode.
getValue());
1351 std::string tabStr =
"";
1352 std::string commentStr =
"";
1354 __COUTV__(filename);
1355 out.open(filename, std::fstream::out | std::fstream::trunc);
1358 __SS__ <<
"Failed to open ARTDAQ fcl file: " << filename << __E__;
1366 OUT <<
"###########################################################" << __E__;
1367 OUT <<
"#" << __E__;
1368 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::Monitor)
1369 <<
" fcl configuration file produced by otsdaq." << __E__;
1370 OUT <<
"# Creation time: \t"
1372 OUT <<
"# Original filename: \t" << filename << __E__;
1373 OUT <<
"# otsdaq-ARTDAQ " << getTypeString(ARTDAQAppType::Monitor) <<
" UID:\t"
1374 << monitorNode.
getValue() << __E__;
1375 OUT <<
"#" << __E__;
1376 OUT <<
"###########################################################" << __E__;
1390 catch(
const std::runtime_error&)
1392 __COUTT__ <<
"Ignoring error, assume this a valid UID node." << __E__;
1399 std::string parentPath =
1403 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::Monitor)
1404 <<
" preamble parameters... " << parentPath << __E__;
1409 monitorNode.
getNode(
"preambleParametersLink"),
1418 monitorNode.
getNode(ARTDAQTableBase::colARTDAQNotReader_.colLinkToArt_);
1419 if(!art.isDisconnected())
1422 OUT <<
"services.message: { "
1423 << artdaq::generateMessageFacilityConfiguration(
1424 mf::GetApplicationName().c_str(),
true,
false)
1426 OUT <<
"services.message.destinations.file: {type: \"GenFile\" threshold: "
1427 "\"INFO\" seperator: \"-\""
1428 <<
" pattern: \"" << monitorNode.
getValue() <<
"-%?H%t-%p.log"
1430 <<
" timestamp_pattern: \"%Y%m%d%H%M%S\""
1431 <<
" directory: \"" << __ENV__(
"OTSDAQ_LOG_ROOT") <<
"/"
1433 <<
" append : false }\n";
1436 auto dispatcherLink = monitorNode.
getNode(
"dispatcherLink");
1437 if(!dispatcherLink.isDisconnected())
1439 std::string monitorHost =
1440 monitorNode.
getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
1442 std::string dispatcherHost =
1443 dispatcherLink.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
1444 .getValueWithDefault(
"localhost");
1445 OUT <<
"source.dispatcherHost: \"" << dispatcherHost <<
"\"\n";
1446 int dispatcherPort = dispatcherLink.getNode(
"DispatcherPort").getValue<
int>();
1447 OUT <<
"source.dispatcherPort: " << dispatcherPort <<
"\n";
1448 OUT <<
"source.commanderPluginType: xmlrpc\n";
1451 int om_tcp_listen_port =
1453 int disp_fake_rank =
1454 dispatcherLink.getNode(
"DispatcherID").getValueWithDefault<
int>(200);
1456 size_t max_fragment_size = monitorNode.
getNode(
"max_fragment_size_words")
1458 std::string transfer_plugin_type = monitorNode.
getNode(
"transfer_plugin_type")
1461 OUT <<
"TransferPluginConfig: {\n";
1463 OUT <<
"transferPluginType: " << transfer_plugin_type <<
"\n";
1464 OUT <<
"host_map: [{ rank: " << disp_fake_rank <<
" host: \""
1465 << dispatcherHost <<
"\"}, { rank: " << om_rank <<
" host: \""
1466 << monitorHost <<
"\"}]\n";
1467 OUT <<
"max_fragment_size_words: " << max_fragment_size <<
"\n";
1468 OUT <<
"source_rank: " << disp_fake_rank <<
"\n";
1469 OUT <<
"destination_rank: " << om_rank <<
"\n";
1470 OUT <<
"port: " << om_tcp_listen_port <<
"\n";
1471 OUT <<
"unique_label: " << monitorNode.
getValue() <<
"_to_"
1472 << dispatcherLink.getValue() <<
"\n";
1475 OUT <<
"source.transfer_plugin: @local::TransferPluginConfig \n";
1476 auto dispatcherArt = monitorNode.
getNode(
"dispatcherArtLink");
1477 if(!dispatcherArt.isDisconnected())
1479 OUT <<
"source.dispatcher_config: {\n";
1485 OUT <<
"filter_paths: [\n";
1489 auto filterPathsLink = monitorNode.
getNode(
"filterPathsLink");
1490 if(!filterPathsLink.isDisconnected())
1497 for(
auto& filterPath : filterPaths)
1503 if(!filterPath.second.status())
1506 OUT <<
"name: " << filterPath.second.getNode(
"Name").getValue()
1508 OUT <<
"path: " << filterPath.second.getNode(
"Path").getValue()
1512 if(!filterPath.second.status())
1521 OUT <<
"unique_label: " << monitorNode.
getValue() <<
"\n";
1535 __COUTT__ <<
"Inserting " << getTypeString(ARTDAQAppType::Monitor)
1536 <<
" add-on parameters... " << parentPath << __E__;
1541 monitorNode.
getNode(
"addOnParametersLink"),
1546 __COUTT__ <<
"outputOnlineMonitorFHICL DONE" << __E__;
1550 __SS__ <<
"\n\nError while generating FHiCL for "
1551 << getTypeString(ARTDAQAppType::Monitor) <<
" node at filename '"
1552 << filename <<
"'" << __E__;
1557 catch(
const std::runtime_error& e)
1559 ss <<
" Here is the error: " << e.what() << __E__;
1561 catch(
const std::exception& e)
1563 ss <<
" Here is the error: " << e.what() << __E__;
1577 std::string& tabStr,
1578 std::string& commentStr,
1579 const std::string& parentPath,
1582 size_t routingTimeoutMs,
1583 size_t routingRetryCount)
1587 __COUTT__ <<
"Filling art.services parentPath =" << parentPath << __E__;
1588 auto services = art.
getNode(
"servicesLink");
1589 if(!services.isDisconnected())
1591 std::string localParentPath =
1593 services.getTableName() +
"/" +
1594 services.getValue();
1595 __COUTT__ <<
"Inserting services... " << localParentPath << __E__;
1596 OUTCL(
"services: {", services.hasComment() ? services.getComment() :
"");
1601 __COUTT__ <<
"Inserting services parameters... " << localParentPath << __E__;
1606 services.getNode(
"ServicesParametersLink"),
1612 OUT <<
"ArtdaqSharedMemoryServiceInterface: {\n";
1614 OUT <<
"service_provider: "
1615 "ArtdaqSharedMemoryService \n";
1617 OUTCLF(
"waiting_time: " << services.getNode(
"sharedMemoryWaitingTime").getValue(),
1619 "sharedMemoryWaitingTime");
1620 OUTCLF(
"resume_after_timeout: "
1621 << (services.getNode(
"sharedMemoryResumeAfterTimeout").getValue<
bool>()
1625 "sharedMemoryResumeAfterTimeout");
1627 OUT <<
"} # end ArtdaqSharedMemoryServiceInterface\n\n";
1629 OUT <<
"ArtdaqFragmentNamingServiceInterface: {\n";
1631 OUT <<
"service_provider: "
1632 "ArtdaqFragmentNamingService \n";
1633 OUTCLF(
"helper_plugin: "
1634 << services.getNode(
"fragmentNamingServiceProvider").getValue(),
1636 "fragmentNamingServiceProvider");
1638 OUT <<
"} # end ArtdaqFragmentNamingServiceInterface\n\n";
1642 __COUTT__ <<
"Inserting services parameters... " << localParentPath << __E__;
1647 services.getNode(
"ServicesParametersLink"),
1653 OUT <<
"} # end services\n\n";
1657 __COUTS__(3) <<
"No services found" << __E__;
1658 std::string localParentPath =
1659 parentPath +
"/" + services.getParentLinkColumnName();
1660 OUTCL(
"# no services found",
"" );
1665 __COUTT__ <<
"Filling art.outputs parentPath =" << parentPath << __E__;
1666 auto outputs = art.
getNode(
"outputsLink");
1667 if(!outputs.isDisconnected())
1669 std::string localParentPath =
1672 __COUTT__ <<
"Inserting output... " << localParentPath << __E__;
1673 OUTCL(
"outputs: {",
"" );
1676 auto outputPlugins = outputs.getChildren();
1677 for(
auto& outputPlugin : outputPlugins)
1679 if(!outputPlugin.second.status())
1682 __COUTT__ <<
"Inserting output parameters... " << localParentPath << __E__;
1683 std::string localParentPath2 =
1684 localParentPath +
":" + outputPlugin.second.getTableName() +
":" +
1685 outputs.getParentLinkIndex() +
":" + outputs.getParentLinkID() +
"/" +
1686 outputPlugin.second.getValue();
1687 __COUTT__ <<
"Inserting output... " << localParentPath2 << __E__;
1689 outputPlugin.second.getNode(
"outputKey").getValue() <<
": {",
1690 outputPlugin.second.hasComment() ? outputPlugin.second.getComment() :
"",
1694 __COUTT__ <<
"insertModuleType... " << localParentPath2 << __E__;
1695 std::string moduleType =
1700 outputPlugin.second.getNode(
"outputModuleType"));
1704 __COUTT__ <<
"Inserting output parameters... " << localParentPath << __E__;
1709 outputPlugin.second.getNode(
"outputModuleParameterLink"),
1714 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1715 "BinaryNetOutput" ||
1716 outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1719 OUT <<
"destinations: { # empty placeholder, '"
1720 << outputPlugin.second.getNode(
"outputModuleType").getValue()
1721 <<
"' destinations handled by artdaq interface\n";
1724 OUT <<
"routing_table_config: {\n";
1727 auto mySubsystemID = 1;
1728 auto destinationSubsystemID = 1;
1731 mySubsystemID = getSubsytemId(subsystemLink);
1733 destinationSubsystemID = info_.subsystems[mySubsystemID].destination;
1734 if(info_.subsystems[destinationSubsystemID].hasRoutingManager)
1736 std::string localParentPath =
1739 __COUTT__ <<
"Inserting routing manager... " << localParentPath
1741 OUTCL(
"use_routing_manager: true",
1742 "auto-generated because subsystem '" +
1743 std::to_string(destinationSubsystemID) +
1744 "' has Routing Manager added");
1747 "routing_manager_hostname: \""
1748 << info_.subsystems[destinationSubsystemID].routingManagerHost
1751 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME);
1752 OUT <<
"table_update_port: 0\n";
1753 OUT <<
"table_update_address: \"0.0.0.0\"\n";
1754 OUT <<
"table_update_multicast_interface: \"0.0.0.0\"\n";
1755 OUT <<
"table_acknowledge_port : 0\n";
1756 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
1757 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
1761 OUTCF(
"use_routing_manager: false",
1762 "auto-generated if subsystem '" +
1763 std::to_string(destinationSubsystemID) +
1764 "' has Routing Manager added",
1768 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1771 info_.subsystems[mySubsystemID].eventMode =
true;
1777 if(outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1779 outputPlugin.second.getNode(
"outputModuleType").getValue() ==
1780 "TransferOutputReliable")
1782 OUT <<
"transfer_plugin: @local::TransferPluginConfig \n";
1786 OUT <<
"} # end " << outputPlugin.second.getNode(
"outputKey").getValue()
1789 if(!outputPlugin.second.status())
1794 OUT <<
"} # end outputs\n\n";
1798 __COUTS__(3) <<
"No outputs found" << __E__;
1799 std::string localParentPath =
1800 parentPath +
"/" + outputs.getParentLinkColumnName();
1801 OUTCL(
"# no outputs found",
"" );
1806 __COUTT__ <<
"Filling art.physics parentPath =" << parentPath << __E__;
1807 auto physics = art.
getNode(
"physicsLink");
1808 if(!physics.isDisconnected())
1810 __COUTT__ <<
"Inserting physics... " << parentPath << __E__;
1811 std::string localParentPath = parentPath +
"/" +
1812 physics.getParentLinkColumnName() +
":" +
1813 physics.getTableName() +
"/" +
1817 OUTCL(
"physics: {", physics.hasComment() ? services.getComment() :
"");
1823 __COUTT__ <<
"Inserting physics other parameters... " << localParentPath << __E__;
1828 physics.getNode(
"physicsOtherParametersLink"),
1829 "physicsParameter" ,
1833 auto analyzers = physics.getNode(
"analyzersLink");
1834 if(!analyzers.isDisconnected())
1836 __COUTT__ <<
"Inserting art.physics.analyzers... " << localParentPath
1838 std::string localParentPath2 =
1839 localParentPath +
"/" + analyzers.getParentLinkColumnName();
1840 __COUTT__ <<
"Inserting art.physics.analyzers... " << localParentPath2
1845 OUTCL2(
"analyzers: {",
"" );
1849 auto modules = analyzers.getChildren();
1850 for(
auto& module : modules)
1852 if(!module.second.status())
1859 auto analyzerNodeParameterLink =
1860 module.second.getNode(
"analyzerModuleParameterLink");
1863 __COUTT__ <<
"Inserting analyzer @table parameters... "
1864 << localParentPath2 << __E__;
1865 std::string localParentPath3 =
1866 localParentPath2 +
":" + module.second.getTableName() +
":" +
1867 analyzers.getParentLinkIndex() +
":" + analyzers.getParentLinkID() +
1868 "/" + module.second.getValue();
1869 __COUTT__ <<
"Inserting analyzer @table parameters... "
1870 << localParentPath3 << __E__;
1875 analyzerNodeParameterLink,
1876 "analyzerParameter" ,
1880 OUT << module.second.getNode(
"analyzerKey").getValue() <<
": {\n";
1886 module.second.getNode(
"analyzerModuleType"));
1890 __COUTT__ <<
"Inserting analayzer not @table parameters... "
1891 << localParentPath3 << __E__;
1896 analyzerNodeParameterLink,
1897 "analyzerParameter" ,
1904 if(!module.second.status())
1908 OUT <<
"} # end physics.analyzers\n\n";
1912 __COUTS__(3) <<
"No analyzers found" << __E__;
1913 std::string localParentPath2 =
1914 localParentPath +
"/" + analyzers.getParentLinkColumnName();
1915 OUTCL2(
"# no analyzers found",
"" );
1918 auto producers = physics.getNode(
"producersLink");
1919 if(!producers.isDisconnected())
1921 __COUTT__ <<
"Inserting art.physics.producers... " << localParentPath
1923 std::string localParentPath2 =
1924 localParentPath +
"/" + producers.getParentLinkColumnName();
1928 OUTCL2(
"producers: {",
"" );
1932 auto modules = producers.getChildren();
1933 for(
auto& module : modules)
1935 if(!module.second.status())
1942 auto producerNodeParameterLink =
1943 module.second.getNode(
"producerModuleParameterLink");
1946 __COUTT__ <<
"Inserting producer @table parameters... "
1947 << localParentPath2 << __E__;
1948 std::string localParentPath3 =
1949 localParentPath2 +
":" + module.second.getTableName() +
":" +
1950 producers.getParentLinkIndex() +
":" + producers.getParentLinkID() +
1951 "/" + module.second.getValue();
1952 __COUTT__ <<
"Inserting producer @table parameters... "
1953 << localParentPath3 << __E__;
1958 producerNodeParameterLink,
1959 "producerParameter" ,
1963 if(module.second.status() &&
1964 module.second.getNode(
"producerModuleType").getValue() ==
"")
1966 std::string tmp = localParentPath2;
1967 localParentPath2 = localParentPath3;
1968 OUTCL2F(
"# skipping '" << module.second.getValue()
1969 <<
"' with empty module type",
1971 "producerModuleType");
1972 localParentPath2 = tmp;
1976 OUT << module.second.getNode(
"producerKey").getValue() <<
": {\n";
1983 module.second.getNode(
"producerModuleType"));
1987 __COUTT__ <<
"Inserting producer not @table parameters... "
1988 << localParentPath3 << __E__;
1993 producerNodeParameterLink,
1994 "producerParameter" ,
2001 if(!module.second.status())
2005 OUT <<
"} # end physics.producers\n\n";
2009 __COUTS__(3) <<
"No producers found" << __E__;
2010 std::string localParentPath2 =
2011 localParentPath +
"/" + producers.getParentLinkColumnName();
2012 OUTCL2(
"# no producers found",
"" );
2015 auto filters = physics.getNode(
"filtersLink");
2016 if(!filters.isDisconnected())
2018 __COUTT__ <<
"Inserting art.physics.filters... " << localParentPath << __E__;
2019 std::string localParentPath2 =
2020 localParentPath +
"/" + filters.getParentLinkColumnName();
2024 OUTCL2(
"filters: {",
"" );
2028 auto modules = filters.getChildren();
2029 for(
auto& module : modules)
2031 if(!module.second.status())
2038 auto filterNodeParameterLink =
2039 module.second.getNode(
"filterModuleParameterLink");
2042 __COUTT__ <<
"Inserting filter @table parameters... " << localParentPath2
2044 std::string localParentPath3 =
2045 localParentPath2 +
":" + module.second.getTableName() +
":" +
2046 filters.getParentLinkIndex() +
":" + filters.getParentLinkID() +
"/" +
2047 module.second.getValue();
2048 __COUTT__ <<
"Inserting filter @table parameters... " << localParentPath3
2054 filterNodeParameterLink,
2058 if(module.second.status() &&
2059 module.second.getNode(
"filterModuleType").getValue() ==
"")
2061 std::string tmp = localParentPath2;
2062 localParentPath2 = localParentPath3;
2063 OUTCL2F(
"# skipping '" << module.second.getValue()
2064 <<
"' with empty module type",
2066 "filterModuleType");
2067 localParentPath2 = tmp;
2071 OUT << module.second.getNode(
"filterKey").getValue() <<
": {\n";
2078 module.second.getNode(
"filterModuleType"));
2082 __COUTT__ <<
"Inserting filter not @table parameters... "
2083 << localParentPath3 << __E__;
2088 filterNodeParameterLink,
2096 if(!module.second.status())
2100 OUT <<
"} # end physics.filters\n\n";
2104 __COUTS__(3) <<
"No filters found" << __E__;
2105 std::string localParentPath2 =
2106 localParentPath +
"/" + services.getParentLinkColumnName();
2107 OUTCL2(
"# no filters found",
"" );
2112 __COUTT__ <<
"Inserting art.physics not @table parameters... " << localParentPath
2118 physics.getNode(
"physicsOtherParametersLink"),
2119 "physicsParameter" ,
2124 OUT <<
"} # end physics\n\n";
2128 __COUTS__(3) <<
"No physics found" << __E__;
2129 std::string localParentPath =
2130 parentPath +
"/" + physics.getParentLinkColumnName();
2131 OUTCL(
"# no physics found",
"" );
2136 __COUTT__ <<
"Filling art.source" << __E__;
2137 auto source = art.
getNode(
"sourceLink");
2138 if(!source.isDisconnected())
2140 __COUTT__ <<
"Inserting source... " << parentPath << __E__;
2141 std::string localParentPath = parentPath +
"/" +
2142 source.getParentLinkColumnName() +
":" +
2143 source.getTableName() +
"/" +
2145 OUTCL(
"source: {", source.hasComment() ? source.getComment() :
"");
2148 out, tabStr, commentStr, parentPath, source.getNode(
"sourceModuleType"));
2154 std::string localParentPath = parentPath +
"/" + source.getParentLinkColumnName();
2155 OUTCL(
"source: { # auto-generated default, to change provide a source link",
2158 OUT <<
"module_type: ArtdaqInput";
2165 __COUTT__ <<
"Writing art.process_name" << __E__;
2166 OUTCF(
"process_name: " << art.
getNode(ARTDAQTableBase::colARTDAQArt_.colProcessName_),
2168 ARTDAQTableBase::colARTDAQArt_.colProcessName_);
2172 __COUTT__ <<
"Inserting art @table parameters... " << parentPath << __E__;
2177 art.
getNode(
"AddOnParametersLink"),
2185 void ARTDAQTableBase::outputRoutingManagerFHICL(
2187 size_t routingTimeoutMs ,
2188 size_t routingRetryCount )
2190 if(ARTDAQ_DONOTWRITE_FCL)
2192 __COUT__ <<
"Skipping fcl generation." << __E__;
2196 std::string filename =
2197 getFHICLFilename(ARTDAQAppType::RoutingManager, routingManagerNode.
getValue());
2203 std::string tabStr =
"";
2204 std::string commentStr =
"";
2206 __COUTV__(filename);
2207 out.open(filename, std::fstream::out | std::fstream::trunc);
2210 __SS__ <<
"Failed to open ARTDAQ RoutingManager fcl file: " << filename << __E__;
2218 OUT <<
"###########################################################" << __E__;
2219 OUT <<
"#" << __E__;
2220 OUT <<
"# artdaq " << getTypeString(ARTDAQAppType::RoutingManager)
2221 <<
" fcl configuration file produced by otsdaq." << __E__;
2222 OUT <<
"# Creation time: \t"
2224 OUT <<
"# Original filename: \t" << filename << __E__;
2225 OUT <<
"# otsdaq-ARTDAQ RoutingManager UID:\t" << routingManagerNode.
getValue()
2227 OUT <<
"#" << __E__;
2228 OUT <<
"###########################################################" << __E__;
2242 catch(
const std::runtime_error&)
2254 OUT <<
"policy: {\n";
2258 if(policyName ==
"DEFAULT")
2259 policyName =
"NoOp";
2260 OUT <<
"policy: " << policyName <<
"\n";
2261 OUT <<
"receiver_ranks: []\n";
2264 auto parametersLink = routingManagerNode.
getNode(
"routingPolicyParametersLink");
2265 if(!parametersLink.isDisconnected())
2268 for(
auto& parameter : parameters)
2270 if(!parameter.second.status())
2281 parameter.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT);
2282 OUT << parameter.second.getNode(
"daqParameterKey").getValue() <<
": "
2283 << parameter.second.getNode(
"daqParameterValue").getValue()
2284 << (comment.isDefaultValue() ?
"" : (
"\t # " + comment.getValue()))
2287 if(!parameter.second.status())
2295 OUT <<
"use_routing_manager: true\n";
2297 auto routingManagerSubsystemID = 1;
2298 auto routingManagerSubsystemLink = routingManagerNode.
getNode(
"SubsystemLink");
2299 std::string rmHost =
"localhost";
2300 if(!routingManagerSubsystemLink.isDisconnected())
2302 routingManagerSubsystemID = getSubsytemId(routingManagerSubsystemLink);
2303 rmHost = info_.subsystems[routingManagerSubsystemID].routingManagerHost;
2305 if(rmHost ==
"localhost" || rmHost ==
"127.0.0.1")
2307 char hostbuf[HOST_NAME_MAX + 1];
2308 gethostname(hostbuf, HOST_NAME_MAX);
2309 rmHost = std::string(hostbuf);
2313 OUT <<
"routing_manager_hostname: \"" << rmHost <<
"\"\n";
2314 OUT <<
"sender_ranks: []\n";
2315 OUT <<
"table_update_port: 0\n";
2316 OUT <<
"table_update_address: \"0.0.0.0\"\n";
2317 OUT <<
"table_acknowledge_port: 0\n";
2318 OUT <<
"token_receiver: {\n";
2321 OUT <<
"routing_token_port: 0\n";
2327 auto tableUpdateIntervalMs =
2329 if(tableUpdateIntervalMs !=
"DEFAULT")
2331 OUT <<
"table_update_interval_ms: " << tableUpdateIntervalMs <<
"\n";
2333 auto tableAckRetryCount =
2335 if(tableAckRetryCount !=
"DEFAULT")
2337 OUT <<
"table_ack_retry_count: " << tableAckRetryCount <<
"\n";
2340 OUT <<
"routing_timeout_ms: " << routingTimeoutMs <<
"\n";
2341 OUT <<
"routing_retry_count: " << routingRetryCount <<
"\n";
2352 __COUTT__ <<
"outputReaderFHICL DONE" << __E__;
2356 __SS__ <<
"\n\nError while generating FHiCL for "
2357 << getTypeString(ARTDAQAppType::RoutingManager) <<
" node at filename '"
2358 << filename <<
"'" << __E__;
2363 catch(
const std::runtime_error& e)
2365 ss <<
" Here is the error: " << e.what() << __E__;
2367 catch(
const std::exception& e)
2369 ss <<
" Here is the error: " << e.what() << __E__;
2381 bool getStatusFalseNodes ,
2383 size_t maxFragmentSizeBytes ,
2384 size_t routingTimeoutMs ,
2385 size_t routingRetryCount ,
2389 progressBar->
step();
2392 info_.subsystems.clear();
2393 info_.processes.clear();
2396 progressBar->
step();
2398 info_.subsystems[NULL_SUBSYSTEM_DESTINATION].id = NULL_SUBSYSTEM_DESTINATION;
2399 info_.subsystems[NULL_SUBSYSTEM_DESTINATION].label = NULL_SUBSYSTEM_DESTINATION_LABEL;
2404 __COUT__ <<
"artdaqSupervisorNode is disconnected." << __E__;
2410 std::chrono::steady_clock::time_point extractStartClock =
2411 std::chrono::steady_clock::now();
2412 std::chrono::steady_clock::time_point stageClock = extractStartClock;
2413 std::vector<std::pair<std::string, double>> stageTimes;
2415 maybeResetFHiCLTimingTrace();
2416 fhiclFlattenCount_ = 0;
2417 fhiclFlattenSeconds_ = 0;
2418 size_t thisInvocation = ++extractInvocation_;
2420 auto recordStageTime = [&](
const std::string& stageName) {
2421 stageTimes.emplace_back(stageName, artdaq::TimeUtils::GetElapsedTime(stageClock));
2422 stageClock = std::chrono::steady_clock::now();
2426 extractRoutingManagersInfo(artdaqSupervisorNode,
2427 getStatusFalseNodes,
2431 recordStageTime(
"RoutingManagers");
2432 __COUT__ <<
"artdaqSupervisorNode RoutingManager size: "
2433 << info_.processes.at(ARTDAQAppType::RoutingManager).size() << __E__;
2436 progressBar->
step();
2438 extractBoardReadersInfo(artdaqSupervisorNode,
2439 getStatusFalseNodes,
2441 maxFragmentSizeBytes,
2444 __COUT__ <<
"artdaqSupervisorNode BoardReader size: "
2445 << info_.processes.at(ARTDAQAppType::BoardReader).size() << __E__;
2446 recordStageTime(
"BoardReaders");
2449 progressBar->
step();
2451 extractEventBuildersInfo(
2452 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2453 __COUT__ <<
"artdaqSupervisorNode EventBuilder size: "
2454 << info_.processes.at(ARTDAQAppType::EventBuilder).size() << __E__;
2455 recordStageTime(
"EventBuilders");
2458 progressBar->
step();
2460 extractDataLoggersInfo(
2461 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2462 __COUT__ <<
"artdaqSupervisorNode DataLogger size: "
2463 << info_.processes.at(ARTDAQAppType::DataLogger).size() << __E__;
2464 recordStageTime(
"DataLoggers");
2467 progressBar->
step();
2469 extractDispatchersInfo(
2470 artdaqSupervisorNode, getStatusFalseNodes, doWriteFHiCL, maxFragmentSizeBytes);
2471 __COUT__ <<
"artdaqSupervisorNode Dispatcher size: "
2472 << info_.processes.at(ARTDAQAppType::Dispatcher).size() << __E__;
2473 recordStageTime(
"Dispatchers");
2476 progressBar->
step();
2484 std::stringstream summary;
2485 summary <<
"FHiCL TIMING TRACE: extractARTDAQInfo call #" << thisInvocation
2486 <<
" (doWriteFHiCL=" << (doWriteFHiCL ?
"true" :
"false") <<
") total "
2487 << artdaq::TimeUtils::GetElapsedTime(extractStartClock) <<
"s"
2488 <<
", of which flattenFHICL was " << fhiclFlattenCount_ <<
" file(s) in "
2489 << fhiclFlattenSeconds_ <<
"s"
2490 <<
"; this-config cumulative flattenFHICL (all passes): "
2491 << fhiclFlattenCountCumulative_ <<
" file(s) in "
2492 << fhiclFlattenSecondsCumulative_ <<
"s";
2493 for(
const auto& stageTime : stageTimes)
2494 summary <<
"\n " << stageTime.first <<
": " << stageTime.second <<
"s";
2495 __COUT_INFO__ << summary.str() << __E__;
2502 void ARTDAQTableBase::extractRoutingManagersInfo(
ConfigurationTree artdaqSupervisorNode,
2503 bool getStatusFalseNodes,
2505 size_t routingTimeoutMs,
2506 size_t routingRetryCount)
2508 __COUT__ <<
"Checking for Routing Managers..." << __E__;
2509 info_.processes[ARTDAQAppType::RoutingManager].clear();
2512 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToRoutingManagers_);
2515 std::vector<std::pair<std::string, ConfigurationTree>> routingManagers =
2518 __COUT__ <<
"There are " << routingManagers.size()
2519 <<
" configured Routing Managers" << __E__;
2521 for(
auto& routingManager : routingManagers)
2523 const std::string& rmUID = routingManager.first;
2525 if(getStatusFalseNodes || routingManager.second.status())
2527 std::string rmHost =
2528 routingManager.second
2529 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2530 .getValueWithDefault(
"localhost");
2531 if(rmHost ==
"localhost" || rmHost ==
"127.0.0.1")
2533 char hostbuf[HOST_NAME_MAX + 1];
2534 gethostname(hostbuf, HOST_NAME_MAX);
2535 rmHost = std::string(hostbuf);
2539 routingManager.second
2540 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2541 .getValueWithDefault(
"");
2543 int routingManagerSubsystemID = 1;
2545 routingManager.second.
getNode(
2546 ARTDAQTableBase::ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2549 routingManagerSubsystemID =
2550 getSubsytemId(routingManagerSubsystemLink);
2553 info_.subsystems[routingManagerSubsystemID].id =
2554 routingManagerSubsystemID;
2556 const std::string& routingManagerSubsystemName =
2560 info_.subsystems[routingManagerSubsystemID].label =
2561 routingManagerSubsystemName;
2563 if(info_.subsystems[routingManagerSubsystemID].hasRoutingManager)
2565 __SS__ <<
"Error: You cannot have multiple Routing Managers in a "
2571 auto routingManagerSubsystemDestinationLink =
2572 routingManagerSubsystemLink.
getNode(
2573 colARTDAQSubsystem_.colLinkToDestination_);
2574 if(routingManagerSubsystemDestinationLink.isDisconnected())
2577 info_.subsystems[routingManagerSubsystemID].destination = 0;
2582 info_.subsystems[routingManagerSubsystemID].destination =
2583 getSubsytemId(routingManagerSubsystemDestinationLink);
2589 if(!info_.subsystems.count(
2590 info_.subsystems[routingManagerSubsystemID].destination) ||
2592 .subsystems[info_.subsystems[routingManagerSubsystemID]
2594 .sources.count(routingManagerSubsystemID))
2597 .subsystems[info_.subsystems[routingManagerSubsystemID]
2599 .sources.insert(routingManagerSubsystemID);
2604 __COUT__ <<
"Found Routing Manager with UID " << rmUID
2605 <<
", DAQInterface Hostname " << rmHost <<
", and Subsystem "
2606 << routingManagerSubsystemID << __E__;
2607 info_.processes[ARTDAQAppType::RoutingManager].emplace_back(
2611 routingManagerSubsystemID,
2612 ARTDAQAppType::RoutingManager,
2613 routingManager.second.status());
2615 info_.subsystems[routingManagerSubsystemID].hasRoutingManager =
true;
2616 info_.subsystems[routingManagerSubsystemID].routingManagerHost = rmHost;
2620 outputRoutingManagerFHICL(
2621 routingManager.second, routingTimeoutMs, routingRetryCount);
2623 flattenFHICL(ARTDAQAppType::RoutingManager,
2624 routingManager.second.getValue());
2629 __COUT__ <<
"Routing Manager " << rmUID <<
" is disabled." << __E__;
2636 void ARTDAQTableBase::extractBoardReadersInfo(
ConfigurationTree artdaqSupervisorNode,
2637 bool getStatusFalseNodes,
2639 size_t maxFragmentSizeBytes,
2640 size_t routingTimeoutMs,
2641 size_t routingRetryCount)
2643 __COUT__ <<
"Checking for Board Readers..." << __E__;
2644 info_.processes[ARTDAQAppType::BoardReader].clear();
2647 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToBoardReaders_);
2650 std::vector<std::pair<std::string, ConfigurationTree>> readers =
2652 __COUT__ <<
"There are " << readers.size() <<
" configured Board Readers."
2655 for(
auto& reader : readers)
2657 const std::string& readerUID = reader.first;
2659 if(getStatusFalseNodes || reader.second.status())
2661 std::string readerHost =
2662 reader.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2663 .getValueWithDefault(
"localhost");
2664 std::string readerAP =
2666 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2667 .getValueWithDefault(
"");
2669 int readerSubsystemID = 1;
2671 reader.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2674 readerSubsystemID = getSubsytemId(readerSubsystemLink);
2676 info_.subsystems[readerSubsystemID].id = readerSubsystemID;
2678 const std::string& readerSubsystemName =
2682 info_.subsystems[readerSubsystemID].label = readerSubsystemName;
2684 auto readerSubsystemDestinationLink = readerSubsystemLink.
getNode(
2685 colARTDAQSubsystem_.colLinkToDestination_);
2686 if(readerSubsystemDestinationLink.isDisconnected())
2689 info_.subsystems[readerSubsystemID].destination = 0;
2694 info_.subsystems[readerSubsystemID].destination =
2695 getSubsytemId(readerSubsystemDestinationLink);
2701 if(!info_.subsystems.count(
2702 info_.subsystems[readerSubsystemID].destination) ||
2703 !info_.subsystems[info_.subsystems[readerSubsystemID].destination]
2704 .sources.count(readerSubsystemID))
2706 info_.subsystems[info_.subsystems[readerSubsystemID].destination]
2707 .sources.insert(readerSubsystemID);
2712 __COUT__ <<
"Found Board Reader with UID " << readerUID
2713 <<
", DAQInterface Hostname " << readerHost <<
", and Subsystem "
2714 << readerSubsystemID << __E__;
2715 info_.processes[ARTDAQAppType::BoardReader].emplace_back(
2720 ARTDAQAppType::BoardReader,
2721 reader.second.status());
2725 outputBoardReaderFHICL(reader.second,
2726 maxFragmentSizeBytes,
2730 flattenFHICL(ARTDAQAppType::BoardReader, reader.second.getValue());
2735 __COUT__ <<
"Board Reader " << readerUID <<
" is disabled." << __E__;
2741 __COUT_WARN__ <<
"There should be at least one Board Reader!";
2748 void ARTDAQTableBase::extractEventBuildersInfo(
ConfigurationTree artdaqSupervisorNode,
2749 bool getStatusFalseNodes,
2751 size_t maxFragmentSizeBytes)
2753 __COUT__ <<
"Checking for Event Builders..." << __E__;
2754 info_.processes[ARTDAQAppType::EventBuilder].clear();
2757 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToEventBuilders_);
2760 std::vector<std::pair<std::string, ConfigurationTree>> builders =
2763 std::string lastBuilderFcl[2],
2764 flattenedLastFclParts
2766 for(
auto& builder : builders)
2768 const std::string& builderUID = builder.first;
2769 __COUTV__(builderUID);
2771 if(getStatusFalseNodes || builder.second.status())
2773 std::string builderHost =
2774 builder.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
2775 .getValueWithDefault(
"localhost");
2776 std::string builderAP =
2778 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
2779 .getValueWithDefault(
"");
2781 int builderSubsystemID = 1;
2783 builder.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
2786 builderSubsystemID = getSubsytemId(builderSubsystemLink);
2789 info_.subsystems[builderSubsystemID].id = builderSubsystemID;
2791 const std::string& builderSubsystemName =
2795 info_.subsystems[builderSubsystemID].label = builderSubsystemName;
2797 auto builderSubsystemDestinationLink = builderSubsystemLink.
getNode(
2798 colARTDAQSubsystem_.colLinkToDestination_);
2799 if(builderSubsystemDestinationLink.isDisconnected())
2802 info_.subsystems[builderSubsystemID].destination = 0;
2807 info_.subsystems[builderSubsystemID].destination =
2808 getSubsytemId(builderSubsystemDestinationLink);
2814 if(!info_.subsystems.count(
2815 info_.subsystems[builderSubsystemID].destination) ||
2816 !info_.subsystems[info_.subsystems[builderSubsystemID].destination]
2817 .sources.count(builderSubsystemID))
2819 info_.subsystems[info_.subsystems[builderSubsystemID].destination]
2820 .sources.insert(builderSubsystemID);
2825 __COUT__ <<
"Found Event Builder with UID " << builderUID
2826 <<
", on Hostname " << builderHost <<
", in Subsystem "
2827 << builderSubsystemID << __E__;
2828 info_.processes[ARTDAQAppType::EventBuilder].emplace_back(
2833 ARTDAQAppType::EventBuilder,
2834 builder.second.status());
2838 std::string returnFcl, processName;
2839 bool needToFlatten =
true;
2840 bool captureAsLastFcl =
2843 (&builder != &builders.back());
2845 ARTDAQAppType::EventBuilder,
2846 maxFragmentSizeBytes,
2847 DEFAULT_ROUTING_TIMEOUT_MS,
2848 DEFAULT_ROUTING_RETRY_COUNT,
2849 captureAsLastFcl ? &returnFcl :
nullptr);
2856 auto cmi = returnFcl.find(
2857 "# otsdaq-ARTDAQ builder UID:");
2858 if(cmi != std::string::npos)
2859 cmi = returnFcl.find(
'\n', cmi);
2860 if(cmi != std::string::npos)
2862 size_t pnj = std::string::npos;
2864 returnFcl.find(
"\tprocess_name: ", cmi);
2865 if(pni != std::string::npos)
2867 pni += std::string(
"\tprocess_name: ")
2869 pnj = returnFcl.find(
'\n', pni);
2871 if(pnj != std::string::npos)
2873 processName = returnFcl.substr(pni, pnj - pni);
2874 __COUT__ <<
"Found process name = " << processName << __E__;
2876 bool sameFirst =
false;
2878 std::string newPiece = returnFcl.substr(cmi, pni - cmi);
2879 if(flattenedLastFclParts[0].size() &&
2880 lastBuilderFcl[0].size() && lastBuilderFcl[0] == newPiece)
2882 __COUT__ <<
"Same first fcl" << __E__;
2887 __COUTVS__(20, lastBuilderFcl[0]);
2888 __COUTVS__(20, newPiece);
2889 for(
size_t i = 0, j = 0;
2890 i < lastBuilderFcl[0].size() && j < newPiece.size();
2893 if(lastBuilderFcl[0][i] != newPiece[j])
2897 __COUTVS__(20, lastBuilderFcl[0].substr(i, 30));
2898 __COUTVS__(20, newPiece.substr(j, 30));
2903 if(captureAsLastFcl)
2904 lastBuilderFcl[0] = newPiece;
2907 newPiece = returnFcl.substr(pnj);
2908 if(lastBuilderFcl[0].size() && lastBuilderFcl[1] == newPiece)
2910 __COUT__ <<
"Same second fcl" << __E__;
2913 std::chrono::steady_clock::time_point startClock =
2914 std::chrono::steady_clock::now();
2915 __COUT__ <<
"Found fcl match! Reuse for "
2916 << builderUID << __E__;
2919 needToFlatten =
false;
2922 std::string outFile = getFlatFHICLFilename(
2923 ARTDAQAppType::EventBuilder, builderUID);
2924 __COUTVS__(3, outFile);
2925 std::ofstream ofs{outFile};
2928 __SS__ <<
"Failed to open fhicl output file '"
2929 << outFile <<
"!'" << __E__;
2932 ofs << flattenedLastFclParts[0] <<
"process_name: \""
2933 << processName <<
"\""
2934 << flattenedLastFclParts[1];
2936 << builderUID <<
" Flatten Clock time = "
2937 << artdaq::TimeUtils::GetElapsedTime(startClock)
2942 if(captureAsLastFcl)
2943 lastBuilderFcl[1] = newPiece;
2948 ARTDAQTableBase::flattenFHICL(
2949 ARTDAQAppType::EventBuilder,
2951 captureAsLastFcl ? &returnFcl :
nullptr);
2953 __COUT__ <<
"Skipping full flatten for " << builderUID << __E__;
2956 __COUTV__(captureAsLastFcl);
2957 if(captureAsLastFcl)
2959 size_t pnj = std::string::npos;
2960 auto pni = returnFcl.find(
"process_name:");
2961 if(pni != std::string::npos)
2965 (returnFcl[pni - 1] ==
' ' || returnFcl[pni - 1] ==
'\n' ||
2966 returnFcl[pni - 1] ==
'\t'))
2967 pnj = returnFcl.find(
'\n', pni);
2969 if(pnj != std::string::npos)
2972 <<
"Found flattened '"
2973 << returnFcl.substr(pni, pnj - pni) <<
"' at pos " << pni
2974 <<
" of " << returnFcl.size() << __E__;
2975 flattenedLastFclParts[0] = returnFcl.substr(0, pni);
2976 flattenedLastFclParts[1] = returnFcl.substr(pnj);
2980 __COUT_WARN__ <<
"Failed to capture fcl for " << processName
2988 __COUT__ <<
"Event Builder " << builderUID <<
" is disabled." << __E__;
2994 __COUT_WARN__ <<
"There should be at least one Event Builder!";
3001 void ARTDAQTableBase::extractDataLoggersInfo(
ConfigurationTree artdaqSupervisorNode,
3002 bool getStatusFalseNodes,
3004 size_t maxFragmentSizeBytes)
3006 __COUT__ <<
"Checking for Data Loggers..." << __E__;
3007 info_.processes[ARTDAQAppType::DataLogger].clear();
3010 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToDataLoggers_);
3013 std::vector<std::pair<std::string, ConfigurationTree>> dataloggers =
3016 for(
auto& datalogger : dataloggers)
3018 const std::string& loggerUID = datalogger.first;
3020 if(getStatusFalseNodes || datalogger.second.status())
3022 std::string loggerHost =
3023 datalogger.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
3024 .getValueWithDefault(
"localhost");
3025 std::string loggerAP =
3027 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
3028 .getValueWithDefault(
"");
3030 int loggerSubsystemID = 1;
3032 datalogger.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
3035 loggerSubsystemID = getSubsytemId(loggerSubsystemLink);
3037 info_.subsystems[loggerSubsystemID].id = loggerSubsystemID;
3039 const std::string& loggerSubsystemName =
3043 info_.subsystems[loggerSubsystemID].label = loggerSubsystemName;
3045 auto loggerSubsystemDestinationLink = loggerSubsystemLink.
getNode(
3046 colARTDAQSubsystem_.colLinkToDestination_);
3047 if(loggerSubsystemDestinationLink.isDisconnected())
3050 info_.subsystems[loggerSubsystemID].destination = 0;
3055 info_.subsystems[loggerSubsystemID].destination =
3056 getSubsytemId(loggerSubsystemDestinationLink);
3062 if(!info_.subsystems.count(
3063 info_.subsystems[loggerSubsystemID].destination) ||
3064 !info_.subsystems[info_.subsystems[loggerSubsystemID].destination]
3065 .sources.count(loggerSubsystemID))
3067 info_.subsystems[info_.subsystems[loggerSubsystemID].destination]
3068 .sources.insert(loggerSubsystemID);
3073 __COUT__ <<
"Found Data Logger with UID " << loggerUID
3074 <<
", DAQInterface Hostname " << loggerHost <<
", and Subsystem "
3075 << loggerSubsystemID << __E__;
3076 info_.processes[ARTDAQAppType::DataLogger].emplace_back(
3081 ARTDAQAppType::DataLogger,
3082 datalogger.second.status());
3087 ARTDAQAppType::DataLogger,
3088 maxFragmentSizeBytes);
3090 flattenFHICL(ARTDAQAppType::DataLogger, datalogger.second.getValue());
3095 __COUT__ <<
"Data Logger " << loggerUID <<
" is disabled." << __E__;
3101 __COUT_WARN__ <<
"There were no Data Loggers found!";
3106 void ARTDAQTableBase::extractDispatchersInfo(
ConfigurationTree artdaqSupervisorNode,
3107 bool getStatusFalseNodes,
3109 size_t maxFragmentSizeBytes)
3111 __COUT__ <<
"Checking for Dispatchers..." << __E__;
3112 info_.processes[ARTDAQAppType::Dispatcher].clear();
3115 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colLinkToDispatchers_);
3118 std::vector<std::pair<std::string, ConfigurationTree>> dispatchers =
3121 for(
auto& dispatcher : dispatchers)
3123 const std::string& dispatcherUID = dispatcher.first;
3125 if(getStatusFalseNodes || dispatcher.second.status())
3127 std::string dispatcherHost =
3128 dispatcher.second.getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_HOSTNAME)
3129 .getValueWithDefault(
"localhost");
3130 std::string dispatcherAP =
3132 .getNode(ARTDAQTableBase::ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS)
3133 .getValueWithDefault(
"");
3134 int dispatcherPort =
3135 dispatcher.second.getNode(
"DispatcherPort").getValue<
int>();
3137 auto dispatcherSubsystemID = 1;
3139 dispatcher.second.
getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK);
3142 dispatcherSubsystemID = getSubsytemId(dispatcherSubsystemLink);
3144 info_.subsystems[dispatcherSubsystemID].id = dispatcherSubsystemID;
3146 const std::string& dispatcherSubsystemName =
3150 info_.subsystems[dispatcherSubsystemID].label =
3151 dispatcherSubsystemName;
3153 auto dispatcherSubsystemDestinationLink =
3154 dispatcherSubsystemLink.
getNode(
3155 colARTDAQSubsystem_.colLinkToDestination_);
3156 if(dispatcherSubsystemDestinationLink.isDisconnected())
3159 info_.subsystems[dispatcherSubsystemID].destination = 0;
3164 info_.subsystems[dispatcherSubsystemID].destination =
3165 getSubsytemId(dispatcherSubsystemDestinationLink);
3171 if(!info_.subsystems.count(
3172 info_.subsystems[dispatcherSubsystemID].destination) ||
3174 .subsystems[info_.subsystems[dispatcherSubsystemID]
3176 .sources.count(dispatcherSubsystemID))
3179 .subsystems[info_.subsystems[dispatcherSubsystemID]
3181 .sources.insert(dispatcherSubsystemID);
3185 __COUT__ <<
"Found Dispatcher with UID " << dispatcherUID
3186 <<
", DAQInterface Hostname " << dispatcherHost
3187 <<
", and Subsystem " << dispatcherSubsystemID << __E__;
3188 info_.processes[ARTDAQAppType::Dispatcher].emplace_back(
3192 dispatcherSubsystemID,
3193 ARTDAQAppType::Dispatcher,
3194 dispatcher.second.status(),
3200 ARTDAQAppType::Dispatcher,
3201 maxFragmentSizeBytes);
3203 flattenFHICL(ARTDAQAppType::Dispatcher, dispatcher.second.getValue());
3208 __COUT__ <<
"Dispatcher " << dispatcherUID <<
" is disabled." << __E__;
3214 __COUT_WARN__ <<
"There were no Dispatchers found!";
3224 for(
auto context : contexts)
3226 if(!context.second.isEnabled())
3229 auto apps = context.second
3230 .getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
3232 for(
auto app : apps)
3235 if(app.second.getNode(XDAQContextTable::colApplication_.colClass_)
3236 .getValue() == ARTDAQ_SUPERVISOR_CLASS &&
3237 app.second.isEnabled())
3255 std::map<std::string ,
3256 std::map<std::string , std::vector<std::string /*property*/>>>&
3257 nodeTypeToObjectMap,
3258 std::map<std::string /*subsystemName*/, std::string /*destinationSubsystemName*/>&
3260 std::vector<std::string /*property*/>& artdaqSupervisoInfo,
3261 bool suppressMultiNode )
3263 __COUT__ <<
"getARTDAQSystem() suppressMultiNode=" << suppressMultiNode << __E__;
3265 artdaqSupervisoInfo.clear();
3276 return ARTDAQTableBase::info_;
3278 __COUTV__(artdaqContext->contextUID_);
3279 __COUTV__(artdaqContext->applications_.size());
3282 std::map<std::string , std::set<std::string >> nodeLayoutNames;
3284 const std::string& finalContextGroupName =
3285 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE);
3287 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE);
3288 const std::string& finalConfigGroupName = cfgMgr->getActiveGroupName(
3289 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
3290 const TableGroupKey& finalConfigGroupKey = cfgMgr->getActiveGroupKey(
3291 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
3296 std::stringstream layoutPath;
3297 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3298 << finalContextGroupName <<
"_" << finalContextGroupKey <<
"."
3299 << finalConfigGroupName <<
"_" << finalConfigGroupKey <<
".dat";
3301 fp = fopen(layoutPath.str().c_str(),
"r");
3304 __COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
3305 << finalContextGroupKey <<
") + " << finalConfigGroupName <<
"("
3306 << finalConfigGroupKey <<
")': " << layoutPath.
str() << __E__;
3310 __COUTV__(layoutPath.str());
3314 std::stringstream layoutPath;
3315 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3316 << finalContextGroupName <<
"_" << finalContextGroupKey <<
".dat";
3317 __COUTV__(layoutPath.str());
3319 fp = fopen(layoutPath.str().c_str(),
"r");
3322 __COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
3323 << finalContextGroupKey <<
")': " << layoutPath.str() << __E__;
3326 __COUTV__(layoutPath.str());
3332 struct dirent* entry;
3337 float bestScore = 0, score;
3338 std::string bestName =
"";
3340 if(!(pDIR = opendir((ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH).c_str())))
3342 __SS__ <<
"Path '" << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH
3343 <<
"' could not be opened!" << __E__;
3348 while((entry = readdir(pDIR)))
3350 name = std::string(entry->d_name);
3351 type = int(entry->d_type);
3353 __COUTS__(2) << type <<
" " << name <<
"\n" << std::endl;
3355 if(name[0] !=
'.' &&
3365 if(type == 0 || type == 10)
3368 DIR* pTmpDIR = opendir(
3369 (ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH +
"/" + name)
3377 __COUTS__(2) <<
"Unable to open path as directory: "
3378 << (ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH +
3390 __COUTS__(2) <<
"Directory: " << type <<
" " << name << __E__;
3394 __COUTS__(2) <<
"File: " << type <<
" " << name <<
"\n"
3396 if(name.find(
".dat") !=
3400 __COUTS__(2) <<
"Contender: " << name <<
"\n" << std::endl;
3405 if(nameSplit.size() > 1)
3408 auto keyi = nameSplit[1].rfind(
'_');
3409 if(keyi != std::string::npos)
3413 .substr(keyi, nameSplit[1].size() - 4 - keyi)
3417 finalConfigGroupKey.key() -
3423 __COUTVS__(2, tmpscore);
3427 __COUTVS__(2, tmpscore);
3430 std::string nameToCompare = nameSplit[1].substr(0, keyi);
3431 __COUTVS__(2, nameToCompare);
3432 size_t i = 0, j = 0;
3434 for(; i < nameToCompare.size() &&
3435 j < finalConfigGroupName.size();
3438 if(nameToCompare[i] == finalConfigGroupName[j])
3444 __COUTVS__(2, tmpscore);
3446 for(; i < nameToCompare.size() &&
3447 j < finalConfigGroupName.size();
3450 if(nameToCompare[i] == finalConfigGroupName[j])
3456 __COUTVS__(2, tmpscore);
3459 __COUTVS__(2, score);
3461 if(nameSplit.size() > 0)
3464 auto keyi = nameSplit[0].rfind(
'_');
3465 if(keyi != std::string::npos)
3469 .substr(keyi, nameSplit[0].size() - 4 - keyi)
3473 finalContextGroupKey.key() -
3479 __COUTVS__(2, tmpscore);
3483 __COUTVS__(2, tmpscore);
3486 std::string nameToCompare = nameSplit[0].substr(0, keyi);
3487 __COUTVS__(2, nameToCompare);
3488 size_t i = 0, j = 0;
3490 for(; i < nameToCompare.size() &&
3491 j < finalContextGroupName.size();
3494 if(nameToCompare[i] == finalContextGroupName[j])
3500 __COUTVS__(2, tmpscore);
3502 for(; i < nameToCompare.size() &&
3503 j < finalContextGroupName.size();
3506 if(nameToCompare[i] == finalContextGroupName[j])
3512 __COUTVS__(2, tmpscore);
3515 __COUTVS__(2, score);
3518 if(score > bestScore)
3522 __COUTVS__(2, bestName);
3530 __COUT__ <<
"Found closest layout file name: " << bestName <<
".dat"
3532 std::stringstream layoutPath;
3533 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << bestName
3535 __COUTV__(layoutPath.str());
3536 fp = fopen(layoutPath.str().c_str(),
"r");
3539 __COUT__ <<
"Closest layout file not found for '" << bestName <<
"'"
3549 __COUT__ <<
"Extract info from layout file.." << __E__;
3555 const size_t maxLineSz = 1000;
3556 char line[maxLineSz];
3557 if(!fgets(line, maxLineSz, fp))
3560 __COUT__ <<
"No layout naming info found." << __E__;
3566 char name[maxLineSz];
3567 char type[maxLineSz];
3569 while(fgets(line, maxLineSz, fp))
3572 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
3573 nodeLayoutNames[type].emplace(name);
3588 for(
auto& artdaqApp : artdaqContext->applications_)
3590 if(artdaqApp.class_ != ARTDAQ_SUPERVISOR_CLASS)
3593 __COUTV__(artdaqApp.applicationUID_);
3594 artdaqSupervisoInfo.push_back(artdaqApp.applicationUID_);
3595 artdaqSupervisoInfo.push_back(
3596 (artdaqContext->status_ && artdaqApp.status_) ?
"1" :
"0");
3597 artdaqSupervisoInfo.push_back(artdaqContext->address_);
3598 artdaqSupervisoInfo.push_back(std::to_string(artdaqContext->port_));
3601 XDAQContextTable::getSupervisorConfigNode(
3603 artdaqContext->contextUID_,
3604 artdaqApp.applicationUID_),
3607 __COUT__ <<
"========== "
3608 <<
"Found " << info.subsystems.size() <<
" subsystems." << __E__;
3611 for(
auto& subsystem : info.subsystems)
3612 subsystemObjectMap.emplace(std::make_pair(
3613 subsystem.second.label, std::to_string(subsystem.second.destination)));
3615 __COUT__ <<
"========== "
3616 <<
"Found " << info.processes.size() <<
" process types." << __E__;
3620 const std::string& typeString = nameTypePair.first;
3621 __COUTV__(typeString);
3623 nodeTypeToObjectMap.emplace(
3624 std::make_pair(typeString,
3625 std::map<std::string ,
3626 std::vector<std::string /*property*/>>()));
3628 auto it = info.processes.find(nameTypePair.second);
3629 if(it == info.processes.end())
3632 <<
"Found 0 " << typeString << __E__;
3636 <<
"Found " << it->second.size() <<
" " << typeString <<
"(s)"
3642 __SS__ <<
"Invalid artdaq node type '" << typeString <<
"' attempted!"
3646 __COUTV__(tableIt->second);
3649 std::stringstream ss;
3650 cfgMgr->getTableByName(tableIt->second)->getView().print(ss);
3651 __COUT_MULTI__(1, ss.str());
3661 const std::set<std::string > skipColumns(
3662 {ARTDAQ_TYPE_TABLE_HOSTNAME,
3663 ARTDAQ_TYPE_TABLE_ALLOWED_PROCESSORS,
3664 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK,
3666 .colDaqFragmentIDs_,
3667 TableViewColumnInfo::COL_NAME_COMMENT,
3668 TableViewColumnInfo::COL_NAME_AUTHOR,
3669 TableViewColumnInfo::
3670 COL_NAME_CREATION});
3672 if(TTEST(1) && nodeLayoutNames.find(typeString) != nodeLayoutNames.end())
3678 for(
auto& artdaqNode : it->second)
3681 if(skipSet.find(StringMacros::encodeURIComponent(artdaqNode.label)) !=
3686 <<
"Found '" << artdaqNode.label <<
"' " << typeString << __E__;
3688 std::string nodeName = artdaqNode.label;
3689 bool status = artdaqNode.status;
3690 std::string hostname = artdaqNode.hostname;
3691 std::string subsystemId = std::to_string(artdaqNode.subsystem);
3692 std::string subsystemName =
3693 info.subsystems.at(artdaqNode.subsystem).label;
3704 std::vector<std::string> multiNodeNames, hostnameArray;
3709 StringMacros::encodeURIComponent(nodeName));
3711 __COUTV__(allNodes.size());
3712 if(!suppressMultiNode)
3713 for(
auto& otherNode : allNodes)
3715 if(skipSet.find(StringMacros::encodeURIComponent(
3716 otherNode.first)) != skipSet.end() ||
3717 otherNode.second.status() !=
3722 if(nodeName.find(
"_clone") != std::string::npos ||
3723 otherNode.first.find(
"_clone") != std::string::npos)
3730 otherNode.second.getNode(ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID)
3739 auto otherNodeColumns = otherNode.second.getChildren();
3741 bool isMultiNode =
true;
3742 for(
unsigned int i = 0;
3743 i < thisNodeColumns.size() && i < otherNodeColumns.size();
3747 if(skipColumns.find(thisNodeColumns[i].first) !=
3748 skipColumns.end() ||
3749 thisNodeColumns[i].second.isLinkNode())
3760 if(thisNodeColumns[i].second.getValueAsString() !=
3761 otherNodeColumns[i].second.getValueAsString())
3763 __COUT__ <<
"Mismatch, not multi-node member."
3765 isMultiNode =
false;
3772 __COUT__ <<
"Found '" << nodeName
3773 <<
"' multi-node member candidate '"
3774 << otherNode.first <<
"'" << __E__;
3777 if(!multiNodeNames.size())
3779 multiNodeNames.push_back(
3780 StringMacros::encodeURIComponent(nodeName));
3781 hostnameArray.push_back(
3782 StringMacros::encodeURIComponent(hostname));
3784 multiNodeNames.push_back(
3785 StringMacros::encodeURIComponent(otherNode.first));
3786 hostnameArray.push_back(StringMacros::encodeURIComponent(
3787 otherNode.second.getNode(ARTDAQ_TYPE_TABLE_HOSTNAME)
3790 __COUTV__(hostnameArray.back());
3792 StringMacros::encodeURIComponent(otherNode.first));
3797 unsigned int nodeFixedWildcardLength = 0, hostFixedWildcardLength = 0;
3798 std::string multiNodeString =
"", hostArrayString =
"";
3800 __COUTV__(nodeName);
3802 if(multiNodeNames.size() > 1)
3804 __COUT__ <<
"Handling multi-node printer syntax" << __E__;
3811 if(nodeLayoutNames.find(typeString) != nodeLayoutNames.end())
3819 std::string bestNodeLayoutName =
"";
3820 size_t bestNodeLayoutMatchCount =
3821 multiNodeNames.size() + 1;
3823 for(
const auto& layoutNameFull : nodeLayoutNames.at(typeString))
3825 __COUTTV__(layoutNameFull);
3826 size_t statusPos = layoutNameFull.find(
";status=");
3827 std::string layoutName = layoutNameFull.substr(0, statusPos);
3828 bool layoutStatus =
true;
3832 layoutStatus = status;
3834 layoutNameFull.substr(statusPos +
3835 std::string(
";status=").size()))
3836 layoutStatus =
false;
3838 __COUTTV__(layoutStatus);
3840 if(layoutStatus != status)
3842 __COUTT__ <<
"Status mismatch for template" << __E__;
3850 bool exactMatch =
true;
3852 for(
const auto& layoutSeg : layoutSplit)
3853 if((pos = nodeName.find(layoutSeg, pos)) ==
3856 __COUTT__ <<
"Did not find '" << layoutSeg <<
"' in '"
3857 << nodeName <<
"'" << __E__;
3862 __COUTTV__(exactMatch);
3865 size_t nodeLayoutMatchCount = 1;
3867 __COUT__ <<
"Found layout template name match! '"
3868 << layoutName <<
"' for node '" << nodeName
3869 <<
".' Trimming multinode candidates to match..."
3872 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3874 __COUTTV__(multiNodeNames[i]);
3875 std::string multiNodeName =
3878 __COUTTV__(multiNodeName);
3879 bool exactMatch =
true;
3881 for(
const auto& layoutSeg : layoutSplit)
3882 if((pos = multiNodeName.find(layoutSeg, pos)) ==
3885 __COUTT__ <<
"Did not find '" << layoutSeg
3886 <<
"' in '" << multiNodeName <<
"'"
3894 ++nodeLayoutMatchCount;
3895 __COUTT__ <<
"Found '" << layoutName <<
"' in '"
3896 << multiNodeName <<
"'" << __E__;
3901 __COUTTV__(nodeLayoutMatchCount);
3902 if(nodeLayoutMatchCount < bestNodeLayoutMatchCount)
3904 bestNodeLayoutName = layoutNameFull;
3905 bestNodeLayoutMatchCount = nodeLayoutMatchCount;
3906 __COUTTV__(bestNodeLayoutName);
3907 __COUTTV__(bestNodeLayoutMatchCount);
3912 __COUTV__(nodeName);
3918 if(bestNodeLayoutMatchCount > 0)
3920 __COUTV__(bestNodeLayoutName);
3921 std::string layoutNameFull = bestNodeLayoutName;
3922 __COUTTV__(layoutNameFull);
3923 size_t statusPos = layoutNameFull.find(
";status=");
3924 std::string layoutName = layoutNameFull.substr(0, statusPos);
3930 __COUT__ <<
"Found layout template name match! '"
3931 << layoutName <<
"' for node '" << nodeName
3932 <<
".' Trimming multinode candidates to match..."
3935 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3937 __COUTTV__(multiNodeNames[i]);
3938 std::string multiNodeName =
3940 __COUTTV__(multiNodeName);
3941 bool exactMatch =
true;
3943 for(
const auto& layoutSeg : layoutSplit)
3944 if((pos = multiNodeName.find(layoutSeg, pos)) ==
3947 __COUTT__ <<
"Did not find '" << layoutSeg
3948 <<
"' in '" << multiNodeName <<
"'"
3956 __COUT__ <<
"Trimming multinode candidate '"
3957 << multiNodeName <<
"'" << __E__;
3958 skipSet.erase(multiNodeNames[i]);
3959 multiNodeNames.erase(multiNodeNames.begin() + i);
3960 hostnameArray.erase(hostnameArray.begin() + i);
3967 __COUTV__(nodeName);
3972 std::vector<std::string>
3976 unsigned int maxScore = 0;
3978 unsigned int minScore = -1;
3979 std::vector<unsigned int> scoreVector;
3980 scoreVector.push_back(-1);
3981 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
3985 __COUTS__(3) << multiNodeNames[0] <<
" vs "
3986 << multiNodeNames[i] << __E__;
3989 for(
unsigned int j = 0, k = 0; j < multiNodeNames[0].size() &&
3990 k < multiNodeNames[i].size();
3993 while(j < multiNodeNames[0].size() &&
3994 !(multiNodeNames[0][j] >=
'a' &&
3995 multiNodeNames[0][j] <=
'z') &&
3996 !(multiNodeNames[0][j] >=
'A' &&
3997 multiNodeNames[0][j] <=
'Z'))
3999 while(k < multiNodeNames[i].size() &&
4000 !(multiNodeNames[i][k] >=
'a' &&
4001 multiNodeNames[i][k] <=
'z') &&
4002 !(multiNodeNames[i][k] >=
'A' &&
4003 multiNodeNames[i][k] <=
'Z'))
4006 while(k < multiNodeNames[i].size() &&
4007 multiNodeNames[0][j] != multiNodeNames[i][k])
4011 << j <<
"-" << k <<
" of " << multiNodeNames[0].size()
4012 <<
"-" << multiNodeNames[i].size() << __E__;
4014 if(j < multiNodeNames[0].size() &&
4015 k < multiNodeNames[i].size())
4019 __COUTVS__(3, score);
4022 for(
unsigned int j = multiNodeNames[0].size() - 1,
4023 k = multiNodeNames[i].size() - 1;
4024 j < multiNodeNames[0].size() &&
4025 k < multiNodeNames[i].size();
4028 while(j < multiNodeNames[0].size() &&
4029 !(multiNodeNames[0][j] >=
'a' &&
4030 multiNodeNames[0][j] <=
'z') &&
4031 !(multiNodeNames[0][j] >=
'A' &&
4032 multiNodeNames[0][j] <=
'Z'))
4034 while(k < multiNodeNames[i].size() &&
4035 !(multiNodeNames[i][k] >=
'a' &&
4036 multiNodeNames[i][k] <=
'z') &&
4037 !(multiNodeNames[i][k] >=
'A' &&
4038 multiNodeNames[i][k] <=
'Z'))
4041 while(k < multiNodeNames[i].size() &&
4042 multiNodeNames[0][j] != multiNodeNames[i][k])
4045 __COUTS__(3) <<
"BACK" << j <<
"-" << k <<
" of "
4046 << multiNodeNames[0].size() <<
"-"
4047 << multiNodeNames[i].size() << __E__;
4049 if(j < multiNodeNames[0].size() &&
4050 k < multiNodeNames[i].size())
4054 __COUTVS__(3, score / 2.0);
4056 scoreVector.push_back(score);
4058 if(score > maxScore)
4063 if(score < minScore)
4070 __COUTVS__(2, minScore);
4071 __COUTVS__(2, maxScore);
4073 __COUT__ <<
"Trimming multi-node members with low match score..."
4078 for(
unsigned int i = multiNodeNames.size() - 1;
4079 i > 0 && i < multiNodeNames.size();
4084 if(maxScore > multiNodeNames[0].size() &&
4085 scoreVector[i] >= maxScore)
4089 __COUT__ <<
"Trimming low score match " << multiNodeNames[i]
4090 <<
" for node name " << nodeName << __E__;
4092 trimmedNodeNames.push_back(multiNodeNames[i]);
4093 skipSet.erase(multiNodeNames[i]);
4094 multiNodeNames.erase(multiNodeNames.begin() + i);
4095 hostnameArray.erase(hostnameArray.begin() + i);
4106 if(multiNodeNames.size() > 2)
4108 bool sameLengths =
true;
4109 size_t nameLen = multiNodeNames[0].size();
4110 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4111 if(multiNodeNames[i].size() != nameLen)
4113 sameLengths =
false;
4117 if(sameLengths && nameLen > 0)
4119 std::vector<bool> varies(nameLen,
false);
4120 for(
unsigned int pos = 0; pos < nameLen; ++pos)
4121 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4122 if(multiNodeNames[i][pos] != multiNodeNames[0][pos])
4130 unsigned int start, end;
4133 std::vector<VaryRun> runs;
4134 for(
unsigned int pos = 0; pos < nameLen;)
4141 unsigned int rStart = pos;
4142 bool runAllDigit =
true;
4143 while(pos < nameLen && varies[pos])
4145 for(
unsigned int i = 0;
4146 i < multiNodeNames.size() && runAllDigit;
4148 if(!(multiNodeNames[i][pos] >=
'0' &&
4149 multiNodeNames[i][pos] <=
'9'))
4150 runAllDigit =
false;
4153 runs.push_back({rStart, pos, runAllDigit});
4162 for(
auto& run : runs)
4166 while(run.start > 0)
4168 bool allDigitAtPrev =
true;
4169 for(
unsigned int i = 0;
4170 i < multiNodeNames.size() && allDigitAtPrev;
4172 if(!(multiNodeNames[i][run.start - 1] >=
'0' &&
4173 multiNodeNames[i][run.start - 1] <=
'9'))
4174 allDigitAtPrev =
false;
4181 unsigned int numDigitRuns = 0;
4182 for(
const auto& run : runs)
4186 if(numDigitRuns > 1 && numDigitRuns == runs.size())
4189 <<
"Numeric wildcard refinement: found "
4191 <<
" separate digit-varying groups in '" << nodeName
4192 <<
"'. Splitting to favor numeric-only wildcards."
4201 unsigned int bestRunToFix = 0;
4202 unsigned int fewestUnique = (
unsigned int)-1;
4203 unsigned int lowestHostCorr = (
unsigned int)-1;
4204 for(
unsigned int r = 0; r < runs.size(); ++r)
4206 std::set<std::string> uniqueVals;
4207 for(
unsigned int i = 0; i < multiNodeNames.size();
4209 uniqueVals.insert(multiNodeNames[i].substr(
4210 runs[r].start, runs[r].end - runs[r].start));
4214 std::map<std::string, std::set<std::string>>
4216 for(
unsigned int i = 0; i < multiNodeNames.size();
4219 std::string dv = multiNodeNames[i].substr(
4220 runs[r].start, runs[r].end - runs[r].start);
4221 valToHosts[dv].insert(hostnameArray[i]);
4226 unsigned int hostCorr = 0;
4227 if(valToHosts.size() > 1)
4230 std::set<std::string> allHostSets;
4231 for(
const auto& [dv, hosts] : valToHosts)
4233 std::string hostKey;
4234 for(
const auto& h : hosts)
4236 allHostSets.insert(hostKey);
4238 hostCorr = allHostSets.size();
4241 __COUTT__ <<
"Digit run " << r <<
" ["
4242 << runs[r].start <<
"-" << (runs[r].end - 1)
4243 <<
"]: uniqueVals=" << uniqueVals.size()
4244 <<
" hostCorr=" << hostCorr << __E__;
4250 if(uniqueVals.size() < fewestUnique ||
4251 (uniqueVals.size() == fewestUnique &&
4252 hostCorr < lowestHostCorr))
4254 fewestUnique = uniqueVals.size();
4255 lowestHostCorr = hostCorr;
4260 std::string keepVal = multiNodeNames[0].substr(
4261 runs[bestRunToFix].start,
4262 runs[bestRunToFix].end - runs[bestRunToFix].start);
4264 __COUTT__ <<
"Fixing digit group at positions "
4265 << runs[bestRunToFix].start <<
"-"
4266 << (runs[bestRunToFix].end - 1) <<
" to value '"
4268 <<
"' (fewest unique=" << fewestUnique <<
")"
4271 for(
unsigned int i = multiNodeNames.size() - 1;
4272 i > 0 && i < multiNodeNames.size();
4275 std::string val = multiNodeNames[i].substr(
4276 runs[bestRunToFix].start,
4277 runs[bestRunToFix].end -
4278 runs[bestRunToFix].start);
4281 __COUTT__ <<
"Numeric refinement trim: "
4282 << multiNodeNames[i]
4283 <<
" (digit group '" << val <<
"' != '"
4284 << keepVal <<
"')" << __E__;
4285 trimmedNodeNames.push_back(multiNodeNames[i]);
4286 skipSet.erase(multiNodeNames[i]);
4287 multiNodeNames.erase(multiNodeNames.begin() + i);
4288 hostnameArray.erase(hostnameArray.begin() + i);
4291 __COUT__ <<
"After numeric refinement: "
4292 << multiNodeNames.size() <<
" nodes remain for '"
4293 << nodeName <<
"'." << __E__;
4304 if(multiNodeNames.size() > 1)
4312 auto matchesCommonChunksPattern =
4313 [](
const std::string& name,
4314 const std::vector<std::string>& chunks,
4315 const std::vector<std::string>& wildcards) ->
bool {
4317 bool wildcardsAllNumeric = !wildcards.empty();
4318 for(
const auto& w : wildcards)
4321 w.find_first_not_of(
"0123456789") != std::string::npos)
4323 wildcardsAllNumeric =
false;
4329 for(
unsigned int c = 0; c < chunks.size(); ++c)
4331 if(chunks[c].empty())
4335 found = (name.size() >= chunks[c].size() &&
4337 0, chunks[c].size(), chunks[c]) == 0)
4339 : std::string::npos;
4342 found = name.find(chunks[c], pos);
4345 if(wildcardsAllNumeric && found != std::string::npos)
4347 std::string gap = name.substr(pos, found - pos);
4349 gap.find_first_not_of(
"0123456789") !=
4354 if(found == std::string::npos)
4356 pos = found + chunks[c].size();
4359 if(wildcardsAllNumeric && pos < name.size())
4361 std::string trailingGap = name.substr(pos);
4362 if(trailingGap.find_first_not_of(
"0123456789") !=
4369 bool collisionRetry =
true;
4370 while(collisionRetry && multiNodeNames.size() > 1)
4372 collisionRetry =
false;
4375 std::vector<std::string> trialCommonChunks;
4376 std::vector<std::string> trialWildcards;
4377 unsigned int trialFixedLen = 0;
4383 __COUT__ <<
"Collision check: trialCommonChunks = "
4388 bool collisionFound =
false;
4389 for(
const auto& trimmedNode : trimmedNodeNames)
4391 if(matchesCommonChunksPattern(
4392 trimmedNode, trialCommonChunks, trialWildcards))
4394 __COUT__ <<
"Collision detected: trimmed node '"
4396 <<
"' matches base pattern from commonChunks"
4398 collisionFound =
true;
4408 std::string currentStatusStr = status ?
"1" :
"0";
4409 for(
const auto& existingEntry :
4410 nodeTypeToObjectMap.at(typeString))
4412 std::string existingBaseName = existingEntry.first;
4413 size_t statusPos = existingBaseName.find(
";status=");
4414 if(statusPos != std::string::npos)
4417 if(existingBaseName.substr(
4419 std::string(
";status=").size()) !=
4423 existingBaseName.substr(0, statusPos);
4426 if(matchesCommonChunksPattern(existingBaseName,
4436 std::string existingGap;
4437 if(trialCommonChunks.size() == 1 &&
4438 existingBaseName.size() >
4439 trialCommonChunks[0].size())
4440 existingGap = existingBaseName.substr(
4441 trialCommonChunks[0].size());
4442 else if(trialCommonChunks.size() >= 2)
4444 size_t suffixLen = 0;
4446 ci < trialCommonChunks.size();
4448 suffixLen += trialCommonChunks[ci].size();
4449 if(existingBaseName.size() >
4450 trialCommonChunks[0].size() + suffixLen)
4451 existingGap = existingBaseName.substr(
4452 trialCommonChunks[0].size(),
4453 existingBaseName.size() -
4454 trialCommonChunks[0].size() -
4458 if(!existingGap.empty())
4460 bool gapInWildcards =
false;
4461 for(
const auto& w : trialWildcards)
4462 if(w == existingGap)
4464 gapInWildcards =
true;
4470 <<
"Existing entry '"
4471 << existingEntry.first
4472 <<
"' matches pattern but gap '"
4474 <<
"' is not in multinode wildcards"
4475 " - not a collision"
4482 <<
"Collision detected: existing map entry '"
4483 << existingEntry.first
4484 <<
"' matches base pattern from commonChunks"
4486 collisionFound =
true;
4496 __COUT__ <<
"Re-scoring remaining multi-node members with "
4497 "full character matching to resolve collision..."
4500 unsigned int fullMaxScore = 0;
4501 std::vector<unsigned int> fullScoreVector;
4502 fullScoreVector.push_back(-1);
4504 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4506 unsigned int fscore = 0;
4508 for(
unsigned int j = 0; j < multiNodeNames[0].size() &&
4509 j < multiNodeNames[i].size();
4512 if(multiNodeNames[0][j] == multiNodeNames[i][j])
4517 fullScoreVector.push_back(fscore);
4518 if(fscore > fullMaxScore)
4519 fullMaxScore = fscore;
4522 __COUT__ <<
"Full char rescore: maxScore = " << fullMaxScore
4526 bool anyTrimmed =
false;
4527 for(
unsigned int i = multiNodeNames.size() - 1;
4528 i > 0 && i < multiNodeNames.size();
4531 if(fullScoreVector[i] >= fullMaxScore)
4534 __COUT__ <<
"Collision trim: removing "
4535 << multiNodeNames[i] <<
" (score "
4536 << fullScoreVector[i] <<
" < " << fullMaxScore
4537 <<
") for node name " << nodeName << __E__;
4539 trimmedNodeNames.push_back(multiNodeNames[i]);
4540 skipSet.erase(multiNodeNames[i]);
4541 multiNodeNames.erase(multiNodeNames.begin() + i);
4542 hostnameArray.erase(hostnameArray.begin() + i);
4544 collisionRetry =
true;
4552 __COUT__ <<
"Cannot narrow multi-node group further to "
4553 "resolve collision. Abandoning multi-node "
4556 <<
"' - remaining members will be "
4557 "processed individually."
4561 for(
unsigned int i = 1; i < multiNodeNames.size(); ++i)
4562 skipSet.erase(multiNodeNames[i]);
4563 multiNodeNames.resize(1);
4564 hostnameArray.resize(1);
4569 __COUT__ <<
"After collision resolution:" << __E__;
4570 __COUTV__(nodeName);
4576 __COUTV__(nodeName);
4583 __COUT__ <<
"Reorganizing multinode '" << nodeName
4584 <<
"' alphabetically..." << __E__;
4586 std::pair<std::string , std::string >>
4588 for(
unsigned int i = 0; i < multiNodeNames.size(); ++i)
4590 std::make_pair(multiNodeNames[i], hostnameArray[i]));
4595 multiNodeNames.clear();
4596 hostnameArray.clear();
4597 for(
const auto& orderedPair : reorderSet)
4599 multiNodeNames.push_back(orderedPair.first);
4600 hostnameArray.push_back(orderedPair.second);
4604 __COUTV__(nodeName);
4609 auto expandNumericWildcards =
4610 [](std::vector<std::string>& commonChunks,
4611 std::vector<std::string>& wildcards,
4612 const std::string& logPrefix) {
4613 bool allDigitWC =
true;
4614 for(
const auto& wc : wildcards)
4616 if(wc.empty() || wc.find_first_not_of(
"0123456789") !=
4623 if(allDigitWC && !commonChunks.empty() &&
4624 !commonChunks[0].empty())
4626 size_t trailingDigits = 0;
4627 for(
int ci = (
int)commonChunks[0].size() - 1; ci >= 0;
4630 if(commonChunks[0][ci] >=
'0' &&
4631 commonChunks[0][ci] <=
'9')
4636 if(trailingDigits > 0 &&
4637 trailingDigits < commonChunks[0].size())
4639 std::string prefix = commonChunks[0].substr(
4640 commonChunks[0].size() - trailingDigits);
4641 commonChunks[0] = commonChunks[0].substr(
4642 0, commonChunks[0].size() - trailingDigits);
4643 for(
auto& wc : wildcards)
4647 << logPrefix <<
"moved '" << prefix
4648 <<
"' from commonChunk prefix into wildcards."
4655 if(multiNodeNames.size() > 1)
4657 std::vector<std::string> commonChunks;
4658 std::vector<std::string> wildcards;
4662 bool wildcardsNeeded =
4666 nodeFixedWildcardLength);
4668 if(!wildcardsNeeded || wildcards.size() != multiNodeNames.size())
4671 <<
"Impossible extractCommonChunks result! Please notify "
4672 "admins or try to simplify record naming convention."
4684 expandNumericWildcards(
4685 commonChunks, wildcards,
"Expanded numeric wildcards: ");
4691 for(
auto& commonChunk : commonChunks)
4693 nodeName += (!first ?
"*" :
"") + commonChunk;
4697 if(commonChunks.size() == 1)
4700 __COUTV__(nodeName);
4707 bool allIntegers =
true;
4708 for(
auto& wildcard : wildcards)
4711 else if(wildcard.size() == 0)
4713 allIntegers =
false;
4717 for(
unsigned int i = 0; i < wildcard.size(); ++i)
4718 if(!(wildcard[i] >=
'0' && wildcard[i] <=
'9'))
4720 allIntegers =
false;
4724 __COUTV__(allIntegers);
4730 std::vector<unsigned int> intWildcards;
4731 for(
auto& wildcard : wildcards)
4732 intWildcards.push_back(strtol(wildcard.c_str(), 0, 10));
4736 unsigned int hyphenLo = -1;
4737 bool isFirst =
true;
4738 for(
unsigned int i = 0; i < intWildcards.size(); ++i)
4740 if(i + 1 < intWildcards.size() &&
4741 intWildcards[i] + 1 == intWildcards[i + 1])
4753 (isFirst ?
"" :
",") +
4754 std::to_string(intWildcards[i]);
4759 if(intWildcards[hyphenLo] + 1 == intWildcards[i])
4761 (isFirst ?
"" :
",") +
4762 std::to_string(intWildcards[hyphenLo]) +
4763 "," + std::to_string(intWildcards[i]);
4766 (isFirst ?
"" :
",") +
4767 std::to_string(intWildcards[hyphenLo]) +
4768 "-" + std::to_string(intWildcards[i]);
4778 nodeFixedWildcardLength =
4782 __COUTV__(multiNodeString);
4783 __COUTV__(nodeFixedWildcardLength);
4786 if(hostnameArray.size() > 1)
4788 std::vector<std::string> commonChunks;
4789 std::vector<std::string> wildcards;
4793 bool wildcardsNeeded =
4797 hostFixedWildcardLength);
4799 __COUTV__(wildcardsNeeded);
4811 expandNumericWildcards(
4814 "Expanded numeric wildcards for hostname: ");
4820 for(
auto& commonChunk : commonChunks)
4822 hostname += (!first ?
"*" :
"") + commonChunk;
4826 if(wildcardsNeeded && commonChunks.size() == 1)
4829 __COUTV__(hostname);
4839 bool allIntegers =
true;
4840 for(
auto& wildcard : wildcards)
4841 for(
unsigned int i = 0; i < wildcard.size(); ++i)
4842 if(!(wildcard[i] >=
'0' && wildcard[i] <=
'9'))
4844 allIntegers =
false;
4848 __COUTV__(allIntegers);
4855 std::vector<unsigned int> intWildcards;
4856 for(
auto& wildcard : wildcards)
4857 intWildcards.push_back(
4858 strtol(wildcard.c_str(), 0, 10));
4862 unsigned int hyphenLo = -1;
4863 bool isFirst =
true;
4864 for(
unsigned int i = 0; i < intWildcards.size(); ++i)
4866 if(i + 1 < intWildcards.size() &&
4867 intWildcards[i] + 1 == intWildcards[i + 1])
4879 (isFirst ?
"" :
",") +
4880 std::to_string(intWildcards[i]);
4885 if(intWildcards[hyphenLo] + 1 ==
4888 (isFirst ?
"" :
",") +
4890 intWildcards[hyphenLo]) +
4891 "," + std::to_string(intWildcards[i]);
4894 (isFirst ?
"" :
",") +
4896 intWildcards[hyphenLo]) +
4897 "-" + std::to_string(intWildcards[i]);
4907 hostFixedWildcardLength =
4911 __COUTV__(hostArrayString);
4912 __COUTV__(hostFixedWildcardLength);
4922 auto result = nodeTypeToObjectMap.at(typeString)
4923 .emplace(std::make_pair(
4924 nodeName, std::vector<std::string /*property*/>()));
4928 __SS__ <<
"Here is the current nodeTypeToObjectMap:" << __E__;
4929 for(
const auto& typePair : nodeTypeToObjectMap)
4931 ss <<
"\tType: " << typePair.first << __E__;
4932 for(
const auto& nodePair : typePair.second)
4934 ss <<
"\t\tNode: " << nodePair.first << __E__;
4935 for(
const auto& property : nodePair.second)
4936 ss <<
"\t\t\tProperty: " <<
property << __E__;
4939 __COUT__ << ss.str() << __E__;
4945 <<
"Collision detected for node '" << nodeName <<
"' of type '"
4947 <<
"' when inserting into nodeTypeToObjectMap. This likely means "
4948 "that two nodes have the same name and status, and if so, "
4949 "they would be indistinguishable in printer syntax. "
4950 <<
"Please notify admins or try to simplify record naming "
4954 __SS__ <<
"Impossible printer syntax handling result! Collision of "
4955 "base names. Please notify "
4956 "admins or try to simplify record naming convention."
4961 nodeTypeToObjectMap.at(typeString)
4963 .push_back(status ?
"1" :
"0");
4965 nodeTypeToObjectMap.at(typeString).at(nodeName).push_back(hostname);
4967 nodeTypeToObjectMap.at(typeString).at(nodeName).push_back(subsystemId);
4968 if(multiNodeNames.size() > 1)
4970 nodeTypeToObjectMap.at(typeString)
4972 .push_back(multiNodeString);
4974 nodeTypeToObjectMap.at(typeString)
4976 .push_back(std::to_string(nodeFixedWildcardLength));
4978 if(hostnameArray.size() > 1)
4980 nodeTypeToObjectMap.at(typeString)
4982 .push_back(hostArrayString);
4984 nodeTypeToObjectMap.at(typeString)
4986 .push_back(std::to_string(hostFixedWildcardLength));
4990 __COUTV__(multiNodeString);
4992 __COUTV__(hostArrayString);
4993 __COUT__ <<
"Done with extraction of node '" << nodeName <<
"'" << __E__;
4999 __COUT__ <<
"Done getting artdaq nodes." << __E__;
5001 return ARTDAQTableBase::info_;
5015 const std::map<std::string ,
5016 std::map<std::string ,
5017 std::vector<std::string /*property*/>>>& nodeTypeToObjectMap,
5018 const std::map<std::string ,
5019 std::string >& subsystemObjectMap)
5021 __COUT__ <<
"setAndActivateARTDAQSystem()" << __E__;
5023 const std::string& author = cfgMgr->
getUsername();
5034 GroupEditStruct configGroupEdit(ConfigurationManager::GroupType::CONFIGURATION_TYPE,
5037 unsigned int artdaqSupervisorRow = TableView::INVALID;
5044 bool needArtdaqSupervisorParents =
true;
5045 bool needArtdaqSupervisorCreation =
false;
5047 __COUTV__(artdaqContext);
5052 const std::string& activeContextGroupName =
5053 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE);
5055 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE);
5056 const std::string& activeConfigGroupName = cfgMgr->getActiveGroupName(
5057 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
5058 const TableGroupKey& activeConfigGroupKey = cfgMgr->getActiveGroupKey(
5059 ConfigurationManager::GroupType::CONFIGURATION_TYPE);
5061 __COUTV__(activeContextGroupName);
5062 __COUTV__(activeContextGroupKey);
5063 __COUTV__(activeConfigGroupName);
5064 __COUTV__(activeConfigGroupKey);
5065 __COUTV__(cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5066 .
getNode(artdaqContext->contextUID_)
5069 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5070 .
getNode(artdaqContext->contextUID_)
5071 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5074 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5075 .
getNode(artdaqContext->contextUID_)
5076 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5077 .
getNode(artdaqContext->applications_[0].applicationUID_)
5079 __COUTV__(artdaqContext->applications_[0].applicationUID_);
5080 __COUTV__(XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
5082 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5083 .
getNode(artdaqContext->contextUID_)
5084 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5085 .
getNode(artdaqContext->applications_[0].applicationUID_)
5086 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_)
5090 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5091 .
getNode(artdaqContext->contextUID_)
5092 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5093 .
getNode(artdaqContext->applications_[0].applicationUID_)
5094 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
5099 needArtdaqSupervisorCreation =
true;
5101 artdaqSupervisorRow = artdaqSupervisorNode.
getRow();
5103 needArtdaqSupervisorParents =
false;
5107 needArtdaqSupervisorCreation =
true;
5109 __COUTV__(needArtdaqSupervisorCreation);
5112 if(!artdaqContext || needArtdaqSupervisorCreation)
5114 __COUT__ <<
"No artdaq Supervisor found! Creating..." << __E__;
5115 __COUTV__(needArtdaqSupervisorParents);
5117 std::string artdaqSupervisorUID;
5126 ARTDAQ_SUPERVISOR_TABLE,
true );
5130 std::stringstream ss;
5131 artdaqSupervisorTable.tableView_->print(ss);
5132 __COUT_MULTI__(0, ss.str());
5136 row = artdaqSupervisorTable.tableView_->
addRow(
5137 author,
true ,
"artdaqSupervisor");
5140 artdaqSupervisorUID =
5141 artdaqSupervisorTable.tableView_
5142 ->getDataView()[row][artdaqSupervisorTable.tableView_->
getColUID()];
5143 artdaqSupervisorRow = row;
5145 __COUTV__(artdaqSupervisorRow);
5146 __COUTV__(artdaqSupervisorUID);
5152 artdaqSupervisorTable.tableView_->
findCol(
5153 colARTDAQSupervisor_.colDAQInterfaceDebugLevel_));
5156 "${MRB_BUILDDIR}/../setup_ots.sh",
5158 artdaqSupervisorTable.tableView_->
findCol(
5159 colARTDAQSupervisor_.colDAQSetupScript_));
5163 ARTDAQ_READER_TABLE,
5165 artdaqSupervisorTable.tableView_->
findCol(
5166 colARTDAQSupervisor_.colLinkToBoardReaders_));
5170 artdaqSupervisorTable.tableView_->
findCol(
5171 colARTDAQSupervisor_.colLinkToBoardReadersGroupID_),
5172 artdaqSupervisorUID +
5176 ARTDAQ_BUILDER_TABLE,
5178 artdaqSupervisorTable.tableView_->
findCol(
5179 colARTDAQSupervisor_.colLinkToEventBuilders_));
5182 artdaqSupervisorTable.tableView_->
findCol(
5183 colARTDAQSupervisor_.colLinkToEventBuildersGroupID_),
5184 artdaqSupervisorUID +
5188 ARTDAQ_LOGGER_TABLE,
5190 artdaqSupervisorTable.tableView_->
findCol(
5191 colARTDAQSupervisor_.colLinkToDataLoggers_));
5194 artdaqSupervisorTable.tableView_->
findCol(
5195 colARTDAQSupervisor_.colLinkToDataLoggersGroupID_),
5196 artdaqSupervisorUID +
5200 ARTDAQ_DISPATCHER_TABLE,
5202 artdaqSupervisorTable.tableView_->
findCol(
5203 colARTDAQSupervisor_.colLinkToDispatchers_));
5206 artdaqSupervisorTable.tableView_->
findCol(
5207 colARTDAQSupervisor_.colLinkToDispatchersGroupID_),
5208 artdaqSupervisorUID +
5213 ARTDAQ_ROUTER_TABLE,
5215 artdaqSupervisorTable.tableView_->
findCol(
5216 colARTDAQSupervisor_.colLinkToRoutingManagers_));
5219 artdaqSupervisorTable.tableView_->
findCol(
5220 colARTDAQSupervisor_.colLinkToRoutingManagersGroupID_),
5221 artdaqSupervisorUID +
5226 std::stringstream ss;
5227 artdaqSupervisorTable.tableView_->print(ss);
5228 __COUT_MULTI__(0, ss.str());
5235 ConfigurationManager::GroupType::CONTEXT_TYPE, cfgMgr);
5238 ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME,
true );
5240 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME,
true );
5242 ConfigurationManager::XDAQ_APP_PROPERTY_TABLE_NAME,
5249 std::string contextUID;
5250 std::string contextAppGroupID;
5252 if(needArtdaqSupervisorParents)
5255 row = contextTable.tableView_->
addRow(
5256 author,
true ,
"artdaqContext");
5262 contextTable.tableView_
5263 ->getDataView()[row][contextTable.tableView_->
getColUID()];
5266 __COUTV__(contextUID);
5270 "http://${HOSTNAME}",
5272 contextTable.tableView_->
findCol(
5273 XDAQContextTable::colContext_.colAddress_));
5276 contextTable.tableView_->
findCol(
5277 XDAQContextTable::colContext_.colPort_),
5283 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME,
5285 contextTable.tableView_->
findCol(
5286 XDAQContextTable::colContext_.colLinkToApplicationTable_));
5289 contextTable.tableView_->
findCol(
5290 XDAQContextTable::colContext_.colLinkToApplicationGroupID_),
5291 "artdaqContextApps");
5293 __COUTV__(contextAppGroupID);
5297 std::string appPropertiesGroupID;
5303 if(needArtdaqSupervisorParents)
5307 unsigned int c = appTable.tableView_->
findCol(
5308 XDAQContextTable::colApplication_.colClass_);
5309 for(
unsigned int r = 0;
5310 r < appTable.tableView_->getNumberOfRows();
5312 if(appTable.tableView_->getDataView()[r][c] ==
5313 ARTDAQ_SUPERVISOR_CLASS)
5316 <<
"Found partially existing artdaq Supervisor "
5318 << appTable.tableView_->getDataView()
5320 <<
"'... Disabling it." << __E__;
5327 row = appTable.tableView_->
addRow(
5328 author,
true ,
"artdaqSupervisor");
5335 ->getDataView()[row][appTable.tableView_->
getColUID()];
5342 ARTDAQ_SUPERVISOR_CLASS,
5345 XDAQContextTable::colApplication_.colClass_));
5348 "${OTSDAQ_LIB}/libARTDAQSupervisor.so",
5351 XDAQContextTable::colApplication_.colModule_));
5356 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5357 .colApplicationGroupID_));
5361 ConfigurationManager::XDAQ_APP_PROPERTY_TABLE_NAME,
5363 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5364 .colLinkToPropertyTable_));
5367 appTable.tableView_->
findCol(XDAQContextTable::colApplication_
5368 .colLinkToPropertyGroupID_),
5369 appUID +
"Properties");
5371 __COUTV__(appPropertiesGroupID);
5375 __COUT__ <<
"Getting row of existing parent supervisor." << __E__;
5379 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5380 .
getNode(artdaqContext->contextUID_)
5381 .
getNode(XDAQContextTable::colContext_
5382 .colLinkToApplicationTable_)
5383 .
getNode(artdaqContext->applications_[0].applicationUID_)
5392 ARTDAQ_SUPERVISOR_TABLE,
5395 XDAQContextTable::colApplication_.colLinkToSupervisorTable_));
5397 artdaqSupervisorUID,
5400 XDAQContextTable::colApplication_.colLinkToSupervisorUID_));
5405 if(needArtdaqSupervisorParents)
5409 const std::vector<std::string> propertyUIDs = {
"Partition0",
5412 "BoardReaderTimeout",
5413 "EventBuilderTimeout",
5414 "DataLoggerTimeout",
5415 "DispatcherTimeout"};
5416 const std::vector<std::string> propertyNames = {
5418 "productsdir_for_bash_scripts",
5419 "max_fragment_size_bytes",
5420 "boardreader_timeout",
5421 "eventbuilder_timeout",
5422 "datalogger_timeout",
5423 "dispatcher_timeout"
5425 const std::vector<std::string> propertyValues = {
5435 for(
unsigned int i = 0; i < propertyNames.size(); ++i)
5438 row = appPropertyTable.tableView_->
addRow(
5441 appUID + propertyUIDs[i]);
5444 "1", row, appPropertyTable.tableView_->
getColStatus());
5448 "ots::SupervisorProperty",
5450 appPropertyTable.tableView_->
findCol(
5451 XDAQContextTable::colAppProperty_.colPropertyType_));
5456 appPropertyTable.tableView_->
findCol(
5457 XDAQContextTable::colAppProperty_.colPropertyName_));
5462 appPropertyTable.tableView_->
findCol(
5463 XDAQContextTable::colAppProperty_.colPropertyValue_));
5466 appPropertiesGroupID,
5468 appPropertyTable.tableView_->
findCol(
5469 XDAQContextTable::colAppProperty_.colPropertyGroupID_));
5474 std::stringstream ss;
5475 contextTable.tableView_->print(ss);
5476 __COUT_MULTI__(0, ss.str());
5479 std::stringstream ss;
5480 appTable.tableView_->print(ss);
5481 __COUT_MULTI__(0, ss.str());
5484 std::stringstream ss;
5485 appPropertyTable.tableView_->print(ss);
5486 __COUT_MULTI__(0, ss.str());
5489 contextTable.tableView_
5491 appTable.tableView_->
init();
5492 appPropertyTable.tableView_
5498 <<
"Table errors while creating ARTDAQ Supervisor. Erasing all newly "
5499 "created table versions."
5504 __COUT_INFO__ <<
"Edits complete for new artdaq Supervisor! Created '"
5505 << appUID <<
"'" << __E__;
5509 __SS__ <<
"DEBUG blocking artdaq supervisor save!" << __E__;
5513 contextGroupEdit.saveChanges(contextGroupEdit.originalGroupName_,
5525 artdaqSupervisorRow =
5526 cfgMgr->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
5527 .
getNode(artdaqContext->contextUID_)
5528 .
getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_)
5529 .
getNode(artdaqContext->applications_[0].applicationUID_)
5530 .
getNode(XDAQContextTable::colApplication_.colLinkToSupervisorTable_)
5534 __COUT__ <<
"------------------------- artdaq nodes to save:" << __E__;
5535 for(
auto& subsystemPair : subsystemObjectMap)
5537 __COUTV__(subsystemPair.first);
5541 for(
auto& nodeTypePair : nodeTypeToObjectMap)
5543 __COUTV__(nodeTypePair.first);
5545 for(
auto& nodePair : nodeTypePair.second)
5547 __COUTV__(nodePair.first);
5551 __COUT__ <<
"------------------------- end artdaq nodes to save." << __E__;
5555 __COUTV__(artdaqSupervisorRow);
5556 if(artdaqSupervisorRow >= TableView::INVALID)
5558 __SS__ <<
"Invalid artdaq Supervisor row " << artdaqSupervisorRow <<
" found!"
5573 ARTDAQ_SUPERVISOR_TABLE,
true );
5577 std::string artdaqSupervisorUID =
5578 artdaqSupervisorTable.tableView_
5579 ->getDataView()[artdaqSupervisorRow]
5580 [artdaqSupervisorTable.tableView_->
getColUID()];
5583 if(artdaqSupervisorTable.tableView_
5584 ->getDataView()[artdaqSupervisorRow]
5585 [artdaqSupervisorTable.tableView_->
findCol(
5586 colARTDAQSupervisor_.colLinkToBoardReaders_)] ==
5587 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5589 __COUT__ <<
"Fixing missing link to Readers" << __E__;
5591 ARTDAQ_READER_TABLE,
5592 artdaqSupervisorRow,
5593 artdaqSupervisorTable.tableView_->
findCol(
5594 colARTDAQSupervisor_.colLinkToBoardReaders_));
5596 artdaqSupervisorRow,
5597 artdaqSupervisorTable.tableView_->
findCol(
5598 colARTDAQSupervisor_.colLinkToBoardReadersGroupID_),
5599 artdaqSupervisorUID +
5604 if(artdaqSupervisorTable.tableView_
5605 ->getDataView()[artdaqSupervisorRow]
5606 [artdaqSupervisorTable.tableView_->
findCol(
5607 colARTDAQSupervisor_.colLinkToEventBuilders_)] ==
5608 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5610 __COUT__ <<
"Fixing missing link to Builders" << __E__;
5612 ARTDAQ_BUILDER_TABLE,
5613 artdaqSupervisorRow,
5614 artdaqSupervisorTable.tableView_->
findCol(
5615 colARTDAQSupervisor_.colLinkToEventBuilders_));
5617 artdaqSupervisorRow,
5618 artdaqSupervisorTable.tableView_->
findCol(
5619 colARTDAQSupervisor_.colLinkToEventBuildersGroupID_),
5620 artdaqSupervisorUID +
5625 if(artdaqSupervisorTable.tableView_
5626 ->getDataView()[artdaqSupervisorRow]
5627 [artdaqSupervisorTable.tableView_->
findCol(
5628 colARTDAQSupervisor_.colLinkToDataLoggers_)] ==
5629 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5631 __COUT__ <<
"Fixing missing link to Loggers" << __E__;
5633 ARTDAQ_LOGGER_TABLE,
5634 artdaqSupervisorRow,
5635 artdaqSupervisorTable.tableView_->
findCol(
5636 colARTDAQSupervisor_.colLinkToDataLoggers_));
5638 artdaqSupervisorRow,
5639 artdaqSupervisorTable.tableView_->
findCol(
5640 colARTDAQSupervisor_.colLinkToDataLoggersGroupID_),
5641 artdaqSupervisorUID +
5646 if(artdaqSupervisorTable.tableView_
5647 ->getDataView()[artdaqSupervisorRow]
5648 [artdaqSupervisorTable.tableView_->
findCol(
5649 colARTDAQSupervisor_.colLinkToDispatchers_)] ==
5650 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5652 __COUT__ <<
"Fixing missing link to Dispatchers" << __E__;
5654 ARTDAQ_DISPATCHER_TABLE,
5655 artdaqSupervisorRow,
5656 artdaqSupervisorTable.tableView_->
findCol(
5657 colARTDAQSupervisor_.colLinkToDispatchers_));
5659 artdaqSupervisorRow,
5660 artdaqSupervisorTable.tableView_->
findCol(
5661 colARTDAQSupervisor_.colLinkToDispatchersGroupID_),
5662 artdaqSupervisorUID +
5667 if(artdaqSupervisorTable.tableView_
5668 ->getDataView()[artdaqSupervisorRow]
5669 [artdaqSupervisorTable.tableView_->
findCol(
5670 colARTDAQSupervisor_.colLinkToRoutingManagers_)] ==
5671 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5673 __COUT__ <<
"Fixing missing link to Routers" << __E__;
5675 ARTDAQ_ROUTER_TABLE,
5676 artdaqSupervisorRow,
5677 artdaqSupervisorTable.tableView_->
findCol(
5678 colARTDAQSupervisor_.colLinkToRoutingManagers_));
5680 artdaqSupervisorRow,
5681 artdaqSupervisorTable.tableView_->
findCol(
5682 colARTDAQSupervisor_.colLinkToRoutingManagersGroupID_),
5683 artdaqSupervisorUID +
5688 std::stringstream ss;
5689 artdaqSupervisorTable.tableView_->print(ss);
5690 __COUT_MULTI__(0, ss.str());
5696 ARTDAQ_SUBSYSTEM_TABLE,
true );
5699 artdaqSubsystemTable.tableView_->deleteAllRows();
5701 for(
auto& subsystemPair : subsystemObjectMap)
5703 __COUTV__(subsystemPair.first);
5704 __COUTV__(subsystemPair.second);
5707 row = artdaqSubsystemTable.tableView_->
addRow(
5708 author,
true , subsystemPair.first);
5710 if(subsystemPair.second !=
"" &&
5711 subsystemPair.second != TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
5712 subsystemPair.second != TableViewColumnInfo::DATATYPE_STRING_ALT_DEFAULT &&
5713 subsystemPair.second != NULL_SUBSYSTEM_DESTINATION_LABEL)
5717 ARTDAQ_SUBSYSTEM_TABLE,
5719 artdaqSubsystemTable.tableView_->
findCol(
5720 colARTDAQSubsystem_.colLinkToDestination_));
5722 subsystemPair.second,
5724 artdaqSubsystemTable.tableView_->
findCol(
5725 colARTDAQSubsystem_.colLinkToDestinationUID_));
5732 for(
auto& nodeTypePair : nodeTypeToObjectMap)
5734 __COUTV__(nodeTypePair.first);
5738 auto it =
processTypes_.mapToTable_.find(nodeTypePair.first);
5741 __SS__ <<
"Invalid artdaq node type '" << nodeTypePair.first
5742 <<
"' attempted!" << __E__;
5745 __COUTV__(it->second);
5755 if(nodeTypePair.second.size())
5758 __COUT__ <<
"Ignoring missing table '" << it->second
5759 <<
"' since there were no user records attempted of type '"
5760 << nodeTypePair.first <<
".'" << __E__;
5767 bool hasArtProcessName =
false;
5768 unsigned int artProcessNameCol = -1;
5772 __COUT__ <<
"Identified non-Reader, no-Router type '"
5773 << nodeTypePair.first
5774 <<
"' that has an art link and thus Process Name, so creating "
5775 "table edit structure to ART table."
5778 ARTDAQTableBase::ARTDAQ_ART_TABLE,
true );
5781 std::stringstream ss;
5782 artTable->tableView_->print(ss);
5783 __COUT_MULTI__(1, ss.str());
5785 artProcessNameCol = artTable->tableView_->
findCol(
5786 ARTDAQTableBase::colARTDAQArt_.colProcessName_);
5787 __COUTTV__(artProcessNameCol);
5789 hasArtProcessName =
true;
5791 __COUTV__(hasArtProcessName);
5793 const unsigned int commentCol =
5794 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_COMMENT);
5795 const unsigned int authorCol =
5796 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_AUTHOR);
5797 const unsigned int timestampCol =
5798 typeTable.tableView_->
findColByType(TableViewColumnInfo::TYPE_TIMESTAMP);
5801 std::map<
unsigned int ,
bool > deleteRecordMap;
5802 unsigned int maxRowToDelete = typeTable.tableView_->getNumberOfRows();
5803 for(
unsigned int r = 0; r < typeTable.tableView_->getNumberOfRows(); ++r)
5804 deleteRecordMap.emplace(std::make_pair(
5807 __COUTTV__(maxRowToDelete);
5813 const unsigned int ORIG_MAP_ART_PROC_NAME_COL = -1;
5814 std::map<std::string ,
5815 std::map<
unsigned int , std::string >>
5816 originalMultinodeValues;
5817 std::map<std::string ,
5818 std::map<
unsigned int ,
5821 originalMultinodeSameSiblingValues;
5824 std::map<
unsigned int ,
5826 std::vector<std::string >>>>
5827 originalMultinodeAllSiblingEmbeddedName;
5830 std::map<
unsigned int ,
5832 std::vector<std::string >>>>
5833 originalMultinodeAllSiblingEmbeddedPrinterIndex;
5836 for(
auto& nodePair : nodeTypePair.second)
5838 __COUTV__(nodePair.first);
5841 std::vector<std::string> nodeIndices, hostnameIndices;
5842 unsigned int hostnameFixedWidth = 0, nodeNameFixedWidth = 0;
5843 std::string hostname;
5850 for(
unsigned int i = 0; i < nodePair.second.size(); ++i)
5852 __COUTV__(nodePair.second[i]);
5856 std::string nodeName;
5862 if(nodePair.second[i][0] ==
':')
5864 __COUT__ <<
"Handling original multi-node." << __E__;
5869 std::string lastOriginalName;
5870 std::vector<std::string> originalParameterArr =
5872 &(nodePair.second[i].c_str()[1]),
5875 if(originalParameterArr.size() != 3)
5877 __SS__ <<
"Illegal original name parameter string '"
5878 << nodePair.second[i] <<
"!'" << __E__;
5884 unsigned int fixedWidth;
5885 sscanf(originalParameterArr[0].c_str(),
"%u", &fixedWidth);
5886 __COUTV__(fixedWidth);
5888 std::vector<std::string> printerSyntaxArr =
5893 std::vector<std::string> originalNodeIndices;
5894 for(
auto& printerSyntaxValue : printerSyntaxArr)
5896 __COUTV__(printerSyntaxValue);
5898 std::vector<std::string> printerSyntaxRange =
5900 printerSyntaxValue, {
'-'} );
5902 if(printerSyntaxRange.size() == 0 ||
5903 printerSyntaxRange.size() > 2)
5905 __SS__ <<
"Illegal multi-node printer syntax string '"
5906 << printerSyntaxValue <<
"!'" << __E__;
5909 else if(printerSyntaxRange.size() == 1)
5911 __COUTV__(printerSyntaxRange[0]);
5912 originalNodeIndices.push_back(printerSyntaxRange[0]);
5916 unsigned int lo, hi;
5917 sscanf(printerSyntaxRange[0].c_str(),
"%u", &lo);
5918 sscanf(printerSyntaxRange[1].c_str(),
"%u", &hi);
5922 sscanf(printerSyntaxRange[0].c_str(),
"%u", &hi);
5924 for(; lo <= hi; ++lo)
5927 originalNodeIndices.push_back(std::to_string(lo));
5932 __COUTTV__(originalParameterArr[2]);
5934 originalParameterArr[2] = originalParameterArr[2].substr(
5935 0, originalParameterArr[2].find(
";status="));
5936 __COUTV__(originalParameterArr[2]);
5937 std::vector<std::string> originalNamePieces =
5942 if(originalNamePieces.size() < 2)
5944 __SS__ <<
"Illegal original multi-node name template - "
5945 "please use * to indicate where the multi-node "
5946 "index should be inserted!"
5953 std::stringstream ss;
5954 typeTable.tableView_->print(ss);
5955 __COUT_MULTI__(1, ss.str());
5960 <<
"originalMultinodeSameSiblingValues init col map for "
5961 << nodePair.first << __E__;
5962 originalMultinodeSameSiblingValues.emplace(std::make_pair(
5968 __COUT__ <<
"originalMultinodeAllSiblingEmbeddedName init "
5970 << nodePair.first << __E__;
5971 originalMultinodeAllSiblingEmbeddedName.emplace(std::make_pair(
5980 __COUT__ <<
"originalMultinodeAllSiblingEmbeddedPrinterIndex "
5982 << nodePair.first << __E__;
5983 originalMultinodeAllSiblingEmbeddedPrinterIndex.emplace(
5996 unsigned int originalRow = TableView::INVALID,
5997 lastOriginalRow = TableView::INVALID,
5998 lastArtProcessRow = TableView::INVALID;
5999 for(
unsigned int i = 0; i < originalNodeIndices.size(); ++i)
6001 std::string originalName = originalNamePieces[0];
6002 std::string nodeNameIndex;
6003 for(
unsigned int p = 1; p < originalNamePieces.size();
6006 nodeNameIndex = originalNodeIndices[i];
6009 if(nodeNameIndex.size() > fixedWidth)
6011 __SS__ <<
"Illegal original node name index '"
6013 <<
"' - length is longer than fixed "
6014 "width requirement of "
6015 << fixedWidth <<
"!" << __E__;
6020 while(nodeNameIndex.size() < fixedWidth)
6021 nodeNameIndex =
"0" + nodeNameIndex;
6024 originalName += nodeNameIndex + originalNamePieces[p];
6026 __COUTTV__(originalName);
6027 originalRow = typeTable.tableView_->
findRow(
6032 __COUTTV__(originalRow);
6036 auto result = originalMultinodeValues.emplace(
6037 std::make_pair(originalName,
6038 std::map<
unsigned int ,
6042 <<
"originalName '" << originalName
6043 <<
"' already in original multinode value cache."
6047 __COUT__ <<
"Saving multinode value " << originalName
6048 <<
"[" << originalRow
6049 <<
"][*] with row count = "
6050 << typeTable.tableView_->getNumberOfRows()
6054 for(
unsigned int col = 0;
6055 col < typeTable.tableView_->getNumberOfColumns();
6058 if(typeTable.tableView_->getColumnInfo(col)
6061 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK ||
6062 typeTable.tableView_->getColumnInfo(col)
6065 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID ||
6066 typeTable.tableView_->getColumnInfo(col)
6069 ARTDAQ_TYPE_TABLE_HOSTNAME ||
6070 typeTable.tableView_->getColumnInfo(col)
6073 typeTable.tableView_->getColumnInfo(col)
6075 col == timestampCol ||
6082 <<
"Caching node value: " << originalName
6083 <<
"[" << originalRow <<
"][" << col
6085 << typeTable.tableView_
6086 ->getColumnInfo(col)
6089 << typeTable.tableView_
6090 ->getDataView()[originalRow][col]
6092 originalMultinodeValues.at(originalName)
6093 .emplace(std::make_pair(
6095 typeTable.tableView_
6096 ->getDataView()[originalRow]
6101 for(
const auto& pair :
6102 originalMultinodeSameSiblingValues)
6103 __COUTT__ <<
"originalMultinodeSameSiblin"
6105 << pair.first <<
"]" << __E__;
6107 originalMultinodeSameSiblingValues
6109 .emplace(std::make_pair(
6114 typeTable.tableView_
6116 [originalRow][col])));
6118 for(
const auto& pair :
6119 originalMultinodeAllSiblingEmbeddedName)
6120 __COUTT__ <<
"originalMultinodeAllSibling"
6122 << pair.first <<
"]" << __E__;
6123 originalMultinodeAllSiblingEmbeddedName
6125 .emplace(std::make_pair(
6128 typeTable.tableView_
6131 .find(originalName) !=
6134 std::vector<std::string>())));
6136 for(
const auto& pair :
6137 originalMultinodeAllSiblingEmbeddedPrinterIndex)
6138 __COUTT__ <<
"originalMultinodeAllSibling"
6139 "EmbeddedPrinterIndex["
6140 << pair.first <<
"]" << __E__;
6141 originalMultinodeAllSiblingEmbeddedPrinterIndex
6143 .emplace(std::make_pair(
6146 typeTable.tableView_
6149 .find(nodeNameIndex) !=
6152 std::vector<std::string>())));
6158 originalMultinodeSameSiblingValues
6164 originalMultinodeAllSiblingEmbeddedName
6168 if(originalMultinodeAllSiblingEmbeddedName
6174 <<
"Determine string splits for "
6177 const std::string& val =
6178 typeTable.tableView_
6179 ->getDataView()[originalRow]
6181 size_t pos = val.find(originalName);
6182 originalMultinodeAllSiblingEmbeddedName
6186 val.substr(0, pos));
6187 originalMultinodeAllSiblingEmbeddedName
6190 .second.push_back(val.substr(
6191 pos + originalName.size()));
6193 originalMultinodeAllSiblingEmbeddedName
6199 originalMultinodeAllSiblingEmbeddedPrinterIndex
6203 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6208 __COUTT__ <<
"Determine string "
6209 "splits for embedded "
6210 "printer syntax index: "
6211 << nodeNameIndex << __E__;
6212 const std::string& val =
6213 typeTable.tableView_
6214 ->getDataView()[originalRow]
6216 size_t pos = val.find(nodeNameIndex);
6217 originalMultinodeAllSiblingEmbeddedPrinterIndex
6221 val.substr(0, pos));
6222 originalMultinodeAllSiblingEmbeddedPrinterIndex
6225 .second.push_back(val.substr(
6226 pos + nodeNameIndex.size()));
6228 originalMultinodeAllSiblingEmbeddedPrinterIndex
6236 if(originalMultinodeSameSiblingValues
6241 __COUTT__ <<
"Checking sibling same "
6243 << nodePair.first << __E__;
6244 if(typeTable.tableView_
6245 ->getDataView()[originalRow]
6247 typeTable.tableView_->getDataView()
6248 [lastOriginalRow][col])
6251 <<
"Found different sibling "
6254 << nodePair.first << __E__;
6255 originalMultinodeSameSiblingValues
6261 if(originalMultinodeAllSiblingEmbeddedName
6266 __COUTT__ <<
"Checking sibling "
6267 "embedded name... for "
6268 << nodePair.first <<
":"
6269 << originalName << __E__;
6270 if(typeTable.tableView_
6271 ->getDataView()[originalRow]
6273 .find(originalName) ==
6276 __COUT__ <<
"Found no embedded "
6278 << col <<
" looking for "
6279 << originalName << __E__;
6280 originalMultinodeAllSiblingEmbeddedName
6286 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6292 <<
"Checking sibling embedded "
6293 "printer syntax index... for "
6294 << nodePair.first <<
":"
6295 << nodeNameIndex << __E__;
6296 if(typeTable.tableView_
6297 ->getDataView()[originalRow]
6299 .find(nodeNameIndex) ==
6302 __COUT__ <<
"Found no embedded "
6305 << col <<
" looking for "
6308 originalMultinodeAllSiblingEmbeddedPrinterIndex
6317 <<
"originalMultinodeSameSiblingValues["
6318 << nodePair.first <<
"][" << col <<
"] = "
6319 << originalMultinodeSameSiblingValues
6325 <<
"originalMultinodeAllSiblingEmbeddedNa"
6327 << nodePair.first <<
"][" << col <<
"] = "
6328 << originalMultinodeAllSiblingEmbeddedName
6334 <<
"originalMultinodeAllSiblingEmbeddedPr"
6336 << nodePair.first <<
"][" << col <<
"] = "
6337 << originalMultinodeAllSiblingEmbeddedPrinterIndex
6343 if(hasArtProcessName && artTable &&
6344 typeTable.tableView_->getColumnInfo(col)
6346 ARTDAQTableBase::colARTDAQNotReader_
6351 <<
"Checking ART Process Name... for "
6353 << originalName <<
"' / "
6354 << typeTable.tableView_
6355 ->getDataView()[originalRow]
6358 unsigned int artRow =
6359 artTable->tableView_->
findRow(
6362 typeTable.tableView_
6363 ->getDataView()[originalRow]
6368 <<
"Found ART Process Name = "
6369 << artTable->tableView_->getDataView()
6370 [artRow][artProcessNameCol]
6374 originalMultinodeValues.at(originalName)
6375 .emplace(std::make_pair(
6376 ORIG_MAP_ART_PROC_NAME_COL,
6377 artTable->tableView_
6380 [artProcessNameCol]));
6382 originalMultinodeValues
6384 .at(ORIG_MAP_ART_PROC_NAME_COL));
6387 originalMultinodeSameSiblingValues
6389 .emplace(std::make_pair(
6390 ORIG_MAP_ART_PROC_NAME_COL,
6394 artTable->tableView_
6397 [artProcessNameCol])));
6398 originalMultinodeAllSiblingEmbeddedName
6400 .emplace(std::make_pair(
6401 ORIG_MAP_ART_PROC_NAME_COL,
6403 artTable->tableView_
6407 .find(originalName) !=
6410 std::vector<std::string>())));
6411 originalMultinodeAllSiblingEmbeddedPrinterIndex
6413 .emplace(std::make_pair(
6414 ORIG_MAP_ART_PROC_NAME_COL,
6416 artTable->tableView_
6424 std::vector<std::string>())));
6430 originalMultinodeSameSiblingValues
6432 .at(ORIG_MAP_ART_PROC_NAME_COL)
6436 originalMultinodeAllSiblingEmbeddedName
6438 .at(ORIG_MAP_ART_PROC_NAME_COL)
6440 if(originalMultinodeAllSiblingEmbeddedName
6442 .at(ORIG_MAP_ART_PROC_NAME_COL)
6446 <<
"Determine string splits "
6449 const std::string& val =
6450 artTable->tableView_
6453 [artProcessNameCol];
6455 val.find(originalName);
6456 originalMultinodeAllSiblingEmbeddedName
6458 .at(ORIG_MAP_ART_PROC_NAME_COL)
6460 val.substr(0, pos));
6461 originalMultinodeAllSiblingEmbeddedName
6463 .at(ORIG_MAP_ART_PROC_NAME_COL)
6464 .second.push_back(val.substr(
6466 originalName.size()));
6468 originalMultinodeAllSiblingEmbeddedName
6470 .at(ORIG_MAP_ART_PROC_NAME_COL)
6474 originalMultinodeAllSiblingEmbeddedPrinterIndex
6476 .at(ORIG_MAP_ART_PROC_NAME_COL)
6478 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6480 .at(ORIG_MAP_ART_PROC_NAME_COL)
6484 <<
"Determine string splits "
6485 "for embedded printer "
6487 << nodeNameIndex << __E__;
6488 const std::string& val =
6489 artTable->tableView_
6492 [artProcessNameCol];
6494 val.find(nodeNameIndex);
6495 originalMultinodeAllSiblingEmbeddedPrinterIndex
6497 .at(ORIG_MAP_ART_PROC_NAME_COL)
6499 val.substr(0, pos));
6500 originalMultinodeAllSiblingEmbeddedPrinterIndex
6502 .at(ORIG_MAP_ART_PROC_NAME_COL)
6503 .second.push_back(val.substr(
6505 nodeNameIndex.size()));
6507 originalMultinodeAllSiblingEmbeddedPrinterIndex
6509 .at(ORIG_MAP_ART_PROC_NAME_COL)
6515 if(originalMultinodeSameSiblingValues
6517 .at(ORIG_MAP_ART_PROC_NAME_COL)
6520 __COUTT__ <<
"Checking sibling "
6521 "same values... for "
6524 if(artTable->tableView_
6527 [artProcessNameCol] !=
6528 artTable->tableView_
6531 [artProcessNameCol])
6534 <<
"Found different "
6536 "at artProcessNameCol="
6537 << artProcessNameCol
6541 originalMultinodeSameSiblingValues
6543 .at(ORIG_MAP_ART_PROC_NAME_COL)
6547 if(originalMultinodeAllSiblingEmbeddedName
6549 .at(ORIG_MAP_ART_PROC_NAME_COL)
6553 <<
"Checking sibling "
6554 "embedded name... for "
6555 << nodePair.first <<
":"
6556 << originalName << __E__;
6557 if(artTable->tableView_
6561 .find(originalName) ==
6565 <<
"Found no embedded "
6567 "artProcessNameCol="
6568 << artProcessNameCol
6570 << originalName << __E__;
6571 originalMultinodeAllSiblingEmbeddedName
6573 .at(ORIG_MAP_ART_PROC_NAME_COL)
6577 if(originalMultinodeAllSiblingEmbeddedPrinterIndex
6579 .at(ORIG_MAP_ART_PROC_NAME_COL)
6583 <<
"Checking sibling "
6584 "embedded printer syntax "
6586 << nodePair.first <<
":"
6587 << nodeNameIndex << __E__;
6588 if(artTable->tableView_
6592 .find(nodeNameIndex) ==
6596 <<
"Found no embedded "
6597 "printer syntax index "
6598 "at artProcessNameCol="
6599 << artProcessNameCol
6601 << nodeNameIndex << __E__;
6602 originalMultinodeAllSiblingEmbeddedPrinterIndex
6604 .at(ORIG_MAP_ART_PROC_NAME_COL)
6611 <<
"originalMultinodeSameSiblingValue"
6613 << nodePair.first <<
"]["
6614 << ORIG_MAP_ART_PROC_NAME_COL
6616 << originalMultinodeSameSiblingValues
6618 .at(ORIG_MAP_ART_PROC_NAME_COL)
6622 <<
"originalMultinodeAllSiblingEmbedd"
6624 << nodePair.first <<
"]["
6625 << ORIG_MAP_ART_PROC_NAME_COL
6627 << originalMultinodeAllSiblingEmbeddedName
6629 .at(ORIG_MAP_ART_PROC_NAME_COL)
6633 <<
"originalMultinodeAllSiblingEmbedd"
6635 << nodePair.first <<
"]["
6636 << ORIG_MAP_ART_PROC_NAME_COL
6638 << originalMultinodeAllSiblingEmbeddedPrinterIndex
6640 .at(ORIG_MAP_ART_PROC_NAME_COL)
6645 <<
"Checking ART Process Name "
6646 "complete for originalName='"
6647 << originalName <<
"' / "
6648 << typeTable.tableView_
6649 ->getDataView()[originalRow]
6663 lastOriginalRow = originalRow;
6665 __COUTTV__(lastOriginalRow);
6666 lastOriginalName = originalName;
6669 for(
const auto& pair :
6670 originalMultinodeSameSiblingValues.at(nodePair.first))
6671 __COUTT__ <<
"originalMultinodeSameSiblingValues["
6672 << nodePair.first <<
"][" << pair.first
6673 <<
"] = " << pair.second.first << __E__;
6674 for(
const auto& pair :
6675 originalMultinodeAllSiblingEmbeddedName.at(
6677 __COUTT__ <<
"originalMultinodeAllSiblingEmbeddedName["
6678 << nodePair.first <<
"][" << pair.first
6679 <<
"] = " << pair.second.first << __E__;
6680 for(
const auto& pair :
6681 originalMultinodeAllSiblingEmbeddedPrinterIndex.at(
6684 <<
"originalMultinodeAllSiblingEmbeddedPrinterIndex["
6685 << nodePair.first <<
"][" << pair.first
6686 <<
"] = " << pair.second.first << __E__;
6688 __COUTTV__(lastOriginalRow);
6689 row = lastOriginalRow;
6694 std::string originalName = nodePair.second[i].substr(
6695 0, nodePair.second[i].find(
";status="));
6696 __COUTV__(originalName);
6699 row = typeTable.tableView_->
findRow(
6709 nodeName = nodePair.first;
6710 __COUTV__(nodeName);
6712 nodeName = nodeName.substr(0, nodeName.find(
";status="));
6715 std::string tmpNodeName = nodeName;
6717 for(
size_t c = 0; c < tmpNodeName.size(); ++c)
6718 if(tmpNodeName[c] !=
'*')
6719 nodeName += tmpNodeName[c];
6722 __COUTV__(nodeName);
6723 if(row == TableView::INVALID)
6726 row = typeTable.tableView_->
addRow(
6727 author,
true , nodeName);
6732 __COUT__ <<
"Handling new " << nodeTypePair.first
6733 <<
" defaults!" << __E__;
6736 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6741 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6743 typeTable.tableView_->
findCol(
6744 ARTDAQTableBase::colARTDAQReader_
6745 .colLinkToDaqParameters_));
6746 std::string daqParameterGroupID =
6749 typeTable.tableView_->
findCol(
6750 ARTDAQTableBase::colARTDAQReader_
6751 .colLinkToDaqParametersGroupID_),
6752 nodeName +
"DaqParameters");
6755 std::stringstream ss;
6756 typeTable.tableView_->print(ss);
6757 __COUT_MULTI__(1, ss.str());
6761 const std::vector<std::string> parameterUIDs = {
6762 "BoardID",
"FragmentID"};
6764 const std::vector<std::string> parameterNames = {
6768 const std::vector<std::string> parameterValues = {
6773 unsigned int parameterRow;
6774 for(
unsigned int i = 0; i < parameterNames.size(); ++i)
6777 parameterRow = daqParameterTable.tableView_->
addRow(
6780 nodeName + parameterUIDs[i]);
6791 daqParameterTable.tableView_->
findCol(
6792 ARTDAQTableBase::colARTDAQDaqParameter_
6793 .colDaqParameterKey_));
6798 daqParameterTable.tableView_->
findCol(
6799 ARTDAQTableBase::colARTDAQDaqParameter_
6800 .colDaqParameterValue_));
6803 daqParameterGroupID,
6805 daqParameterTable.tableView_->
findCol(
6806 ARTDAQTableBase::colARTDAQDaqParameter_
6807 .colDaqParameterGroupID_));
6811 daqParameterTable.tableView_
6819 __COUT__ <<
"Handling new " << nodeTypePair.first
6820 <<
" defaults!" << __E__;
6825 ARTDAQTableBase::ARTDAQ_DAQ_TABLE,
6828 unsigned int daqRecordRow = daqTable.tableView_->
addRow(
6832 std::string daqRecordUID =
6834 ->getDataView()[daqRecordRow]
6839 ARTDAQTableBase::ARTDAQ_DAQ_TABLE,
6841 typeTable.tableView_->
findCol(
6842 ARTDAQTableBase::colARTDAQNotReader_
6847 typeTable.tableView_->
findCol(
6848 ARTDAQTableBase::colARTDAQNotReader_
6849 .colLinkToDaqUID_));
6853 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6857 ARTDAQTableBase::ARTDAQ_DAQ_PARAMETER_TABLE,
6860 ARTDAQTableBase::colARTDAQDaq_
6861 .colLinkToDaqParameters_));
6862 std::string daqParameterGroupID =
6866 ARTDAQTableBase::colARTDAQDaq_
6867 .colLinkToDaqParametersGroupID_),
6868 nodeName +
"DaqParameters");
6871 const std::vector<std::string> parameterUIDs = {
6872 "BufferCount",
"FragmentsPerEvent"};
6874 const std::vector<std::string> parameterNames = {
6876 "expected_fragments_per_event"
6878 const std::vector<std::string> parameterValues = {
6883 unsigned int parameterRow;
6884 for(
unsigned int i = 0; i < parameterNames.size(); ++i)
6887 parameterRow = daqParameterTable.tableView_->
addRow(
6890 nodeName + parameterUIDs[i]);
6901 daqParameterTable.tableView_->
findCol(
6902 ARTDAQTableBase::colARTDAQDaqParameter_
6903 .colDaqParameterKey_));
6908 daqParameterTable.tableView_->
findCol(
6909 ARTDAQTableBase::colARTDAQDaqParameter_
6910 .colDaqParameterValue_));
6913 daqParameterGroupID,
6915 daqParameterTable.tableView_->
findCol(
6916 ARTDAQTableBase::colARTDAQDaqParameter_
6917 .colDaqParameterGroupID_));
6923 daqParameterTable.tableView_
6931 <<
"Reusing row " << row <<
" current-UID="
6932 << typeTable.tableView_
6933 ->getDataView()[row]
6935 <<
" as (temporarily to basename if multinode) new-UID="
6936 << nodeName << __E__;
6937 typeTable.tableView_
6946 if(row < maxRowToDelete)
6947 deleteRecordMap[row] =
false;
6954 artdaqSupervisorTable.tableView_
6955 ->getDataView()[artdaqSupervisorRow]
6956 [artdaqSupervisorTable.tableView_->
findCol(
6958 .at(nodeTypePair.first))],
6960 typeTable.tableView_->
findCol(
6962 nodeTypePair.first)));
6975 hostname = nodePair.second[i];
6979 typeTable.tableView_->
findCol(ARTDAQ_TYPE_TABLE_HOSTNAME));
6984 if(nodePair.second[i] !=
"" &&
6985 nodePair.second[i] !=
6986 TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
6987 nodePair.second[i] !=
6988 TableViewColumnInfo::DATATYPE_STRING_ALT_DEFAULT)
6991 if(subsystemObjectMap.find(nodePair.second[i]) ==
6992 subsystemObjectMap.end())
6994 __SS__ <<
"Illegal subsystem '" << nodePair.second[i]
6995 <<
"' mismatch!" << __E__;
7000 ARTDAQ_SUBSYSTEM_TABLE,
7002 typeTable.tableView_->
findCol(
7003 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK));
7007 typeTable.tableView_->
findCol(
7008 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK_UID));
7013 TableViewColumnInfo::DATATYPE_LINK_DEFAULT,
7015 typeTable.tableView_->
findCol(
7016 ARTDAQ_TYPE_TABLE_SUBSYSTEM_LINK));
7020 i == 4 || i == 5 || i == 6 ||
7027 __COUT__ <<
"Handling printer syntax i=" << i << __E__;
7029 std::vector<std::string> printerSyntaxArr =
7033 if(printerSyntaxArr.size() == 2)
7035 if(printerSyntaxArr[0] ==
7038 sscanf(printerSyntaxArr[1].c_str(),
7040 &nodeNameFixedWidth);
7041 __COUTV__(nodeNameFixedWidth);
7044 else if(printerSyntaxArr[0] ==
7047 sscanf(printerSyntaxArr[1].c_str(),
7049 &hostnameFixedWidth);
7050 __COUTV__(hostnameFixedWidth);
7056 for(
auto& printerSyntaxValue : printerSyntaxArr)
7058 __COUTV__(printerSyntaxValue);
7060 std::vector<std::string> printerSyntaxRange =
7063 if(printerSyntaxRange.size() == 0 ||
7064 printerSyntaxRange.size() > 2)
7066 __SS__ <<
"Illegal multi-node printer syntax string '"
7067 << printerSyntaxValue <<
"!'" << __E__;
7070 else if(printerSyntaxRange.size() == 1)
7073 __COUTV__(printerSyntaxRange[0]);
7078 nodeIndices.push_back(printerSyntaxRange[0]);
7080 hostnameIndices.push_back(printerSyntaxRange[0]);
7084 unsigned int lo, hi;
7085 sscanf(printerSyntaxRange[0].c_str(),
"%u", &lo);
7086 sscanf(printerSyntaxRange[1].c_str(),
"%u", &hi);
7090 sscanf(printerSyntaxRange[0].c_str(),
"%u", &hi);
7092 for(; lo <= hi; ++lo)
7096 nodeIndices.push_back(std::to_string(lo));
7098 hostnameIndices.push_back(std::to_string(lo));
7105 __SS__ <<
"Unexpected parameter[" << i <<
" '"
7106 << nodePair.second[i] <<
"' for node " << nodePair.first
7112 __COUTV__(nodeIndices.size());
7113 __COUTV__(hostnameIndices.size());
7115 if(hostnameIndices.size())
7117 if(hostnameIndices.size() != nodeIndices.size())
7119 __SS__ <<
"Illegal associated hostname array has count "
7120 << hostnameIndices.size()
7121 <<
" which is not equal to the node count "
7122 << nodeIndices.size() <<
"!" << __E__;
7127 if(nodeIndices.size())
7129 unsigned int hostnameCol =
7130 typeTable.tableView_->
findCol(ARTDAQ_TYPE_TABLE_HOSTNAME);
7135 std::vector<std::string> namePieces =
7137 nodePair.first.substr(0, nodePair.first.find(
";status=")),
7141 if(namePieces.size() < 2)
7144 <<
"Illegal multi-node name template - please use * to "
7145 "indicate where the multi-node index should be inserted!"
7150 std::vector<std::string> hostnamePieces;
7151 if(hostnameIndices.size())
7157 if(hostnamePieces.size() < 2)
7160 <<
"Illegal hostname array template - please use * to "
7161 "indicate where the hostname index should be inserted!"
7167 bool isFirst =
true;
7168 unsigned int lastArtRow = TableView::INVALID;
7169 for(
unsigned int i = 0; i < nodeIndices.size(); ++i)
7171 std::string name = namePieces[0];
7172 std::string nodeNameIndex;
7173 for(
unsigned int p = 1; p < namePieces.size(); ++p)
7175 nodeNameIndex = nodeIndices[i];
7176 if(nodeNameFixedWidth > 1)
7178 if(nodeNameIndex.size() > nodeNameFixedWidth)
7181 if(nodeNameIndex.find(
"_clone") == std::string::npos)
7183 __SS__ <<
"Illegal node name index '"
7185 <<
"' - length is longer than fixed width "
7187 << nodeNameFixedWidth <<
"!" << __E__;
7193 while(nodeNameIndex.size() < nodeNameFixedWidth)
7194 nodeNameIndex =
"0" + nodeNameIndex;
7197 name += nodeNameIndex + namePieces[p];
7201 if(hostnamePieces.size())
7203 hostname = hostnamePieces[0];
7204 std::string hostnameIndex;
7205 for(
unsigned int p = 1; p < hostnamePieces.size(); ++p)
7207 hostnameIndex = hostnameIndices[i];
7208 if(hostnameFixedWidth > 1)
7210 if(hostnameIndex.size() > hostnameFixedWidth)
7213 if(hostnameIndex.find(
"_clone") ==
7216 __SS__ <<
"Illegal hostname index '"
7218 <<
"' - length is longer than fixed "
7221 << hostnameFixedWidth <<
"!" << __E__;
7227 while(hostnameIndex.size() < hostnameFixedWidth)
7228 hostnameIndex =
"0" + hostnameIndex;
7231 hostname += hostnameIndex + hostnamePieces[p];
7233 __COUTV__(hostname);
7240 << author <<
"... Replacing row UID '"
7241 << typeTable.tableView_
7242 ->getDataView()[row]
7244 <<
"' with UID '" << name <<
"'" << __E__;
7247 if(row < maxRowToDelete)
7248 deleteRecordMap[row] =
false;
7253 << author <<
"... Copying row UID '"
7254 << typeTable.tableView_
7255 ->getDataView()[row]
7257 <<
"' to UID '" << name <<
"'" << __E__;
7258 unsigned int copyRow = typeTable.tableView_->
copyRows(
7260 *(typeTable.tableView_),
7267 if(row < maxRowToDelete)
7268 deleteRecordMap[copyRow] =
false;
7273 name, row, typeTable.tableView_->
getColUID());
7275 hostname, row, hostnameCol);
7278 TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT,
7282 typeTable.tableView_->
setValue(time(0), row, timestampCol);
7284 __COUTTV__(typeTable
7286 ->getDataView()[row][commentCol]);
7287 __COUTTV__(typeTable
7289 ->getDataView()[row][authorCol]);
7290 __COUTTV__(typeTable
7292 ->getDataView()[row][timestampCol]);
7302 <<
"Looking for best original node match for row=" << row
7303 <<
" UID='" << name <<
"'" << __E__;
7304 size_t bestScore = 0;
7305 std::string bestOriginalNodeName;
7306 for(
const auto& originalNodePair : originalMultinodeValues)
7308 if(originalNodePair.second.find(
7309 ORIG_MAP_ART_PROC_NAME_COL) !=
7310 originalNodePair.second.end())
7311 __COUTTV__(originalNodePair.second.at(
7312 ORIG_MAP_ART_PROC_NAME_COL));
7314 for(
size_t c = 0, d = 0;
7315 c < originalNodePair.first.size() && d < name.size();
7318 if(name[d] == originalNodePair.first[c])
7320 else if(d + 1 < name.size() &&
7321 name[d + 1] == originalNodePair.first[c])
7323 else if(c + 1 < originalNodePair.first.size() &&
7324 name[d] == originalNodePair.first[c + 1])
7327 if(originalNodePair.first.size() == name.size())
7329 __COUTVS__(2, score);
7330 if(score > bestScore)
7332 bestOriginalNodeName = originalNodePair.first;
7334 __COUTVS__(2, bestOriginalNodeName);
7335 __COUTVS__(2, bestScore);
7339 bool exactMatch = (bestOriginalNodeName == name);
7340 bool needToHandleArtProcessName =
false;
7341 std::string artProcessName;
7344 originalMultinodeValues.find(bestOriginalNodeName) !=
7345 originalMultinodeValues.end())
7347 __COUT__ <<
"Populating original multinode value from '"
7348 << bestOriginalNodeName <<
"' into '" << name
7351 for(
const auto& valuePair :
7352 originalMultinodeValues.at(bestOriginalNodeName))
7355 if(!exactMatch && (valuePair.first == commentCol ||
7356 valuePair.first == authorCol ||
7357 valuePair.first == timestampCol))
7360 <<
"Not exact node name match, so keeping "
7361 "default meta info for node: "
7362 << name <<
"[" << row <<
"]["
7364 <<
"] /= " << valuePair.second <<
" keep= "
7365 << typeTable.tableView_
7366 ->getDataView()[row][valuePair.first]
7371 __COUTT__ <<
"Customizing node: " << name <<
"["
7372 << row <<
"][" << valuePair.first
7373 <<
"] = " << valuePair.second << __E__;
7375 if(valuePair.first == ORIG_MAP_ART_PROC_NAME_COL)
7377 __COUTT__ <<
"NEED Special art Process Name "
7379 << valuePair.second << __E__;
7380 needToHandleArtProcessName =
true;
7381 artProcessName = valuePair.second;
7384 valuePair.second, row, artProcessNameCol);
7388 valuePair.second, row, valuePair.first);
7392 __COUT__ <<
"Did not find '" << name
7393 <<
"' in original value cache. Looking for "
7394 "bestOriginalNodeName="
7395 << bestOriginalNodeName << __E__;
7397 __COUTV__(exactMatch);
7400 if(originalMultinodeSameSiblingValues.find(
7402 originalMultinodeSameSiblingValues.end())
7404 __COUT__ <<
"Applying multinode sibling same value "
7406 << row <<
" UID='" << name <<
"'" << __E__;
7407 for(
const auto& sameValuePair :
7408 originalMultinodeSameSiblingValues.at(
7411 if(!sameValuePair.second.first)
7414 <<
"Found originalMultinodeSameSiblingValues["
7415 << nodePair.first <<
"]["
7416 << sameValuePair.first <<
"] = "
7417 << sameValuePair.second.first <<
" --> "
7418 << sameValuePair.second.second << __E__;
7421 if(sameValuePair.first ==
7422 ORIG_MAP_ART_PROC_NAME_COL)
7424 __COUTT__ <<
"NEED Special art Process Name "
7426 << sameValuePair.second.second
7428 needToHandleArtProcessName =
true;
7429 artProcessName = sameValuePair.second.second;
7432 sameValuePair.second.second,
7438 sameValuePair.second.second,
7440 sameValuePair.first);
7445 if(originalMultinodeAllSiblingEmbeddedPrinterIndex.find(
7447 originalMultinodeAllSiblingEmbeddedPrinterIndex.end())
7449 __COUT__ <<
"Applying multinode sibling embbeded "
7450 "printer syntax index rules for row="
7451 << row <<
" UID='" << name
7452 <<
"' and printer index='" << nodeNameIndex
7454 for(
const auto& embedValuePair :
7455 originalMultinodeAllSiblingEmbeddedPrinterIndex
7456 .at(nodePair.first))
7458 if(!embedValuePair.second.first ||
7459 embedValuePair.second.second.size() < 2)
7463 "originalMultinodeAllSiblingEmbeddedPrinte"
7465 << nodePair.first <<
"]["
7466 << embedValuePair.first <<
"] = "
7467 << embedValuePair.second.first <<
" --> "
7469 embedValuePair.second.second)
7471 std::string embedValue =
7473 embedValuePair.second.second,
7475 __COUTTV__(embedValue);
7478 if(embedValuePair.first ==
7479 ORIG_MAP_ART_PROC_NAME_COL)
7481 __COUTT__ <<
"NEED Special art Process Name "
7483 << embedValue << __E__;
7484 needToHandleArtProcessName =
true;
7485 artProcessName = embedValue;
7488 embedValue, row, artProcessNameCol);
7492 embedValue, row, embedValuePair.first);
7496 if(originalMultinodeAllSiblingEmbeddedName.find(
7498 originalMultinodeAllSiblingEmbeddedName.end())
7500 __COUT__ <<
"Applying multinode sibling embbeded "
7501 "name rules for row="
7502 << row <<
" UID='" << name <<
"'" << __E__;
7503 for(
const auto& embedValuePair :
7504 originalMultinodeAllSiblingEmbeddedName.at(
7507 if(!embedValuePair.second.first ||
7508 embedValuePair.second.second.size() < 2)
7512 "originalMultinodeAllSiblingEmbeddedName["
7513 << nodePair.first <<
"]["
7514 << embedValuePair.first <<
"] = "
7515 << embedValuePair.second.first <<
" --> "
7517 embedValuePair.second.second)
7519 std::string embedValue =
7521 embedValuePair.second.second, name);
7522 __COUTTV__(embedValue);
7525 if(embedValuePair.first ==
7526 ORIG_MAP_ART_PROC_NAME_COL)
7528 __COUTT__ <<
"NEED Special art Process Name "
7530 << embedValue << __E__;
7531 needToHandleArtProcessName =
true;
7532 artProcessName = embedValue;
7535 embedValue, row, artProcessNameCol);
7539 embedValue, row, embedValuePair.first);
7543 __COUTV__(needToHandleArtProcessName);
7544 if(needToHandleArtProcessName)
7546 __COUTT__ <<
"Special art Process Name column value: "
7547 << artProcessName << __E__;
7549 std::string artRecord =
7550 typeTable.tableView_->getDataView()
7551 [row][typeTable.tableView_->
findCol(
7552 ARTDAQTableBase::colARTDAQNotReader_
7553 .colLinkToArtUID_)];
7554 __COUTTV__(artRecord);
7556 const unsigned int artCommentCol =
7558 TableViewColumnInfo::TYPE_COMMENT);
7559 const unsigned int artAuthorCol =
7561 TableViewColumnInfo::TYPE_AUTHOR);
7562 const unsigned int artTimestampCol =
7564 TableViewColumnInfo::TYPE_TIMESTAMP);
7566 unsigned int artRow = artTable->tableView_->
findRow(
7572 if(artRow == TableView::INVALID)
7574 __COUTT__ <<
"Need to make art Process record... "
7576 << artRecord << __E__;
7580 __COUTTV__(bestOriginalNodeName);
7581 const unsigned int bestMatchRow =
7582 typeTable.tableView_->
findRow(
7584 bestOriginalNodeName);
7585 __COUTTV__(bestMatchRow);
7587 std::string bestMatchArtRecord =
7588 typeTable.tableView_->getDataView()
7590 [typeTable.tableView_->
findCol(
7593 .colLinkToArtUID_)];
7594 __COUTTV__(bestMatchArtRecord);
7596 unsigned int bestMatchArtRow =
7597 artTable->tableView_->
findRow(
7602 __COUTTV__(bestMatchArtRow);
7603 if(bestMatchArtRow !=
7608 __COUTTV__(lastArtRow);
7611 if(lastArtRow != TableView::INVALID)
7613 __COUTT__ <<
"Copying art Process record... "
7615 << lastArtRow << __E__;
7616 unsigned int copyRow =
7619 *(artTable->tableView_),
7633 DATATYPE_COMMENT_DEFAULT,
7637 author, artRow, artAuthorCol);
7639 time(0), artRow, artTimestampCol);
7643 __COUTT__ <<
"Creating art Process record... "
7645 << artRecord << __E__;
7647 artRow = artTable->tableView_->
addRow(
7653 <<
"Made art Process record... artRecord="
7654 << artRecord << __E__;
7657 __COUTT__ <<
"Modify art Process record based on "
7658 "sibling rules... artRecord="
7660 <<
" artProcessName=" << artProcessName
7664 artProcessName, artRow, artProcessNameCol);
7665 lastArtRow = artRow;
7669 needToHandleArtProcessName)
7671 std::string artRecord =
7672 typeTable.tableView_->getDataView()
7673 [row][typeTable.tableView_->
findCol(
7674 ARTDAQTableBase::colARTDAQNotReader_
7675 .colLinkToArtUID_)];
7676 __COUTTV__(artRecord);
7677 unsigned int artRow = artTable->tableView_->
findRow(
7685 lastArtRow = artRow;
7688 __COUTTV__(lastArtRow);
7693 if(row < maxRowToDelete)
7694 __COUTTV__(deleteRecordMap[row]);
7696 __COUTTV__(typeTable
7698 ->getDataView()[row][commentCol]);
7699 __COUTTV__(typeTable
7701 ->getDataView()[row][authorCol]);
7702 __COUTTV__(typeTable
7704 ->getDataView()[row][timestampCol]);
7714 __COUT__ <<
"Deleting '" << nodeTypePair.first
7715 <<
"' records not specified..." << __E__;
7718 std::set<unsigned int> orderedRowSet;
7719 for(
auto& deletePair : deleteRecordMap)
7721 if(!deletePair.second)
7723 __COUTT__ <<
"Row keep = " << deletePair.first << __E__;
7727 __COUTT__ <<
"Row delete = " << deletePair.first << __E__;
7728 orderedRowSet.emplace(deletePair.first);
7732 for(std::set<unsigned int>::reverse_iterator rit = orderedRowSet.rbegin();
7733 rit != orderedRowSet.rend();
7739 if(TTEST(1) && artTable)
7741 std::stringstream ss;
7742 artTable->tableView_->print(ss);
7743 __COUT_MULTI__(1, ss.str());
7746 if(hasArtProcessName && artTable)
7747 artTable->tableView_
7752 std::stringstream ss;
7753 typeTable.tableView_->print(ss);
7754 __COUT_MULTI__(1, ss.str());
7757 typeTable.tableView_->
init();
7764 std::stringstream ss;
7765 artdaqSupervisorTable.tableView_->print(ss);
7766 __COUT_MULTI__(1, ss.str());
7769 std::stringstream ss;
7770 artdaqSubsystemTable.tableView_->print(ss);
7771 __COUT_MULTI__(1, ss.str());
7775 artdaqSupervisorTable.tableView_
7777 artdaqSubsystemTable.tableView_
7782 __COUT__ <<
"Table errors while creating ARTDAQ nodes. Erasing all newly "
7783 "created table versions."
7788 __COUT__ <<
"Edits complete for artdaq nodes and subsystems.. now save and activate "
7789 "groups, and update aliases!"
7795 __SS__ <<
"DEBUG blocking save!" << __E__;
7799 std::string localAccumulatedWarnings;
7800 configGroupEdit.saveChanges(configGroupEdit.originalGroupName_,
7801 newConfigurationGroupKey,
7808 &localAccumulatedWarnings);
7824 void ARTDAQTableBase::addCommentWhitespace(std::ostream& os,
size_t lineLength)
7826 for(
size_t i = 0;
true; i += 20)
7828 if(lineLength < FCL_COMMENT_POSITION + i)
7830 os << std::string(FCL_COMMENT_POSITION + i - lineLength,
' ');
7838 std::string ARTDAQTableBase::getStructureAsJSON(
7841 if(fclMap_.size() == 0)
7843 std::stringstream oss;
7845 oss <<
"{" << __E__;
7847 if(fclMap_.size() > 1)
7850 bool firstType =
true;
7851 for(
const auto& typePairMap : fclMap_)
7855 oss <<
"\t\"" << getTypeString(typePairMap.first) <<
"\": {" << __E__;
7857 bool firstEntry =
true;
7858 for(
const auto& fclPair : typePairMap.second)
7862 oss <<
"\t\t\"" << fclPair.first <<
"\": \""
7868 oss <<
"\t}" << __E__;
7875 bool firstEntry =
true;
7876 for(
const auto& typePairMap : fclMap_)
7878 for(
const auto& fclPair : typePairMap.second)
7882 oss <<
"\t\"" << fclPair.first <<
"\": \""
7890 oss <<
"}" << __E__;
7899 size_t maxFragmentSizeBytes,
7900 size_t routingTimeoutMs,
7901 size_t routingRetryCount,
7906 __SS__ <<
"ARTDAQ Supervisor node is disconnected while generating boot.txt "
7907 <<
"content." << __E__;
7911 const ARTDAQInfo& info = extractARTDAQInfo(artdaqSupervisorNode,
7914 maxFragmentSizeBytes,
7920 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colDAQInterfaceDebugLevel_)
7922 std::string setupScript =
7923 artdaqSupervisorNode.
getNode(colARTDAQSupervisor_.colDAQSetupScript_).
getValue();
7932 const std::string& setupScript,
7935 std::stringstream o;
7937 o <<
"DAQ setup script: " << setupScript << std::endl;
7938 o <<
"debug level: " << debugLevel << std::endl;
7941 if(info.subsystems.size() > 1)
7943 for(
auto& ss : info.subsystems)
7947 o <<
"Subsystem id: " << ss.first << std::endl;
7948 if(ss.second.destination != 0)
7950 o <<
"Subsystem destination: " << ss.second.destination << std::endl;
7952 for(
auto& sss : ss.second.sources)
7954 o <<
"Subsystem source: " << sss << std::endl;
7956 if(ss.second.eventMode)
7958 o <<
"Subsystem fragmentMode: False" << std::endl;
7964 for(
auto& builder : info.processes.at(ARTDAQAppType::EventBuilder))
7966 o <<
"EventBuilder host: " << builder.hostname << std::endl;
7967 o <<
"EventBuilder label: " << builder.label << std::endl;
7968 if(builder.subsystem != 1)
7970 o <<
"EventBuilder subsystem: " << builder.subsystem << std::endl;
7972 if(builder.allowed_processors !=
"")
7974 o <<
"EventBuilder allowed_processors: " << builder.allowed_processors
7980 for(
auto& logger : info.processes.at(ARTDAQAppType::DataLogger))
7982 o <<
"DataLogger host: " << logger.hostname << std::endl;
7983 o <<
"DataLogger label: " << logger.label << std::endl;
7984 if(logger.subsystem != 1)
7986 o <<
"DataLogger subsystem: " << logger.subsystem << std::endl;
7988 if(logger.allowed_processors !=
"")
7990 o <<
"DataLogger allowed_processors: " << logger.allowed_processors
7996 for(
auto& dispatcher : info.processes.at(ARTDAQAppType::Dispatcher))
7998 o <<
"Dispatcher host: " << dispatcher.hostname << std::endl;
7999 o <<
"Dispatcher label: " << dispatcher.label << std::endl;
8000 if(dispatcher.port != 0)
8002 o <<
"Dispatcher port: " << dispatcher.port << std::endl;
8004 if(dispatcher.subsystem != 1)
8006 o <<
"Dispatcher subsystem: " << dispatcher.subsystem << std::endl;
8008 if(dispatcher.allowed_processors !=
"")
8010 o <<
"Dispatcher allowed_processors: " << dispatcher.allowed_processors
8016 for(
auto& rm : info.processes.at(ARTDAQAppType::RoutingManager))
8018 o <<
"RoutingManager host: " << rm.hostname << std::endl;
8019 o <<
"RoutingManager label: " << rm.label << std::endl;
8020 if(rm.subsystem != 1)
8022 o <<
"RoutingManager subsystem: " << rm.subsystem << std::endl;
8024 if(rm.allowed_processors !=
"")
8026 o <<
"RoutingManager allowed_processors: " << rm.allowed_processors
<virtual so future plugins can inherit from multiple table base classes
static void outputDataReceiverFHICL(const ConfigurationTree &receiverNode, ARTDAQAppType appType, size_t maxFragmentSizeBytes=DEFAULT_MAX_FRAGMENT_SIZE, size_t routingTimeoutMs=DEFAULT_ROUTING_TIMEOUT_MS, size_t routingRetryCount=DEFAULT_ROUTING_RETRY_COUNT, std::string *returnFcl=nullptr)
static void insertArtProcessBlock(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree art, ConfigurationTree subsystemLink=ConfigurationTree(), size_t routingTimeoutMs=DEFAULT_ROUTING_TIMEOUT_MS, size_t routingRetryCount=DEFAULT_ROUTING_RETRY_COUNT)
static const std::string ARTDAQ_FCL_PATH
Tree-path rule is, if the last link in the path is a group link with a specified group ID,...
static std::string insertModuleType(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree moduleTypeNode)
static std::string getBootFileContentFromInfo(const ARTDAQInfo &info, const std::string &setupScript, int debugLevel)
static bool isARTDAQEnabled(const ConfigurationManager *cfgMgr)
isARTDAQEnabled
static void insertParameters(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree parameterLink, const std::string ¶meterPreamble, bool onlyInsertAtTableParameters=false, bool includeAtTableParameters=false)
static void setAndActivateARTDAQSystem(ConfigurationManagerRW *cfgMgr, const std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, const std::map< std::string, std::string > &subsystemObjectMap)
static struct ots::ARTDAQTableBase::ProcessTypes processTypes_
Note!!!! processTypes_ must be instantiate after the static artdaq table names (to construct map in c...
static void outputOnlineMonitorFHICL(const ConfigurationTree &onlineMonitorNode)
std::string getBootFileContent(ConfigurationTree artdaqSupervisorNode, size_t maxFragmentSizeBytes=DEFAULT_MAX_FRAGMENT_SIZE, size_t routingTimeoutMs=DEFAULT_ROUTING_TIMEOUT_MS, size_t routingRetryCount=DEFAULT_ROUTING_RETRY_COUNT, ProgressBar *progressBar=0)
static void insertMetricsBlock(std::ostream &out, std::string &tabStr, std::string &commentStr, const std::string &parentPath, ConfigurationTree daqNode)
insertMetricsBlock
static const ARTDAQInfo & getARTDAQSystem(ConfigurationManagerRW *cfgMgr, std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, std::map< std::string, std::string > &subsystemObjectMap, std::vector< std::string > &artdaqSupervisoInfo, bool suppressMultiNode=false)
when true, skip multi-node "printer syntax" wildcard compression and emit one concrete record per nod...
const std::string & getUsername(void) const
Getters.
bool isOwnerFirstAppInContext(void)
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
const TableBase * getTableByName(const std::string &configurationName) const
void initPrereqsForARTDAQ(void)
loadGroupHistory
const unsigned int & getRow(void) const
getRow
bool isDisconnected(void) const
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
navigating between nodes
const std::string & getTableName(void) const
getTableName
T getValueWithDefault(const T &defaultValue) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
const ConfigurationManager * getConfigurationManager(void) const
extracting information from node
void getValue(T &value) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
std::string getParentLinkIndex(void) const
getParentLinkIndex
const std::string & getUIDAsString(void) const
const unsigned int & getNodeRow(void) const
getNodeRow
const std::string & getFieldName(void) const
alias for getValueName
std::string getParentLinkID(void) const
getParentLinkID
const std::string & getParentTableName(void) const
getParentTableName
const std::string & getParentRecordName(void) const
getParentRecordName
const std::string & getParentLinkColumnName(void) const
getParentLinkColumnName
bool isFirstAppInContext_
for managing things that should only happen once per node (e.g., write files). If used,...
std::string str() const
alternative alias method
bool isUID(void) const
isUID
bool isGroupID(void) const
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
< in included .icc source
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
unsigned int getColStatus(void) const
unsigned int findColByType(const std::string &type, unsigned int startingCol=0) const
unsigned int copyRows(const std::string &author, const TableView &src, unsigned int srcOffsetRow=0, unsigned int srcRowsToCopy=(unsigned int) -1, unsigned int destOffsetRow=(unsigned int) -1, unsigned char generateUniqueDataColumns=false, const std::string &baseNameAutoUID="")
const std::string & setUniqueColumnValue(unsigned int row, unsigned int col, std::string baseValueAsString="", bool doMathAppendStrategy=false, std::string childLinkIndex="", std::string groupId="")
unsigned int getColUID(void) const
unsigned int findCol(const std::string &name) const
void setValue(const T &value, unsigned int row, unsigned int col)
< in included .icc source
unsigned int addRow(const std::string &author="", unsigned char incrementUniqueData=false, const std::string &baseNameAutoUID="", unsigned int rowToAdd=(unsigned int) -1, std::string childLinkIndex="", std::string groupId="")
const XDAQContext * getTheARTDAQSupervisorContext(void) const
artdaq specific get methods
defines used also by OtsConfigurationWizardSupervisor
ARTDAQ DAQ Parameter Column names.
ARTDAQ Builder/Logger/Dispatcher Column names.
ARTDAQ Reader Column names.
ARTDAQ Subsystem Column names.
ARTDAQ Supervisor Column names.
TableEditStruct & getTableEditStruct(const std::string &tableName, bool markModified=false)
Note: if markModified, and table not found in group, this function will try to add it to group.
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static const std::string & trim(std::string &s)
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
vectorToString ~
static std::string escapeJSONStringEntities(const std::string &str)
static bool extractCommonChunks(const std::vector< std::string > &haystack, std::vector< std::string > &commonChunksToReturn, std::vector< std::string > &wildcardStrings, unsigned int &fixedWildcardLength)
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static std::string decodeURIComponent(const std::string &data)
static std::string stackTrace(void)