ACTARSim
ACTAR TPC Simulation Reference Guide
ActarSimROOTAnalSil.cc
Go to the documentation of this file.
1 // - AUTHOR: Hector Alvarez-Pol 05/2005
2 /******************************************************************
3  * Copyright (C) 2005-2016, Hector Alvarez-Pol *
4  * All rights reserved. *
5  * *
6  * License according to GNU LESSER GPL (see lgpl-3.0.txt). *
7  * For the list of contributors see CREDITS. *
8  ******************************************************************/
9 //////////////////////////////////////////////////////////////////
10 /// \class ActarSimROOTAnalSil
11 /// The ACTAR Silicon detectorpart of the ROOT Analysis
12 /////////////////////////////////////////////////////////////////
13 
14 #include "ActarSimROOTAnalSil.hh"
15 
16 #include "G4ios.hh"
17 #include "G4RunManager.hh"
18 #include "G4SDManager.hh"
19 #include "G4Event.hh"
20 #include "G4Run.hh"
21 #include "G4Track.hh"
22 #include "G4ClassificationOfNewTrack.hh"
23 #include "G4TrackStatus.hh"
24 #include "G4Step.hh"
25 #include "G4Types.hh"
26 
27 //#include "G4PhysicalConstants.hh"
28 //#include "G4SystemOfUnits.hh"
29 
30 //ROOT INCLUDES
31 #include "TROOT.h"
32 //#include "TApplication.h"
33 //#include "TSystem.h"
34 //#include "TH1.h"
35 //#include "TH2.h"
36 //#include "TPad.h"
37 //#include "TCanvas.h"
38 #include "TTree.h"
39 #include "TFile.h"
40 #include "TClonesArray.h"
41 
42 //////////////////////////////////////////////////////////////////
43 /// Constructor
45  //The simulation file
47  simFile->cd();
48 
49  //The tree
51 
52  //The clones array of Sci Hits
53  //TODO-> Repeat here the trick SimpleHit/HitSim/Hit that is existing in ActarSimAnalSil.cc
54  silHitCA = new TClonesArray("ActarSimSilHit",2);
55 
56  silHitsBranch = eventTree->Branch("silHits",&silHitCA);
57  silHitsBranch->SetAutoDelete(kTRUE);
58 }
59 
60 //////////////////////////////////////////////////////////////////
61 /// Destructor. Makes nothing.
63 }
64 
65 //////////////////////////////////////////////////////////////////
66 /// Actions to perform in the silicon anal when generating the primaries
67 void ActarSimROOTAnalSil::GeneratePrimaries(const G4Event *anEvent){
68  if(anEvent){;} /* keep the compiler "quiet" */
69 }
70 
71 //////////////////////////////////////////////////////////////////
72 /// Actions to perform in the silicon anal at the begining of the run
73 void ActarSimROOTAnalSil::BeginOfRunAction(const G4Run *aRun) {
74  if (aRun){;} /* keep the compiler "quiet" */
75 
76  //Storing the runID
77  SetTheRunID(aRun->GetRunID());
78 
79  char newDirName[255];
80  sprintf(newDirName,"%s%i","Histos",aRun->GetRunID());
81  simFile->cd(newDirName);
82 
83  dirName = new char[255];
84 
85  sprintf(dirName,"%s","sil");
86  gDirectory->mkdir(dirName,dirName);
87  gDirectory->cd(dirName);
88 
89  simFile->cd();
90 }
91 
92 //////////////////////////////////////////////////////////////////
93 /// Actions to perform in the silicon anal at the begining of the event
94 void ActarSimROOTAnalSil::BeginOfEventAction(const G4Event *anEvent) {
95  SetTheEventID(anEvent->GetEventID());
96 }
97 
98 //////////////////////////////////////////////////////////////////
99 /// Actions to perform in the silicon anal at the beginning of the run
100 /// Defining the ActarSimSilHit from the ActarSimSilGeantHits
101 void ActarSimROOTAnalSil::EndOfEventAction(const G4Event *anEvent) {
102  FillingHits(anEvent);
103 }
104 
105 //////////////////////////////////////////////////////////////////
106 /// Defining the ActarSimSilHits from the ActarSimSilGeantHits
107 ///
108 /// A simple algorithm checking the number of primaries
109 /// reaching the Sil and calculating their mean parameters
110 /// taking into account their energy deposition on the silicons
111 /// NOTE that only primaries can produce Hits following this scheme
112 void ActarSimROOTAnalSil::FillingHits(const G4Event *anEvent) {
113  //Hit Container ID for ActarSimSilGeantHit
114  G4int hitsCollectionID =
115  G4SDManager::GetSDMpointer()->GetCollectionID("SilCollection");
116 
117  G4HCofThisEvent* HCofEvent = anEvent->GetHCofThisEvent();
118 
119  ActarSimSilGeantHitsCollection* hitsCollection =
120  (ActarSimSilGeantHitsCollection*) HCofEvent->GetHC(hitsCollectionID);
121 
122  //Number of ActarSimSilGeantHit (or steps) in the hitsCollection
123  G4int NbHits = hitsCollection->entries();
124 
125  G4int indepHits = 0; //number of Hits
126  G4int* trackIDtable; //stores the trackID of primary particles for each (valid) GeantHit
127  trackIDtable = new G4int[NbHits];
128  G4int* detIDtable; //stores the detIDs for each (valid) GeantHit
129  detIDtable = new G4int[NbHits];
130  G4int* IDtable; //stores the order in previous array for each (valid) GeantHit
131  IDtable = new G4int[NbHits];
132 
133  for (G4int i=0;i<NbHits;i++) {
134  if((*hitsCollection)[i]->GetParentID()==0) { //step from primary
135  if(indepHits==0) { //only for the first Hit
136  trackIDtable[indepHits] = (*hitsCollection)[i]->GetTrackID();
137  detIDtable[indepHits] = (*hitsCollection)[i]->GetDetID();
138  IDtable[i] = indepHits;
139  indepHits++;
140  }
141  else { // this part is never reached. Maybe because there is always only one indepHits that has parentID equals to 0.
142  for(G4int j=0; j<indepHits;j++) {
143  if( (*hitsCollection)[i]->GetTrackID() == trackIDtable[j] &&
144  (*hitsCollection)[i]->GetDetID() == detIDtable[j]) { //checking trackID and detID
145  IDtable[i] = j;
146  break; //not a new Hit
147  }
148  if(j==indepHits-1){ //we got the last hit and there was no match!
149  trackIDtable[indepHits] = (*hitsCollection)[i]->GetTrackID();
150  detIDtable[indepHits] = (*hitsCollection)[i]->GetDetID();
151  IDtable[i] = indepHits;
152  indepHits++;
153  }
154  }
155  }
156  }
157  }
158 
159  //Let us create as many ActarSimSilHit as independent primary particles
160  theSilHit = new ActarSimSilHit*[indepHits];
161  for (G4int i=0;i<indepHits;i++)
162  theSilHit[i] = new ActarSimSilHit();
163 
164  //Clear the ClonesArray before filling it
165  silHitCA->Clear();
166 
167  //a variable to check if the Hit was already created
168  G4int* existing;
169  existing = new G4int[indepHits];
170  for(G4int i=0;i<indepHits;i++) existing[i] = 0;
171 
172  for(G4int i=0;i<NbHits;i++) {
173  if( (*hitsCollection)[i]->GetParentID()==0 ) { //step from primary
174  //the IDtable[i] contains the order in the indepHits list
175  if( existing[IDtable[i]]==0) { //if the indepHits does not exist
176  AddSilHit(theSilHit[IDtable[i]],(*hitsCollection)[i],0);
177  existing[IDtable[i]] = 1;
178  }
179  else
180  AddSilHit(theSilHit[IDtable[i]],(*hitsCollection)[i],1);
181  }
182  }
183 
184  //at the end, fill the ClonesArray
185  for (G4int i=0;i<indepHits;i++){
186  //G4cout<<"ActarSimROOTAnalSil----------->FillingHits() "<<silHitCA<<G4endl;
187  new((*silHitCA)[i])ActarSimSilHit(*theSilHit[i]);
188  //G4cout<<"ActarSimROOTAnalSil----------->FillingHits() "<<silHitCA<<G4endl;
189  }
190  delete [] trackIDtable;
191  delete [] IDtable;
192  delete [] existing;
193  delete [] detIDtable;
194  for (G4int i=0;i<indepHits;i++) delete theSilHit[i];
195  delete [] theSilHit;
196 }
197 
198 //////////////////////////////////////////////////////////////////
199 /// Function to move the information from the ActarSimSilGeantHit (a step hit)
200 /// to ActarSimSilHit (a simple primary representation in the silicon)
201 ///
202 /// Two modes are possible:
203 /// - mode == 0 : creation; the ActarSimSilHit is void and is
204 /// filled by the data from the ActarSimSilGeantHit
205 /// - mode == 1 : addition; the ActarSimSilHit was already created
206 /// by other ActarSimSilGeantHit and some data members are updated
208  ActarSimSilGeantHit* gHit,
209  G4int mode) {
210  if(mode == 0) { //creation
211  cHit->SetDetectorID(gHit->GetDetID());
212 
213  cHit->SetXPos(gHit->GetLocalPrePos().x()/CLHEP::mm);
214  cHit->SetYPos(gHit->GetLocalPrePos().y()/CLHEP::mm);
215  cHit->SetZPos(gHit->GetLocalPrePos().z()/CLHEP::mm);
216 
217  cHit->SetTime(gHit->GetToF()/CLHEP::ns);
218  cHit->SetEnergy(gHit->GetEdep()/CLHEP::MeV);
219  cHit->SetEBeforeSil(gHit->GetEBeforeSil()/CLHEP::MeV);
220  cHit->SetEAfterSil(gHit->GetEAfterSil()/CLHEP::MeV);
221 
222  cHit->SetTrackID(gHit->GetTrackID());
223  cHit->SetEventID(GetTheEventID());
224  cHit->SetRunID(GetTheRunID());
225 
226  cHit->SetParticleID(gHit->GetParticleID());
227  cHit->SetParticleCharge(gHit->GetParticleCharge());
228  cHit->SetParticleMass(gHit->GetParticleMass());
229 
230  cHit->SetStepsContributing(1);
231  }
232 
233  else if(mode==1){ //addition
234  cHit->SetEnergy(cHit->GetEnergy() + gHit->GetEdep());
235  //taking the smaller outgoing energy of the geantHits
236  if(cHit->GetEAfterSil()>gHit->GetEAfterSil()) cHit->SetEAfterSil(gHit->GetEAfterSil()/CLHEP::MeV);
237  //taking the larger incoming energy of the geantHits
238  if(cHit->GetEBeforeSil()<gHit->GetEBeforeSil()) cHit->SetEBeforeSil(gHit->GetEBeforeSil()/CLHEP::MeV);
239 
241  // The mean value of a distribution {x_i} can also be computed iteratively
242  // if the values x_i are drawn one-by-one. After a new value x, the new mean is:
243  // mean(t) = mean(t-1) + (1/t)(x-mean(t-1))
244  cHit->SetXPos(cHit->GetXPos() +
245  (gHit->GetLocalPrePos().x()-cHit->GetXPos())/((G4double)cHit->GetStepsContributing()));
246  cHit->SetYPos(cHit->GetYPos() +
247  (gHit->GetLocalPrePos().y()-cHit->GetYPos())/((G4double)cHit->GetStepsContributing()));
248  cHit->SetZPos(cHit->GetZPos() +
249  (gHit->GetLocalPrePos().z()-cHit->GetZPos())/((G4double)cHit->GetStepsContributing()));
250 
251  //taking the shorter time of the geantHits
252  if(cHit->GetTime()>gHit->GetToF()) cHit->SetTime(gHit->GetToF()/CLHEP::ns);
253  }
254 }
255 
256 //////////////////////////////////////////////////////////////////
257 /// Actions to perform in the ACTAR gas detector analysis after each step
258 void ActarSimROOTAnalSil::UserSteppingAction(const G4Step *aStep){
259  if(aStep){;} /* keep the compiler "quiet" */
260 }
TClonesArray * silHitCA
ClonesArray of the hits in the silicons.
void SetTheRunID(G4int id)
G4ThreeVector GetLocalPrePos()
void SetRunID(UInt_t run)
void SetStepsContributing(UInt_t step)
void BeginOfEventAction(const G4Event *)
Actions to perform in the silicon anal at the begining of the event.
void SetTrackID(UInt_t tr)
void SetEventID(UInt_t ev)
ActarSimROOTAnalSil()
Constructor.
void SetEAfterSil(Double_t ea)
void EndOfEventAction(const G4Event *)
void SetZPos(Double_t z)
~ActarSimROOTAnalSil()
Destructor. Makes nothing.
TFile * simFile
Local pointer to simFile.
void SetParticleMass(Double_t pdgMass)
Double_t GetEnergy()
void SetYPos(Double_t y)
Double_t GetEBeforeSil()
G4THitsCollection< ActarSimSilGeantHit > ActarSimSilGeantHitsCollection
Double_t GetXPos()
void SetTheEventID(G4int id)
Double_t GetTime()
TBranch * silHitsBranch
Local branch for the silicon hits.
void SetEBeforeSil(Double_t eb)
void SetParticleID(UInt_t pdgID)
ActarSimROOTAnalysis * gActarSimROOTAnalysis
Global pointer to this soliton.
TTree * eventTree
Local pointer to the event tree.
Double_t GetYPos()
Double_t GetZPos()
void SetXPos(Double_t x)
void AddSilHit(ActarSimSilHit *cHit, ActarSimSilGeantHit *gHit, G4int mode)
void UserSteppingAction(const G4Step *)
Actions to perform in the ACTAR gas detector analysis after each step.
Double_t GetEAfterSil()
void GeneratePrimaries(const G4Event *)
Actions to perform in the silicon anal when generating the primaries.
UInt_t GetStepsContributing()
void FillingHits(const G4Event *)
ActarSimSilHit ** theSilHit
Pointer to the hits in the silicons.
void SetDetectorID(Int_t det)
void BeginOfRunAction(const G4Run *)
Actions to perform in the silicon anal at the begining of the run.
void SetParticleCharge(Double_t pdgCharge)
void SetEnergy(Double_t ed)
void SetTime(Double_t ti)