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