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