otsdaq  v2_00_00
ARTDAQAggregatorConfiguration_configuration.cc
1 #include "otsdaq-core/ConfigurationPluginDataFormats/ARTDAQAggregatorConfiguration.h"
2 #include "otsdaq-core/Macros/ConfigurationPluginMacros.h"
3 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
4 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
5 
6 #include <iostream>
7 #include <fstream> // std::fstream
8 #include <stdio.h>
9 #include <sys/stat.h> //for mkdir
10 
11 using namespace ots;
12 
13 
14 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/"+ "ARTDAQConfigurations/"
15 #define ARTDAQ_FILE_PREAMBLE "aggregator"
16 
17 //helpers
18 #define OUT out << tabStr << commentStr
19 #define PUSHTAB tabStr += "\t"
20 #define POPTAB tabStr.resize(tabStr.size()-1)
21 #define PUSHCOMMENT commentStr += "# "
22 #define POPCOMMENT commentStr.resize(commentStr.size()-2)
23 
24 
25 //========================================================================================================================
26 ARTDAQAggregatorConfiguration::ARTDAQAggregatorConfiguration(void)
27  : ConfigurationBase("ARTDAQAggregatorConfiguration")
28 {
30  //WARNING: the names used in C++ MUST match the Configuration INFO //
32 
33 }
34 
35 //========================================================================================================================
36 ARTDAQAggregatorConfiguration::~ARTDAQAggregatorConfiguration(void)
37 {}
38 
39 //========================================================================================================================
40 void ARTDAQAggregatorConfiguration::init(ConfigurationManager* configManager)
41 {
42  //make directory just in case
43  mkdir((ARTDAQ_FCL_PATH).c_str(), 0755);
44 
45  __COUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl;
46  __COUT__ << configManager->__SELF_NODE__ << std::endl;
47 
48  const XDAQContextConfiguration *contextConfig = configManager->__GET_CONFIG__(XDAQContextConfiguration);
49  std::vector<const XDAQContextConfiguration::XDAQContext *> aggContexts =
50  contextConfig->getAggregatorContexts();
51 
52  //for each aggregator context
53  // output associated fcl config file
54  for (auto &aggContext : aggContexts)
55  {
56  ConfigurationTree aggConfigNode = contextConfig->getSupervisorConfigNode(configManager,
57  aggContext->contextUID_, aggContext->applications_[0].applicationUID_);
58 
59  __COUT__ << "Path for this aggregator config is " <<
60  aggContext->contextUID_ << "/" <<
61  aggContext->applications_[0].applicationUID_ << "/" <<
62  aggConfigNode.getValueAsString() <<
63  std::endl;
64 
65  outputFHICL(configManager,aggConfigNode,
66  contextConfig->getARTDAQAppRank(aggContext->contextUID_),
67  contextConfig->getContextAddress(aggContext->contextUID_),
68  contextConfig->getARTDAQDataPort(configManager,aggContext->contextUID_),
69  contextConfig);
70  }
71 }
72 
73 //========================================================================================================================
74 std::string ARTDAQAggregatorConfiguration::getFHICLFilename(const ConfigurationTree &aggregatorNode)
75 {
76  __COUT__ << "ARTDAQ Aggregator UID: " << aggregatorNode.getValue() << std::endl;
77  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
78  std::string uid = aggregatorNode.getValue();
79  for (unsigned int i = 0; i < uid.size(); ++i)
80  if ((uid[i] >= 'a' && uid[i] <= 'z') ||
81  (uid[i] >= 'A' && uid[i] <= 'Z') ||
82  (uid[i] >= '0' && uid[i] <= '9')) //only allow alpha numeric in file name
83  filename += uid[i];
84 
85  filename += ".fcl";
86 
87  __COUT__ << "fcl: " << filename << std::endl;
88 
89  return filename;
90 }
91 
92 //========================================================================================================================
93 void ARTDAQAggregatorConfiguration::outputFHICL(ConfigurationManager *configManager,
94  const ConfigurationTree &aggregatorNode,
95  unsigned int selfRank, std::string selfHost, unsigned int selfPort,
96  const XDAQContextConfiguration *contextConfig)
97 {
98  /*
99  the file will look something like this:
100 
101  services: {
102  scheduler: {
103  fileMode: NOMERGE
104  errorOnFailureToPut: false
105  }
106  NetMonTransportServiceInterface: {
107  service_provider: NetMonTransportService
108  }
109 
110  #SimpleMemoryCheck: { }
111  }
112 
113  daq: {
114  aggregator: {
115  expected_events_per_bunch: 1
116  print_event_store_stats: true
117  event_queue_depth: 20
118  event_queue_wait_time: 5
119  onmon_event_prescale: 1
120  xmlrpc_client_list: ";http://ironwork.fnal.gov:5205/RPC2,3;http://ironwork.fnal.gov:5206/RPC2,3;http://ironwork.fnal.gov:5235/RPC2,4;http://ironwork.fnal.gov:5236/RPC2,4;http://ironwork.fnal.gov:5265/RPC2,5;http://ironwork.fnal.gov:5266/RPC2,5"
121  file_size_MB: 0.0
122  file_duration: 0
123  file_event_count: 0
124  is_data_logger: true
125 
126  sources: {
127  s2: { transferPluginType: MPI source_rank: 2 max_fragment_size_words: 2097152}
128  s3: { transferPluginType: MPI source_rank: 3 max_fragment_size_words: 2097152}
129 
130  }
131  }
132 
133  metrics: {
134  aggFile: {
135  metricPluginType: "file"
136  level: 3
137  fileName: "/tmp/aggregator/agg_%UID%_metrics.log"
138  uniquify: true
139  }
140  # ganglia: {
141  # metricPluginType: "ganglia"
142  # level: %{ganglia_level}
143  # reporting_interval: 15.0
144  #
145  # configFile: "/etc/ganglia/gmond.conf"
146  # group: "ARTDAQ"
147  # }
148  # msgfac: {
149  # level: %{mf_level}
150  # metricPluginType: "msgFacility"
151  # output_message_application_name: "ARTDAQ Metric"
152  # output_message_severity: 0
153  # }
154  # graphite: {
155  # level: %{graphite_level}
156  # metricPluginType: "graphite"
157  # host: "localhost"
158  # port: 20030
159  # namespace: "artdaq."
160  # }
161  }
162 
163  transfer_to_dispatcher: {
164  transferPluginType: Shmem
165  source_rank: 4
166  destination_rank: 5
167  max_fragment_size_words: 2097152
168  }
169 
170  }
171 
172  source: {
173  module_type: NetMonInput
174  }
175  outputs: {
176  normalOutput: {
177  module_type: RootOutput
178  fileName: "/tmp/artdaqdemo_r%06r_sr%02s_%to.root"
179  }
180 
181  #normalOutputMod2: {
182  # module_type: RootOutput
183  # fileName: "/tmp/artdaqdemo_r%06r_sr%02s_%to_mod2.root"
184  # SelectEvents: { SelectEvents: [ pmod2 ] }
185  #}
186 
187  #normalOutputMod3: {
188  # module_type: RootOutput
189  # fileName: "/tmp/artdaqdemo_r%06r_sr%02s_%to_mod3.root"
190  # SelectEvents: { SelectEvents: [ pmod3 ] }
191  #}
192 
193  }
194  physics: {
195  analyzers: {
196 
197 
198  checkintegrity: {
199  module_type: CheckIntegrity
200  raw_data_label: daq
201  frag_type: TOY1
202  }
203 
204  }
205 
206  producers: {
207 
208  BuildInfo:
209  {
210  module_type: ArtdaqDemoBuildInfo
211  instance_name: ArtdaqDemo
212  }
213  }
214 
215  filters: {
216 
217  prescaleMod2: {
218  module_type: NthEvent
219  nth: 2
220  }
221 
222  prescaleMod3: {
223  module_type: NthEvent
224  nth: 3
225  }
226  }
227 
228  p2: [ BuildInfo ]
229  pmod2: [ prescaleMod2 ]
230  pmod3: [ prescaleMod3 ]
231 
232  #a1: [ app, wf]
233 
234  my_output_modules: [ normalOutput ]
235  #my_output_modules: [ normalOutputMod2, normalOutputMod3 ]
236  }
237  process_name: DAQAG
238 
239  */
240 
241  std::string filename = getFHICLFilename(aggregatorNode);
242 
243  __COUT__ << "selfRank = " << selfRank << std::endl;
244 
245 
247  //generate xdaq run parameter file
248  std::fstream out;
249 
250  std::string tabStr = "";
251  std::string commentStr = "";
252 
253  out.open(filename, std::fstream::out | std::fstream::trunc);
254  if (out.fail())
255  {
256  __SS__ << "Failed to open ARTDAQ Aggregator fcl file: " << filename << std::endl;
257  throw std::runtime_error(ss.str());
258  }
259 
260  //no primary link to configuration tree for aggregator node!
261  if (aggregatorNode.isDisconnected())
262  {
263  //create empty fcl
264  OUT << "{}\n\n";
265  out.close();
266  return;
267  }
268 
269  //--------------------------------------
270  //handle services
271  auto services = aggregatorNode.getNode("servicesLink");
272  if (!services.isDisconnected())
273  {
274  OUT << "services: {\n";
275 
276  //scheduler
277  PUSHTAB;
278  OUT << "scheduler: {\n";
279 
280  PUSHTAB;
281  OUT << "fileMode: " << services.getNode("schedulerFileMode").getValue() <<
282  "\n";
283  OUT << "errorOnFailureToPut: " <<
284  (services.getNode("schedulerErrorOnFailtureToPut").getValue<bool>() ? "true" : "false") <<
285  "\n";
286  POPTAB;
287 
288  OUT << "}\n\n";
289 
290 
291  //NetMonTransportServiceInterface
292  OUT << "NetMonTransportServiceInterface: {\n";
293 
294  PUSHTAB;
295  OUT << "service_provider: " <<
296  //services.getNode("NetMonTrasportServiceInterfaceServiceProvider").getEscapedValue()
297  services.getNode("NetMonTrasportServiceInterfaceServiceProvider").getValue()
298  << "\n";
299 
300  POPTAB;
301  OUT << "}\n\n"; //end NetMonTransportServiceInterface
302 
303  POPTAB;
304  OUT << "}\n\n"; //end services
305 
306  }
307 
308  //--------------------------------------
309  //handle daq
310  auto daq = aggregatorNode.getNode("daqLink");
311  if (!daq.isDisconnected())
312  {
313  OUT << "daq: {\n";
314 
315  //aggregator
316  PUSHTAB;
317  OUT << "aggregator: {\n";
318 
319  PUSHTAB;
320  auto parametersLink = daq.getNode("daqAggregatorParametersLink");
321  if (!parametersLink.isDisconnected())
322  {
323 
324  auto parameters = parametersLink.getChildren();
325  for (auto &parameter : parameters)
326  {
327  if (!parameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
328  PUSHCOMMENT;
329 
330  auto comment = parameter.second.getNode("CommentDescription");
331  OUT << parameter.second.getNode("daqParameterKey").getValue() <<
332  ": " <<
333  parameter.second.getNode("daqParameterValue").getValue()
334  <<
335  (comment.isDefaultValue() ? "" : ("\t # " + comment.getValue())) <<
336  "\n";
337 
338  if (!parameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
339  POPCOMMENT;
340  }
341  }
342  OUT << "\n"; //end daq aggregator parameters
343 
344  OUT << "sources: {\n";
345 
346  PUSHTAB;
347  auto sourcesGroup = daq.getNode("daqAggregatorSourcesLink");
348  if (!sourcesGroup.isDisconnected())
349  {
350  try
351  {
352  auto sources = sourcesGroup.getChildren();
353  for (auto &source : sources)
354  {
355  std::string sourceContextUID = source.second.getNode("sourceARTDAQContextLink").getValueAsString();
356 
357  std::string host = contextConfig->getContextAddress(sourceContextUID);
358  unsigned int sourceRank = contextConfig->getARTDAQAppRank(sourceContextUID);
359  unsigned int port = contextConfig->getARTDAQDataPort(configManager, sourceContextUID);
360 
361  OUT << source.second.getNode("sourceKey").getValue() <<
362  ": {" <<
363  " transferPluginType: " <<
364  source.second.getNode("transferPluginType").getValue() <<
365  " source_rank: " <<
366  sourceRank <<
367  " max_fragment_size_words: " <<
368  source.second.getNode("ARTDAQGlobalConfigurationLink/maxFragmentSizeWords").getValue<unsigned int>() <<
369  " host_map: [{rank: " << sourceRank << " host: \"" << host << "\" portOffset: " << std::to_string(port) << "}, " <<
370  "{rank: " << selfRank << " host: \"" << selfHost << "\" portOffset: " << std::to_string(selfPort) << "}]" <<
371  "}\n";
372  }
373  }
374  catch (const std::runtime_error& e)
375  {
376  __SS__ << "Are the DAQ sources valid? Error occurred looking for Aggregator DAQ sources for UID '" <<
377  aggregatorNode.getValue() << "': " << e.what() << std::endl;
378  __COUT_ERR__ << ss.str() << std::endl;
379  throw std::runtime_error(ss.str());
380  }
381  }
382  POPTAB;
383  OUT << "}\n\n"; //end sources
384 
385  POPTAB;
386  OUT << "}\n\n"; //end aggregator
387 
388 
389  OUT << "metrics: {\n";
390 
391  PUSHTAB;
392  auto metricsGroup = daq.getNode("daqMetricsLink");
393  if (!metricsGroup.isDisconnected())
394  {
395  auto metrics = metricsGroup.getChildren();
396 
397  for (auto &metric : metrics)
398  {
399  if (!metric.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
400  PUSHCOMMENT;
401 
402  OUT << metric.second.getNode("metricKey").getValue() <<
403  ": {\n";
404  PUSHTAB;
405 
406  OUT << "metricPluginType: " <<
407  metric.second.getNode("metricPluginType").getValue()
408  << "\n";
409  OUT << "level: " <<
410  metric.second.getNode("metricLevel").getValue()
411  << "\n";
412 
413  auto metricParametersGroup = metric.second.getNode("metricParametersLink");
414  if (!metricParametersGroup.isDisconnected())
415  {
416  auto metricParameters = metricParametersGroup.getChildren();
417  for (auto &metricParameter : metricParameters)
418  {
419  if (!metricParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
420  PUSHCOMMENT;
421 
422  auto comment = metricParameter.second.getNode("CommentDescription");
423  OUT << metricParameter.second.getNode("metricParameterKey").getValue() <<
424  ": " <<
425  metricParameter.second.getNode("metricParameterValue").getValue()
426  <<
427  (comment.isDefaultValue() ? "" : ("\t # " + comment.getValue())) <<
428  "\n";
429 
430  if (!metricParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
431  POPCOMMENT;
432 
433  }
434  }
435  POPTAB;
436  OUT << "}\n\n"; //end metric
437 
438  if (!metric.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
439  POPCOMMENT;
440  }
441  }
442  POPTAB;
443  OUT << "}\n\n"; //end metrics
444 
445  OUT << "destinations: {\n";
446 
447  PUSHTAB;
448  //other destinations
449  auto destinationsGroup = daq.getNode("daqAggregatorDestinationsLink");
450  if (!destinationsGroup.isDisconnected())
451  {
452  try
453  {
454  auto destinations = destinationsGroup.getChildren();
455  for (auto &destination : destinations)
456  {
457  auto destinationContextUID = destination.second.getNode("destinationARTDAQContextLink").getValueAsString();
458 
459  unsigned int destinationRank = contextConfig->getARTDAQAppRank(destinationContextUID);
460  std::string host = contextConfig->getContextAddress(destinationContextUID);
461  unsigned int port = contextConfig->getARTDAQDataPort(configManager,destinationContextUID);
462 
463  OUT << destination.second.getNode("destinationKey").getValue() <<
464  ": {" <<
465  " transferPluginType: " <<
466  destination.second.getNode("transferPluginType").getValue() <<
467  " source_rank: " <<
468  selfRank <<
469  " destination_rank: " <<
470  destinationRank <<
471  " max_fragment_size_words: " <<
472  destination.second.getNode("ARTDAQGlobalConfigurationLink/maxFragmentSizeWords").getValue<unsigned int>() <<
473  " host_map: [{rank: " << destinationRank << " host: \"" << host << "\" portOffset: " << std::to_string(port) << "}, " <<
474  "{rank: " << selfRank << " host: \"" << selfHost << "\" portOffset: " << std::to_string(selfPort) << "}]" <<
475  "}\n";
476  }
477  }
478  catch (const std::runtime_error& e)
479  {
480  __SS__ << "Are the DAQ destinations valid? Error occurred looking for Aggregator DAQ destinations for UID '" <<
481  aggregatorNode.getValue() << "': " << e.what() << std::endl;
482  __COUT_ERR__ << ss.str() << std::endl;
483  throw std::runtime_error(ss.str());
484  }
485  }
486  POPTAB;
487  OUT << "}\n\n"; //end destinations
488 
489  POPTAB;
490  OUT << "}\n\n"; //end daq
491  }
492 
493 
494  //--------------------------------------
495  //handle source
496  auto source = aggregatorNode.getNode("sourceLink");
497  if (!source.isDisconnected())
498  {
499  OUT << "source: {\n";
500 
501  PUSHTAB;
502  OUT << "module_type: " << source.getNode("sourceModuleType").getValue() <<
503  "\n";
504  POPTAB;
505  OUT << "}\n\n"; //end source
506  }
507 
508  //--------------------------------------
509  //handle outputs
510  auto outputs = aggregatorNode.getNode("outputsLink");
511  if (!outputs.isDisconnected())
512  {
513  OUT << "outputs: {\n";
514 
515  PUSHTAB;
516 
517  auto outputPlugins = outputs.getChildren();
518  for (auto &outputPlugin : outputPlugins)
519  {
520  if (!outputPlugin.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
521  PUSHCOMMENT;
522 
523  OUT << outputPlugin.second.getNode("outputKey").getValue() <<
524  ": {\n";
525  PUSHTAB;
526  OUT << "module_type: " <<
527  outputPlugin.second.getNode("outputModuleType").getValue() <<
528  "\n";
529  auto pluginParameterLink = outputPlugin.second.getNode("outputModuleParameterLink");
530  if (!pluginParameterLink.isDisconnected())
531  {
532  auto pluginParameters = pluginParameterLink.getChildren();
533  for (auto &pluginParameter : pluginParameters)
534  {
535  if (!pluginParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
536  PUSHCOMMENT;
537 
538  auto comment = pluginParameter.second.getNode("CommentDescription");
539  OUT << pluginParameter.second.getNode("outputParameterKey").getValue() <<
540  ": " <<
541  pluginParameter.second.getNode("outputParameterValue").getValue()
542  <<
543  (comment.isDefaultValue() ? "" : ("\t # " + comment.getValue())) <<
544  "\n";
545 
546  if (!pluginParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
547  POPCOMMENT;
548  }
549  }
550  POPTAB;
551  OUT << "}\n\n"; //end output module
552 
553  if (!outputPlugin.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
554  POPCOMMENT;
555  }
556 
557  POPTAB;
558  OUT << "}\n\n"; //end outputs
559  }
560 
561 
562  //--------------------------------------
563  //handle physics
564  auto physics = aggregatorNode.getNode("physicsLink");
565  if (!physics.isDisconnected())
566  {
568  OUT << "physics: {\n";
569 
570  PUSHTAB;
571 
572  auto analyzers = physics.getNode("analyzersLink");
573  if (!analyzers.isDisconnected())
574  {
576  OUT << "analyzers: {\n";
577 
578  PUSHTAB;
579  auto modules = analyzers.getChildren();
580  for (auto &module : modules)
581  {
582  if (!module.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
583  PUSHCOMMENT;
584 
585  OUT << module.second.getNode("analyzerKey").getValue() <<
586  ": {\n";
587  PUSHTAB;
588  OUT << "module_type: " <<
589  module.second.getNode("analyzerModuleType").getValue() <<
590  "\n";
591  auto moduleParameterLink = module.second.getNode("analyzerModuleParameterLink");
592  if (!moduleParameterLink.isDisconnected())
593  {
594  auto moduleParameters = moduleParameterLink.getChildren();
595  for (auto &moduleParameter : moduleParameters)
596  {
597  if (!moduleParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
598  PUSHCOMMENT;
599 
600  auto comment = moduleParameter.second.getNode("CommentDescription");
601  OUT << moduleParameter.second.getNode("analyzerParameterKey").getValue() <<
602  ": " <<
603  moduleParameter.second.getNode("analyzerParameterValue").getValue()
604  <<
605  (comment.isDefaultValue() ? "" : ("\t # " + comment.getValue())) <<
606  "\n";
607 
608  if (!moduleParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
609  POPCOMMENT;
610  }
611  }
612  POPTAB;
613  OUT << "}\n\n"; //end analyzer module
614 
615  if (!module.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
616  POPCOMMENT;
617  }
618  POPTAB;
619  OUT << "}\n\n"; //end analyzer
620  }
621 
622  auto producers = physics.getNode("producersLink");
623  if (!producers.isDisconnected())
624  {
626  OUT << "producers: {\n";
627 
628  PUSHTAB;
629  auto modules = producers.getChildren();
630  for (auto &module : modules)
631  {
632  if (!module.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
633  PUSHCOMMENT;
634 
635  OUT << module.second.getNode("producerKey").getValue() <<
636  ": {\n";
637  PUSHTAB;
638  OUT << "module_type: " <<
639  module.second.getNode("producerModuleType").getValue() <<
640  "\n";
641  auto moduleParameterLink = module.second.getNode("producerModuleParameterLink");
642  if (!moduleParameterLink.isDisconnected())
643  {
644  auto moduleParameters = moduleParameterLink.getChildren();
645  for (auto &moduleParameter : moduleParameters)
646  {
647  if (!moduleParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
648  PUSHCOMMENT;
649 
650  auto comment = moduleParameter.second.getNode("CommentDescription");
651  OUT << moduleParameter.second.getNode("producerParameterKey").getValue() <<
652  ":" <<
653  moduleParameter.second.getNode("producerParameterValue").getValue()
654  <<
655  (comment.isDefaultValue() ? "" : ("\t # " + comment.getValue())) <<
656  "\n";
657 
658  if (!moduleParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
659  POPCOMMENT;
660  }
661  }
662  POPTAB;
663  OUT << "}\n\n"; //end producer module
664 
665  if (!module.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
666  POPCOMMENT;
667  }
668  POPTAB;
669  OUT << "}\n\n"; //end producer
670  }
671 
672 
673  auto filters = physics.getNode("filtersLink");
674  if (!filters.isDisconnected())
675  {
677  OUT << "filters: {\n";
678 
679  PUSHTAB;
680  auto modules = filters.getChildren();
681  for (auto &module : modules)
682  {
683  if (!module.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
684  PUSHCOMMENT;
685 
686  OUT << module.second.getNode("filterKey").getValue() <<
687  ": {\n";
688  PUSHTAB;
689  OUT << "module_type: " <<
690  module.second.getNode("filterModuleType").getValue() <<
691  "\n";
692  auto moduleParameterLink = module.second.getNode("filterModuleParameterLink");
693  if (!moduleParameterLink.isDisconnected())
694  {
695  auto moduleParameters = moduleParameterLink.getChildren();
696  for (auto &moduleParameter : moduleParameters)
697  {
698  if (!moduleParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
699  PUSHCOMMENT;
700 
701  auto comment = moduleParameter.second.getNode("CommentDescription");
702  OUT << moduleParameter.second.getNode("filterParameterKey").getValue()
703  << ": " <<
704  moduleParameter.second.getNode("filterParameterValue").getValue()
705  <<
706  (comment.isDefaultValue() ? "" : ("\t # " + comment.getValue())) <<
707  "\n";
708 
709  if (!moduleParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
710  POPCOMMENT;
711  }
712  }
713  POPTAB;
714  OUT << "}\n\n"; //end filter module
715 
716  if (!module.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
717  POPCOMMENT;
718  }
719  POPTAB;
720  OUT << "}\n\n"; //end filter
721  }
722 
723 
724  auto otherParameterLink = physics.getNode("physicsOtherParametersLink");
725  if (!otherParameterLink.isDisconnected())
726  {
728  auto physicsParameters = otherParameterLink.getChildren();
729  for (auto &parameter : physicsParameters)
730  {
731  if (!parameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
732  PUSHCOMMENT;
733 
734  auto comment = parameter.second.getNode("CommentDescription");
735  OUT << parameter.second.getNode("physicsParameterKey").getValue() <<
736  ": " <<
737  parameter.second.getNode("physicsParameterValue").getValue()
738  <<
739  (comment.isDefaultValue() ? "" : ("\t # " + comment.getValue())) <<
740  "\n";
741 
742  if (!parameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
743  POPCOMMENT;
744  }
745  }
746  POPTAB;
747  OUT << "}\n\n"; //end physics
748  }
749 
750 
751  //--------------------------------------
752  //handle process_name
753  OUT << "process_name: " <<
754  aggregatorNode.getNode("ARTDAQGlobalConfigurationForProcessNameLink/processNameForAggregators")
755  << "\n";
756 
757 
758 
759 
760  out.close();
761 }
762 
763 DEFINE_OTS_CONFIGURATION(ARTDAQAggregatorConfiguration)