MdEdepSimulator.cc
Go to the documentation of this file.
1 #include "MdEdepSimulator.h"
3 #include "PhysicsList.h"
5 #include "PrimaryGenerator.h"
8 #include <G4RunManager.hh>
9 #include <G4UImanager.hh>
10 #include <G4VisManager.hh>
11 #include <G4VisExecutive.hh>
12 
13 #include <fwk/CentralConfig.h>
14 #include <fwk/RandomEngineRegistry.h>
15 
16 #include <det/Detector.h>
17 #include <mdet/Counter.h>
18 #include <mdet/Module.h>
19 #include <mdet/Scintillator.h>
20 
21 #include <evt/Event.h>
22 #include <mevt/Counter.h>
23 #include <mevt/Module.h>
24 #include <mevt/Scintillator.h>
25 #include <mevt/CounterSimData.h>
26 #include <mevt/ScintillatorSimData.h>
27 
28 #include <utl/ErrorLogger.h>
29 #include <utl/Reader.h>
30 #include <utl/Particle.h>
31 #include <utl/ShowerParticleIterator.h>
32 #include <utl/TimeDistribution.h>
33 #include <utl/TimeDistributionAlgorithm.h>
34 #include <utl/AugerUnits.h>
35 
36 #include <utl/TabularStream.h>
37 #include <utl/ConfigUtils.h>
38 
39 #include <cstddef>
40 #include <iostream>
41 #include <fstream>
42 #include <sstream>
43 
44 #include <CLHEP/Random/Random.h>
45 
46 #include <tls/Geant4Manager.h>
47 
48 using namespace utl;
49 using namespace fwk;
50 using namespace std;
51 using namespace evt;
52 using namespace mevt;
53 using namespace mdet;
54 using namespace det;
55 using namespace EdepSimulatorAG;
56 
57 const mdet::Scintillator* EdepSimulator::fCurrentDetectorScintillator = 0;
58 mevt::Module::ScintillatorIterator EdepSimulator::fCurrentEventScintillatorIt;
59 mevt::ScintillatorSimData::ParticleIterator EdepSimulator::fCurrentParticleIt;
60 
61 EdepSimulator::EdepSimulator() :
62  fUImanager(0),
63  fVisManager(0),
64  fSteppingAction(0)
65 {
66  fGeomVisOn = false;
67  fTrajVisOn = false;
68  fUseGlobalPhysicsList = false;
69 }
70 
72 
75 {
76  //Top branch
77 
78  Branch config = CentralConfig::GetInstance()->GetTopBranch("MdEdepSimulator");
79  fLog.Configure(config);
80  //Set energy units to MeV (otherwise default is eV)
83  fUnits.Configure(config);
84 
85  LoadConfig( config.GetChild("visualization"), "geometry", fGeomVisOn, 0 );
86  LoadConfig( config.GetChild("visualization"), "trajectories", fTrajVisOn, 0 );
87 
88  //Physics list branch
89  string physList;
90 
91  LoadConfig( config.GetChild("physics"), "list", physList, "QGSP_BERT");
92  LoadConfig(config, "globalPhysicsList", fUseGlobalPhysicsList, 1 );
93 
94  if ( (fGeomVisOn || fTrajVisOn) && !fVisManager) {
95  fVisManager = new G4VisExecutive();
96  }
97  if (!fRunManager) {
99  fRunManager = tls::Geant4Manager::GetInstance().GetRunManager();
100  else
101  fRunManager = new G4RunManager;
102  }
103 
104  LoadConfig(config, "verbosityLevel", fVerbosityLevel, 0 );
105  stringstream oss (ostringstream::out);
106  fUImanager = G4UImanager::GetUIpointer();
107 
108  oss << "/run/verbose " << fVerbosityLevel;
109  fUImanager->ApplyCommand( oss.str() );
110  oss.str("");
111  oss << "/event/verbose " << fVerbosityLevel;
112  fUImanager->ApplyCommand( oss.str() );
113  oss.str("");
114  oss << "/tracking/verbose " << fVerbosityLevel;
115  fUImanager->ApplyCommand( oss.str() );
116  oss.str("");
117  oss << "/stepping/verbose " << fVerbosityLevel;
118  fUImanager->ApplyCommand( oss.str() );
119 
121  tls::Geant4Manager::GetInstance().AddVisManager(fVisManager);
122 
123  INFO("using global PhysicsList from Geant4Manager");
124  PhysicsListCustomization* physicsListCustomization = new PhysicsListCustomization();
125 
126  INFO("\n++++\nConstructing G4 ground");
127  ScintillatorConstruction* scintConstruction = new ScintillatorConstruction();
128 
129  tls::Geant4Customization custom("MdEdepSimulator", scintConstruction, physicsListCustomization);
130 
131  INFO("\n++++\nInitializing G4 stepping action");
134 
135  INFO("\n++++\nInitializing G4 primary generator");
137 
138  tls::Geant4Manager::GetInstance().AddCustomization(custom);
139 
140  } else {
141  INFO("using PhysicsList from MdEdepSimulator");
142  fRunManager->SetUserInitialization(new PhysicsList);
143 
144  INFO("\n++++\nConstructing G4 ground");
145  fRunManager->SetUserInitialization(new ScintillatorConstruction());
146 
147  INFO("\n++++\nInitializing G4 stepping action");
149  fRunManager->SetUserAction(fSteppingAction);
150 
151  INFO("\n++++\nInitializing G4 primary generator");
152  fRunManager->SetUserAction(new PrimaryGenerator());
153 
154  fUImanager->ApplyCommand("/physlist/CutsAll 1 mm");
155 
156  //configure physicsList
157  oss.str("");
158  oss << "/physlist/Physics " << physList;
159  fUImanager->ApplyCommand( oss.str() );
160  }
161 
162  if ( fGeomVisOn || fTrajVisOn ) {
163  fVisManager->Initialize();
164  fUImanager->ApplyCommand("/vis/open HepRepFile");
165  fUImanager->ApplyCommand("/vis/scene/create");
166  fUImanager->ApplyCommand("/vis/sceneHandler/attach");
167  fUImanager->ApplyCommand("/vis/scene/add/volume");
168  fUImanager->ApplyCommand("/vis/drawVolume");
169  fUImanager->ApplyCommand("/vis/scene/notifyHandlers");
170  fUImanager->ApplyCommand("/vis/viewer/update");
171  }
172  if (fTrajVisOn) {
173  fUImanager->ApplyCommand("/tracking/storeTrajectory 1");
174  fUImanager->ApplyCommand("/vis/scene/add/trajectories rich");
175  }
176 
177  return eSuccess;
178 }
179 
180 void
182 {
183  string Sname, Pname;
184  int PDGCode(0), ParentID(0), TrackID(0);
185  //Position
186  double x(0), y(0), z(0);
187  //Direction
188  double px(0), py(0), pz(0);
189  //Energy & Time
190  double KinE(0), Time(0);
191 
193  DataCollection::iterator dIt;
194 
196 // G4cerr << "Map size before steps integration " << sstepMap.size() << endl;
197  for ( sstepIt = sstepMap.begin(); sstepIt != sstepMap.end(); ++sstepIt ) {
198 
199  DataCollection &cur = (*sstepIt).second;
200 // cout << " Scintillator ID " << (*sstepIt).first << endl;
201 
202  double totalEdep = 0;
203  bool first_particle = true;//to trace first particle entering in each scintillator
204 
205  for ( dIt = cur.begin(); dIt != cur.end(); ++dIt ) {
206 
207  Data data = (*dIt);
208  totalEdep += data.Edep;
209 
210  if ( first_particle ){
211  Sname = data.Sname ;
212  Pname = data.Pname ;
213  PDGCode = data.PDGCode ;
214  ParentID= data.ParentID;
215  TrackID = data.TrackID ;
216  x = data.x ;
217  y = data.y ;
218  z = data.z ;
219  px = data.px ;
220  py = data.py ;
221  pz = data.pz ;
222  KinE = data.KinE ;
223  Time = data.Time ;
224  first_particle = false;
225  }
226 /*
227  cout << "Pname " << data.Pname << " - " << data.KinE/CLHEP::MeV << " (MeV)" << endl;
228  cout << "PDGCode " << data.PDGCode << " - " << data.Time/CLHEP::ns << " (ns)" << endl;
229  cout << "ParentID " << data.ParentID << endl;
230  cout << "TrackID " << data.TrackID << " - " << data.Sname << endl;
231  cout << "Edep " << data.Edep/CLHEP::MeV << " (MeV)" << endl;
232  cout << "x " << data.x/CLHEP::m << endl;
233  cout << "y " << data.y/CLHEP::m << endl;
234  cout << "z " << data.z/CLHEP::m << endl;
235  cout << "px " << data.px << endl;
236  cout << "py " << data.py << endl;
237  cout << "pz " << data.pz << endl;
238 */
239  }//end loop on steps
240 
241  //If scintId (key) not found, then creates the key
242  if ( scintMap.find( (*sstepIt).first ) == scintMap.end()){
243  DataCollection nuovo;
244 // G4cerr << "Scinti ID " << (*sstepIt).first << " not found in scintMap... I will creat it" << G4endl;
245  scintMap[ (*sstepIt).first] = nuovo;
246  }
247  Data partdata;
248  //Fill obj with relevant step data
249  partdata.Sname = Sname;
250  partdata.Pname = Pname;
251  partdata.PDGCode = PDGCode;
252  partdata.ParentID= ParentID;
253  partdata.TrackID = TrackID;
254  partdata.x = x;
255  partdata.y = y;
256  partdata.z = z;
257  partdata.px = px;
258  partdata.py = py;
259  partdata.pz = pz;
260  partdata.KinE = KinE;
261  partdata.Edep = totalEdep;//HERE IS ALL WE NEED ACTUALLY :-)
262  partdata.Time = Time;
264  //Fill the vector with the data of a given scintillator
265  scintMap[(*sstepIt).first].push_back( partdata );
266  }//end loop on scintillators
267  fSteppingAction->ClearMap();//Map of steps
268 // G4cerr << "Cleared map (size " << fSteppingAction->GetScintMap().size() << ")" << G4endl << G4endl;
269 }
270 
273 {
274  if (!event.HasMEvent()) {
275  ERROR("\nMEvent does not exist.");
276  return eFailure;
277  }
278 
279  // Get the MEvent
280  MEvent& mEvent = event.GetMEvent();
281 
282  if (mEvent.GetNumberOfCounters() > 0) {
283  INFO("\n++++\nActivating G4 for this run");
285  fRunManager->Initialize();
286  } else {
287  tls::Geant4Manager::GetInstance().Customize("MdEdepSimulator");
288  }
289  }
290 
291  // Get the MDetector
292  const MDetector& mDetector = Detector::GetInstance().GetMDetector();
293 
294  for (MEvent::CounterIterator cIt = mEvent.CountersBegin(); cIt != mEvent.CountersEnd(); ++cIt) {
295 
296  const int counterId = cIt->GetId();
297  const mdet::Counter& counter = mDetector.GetCounter(counterId);
298  for (mevt::Counter::ModuleIterator im = cIt->ModulesBegin(), em = cIt->ModulesEnd(); im != em; ++im) {
299 
300  const int modId = im->GetId();
301  const mdet::Module& module = counter.GetModule(modId);
302 
303  SteppingAction::ScintMap scintMap;
304 
305  for (mevt::Module::ScintillatorIterator is = im->ScintillatorsBegin(), es = im->ScintillatorsEnd();
306  is != es; ++is) {
307  if (is->HasSimData()) {
308  //const mdet::Scintillator& scint = module.GetScintillator(is->GetId());
309  mevt::ScintillatorSimData& sSimData = is->GetSimData();
311  const int scintId = is->GetId();
313 
314  if( sSimData.GetNumberOfParticles() != 0 ) {
315  fLog("Counter ", 1, false)( counterId )(" ");
316  fLog("Module ", 1, false)( modId )(" ");
317  fLog("Scint. ", 1)( scintId )(" has : ")( sSimData.GetNumberOfParticles())(" particles on top" );
318  }
319 
320  fSteppingAction->SetScintillatorId( scintId );//Store ID of current scintillator (to distinguish it from neighours)
321 
323  pIt != sSimData.ParticlesEnd(); ++pIt) {
324 
325  fCurrentParticleIt = pIt;
326  if ( fCurrentParticleIt->HasParent() ) {
327  utl::Particle * parent = new Particle(fCurrentParticleIt->GetParent() );
329  }
330 
331  //Run G4 simulation
332  fRunManager->BeamOn(1);
333 
334  //Integrate all particle steps plus secondary particles data
335  //in central and (if needed) in lateral scintillators
336  //where particles might have deposited energy
337  AddUpContributions( scintMap );
338 
339  }//end loop on particles in a given scintillator
340 
341  //Remove already processes particles in this scintillator
342  sSimData.ClearParticleList();
343 
344  }//end if is->HasSimData()
345  }//scintillator loop
346 
348 
349  // Table for the inserted particles.
350  const unsigned int particleTableLogLevel = 2;
351  std::unique_ptr<utl::TabularStream> table;
352  if (fLog.GetLevel() >= particleTableLogLevel) {
353  //-----------------------------------1-2-3-4-5-6-7-8-9-10-11-12
354  table.reset(new utl::TabularStream("|r|r|r|r|r|r|r|r|r|r|r|r|"));
355  fLog.ApplyConfigurationOn(*table);
356  *table << utl::hline
357  << '#' << utl::endc //1
358  << "name" << utl::endc //2
359  << "parentID" << utl::endc //3
360  << "trackID" << utl::endc //4
361  << "kin. energy" << "(" << fUnits.GetEnergyName() << ")" << utl::endc //5
362  << "x" << "(" << fUnits.GetLengthName() << ")" << utl::endc //6
363  << "y" << "(" << fUnits.GetLengthName() << ")" << utl::endc //7
364  << "z" << "(" << fUnits.GetLengthName() << ")" << utl::endc //8
365  << "energy dep." << "(" << fUnits.GetEnergyName() << ")" << utl::endc //9
366  << "px " << utl::endc //10
367  << "py " << utl::endc //11
368  << "pz " << utl::endr //12
369  << utl::hline;
370  }
371 
372  for ( scintIt = scintMap.begin(); scintIt != scintMap.end(); ++scintIt ) {
373 
374  DataCollection::iterator dIt;
375  DataCollection &cur = (*scintIt).second;
376  int ScIdx = (*scintIt).first;
377  /*
378  cout << "\n*************\n";
379  cout << "Found Scintillator ID " << ScIdx << endl;
380  */
381  if (!im->HasScintillator(ScIdx)) {
382  im->MakeScintillator(ScIdx);
383  im->GetScintillator(ScIdx).MakeSimData();
384  }
385 
386  for (mevt::Module::ScintillatorIterator is = im->ScintillatorsBegin(), es = im->ScintillatorsEnd();
387  is != es; ++is) {
388 
389  const int scintId = is->GetId();
390 
391  if( (*scintIt).first != scintId )
392  continue;
393 
394  const CoordinateSystemPtr ScintillatorCS = module.GetScintillator(scintId).GetLocalCoordinateSystem();
395  mevt::ScintillatorSimData& sSimData = is->GetSimData();
396 
397  fLog("Particles that deposited energy in scintillator ", 5 )(scintId)(" : ")( cur.size() );
398 
399  int n = 0;
400  for ( dIt = cur.begin(); dIt != cur.end(); ++dIt, ++n ) {
401 
402  Data data = (*dIt);
403 
404  // only accumulate in the table if it will be used at last:
405  if (fLog.GetLevel() >= particleTableLogLevel) {
406  *table << (n+1) << utl::endc
407  << fLog << data.Pname << " (PDG code " << data.PDGCode << ")" << utl::endc
408  << fLog << data.ParentID << utl::endc
409  << fLog << data.TrackID << utl::endc
411  << fLog << data.x /CLHEP::m * utl::m / fUnits.GetLengthUnit() << utl::endc
412  << fLog << data.y /CLHEP::m * utl::m / fUnits.GetLengthUnit() << utl::endc
413  << fLog << data.z /CLHEP::m * utl::m / fUnits.GetLengthUnit() << utl::endc
415  << fLog << data.px << utl::endc
416  << fLog << data.py << utl::endc
417  << fLog << data.pz << utl::endr;
418  }
419 
420  Point pPos( data.x/CLHEP::m * utl::m, data.y/CLHEP::m * utl::m, data.z/CLHEP::m * utl::m, ScintillatorCS);
421  Vector pDir( data.px, data.py, data.pz, ScintillatorCS );
422  //Creates new particle (uses kinetic energy to pass the energy deposited by the particle)
423  //#warning "ENERGY DEPOSITED BY THE PARTICLE IS NOW PASSED in the WEIGHT field (a la MARTA :-))"
424  Particle part( data.PDGCode, utl::Particle::eShower, pPos, pDir, data.Time/CLHEP::ns*utl::ns, data.Edep/CLHEP::MeV*utl::MeV, data.KinE/CLHEP::MeV * utl::MeV );
425 
426 
427  if ( data.PParent )
428  part.SetParent( *data.PParent );
429 
430  sSimData.AddParticle( part );
431 
432  }//end loop on steps
433 
434  }//end of mevt::scintillator loop
435  }//end of scintiMap loop
436  scintMap.clear();
437  scintMap.erase( scintMap.begin(), scintMap.end() );
438 
439  if (fLog.GetLevel() >= particleTableLogLevel) {
440  *table << utl::hline;
441  fLog("Particle table after G4 Scintillator simulation:", particleTableLogLevel);
442  fLog(table->Str(), particleTableLogLevel);
443  }
444  }//end of module loop
445  }//end loop on counters with particles on ground
446  cout << endl;
447 
448  return eSuccess;
449 }
450 
453 {
454  if (fUseGlobalPhysicsList) {
455  tls::Geant4Manager::GetInstance().NotifyDelete();
456  } else {
457  if (fRunManager) {
458  delete fRunManager;
459  fRunManager = 0;
460  }
461  }
462 
463  return eSuccess;
464 }
Branch GetTopBranch() const
Definition: Branch.cc:63
int GetNumberOfCounters() const
Definition: MEvent.h:46
const Module & GetModule(const int mId) const
Retrieve by id a constant module.
CounterConstIterator CountersBegin() const
Definition: MEvent.h:49
Point object.
Definition: Point.h:32
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
void SetPrimaryGenerator(G4VUserPrimaryGeneratorAction *const action)
bool HasMEvent() const
Report success to RunController.
Definition: VModule.h:62
double GetLengthUnit() const
Definition: UnitsConfig.h:121
Describes a particle for Simulation.
Definition: Particle.h:26
const std::string & GetLengthName() const
Definition: UnitsConfig.h:95
void SetEnergyDefault(const double unit, const std::string &name)
Definition: UnitsConfig.cc:120
bool is(const double a, const double b)
Definition: testlib.cc:113
utl::CoordinateSystemPtr GetLocalCoordinateSystem() const
Local system based on position and configured rotations.
static const mdet::Scintillator * fCurrentDetectorScintillator
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void AddParticle(const utl::Particle &particle)
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
Detector associated to muon detector hierarchy.
Definition: MDetector.h:32
fwk::VModule::ResultFlag Run(evt::Event &theEvent)
Run: invoked once per event.
constexpr double MeV
Definition: AugerUnits.h:184
Actual muon-sensitive objects.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
utl::MessageLoggerConfig fLog
Output messages handler.
Class representing a document branch.
Definition: Branch.h:107
boost::indirect_iterator< InternalParticleIterator, utl::Particle & > ParticleIterator
static mevt::ScintillatorSimData::ParticleIterator fCurrentParticleIt
const double ns
void Configure(const utl::Branch &config)
Configure units (values and defaults) given a branch.
Definition: UnitsConfig.cc:395
allow customization of the standard global PhysicsList that are handled by the Geant4Manager ...
const unsigned int & GetLevel() const
Retrieve (read-only) the current level of verbosity.
const EndRow endr
void SetLengthDefault(const double unit, const std::string &name)
Definition: UnitsConfig.cc:155
Array of Scintillator.
void Configure(const Branch &config)
class to format data in tabular form
Data structure to hold the different Geant4 global objects required to run a single module...
void AddUpContributions(SteppingAction::ScintMap &)
utl::UnitsConfig fUnits
Units configuration.
static mevt::Module::ScintillatorIterator fCurrentEventScintillatorIt
InternalModuleCollection::ComponentIterator ModuleIterator
G4RunManager * fRunManager
Private G4 members.
Root detector of the muon detector hierarchy.
const std::string & GetEnergyName() const
Definition: UnitsConfig.h:90
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
Scintillator level simulation data.
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
double GetEnergyUnit() const
Definition: UnitsConfig.h:116
InternalCounterCollection::ComponentIterator CounterIterator
Definition: MEvent.h:31
uint16_t * data
Definition: dump1090.h:228
constexpr double cm
Definition: AugerUnits.h:117
InternalScintillatorCollection::ComponentIterator ScintillatorIterator
void LoadConfig(const utl::Branch &b, const std::string &tag, T1 &var, const T2 &defaultValue)
Helper method to load a particular configuration parameter.
Definition: ConfigUtils.h:35
Vector object.
Definition: Vector.h:30
Report failure to RunController, causing RunController to terminate execution.
Definition: VModule.h:64
CounterConstIterator CountersEnd() const
Definition: MEvent.h:52
constexpr double ns
Definition: AugerUnits.h:162
int GetId() const
The id of this component.
void SetParent(Particle &parent)
Definition: Particle.h:150
unsigned int GetNumberOfParticles() const
const Scintillator & GetScintillator(int sId) const
Direct accesor by id.
const Counter & GetCounter(int id) const
Retrieve Counter by id.
Definition: MDetector.h:68
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
const HLine hline('-')
const EndColumn endc
Root of the Muon event hierarchy.
Definition: MEvent.h:25
void SetSteppingAction(G4UserSteppingAction *const action)

, generated on Tue Sep 26 2023.