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