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