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