otsdaq  v1_01_03
 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  ConfigurationTree 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 
242 
244  //generate xdaq run parameter file
245  std::fstream out;
246 
247  std::string tabStr = "";
248  std::string commentStr = "";
249 
250  out.open(filename, std::fstream::out | std::fstream::trunc);
251  if(out.fail())
252  {
253  __SS__ << "Failed to open ARTDAQ Builder fcl file: " << filename << std::endl;
254  throw std::runtime_error(ss.str());
255  }
256 
257  //no primary link to configuration tree for aggregator node!
258  if(aggregatorNode.isDisconnected())
259  {
260  //create empty fcl
261  OUT << "{}\n\n";
262  out.close();
263  return;
264  }
265 
266  //--------------------------------------
267  //handle services
268  auto services = aggregatorNode.getNode("servicesLink");
269  if(!services.isDisconnected())
270  {
271  OUT << "services: {\n";
272 
273  //scheduler
274  PUSHTAB;
275  OUT << "scheduler: {\n";
276 
277  PUSHTAB;
278  OUT << "fileMode: " << services.getNode("schedulerFileMode").getValue() <<
279  "\n";
280  OUT << "errorOnFailureToPut: " <<
281  (services.getNode("schedulerErrorOnFailtureToPut").getValue<bool>()?"true":"false") <<
282  "\n";
283  POPTAB;
284 
285  OUT << "}\n\n";
286 
287 
288  //NetMonTransportServiceInterface
289  OUT << "NetMonTransportServiceInterface: {\n";
290 
291  PUSHTAB;
292  OUT << "service_provider: " <<
293  //services.getNode("NetMonTrasportServiceInterfaceServiceProvider").getEscapedValue()
294  services.getNode("NetMonTrasportServiceInterfaceServiceProvider").getValue()
295  << "\n";
296 
297  POPTAB;
298  OUT << "}\n\n"; //end NetMonTransportServiceInterface
299 
300  POPTAB;
301  OUT << "}\n\n"; //end services
302 
303  }
304 
305  //--------------------------------------
306  //handle daq
307  auto daq = aggregatorNode.getNode("daqLink");
308  if(!daq.isDisconnected())
309  {
310  OUT << "daq: {\n";
311 
312  //aggregator
313  PUSHTAB;
314  OUT << "aggregator: {\n";
315 
316  PUSHTAB;
317  auto parametersLink = daq.getNode("daqAggregatorParametersLink");
318  if(!parametersLink.isDisconnected())
319  {
320 
321  auto parameters = parametersLink.getChildren();
322  for(auto &parameter:parameters)
323  {
324  if(!parameter.second.getNode("Status").getValue<bool>())
325  PUSHCOMMENT;
326 
327  auto comment = parameter.second.getNode("CommentDescription");
328  OUT << parameter.second.getNode("daqParameterKey").getValue() <<
329  ": " <<
330  parameter.second.getNode("daqParameterValue").getValue()
331  <<
332  (comment.isDefaultValue()?"":("\t # " + comment.getValue())) <<
333  "\n";
334 
335  if(!parameter.second.getNode("Status").getValue<bool>())
336  POPCOMMENT;
337  }
338  }
339  OUT << "\n"; //end daq aggregator parameters
340 
341  OUT << "sources: {\n";
342 
343  PUSHTAB;
344  auto sourcesGroup = daq.getNode("daqAggregatorSourcesLink");
345  if(!sourcesGroup.isDisconnected())
346  {
347  auto sources = sourcesGroup.getChildren();
348  for(auto &source:sources)
349  {
350  unsigned int sourceRank =
351  contextConfig->getARTDAQAppRank(
352  source.second.getNode("sourceARTDAQContextLink").getValue());
353 
354  OUT << source.second.getNode("sourceKey").getValue() <<
355  ": {" <<
356  " transferPluginType: " <<
357  source.second.getNode("transferPluginType").getValue() <<
358  " source_rank: " <<
359  sourceRank <<
360  " max_fragment_size_words: " <<
361  source.second.getNode("ARTDAQGlobalConfigurationLink/maxFragmentSizeWords").getValue<unsigned int>() <<
362  "}\n";
363  }
364  }
365  POPTAB;
366  OUT << "}\n\n"; //end sources
367 
368  POPTAB;
369  OUT << "}\n\n"; //end aggregator
370 
371 
372  OUT << "metrics: {\n";
373 
374  PUSHTAB;
375  auto metricsGroup = daq.getNode("daqMetricsLink");
376  if(!metricsGroup.isDisconnected())
377  {
378  auto metrics = metricsGroup.getChildren();
379 
380  for(auto &metric:metrics)
381  {
382  if(!metric.second.getNode("Status").getValue<bool>())
383  PUSHCOMMENT;
384 
385  OUT << metric.second.getNode("metricKey").getValue() <<
386  ": {\n";
387  PUSHTAB;
388 
389  OUT << "metricPluginType: " <<
390  metric.second.getNode("metricPluginType").getValue()
391  << "\n";
392  OUT << "level: " <<
393  metric.second.getNode("metricLevel").getValue()
394  << "\n";
395 
396  auto metricParametersGroup = metric.second.getNode("metricParametersLink");
397  if(!metricParametersGroup.isDisconnected())
398  {
399  auto metricParameters = metricParametersGroup.getChildren();
400  for(auto &metricParameter:metricParameters)
401  {
402  if(!metricParameter.second.getNode("Status").getValue<bool>())
403  PUSHCOMMENT;
404 
405  auto comment = metricParameter.second.getNode("CommentDescription");
406  OUT << metricParameter.second.getNode("metricParameterKey").getValue() <<
407  ": " <<
408  metricParameter.second.getNode("metricParameterValue").getValue()
409  <<
410  (comment.isDefaultValue()?"":("\t # " + comment.getValue())) <<
411  "\n";
412 
413  if(!metricParameter.second.getNode("Status").getValue<bool>())
414  POPCOMMENT;
415 
416  }
417  }
418  POPTAB;
419  OUT << "}\n\n"; //end metric
420 
421  if(!metric.second.getNode("Status").getValue<bool>())
422  POPCOMMENT;
423  }
424  }
425  POPTAB;
426  OUT << "}\n\n"; //end metrics
427 
428  //other destinations
429  auto destinationsGroup = daq.getNode("daqAggregatorDestinationsLink");
430  if(!destinationsGroup.isDisconnected())
431  {
432  auto destinations = destinationsGroup.getChildren();
433  for(auto &destination:destinations)
434  {
435  unsigned int destinationRank = contextConfig->getARTDAQAppRank(
436  destination.second.getNode("destinationARTDAQContextLink").getValueAsString());
437 
438  OUT << destination.second.getNode("destinationKey").getValue() <<
439  ": {" <<
440  " transferPluginType: " <<
441  destination.second.getNode("transferPluginType").getValue() <<
442  " source_rank: " <<
443  selfRank <<
444  " destination_rank: " <<
445  destinationRank <<
446  " max_fragment_size_words: " <<
447  destination.second.getNode("ARTDAQGlobalConfigurationLink/maxFragmentSizeWords").getValue<unsigned int>() <<
448  "}\n";
449  }
450  }
451 
452  POPTAB;
453  OUT << "}\n\n"; //end daq
454  }
455 
456 
457  //--------------------------------------
458  //handle source
459  auto source = aggregatorNode.getNode("sourceLink");
460  if(!source.isDisconnected())
461  {
462  OUT << "source: {\n";
463 
464  PUSHTAB;
465  OUT << "module_type: " << source.getNode("sourceModuleType").getValue() <<
466  "\n";
467  POPTAB;
468  OUT << "}\n\n"; //end source
469  }
470 
471  //--------------------------------------
472  //handle outputs
473  auto outputs = aggregatorNode.getNode("outputsLink");
474  if(!outputs.isDisconnected())
475  {
476  OUT << "outputs: {\n";
477 
478  PUSHTAB;
479 
480  auto outputPlugins = outputs.getChildren();
481  for(auto &outputPlugin:outputPlugins)
482  {
483  if(!outputPlugin.second.getNode("Status").getValue<bool>())
484  PUSHCOMMENT;
485 
486  OUT << outputPlugin.second.getNode("outputKey").getValue() <<
487  ": {\n";
488  PUSHTAB;
489  OUT << "module_type: " <<
490  outputPlugin.second.getNode("outputModuleType").getValue() <<
491  "\n";
492  auto pluginParameterLink = outputPlugin.second.getNode("outputModuleParameterLink");
493  if(!pluginParameterLink.isDisconnected())
494  {
495  auto pluginParameters = pluginParameterLink.getChildren();
496  for(auto &pluginParameter:pluginParameters)
497  {
498  if(!pluginParameter.second.getNode("Status").getValue<bool>())
499  PUSHCOMMENT;
500 
501  auto comment = pluginParameter.second.getNode("CommentDescription");
502  OUT << pluginParameter.second.getNode("outputParameterKey").getValue() <<
503  ": " <<
504  pluginParameter.second.getNode("outputParameterValue").getValue()
505  <<
506  (comment.isDefaultValue()?"":("\t # " + comment.getValue())) <<
507  "\n";
508 
509  if(!pluginParameter.second.getNode("Status").getValue<bool>())
510  POPCOMMENT;
511  }
512  }
513  POPTAB;
514  OUT << "}\n\n"; //end output module
515 
516  if(!outputPlugin.second.getNode("Status").getValue<bool>())
517  POPCOMMENT;
518  }
519 
520  POPTAB;
521  OUT << "}\n\n"; //end outputs
522  }
523 
524 
525  //--------------------------------------
526  //handle physics
527  auto physics = aggregatorNode.getNode("physicsLink");
528  if(!physics.isDisconnected())
529  {
531  OUT << "physics: {\n";
532 
533  PUSHTAB;
534 
535  auto analyzers = physics.getNode("analyzersLink");
536  if(!analyzers.isDisconnected())
537  {
539  OUT << "analyzers: {\n";
540 
541  PUSHTAB;
542  auto modules = analyzers.getChildren();
543  for(auto &module:modules)
544  {
545  if(!module.second.getNode("Status").getValue<bool>())
546  PUSHCOMMENT;
547 
548  OUT << module.second.getNode("analyzerKey").getValue() <<
549  ": {\n";
550  PUSHTAB;
551  OUT << "module_type: " <<
552  module.second.getNode("analyzerModuleType").getValue() <<
553  "\n";
554  auto moduleParameterLink = module.second.getNode("analyzerModuleParameterLink");
555  if(!moduleParameterLink.isDisconnected())
556  {
557  auto moduleParameters = moduleParameterLink.getChildren();
558  for(auto &moduleParameter:moduleParameters)
559  {
560  if(!moduleParameter.second.getNode("Status").getValue<bool>())
561  PUSHCOMMENT;
562 
563  auto comment = moduleParameter.second.getNode("CommentDescription");
564  OUT << moduleParameter.second.getNode("analyzerParameterKey").getValue() <<
565  ": " <<
566  moduleParameter.second.getNode("analyzerParameterValue").getValue()
567  <<
568  (comment.isDefaultValue()?"":("\t # " + comment.getValue())) <<
569  "\n";
570 
571  if(!moduleParameter.second.getNode("Status").getValue<bool>())
572  POPCOMMENT;
573  }
574  }
575  POPTAB;
576  OUT << "}\n\n"; //end analyzer module
577 
578  if(!module.second.getNode("Status").getValue<bool>())
579  POPCOMMENT;
580  }
581  POPTAB;
582  OUT << "}\n\n"; //end analyzer
583  }
584 
585  auto producers = physics.getNode("producersLink");
586  if(!producers.isDisconnected())
587  {
589  OUT << "producers: {\n";
590 
591  PUSHTAB;
592  auto modules = producers.getChildren();
593  for(auto &module:modules)
594  {
595  if(!module.second.getNode("Status").getValue<bool>())
596  PUSHCOMMENT;
597 
598  OUT << module.second.getNode("producerKey").getValue() <<
599  ": {\n";
600  PUSHTAB;
601  OUT << "module_type: " <<
602  module.second.getNode("producerModuleType").getValue() <<
603  "\n";
604  auto moduleParameterLink = module.second.getNode("producerModuleParameterLink");
605  if(!moduleParameterLink.isDisconnected())
606  {
607  auto moduleParameters = moduleParameterLink.getChildren();
608  for(auto &moduleParameter:moduleParameters)
609  {
610  if(!moduleParameter.second.getNode("Status").getValue<bool>())
611  PUSHCOMMENT;
612 
613  auto comment = moduleParameter.second.getNode("CommentDescription");
614  OUT << moduleParameter.second.getNode("producerParameterKey").getValue() <<
615  ":" <<
616  moduleParameter.second.getNode("producerParameterValue").getValue()
617  <<
618  (comment.isDefaultValue()?"":("\t # " + comment.getValue())) <<
619  "\n";
620 
621  if(!moduleParameter.second.getNode("Status").getValue<bool>())
622  POPCOMMENT;
623  }
624  }
625  POPTAB;
626  OUT << "}\n\n"; //end producer module
627 
628  if(!module.second.getNode("Status").getValue<bool>())
629  POPCOMMENT;
630  }
631  POPTAB;
632  OUT << "}\n\n"; //end producer
633  }
634 
635 
636  auto filters = physics.getNode("filtersLink");
637  if(!filters.isDisconnected())
638  {
640  OUT << "filters: {\n";
641 
642  PUSHTAB;
643  auto modules = filters.getChildren();
644  for(auto &module:modules)
645  {
646  if(!module.second.getNode("Status").getValue<bool>())
647  PUSHCOMMENT;
648 
649  OUT << module.second.getNode("filterKey").getValue() <<
650  ": {\n";
651  PUSHTAB;
652  OUT << "module_type: " <<
653  module.second.getNode("filterModuleType").getValue() <<
654  "\n";
655  auto moduleParameterLink = module.second.getNode("filterModuleParameterLink");
656  if(!moduleParameterLink.isDisconnected())
657  {
658  auto moduleParameters = moduleParameterLink.getChildren();
659  for(auto &moduleParameter:moduleParameters)
660  {
661  if(!moduleParameter.second.getNode("Status").getValue<bool>())
662  PUSHCOMMENT;
663 
664  auto comment = moduleParameter.second.getNode("CommentDescription");
665  OUT << moduleParameter.second.getNode("filterParameterKey").getValue()
666  << ": " <<
667  moduleParameter.second.getNode("filterParameterValue").getValue()
668  <<
669  (comment.isDefaultValue()?"":("\t # " + comment.getValue())) <<
670  "\n";
671 
672  if(!moduleParameter.second.getNode("Status").getValue<bool>())
673  POPCOMMENT;
674  }
675  }
676  POPTAB;
677  OUT << "}\n\n"; //end filter module
678 
679  if(!module.second.getNode("Status").getValue<bool>())
680  POPCOMMENT;
681  }
682  POPTAB;
683  OUT << "}\n\n"; //end filter
684  }
685 
686 
687  auto otherParameterLink = physics.getNode("physicsOtherParametersLink");
688  if(!otherParameterLink.isDisconnected())
689  {
691  auto physicsParameters = otherParameterLink.getChildren();
692  for(auto &parameter:physicsParameters)
693  {
694  if(!parameter.second.getNode("Status").getValue<bool>())
695  PUSHCOMMENT;
696 
697  auto comment = parameter.second.getNode("CommentDescription");
698  OUT << parameter.second.getNode("physicsParameterKey").getValue() <<
699  ": " <<
700  parameter.second.getNode("physicsParameterValue").getValue()
701  <<
702  (comment.isDefaultValue()?"":("\t # " + comment.getValue())) <<
703  "\n";
704 
705  if(!parameter.second.getNode("Status").getValue<bool>())
706  POPCOMMENT;
707  }
708  }
709  POPTAB;
710  OUT << "}\n\n"; //end physics
711  }
712 
713 
714  //--------------------------------------
715  //handle process_name
716  OUT << "process_name: " <<
717  aggregatorNode.getNode("ARTDAQGlobalConfigurationForProcessNameLink/processNameForAggregators")
718  << "\n";
719 
720 
721 
722 
723  out.close();
724 }
725 
726 DEFINE_OTS_CONFIGURATION(ARTDAQAggregatorConfiguration)