G4TankSimulatorOG/G4TankSimulator.cc
Go to the documentation of this file.
1 #include "G4TankSimulator.h"
3 #include "G4TankPhysicsList.h"
4 #include "G4TankConstruction.h"
6 #include "G4TankTrackingAction.h"
7 #include "G4TankStackingAction.h"
8 #include "G4TankSteppingAction.h"
9 #include "G4TankEventAction.h"
10 #include "G4TankRunAction.h"
11 #include "G4TankVisManager.h"
12 #include "G4TankFastCerenkov.h"
13 #include "G4OutputHandler.h"
14 
15 #include <G4RunManager.hh>
16 #include <G4UImanager.hh>
17 #include <G4VisManager.hh>
18 
19 #include <fwk/CentralConfig.h>
20 #include <fwk/RandomEngineRegistry.h>
21 
22 #include <det/Detector.h>
23 
24 #include <evt/Event.h>
25 #include <evt/ShowerSimData.h>
26 
27 #include <sdet/SDetector.h>
28 #include <sdet/Station.h>
29 
30 #include <sevt/PMT.h>
31 #include <sevt/PMTSimData.h>
32 #include <sevt/SEvent.h>
33 #include <sevt/Station.h>
34 #include <sevt/StationSimData.h>
35 
36 #include <utl/ErrorLogger.h>
37 #include <utl/Reader.h>
38 #include <utl/Particle.h>
39 #include <utl/ParticleCases.h>
40 #include <utl/ShowerParticleIterator.h>
41 #include <utl/TimeDistribution.h>
42 #include <utl/TimeDistributionAlgorithm.h>
43 
44 #include <cstddef>
45 #include <iostream>
46 #include <sstream>
47 
48 #include <CLHEP/Random/Random.h>
49 
50 #include <tls/Geant4Manager.h>
51 
52 using namespace utl;
53 using namespace fwk;
54 using namespace std;
55 using namespace sevt;
56 using namespace sdet;
57 using namespace evt;
58 using namespace det;
59 using namespace G4TankSimulatorOG;
60 
61 
62 const sdet::Station* G4TankSimulator::fCurrentDetectorStation = 0;
63 SEvent::StationIterator G4TankSimulator::fCurrentEventStationIt;
64 StationSimData::ParticleIterator G4TankSimulator::fCurrentParticleIt;
65 
66 bool G4TankSimulator::fgMuCapture;
67 
68 
69 G4TankSimulator::G4TankSimulator() :
70  fRunManager(0),
71  fUImanager(0),
72  fVisManager(0),
73  fGeoVisOn(0),
74  fTrajVisOn(0),
75  fUseGlobalPhysicsList(false),
76  fSignalSeparationMode(eStandard),
77  fDetectorConstructed(0),
78  fFastMode(false),
79  fEventId("")
80 { }
81 
82 
84 { }
85 
86 
89 {
90  Branch topB =
91  CentralConfig::GetInstance()->GetTopBranch("G4TankSimulator");
92  Branch visB = topB.GetChild("visualization");
93 
94  visB.GetChild("geometry").GetData(fGeoVisOn);
95  visB.GetChild("trajectories").GetData(fTrajVisOn);
96 
97  Branch fastModeB = topB.GetChild("fastMode");
98  fastModeB.GetData(fFastMode);
99 
100  Branch muCaptureB = topB.GetChild("muCapture");
101  muCaptureB.GetData(fgMuCapture);
102 
103  Branch globalPhysicsListB = topB.GetChild("globalPhysicsList");
104  globalPhysicsListB.GetData(fUseGlobalPhysicsList);
105 
106  string sepMode;
107  topB.GetChild("signalSeparationMode").GetData(sepMode);
108  if (sepMode == "Standard")
110  else if (sepMode == "Universality")
112 
113  if ( (fGeoVisOn || fTrajVisOn) && !fVisManager) {
115  }
116  if (!fRunManager) {
118  fRunManager = tls::Geant4Manager::GetInstance().GetRunManager();
119  else
120  fRunManager = new G4RunManager;
121  }
122 
123  fUImanager = G4UImanager::GetUIpointer();
124 
125  G4OutputHandler* logger = new G4OutputHandler();
126  fUImanager->SetCoutDestination(logger);
127 
128  if (fUseGlobalPhysicsList) {
129  INFO("using global PhysicsList from Geant4Manager");
130  tls::Geant4Manager::GetInstance().AddVisManager(fVisManager);
131 
132  G4TankPhysicsListCustomization* physicsListCustomization =
134 
135  INFO("Constructing G4Tank");
136  const SDetector& sDetector = Detector::GetInstance().GetSDetector();
137  const SDetector::StationIterator sIt = sDetector.AllStationsBegin();
138  fCurrentDetectorStation = &(*sIt);
139  fgTankConstruction = new G4TankConstruction(); //reads fCurrentDetectorStation
140 
141  tls::Geant4Customization custom("G4TankSimulator", fgTankConstruction, physicsListCustomization);
147  custom.SetEventAction(new G4TankEventAction);
148  custom.SetRunAction(new G4TankRunAction);
149 
150  tls::Geant4Manager::GetInstance().AddCustomization(custom);
151  }
152  else {
153  INFO("using PhysicsList from G4TankPhysicsList");
154  fRunManager->SetUserInitialization(new G4TankPhysicsList(fFastMode));
155 
156  fRunManager->SetUserAction(new G4TankPrimaryGenerator);
157 
159  fRunManager->SetUserAction(fStackingAction);
160  fRunManager->SetUserAction(new G4TankTrackingAction);
161  fRunManager->SetUserAction(new G4TankSteppingAction);
162  fRunManager->SetUserAction(new G4TankEventAction);
163  fRunManager->SetUserAction(new G4TankRunAction);
164 
165  fUImanager->ApplyCommand("/run/verbose 0");
166  fUImanager->ApplyCommand("/event/verbose 0");
167  fUImanager->ApplyCommand("/tracking/verbose 0");
168  }
169 
170  fDetectorConstructed = false;
171 
172  return eSuccess;
173 }
174 
175 
178 {
179  if (!event.HasSEvent()) {
180  ERROR("SEvent does not exist.");
181  return eFailure;
182  }
183 
184  CLHEP::HepRandom::setTheEngine(&RandomEngineRegistry::GetInstance().
185  Get(RandomEngineRegistry::eDetector).
186  GetEngine());
187 
188  SEvent& sEvent = event.GetSEvent();
189 
190  if (!fDetectorConstructed && sEvent.GetNumberOfStations() > 0) {
191 
192  if (!fUseGlobalPhysicsList) {
193  INFO("Constructing G4Tank");
194 
195  const SEvent::ConstStationIterator sIt = sEvent.StationsBegin();
196  if (sIt == sEvent.StationsEnd()) {
197  ERROR("No stations!");
198  return eFailure;
199  }
200 
201  const SDetector& sDetector = Detector::GetInstance().GetSDetector();
202  fCurrentDetectorStation = &sDetector.GetStation(sIt->GetId());
203 
204  // Construct detector geometry and register w/ RunManager
205  fRunManager->SetUserInitialization(new G4TankConstruction);
206 
207  fRunManager->Initialize();
208  }
209 
210  fDetectorConstructed = true;
211 
212  if (fGeoVisOn || fTrajVisOn) {
213  fVisManager->Initialize();
214  fUImanager->ApplyCommand("/vis/open VRML2FILE");
215  fUImanager->ApplyCommand("/vis/scene/create");
216  fUImanager->ApplyCommand("/vis/sceneHandler/attach");
217  fUImanager->ApplyCommand("/vis/scene/add/volume");
218  fUImanager->ApplyCommand("/vis/viewero/set/style/wireframe");
219  fUImanager->ApplyCommand("/vis/drawVolume");
220  fUImanager->ApplyCommand("/vis/scene/notifyHandlers");
221  fUImanager->ApplyCommand("/vis/viewer/update");
222  }
223  if (fTrajVisOn) {
224  fUImanager->ApplyCommand("/tracking/storeTrajectory 1");
225  fUImanager->ApplyCommand("/vis/scene/add/trajectories");
226  }
227 
228  }
229 
231  tls::Geant4Manager::GetInstance().Customize("G4TankSimulator");
232 
233  return fFastMode ? RunFast(event) : RunFull(event);
234 }
235 
236 
239 {
240  // Get the SEvent
241  SEvent& sEvent = event.GetSEvent();
242 
243  // Get the SDetector
244  const SDetector& sDetector = Detector::GetInstance().GetSDetector();
245 
246  for (SEvent::StationIterator sIt = sEvent.StationsBegin();
247  sIt != sEvent.StationsEnd(); ++sIt) {
248 
249  if (!fDetectorConstructed) {
250  ERROR("The detector hasn't been initialized when looping over stations");
251  return eFailure;
252  }
253 
254  if (sIt->HasSimData()) {
255 
256  StationSimData& simData = sIt->GetSimData();
257 
258  // full-blown tank sim (no optimization of photon tracking)
259  simData.SetSimulatorSignature("G4TankSimulatorFullOG");
260 
261  const int stationId = sIt->GetId();
262 
263  const unsigned long numParticles =
264  simData.ParticlesEnd() - simData.ParticlesBegin();
265 
266  if (numParticles)
267  G4cerr << stationId << ':' << numParticles << ' ' << flush;
268  else
269  continue;
270 
271  /*
272  * Counting the number of particles that are actually simulated (post
273  * station-level thinning). Due to resampling simulation option that
274  * uses cycles with maximum particle number per cycle, we always check
275  * if particles have already been simulated.
276  */
277  const unsigned int nParticlesAlreadySimulated = simData.GetTotalSimParticleCount();
278  if (!nParticlesAlreadySimulated)
279  simData.SetTotalSimParticleCount(numParticles);
280  else
281  simData.SetTotalSimParticleCount(nParticlesAlreadySimulated + numParticles);
282 
284  fCurrentDetectorStation = &sDetector.GetStation(stationId);
286 
287  ConstructTraces(*sIt);
288 
290  pIt != simData.ParticlesEnd(); ++pIt) {
291 
292  fCurrentParticleIt = pIt;
293 
294  fRunManager->BeamOn(1);
295 
296  }
297  }
298  }
299 
300  return eSuccess;
301 }
302 
303 
306 {
307  SEvent& sEvent = event.GetSEvent();
308  const SDetector& sDetector = Detector::GetInstance().GetSDetector();
309 
310  // find first station with SimData
311  for (fCurrentEventStationIt = sEvent.StationsBegin();
312  fCurrentEventStationIt != sEvent.StationsEnd() &&
314 
315  if (fCurrentEventStationIt == sEvent.StationsEnd()) {
316  INFO("No stations with SimData found.");
317  return eContinueLoop;
318  }
319 
320  const int id = fCurrentEventStationIt->GetId();
321  fCurrentDetectorStation = &sDetector.GetStation(id);
322  if (!fDetectorConstructed) {
324  fRunManager->SetUserInitialization(fgTankConstruction);
325  fRunManager->Initialize();
326  fDetectorConstructed = true;
327  }
328 
329  for (SEvent::StationIterator sIt = sEvent.StationsBegin();
330  sIt != sEvent.StationsEnd(); ++sIt) {
331 
332  if (!sIt->HasSimData())
333  continue;
334 
335  StationSimData& simData = sIt->GetSimData();
336 
337  simData.SetSimulatorSignature("G4TankSimulatorOG");
338 
339  const unsigned long numParticles =
340  simData.ParticlesEnd() - simData.ParticlesBegin();
341 
342  const int stationId = sIt->GetId();
343 
344  if (numParticles)
345  G4cerr << stationId << ':' << numParticles << ' ' << flush;
346  else
347  continue;
348 
349  /*
350  * Counting the number of particles that are actually simulated (post
351  * station-level thinning). Due to resampling simulation option that
352  * uses cycles with maximum particle number per cycle, we always check
353  * if particles have already been simulated.
354  */
355  const unsigned int nParticlesAlreadySimulated = simData.GetTotalSimParticleCount();
356  if (!nParticlesAlreadySimulated)
357  simData.SetTotalSimParticleCount(numParticles);
358  else
359  simData.SetTotalSimParticleCount(nParticlesAlreadySimulated + numParticles);
360 
362  fCurrentDetectorStation = &sDetector.GetStation(stationId);
363 
364  ConstructTraces(*sIt);
365 
366  // prod the Cerenkov process update it's tank description data
368 
370  pIt != simData.ParticlesEnd(); ++pIt) {
371 
372  fCurrentParticleIt = pIt;
373 
374  fRunManager->BeamOn(1);
375 
376  } // particles
377 
378  } // stations
379 
380  G4cerr << endl;
381 
382  return eSuccess;
383 }
384 
385 
388 {
390  tls::Geant4Manager::GetInstance().NotifyDelete();
391  else {
392  delete fRunManager;
393  fRunManager = 0;
394  }
395  return eSuccess;
396 }
397 
398 
399 void
401  const
402 {
403  const StationSimData& sSim = station.GetSimData();
404 
405  // Add pmt sim data only if the station contains particles
406  if (sSim.ParticlesEnd() == sSim.ParticlesBegin())
407  return;
408 
409  for (sevt::Station::PMTIterator pmtIt = station.PMTsBegin();
410  pmtIt != station.PMTsEnd(); ++pmtIt)
411  if (!pmtIt->HasSimData())
412  pmtIt->MakeSimData();
413 }
414 
415 
416 void
417 G4TankSimulator::AddPhoton(const int nPMT, const double peTime)
418  const
419 {
420  PMTSimData& pmtSim = fCurrentEventStationIt->GetPMT(nPMT).GetSimData();
421 
422  const int type = fCurrentParticleIt->GetType();
423  const int source = fCurrentParticleIt->GetSource();
424 
427 
428  switch (fSignalSeparationMode) {
429  case eStandard:
430  switch (type) {
431  case OFFLINE_ELECTRONS:
435  break;
436  case OFFLINE_PHOTON:
440  break;
441  case OFFLINE_MUONS:
442  component = sevt::StationConstants::eMuon;
443  break;
444  case OFFLINE_HADRONS:
446  break;
447  default:
448  cerr << "Unknown particle type" << endl;
449  exit(-1);
450  }
451  break;
452  case eUniversality:
453  switch (type) {
454  case OFFLINE_ELECTRONS:
457  else if (source == utl::Particle::eShowerFromMuonDecay)
459  else
461  break;
462  case OFFLINE_PHOTON:
465  else if (source == utl::Particle::eShowerFromMuonDecay)
467  else
469  break;
470  case OFFLINE_MUONS:
471  component = sevt::StationConstants::eMuon;
472  break;
473  case OFFLINE_HADRONS:
475  break;
476  default:
477  cerr << "Unknown particle type" << endl;
478  exit(-1);
479  }
480  break;
481  }
482 
483  if (!pmtSim.HasPETimeDistribution())
484  pmtSim.MakePETimeDistribution();
485  pmtSim.GetPETimeDistribution().AddTime(peTime);
486 
487  if (!pmtSim.HasPETimeDistribution(component))
488  pmtSim.MakePETimeDistribution(component);
489  pmtSim.GetPETimeDistribution(component).AddTime(peTime);
490 
491  if (extraComponent != sevt::StationConstants::eTotal) {
492  if (!pmtSim.HasPETimeDistribution(extraComponent))
493  pmtSim.MakePETimeDistribution(extraComponent);
494  pmtSim.GetPETimeDistribution(extraComponent).AddTime(peTime);
495  }
496 }
void SetRunAction(G4UserRunAction *const action)
Branch GetTopBranch() const
Definition: Branch.cc:63
allow customization of the standard global PhysicsList that are handled by the Geant4Manager ...
Station Level Simulated Data
StationIterator StationsEnd()
End of all stations.
Definition: SEvent.h:59
void SetPrimaryGenerator(G4VUserPrimaryGeneratorAction *const action)
Detector description interface for Station-related data.
Report success to RunController.
Definition: VModule.h:62
total (shower and background)
int GetNumberOfStations() const
Get total number of stations in the event.
Definition: SEvent.h:124
void AddPhoton(const int nPMT, const double peTime) const
Interface class to access to the SD part of an event.
Definition: SEvent.h:39
PMTIterator PMTsBegin(const sdet::PMTConstants::PMTType type=sdet::PMTConstants::eWaterCherenkovLarge)
begin PMT iterator for read/write
Skip remaining modules in the current loop and continue with next iteration of the loop...
Definition: VModule.h:68
void SetStackingAction(G4UserStackingAction *const action)
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
void ConstructTraces(sevt::Station &station) const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
electrons produced by hadrons close to the detector
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
boost::filter_iterator< PMTFilter, InternalPMTIterator > PMTIterator
Iterator over station for read/write.
int exit
Definition: dump1090.h:237
void SetSimulatorSignature(const std::string &name)
Set name of the tank simulator module used to simulate this station.
bool HasPETimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal) const
Check if a PE release time distribution exists (optionally for a given source)
Definition: PMTSimData.h:65
StationIterator AllStationsBegin() const
Beginning of the collection of pointers to all stations in the history of the array.
Definition: SDetector.h:121
ParticleVector::iterator ParticleIterator
electrons and positrons from shower
Class representing a document branch.
Definition: Branch.h:107
class to hold data at Station level
void SetEventAction(G4UserEventAction *const action)
static sevt::SEvent::StationIterator fCurrentEventStationIt
PMTIterator PMTsEnd(const sdet::PMTConstants::PMTType type=sdet::PMTConstants::eWaterCherenkovLarge)
end PMT iterator for read/write
implementation of G4 visualization manager
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
Data structure to hold the different Geant4 global objects required to run a single module...
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
ParticleIterator ParticlesBegin()
Beginning of simulated particles entering the station.
fwk::VModule::ResultFlag RunFull(evt::Event &theEvent)
void SetTrackingAction(G4UserTrackingAction *const action)
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
unsigned int GetTotalSimParticleCount() const
Get the total number of particles that were actually simulated (after thinning)
void SetTotalSimParticleCount(const unsigned int n)
StationIterator StationsBegin()
Beginning of all stations.
Definition: SEvent.h:57
Class to hold simulated data at PMT level.
Definition: PMTSimData.h:40
Detector description interface for SDetector-related data.
Definition: SDetector.h:42
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
static sevt::StationSimData::ParticleIterator fCurrentParticleIt
boost::indirect_iterator< InternalStationIterator, Station & > StationIterator
Iterator over all stations.
Definition: SEvent.h:52
sevt::StationSimData & GetSimData()
Get simulated data at station level.
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
utl::TimeDistributionI & GetPETimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal)
Simulated photoelectron time distribution.
Definition: PMTSimData.h:54
fwk::VModule::ResultFlag RunFast(evt::Event &theEvent)
const Station & GetStation(const int stationId) const
Get station by Station Id.
Definition: SDetector.cc:192
fwk::VModule::ResultFlag Run(evt::Event &theEvent)
Run: invoked once per event.
boost::indirect_iterator< InternalConstStationIterator, const Station & > ConstStationIterator
Definition: SEvent.h:54
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
ParticleIterator ParticlesEnd()
End of simulated particles entering the station.
void AddTime(const double time, const T weight=T(1))
Add an entry (optionally weighted) for the given time. Slot will be computed.
mu+ and mu- (including signal from mu decay electrons) from shower
bool HasSEvent() const
void SetSteppingAction(G4UserSteppingAction *const action)
void MakePETimeDistribution(const StationConstants::SignalComponent source=StationConstants::eTotal)
Create a PE release time distribution (optionally for given source)
Definition: PMTSimData.cc:12

, generated on Tue Sep 26 2023.