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