KaliVeda
Toolkit for HIC analysis
KVMaterialStack.cpp
1 #include "KVMaterialStack.h"
2 
4 
5 
6 
9 KVMaterialStack::KVMaterialStack(const KVDetector* D, double incidence)
10  : KVBase(),
11  fDetector(D),
12  fELossF("ELossActive", this, &KVMaterialStack::ELossActive, 0., 1.e+04, 2, "KVMaterialStack", "ELossActive", TF1::EAddToList::kNo),
13  fEResF("ERes", this, &KVMaterialStack::EResDet, 0., 1.e+04, 2, "KVMaterialStack", "EResDet", TF1::EAddToList::kNo),
14  fmaxELossF("maxELoss", this, &KVMaterialStack::MaxELossActive, 0., 90., 2, "KVMaterialStack", "MaxELossActive", TF1::EAddToList::kNo)
15 {
16  // Copy all materials to stack, adjust thicknesses according to incidence angle
17 
18  fELossF.SetNpx(500);
19  fEResF.SetNpx(500);
20  fmaxELossF.SetNpx(500);
21 
22  TIter next(D->GetListOfAbsorbers());
23  KVMaterial* mat;
24  auto active = D->GetActiveLayer();
25  int layer = 0;
26  while ((mat = (KVMaterial*)next())) {
27  if (mat == active) fActiveLayer = layer;
28  fAbsorbers.push_back(*mat);
29  fLayThick.push_back(mat->GetThickness());
30  ++layer;
31  }
32 }
33 
34 
35 
37 
39 {
41  fELossF.SetRange(0., fDetector->GetSmallestEmaxValid(Z, A));
42  fELossF.SetTitle(Form("Energy loss [MeV] in detector %s for Z=%d A=%d", fDetector->GetName(), Z, A));
43  return fELossF;
44 }
45 
46 
47 
49 
51 {
53  fEResF.SetRange(0., fDetector->GetSmallestEmaxValid(Z, A));
54  fEResF.SetTitle(Form("Residual energy [MeV] after detector %s for Z=%d A=%d", fDetector->GetName(), Z, A));
55  return fEResF;
56 }
57 
58 
59 
61 
63 {
65  return fmaxELossF;
66 }
67 
68 
69 
79 
81 {
82  // Calculates energy loss (in MeV) in active layer of stack,
83  // taking into account preceding layers
84  //
85  // Arguments are:
86  // x[0] is incident energy in MeV
87  // Parameters are:
88  // par[0] Z of ion
89  // par[1] A of ion
90 
91  Double_t e = x[0];
92  int layer = 0;
93  if (fActiveLayer > 0) {
94  for (auto& mat : fAbsorbers) {
95  e = mat.GetERes(par[0], par[1], e, fLayThick[layer] / fIncAngleCosine);
96  if (e <= 0.)
97  return 0.; // return 0 if particle stops in layers before active layer
98  ++layer;
99  if (layer == fActiveLayer) break;
100  }
101  }
102  //calculate energy loss in active layer
103  return fAbsorbers[fActiveLayer].GetDeltaE(par[0], par[1], e, fLayThick[layer] / fIncAngleCosine);
104 }
105 
106 
107 
117 
119 {
120  // Calculates maximum energy loss (in MeV) in active layer of stack,
121  // taking into account preceding layers
122  //
123  // Arguments are:
124  // x[0] is incident angle of particle measured wrt normal to entrance window
125  // Parameters are:
126  // par[0] Z of ion
127  // par[1] A of ion
128 
129  Double_t psi = x[0];
130  auto psi_sav = fIncAngle;
131  SetIncidenceAngle(psi);
132  auto demax = GetELossFunction(par[0], par[1]).GetMaximum();
133  SetIncidenceAngle(psi_sav);
134  return demax;
135 }
136 
137 
138 
148 
150 {
151  // Calculates residual energy (in MeV) of particle after traversing all layers of detector.
152  // Returned value is -1000 if particle stops in one of the layers of the detector.
153  //
154  // Arguments are:
155  // x[0] is incident energy in MeV
156  // Parameters are:
157  // par[0] Z of ion
158  // par[1] A of ion
159 
160  Double_t e = x[0];
161  int layer = 0;
162  for (auto& mat : fAbsorbers) {
163  Double_t eres = mat.GetERes(par[0], par[1], e, fLayThick[layer] / fIncAngleCosine); //residual energy after layer
164  if (eres <= 0.)
165  return -1000.; // return -1000 if particle stops in layers before active layer
166  e = eres;
167  ++layer;
168  }
169  return e;
170 }
171 
172 
173 
180 
182 {
183  // Overrides KVMaterial::GetIncidentEnergyFromERes
184  //
185  // Calculate incident energy of nucleus from residual energy.
186  //
187  // Returns -1 if Eres is out of defined range of values
188 
189  if (Z < 1 || Eres <= 0.) return 0.;
190  Int_t status;
191  Double_t einc = KVBase::ProtectedGetX(&GetEResFunction(Z, A), Eres, status);
192  if (status != 0) {
193  // problem with inversion - value out of defined range of function
194  return -1;
195  }
196  return einc;
197 }
198 
199 
200 
222 
224 {
225  // Overrides KVMaterial::GetIncidentEnergy
226  // Returns incident energy corresponding to energy loss delta_e in active layer for a given nucleus.
227  //
228  // By default the solution corresponding to the highest incident energy is returned
229  // This is the solution found for Einc greater than the maximum of the dE(Einc) curve.
230  // If you want the low energy solution set SolType = KVIonRangeTable::kEmin.
231  //
232  // WARNING: calculating the incident energy of a particle using only the dE in a detector
233  // is ambiguous, as in general (and especially for very heavy ions) the maximum of the dE
234  // curve occurs for Einc greater than the punch-through energy, therefore it is not always
235  // true to assume that if the particle does not stop in the detector the required solution
236  // is that for type=KVIonRangeTable::kEmax. For a range of energies between punch-through
237  // and dE_max, the required solution is still that for type=KVIonRangeTable::kEmin.
238  // If the residual energy of the particle is unknown, there is no way to know which is the
239  // correct solution.
240  //
241  // WARNING 2
242  // If the given energy loss in the active layer is greater than the maximum theoretical dE
243  // for given Z & A, (dE > GetMaxDeltaE(Z,A)) then we return a NEGATIVE incident energy
244  // corresponding to the maximum, GetEIncOfMaxDeltaE(Z,A)
245 
246  if (Z < 1) return 0.;
247 
248  Double_t DE = delta_e;
249 
250  // If the given energy loss in the active layer is greater than the maximum theoretical dE
251  // for given Z & A, (dE > GetMaxDeltaE(Z,A)) then we return a NEGATIVE incident energy
252  // corresponding to the maximum, GetEIncOfMaxDeltaE(Z,A)
253  if (DE > GetMaxDeltaE(Z, A)) {
254  return -GetEIncOfMaxDeltaE(Z, A);
255  }
256 
257  TF1* dE = &GetELossFunction(Z, A);
258  Double_t e1, e2;
259  dE->GetRange(e1, e2);
260  switch (type) {
261  case KVMaterial::SolType::kEmin:
262  e2 = GetEIncOfMaxDeltaE(Z, A);
263  break;
264  case KVMaterial::SolType::kEmax:
265  e1 = GetEIncOfMaxDeltaE(Z, A);
266  break;
267  }
268  int status;
269  Double_t EINC = ProtectedGetX(dE, DE, status, e1, e2);
270  if (status != 0) {
271  return -EINC;
272  }
273  return EINC;
274 }
275 
276 
277 
282 
284 {
285  // Overrides KVMaterial::GetERes
286  // Returns residual energy of given nucleus after the detector.
287  // Returns 0 if Einc<=0
288 
289  if (Einc <= 0.) return 0.;
290  Double_t eres = GetEResFunction(Z, A).Eval(Einc);
291  // Eres function returns -1000 when particle stops in detector,
292  // in order for function inversion (GetEIncFromEres) to work
293  if (eres < 0.) eres = 0.;
294  return eres;
295 }
296 
297 
298 
int Int_t
#define e(i)
double Double_t
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char * Form(const char *fmt,...)
Base class for KaliVeda framework.
Definition: KVBase.h:139
Double_t ProtectedGetX(const TF1 *func, Double_t val, int &status, Double_t xmin=0.0, Double_t xmax=0.0) const
Definition: KVBase.cpp:1598
A stack of materials in which successive energy losses of charged particles can be calculated ,...
Double_t GetIncidentEnergyFromERes(Int_t Z, Int_t A, Double_t Eres)
std::vector< KVMaterial > fAbsorbers
TF1 & GetEResFunction(Int_t Z, Int_t A)
Double_t GetEIncOfMaxDeltaE(Int_t Z, Int_t A)
Double_t GetERes(Int_t Z, Int_t A, Double_t Einc)
Double_t EResDet(Double_t *x, Double_t *par)
Double_t fIncAngleCosine
TF1 & GetELossFunction(Int_t Z, Int_t A)
TF1 & GetMaxELossFunction(Int_t Z, Int_t A)
Double_t ELossActive(Double_t *x, Double_t *par)
Double_t GetIncidentEnergy(Int_t Z, Int_t A, Double_t delta_e, enum KVMaterial::SolType type=KVMaterial::SolType::kEmax)
std::vector< double > fLayThick
Double_t MaxELossActive(Double_t *x, Double_t *par)
void SetIncidenceAngle(double psi)
const KVDetector * fDetector
Double_t GetMaxDeltaE(Int_t Z, Int_t A)
Int_t fActiveLayer
layer thicknesses in cm
Description of physical materials used to construct detectors & targets; interface to range tables.
Definition: KVMaterial.h:89
virtual Double_t GetThickness() const
Definition: KVMaterial.cpp:484
virtual KVMaterial * GetActiveLayer() const
Definition: KVMaterial.h:176
virtual void SetRange(Double_t xmin, Double_t xmax)
void SetTitle(const char *title="") override
virtual void GetRange(Double_t &xmin, Double_t &xmax) const
virtual void SetParameters(const Double_t *params)
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
virtual Double_t GetMaximum(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
Double_t x[n]
ClassImp(TPyArg)