otsdaq  v2_04_01
ARTDAQBuilderTable_table.cc
1 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
2 #include "otsdaq-core/Macros/TablePluginMacros.h"
3 #include "otsdaq-core/TablePlugins/ARTDAQBuilderTable.h"
4 #include "otsdaq-core/TablePlugins/XDAQContextTable.h"
5 
6 #include <stdio.h>
7 #include <sys/stat.h> //for mkdir
8 #include <fstream> // std::fstream
9 #include <iostream>
10 
11 using namespace ots;
12 
13 #define ARTDAQ_FCL_PATH std::string(__ENV__("USER_DATA")) + "/" + "ARTDAQConfigurations/"
14 #define ARTDAQ_FILE_PREAMBLE "builder"
15 
16 // helpers
17 #define OUT out << tabStr << commentStr
18 #define PUSHTAB tabStr += "\t"
19 #define POPTAB tabStr.resize(tabStr.size() - 1)
20 #define PUSHCOMMENT commentStr += "# "
21 #define POPCOMMENT commentStr.resize(commentStr.size() - 2)
22 
23 //========================================================================================================================
24 ARTDAQBuilderTable::ARTDAQBuilderTable(void) : TableBase("ARTDAQBuilderTable")
25 {
27  // WARNING: the names used in C++ MUST match the Table INFO //
29 }
30 
31 //========================================================================================================================
32 ARTDAQBuilderTable::~ARTDAQBuilderTable(void) {}
33 
34 //========================================================================================================================
35 void ARTDAQBuilderTable::init(ConfigurationManager* configManager)
36 {
37  // use isFirstAppInContext to only run once per context, for example to avoid
38  // generating files on local disk multiple times.
39  bool isFirstAppInContext = configManager->isOwnerFirstAppInContext();
40 
41  //__COUTV__(isFirstAppInContext);
42  if(!isFirstAppInContext)
43  return;
44 
45  // make directory just in case
46  mkdir((ARTDAQ_FCL_PATH).c_str(), 0755);
47 
48  __COUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << __E__;
49  __COUT__ << configManager->__SELF_NODE__ << __E__;
50 
51  const XDAQContextTable* contextConfig =
52  configManager->__GET_CONFIG__(XDAQContextTable);
53 
54  std::vector<const XDAQContextTable::XDAQContext*> builderContexts =
55  contextConfig->getEventBuilderContexts();
56 
57  // for each aggregator context
58  // output associated fcl config file
59  for(auto& builderContext : builderContexts)
60  {
61  ConfigurationTree builderAppNode = contextConfig->getApplicationNode(
62  configManager,
63  builderContext->contextUID_,
64  builderContext->applications_[0].applicationUID_);
65  ConfigurationTree builderConfigNode = contextConfig->getSupervisorConfigNode(
66  configManager,
67  builderContext->contextUID_,
68  builderContext->applications_[0].applicationUID_);
69 
70  __COUT__ << "Path for this aggregator config is " << builderContext->contextUID_
71  << "/" << builderContext->applications_[0].applicationUID_ << "/"
72  << builderConfigNode.getValueAsString() << __E__;
73 
74  outputFHICL(
75  configManager,
76  builderConfigNode,
77  contextConfig->getARTDAQAppRank(builderContext->contextUID_),
78  contextConfig->getContextAddress(builderContext->contextUID_),
79  contextConfig->getARTDAQDataPort(configManager, builderContext->contextUID_),
80  contextConfig);
81  }
82 }
83 
84 //========================================================================================================================
85 std::string ARTDAQBuilderTable::getFHICLFilename(const ConfigurationTree& builderNode)
86 {
87  __COUT__ << "ARTDAQ Builder UID: " << builderNode.getValue() << __E__;
88  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
89  std::string uid = builderNode.getValue();
90  for(unsigned int i = 0; i < uid.size(); ++i)
91  if((uid[i] >= 'a' && uid[i] <= 'z') || (uid[i] >= 'A' && uid[i] <= 'Z') ||
92  (uid[i] >= '0' && uid[i] <= '9')) // only allow alpha numeric in file name
93  filename += uid[i];
94 
95  filename += ".fcl";
96 
97  __COUT__ << "fcl: " << filename << __E__;
98 
99  return filename;
100 } // end getFHICLFilename()
101 
102 //========================================================================================================================
103 void ARTDAQBuilderTable::outputFHICL(ConfigurationManager* configManager,
104  const ConfigurationTree& builderNode,
105  unsigned int selfRank,
106  std::string selfHost,
107  unsigned int selfPort,
108  const XDAQContextTable* contextConfig)
109 {
110  /*
111  the file will look something like this:
112 
113  services: {
114  scheduler: {
115  fileMode: NOMERGE
116  errorOnFailureToPut: false
117  }
118  NetMonTransportServiceInterface: {
119  service_provider: NetMonTransportService
120  #broadcast_sends: true
121  destinations: {
122  d4: { transferPluginType: MPI destination_rank: 4 max_fragment_size_bytes:
123  2097152}
124 
125  }
126  }
127 
128  #SimpleMemoryCheck: { }
129  }
130 
131  daq: {
132  event_builder: {
133  expected_fragments_per_event: 2
134  use_art: true
135  print_event_store_stats: true
136  verbose: false
137  send_requests: true
138  request_port:
139  request_address:
140 
141  sources: {
142  s0: { transferPluginType: MPI source_rank: 0 max_fragment_size_bytes:
143  2097152} s1: { transferPluginType: MPI source_rank: 1 max_fragment_size_bytes:
144  2097152}
145 
146  }
147  }
148  metrics: {
149  evbFile: {
150  metricPluginType: "file"
151  level: 3
152  fileName: "/tmp/eventbuilder/evb_%UID%_metrics.log"
153  uniquify: true
154  }
155  # ganglia: {
156  # metricPluginType: "ganglia"
157  # level: %{ganglia_level}
158  # reporting_interval: 15.0
159  #
160  # configFile: "/etc/ganglia/gmond.conf"
161  # group: "ARTDAQ"
162  # }
163  # msgfac: {
164  # level: %{mf_level}
165  # metricPluginType: "msgFacility"
166  # output_message_application_name: "ARTDAQ Metric"
167  # output_message_severity: 0
168  # }
169  # graphite: {
170  # level: %{graphite_level}
171  # metricPluginType: "graphite"
172  # host: "localhost"
173  # port: 20030
174  # namespace: "artdaq."
175  # }
176  }
177  }
178 
179  outputs: {
180  rootMPIOutput: {
181  module_type: RootMPIOutput
182  #SelectEvents: { SelectEvents: [ pmod2,pmod3 ] }
183  }
184  #normalOutput: {
185  # module_type: RootOutput
186  # fileName: "/tmp/artdaqdemo_eb00_r%06r_sr%02s_%to.root"
187  # #SelectEvents: { SelectEvents: [ pmod2,pmod3 ] }
188  #}
189  }
190 
191  physics: {
192  analyzers: {
193 
194  }
195 
196  producers: {
197  }
198 
199  filters: {
200 
201  prescaleMod2: {
202  module_type: NthEvent
203  nth: 2
204  }
205 
206  prescaleMod3: {
207  module_type: NthEvent
208  nth: 3
209  }
210  }
211 
212  pmod2: [ prescaleMod2 ]
213  pmod3: [ prescaleMod3 ]
214 
215 
216  #a1: [ app, wf ]
217 
218  my_output_modules: [ rootMPIOutput ]
219  #my_output_modules: [ normalOutput ]
220  }
221  source: {
222  module_type: DemoInput
223  waiting_time: 2500000
224  resume_after_timeout: true
225  }
226  process_name: DAQ
227 
228  */
229 
230  std::string filename = getFHICLFilename(builderNode);
231 
233  // generate xdaq run parameter file
234  std::fstream out;
235 
236  std::string tabStr = "";
237  std::string commentStr = "";
238 
239  out.open(filename, std::fstream::out | std::fstream::trunc);
240  if(out.fail())
241  {
242  __SS__ << "Failed to open ARTDAQ Builder fcl file: " << filename << __E__;
243  __SS_THROW__;
244  }
245 
246  //--------------------------------------
247  // header
248  OUT << "###########################################################" << __E__;
249  OUT << "#" << __E__;
250  OUT << "# artdaq builder fcl configuration file produced by otsdaq." << __E__;
251  OUT << "# Creation timestamp: " << StringMacros::getTimestampString() << __E__;
252  OUT << "# Original filename: " << filename << __E__;
253  OUT << "# otsdaq-ARTDAQ Builder UID: " << builderNode.getValue() << __E__;
254  OUT << "#" << __E__;
255  OUT << "###########################################################" << __E__;
256  OUT << "\n\n";
257 
258  // no primary link to table tree for reader node!
259  if(builderNode.isDisconnected())
260  {
261  // create empty fcl
262  OUT << "{}\n\n";
263  out.close();
264  return;
265  }
266 
267  //--------------------------------------
268  // handle services
269  auto services = builderNode.getNode("servicesLink");
270  if(!services.isDisconnected())
271  {
272  OUT << "services: {\n";
273 
274  // scheduler
275  PUSHTAB;
276  OUT << "scheduler: {\n";
277 
278  PUSHTAB;
279  OUT << "fileMode: " << services.getNode("schedulerFileMode").getValue() << "\n";
280  OUT << "errorOnFailureToPut: "
281  << (services.getNode("schedulerErrorOnFailtureToPut").getValue<bool>()
282  ? "true"
283  : "false")
284  << "\n";
285  POPTAB;
286 
287  OUT << "}\n\n";
288 
289  // NetMonTransportServiceInterface
290  OUT << "NetMonTransportServiceInterface: {\n";
291 
292  PUSHTAB;
293  OUT << "service_provider: " <<
294  // services.getNode("NetMonTrasportServiceInterfaceServiceProvider").getEscapedValue()
295  services.getNode("NetMonTrasportServiceInterfaceServiceProvider").getValue()
296  << "\n";
297  OUT << "destinations: {\n";
298 
299  PUSHTAB;
300  auto destinationsGroup =
301  services.getNode("NetMonTrasportServiceInterfaceDestinationsLink");
302  if(!destinationsGroup.isDisconnected())
303  {
304  try
305  {
306  auto destinations = destinationsGroup.getChildren();
307  for(auto& destination : destinations)
308  {
309  auto destinationContextUID =
310  destination.second.getNode("destinationARTDAQContextLink")
311  .getValueAsString();
312 
313  unsigned int destinationRank = -1;
314  try
315  {
316  destinationRank =
317  contextConfig->getARTDAQAppRank(destinationContextUID);
318  }
319  catch(const std::runtime_error& e)
320  {
321  __MCOUT_WARN__(
322  "Are the Transport Service destinations valid? "
323  << "Perhaps a Context has been turned off? "
324  << "Skipping destination due to an error looking for Event "
325  << "Builder DAQ source context '" << destinationContextUID
326  << "' for UID '" << builderNode.getValue()
327  << "': " << e.what() << __E__);
328  continue;
329  }
330 
331  std::string host =
332  contextConfig->getContextAddress(destinationContextUID);
333  unsigned int port = contextConfig->getARTDAQDataPort(
334  configManager, destinationContextUID);
335 
336  // open destination object
337  OUT << destination.second.getNode("destinationKey").getValue()
338  << ": {\n";
339  PUSHTAB;
340 
341  OUT << "transferPluginType: "
342  << destination.second.getNode("transferPluginType").getValue()
343  << __E__;
344 
345  OUT << "destination_rank: " << destinationRank << __E__;
346 
347  try
348  {
349  auto mfsb =
350  destination.second
351  .getNode("ARTDAQGlobalTableLink/maxFragmentSizeBytes")
352  .getValue<unsigned long long>();
353  OUT << "max_fragment_size_bytes: " << mfsb << __E__;
354  OUT << "max_fragment_size_words: " << (mfsb / 8) << __E__;
355  }
356  catch(...)
357  {
358  __SS__ << "The field ARTDAQGlobalTableLink/maxFragmentSizeBytes "
359  "could not be accessed. Make sure the link is valid."
360  << __E__;
361  __SS_THROW__;
362  }
363 
364  OUT << "host_map: [\n";
365  PUSHTAB;
366  OUT << "{\n";
367  PUSHTAB;
368  OUT << "rank: " << destinationRank << __E__;
369  OUT << "host: \"" << host << "\"" << __E__;
370  OUT << "portOffset: " << std::to_string(port) << __E__;
371  POPTAB;
372  OUT << "},\n";
373  OUT << "{\n";
374  PUSHTAB;
375  OUT << "rank: " << selfRank << __E__;
376  OUT << "host: \"" << selfHost << "\"" << __E__;
377  OUT << "portOffset: " << std::to_string(selfPort) << __E__;
378  POPTAB;
379  OUT << "}" << __E__;
380  POPTAB;
381  OUT << "]" << __E__; // close host_map
382 
383  POPTAB;
384  OUT << "}" << __E__; // close destination object
385  }
386  }
387  catch(const std::runtime_error& e)
388  {
389  __SS__ << "Are the Net Monitor Transport Service destinations valid? "
390  "Error occurred looking for Event Builder transport service "
391  "destinations for UID '"
392  << builderNode.getValue() << "': " << e.what() << __E__;
393  __SS_THROW__;
394  }
395  }
396  POPTAB;
397  OUT << "}\n\n"; // end destinations
398 
399  POPTAB;
400  OUT << "}\n\n"; // end NetMonTransportServiceInterface
401 
402  auto otherParameterLink = services.getNode("ServicesParametersLink");
403  if(!otherParameterLink.isDisconnected())
404  {
406  auto servicesParameters = otherParameterLink.getChildren();
407 
408  //__COUTV__(servicesParameters.size());
409  for(auto& parameter : servicesParameters)
410  {
411  if(!parameter.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
412  .getValue<bool>())
413  PUSHCOMMENT;
414 
415  OUT << parameter.second.getNode("daqParameterKey").getValue() << ": "
416  << parameter.second.getNode("daqParameterValue").getValue() << "\n";
417 
418  if(!parameter.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
419  .getValue<bool>())
420  POPCOMMENT;
421  }
422  }
423  // else
424  // __COUT__ << "No services parameters found" << __E__;
425 
426  POPTAB;
427  OUT << "}\n\n"; // end services
428  }
429 
430  //--------------------------------------
431  // handle daq
432  auto daq = builderNode.getNode("daqLink");
433  if(!daq.isDisconnected())
434  {
436  OUT << "daq: {\n";
437 
438  // event_builder
439  PUSHTAB;
440  OUT << "event_builder: {\n";
441 
442  PUSHTAB;
443 
444  auto mfsb = daq.getNode("daqEventBuilderMaxFragmentSizeBytes")
445  .getValue<unsigned long long>();
446  OUT << "max_fragment_size_bytes: " << mfsb << __E__;
447  OUT << "max_fragment_size_words: " << (mfsb / 8) << __E__;
448  OUT << "buffer_count: "
449  << daq.getNode("daqEventBuilderBufferCount").getValue<unsigned long long>()
450  << __E__;
451 
452  auto parametersLink = daq.getNode("daqEventBuilderParametersLink");
453  if(!parametersLink.isDisconnected())
454  {
455  auto parameters = parametersLink.getChildren();
456  for(auto& parameter : parameters)
457  {
458  if(!parameter.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
459  .getValue<bool>())
460  PUSHCOMMENT;
461 
462  OUT << parameter.second.getNode("daqParameterKey").getValue() << ": "
463  << parameter.second.getNode("daqParameterValue").getValue() << "\n";
464 
465  if(!parameter.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
466  .getValue<bool>())
467  POPCOMMENT;
468  }
469  }
470  OUT << "\n"; // end daq event builder parameters
471 
472  OUT << "sources: {\n";
473 
474  PUSHTAB;
475  auto sourcesGroup = daq.getNode("daqEventBuilderSourcesLink");
476  if(!sourcesGroup.isDisconnected())
477  {
478  try
479  {
480  auto sources = sourcesGroup.getChildren();
481  for(auto& source : sources)
482  {
483  auto sourceContextUID =
484  source.second.getNode("sourceARTDAQContextLink")
485  .getValueAsString();
486 
487  unsigned int sourceRank = -1;
488  try
489  {
490  sourceRank = contextConfig->getARTDAQAppRank(sourceContextUID);
491  }
492  catch(const std::runtime_error& e)
493  {
494  __MCOUT_WARN__(
495  "Are the DAQ sources valid? "
496  << "Perhaps a Context has been turned off? "
497  << "Skipping source due to an error looking for Event "
498  << "Builder DAQ source context '" << sourceContextUID
499  << "' for UID '" << builderNode.getValue()
500  << "': " << e.what() << __E__);
501  continue;
502  }
503 
504  std::string host = contextConfig->getContextAddress(sourceContextUID);
505  unsigned int port =
506  contextConfig->getARTDAQDataPort(configManager, sourceContextUID);
507 
508  // open source object
509  OUT << source.second.getNode("sourceKey").getValue() << ": {\n";
510  PUSHTAB;
511 
512  OUT << "transferPluginType: "
513  << source.second.getNode("transferPluginType").getValue()
514  << __E__;
515 
516  OUT << "source_rank: " << sourceRank << __E__;
517 
518  try
519  {
520  auto mfsb =
521  source.second
522  .getNode("ARTDAQGlobalTableLink/maxFragmentSizeBytes")
523  .getValue<unsigned long long>();
524  OUT << "max_fragment_size_bytes: " << mfsb << __E__;
525  OUT << "max_fragment_size_words: " << (mfsb / 8) << __E__;
526  }
527  catch(...)
528  {
529  __SS__ << "The field ARTDAQGlobalTableLink/maxFragmentSizeBytes "
530  "could not be accessed. Make sure the link is valid."
531  << __E__;
532  __SS_THROW__;
533  }
534 
535  OUT << "host_map: [\n";
536  PUSHTAB;
537  OUT << "{\n";
538  PUSHTAB;
539  OUT << "rank: " << sourceRank << __E__;
540  OUT << "host: \"" << host << "\"" << __E__;
541  OUT << "portOffset: " << std::to_string(port) << __E__;
542  POPTAB;
543  OUT << "},\n";
544  OUT << "{\n";
545  PUSHTAB;
546  OUT << "rank: " << selfRank << __E__;
547  OUT << "host: \"" << selfHost << "\"" << __E__;
548  OUT << "portOffset: " << std::to_string(selfPort) << __E__;
549  POPTAB;
550  OUT << "}" << __E__;
551  POPTAB;
552  OUT << "]" << __E__; // close host_map
553 
554  POPTAB;
555  OUT << "}" << __E__; // close source object
556  }
557  }
558  catch(const std::runtime_error& e)
559  {
560  __SS__ << "Are the DAQ sources valid? Error occurred looking for Event "
561  "Builder DAQ sources for UID '"
562  << builderNode.getValue() << "': " << e.what() << __E__;
563  __SS_THROW__;
564  }
565  }
566  POPTAB;
567  OUT << "}\n\n"; // end sources
568 
569  POPTAB;
570  OUT << "}\n\n"; // end event builder
571 
572  OUT << "metrics: {\n";
573 
574  PUSHTAB;
575  auto metricsGroup = daq.getNode("daqMetricsLink");
576  if(!metricsGroup.isDisconnected())
577  {
578  auto metrics = metricsGroup.getChildren();
579 
580  for(auto& metric : metrics)
581  {
582  if(!metric.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
583  .getValue<bool>())
584  PUSHCOMMENT;
585 
586  OUT << metric.second.getNode("metricKey").getValue() << ": {\n";
587  PUSHTAB;
588 
589  OUT << "metricPluginType: "
590  << metric.second.getNode("metricPluginType").getValue() << "\n";
591  OUT << "level: " << metric.second.getNode("metricLevel").getValue()
592  << "\n";
593 
594  auto metricParametersGroup =
595  metric.second.getNode("metricParametersLink");
596  if(!metricParametersGroup.isDisconnected())
597  {
598  auto metricParameters = metricParametersGroup.getChildren();
599  for(auto& metricParameter : metricParameters)
600  {
601  if(!metricParameter.second
602  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
603  .getValue<bool>())
604  PUSHCOMMENT;
605 
606  OUT << metricParameter.second.getNode("metricParameterKey")
607  .getValue()
608  << ": "
609  << metricParameter.second.getNode("metricParameterValue")
610  .getValue()
611  << "\n";
612 
613  if(!metricParameter.second
614  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
615  .getValue<bool>())
616  POPCOMMENT;
617  }
618  }
619  POPTAB;
620  OUT << "}\n\n"; // end metric
621 
622  if(!metric.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
623  .getValue<bool>())
624  POPCOMMENT;
625  }
626  }
627  POPTAB;
628  OUT << "}\n\n"; // end metrics
629 
630  POPTAB;
631  OUT << "}\n\n"; // end daq
632  }
633 
634  //--------------------------------------
635  // handle outputs
636  auto outputs = builderNode.getNode("outputsLink");
637  if(!outputs.isDisconnected())
638  {
639  OUT << "outputs: {\n";
640 
641  PUSHTAB;
642 
643  auto outputPlugins = outputs.getChildren();
644  for(auto& outputPlugin : outputPlugins)
645  {
646  if(!outputPlugin.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
647  .getValue<bool>())
648  PUSHCOMMENT;
649 
650  std::string moduleType =
651  outputPlugin.second.getNode("outputModuleType").getValue();
652 
653  OUT << outputPlugin.second.getNode("outputKey").getValue() << ": {\n";
654  PUSHTAB;
655 
656  OUT << "module_type: " << moduleType << "\n";
657 
658  auto pluginParameterLink =
659  outputPlugin.second.getNode("outputModuleParameterLink");
660  if(!pluginParameterLink.isDisconnected())
661  {
662  auto pluginParameters = pluginParameterLink.getChildren();
663  for(auto& pluginParameter : pluginParameters)
664  {
665  if(!pluginParameter.second
666  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
667  .getValue<bool>())
668  PUSHCOMMENT;
669 
670  OUT << pluginParameter.second.getNode("outputParameterKey").getValue()
671  << ": "
672  << pluginParameter.second.getNode("outputParameterValue")
673  .getValue()
674  << "\n";
675 
676  if(!pluginParameter.second
677  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
678  .getValue<bool>())
679  POPCOMMENT;
680  }
681  }
682 
683  // ONLY For output module type 'BinaryNetOuput,' allow destinations
684  auto destinationsGroup =
685  outputPlugin.second.getNode("outputModuleDestinationLink");
686  if(!destinationsGroup.isDisconnected())
687  {
688  try
689  {
690  if(moduleType.find("BinaryNetOuput") == std::string::npos)
691  {
692  __SS__ << "Illegal output module type '" << moduleType
693  << "' to include destinations. Only modules of type "
694  "'BinaryNetOuput' "
695  << "are allowed to have destinations." << __E__;
696  __SS_THROW__;
697  }
698 
699  OUT << "destinations: {\n";
700  PUSHTAB;
701 
702  auto destinations = destinationsGroup.getChildren();
703  for(auto& destination : destinations)
704  try
705  {
706  auto destinationContextUID =
707  destination.second.getNode("destinationARTDAQContextLink")
708  .getValueAsString();
709 
710  unsigned int destinationRank = -1;
711  try
712  {
713  destinationRank = contextConfig->getARTDAQAppRank(
714  destinationContextUID);
715  }
716  catch(const std::runtime_error& e)
717  {
718  __MCOUT_WARN__(
719  "Are the DAQ destinations valid? "
720  << "Perhaps a Context has been turned off? "
721  << "Skipping destination due to an error looking for "
722  "Event "
723  << "Builder DAQ source context '"
724  << destinationContextUID << "' for UID '"
725  << builderNode.getValue() << "': " << e.what()
726  << __E__);
727  continue;
728  }
729 
730  std::string host =
731  contextConfig->getContextAddress(destinationContextUID);
732  unsigned int port = contextConfig->getARTDAQDataPort(
733  configManager, destinationContextUID);
734 
735  // open destination object
736  OUT << destination.second.getNode("destinationKey").getValue()
737  << ": {\n";
738  PUSHTAB;
739 
740  OUT << "transferPluginType: "
741  << destination.second.getNode("transferPluginType")
742  .getValue()
743  << __E__;
744 
745  OUT << "destination_rank: " << destinationRank << __E__;
746 
747  try
748  {
749  auto mfsb =
750  destination.second
751  .getNode(
752  "ARTDAQGlobalTableLink/maxFragmentSizeBytes")
753  .getValue<unsigned long long>();
754  OUT << "max_fragment_size_bytes: " << mfsb << __E__;
755  OUT << "max_fragment_size_words: " << (mfsb / 8) << __E__;
756  }
757  catch(...)
758  {
759  __SS__
760  << "The field "
761  "ARTDAQGlobalTableLink/maxFragmentSizeBytes could "
762  "not be accessed. Make sure the link is valid."
763  << __E__;
764  __SS_THROW__;
765  }
766 
767  OUT << "host_map: [\n";
768  PUSHTAB;
769  OUT << "{\n";
770  PUSHTAB;
771  OUT << "rank: " << destinationRank << __E__;
772  OUT << "host: \"" << host << "\"" << __E__;
773  OUT << "portOffset: " << std::to_string(port) << __E__;
774  POPTAB;
775  OUT << "},\n";
776  OUT << "{\n";
777  PUSHTAB;
778  OUT << "rank: " << selfRank << __E__;
779  OUT << "host: \"" << selfHost << "\"" << __E__;
780  OUT << "portOffset: " << std::to_string(selfPort) << __E__;
781  POPTAB;
782  OUT << "}" << __E__;
783  POPTAB;
784  OUT << "]" << __E__; // close host_map
785 
786  POPTAB;
787  OUT << "}" << __E__; // close destination object
788  }
789  catch(const std::runtime_error& e)
790  {
791  __SS__ << "Error encountered populating parameters for "
792  "output module destination '"
793  << destination.first
794  << "'... Please verify fields. Here was the error: "
795  << e.what() << __E__;
796  __SS_ONLY_THROW__;
797  }
798 
799  POPTAB;
800  OUT << "}\n\n"; // end destinations
801  }
802  catch(const std::runtime_error& e)
803  {
804  __SS__ << "Are the Output module destinations valid? "
805  "Error occurred looking for Event Builder output module "
806  "destinations for UID '"
807  << outputPlugin.second.getValue() << "': " << e.what()
808  << __E__;
809  __SS_THROW__;
810  }
811  }
812 
813  POPTAB;
814  OUT << "}\n\n"; // end output module
815 
816  if(!outputPlugin.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
817  .getValue<bool>())
818  POPCOMMENT;
819  }
820 
821  POPTAB;
822  OUT << "}\n\n"; // end outputs
823  }
824 
825  //--------------------------------------
826  // handle physics
827  auto physics = builderNode.getNode("physicsLink");
828  if(!physics.isDisconnected())
829  {
831  OUT << "physics: {\n";
832 
833  PUSHTAB;
834 
835  auto analyzers = physics.getNode("analyzersLink");
836  if(!analyzers.isDisconnected())
837  {
839  OUT << "analyzers: {\n";
840 
841  PUSHTAB;
842  auto modules = analyzers.getChildren();
843  for(auto& module : modules)
844  {
845  if(!module.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
846  .getValue<bool>())
847  PUSHCOMMENT;
848 
849  OUT << module.second.getNode("analyzerKey").getValue() << ": {\n";
850  PUSHTAB;
851  OUT << "module_type: "
852  << module.second.getNode("analyzerModuleType").getValue() << "\n";
853  auto moduleParameterLink =
854  module.second.getNode("analyzerModuleParameterLink");
855  if(!moduleParameterLink.isDisconnected())
856  {
857  auto moduleParameters = moduleParameterLink.getChildren();
858  for(auto& moduleParameter : moduleParameters)
859  {
860  if(!moduleParameter.second
861  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
862  .getValue<bool>())
863  PUSHCOMMENT;
864 
865  OUT << moduleParameter.second.getNode("analyzerParameterKey")
866  .getValue()
867  << ": "
868  << moduleParameter.second.getNode("analyzerParameterValue")
869  .getValue()
870  << "\n";
871 
872  if(!moduleParameter.second
873  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
874  .getValue<bool>())
875  POPCOMMENT;
876  }
877  }
878  POPTAB;
879  OUT << "}\n\n"; // end analyzer module
880 
881  if(!module.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
882  .getValue<bool>())
883  POPCOMMENT;
884  }
885  POPTAB;
886  OUT << "}\n\n"; // end analyzer
887  }
888 
889  auto producers = physics.getNode("producersLink");
890  if(!producers.isDisconnected())
891  {
893  OUT << "producers: {\n";
894 
895  PUSHTAB;
896  auto modules = producers.getChildren();
897  for(auto& module : modules)
898  {
899  if(!module.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
900  .getValue<bool>())
901  PUSHCOMMENT;
902 
903  OUT << module.second.getNode("producerKey").getValue() << ": {\n";
904  PUSHTAB;
905  OUT << "module_type: "
906  << module.second.getNode("producerModuleType").getValue() << "\n";
907  auto moduleParameterLink =
908  module.second.getNode("producerModuleParameterLink");
909  if(!moduleParameterLink.isDisconnected())
910  {
911  auto moduleParameters = moduleParameterLink.getChildren();
912  for(auto& moduleParameter : moduleParameters)
913  {
914  if(!moduleParameter.second
915  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
916  .getValue<bool>())
917  PUSHCOMMENT;
918 
919  OUT << moduleParameter.second.getNode("producerParameterKey")
920  .getValue()
921  << ":"
922  << moduleParameter.second.getNode("producerParameterValue")
923  .getValue()
924  << "\n";
925 
926  if(!moduleParameter.second
927  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
928  .getValue<bool>())
929  POPCOMMENT;
930  }
931  }
932  POPTAB;
933  OUT << "}\n\n"; // end producer module
934 
935  if(!module.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
936  .getValue<bool>())
937  POPCOMMENT;
938  }
939  POPTAB;
940  OUT << "}\n\n"; // end producer
941  }
942 
943  auto filters = physics.getNode("filtersLink");
944  if(!filters.isDisconnected())
945  {
947  OUT << "filters: {\n";
948 
949  PUSHTAB;
950  auto modules = filters.getChildren();
951  for(auto& module : modules)
952  {
953  if(!module.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
954  .getValue<bool>())
955  PUSHCOMMENT;
956 
957  OUT << module.second.getNode("filterKey").getValue() << ": {\n";
958  PUSHTAB;
959  OUT << "module_type: "
960  << module.second.getNode("filterModuleType").getValue() << "\n";
961  auto moduleParameterLink =
962  module.second.getNode("filterModuleParameterLink");
963  if(!moduleParameterLink.isDisconnected())
964  {
965  auto moduleParameters = moduleParameterLink.getChildren();
966  for(auto& moduleParameter : moduleParameters)
967  {
968  if(!moduleParameter.second
969  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
970  .getValue<bool>())
971  PUSHCOMMENT;
972 
973  OUT << moduleParameter.second.getNode("filterParameterKey")
974  .getValue()
975  << ": "
976  << moduleParameter.second.getNode("filterParameterValue")
977  .getValue()
978  << "\n";
979 
980  if(!moduleParameter.second
981  .getNode(TableViewColumnInfo::COL_NAME_STATUS)
982  .getValue<bool>())
983  POPCOMMENT;
984  }
985  }
986  POPTAB;
987  OUT << "}\n\n"; // end filter module
988 
989  if(!module.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
990  .getValue<bool>())
991  POPCOMMENT;
992  }
993  POPTAB;
994  OUT << "}\n\n"; // end filter
995  }
996 
997  auto otherParameterLink = physics.getNode("physicsOtherParametersLink");
998  if(!otherParameterLink.isDisconnected())
999  {
1001  auto physicsParameters = otherParameterLink.getChildren();
1002  for(auto& parameter : physicsParameters)
1003  {
1004  if(!parameter.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
1005  .getValue<bool>())
1006  PUSHCOMMENT;
1007 
1008  OUT << parameter.second.getNode("physicsParameterKey").getValue() << ": "
1009  << parameter.second.getNode("physicsParameterValue").getValue()
1010  << "\n";
1011 
1012  if(!parameter.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
1013  .getValue<bool>())
1014  POPCOMMENT;
1015  }
1016  }
1017  POPTAB;
1018  OUT << "}\n\n"; // end physics
1019  }
1020 
1021  //--------------------------------------
1022  // handle source
1023  auto source = builderNode.getNode("sourceLink");
1024  if(!source.isDisconnected())
1025  {
1026  OUT << "source: {\n";
1027 
1028  PUSHTAB;
1029  OUT << "module_type: " << source.getNode("sourceModuleType").getValue() << "\n";
1030  OUT << "waiting_time: " << source.getNode("sourceWaitingTime").getValue() << "\n";
1031  OUT << "resume_after_timeout: "
1032  << (source.getNode("sourceResumeAfterTimeout").getValue<bool>() ? "true"
1033  : "false")
1034  << "\n";
1035  POPTAB;
1036  OUT << "}\n\n"; // end source
1037  }
1038 
1039  //--------------------------------------
1040  // handle process_name
1041  OUT << "process_name: "
1042  << builderNode.getNode(
1043  "ARTDAQGlobalTableForProcessNameLink/processNameForBuilders")
1044  << "\n";
1045 
1046  auto otherParameterLink = builderNode.getNode("addOnParametersLink");
1047  if(!otherParameterLink.isDisconnected())
1048  {
1050  auto otherParameters = otherParameterLink.getChildren();
1051 
1052  //__COUTV__(otherParameters.size());
1053  for(auto& parameter : otherParameters)
1054  {
1055  if(!parameter.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
1056  .getValue<bool>())
1057  PUSHCOMMENT;
1058 
1059  OUT << parameter.second.getNode("daqParameterKey").getValue() << ": "
1060  << parameter.second.getNode("daqParameterValue").getValue() << "\n";
1061 
1062  if(!parameter.second.getNode(TableViewColumnInfo::COL_NAME_STATUS)
1063  .getValue<bool>())
1064  POPCOMMENT;
1065  }
1066  }
1067  // else
1068  // __COUT__ << "No add-on parameters found" << __E__;
1069 
1070  out.close();
1071 } // end outputFHICL()
1072 
1073 DEFINE_OTS_TABLE(ARTDAQBuilderTable)