1 #include "ERBeamDetPID.h" 3 #include "G4IonTable.hh" 4 #include "G4ParticleDefinition.hh" 5 #include "G4NistManager.hh" 6 #include "G4EmCalculator.hh" 10 #include "TDatabasePDG.h" 11 #include "TParticlePDG.h" 12 #include "TGeoManager.h" 14 #include "FairRootManager.h" 15 #include "FairRuntimeDb.h" 16 #include "FairLogger.h" 19 #include "ERDetectorList.h" 20 #include "ERBeamDetSetup.h" 25 :
ERTask(
"ER BeamDet particle finding scheme")
31 :
ERTask(
"ER BeamDet particle finding scheme ", verbose)
48 LOG(FATAL) <<
"PID not defined for ERBeamDetPID!" << FairLogger::endl;
51 FairRootManager* ioman = FairRootManager::Instance();
52 if ( ! ioman ) Fatal(
"Init",
"No FairRootManager");
56 fBeamDetTrack = (TClonesArray*) ioman->GetObject(
"BeamDetTrack");
58 fProjectile =
new TClonesArray(
"ERBeamDetParticle", consts::approx_beamdet_particle_number);
62 ioman->Register(
"BeamDetParticle.",
"BeamDet Particle",
fProjectile, kTRUE);
70 LOG(DEBUG) <<
"[ERBeamDetPID]---------------------Started-----------------------------------------" 74 LOG(DEBUG) <<
"[ERBeamDetPID] No track" << FairLogger::endl;
78 Double_t ToF1, ToF2, ToF;
79 Double_t dE1, dE2, dE;
88 LOG(DEBUG) <<
"[ERBeamDetPID] dE1 = " << dE1 <<
" ToF1 = " << ToF1 << FairLogger::endl;
92 LOG(DEBUG) <<
"[ERBeamDetPID] dE2 = " << dE2 <<
" ToF2 = " << ToF2 << FairLogger::endl;
94 LOG(DEBUG) <<
"[ERBeamDetPID] dE = " << dE <<
" MeV; " <<
" ToF1 = " << ToF1 <<
" ns;" 95 <<
" ToF2 = " << ToF2 <<
" ns;" << FairLogger::endl;
97 LOG(DEBUG) <<
"[ERBeamDetPID] dE = " << dE <<
" MeV; " <<
" ToF = " << ToF <<
" ns;" 99 if(ToF <= fToF1 || ToF >=
fToF2 || dE <= fdE1 || dE >=
fdE2){
106 LOG(DEBUG) <<
"[ERBeamDetPID] Probability " << probability <<
" less then threshold " 111 LOG(DEBUG) <<
"[ERBeamDetPID] Mass " <<
fIonMass << FairLogger::endl;
113 beta = distanceBetweenToF * 1e-2 / (ToF * 1e-9) / TMath::C();
114 if(beta <= 0 || beta >= 1) {
115 LOG(DEBUG) <<
"[ERBeamDetPID] Wrong beta " << beta << FairLogger::endl;
119 gamma = 1. / TMath::Sqrt(1.- beta*beta);
123 px = p * TMath::Sin(track->GetVector().Theta()) * TMath::Cos(track->GetVector().Phi());
124 py = p * TMath::Sin(track->GetVector().Theta()) * TMath::Sin(track->GetVector().Phi());
125 pz = p * TMath::Cos(track->GetVector().Theta());
126 energy = fIonMass * gamma;
127 LOG(DEBUG) <<
"[ERBeamDetPID] TOF State:: PID: " <<
fPID <<
"; px: " << px <<
"; py: " << py
128 <<
"; pz: " << pz <<
" energy: " << energy <<
"; probability " << probability
131 auto T_and_time_on_target = CalcEkinAndTimeOnTarget(*track,
fPID , p, fIonMass, ToF2);
132 float T = T_and_time_on_target.first;
133 float time_on_target = T_and_time_on_target.second;
134 float pt, ptx, pty, ptz, et;
135 pt = TMath::Sqrt(T * T + 2. * T * fIonMass);
136 ptx = pt * TMath::Sin(track->GetVector().Theta()) * TMath::Cos(track->GetVector().Phi());
137 pty = pt * TMath::Sin(track->GetVector().Theta()) * TMath::Sin(track->GetVector().Phi());
138 ptz = pt * TMath::Cos(track->GetVector().Theta());
140 LOG(DEBUG) <<
"[ERBeamDetPID] Target State:: px: " << ptx <<
"; py: " << pty <<
"; pz: " << ptz
141 <<
" energy: " << et << FairLogger::endl;
142 AddParticle(
fPID, TLorentzVector(px, py, pz, energy), TLorentzVector(ptx,pty,ptz,et),
143 time_on_target, probability);
144 LOG(DEBUG) <<
"[ERBeamDetPID]---------------------Finished----------------------------------------" 148 std::pair<float, float> ERBeamDetPID::CalcEkinAndTimeOnTarget(
ERBeamDetTrack& track,
int pid,
float mom,
149 float mass,
float time_on_tof5){
150 FairRun* run = FairRun::Instance();
151 if (!TString(run->ClassName()).Contains(
"ERRunAna"))
152 LOG(FATAL) <<
"[ERBeamDet] Use ERRunAna for ERBeamDetPID!!!" << FairLogger::endl;
154 const TVector3 target_vertex = track.GetTargetVertex();
155 LOG(DEBUG) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] Eloss calculation with target vertex = (" << target_vertex.X()
156 <<
"," << target_vertex.Y() <<
"," << target_vertex.Z() <<
"), direction on target = (" 157 << track.GetVector().X() <<
"," << track.GetVector().Y() <<
"," << track.GetVector().Z()
158 <<
")" << FairLogger::endl;
159 Float_t z_start = -3000.;
160 Float_t x_start = target_vertex.X()
161 + z_start*TMath::Sin(track.GetVector().Theta()) * TMath::Cos(track.GetVector().Phi());
162 Float_t y_start = target_vertex.Y()
163 + z_start*TMath::Sin(track.GetVector().Theta()) * TMath::Sin(track.GetVector().Phi());
164 LOG(DEBUG) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] Eloss calculation start vertex = (" << x_start <<
"," 165 << y_start <<
"," << z_start <<
")" << FairLogger::FairLogger::endl;
166 G4IonTable* ion_table = G4IonTable::GetIonTable();
167 G4ParticleDefinition* ion = ion_table->GetIon(pid);
168 G4NistManager* nist = G4NistManager::Instance();
169 const auto track_direction = track.GetDirection();
170 TGeoNode* node = gGeoManager->InitTrack(x_start, y_start, z_start, track_direction.X(),
171 track_direction.Y(), track_direction.Z());
172 Float_t E = TMath::Sqrt(mom * mom + mass * mass);
173 Float_t T = E - mass;
174 float time_on_target = time_on_tof5;
175 Float_t sumLoss = 0.;
176 Bool_t firstTofAlreadySkipped = kFALSE;
177 bool secondTofPassed =
false;
179 while(!gGeoManager->IsOutside()) {
180 TString matName = node->GetMedium()->GetMaterial()->GetName();
181 if (TString(node->GetName()).Contains(
"anode")) {
184 G4Material* mat = nist->FindOrBuildMaterial(matName.Data());
185 node = gGeoManager->FindNextBoundary();
186 Double_t step = gGeoManager->GetStep();
187 const TVector3 current_position(gGeoManager->GetCurrentPoint());
188 LOG(DEBUG) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] track position (" << current_position.X() <<
", " 189 << current_position.Y() <<
", " << current_position.Z() <<
")" << FairLogger::endl;
190 LOG(DEBUG) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] path = " << gGeoManager->GetPath()
192 if (!firstTofAlreadySkipped && TString(gGeoManager->GetPath()).Contains(
"ToF")) {
193 firstTofAlreadySkipped = kTRUE;
194 node = gGeoManager->Step();
199 if (!firstTofAlreadySkipped) {
200 node = gGeoManager->Step();
203 const double step_to_target_vertex = (target_vertex - current_position).Mag();
204 const bool is_last_step = step_to_target_vertex <= step;
205 step = is_last_step ? step_to_target_vertex : step;
206 Double_t edep = ComputeElossIntegralVolStep(T, *ion, *mat,
"ionIoni", step);
207 node = gGeoManager->GetCurrentNode();
208 LOG(DEBUG) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] Kinetic Energy = " << T <<
" medium " << matName
209 <<
" step = " << step <<
" edep = " << edep << FairLogger::endl;
210 if (secondTofPassed) {
211 auto velocity = [mass](
float Ekin) {
212 float p = TMath::Sqrt(Ekin * Ekin + 2. * Ekin * mass);
213 const float c = TMath::C();
215 float m = mass / c / c;
216 return p * c / TMath::Sqrt(m * m * c * c + p * p) ;
219 float ave_velocity = (velocity(T) + velocity(T - edep)) / 2.;
220 if (ave_velocity > 0.) {
221 time_on_target += step * 0.01 / ave_velocity * 1e9;
222 LOG(DEBUG) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] Current time = " 223 << time_on_target <<
" ns " << FairLogger::endl;
225 LOG(WARNING) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] Ion has velocity equals zero." 231 if (!secondTofPassed && TString(gGeoManager->GetPath()).Contains(
"ToF")) {
232 secondTofPassed =
true;
236 node = gGeoManager->Step();
238 if (!firstTofAlreadySkipped) {
239 LOG(WARNING) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] First ToF not found." << FairLogger::endl;
241 if (!secondTofPassed) {
242 LOG(WARNING) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] Second ToF not found." << FairLogger::endl;
244 LOG(DEBUG) <<
"[ERBeamDet][CalcEkinAndTimeOnTarget] Sum Eloss = " << sumLoss << FairLogger::endl;
245 return std::make_pair(T, time_on_target);
255 TDatabasePDG* pdgDB = TDatabasePDG::Instance();
256 TParticlePDG* kProton = pdgDB->GetParticle(2212);
257 Double_t kProtonMass=kProton->Mass();
258 fIonMass = kProtonMass * Double_t(a);
262 TLorentzVector targetState,
float time_on_target,
264 return new((*fProjectile)[
fProjectile->GetEntriesFast()])
virtual void Reset()
Resets all output data.
Double_t fdE2
ToF summary energy deposit boundaries.
ERBeamDetParticle * AddParticle(Int_t pid, TLorentzVector tofState, TLorentzVector targetState, float time_on_target, float probability)
Adds a ERBeamDetParticle to the output Collection.
TClonesArray * fBeamDetTrack
input collection of tracks
ERBeamDetSetup * fBeamDetSetup
access to ERBeamDetSetup class instance
virtual InitStatus Init()
Double_t fIonMass
ion mass
TClonesArray * fBeamDetToFDigi1
input collection of ToF first plastic points
Double_t fProbabilityThreshold
probability threshold
void SetIonMassNumber(Int_t a)
Sets ion mass number.
TClonesArray * fProjectile
output projectile collection
virtual InitStatus Init()
Defines all input and output object colletions participate in particle identification.
Class for particle identification.
std::vector< TString > fAvailibleRunManagers
Run managers that are availible for this task.
Double_t fOffsetToF
ToF calibration parameter.
Base abstract class for all tasks in er.
Double_t fToF2
ToF selection boundaries.
ERBeamDetPID()
Default constructor.
TClonesArray * fBeamDetToFDigi2
input collection of ToF second plastic points
void SetBoxPID(Double_t tof1, Double_t tof2, Double_t dE1, Double_t dE2)
Sets selection box area on the ToF/dE scatter plot.
virtual void Exec(Option_t *opt)
Defines selection and calculetion of parameters for each event: Four-vector is determined by equati...