Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4DetectorGroupSubsystem.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4DetectorGroupSubsystem.cc
2 
3 #include <g4main/PHG4Subsystem.h> // for PHG4Subsystem
4 
5 #include <phparameter/PHParameters.h>
6 #include <phparameter/PHParametersContainer.h>
7 
8 #include <pdbcalbase/PdbParameterMapContainer.h>
9 
10 #include <phool/PHCompositeNode.h>
11 #include <phool/PHDataNode.h>
12 #include <phool/PHNode.h> // for PHNode
13 #include <phool/PHNodeIterator.h>
14 #include <phool/getClass.h>
15 #include <phool/phool.h>
16 
17 #include <TSystem.h>
18 
19 #include <boost/format.hpp>
20 
21 // boost stacktrace has shadowed variables
22 #pragma GCC diagnostic push
23 #pragma GCC diagnostic ignored "-Wshadow"
24 #include <boost/stacktrace.hpp>
25 #pragma GCC diagnostic pop
26 
27 #include <cassert> // for assert
28 #include <cstdlib> // for exit
29 #include <iostream>
30 #include <sstream>
31 
33  : PHG4Subsystem(name)
34  , m_ParamsContainerDefault(new PHParametersContainer(Name()))
35  , m_Layer(lyr)
36 {
37  // put the layer into the name so we get unique names
38  // for multiple layers
39  std::ostringstream nam;
40  nam << name << "_" << lyr;
41  Name(nam.str());
42 }
43 
45 {
46  m_SaveTopNode = topNode;
48  int iret = InitSubsystem(topNode);
49  return iret;
50 }
51 
53 {
54  PHNodeIterator iter(topNode);
55  PHCompositeNode *parNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "PAR"));
56  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
57 
58  std::string g4geonodename = "G4GEO_";
59  std::string paramnodename = "G4GEOPARAM_";
60  std::string calibdetname;
61  int isSuperDetector = 0;
62  if (m_SuperDetector != "NONE")
63  {
64  g4geonodename += SuperDetector();
65  m_ParamsContainer = findNode::getClass<PHParametersContainer>(parNode, g4geonodename);
66  if (!m_ParamsContainer)
67  {
68  PHNodeIterator parIter(parNode);
69  PHCompositeNode *DetNode = dynamic_cast<PHCompositeNode *>(parIter.findFirst("PHCompositeNode", SuperDetector()));
70  if (!DetNode)
71  {
72  DetNode = new PHCompositeNode(SuperDetector());
73  parNode->addNode(DetNode);
74  }
76  DetNode->addNode(new PHDataNode<PHParametersContainer>(m_ParamsContainer, g4geonodename));
77  }
78  paramnodename += m_SuperDetector;
79  calibdetname = m_SuperDetector;
80  isSuperDetector = 1;
81  }
82  else
83  {
85  g4geonodename += m_ParamsContainer->Name();
86  parNode->addNode(new PHDataNode<PHParametersContainer>(m_ParamsContainer, g4geonodename));
87  paramnodename += m_ParamsContainer->Name();
88  calibdetname = m_ParamsContainer->Name();
89  }
90 
92  for (PHParametersContainer::ConstIterator piter = begin_end.first; piter != begin_end.second; ++piter)
93  {
94  m_ParamsContainer->AddPHParameters(piter->first, piter->second);
95  }
96  // the content has been handed off to the param container on the node tree
97  // clear our internal map of parameters and delete it to avoid it being used accidentally
100  m_ParamsContainerDefault = nullptr;
101  // ASSUMPTION: if we read from DB and/or file we don't want the stuff from
102  // the node tree
103  // We leave the defaults intact in case there is no entry for
104  // those in the object read from the DB or file
105  // Order: read first DB, then calib file if both are enabled
107  {
108  if (ReadDB())
109  {
110  ReadParamsFromDB(calibdetname, isSuperDetector);
111  }
113  {
114  ReadParamsFromFile(calibdetname, get_filetype(), isSuperDetector);
115  }
116  }
117  else
118  {
119  // if not filled from file or DB, check if we have a node containing those calibrations
120  // on the node tree and load them (the embedding wants to use the
121  // parameters saved on the previous pass)
122  PdbParameterMapContainer *nodeparams = findNode::getClass<PdbParameterMapContainer>(topNode, paramnodename);
123  if (nodeparams)
124  {
125  m_ParamsContainer->FillFrom(nodeparams);
126  }
127  }
128  // parameters set in the macro always override whatever is read from
129  // the node tree, DB or file
131  // save updated persistant copy on node tree
132  PHCompositeNode *RunDetNode = runNode;
133  if (m_SuperDetector != "NONE")
134  {
135  PHNodeIterator runIter(runNode);
136  RunDetNode = dynamic_cast<PHCompositeNode *>(runIter.findFirst("PHCompositeNode", SuperDetector()));
137  if (!RunDetNode)
138  {
139  RunDetNode = new PHCompositeNode(SuperDetector());
140  runNode->addNode(RunDetNode);
141  }
142  }
143  m_ParamsContainer->SaveToNodeTree(RunDetNode, paramnodename);
144  // define the materials for the detector
145  // at this point all flags are known so materials set in the macro can
146  // be implemented here
147  DefineMaterials();
148  int iret = InitRunSubsystem(topNode);
149  m_ParamsContainer->UpdateNodeTree(RunDetNode, paramnodename);
150  if (Verbosity() > 0)
151  {
152  PdbParameterMapContainer *nodeparams = findNode::getClass<PdbParameterMapContainer>(topNode, paramnodename);
153  std::cout << Name() << std::endl;
154  nodeparams->print();
155  }
157  return iret;
158 }
159 
161 {
163  return;
164 }
165 
166 double PHG4DetectorGroupSubsystem::get_double_param(const int detid, const std::string &name) const
167 {
168  const PHParameters *params = m_ParamsContainer->GetParameters(detid);
169  if (params)
170  {
171  return params->get_double_param(name);
172  }
173  else
174  {
175  std::cout << PHWHERE << " no parameters for detid " << detid << std::endl;
176  gSystem->Exit(1);
177  exit(1);
178  }
179 }
180 
182 {
183  const PHParameters *params = m_ParamsContainer->GetParameters(detid);
184  if (params)
185  {
186  return params->get_int_param(name);
187  }
188  else
189  {
190  std::cout << PHWHERE << " no parameters for detid " << detid << std::endl;
191  gSystem->Exit(1);
192  exit(1);
193  }
194 }
195 
198 {
199  const PHParameters *params = m_ParamsContainer->GetParameters(detid);
200  if (params)
201  {
202  return params->get_string_param(name);
203  }
204  else
205  {
206  std::cout << PHWHERE << " no parameters for detid " << detid << std::endl;
207  gSystem->Exit(1);
208  exit(1);
209  }
210 }
211 
212 void PHG4DetectorGroupSubsystem::set_double_param(const int detid, const std::string &name, const double dval)
213 {
214  auto iter = m_DefaultDoubleParamsMap.find(detid);
215  if (iter == m_DefaultDoubleParamsMap.end())
216  {
217  std::cout << "called like set_double_param(" << detid << ", \""
218  << name << "\", " << dval << ")" << std::endl;
219  std::cout << "detid " << detid << " not implemented" << std::endl;
220  std::cout << "implemented detector ids: " << std::endl;
221  for (auto &iter2 : m_DefaultDoubleParamsMap)
222  {
223  std::cout << "detid: " << iter2.first << std::endl;
224  }
225  return;
226  }
227  if (iter->second.find(name) == iter->second.end())
228  {
229  std::cout << "double parameter " << name << " not implemented for detid "
230  << detid << std::endl;
231  std::cout << "implemented double parameters are:" << std::endl;
232  for (auto &iter2 : iter->second)
233  {
234  std::cout << iter2.first << std::endl;
235  }
236  return;
237  }
238  // here we know we have entries for the detector id and the variable name exists
239  // in the defaults, so now lets set it
240  // with C++11 insert returns a pair of an iterator to the element and
241  // a boolean if the object was inserted or if it already exist (in which case it
242  // does not get replaced). We do not check this because we do not care if a new map
243  // was inserted or not. All we need is the iterator to it
244  std::map<const std::string, double> newdmap;
245  auto ret = m_MacroDoubleParamsMap.insert(make_pair(detid, newdmap));
246  // here we use the operator [] rather than insert because we
247  // want to create a new entry if [name] does not exist. If it does
248  // exist we want to overwrite it (so even if a parameter is set twice,
249  // the last setting in the macro is used). Using insert would preserve the first
250  // parameter setting
251  ret.first->second[name] = dval;
252  return;
253 }
254 
255 void PHG4DetectorGroupSubsystem::set_int_param(const int detid, const std::string &name, const int ival)
256 {
257  auto iter = m_DefaultIntegerParamsMap.find(detid);
258  if (iter == m_DefaultIntegerParamsMap.end())
259  {
260  std::cout << "called like set_int_param(" << detid << ", \""
261  << name << "\", " << ival << ")" << std::endl;
262  std::cout << "detid " << detid << " not implemented" << std::endl;
263  std::cout << "implemented detector ids: " << std::endl;
264  for (auto &iter2 : m_DefaultIntegerParamsMap)
265  {
266  std::cout << "detid: " << iter2.first << std::endl;
267  }
268  return;
269  }
270  if (iter->second.find(name) == iter->second.end())
271  {
272  std::cout << "int parameter " << name << " not implemented for detid"
273  << detid << std::endl;
274  std::cout << "implemented int parameters are:" << std::endl;
275  for (auto &iter2 : iter->second)
276  {
277  std::cout << iter2.first << std::endl;
278  }
279  return;
280  }
281  // here we know we have entries for the detector id and the variable name exists
282  // in the defaults, so now lets set it
283  std::map<const std::string, int> newintmap;
284  auto ret = m_MacroIntegerParamsMap.insert(make_pair(detid, newintmap));
285  // here we use the operator [] rather than insert because we
286  // want to create a new entry if [name] does not exist. If it does
287  // exist we want to overwrite it (so even if a parameter is set twice,
288  // the last setting in the macro is used). Using insert would preserve the first
289  // parameter setting
290  ret.first->second[name] = ival;
291 }
292 
294 {
295  auto iter = m_DefaultStringParamsMap.find(detid);
296  if (iter == m_DefaultStringParamsMap.end())
297  {
298  std::cout << "called like set_string_param(" << detid << ", \""
299  << name << "\", " << sval << ")" << std::endl;
300  std::cout << "detid " << detid << " not implemented" << std::endl;
301  std::cout << "implemented detector ids: " << std::endl;
302  for (auto &iter2 : m_DefaultStringParamsMap)
303  {
304  std::cout << "detid: " << iter2.first << std::endl;
305  }
306  return;
307  }
308  if (iter->second.find(name) == iter->second.end())
309  {
310  std::cout << "string parameter " << name << " not implemented for detid "
311  << detid << std::endl;
312  std::cout << "implemented string parameters are:" << std::endl;
313  for (auto &iter2 : iter->second)
314  {
315  std::cout << iter2.first << std::endl;
316  }
317  return;
318  }
319  // here we know we have entries for the detector id and the variable name exists
320  // in the defaults, so now lets set it
321 
322  // with C++11 insert returns a pair of an iterator to the element and
323  // a boolean if the object was inserted or if it already exist (in which case it
324  // does not get replaced). We do not check this because we do not care if a new map
325  // was inserted or not. All we need is the iterator to it
326  std::map<const std::string, std::string> newdmap;
327  auto ret = m_MacroStringParamsMap.insert(make_pair(detid, newdmap));
328  // here we use the operator [] rather than insert because we
329  // want to create a new entry if [name] does not exist. If it does
330  // exist we want to overwrite it (so even if a parameter is set twice,
331  // the last setting in the macro is used). Using insert would preserve the first
332  // parameter setting
333  ret.first->second[name] = sval;
334  return;
335 }
336 
338 {
339  for (auto &iter1 : m_MacroDoubleParamsMap)
340  {
341  PHParameters *params = GetParamsContainer()->GetParametersToModify(iter1.first);
342  for (auto &iter2 : iter1.second)
343  {
344  params->set_double_param(iter2.first, iter2.second);
345  }
346  }
347 
348  for (auto &iter1 : m_MacroIntegerParamsMap)
349  {
350  PHParameters *params = GetParamsContainer()->GetParametersToModify(iter1.first);
351  for (auto &iter2 : iter1.second)
352  {
353  params->set_int_param(iter2.first, iter2.second);
354  }
355  }
356 
357  for (auto &iter1 : m_MacroStringParamsMap)
358  {
359  PHParameters *params = GetParamsContainer()->GetParametersToModify(iter1.first);
360  for (auto &iter2 : iter1.second)
361  {
362  params->set_string_param(iter2.first, iter2.second);
363  }
364  }
365  return;
366 }
367 
368 // all set_default_XXX_param methods work the same way
369 // They use the returned pair <iterator, bool> for c++11 map.insert. The boolean tells us
370 // if a new element was inserted (true) or an iterator to the exisiting one is returned (false)
371 // map.insert does not overwrite existing entries. So what we are doing here is
372 // get an iterator to the double/int/string map for a given detector (for us it does not
373 // matter if it already exists or a new one is inserted, we just need an iterator to it)
374 // Then we use map.insert to insert the new double/int/string parameter into the
375 // double/int/string map. If
376 // the return boolean is false, it means an entry for this parameter already exists
377 // which is just bad (means you called set_default_XXX_param for the same parameter
378 // twice in your code), so tell the user to fix the code and exit
379 
380 void PHG4DetectorGroupSubsystem::set_default_double_param(const int detid, const std::string &name, const double dval)
381 {
382  std::map<const std::string, double> newdoublemap;
383  auto ret = m_DefaultDoubleParamsMap.insert(make_pair(detid, newdoublemap));
384  auto ret2 = ret.first->second.insert(make_pair(name, dval));
385  if (ret2.second == false)
386  {
387  std::cout << PHWHERE << "Default double Parameter " << name
388  << " for detid " << detid << " already set to "
389  << ret.first->second[name] << " will not overwrite with " << dval << std::endl;
390  std::cout << "Means: You are calling set_default_double_param twice for the same parameter" << std::endl;
391  std::cout << "Please make up your mind and call it only once using the correct default" << std::endl;
392  gSystem->Exit(1);
393  exit(1);
394  }
395  return;
396 }
397 
398 void PHG4DetectorGroupSubsystem::set_default_int_param(const int detid, const std::string &name, const int ival)
399 {
400  std::map<const std::string, int> newintmap;
401  auto ret = m_DefaultIntegerParamsMap.insert(make_pair(detid, newintmap));
402  auto ret2 = ret.first->second.insert(make_pair(name, ival));
403  if (ret2.second == false)
404  {
405  std::cout << PHWHERE << "Default integer Parameter " << name
406  << " for detid " << detid << " already set to "
407  << ret.first->second[name] << " will not overwrite with " << ival << std::endl;
408  std::cout << "Means: You are calling set_default_int_param twice for the same parameter" << std::endl;
409  std::cout << "Please make up your mind and call it only once using the correct default" << std::endl;
410  gSystem->Exit(1);
411  exit(1);
412  }
413  return;
414 }
415 
417 {
418  std::map<const std::string, std::string> newstringmap;
419  auto ret = m_DefaultStringParamsMap.insert(make_pair(detid, newstringmap));
420  auto ret2 = ret.first->second.insert(make_pair(name, sval));
421  if (ret2.second == false)
422  {
423  std::cout << PHWHERE << "Default String Parameter " << name
424  << " for detid " << detid << " already set to "
425  << ret.first->second[name] << " will not overwrite with " << sval << std::endl;
426  std::cout << "Means: You are calling set_default_string_param twice for the same parameter" << std::endl;
427  std::cout << "Please make up your mind and call it only once using the correct default" << std::endl;
428  gSystem->Exit(1);
429  exit(1);
430  }
431  return;
432 }
433 
435 {
436  for (auto &iter : m_LayerSet)
437  {
438  set_default_int_param(iter, "absorberactive", 0);
439  set_default_int_param(iter, "absorbertruth", 0);
440  set_default_int_param(iter, "blackhole", 0);
441  set_default_int_param(iter, "supportactive", 0);
442  }
443  SetDefaultParameters(); // call method from specific subsystem
444  // now load those parameters to our params class
445  for (const auto &iter1 : m_DefaultDoubleParamsMap)
446  {
447  PHParameters *detidparams = m_ParamsContainerDefault->GetParametersToModify(iter1.first);
448  if (!detidparams)
449  {
450  detidparams = new PHParameters((boost::format("%s_%d") % Name() % iter1.first).str());
451  m_ParamsContainerDefault->AddPHParameters(iter1.first, detidparams);
452  }
453  for (auto &iter2 : iter1.second)
454  {
455  detidparams->set_double_param(iter2.first, iter2.second);
456  }
457  }
458 
459  for (auto &iter1 : m_DefaultIntegerParamsMap)
460  {
461  PHParameters *detidparams = m_ParamsContainerDefault->GetParametersToModify(iter1.first);
462  if (!detidparams)
463  {
464  detidparams = new PHParameters((boost::format("%s_%d") % Name() % iter1.first).str());
465  m_ParamsContainerDefault->AddPHParameters(iter1.first, detidparams);
466  }
467  for (auto &iter2 : iter1.second)
468  {
469  detidparams->set_int_param(iter2.first, iter2.second);
470  }
471  }
472 
473  for (auto &iter1 : m_DefaultStringParamsMap)
474  {
475  PHParameters *detidparams = m_ParamsContainerDefault->GetParametersToModify(iter1.first);
476  if (!detidparams)
477  {
478  detidparams = new PHParameters((boost::format("%s_%d") % Name() % iter1.first).str());
479  m_ParamsContainerDefault->AddPHParameters(iter1.first, detidparams);
480  }
481  for (auto &iter2 : iter1.second)
482  {
483  detidparams->set_string_param(iter2.first, iter2.second);
484  }
485  }
486 }
487 
489 {
490  int iret = 0;
492  iret = m_ParamsContainer->WriteToDB();
493  if (iret)
494  {
495  std::cout << "problem committing to DB" << std::endl;
496  }
497  return iret;
498 }
499 
500 int PHG4DetectorGroupSubsystem::ReadParamsFromDB(const std::string & /*name*/, const int /*issuper*/)
501 {
502  int iret = 1;
503  // if (issuper)
504  // {
505  // iret = params->ReadFromDB(name,layer);
506  // }
507  // else
508  // {
509  // iret = params->ReadFromDB();
510  // }
511  // if (iret)
512  std::cout << boost::stacktrace::stacktrace();
513  std::cout << std::endl
514  << "DO NOT PANIC - this is not a segfault" << std::endl;
515  std::cout << "This method is a dummy, tell the offline gurus about it and give this stack trace" << std::endl;
516  {
517  std::cout << "problem reading from DB" << std::endl;
518  }
519  gSystem->Exit(1);
520  return iret;
521 }
522 
524 {
526  switch (ftyp)
527  {
528  case xml:
529  extension = "xml";
530  break;
531  case root:
532  extension = "root";
533  break;
534  default:
535  std::cout << PHWHERE << "filetype " << ftyp << " not implemented" << std::endl;
536  exit(1);
537  }
538  int iret = 0;
540  iret = m_ParamsContainer->WriteToFile(extension, m_CalibFileDir);
541  if (iret)
542  {
543  std::cout << "problem saving to " << extension << " file " << std::endl;
544  }
545  return iret;
546 }
547 
549 {
551  switch (ftyp)
552  {
553  case xml:
554  extension = "xml";
555  break;
556  case root:
557  extension = "root";
558  break;
559  default:
560  std::cout << PHWHERE << "filetype " << ftyp << " not implemented" << std::endl;
561  exit(1);
562  }
563  int iret = 1;
564  // int iret = params->ReadFromFile(name, extension, layer, issuper, m_CalibFileDir);
565  // if (iret)
566  std::cout << boost::stacktrace::stacktrace();
567  std::cout << std::endl
568  << "DO NOT PANIC - this is not a segfault" << std::endl;
569  std::cout << "This method is a dummy, tell the offline gurus about it and give this stack trace" << std::endl;
570  std::cout << "problem reading from " << extension << " file " << std::endl;
571  std::cout << "problem reading from DB" << std::endl;
572  gSystem->Exit(1);
573  return iret;
574 }
575 
576 void PHG4DetectorGroupSubsystem::SetActive(const int detid, const int i)
577 {
578  set_int_param(detid, "active", i);
579 }
580 
582 {
583  for (auto &detid : m_LayerSet)
584  {
585  set_int_param(detid, "active", i);
586  }
587 }
588 
589 void PHG4DetectorGroupSubsystem::SetAbsorberActive(const int detid, const int i)
590 {
591  set_int_param(detid, "absorberactive", i);
592 }
593 
595 {
596  for (auto &detid : m_LayerSet)
597  {
598  set_int_param(detid, "absorberactive", i);
599  }
600 }
601 
602 void PHG4DetectorGroupSubsystem::SetSupportActive(const int detid, const int i)
603 {
604  set_int_param(detid, "supportactive", i);
605 }
606 
608 {
609  for (auto &detid : m_LayerSet)
610  {
611  set_int_param(detid, "supportactive", i);
612  }
613 }
614 
615 void PHG4DetectorGroupSubsystem::BlackHole(const int detid, const int i)
616 {
617  set_int_param(detid, "blackhole", i);
618 }
619 
621 {
622  for (auto &detid : m_LayerSet)
623  {
624  set_int_param(detid, "blackhole", i);
625  }
626 }
627 
628 void PHG4DetectorGroupSubsystem::SetAbsorberTruth(const int detid, const int i)
629 {
630  set_int_param(detid, "absorbertruth", i);
631 }
632 
634 {
635  for (auto &detid : m_LayerSet)
636  {
637  set_int_param(detid, "absorbertruth", i);
638  }
639 }
640 
642 {
643  std::cout << "Default Parameters: " << std::endl;
644  std::cout << "int values: " << std::endl;
645  for (auto &iter1 : m_DefaultIntegerParamsMap)
646  {
647  std::cout << "Detector id: " << iter1.first << std::endl;
648  for (auto &iter2 : iter1.second)
649  {
650  std::cout << iter2.first << " : " << iter2.second << std::endl;
651  }
652  }
653  std::cout << "double values: " << std::endl;
654  for (auto &iter1 : m_DefaultDoubleParamsMap)
655  {
656  std::cout << "Detector id: " << iter1.first << std::endl;
657  for (auto &iter2 : iter1.second)
658  {
659  std::cout << iter2.first << " : " << iter2.second << std::endl;
660  }
661  }
662  std::cout << "string values: " << std::endl;
663  for (auto &iter1 : m_DefaultStringParamsMap)
664  {
665  std::cout << "Detector id: " << iter1.first << std::endl;
666  for (auto &iter2 : iter1.second)
667  {
668  std::cout << iter2.first << " : " << iter2.second << std::endl;
669  }
670  }
671  return;
672 }
673 
675 {
676  std::cout << "Macro Parameters: " << std::endl;
677  std::cout << "int values: " << std::endl;
678  for (auto &iter1 : m_MacroIntegerParamsMap)
679  {
680  std::cout << "Detector id: " << iter1.first << std::endl;
681  for (auto &iter2 : iter1.second)
682  {
683  std::cout << iter2.first << " : " << iter2.second << std::endl;
684  }
685  }
686  std::cout << "double values: " << std::endl;
687  for (auto &iter1 : m_MacroDoubleParamsMap)
688  {
689  std::cout << "Detector id: " << iter1.first << std::endl;
690  for (auto &iter2 : iter1.second)
691  {
692  std::cout << iter2.first << " : " << iter2.second << std::endl;
693  }
694  }
695  std::cout << "string values: " << std::endl;
696  for (auto &iter1 : m_MacroStringParamsMap)
697  {
698  std::cout << "Detector id: " << iter1.first << std::endl;
699  for (auto &iter2 : iter1.second)
700  {
701  std::cout << iter2.first << " : " << iter2.second << std::endl;
702  }
703  }
704  return;
705 }