GEMC  1.8
Geant4 Monte-Carlo Framework
MEventAction.cc
Go to the documentation of this file.
1 // %%%%%%%%%%
2 // G4 headers
3 // %%%%%%%%%%
4 #include "G4Event.hh"
5 #include "G4RunManager.hh"
6 #include "G4Trajectory.hh"
7 
8 // %%%%%%%%%%%%%
9 // gemc headers
10 // %%%%%%%%%%%%%
11 #include "MEventAction.h"
12 #include "MHit.h"
13 
14 #include <iostream>
15 using namespace std;
16 // the following functions return the pid, mpid and charges vector<int> from a map<int, TInfos>
17 
18 vector<int> vector_zint(int size)
19 {
20  vector<int> zints;
21  for(int t=0; t<size; t++)
22  zints.push_back(0);
23 
24  return zints;
25 }
26 
27 vector<G4ThreeVector> vector_zthre(int size)
28 {
29  vector<G4ThreeVector> zthre;
30  for(int t=0; t<size; t++)
31  zthre.push_back(G4ThreeVector(0,0,0));
32 
33  return zthre;
34 }
35 
36 vector<int> vector_mtids(map<int, TInfos> tinfos, vector<int> tids)
37 {
38  vector<int> mtids;
39  for(unsigned int t=0; t<tids.size(); t++)
40  mtids.push_back(tinfos[tids[t]].mtid);
41 
42  return mtids;
43 }
44 
45 vector<int> vector_mpids(map<int, TInfos> tinfos, vector<int> tids)
46 {
47  vector<int> mpids;
48  for(unsigned int t=0; t<tids.size(); t++)
49  mpids.push_back(tinfos[tids[t]].mpid);
50 
51  return mpids;
52 }
53 
54 vector<G4ThreeVector> vector_mvert(map<int, TInfos> tinfos, vector<int> tids)
55 {
56  vector<G4ThreeVector> mvert;
57  for(unsigned int t=0; t<tids.size(); t++)
58  mvert.push_back(tinfos[tids[t]].mv);
59 
60  return mvert;
61 }
62 
63 MEventAction::MEventAction(gemc_opts opts, map<string, double> gpars)
64 {
65  gemcOpt = opts;
66  hd_msg = gemcOpt.args["LOG_MSG"].args + " Event Action: >> ";
67  Modulo = (int) gemcOpt.args["PRINT_EVENT"].arg ;
68  VERB = gemcOpt.args["OUT_VERBOSITY"].arg ;
69  catch_v = gemcOpt.args["CATCH"].args;
70  SAVE_ALL_MOTHERS = (int) gemcOpt.args["SAVE_ALL_MOTHERS"].arg ;
71  gPars = gpars;
72  MAXP = (int) gemcOpt.args["NGENP"].arg;
73 }
74 
76 {
77  ;
78 }
79 
80 void MEventAction::BeginOfEventAction(const G4Event* evt)
81 {
82  if(evtN%Modulo == 0 )
83  {
84  cout << hd_msg << " Begin of event " << evtN << endl;
85  cout << hd_msg << " Random Number: " << G4UniformRand() << endl;
86  // CLHEP::HepRandom::showEngineStatus();
87  }
88 }
89 
90 void MEventAction::EndOfEventAction(const G4Event* evt)
91 {
92  if(evtN%Modulo == 0 )
93  cout << hd_msg << " End of Event " << evtN << " Routine..." << endl;
94 
95  MHitCollection* MHC;
96  MHit* aHit;
97  int nhits;
98 
99  // building the tracks database with all the tracks in all the hits
100  // if SAVE_ALL_MOTHERS is set
101  set<int> track_db;
102  if(SAVE_ALL_MOTHERS)
103  for(map<string, MSensitiveDetector*>::iterator it = SeDe_Map.begin(); it!= SeDe_Map.end(); it++)
104  {
105  string hitType;
106 
107  MHC = it->second->GetMHitCollection();
108  nhits = MHC->GetSize();
109 
110  for(int h=0; h<nhits; h++)
111  {
112  vector<int> tids = (*MHC)[h]->GetTIds();
113  for(unsigned int t=0; t<tids.size(); t++)
114  track_db.insert(tids[t]);
115  }
116  }
117 
118  // now filling the map of tinfos with tracks infos from the track_db database
119  // this won't get the mother particle infos except for their track ID
120  map<int, TInfos> tinfos;
121  set<int>::iterator it;
122 
123  // the container is full only if /tracking/storeTrajectory 2
124  G4TrajectoryContainer *trajectoryContainer;
125 
126  if(SAVE_ALL_MOTHERS)
127  {
128  trajectoryContainer = evt->GetTrajectoryContainer();
129 
130  while(trajectoryContainer && track_db.size())
131  {
132  // looping over all tracks
133  for(unsigned int i=0; i< trajectoryContainer->size(); i++)
134  {
135  // cout << " index track " << i << endl;
136  G4Trajectory* trj = (G4Trajectory*)(*(evt->GetTrajectoryContainer()))[i];
137  int tid = trj->GetTrackID();
138 
139  // is this track involved in a hit?
140  // if yes, add it to the map
141  it = track_db.find(tid);
142  if(it != track_db.end())
143  {
144  int mtid = trj->GetParentID();
145  tinfos[tid] = TInfos(mtid);
146  // cout << " At map level: " << tid << " " <<mtid << " " << pid << " charge: " << q << endl;
147  // remove the track from the database so we don't have to loop over it next time
148  track_db.erase(it);
149  }
150  }
151  }
152 
153 
154  // now accessing the mother particle infos
155  map<int, TInfos>::iterator itm;
156  for(itm = tinfos.begin(); itm != tinfos.end(); itm++)
157  {
158  int mtid = (*itm).second.mtid;
159  // looking for mtid infos in the trajectoryContainer
160  for(unsigned int i=0; i< trajectoryContainer->size() && mtid != 0; i++)
161  {
162  G4Trajectory* trj = (G4Trajectory*)(*(evt->GetTrajectoryContainer()))[i];
163  int tid = trj->GetTrackID();
164  if(tid == mtid)
165  {
166  tinfos[(*itm).first].mpid = trj->GetPDGEncoding();
167  tinfos[(*itm).first].mv = trj->GetPoint(0)->GetPosition();
168  }
169  }
170  }
171  }
172 
173 
174  PH_output output;
175  double Etot;
176 
177  // Making sure the output routine exists in the ProcessOutput map
178  // If no output selected, or HitProcess not found, end current event
179  map<string, MOutput_Factory>::iterator ito = Out->find(MOut->outType);
180  if(ito == Out->end())
181  {
182  if(MOut->outType != "no")
183  cout << hd_msg << " Warning: output type <" << MOut->outType << "> is not registered in the <MOutput_Factory>. " << endl
184  << " This event will not be written out." << endl;
185  evtN++;
186  return;
187  }
188  MOutputBaseClass *ProcessOutput = GetMOutputClass(Out, MOut->outType);
189 
190 
191  // Header Bank contains event number
192  // Need to change this to read DB header bank
193  //
194  header head;
195  head.evn = evtN;
196  head.type = -1;
197  head.beamPol = gen_action->getBeamPol();
198  head.targetPol = gen_action->getTargetPol();
199 
200  ProcessOutput->SetOutpHeader(head, MOut);
201 
202  // Getting Generated Particles info
203  vector<MGeneratedParticle> MPrimaries;
204  for(int pv=0; pv<evt->GetNumberOfPrimaryVertex() && pv<MAXP; pv++)
205  {
206  MGeneratedParticle Mparticle;
207  G4PrimaryVertex* MPV = evt->GetPrimaryVertex(pv);
208  Mparticle.vertex = MPV->GetPosition();
209  for(int pp = 0; pp<MPV->GetNumberOfParticle() && pv<MAXP; pp++)
210  {
211 
212  G4PrimaryParticle *PP = MPV->GetPrimary(pp);
213  Mparticle.momentum = PP->GetMomentum();
214  Mparticle.PID = PP->GetPDGcode();
215  }
216  MPrimaries.push_back(Mparticle) ;
217  }
218  ProcessOutput-> WriteGenerated(MOut, MPrimaries);
219 
220  for(map<string, MSensitiveDetector*>::iterator it = SeDe_Map.begin(); it!= SeDe_Map.end(); it++)
221  {
222  string hitType;
223 
224  MHC = it->second->GetMHitCollection();
225  nhits = MHC->GetSize();
226 
227 
228  // The same ProcessHit Routine must apply to all the hits in this HitCollection.
229  // Instantiating the ProcessHitRoutine only once for the first hit.
230  if(nhits)
231  {
232  ProcessOutput->SetBankHeader(it->second->SDID.id, it->first, MOut);
233 
234  aHit = (*MHC)[0];
235  string vname = aHit->GetDetector().name;
236  hitType = it->second->GetDetectorHitType(vname);
237 
238  // Making sure the Routine exists in the MProcessHit_Map
239  map<string, MPHB_Factory>::iterator itp = MProcessHit_Map->find(hitType);
240  if(itp == MProcessHit_Map->end())
241  {
242  cout << hd_msg << " Warning: hit Type <" << hitType << "> is not registered in the <MProcessHit_Map>. " << endl
243  << " This hit collection will not be processed." << endl;
244  return;
245  }
246 
247  MPHBaseClass *ProcessHitRoutine = GetMPHClass(MProcessHit_Map, hitType);
248  ProcessHitRoutine->gpars = gPars;
249 
250  for(int h=0; h<nhits; h++)
251  {
252  aHit = (*MHC)[h];
253 
254  if(SAVE_ALL_MOTHERS)
255  {
256  // setting track infos before processing the hit
257  vector<int> tids = aHit->GetTIds();
258  aHit->SetmTrackIds(vector_mtids( tinfos, tids));
259  aHit->SetmPIDs( vector_mpids( tinfos, tids));
260  aHit->SetmVerts( vector_mvert( tinfos, tids));
261  }
262  else
263  {
264  int thisHitSize = aHit->GetId().size();
265  vector<int> zint = vector_zint(thisHitSize);
266  vector<G4ThreeVector> zthre = vector_zthre(thisHitSize);
267  aHit->SetmTrackIds(zint);
268  aHit->SetmPIDs( zint);
269  aHit->SetmVerts( zthre);
270 
271  }
272  output = ProcessHitRoutine->ProcessHit(aHit, gemcOpt);
273  ProcessOutput->ProcessOutput(output, MOut, (*MBank_Map)[hitType]);
274 
275  string vname = aHit->GetId()[aHit->GetId().size()-1].name;
276  if(VERB > 4 || vname.find(catch_v) != string::npos)
277  {
278  cout << hd_msg << " Hit " << h + 1 << " -- total number of steps this hit: " << aHit->GetPos().size() << endl;
279  cout << aHit->GetId();
280  Etot = 0;
281  for(unsigned int e=0; e<aHit->GetPos().size(); e++) Etot = Etot + aHit->GetEdep()[e];
282  cout << " Total energy deposited: " << Etot/MeV << " MeV" << endl;
283  }
284  }
285  delete ProcessHitRoutine;
286 
287  // cout << it->second->HCname << " " << evtN << " " << nhits << endl;
288  }
289  ProcessOutput->RecordAndClear(MOut, (*MBank_Map)[hitType]);
290 
291  }
292  ProcessOutput->WriteEvent(MOut);
293 
294  // merging information from another file
295 
296 
297 
298  delete ProcessOutput;
299 
300  if(evtN%Modulo == 0 )
301  cout << " done." << endl << endl;;
302 
303  evtN++;
304  return;
305 }
306 
307 
308 
309 
310 
311 
312 
313 
314 
315 
316 
virtual PH_output ProcessHit(MHit *, gemc_opts)=0
Virtual Method to process the hit.
G4ThreeVector momentum
void SetmPIDs(vector< int > mpid)
Definition: MHit.h:121
STL namespace.
void SetmTrackIds(vector< int > tid)
Definition: MHit.h:116
vector< identifier > GetId()
Definition: MHit.h:96
Definition: usage.h:43
double beamPol
Beam Polarization.
virtual void WriteEvent(MOutputs *)=0
Pure Virtual Method to write event on disk.
G4THitsCollection< MHit > MHitCollection
Definition: MHit.h:134
vector< G4ThreeVector > vector_zthre(int size)
provides a vector of (0,0,0)
Definition: MEventAction.cc:27
vector< int > vector_mpids(map< int, TInfos > tinfos, vector< int > tids)
Definition: MEventAction.cc:45
void EndOfEventAction(const G4Event *)
Routine at the end of each event.
Definition: MEventAction.cc:90
void BeginOfEventAction(const G4Event *)
Routine at the start of each event.
Definition: MEventAction.cc:80
MEventAction(gemc_opts, map< string, double >)
Constructor copies gemc options.
Definition: MEventAction.cc:63
vector< G4ThreeVector > vector_mvert(map< int, TInfos > tinfos, vector< int > tids)
Definition: MEventAction.cc:54
MOutputBaseClass * GetMOutputClass(map< string, MOutput_Factory > *MProcessOutput_Map, string outputType)
Instantiates MOutputBaseClass.
vector< G4ThreeVector > GetPos()
Definition: MHit.h:65
string name
Name of the volume. Since this is the key of the STL map, it has to be unique.
Definition: detector.h:53
map< string, double > gpars
Definition: MPHBaseClass.h:42
MPHBaseClass * GetMPHClass(map< string, MPHB_Factory > *MProcessHit_Map, string HCname)
Return MPHBaseClass from the Hit Process Map.
Definition: MPHBaseClass.cc:8
G4ThreeVector vertex
Definition: MHit.h:29
vector< int > vector_mtids(map< int, TInfos > tinfos, vector< int > tids)
Definition: MEventAction.cc:36
virtual void RecordAndClear(MOutputs *, MBank)=0
Pure Virtual Method to record hits in event / then clear hits objects on heap.
map< string, opts > args
Options map.
Definition: usage.h:68
double targetPol
Target Polarization.
vector< int > GetTIds()
Definition: MHit.h:94
virtual void SetOutpHeader(header, MOutputs *)=0
Pure Virtual Method to set the output header. MOutputs needed for some output (txt) ...
vector< double > GetEdep()
Definition: MHit.h:76
void SetmVerts(vector< G4ThreeVector > ver)
Definition: MHit.h:126
virtual void SetBankHeader(int, string, MOutputs *)=0
Pure Virtual Method to set the bank header.
detector GetDetector()
Definition: MHit.h:101
~MEventAction()
Destructor.
Definition: MEventAction.cc:75
int evn
Event number.
vector< int > vector_zint(int size)
provides a vector of 0
Definition: MEventAction.cc:18
virtual void ProcessOutput(PH_output, MOutputs *, MBank)=0
Pure Virtual Method to process the output.