KaliVeda
Toolkit for HIC analysis
KVRangeTableGeoNavigator.cpp
1 #include "KVRangeTableGeoNavigator.h"
2 #include <TGeoMaterial.h>
3 #include <TGeoManager.h>
4 #include <TGeoVolume.h>
5 #include <TGeoNode.h>
6 #include "KVNucleus.h"
7 #include <KVIonRangeTableMaterial.h>
8 
10 
11 // BEGIN_HTML <!--
13 /* -->
14 <h2>KVRangeTableGeoNavigator</h2>
15 <h4>Propagate particles through a geometry and calculate their energy losses</h4>
16 <!-- */
17 // --> END_HTML
18 
19 
21 
22 
34 void KVRangeTableGeoNavigator::ParticleEntersNewVolume(KVNucleus* part)
35 {
36  // Overrides method in KVGeoNavigator base class.
37  // Every time a particle enters a new volume, we check the material to see
38  // if it is known (i.e. contained in the range table fRangeTable).
39  // If so, then we calculate the energy loss of the particle in this volume,
40  // reduce the particle's energy accordingly, and, if the energy falls below
41  // a certain cut-off (default 1.e-3 MeV; can be modified with
42  // SetCutOffKEForPropagation(Double_t) ), we stop the propagation.
43  //
44  // The (cumulated) energy losses in the active layers of all hit detectors
45  // are updated with the energy lost by this particle
46 
47  Double_t de = 0;
48  Double_t e = part->GetEnergy();
49  if (e <= fCutOffEnergy) {
50  e = 0.;
51  SetStopPropagation();//propagation will stop after this step
52  if (IsTracking()) {
53  AddPointToCurrentTrack(GetEntryPoint().X(), GetEntryPoint().Y(), GetEntryPoint().Z());
54  AddPointToCurrentTrack(GetExitPoint().X(), GetExitPoint().Y(), GetExitPoint().Z());
55  }
56  return;
57  }
58 
59  // calculate energy losses in known materials for charged particles
60  TGeoMaterial* material = GetCurrentVolume()->GetMaterial();
61  KVIonRangeTableMaterial* irmat = 0;
62  if ((irmat = fRangeTable->GetMaterial(material))) {
63 // Info("PartEntNewVol", "mat=%s thickness=%f pressure=%Lf mbar", material->GetName(), GetStepSize(),
64 // material->GetPressure() / KVUnits::mbar);
65  de = irmat->GetLinearDeltaEOfIon(
66  part->GetZ(), part->GetA(), e, GetStepSize(), 0.,
67  material->GetTemperature(),
68  material->GetPressure());
69  e -= de;
70  if (e <= fCutOffEnergy) {
71  e = 0.;
72  SetStopPropagation();//propagation will stop after this step
73  }
74  //set flag to say that particle has been slowed down
75  part->SetIsDetected();
76  //If this is the first absorber that the particle crosses, we set a "reminder" of its
77  //initial energy
78  if (!part->GetPInitial()) part->SetE0();
79 
80  TString absorber_name;
81  KVDetector* theDet = GetDetectorFromPath(GetCurrentPath());
82 
83  Bool_t active_layer = kFALSE;
84  int subdet_number = -1;
85  if (theDet) {
86  if (theDet->IsSegmented())
87  subdet_number = GetSubDetectorFromPathAndNodeName(theDet, GetCurrentPath(), GetCurrentNode()->GetName());
88  if (!theDet->IsSingleLayer()) {
89  absorber_name.Form("%s/%s", theDet->GetName(), GetCurrentNode()->GetName());
90  if (strncmp(GetCurrentNode()->GetName(), "ACTIVE", 6) == 0) active_layer = kTRUE;
91  }
92  else {
93  absorber_name = theDet->GetName();
94  active_layer = kTRUE;
95  }
96  }
97  else
98  absorber_name = irmat->GetName();
99 
100  if (part->GetZ()) {
101  part->GetParameters()->SetValue(Form("DE:%s", absorber_name.Data()), de);
102  part->GetParameters()->SetValue(Form("DX:%s", absorber_name.Data()), GetStepSize());
103  if (subdet_number > -1)
104  part->GetParameters()->SetValue(Form("%s:SUBDET", absorber_name.Data()), subdet_number);
105  if (theDet) {
106  if (active_layer) {
107  // update energy loss in active layer of detector
108  Double_t E = theDet->GetEnergyLoss() + de;
109  theDet->SetEnergyLoss(E);
110  }
111  else if (theDet->IsSegmented()) {
112  theDet->AddEnergyLossInSubDetector(subdet_number, de);
113  }
114  }
115  }
116 // part->GetParameters()->SetValue(Form("Xin:%s", absorber_name.Data()), GetEntryPoint().X());
117 // part->GetParameters()->SetValue(Form("Yin:%s", absorber_name.Data()), GetEntryPoint().Y());
118 // part->GetParameters()->SetValue(Form("Zin:%s", absorber_name.Data()), GetEntryPoint().Z());
119  if (StopPropagation()) {
120  // If particle stops in this volume, we use as 'exit point' the point corresponding to
121  // the calculated range of the particle
122  Double_t r = irmat->GetRangeOfLastDE() / irmat->GetDensity();
123  TVector3 path = GetExitPoint() - GetEntryPoint();
124  TVector3 midVol = GetEntryPoint() + (r / path.Mag()) * path;
125  //part->GetParameters()->SetValue(Form("Xout:%s", absorber_name.Data()), midVol.X());
126  //part->GetParameters()->SetValue(Form("Yout:%s", absorber_name.Data()), midVol.Y());
127  //part->GetParameters()->SetValue(Form("Zout:%s", absorber_name.Data()), midVol.Z());
128  if (IsTracking()) {
129  AddPointToCurrentTrack(GetEntryPoint().X(), GetEntryPoint().Y(), GetEntryPoint().Z());
130  AddPointToCurrentTrack(midVol.X(), midVol.Y(), midVol.Z());
131  }
132  }
133  else {
134  //part->GetParameters()->SetValue(Form("Xout:%s", absorber_name.Data()), GetExitPoint().X());
135  //part->GetParameters()->SetValue(Form("Yout:%s", absorber_name.Data()), GetExitPoint().Y());
136  //part->GetParameters()->SetValue(Form("Zout:%s", absorber_name.Data()), GetExitPoint().Z());
137  if (IsTracking()) {
138  AddPointToCurrentTrack(GetEntryPoint().X(), GetEntryPoint().Y(), GetEntryPoint().Z());
139  AddPointToCurrentTrack(GetExitPoint().X(), GetExitPoint().Y(), GetExitPoint().Z());
140  }
141  }
142  part->SetEnergy(e);
143  }
144 }
145 
146 
147 
150 
152 {
153  // Start a new track to visualise trajectory of nucleus through the array
154 
155  fTrackTime = 0.;
156  Int_t pdg = part->GetN() * 100 + part->GetZ();
157  gGeoManager->SetPdgName(pdg, part->GetSymbol());
158  Int_t itrack = gGeoManager->AddTrack(GetTrackID(), pdg, part);
161  if (TheOrigin) AddPointToCurrentTrack(TheOrigin->x(), TheOrigin->y(), TheOrigin->z());
162  else AddPointToCurrentTrack(0, 0, 0);
163 }
164 
165 
166 
169 
171 {
172  // We start a new track to represent the particle's trajectory through the array.
173 
174  if (IsTracking()) InitialiseTrack(part, TheOrigin);
175 
176  KVGeoNavigator::PropagateParticle(part, TheOrigin);
177 
178  if (part->GetParameters()->HasParameter("DEADZONE")) {
179  if (IsTracking()) {
181  }
182  }
183 }
184 
185 
int Int_t
ROOT::R::TRInterface & r
#define e(i)
bool Bool_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
#define X(type, name)
R__EXTERN TGeoManager * gGeoManager
char * Form(const char *fmt,...)
Bool_t IsTracking() const
Int_t GetTrackID() const
void IncrementTrackID()
virtual void PropagateParticle(KVNucleus *, TVector3 *TheOrigin=0)
const TVector3 & GetEntryPoint() const
Material for use in energy loss & range calculations.
virtual Double_t GetLinearDeltaEOfIon(Int_t Z, Int_t A, Double_t E, Double_t e, Double_t isoAmat=0., Double_t T=-1., Double_t P=-1.)
Bool_t HasParameter(const Char_t *name) const
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:123
const Char_t * GetSymbol(Option_t *opt="") const
Definition: KVNucleus.cpp:71
Int_t GetN() const
Return the number of neutron.
Definition: KVNucleus.cpp:774
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:763
KVNameValueList * GetParameters() const
Definition: KVParticle.h:818
Propagate particles through array geometry calculating energy losses.
void InitialiseTrack(KVNucleus *part, TVector3 *TheOrigin)
Start a new track to visualise trajectory of nucleus through the array.
void PropagateParticle(KVNucleus *, TVector3 *TheOrigin=0) override
We start a new track to represent the particle's trajectory through the array.
TVirtualGeoTrack * fCurrentTrack
current track of nucleus being propagated
Double_t fTrackTime
track "clock"
void AddPointToCurrentTrack(Double_t x, Double_t y, Double_t z) override
Int_t AddTrack(Int_t id, Int_t pdgcode, TObject *particle=nullptr)
void SetPdgName(Int_t pdg, const char *name)
TVirtualGeoTrack * GetTrack(Int_t index)
Double_t GetTemperature() const
Double_t GetPressure() const
const char * GetName() const override
const char * Data() const
void Form(const char *fmt,...)
Double_t Z() const
Double_t Y() const
Double_t X() const
Double_t z() const
Double_t x() const
Double_t Mag() const
Double_t y() const
constexpr Double_t E()
ClassImp(TPyArg)