Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4Reco.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4Reco.cc
1 #include "PHG4Reco.h"
2 
3 #include "Fun4AllMessenger.h"
5 #include "PHG4DisplayAction.h"
6 #include "PHG4InEvent.h"
7 #include "PHG4PhenixDetector.h"
14 #include "PHG4Subsystem.h"
15 #include "PHG4TrackingAction.h"
16 #include "PHG4UIsession.h"
17 #include "PHG4Utils.h"
18 
19 #include <g4decayer/EDecayType.hh>
21 
23 
24 #include <phgeom/PHGeomUtility.h>
25 
27 
28 #include <phfield/PHFieldConfig.h> // for PHFieldConfig
29 #include <phfield/PHFieldConfigv1.h>
30 #include <phfield/PHFieldConfigv2.h>
31 #include <phfield/PHFieldUtility.h>
32 
34 
36 #include <fun4all/Fun4AllServer.h>
37 #include <fun4all/SubsysReco.h> // for SubsysReco
38 
39 #include <phool/PHCompositeNode.h>
40 #include <phool/PHDataNode.h> // for PHDataNode
41 #include <phool/PHNode.h> // for PHNode
42 #include <phool/PHNodeIterator.h> // for PHNodeIterator
43 #include <phool/PHObject.h> // for PHObject
44 #include <phool/PHRandomSeed.h>
45 #include <phool/getClass.h>
46 #include <phool/phool.h> // for PHWHERE
47 #include <phool/recoConsts.h>
48 
49 #include <TSystem.h> // for TSystem, gSystem
50 
51 #include <CLHEP/Random/Random.h>
52 
53 #include <G4HadronicParameters.hh> // for G4HadronicParameters
54 #include <Geant4/G4Cerenkov.hh>
55 #include <Geant4/G4Element.hh> // for G4Element
56 #include <Geant4/G4EventManager.hh> // for G4EventManager
57 #include <Geant4/G4HadronicProcessStore.hh>
58 #include <Geant4/G4IonisParamMat.hh> // for G4IonisParamMat
59 #include <Geant4/G4LossTableManager.hh>
60 #include <Geant4/G4Material.hh>
61 #include <Geant4/G4NistManager.hh>
62 #include <Geant4/G4OpAbsorption.hh>
63 #include <Geant4/G4OpBoundaryProcess.hh>
64 #include <Geant4/G4OpMieHG.hh>
65 #include <Geant4/G4OpRayleigh.hh>
66 #include <Geant4/G4OpWLS.hh>
67 #include <Geant4/G4OpticalPhoton.hh>
68 #include <Geant4/G4ParticleDefinition.hh>
69 #include <Geant4/G4ParticleTable.hh>
70 #include <Geant4/G4PhotoElectricEffect.hh> // for G4PhotoElectricEffect
71 #include <Geant4/G4ProcessManager.hh>
72 #include <Geant4/G4RunManager.hh>
73 #include <Geant4/G4Scintillation.hh>
74 #include <Geant4/G4StepLimiterPhysics.hh>
75 #include <Geant4/G4String.hh> // for G4String
76 #include <Geant4/G4SystemOfUnits.hh>
77 #include <Geant4/G4Types.hh> // for G4double, G4int
78 #include <Geant4/G4UIExecutive.hh>
79 #include <Geant4/G4UImanager.hh>
80 #include <Geant4/G4UImessenger.hh> // for G4UImessenger
81 #include <Geant4/G4VModularPhysicsList.hh> // for G4VModularPhysicsList
82 #include <Geant4/G4Version.hh>
83 #include <Geant4/G4VisExecutive.hh>
84 #include <Geant4/G4VisManager.hh> // for G4VisManager
85 #include <Geant4/Randomize.hh> // for G4Random
86 
87 // physics lists
88 #include <Geant4/FTFP_BERT.hh>
89 #include <Geant4/FTFP_BERT_HP.hh>
90 #include <Geant4/FTFP_INCLXX.hh>
91 #include <Geant4/FTFP_INCLXX_HP.hh>
92 #include <Geant4/QGSP_BERT.hh>
93 #include <Geant4/QGSP_BERT_HP.hh>
94 #include <Geant4/QGSP_BIC.hh>
95 #include <Geant4/QGSP_BIC_HP.hh>
96 #include <Geant4/QGSP_INCLXX.hh>
97 #include <Geant4/QGSP_INCLXX_HP.hh>
98 
99 #include <cassert>
100 #include <cstdlib>
101 #include <exception> // for exception
102 #include <iostream> // for operator<<, endl
103 #include <memory>
104 
105 class G4EmSaturation;
106 class G4TrackingManager;
107 class G4VPhysicalVolume;
108 class PHField;
109 class PHG4EventAction;
110 class PHG4StackingAction;
111 class PHG4SteppingAction;
112 
113 //_________________________________________________________________
115  : SubsysReco(name)
116  , m_Fun4AllMessenger(new Fun4AllMessenger(Fun4AllServer::instance()))
117 {
118  return;
119 }
120 
121 //_________________________________________________________________
123 {
124  // one can delete null pointer (it results in a nop), so checking if
125  // they are non zero is not needed
126  delete m_Field;
127  delete m_RunManager;
128  delete m_UISession;
129  delete m_VisManager;
130  delete m_Fun4AllMessenger;
131  while (m_SubsystemList.begin() != m_SubsystemList.end())
132  {
133  delete m_SubsystemList.back();
134  m_SubsystemList.pop_back();
135  }
136  delete m_DisplayAction;
137 }
138 
139 //_________________________________________________________________
141 {
142  if (Verbosity() > 0)
143  {
144  std::cout << "========================= PHG4Reco::Init() ================================" << std::endl;
145  }
146  unsigned int iseed = PHRandomSeed();
147  G4Seed(iseed); // fixed seed handled in PHRandomSeed()
148 
149  // create GEANT run manager
150  if (Verbosity() > 1)
151  {
152  std::cout << "PHG4Reco::Init - create run manager" << std::endl;
153  }
154 
155  // redirect GEANT verbosity to nowhere
156  // if (Verbosity() < 1)
157  if (false)
158  {
159  G4UImanager *uimanager = G4UImanager::GetUIpointer();
160  m_UISession = new PHG4UIsession();
161  uimanager->SetSession(m_UISession);
162  uimanager->SetCoutDestination(m_UISession);
163  }
164 
165  m_RunManager = new G4RunManager();
166 
167  DefineMaterials();
168  // create physics processes
169  G4VModularPhysicsList *myphysicslist = nullptr;
170  if (m_PhysicsList == "FTFP_BERT")
171  {
172  myphysicslist = new FTFP_BERT(Verbosity());
173  }
174  else if (m_PhysicsList == "FTFP_BERT_HP")
175  {
176  setenv("AllowForHeavyElements", "1", 1);
177  myphysicslist = new FTFP_BERT_HP(Verbosity());
178  }
179  else if (m_PhysicsList == "FTFP_INCLXX")
180  {
181  myphysicslist = new FTFP_INCLXX(Verbosity());
182  }
183  else if (m_PhysicsList == "FTFP_INCLXX_HP")
184  {
185  setenv("AllowForHeavyElements", "1", 1);
186  myphysicslist = new FTFP_INCLXX_HP(Verbosity());
187  }
188  else if (m_PhysicsList == "QGSP_BERT")
189  {
190  myphysicslist = new QGSP_BERT(Verbosity());
191  }
192  else if (m_PhysicsList == "QGSP_BERT_HP")
193  {
194  setenv("AllowForHeavyElements", "1", 1);
195  myphysicslist = new QGSP_BERT_HP(Verbosity());
196  }
197  else if (m_PhysicsList == "QGSP_BIC")
198  {
199  myphysicslist = new QGSP_BIC(Verbosity());
200  }
201  else if (m_PhysicsList == "QGSP_BIC_HP")
202  {
203  setenv("AllowForHeavyElements", "1", 1);
204  myphysicslist = new QGSP_BIC_HP(Verbosity());
205  }
206  else if (m_PhysicsList == "QGSP_INCLXX")
207  {
208  myphysicslist = new QGSP_INCLXX(Verbosity());
209  }
210  else if (m_PhysicsList == "QGSP_INCLXX_HP")
211  {
212  setenv("AllowForHeavyElements", "1", 1);
213  myphysicslist = new QGSP_INCLXX_HP(Verbosity());
214  }
215  else
216  {
217  std::cout << "Physics List " << m_PhysicsList << " not implemented" << std::endl;
218  gSystem->Exit(1);
219  exit(1);
220  }
221 
222  if (m_Decayer == kPYTHIA6Decayer)
223  {
224  std::cout << "Use PYTHIA Decayer" << std::endl;
225  G4HadronicParameters::Instance()->SetEnableBCParticles(false); // Disable the Geant4 built in HF Decay and use external decayers for them
228  {
230  }
231  myphysicslist->RegisterPhysics(decayer);
232  }
233 
234  if (m_Decayer == kEvtGenDecayer)
235  {
236  std::cout << "Use EvtGen Decayer" << std::endl;
237  G4HadronicParameters::Instance()->SetEnableBCParticles(false); // Disable the Geant4 built in HF Decay and use external decayers for them
239  if (CustomizeDecay)
240  {
242  }
243 
244  myphysicslist->RegisterPhysics(decayer);
245  }
246 
248  {
249  std::cout << "Use GEANT Internal Decayer" << std::endl;
250  }
251 
252  myphysicslist->RegisterPhysics(new G4StepLimiterPhysics());
253  // initialize cuts so we can ask the world region for it's default
254  // cuts to propagate them to other regions in DefineRegions()
255  myphysicslist->SetCutsWithDefault();
256  m_RunManager->SetUserInitialization(myphysicslist);
257 
258  DefineRegions();
259  // initialize registered subsystems
260  for (SubsysReco *reco : m_SubsystemList)
261  {
262  reco->Init(topNode);
263  }
264 
265  if (Verbosity() > 0)
266  {
267  std::cout << "===========================================================================" << std::endl;
268  }
269  return 0;
270 }
271 
273 {
274  if (Verbosity() > 1)
275  {
276  std::cout << "PHG4Reco::InitField - create magnetic field setup" << std::endl;
277  }
278 
279  std::unique_ptr<PHFieldConfig> default_field_cfg(nullptr);
280 
281  if (m_FieldMapFile == "CDB")
282  {
283  // loading from database
285  default_field_cfg.reset(new PHFieldConfigv1(m_FieldConfigType, url, m_MagneticFieldRescale));
286  }
287  else if (m_FieldMapFile != "NONE")
288  {
290  }
291  else
292  {
293  default_field_cfg.reset(new PHFieldConfigv2(0, 0, m_MagneticField * m_MagneticFieldRescale));
294  }
295 
296  if (Verbosity() > 1)
297  {
298  std::cout << "PHG4Reco::InitField - create magnetic field setup" << std::endl;
299  }
300 
301  PHField *phfield = PHFieldUtility::GetFieldMapNode(default_field_cfg.get(), topNode, Verbosity() + 1);
302  assert(phfield);
303 
304  m_Field = new G4TBMagneticFieldSetup(phfield);
305 
307 }
308 
310 {
311  // this is a dumb protection against executing this twice.
312  // we have cases (currently detector display or material scan) where
313  // we need the detector but have not run any events (who wants to wait
314  // for processing an event if you just want a detector display?).
315  // Then the InitRun is executed from a macro. But if you decide to run events
316  // afterwards, the InitRun is executed by the framework together with all
317  // other modules. This prevents the PHG4Reco::InitRun() to be executed
318  // again in this case
319  static int InitRunDone = 0;
320  if (InitRunDone)
321  {
323  }
324  InitRunDone = 1;
325  if (Verbosity() > 0)
326  {
327  std::cout << "========================= PHG4Reco::InitRun() ================================" << std::endl;
328  }
329 
331 
332  rc->set_StringFlag("WorldMaterial", m_WorldMaterial);
333  // build world material - so in subsequent code we can call
334  // G4Material::GetMaterial(rc->get_StringFlag("WorldMaterial"))
335  // if the world material is not in the nist DB, we need to implement it here
336  G4NistManager::Instance()->FindOrBuildMaterial(m_WorldMaterial);
337  // G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
338  // G4NistManager::Instance()->FindOrBuildMaterial("G4_Be");
339  // G4NistManager::Instance()->FindOrBuildMaterial("G4_Al");
340  // G4NistManager::Instance()->FindOrBuildMaterial("G4_STAINLESS-STEEL");
341  rc->set_FloatFlag("WorldSizex", m_WorldSize[0]);
342  rc->set_FloatFlag("WorldSizey", m_WorldSize[1]);
343  rc->set_FloatFlag("WorldSizez", m_WorldSize[2]);
344 
345  // setup the global field
346  const int field_ret = InitField(topNode);
347  if (field_ret != Fun4AllReturnCodes::EVENT_OK)
348  {
349  std::cout << "PHG4Reco::InitRun- Error - Failed field init with status = " << field_ret << std::endl;
350  return field_ret;
351  }
352 
353  // initialize registered subsystems
354  for (SubsysReco *reco : m_SubsystemList)
355  {
356  if (Verbosity() >= 1)
357  {
358  std::cout << "PHG4Reco::InitRun - " << reco->Name() << "->InitRun" << std::endl;
359  }
360  reco->InitRun(topNode);
361  }
362 
363  // create phenix detector, add subsystems, and register to GEANT
364  // create display settings before detector
366  if (Verbosity() > 1)
367  {
368  std::cout << "PHG4Reco::Init - create detector" << std::endl;
369  }
370  m_Detector = new PHG4PhenixDetector(this);
377 
378  for (PHG4Subsystem *g4sub : m_SubsystemList)
379  {
380  if (g4sub->GetDetector())
381  {
382  m_Detector->AddDetector(g4sub->GetDetector());
383  }
384  }
385  m_RunManager->SetUserInitialization(m_Detector);
386 
388  {
389  std::cout << "PHG4Reco::InitRun - WARNING - event/track/stepping action disabled! "
390  << "This is aimed to reduce resource consumption for G4 running only. E.g. dose analysis. "
391  << "Meanwhile, it will disable all Geant4 based analysis. Toggle this feature on/off with PHG4Reco::setDisableUserActions()" << std::endl;
392  }
393 
394  setupInputEventNodeReader(topNode);
395  // create main event action, add subsystemts and register to GEANT
397 
398  for (PHG4Subsystem *g4sub : m_SubsystemList)
399  {
400  PHG4EventAction *evtact = g4sub->GetEventAction();
401  if (evtact)
402  {
403  m_EventAction->AddAction(evtact);
404  }
405  }
406 
407  if (not m_disableUserActions)
408  {
409  m_RunManager->SetUserAction(m_EventAction);
410  }
411 
412  // create main stepping action, add subsystems and register to GEANT
414  for (PHG4Subsystem *g4sub : m_SubsystemList)
415  {
416  PHG4StackingAction *action = g4sub->GetStackingAction();
417  if (action)
418  {
419  if (Verbosity() > 1)
420  {
421  std::cout << "Adding steppingaction for " << g4sub->Name() << std::endl;
422  }
423  m_StackingAction->AddAction(g4sub->GetStackingAction());
424  }
425  }
426 
427  if (not m_disableUserActions)
428  {
429  m_RunManager->SetUserAction(m_StackingAction);
430  }
431 
432  // create main stepping action, add subsystems and register to GEANT
434  for (PHG4Subsystem *g4sub : m_SubsystemList)
435  {
436  PHG4SteppingAction *action = g4sub->GetSteppingAction();
437  if (action)
438  {
439  if (Verbosity() > 1)
440  {
441  std::cout << "Adding steppingaction for " << g4sub->Name() << std::endl;
442  }
443 
444  m_SteppingAction->AddAction(g4sub->GetSteppingAction());
445  }
446  }
447 
448  if (not m_disableUserActions)
449  {
450  m_RunManager->SetUserAction(m_SteppingAction);
451  }
452 
453  // create main tracking action, add subsystems and register to GEANT
455  for (PHG4Subsystem *g4sub : m_SubsystemList)
456  {
457  m_TrackingAction->AddAction(g4sub->GetTrackingAction());
458 
459  // not all subsystems define a user tracking action
460  if (g4sub->GetTrackingAction())
461  {
462  // make tracking manager accessible within user tracking action if defined
463  if (G4TrackingManager *trackingManager = G4EventManager::GetEventManager()->GetTrackingManager())
464  {
465  g4sub->GetTrackingAction()->SetTrackingManagerPointer(trackingManager);
466  }
467  }
468  }
469 
470  if (not m_disableUserActions)
471  {
472  m_RunManager->SetUserAction(m_TrackingAction);
473  }
474 
475  // initialize
476  m_RunManager->Initialize();
477 
478 #if G4VERSION_NUMBER >= 1033
479  G4EmSaturation *emSaturation = G4LossTableManager::Instance()->EmSaturation();
480  if (!emSaturation)
481  {
482  std::cout << PHWHERE << "Could not initialize EmSaturation, Birks constants will fail" << std::endl;
483  }
484 #endif
485 
486  // add cerenkov and optical photon processes
487  // std::cout << std::endl << "Ignore the next message - we implemented this correctly" << std::endl;
488  G4Cerenkov *theCerenkovProcess = new G4Cerenkov("Cerenkov");
489  // std::cout << "End of bogus warning message" << std::endl << std::endl;
490  G4Scintillation *theScintillationProcess = new G4Scintillation("Scintillation");
491 
492  /*
493  if (Verbosity() > 0)
494  {
495  // This segfaults
496  theCerenkovProcess->DumpPhysicsTable();
497  }
498  */
499  theCerenkovProcess->SetMaxNumPhotonsPerStep(300);
500  theCerenkovProcess->SetMaxBetaChangePerStep(10.0);
501  theCerenkovProcess->SetTrackSecondariesFirst(false); // current PHG4TruthTrackingAction does not support suspect active track and track secondary first
502 #if G4VERSION_NUMBER < 1100
503  theScintillationProcess->SetScintillationYieldFactor(1.0);
504 #endif
505  theScintillationProcess->SetTrackSecondariesFirst(false);
506  // theScintillationProcess->SetScintillationExcitationRatio(1.0);
507 
508  // Use Birks Correction in the Scintillation process
509 
510  // G4EmSaturation* emSaturation = G4LossTableManager::Instance()->EmSaturation();
511  // theScintillationProcess->AddSaturation(emSaturation);
512 
513  G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
514  G4ParticleTable::G4PTblDicIterator *_theParticleIterator;
515  _theParticleIterator = theParticleTable->GetIterator();
516  _theParticleIterator->reset();
517  while ((*_theParticleIterator)())
518  {
519  G4ParticleDefinition *particle = _theParticleIterator->value();
520  G4String particleName = particle->GetParticleName();
521  G4ProcessManager *pmanager = particle->GetProcessManager();
522  if (theCerenkovProcess->IsApplicable(*particle))
523  {
524  pmanager->AddProcess(theCerenkovProcess);
525  pmanager->SetProcessOrdering(theCerenkovProcess, idxPostStep);
526  }
527  if (theScintillationProcess->IsApplicable(*particle))
528  {
529  pmanager->AddProcess(theScintillationProcess);
530  pmanager->SetProcessOrderingToLast(theScintillationProcess, idxAtRest);
531  pmanager->SetProcessOrderingToLast(theScintillationProcess, idxPostStep);
532  }
533  for (PHG4Subsystem *g4sub : m_SubsystemList)
534  {
535  g4sub->AddProcesses(particle);
536  }
537  }
538  G4ProcessManager *pmanager = G4OpticalPhoton::OpticalPhoton()->GetProcessManager();
539  // std::cout << " AddDiscreteProcess to OpticalPhoton " << std::endl;
540  pmanager->AddDiscreteProcess(new G4OpAbsorption());
541  pmanager->AddDiscreteProcess(new G4OpRayleigh());
542  pmanager->AddDiscreteProcess(new G4OpMieHG());
543  pmanager->AddDiscreteProcess(new G4OpBoundaryProcess());
544  pmanager->AddDiscreteProcess(new G4OpWLS());
545  pmanager->AddDiscreteProcess(new G4PhotoElectricEffect());
546  // pmanager->DumpInfo();
547 
548  // needs large amount of memory which kills central hijing events
549  // store generated trajectories
550  // if( G4TrackingManager* trackingManager = G4EventManager::GetEventManager()->GetTrackingManager() ){
551  // trackingManager->SetStoreTrajectory( true );
552  //}
553 
554  // quiet some G4 print-outs (EM and Hadronic settings during first event)
555  G4HadronicProcessStore::Instance()->SetVerbose(0);
556  G4LossTableManager::Instance()->SetVerbose(1);
557 
558  if ((Verbosity() < 1) && (m_UISession))
559  {
560  m_UISession->Verbosity(1); // let messages after setup come through
561  }
562 
563  // Geometry export to DST
565  {
567  std::cout << "PHG4Reco::InitRun - export geometry to DST via tmp file " << filename << std::endl;
568 
569  Dump_GDML(filename);
570 
571  PHGeomUtility::ImportGeomFile(topNode, filename);
572 
574  }
575 
576  if (Verbosity() > 0)
577  {
578  std::cout << "===========================================================================" << std::endl;
579  }
580 
581  // dump geometry to root file
582  if (m_ExportGeometry)
583  {
584  std::cout << "PHG4Reco::InitRun - writing geometry to " << m_ExportGeomFilename << std::endl;
586  }
587 
588  if (PHRandomSeed::Verbosity() >= 2)
589  {
590  // at high verbosity, to save the random number to file
591  G4RunManager::GetRunManager()->SetRandomNumberStore(true);
592  }
593  return 0;
594 }
595 
596 //________________________________________________________________
597 // Dump TGeo File
599 {
601 }
602 
603 //________________________________________________________________
604 // Dump TGeo File using native Geant4 tools
606 {
608 }
609 
610 //_________________________________________________________________
612 {
613  InitUImanager();
614  int iret = m_UImanager->ApplyCommand(cmd.c_str());
615  return iret;
616 }
617 //_________________________________________________________________
618 
620 {
621  // kludge, using boost::dll::program_location().string().c_str() for the
622  // program name and putting it into args lead to invalid reads in G4String
623  char *args[] = {(char *) ("root.exe")};
624  G4UIExecutive *ui = new G4UIExecutive(1, args, "qt");
625  InitUImanager();
626  m_UImanager->ApplyCommand("/control/execute init_gui_vis.mac");
627  ui->SessionStart();
628  delete ui;
629  return 0;
630 }
631 
633 {
634  if (!m_UImanager)
635  {
636  // Get the pointer to the User Interface manager
637  // Initialize visualization
638  m_VisManager = new G4VisExecutive;
639  m_VisManager->Initialize();
640  m_UImanager = G4UImanager::GetUIpointer();
641  }
642  return 0;
643 }
644 
645 //_________________________________________________________________
647 {
648  if (PHRandomSeed::Verbosity() >= 2)
649  {
650  G4Random::showEngineStatus();
651  }
652 
653  // make sure Actions and subsystems have the relevant pointers set
654  PHG4InEvent *ineve = findNode::getClass<PHG4InEvent>(topNode, "PHG4INEVENT");
656 
657  for (SubsysReco *reco : m_SubsystemList)
658  {
659  if (Verbosity() >= 2)
660  {
661  std::cout << "PHG4Reco::process_event - " << reco->Name() << "->process_event" << std::endl;
662  }
663 
664  try
665  {
666  reco->process_event(topNode);
667  }
668  catch (const std::exception &e)
669  {
670  std::cout << PHWHERE << " caught exception thrown during process_event from "
671  << reco->Name() << std::endl;
672  std::cout << "error: " << e.what() << std::endl;
674  }
675  }
676 
677  // run one event
678  if (Verbosity() >= 2)
679  {
680  std::cout << " PHG4Reco::process_event - "
681  << "run one event :" << std::endl;
682  ineve->identify();
683  }
684  m_RunManager->BeamOn(1);
685 
686  for (PHG4Subsystem *g4sub : m_SubsystemList)
687  {
688  if (Verbosity() >= 2)
689  {
690  std::cout << " PHG4Reco::process_event - " << g4sub->Name() << "->process_after_geant" << std::endl;
691  }
692  try
693  {
694  g4sub->process_after_geant(topNode);
695  }
696  catch (const std::exception &e)
697  {
698  std::cout << PHWHERE << " caught exception thrown during process_after_geant from "
699  << g4sub->Name() << std::endl;
700  std::cout << "error: " << e.what() << std::endl;
702  }
703  }
704  return 0;
705 }
706 
708 {
709  for (SubsysReco *reco : m_SubsystemList)
710  {
711  reco->ResetEvent(topNode);
712  }
713  return 0;
714 }
715 
716 void PHG4Reco::Print(const std::string &what) const
717 {
718  for (SubsysReco *reco : m_SubsystemList)
719  {
720  if (what.empty() || what == "ALL" || (reco->Name()).find(what) != std::string::npos)
721  {
722  std::cout << "Printing " << reco->Name() << std::endl;
723  reco->Print(what);
724  std::cout << "---------------------------" << std::endl;
725  }
726  }
727  return;
728 }
729 
731 {
732  PHG4InEvent *ineve = findNode::getClass<PHG4InEvent>(topNode, "PHG4INEVENT");
733  if (!ineve)
734  {
735  PHNodeIterator iter(topNode);
736  PHCompositeNode *dstNode;
737  dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
738 
739  ineve = new PHG4InEvent();
740  PHDataNode<PHObject> *newNode = new PHDataNode<PHObject>(ineve, "PHG4INEVENT", "PHObject");
741  dstNode->addNode(newNode);
742  }
743  // check if we have already registered a generator before creating the default which uses PHG4InEvent Node
744  if (!m_GeneratorAction)
745  {
747  }
748  m_RunManager->SetUserAction(m_GeneratorAction);
749  return 0;
750 }
751 
753 {
754  m_EtaCoverage = eta;
756 }
757 
758 void PHG4Reco::G4Seed(const unsigned int i)
759 {
760  CLHEP::HepRandom::setTheSeed(i);
761 
762  if (PHRandomSeed::Verbosity() >= 2)
763  {
764  G4Random::showEngineStatus();
765  }
766 
767  return;
768 }
769 
770 //____________________________________________________________________________
772 {
773  G4String symbol, name; // a=mass of a mole;
774  G4double density; // z=mean number of protons;
775  G4double fractionmass, a;
776  G4int ncomponents, natoms, z;
777  // this is for FTFP_BERT_HP where the neutron code barfs
778  // if the z difference to the last known element (U) is too large
779  // home made compounds
780  // this is a legacy implementation but if they are used in multiple
781  // subsystems put them here
782  // otherwise implement locally used ones now in the DefineMaterials()
783  // method in your subsystem
784 
785  // making quartz
786  G4Material *quartz = new G4Material("Quartz", density = 2.200 * g / cm3, ncomponents = 2);
787  quartz->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), 1);
788  quartz->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), 2);
789 
790  // making carbon fiber epoxy
791  G4Material *cfrp_intt = new G4Material("CFRP_INTT", density = 1.69 * g / cm3, ncomponents = 3);
792  cfrp_intt->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 10);
793  cfrp_intt->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), 6);
794  cfrp_intt->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), 1);
795 
796  // water glycol mixture for the INTT endcap rings
797  G4Material *PropyleneGlycol = new G4Material("Propyleneglycol", 1.036 * g / cm3, 3);
798  PropyleneGlycol->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 3);
799  PropyleneGlycol->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), 8);
800  PropyleneGlycol->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), 2);
801 
802  G4Material *WaterGlycol_INTT = new G4Material("WaterGlycol_INTT", density = (0.997 * 0.7 + 1.036 * 0.3) * g / cm3, ncomponents = 2);
803  WaterGlycol_INTT->AddMaterial(PropyleneGlycol, fractionmass = 0.30811936);
804  WaterGlycol_INTT->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER"), fractionmass = 0.69188064);
805 
806  // making Rohacell foam 110
807  G4Material *rohacell_foam_110 = new G4Material("ROHACELL_FOAM_110", density = 0.110 * g / cm3, ncomponents = 4);
808  rohacell_foam_110->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 8);
809  rohacell_foam_110->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), 11);
810  rohacell_foam_110->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), 2);
811  rohacell_foam_110->AddElement(G4NistManager::Instance()->FindOrBuildElement("N"), 1);
812 
813  // making Rohacell foam ROHACELL 51 WF
814  // Source of density: https://www.rohacell.com/product/peek-industrial/downloads/rohacell%20wf%20product%20information.pdf
815  G4Material *rohacell_foam_51 = new G4Material("ROHACELL_FOAM_51", density = 0.052 * g / cm3, ncomponents = 4);
816  rohacell_foam_51->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 8);
817  rohacell_foam_51->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), 11);
818  rohacell_foam_51->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), 2);
819  rohacell_foam_51->AddElement(G4NistManager::Instance()->FindOrBuildElement("N"), 1);
820 
821  // making Carbon PEEK : 30 - 70 Vf.
822  // https://www.quantum-polymers.com/wp-content/uploads/2017/03/QuantaPEEK-CF30.pdf
823  G4Material *peek = new G4Material("PEEK", density = 1.32 * g / cm3, ncomponents = 3);
824  peek->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 19);
825  peek->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), 12);
826  peek->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), 3);
827 
828  G4Material *cf = new G4Material("CF", density = 1.62 * g / cm3, ncomponents = 1);
829  cf->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 1.);
830 
831  G4Material *cf30_peek70 = new G4Material("CF30_PEEK70", density = (1.32 * 0.7 + 1.62 * 0.3) * g / cm3, ncomponents = 2);
832  cf30_peek70->AddMaterial(cf, fractionmass = 0.34468085);
833  cf30_peek70->AddMaterial(peek, fractionmass = 0.65531915);
834 
835  // that seems to be the composition of 304 Stainless steel
836  G4Material *StainlessSteel =
837  new G4Material("SS304", density = 7.9 * g / cm3, ncomponents = 8);
838  StainlessSteel->AddElement(G4NistManager::Instance()->FindOrBuildElement("Fe"), 0.70105);
839  StainlessSteel->AddElement(G4NistManager::Instance()->FindOrBuildElement("Cr"), 0.18);
840  StainlessSteel->AddElement(G4NistManager::Instance()->FindOrBuildElement("Ni"), 0.09);
841  StainlessSteel->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mn"), 0.02);
842  StainlessSteel->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 0.0007);
843  StainlessSteel->AddElement(G4NistManager::Instance()->FindOrBuildElement("S"), 0.0003);
844  StainlessSteel->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), 0.0075);
845  StainlessSteel->AddElement(G4NistManager::Instance()->FindOrBuildElement("P"), 0.00045);
846 
847  G4Material *SS310 =
848  new G4Material("SS310", density = 8.0 * g / cm3, ncomponents = 8);
849  SS310->AddElement(G4NistManager::Instance()->FindOrBuildElement("Fe"), 0.50455);
850  SS310->AddElement(G4NistManager::Instance()->FindOrBuildElement("Cr"), 0.25);
851  SS310->AddElement(G4NistManager::Instance()->FindOrBuildElement("Ni"), 0.20);
852  SS310->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mn"), 0.02);
853  SS310->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 0.0025);
854  SS310->AddElement(G4NistManager::Instance()->FindOrBuildElement("S"), 0.015);
855  SS310->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), 0.0075);
856  SS310->AddElement(G4NistManager::Instance()->FindOrBuildElement("P"), 0.00045);
857 
858  // SS316 from https://www.azom.com
859  G4Material *SS316 =
860  new G4Material("SS316", density = 8.0 * g / cm3, ncomponents = 9);
861  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("Fe"), 0.68095);
862  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("Cr"), 0.16);
863  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("Ni"), 0.11);
864  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mn"), 0.02);
865  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mo"), 0.02);
866  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 0.0008);
867  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("S"), 0.0003);
868  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), 0.0075);
869  SS316->AddElement(G4NistManager::Instance()->FindOrBuildElement("P"), 0.00045);
870 
871  G4Material *Steel =
872  new G4Material("Steel", density = 7.86 * g / cm3, ncomponents = 5);
873  Steel->AddElement(G4NistManager::Instance()->FindOrBuildElement("Fe"), 0.9834);
874  Steel->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mn"), 0.014);
875  Steel->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 0.0017);
876  Steel->AddElement(G4NistManager::Instance()->FindOrBuildElement("S"), 0.00045);
877  Steel->AddElement(G4NistManager::Instance()->FindOrBuildElement("P"), 0.00045);
878 
879  // a36 steel from http://www.matweb.com
880  G4Material *a36 = new G4Material("Steel_A36", density = 7.85 * g / cm3, ncomponents = 5);
881  a36->AddElement(G4NistManager::Instance()->FindOrBuildElement("Fe"), 0.9824);
882  a36->AddElement(G4NistManager::Instance()->FindOrBuildElement("Cu"), 0.002);
883  a36->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 0.0025);
884  a36->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mn"), 0.0103);
885  a36->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), 0.0028);
886 
887  // 1006 steel from http://www.matweb.com
888  G4Material *steel_1006 = new G4Material("Steel_1006", density = 7.872 * g / cm3, ncomponents = 2);
889  steel_1006->AddElement(G4NistManager::Instance()->FindOrBuildElement("Fe"), 0.996);
890  steel_1006->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mn"), 0.004);
891 
892  // from www.aalco.co.uk
893  G4Material *Al5083 = new G4Material("Al5083", density = 2.65 * g / cm3, ncomponents = 3);
894  Al5083->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mn"), 0.004);
895  Al5083->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mg"), 0.04);
896  Al5083->AddElement(G4NistManager::Instance()->FindOrBuildElement("Al"), 0.956);
897 
898  // Al 4046 from http://www.matweb.com
899  G4Material *Al4046 = new G4Material("Al4046", density = 2.66 * g / cm3, ncomponents = 3);
900  Al4046->AddElement(G4NistManager::Instance()->FindOrBuildElement("Al"), 0.897);
901  Al4046->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), 0.1);
902  Al4046->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mg"), 0.003);
903 
904  // Al 6061T6 from http://www.matweb.com
905  G4Material *Al6061T6 = new G4Material("Al6061T6", density = 2.70 * g / cm3, ncomponents = 4);
906  Al6061T6->AddElement(G4NistManager::Instance()->FindOrBuildElement("Al"), 0.975);
907  Al6061T6->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), 0.008);
908  Al6061T6->AddElement(G4NistManager::Instance()->FindOrBuildElement("Mg"), 0.01);
909  Al6061T6->AddElement(G4NistManager::Instance()->FindOrBuildElement("Fe"), 0.007);
910 
911  // E864 Pb-Scifi calorimeter
912  // E864 Calorimeter is 99% Pb, 1% Antimony
913  // Nuclear Instruments and Methods in Physics Research A 406 (1998) 227 258
914  G4double density_e864 = (0.99 * 11.34 + 0.01 * 6.697) * g / cm3;
915  G4Material *absorber_e864 = new G4Material("E864_Absorber", density_e864, 2);
916  absorber_e864->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_Pb"), 0.99);
917  absorber_e864->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_Sb"), 0.01);
918 
919  G4Material *FPC = new G4Material("FPC", 1.542 * g / cm3, 2);
920  FPC->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_Cu"), 0.0162);
921  FPC->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_KAPTON"), 0.9838);
922 
923  // This is an approximation for the W saturated epoxy of the EMCal.
924  G4Material *W_Epoxy = new G4Material("W_Epoxy", density = 10.2 * g / cm3, ncomponents = 2);
925  W_Epoxy->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_W"), fractionmass = 0.5);
926  W_Epoxy->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_POLYSTYRENE"), fractionmass = 0.5);
927 
928  // from http://www.physi.uni-heidelberg.de/~adler/TRD/TRDunterlagen/RadiatonLength/tgc2.htm
929  // Epoxy (for FR4 )
930  // density = 1.2*g/cm3;
931  G4Material *Epoxy = new G4Material("Epoxy", 1.2 * g / cm3, ncomponents = 2);
932  Epoxy->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), natoms = 2);
933  Epoxy->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), natoms = 2);
934 
935  // FR4 (Glass + Epoxy)
936  density = 1.86 * g / cm3;
937  G4Material *FR4 = new G4Material("FR4", density, ncomponents = 2);
938  FR4->AddMaterial(quartz, fractionmass = 0.528);
939  FR4->AddMaterial(Epoxy, fractionmass = 0.472);
940  // NOMEX (HoneyComb)
941  // density from http://www.fibreglast.com/product/Nomex_Honeycomb_1562/Vacuum_Bagging_Sandwich_Core
942  // 1562: 29 kg/m^3 <-- I guess it is this one
943  // 2562: 48 kg/m^3
944  // chemical composition http://ww2.unime.it/cdlchimind/adm/inviofile/uploads/HP_Pols2.b.pdf
945  density = 29 * kg / m3;
946  G4Material *NOMEX = new G4Material("NOMEX", density, ncomponents = 4);
947  NOMEX->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), natoms = 14);
948  NOMEX->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), natoms = 10);
949  NOMEX->AddElement(G4NistManager::Instance()->FindOrBuildElement("N"), natoms = 2);
950  NOMEX->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), natoms = 2);
951  // spacal material. Source : EICROOT/A. Kiselev
952  /*
953  WEpoxyMix 3 12.011 1.008 183.85 6. 1. 74. 12.18 0.029 0.002 0.969
954  1 1 30. .00001
955  0
956  */
957  G4Material *Spacal_W_Epoxy =
958  new G4Material("Spacal_W_Epoxy", density = 12.18 * g / cm3, ncomponents = 3);
959  Spacal_W_Epoxy->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 0.029);
960  Spacal_W_Epoxy->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), 0.002);
961  Spacal_W_Epoxy->AddElement(G4NistManager::Instance()->FindOrBuildElement("W"), 0.969);
962  /*
963 PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4
964  1 1 20. .00001
965  0
966  */
967  G4Material *PMMA =
968  new G4Material("PMMA", density = 1.19 * g / cm3, ncomponents = 3);
969  PMMA->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), 3.6 / (3.6 + 5.7 + 1.4));
970  PMMA->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), 5.7 / (3.6 + 5.7 + 1.4));
971  PMMA->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), 1.4 / (3.6 + 5.7 + 1.4));
972 
973  // scintillator for HCal, use a new name in order to change the Birks' constant
974  G4Material *Uniplast_scintillator = new G4Material("Uniplast_scintillator", 1.06 * g / cm3, ncomponents = 1);
975  Uniplast_scintillator->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_POLYSTYRENE"), fractionmass = 1.);
976 
977  G4Material *G10 =
978  new G4Material("G10", density = 1.700 * g / cm3, ncomponents = 4);
979  G10->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), natoms = 1);
980  G10->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), natoms = 2);
981  G10->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), natoms = 3);
982  G10->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), natoms = 3);
983 
984  G4Material *CsI =
985  new G4Material("CsI", density = 4.534 * g / cm3, ncomponents = 2);
986  CsI->AddElement(G4NistManager::Instance()->FindOrBuildElement("Cs"), natoms = 1);
987  CsI->AddElement(G4NistManager::Instance()->FindOrBuildElement("I"), natoms = 1);
988  CsI->GetIonisation()->SetMeanExcitationEnergy(553.1 * eV);
989 
990  G4Material *C4F10 =
991  new G4Material("C4F10", density = 0.00973 * g / cm3, ncomponents = 2);
992  C4F10->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), natoms = 4);
993  C4F10->AddElement(G4NistManager::Instance()->FindOrBuildElement("F"), natoms = 10);
994 
995  G4Material *CF4 = new G4Material("CF4", density = 3.72 * mg / cm3, ncomponents = 2, kStateGas, 288.15 * kelvin, 1 * atmosphere);
996  CF4->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), natoms = 1);
997  CF4->AddElement(G4NistManager::Instance()->FindOrBuildElement("F"), natoms = 4);
998 
999  G4Element *elLu = new G4Element(name = "Lutetium", symbol = "Lu", z = 71., a = 174.97 * g / mole);
1000  G4Material *LSO = new G4Material("LSO", // its name
1001  density = 7.4 * g / cm3, // its density
1002  ncomponents = 3); // number of components
1003 
1004  LSO->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), natoms = 1);
1005  LSO->AddElement(elLu, natoms = 2);
1006  LSO->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), natoms = 5);
1007 
1008  // Silver epoxy glue LOCTITE ABLESTIK 2902 for the silicon sensors and FPHX chips of INTT
1009  G4Material *SilverEpoxyGlue_INTT = new G4Material("SilverEpoxyGlue_INTT", density = 3.2 * g / cm3, ncomponents = 2);
1010  SilverEpoxyGlue_INTT->AddMaterial(Epoxy, fractionmass = 0.79);
1011  SilverEpoxyGlue_INTT->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_Ag"), fractionmass = 0.21);
1012 
1013  // this here is very close but makes more sense since it uses Ne and CF4
1014  double G4_Ne_frac = 0.5;
1015  double CF4_frac = 0.5;
1016  const double den_G4_Ne = G4NistManager::Instance()->FindOrBuildMaterial("G4_Ne")->GetDensity();
1017  const double den_CF4_2 = CF4->GetDensity();
1018  const double den_sphenix_tpc_gas = den_G4_Ne * G4_Ne_frac + den_CF4_2 * CF4_frac;
1019  G4Material *sPHENIX_tpc_gas = new G4Material("sPHENIX_TPC_Gas", den_sphenix_tpc_gas, ncomponents = 2, kStateGas);
1020  sPHENIX_tpc_gas->AddMaterial(CF4, den_CF4_2 * CF4_frac / den_sphenix_tpc_gas);
1021  sPHENIX_tpc_gas->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_Ne"), den_G4_Ne * G4_Ne_frac / den_sphenix_tpc_gas);
1022 
1023  // Due to supply issues, we are now expecting to use Ar CF4.
1024  // The fractions are tuned to produce very similar drift speed
1025  // and other parameters as the original NeCF4 mixture.
1026  double alt_G4_Ar_frac = 0.6;
1027  double alt_CF4_frac = 0.4;
1028  const double alt_den_G4_Ar = G4NistManager::Instance()->FindOrBuildMaterial("G4_Ar")->GetDensity();
1029  const double alt_den_CF4 = CF4->GetDensity();
1030  const double alt_den_sphenix_tpc_gas = alt_den_G4_Ar * alt_G4_Ar_frac + alt_den_CF4 * alt_CF4_frac;
1031  G4Material *alt_sPHENIX_tpc_gas = new G4Material("sPHENIX_TPC_Gas_ArCF4", alt_den_sphenix_tpc_gas, ncomponents = 2, kStateGas);
1032  alt_sPHENIX_tpc_gas->AddMaterial(CF4, alt_den_CF4 * alt_CF4_frac / alt_den_sphenix_tpc_gas);
1033  alt_sPHENIX_tpc_gas->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_Ar"), alt_den_G4_Ar * alt_G4_Ar_frac / alt_den_sphenix_tpc_gas);
1034 
1035  // define P10 Gas which will be used for TPC Benchmarking
1036  G4Material *P10 =
1037  new G4Material("P10", density = 1.74 * mg / cm3, ncomponents = 3); // @ 0K, 1atm
1038  P10->AddElement(G4NistManager::Instance()->FindOrBuildElement("Ar"), fractionmass = 0.9222);
1039  P10->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), fractionmass = 0.0623);
1040  P10->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), fractionmass = 0.0155);
1041 }
1042 
1044 {
1045  // the PAI model does not work anymore in G4 10.06
1046  // const G4RegionStore *theRegionStore = G4RegionStore::GetInstance();
1047  // G4ProductionCuts *gcuts = new G4ProductionCuts(*(theRegionStore->GetRegion("DefaultRegionForTheWorld")->GetProductionCuts()));
1048  // G4Region *tpcregion = new G4Region("REGION_TPCGAS");
1049  // tpcregion->SetProductionCuts(gcuts);
1050  // #if G4VERSION_NUMBER >= 1033
1051  // // Use this from the new G4 version 10.03 on
1052  // // was commented out, crashes in 10.06 I think
1053  // // add the PAI model to the TPCGAS region
1054  // // undocumented, painfully digged out with debugger by tracing what
1055  // // is done for command "/process/em/AddPAIRegion all TPCGAS PAI"
1056  // // G4EmParameters *g4emparams = G4EmParameters::Instance();
1057  // // g4emparams->AddPAIModel("all", "REGION_TPCGAS", "PAI");
1058  // #endif
1059  return;
1060 }
1061 
1062 PHG4Subsystem *
1064 {
1065  for (PHG4Subsystem *subsys : m_SubsystemList)
1066  {
1067  if (subsys->Name() == name)
1068  {
1069  if (Verbosity() > 0)
1070  {
1071  std::cout << "Found Subsystem " << name << std::endl;
1072  }
1073  return subsys;
1074  }
1075  }
1076  std::cout << "Could not find Subsystem " << name << std::endl;
1077  return nullptr;
1078 }
1079 
1080 void PHG4Reco::G4Verbosity(const int i)
1081 {
1082  if (m_RunManager)
1083  {
1084  m_RunManager->SetVerboseLevel(i);
1085  }
1086 }
1087 
1089 {
1090  if (!m_Detector)
1091  {
1092  return;
1093  }
1095  m_DisplayAction->ApplyDisplayAction(physworld);
1096  for (PHG4Subsystem *g4sub : m_SubsystemList)
1097  {
1098  PHG4DisplayAction *action = g4sub->GetDisplayAction();
1099  if (action)
1100  {
1101  if (Verbosity() > 1)
1102  {
1103  std::cout << "Adding steppingaction for " << g4sub->Name() << std::endl;
1104  }
1105  action->ApplyDisplayAction(physworld);
1106  }
1107  }
1108 }