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