FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FairGeoMedium.cxx
Go to the documentation of this file.
1 /********************************************************************************
2  * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 //*-- รถ : Ilse Koenig
9 //*-- Modified : 10/11/2003 by Ilse Koenig
10 
12 //
13 // Class for tracking medium ( includes also material )
14 //
16 #include "FairGeoMedium.h"
17 
18 #include <TString.h> // for TString
19 #include <cmath> // for pow, log
20 // IWYU pragma: no_include <architecture/i386/math.h>
21 #include <climits> // for INT_MAX
22 #include <fstream> // for fstream
23 #include <iostream> // for cout
24 #include <stdlib.h> // for abs
25 
26 using std::cout;
27 using std::log;
28 using std::pow;
29 
31 
33  : TNamed(name, "")
34  , medId(0)
35  , autoflag(1)
36  , nComponents(0)
37  , weightFac(0)
38  , ca(nullptr)
39  , cz(nullptr)
40  , cw(nullptr)
41  , density(0)
42  , radLen(0)
43  , sensFlag(0)
44  , fldFlag(0)
45  , fld(0)
46  , epsil(0)
47  , madfld(-1)
48  , maxstep(-1)
49  , maxde(-1)
50  , minstep(-1)
51  , npckov(0)
52  , ppckov(nullptr)
53  , absco(nullptr)
54  , effic(nullptr)
55  , rindex(nullptr){
56  // Constructor for a medium with name and index id
57  // SetName(name);
58  };
59 
61 {
62  // Destructor
63  if (nComponents > 0) {
64  delete[] ca;
65  ca = 0;
66  delete[] cz;
67  cz = 0;
68  delete[] cw;
69  cw = 0;
70  nComponents = 0;
71  }
72  if (npckov > 0) {
73  delete[] ppckov;
74  ppckov = 0;
75  delete[] absco;
76  absco = 0;
77  delete[] effic;
78  effic = 0;
79  delete[] rindex;
80  rindex = 0;
81  npckov = 0;
82  }
83 }
84 
86 {
87  // Sets the number of components in the material
88  if (n == 0) {
89  return;
90  }
91  Int_t k = abs(n);
92  if (nComponents != 0 && k != nComponents) {
93  delete[] ca;
94  delete[] cz;
95  delete[] cw;
96  nComponents = 0;
97  }
98  if (nComponents == 0) {
99  nComponents = k;
100  ca = new Double_t[k];
101  cz = new Double_t[k];
102  cw = new Double_t[k];
103  }
104  weightFac = static_cast<Int_t>(n / nComponents);
105 }
106 
107 Bool_t FairGeoMedium::setComponent(Int_t i, Double_t a, Double_t z, Double_t weight)
108 {
109  // Defines the ith material component
110  if (i < 0 || i >= nComponents) {
111  Error("setNComponents", "Wrong index");
112  return kFALSE;
113  }
114  ca[i] = a;
115  cz[i] = z;
116  cw[i] = weight;
117  return kTRUE;
118 }
119 
120 void FairGeoMedium::getComponent(Int_t i, Double_t* p)
121 {
122  // Returns the ith material component
123  if (i >= 0 && i < nComponents) {
124  p[0] = ca[i];
125  p[1] = cz[i];
126  p[2] = cw[i];
127  // cout << " -I p: " << p[0] << p[1] << p[2] << endl;
128  } else {
129  p[0] = p[1] = p[2] = 0.;
130  }
131 }
132 
134 {
135  // Sets the number of optical parameters for the tracking of Cerenkov light
136  if (n != npckov && npckov > 0) {
137  delete[] ppckov;
138  delete[] absco;
139  delete[] effic;
140  delete[] rindex;
141  }
142  npckov = n;
143  if (n > 0) {
144  ppckov = new Double_t[npckov];
145  absco = new Double_t[npckov];
146  effic = new Double_t[npckov];
147  rindex = new Double_t[npckov];
148  }
149 }
150 
151 Bool_t FairGeoMedium::setCerenkovPar(Int_t i, Double_t p, Double_t a, Double_t e, Double_t r)
152 {
153  // Defines the ith parameter set of the optical parameters
154  if (i < 0 || i >= npckov) {
155  Error("setNpckov", "Wrong index");
156  return kFALSE;
157  }
158  ppckov[i] = p;
159  absco[i] = a;
160  effic[i] = e;
161  rindex[i] = r;
162  return kTRUE;
163 }
164 
165 void FairGeoMedium::getCerenkovPar(Int_t i, Double_t* p)
166 {
167  // returns the ith parameter set of the optical parameters
168  if (i >= 0 && i < npckov) {
169  p[0] = ppckov[i];
170  p[1] = absco[i];
171  p[2] = effic[i];
172  p[3] = rindex[i];
173  } else {
174  p[0] = p[1] = p[2] = p[3] = 0.;
175  }
176 }
177 
178 void FairGeoMedium::setMediumPar(Int_t sensitivityFlag,
179  Int_t fieldFlag,
180  Double_t maxField,
181  Double_t precision,
182  Double_t maxDeviation,
183  Double_t maxStep,
184  Double_t maxDE,
185  Double_t minStep)
186 {
187  // Sets the medium parameters
188  sensFlag = sensitivityFlag;
189  fldFlag = fieldFlag;
190  fld = maxField;
191  epsil = precision;
192  madfld = maxDeviation;
193  maxstep = maxStep;
194  maxde = maxDE;
195  minstep = minStep;
196 }
197 
198 void FairGeoMedium::getMediumPar(Double_t* params)
199 {
200  // Returns the medium parameters
201  params[0] = sensFlag;
202  params[1] = fldFlag;
203  params[2] = fld;
204  params[3] = madfld;
205  params[4] = maxstep;
206  params[5] = maxde;
207  params[6] = epsil;
208  params[7] = minstep;
209  params[8] = 0.;
210  params[9] = 0.;
211 }
212 
213 void FairGeoMedium::read(std::fstream& fin, Int_t aflag)
214 {
215  // Reads the parameters from file
216  autoflag = aflag;
217  Int_t n;
218  fin >> n;
219  setNComponents(n);
220  for (Int_t ik = 0; ik < nComponents; ik++) {
221  fin >> ca[ik];
222  }
223  for (Int_t i = 0; i < nComponents; i++) {
224  fin >> cz[i];
225  }
226  fin >> density;
227  if (nComponents == 1) {
228  cw[0] = 1.;
230  } else {
231  for (Int_t i = 0; i < nComponents; i++) {
232  fin >> cw[i];
233  }
234  }
235  fin >> sensFlag >> fldFlag >> fld >> epsil;
236  if (autoflag < 1) {
237  fin >> madfld >> maxstep >> maxde >> minstep;
238  } else {
239  // to use this feature one has to set TGeant3::SetAUTO(0), thus if the media does not
240  // defined these values one can force Geant3 to calculate them by given them a value
241  // of -1
242  madfld = -1;
243  maxstep = -1;
244  maxde = -1;
245  minstep = -1;
246  }
247  fin >> n;
248  if (n > 0 && n < (INT_MAX - 1)) {
249  setNpckov(n);
250  // if (n>0) {
251  for (Int_t i = 0; i < n; i++) {
252  fin >> ppckov[i] >> absco[i] >> effic[i] >> rindex[i];
253  }
254  }
255 }
256 
258 {
259  // Prints the medium definition
260  const char* bl = " ";
261  cout << GetName() << '\n' << nComponents * weightFac << bl;
262  for (Int_t ii = 0; ii < nComponents; ii++) {
263  cout << ca[ii] << bl;
264  }
265  for (Int_t j = 0; j < nComponents; j++) {
266  cout << cz[j] << bl;
267  }
268  cout << density << bl;
269  if (nComponents < 2) {
270  cout << radLen;
271  } else
272  for (Int_t iik = 0; iik < nComponents; iik++) {
273  cout << cw[iik] << bl;
274  }
275  cout << '\n' << sensFlag << bl << fldFlag << bl << fld << bl << epsil << '\n';
276  if (autoflag < 1) {
277  cout << madfld << bl << maxstep << bl << maxde << bl << minstep << '\n';
278  }
279  cout << npckov << '\n';
280  if (npckov > 0) {
281  for (Int_t i = 0; i < npckov; i++) {
282  cout << ppckov[i] << bl << absco[i] << bl << effic[i] << bl << rindex[i] << '\n';
283  }
284  }
285  cout << '\n';
286 }
287 
288 void FairGeoMedium::write(std::fstream& fout)
289 {
290  // Writes the medium definition into stream
291  const char* bl = " ";
292  fout << GetName() << '\n' << nComponents * weightFac << bl;
293  for (Int_t i = 0; i < nComponents; i++) {
294  fout << ca[i] << bl;
295  }
296  for (Int_t j = 0; j < nComponents; j++) {
297  fout << cz[j] << bl;
298  }
299  fout << density << bl;
300  if (nComponents < 2) {
301  fout << radLen;
302  } else
303  for (Int_t i = 0; i < nComponents; i++) {
304  fout << cw[i] << bl;
305  }
306  fout << '\n' << sensFlag << bl << fldFlag << bl << fld << bl << epsil << '\n';
307  if (autoflag < 1) {
308  fout << madfld << bl << maxstep << bl << maxde << bl << minstep << '\n';
309  }
310  fout << npckov << '\n';
311  if (npckov > 0) {
312  for (Int_t i = 0; i < npckov; i++) {
313  fout << ppckov[i] << bl << absco[i] << bl << effic[i] << bl << rindex[i] << '\n';
314  }
315  }
316  fout << '\n';
317 }
318 
320 {
321  // calculates radiation length
322  // formula in GEANT manual CONS110
323  if (cz[0] < 1.e-6) { // VAKUUM$
324  radLen = 1.e+16;
325  return kTRUE;
326  }
327  Double_t alpha = 1 / 137.; // fine structure constant
328  Double_t fac = .1912821; // 4*((electron radius)**2)*(avogadro's number)
329  Double_t z, a, w, az2, fc, y, xi, x0i, amol = 0., x0itot = 0.;
330  if (weightFac > 0) {
331  amol = 1.;
332  } else {
333  for (int i = 0; i < nComponents; i++) {
334  amol += cw[i] * ca[i];
335  if (amol == 0.) {
336  Error("calcRadiationLength()", "amol==0 for medium %s", fName.Data());
337  return kFALSE;
338  }
339  }
340  }
341  for (int i = 0; i < nComponents; i++) {
342  z = cz[i];
343  a = ca[i];
344  if (weightFac > 0) {
345  w = cw[i] / amol;
346  } else {
347  w = a * cw[i] / amol;
348  }
349  az2 = alpha * alpha * z * z;
350  fc = az2 * (1. / (1. + az2) + 0.20206 - 0.0369 * az2 + 0.0083 * az2 * az2 - .002F * az2 * az2 * az2);
351  y = log(183. / pow(z, 1. / 3.)) - fc;
352  xi = static_cast<float>(log(1440. / pow(z, 2. / 3.)) / y);
353  x0i = fac * alpha / a * z * (z + xi) * y;
354  x0itot += (x0i * w);
355  }
356  if (x0itot == 0. || density == 0.) {
357  Error("calcRadiationLength()", "x0itot=0 or density=0 for medium %s", fName.Data());
358  return kFALSE;
359  }
360  radLen = 1 / density / x0itot;
361  return kTRUE;
362 }
void setNComponents(Int_t)
Bool_t setComponent(Int_t, Double_t, Double_t, Double_t w=1.)
void write(std::fstream &)
FairGeoMedium(const char *name="")
Bool_t setCerenkovPar(Int_t, Double_t, Double_t, Double_t, Double_t)
void getCerenkovPar(Int_t, Double_t *)
ClassImp(FairEventBuilder)
void getMediumPar(Double_t *)
void setNpckov(Int_t)
void read(std::fstream &, Int_t autoflag)
void getComponent(Int_t, Double_t *)
Bool_t calcRadiationLength()
void setMediumPar(Int_t, Int_t, Double_t, Double_t, Double_t maxDeviation=-1., Double_t maxStep=-1., Double_t maxDE=-1., Double_t minStepDouble_t=-1.)