BmnRoot
Loading...
Searching...
No Matches
BmnGemGas.cxx
Go to the documentation of this file.
1#include "BmnGemGas.h"
2
3#include "TError.h"
4
5#include <TRandom.h>
6#include <fstream>
7#include <iostream>
8#include <ostream>
9
10// #include "ErrLogger/ErrLog.hh"
11
13 : _E(0)
14 , _B(0)
15 , _T(293.)
16 , _p(1024.)
17 , _VDrift(0)
18 , _Dl(0)
19 , _Dt(0)
20 , _k(0)
21 , _W(0)
22 , _CSD(0)
23 , _CSDNorm(0)
24 , _CSDEpol(0)
25{}
26
27BmnGemGas::BmnGemGas(double const E,
28 double const B,
29 double const T,
30 double const p,
31 double const VDrift,
32 double const Dl,
33 double const Dt,
34 double const k,
35 double const W,
36 const std::vector<double>& CSD,
37 double const CSDEpol)
38 : _E(E)
39 , _B(B)
40 , _T(T)
41 , _p(p)
42 , _VDrift(VDrift)
43 , _Dl(Dl)
44 , _Dt(Dt)
45 , _k(k)
46 , _W(W)
47 , _CSD(CSD)
48 , _CSDNorm(0)
49 , _CSDEpol(CSDEpol)
50{}
51
52BmnGemGas::BmnGemGas(const std::string& Filename, double const E)
53 : _E(E)
54{
55 // Reading the GasFile
56 std::ifstream infile(Filename.c_str(), std::fstream::in);
57 if (!infile.good())
58 Fatal("BmnGemGas::BmnGemGas", "Input File is not found");
59 // ReadGasBegin returns the number of electric fields (and sets _T, _B, _p)
60 int noent = ReadGasBegin(&infile);
61 if (noent <= 0)
62 Fatal("BmnGemGas::BmnGemGas",
63 "Number of electric fields nonpositive?\nCould not read File.\nExecution aborted.");
64 double e[noent]; // E field in V/cm
65 double vdrift[noent]; // e-drift velocity in cm/ns
66 double dt[noent]; // transverse diffusion in sqrt(cm)
67 double dl[noent]; // longitudinal diff. in sqrt(cm)
68 double k[noent]; // attachment coefficient in 1/cm
69
70 // ReadGasArrays returns the number of entries in cluster size distribution
71 // and sets the values in the assigned arrays (and _W)
72 int nCSDFile = ReadGasArrays(&infile, noent, e, vdrift, dt, dl, k);
73 if (nCSDFile < 2)
74 Fatal("BmnGemGas::BmnGemGas", "Number of cluster sizes too small in File.\nExecution aborted.");
75
76 // cluster size distribution: first entry is the rel. number of clusters with
77 // 1 electron,the last entry the rel. nr. of clusters with more than nCSDFile
78 // so the last entry may not be transferred
79 int _nCSD = nCSDFile - 1; // omit the last
80 _CSD.resize(_nCSD);
81
82 _CSDNorm = 0;
83 for (int i = 0; i < _nCSD; i++) {
84 infile >> _CSD[i];
85 _CSDNorm += _CSD[i];
86 }
87 if (!infile.good())
88 Fatal("BmnGemGas::BmnGemGas", "Could not read cluster size distribution in File.\nExecution aborted.");
89 infile.close();
90 // file is read
91
92 // Linear extrapolation to get the value at the right e field
93
94 double inTable = GetPositionOfE(noent, e);
95 /*The down rounded value of inTable is the index of the e field (in e)
96 that is smaller than _E.
97 (Exception: neg. Value , if _E is smaller than the smallest value in e)
98 The decimal places render about the position between two entries in e*/
99
100 if (inTable < 0 || inTable > noent - 1)
101 Warning("BmnGemGas::BmnGemGas", "E field out of the range defined in input file");
102 _VDrift = LinExpolation(inTable, vdrift, noent);
103 _Dl = LinExpolation(inTable, dl, noent);
104 _Dt = LinExpolation(inTable, dt, noent);
105 _k = LinExpolation(inTable, k, noent);
106
107 // Define the constant for the quadratic CSD extrapolation in such a way
108 // that the csd is continous (the inverse quadratic approximation
109 // is rather improper anyhow)
110 _CSDEpol = _CSD[_nCSD - 1] * (_nCSD - 1) * (_nCSD - 1);
111}
112
114
115void BmnGemGas::operator=(const BmnGemGas& GasToCopy)
116{
117 _VDrift = GasToCopy._VDrift;
118 _Dl = GasToCopy._Dl;
119 _Dt = GasToCopy._Dt;
120 _k = GasToCopy._k;
121 _W = GasToCopy._W;
122 _CSDNorm = GasToCopy._CSDNorm;
123 _CSDEpol = GasToCopy._CSDEpol;
124
125 _E = GasToCopy._E;
126 _B = GasToCopy._B;
127 _T = GasToCopy._T;
128 _p = GasToCopy._p;
129
130 _CSD = GasToCopy._CSD;
131}
132
133// Use Uniform generator and correct bug with not properly normalized table
135{
136 double r = gRandom->Uniform();
137 while (r > _CSDNorm)
138 r = gRandom->Uniform();
139
140 return GetRandomCS(r);
141}
142
143// return wrong number if r > overall sum
144int BmnGemGas::GetRandomCS(double const r) const
145{
146 size_t i = 0;
147 double sum = _CSD[0];
148 while (r > sum && ++i < _CSD.size()) {
149 sum += _CSD[i];
150 }
151 if (_CSDEpol > 0)
152 while (r > sum && i < 100) // sum could converge < 1
153 {
154 sum += _CSDEpol / i / i;
155 i++;
156 }
157 return i + 1;
158}
159
160void BmnGemGas::SetCSD(const std::vector<double>& CSD)
161{
162 _CSD = CSD;
163}
164
165std::ostream& operator<<(std::ostream& stream, const BmnGemGas& g)
166{
167 stream << "--------------------------------------------------------\n"
168 << "Tpc gas parameters: \n"
169 << " drift velocity VDrift=" << g._VDrift << "cm/ns \n"
170 << " long.diffusion Dl =" << g._Dl << "sqrt(cm) \n"
171 << " trans.diffusion Dt =" << g._Dt << "sqrt(cm) \n"
172 << " attachment k =" << g._k << "1/cm\n"
173 << " eff. ionisation W =" << g._W << "eV \n"
174 << " ClusterSizeDistribution CSD:";
175 for (int i = 0; i < g.nCSD(); i++) {
176 if (i % 3 == 0)
177 stream << "\n ";
178 stream << i + 1 << ": " << g._CSD[i] << " ";
179 }
180 stream << "\n"
181 << " extrapol. const CSDEpol=" << g._CSDEpol << "\n"
182 << "Gas parameters given for this environment: \n"
183 << " drift field E=" << g._E << "V/cm \n"
184 << " magnetic field B=" << g._B << "T \n"
185 << " pressure p=" << g._p << "mbar \n"
186 << " temperature T=" << g._T << "K \n"
187 << "--------------------------------------------------------\n";
188 return stream;
189}
190
191int BmnGemGas::ReadGasBegin(std::ifstream* const pinfile)
192{
193 int noent = 0; // Nr. of E fields
194 (*pinfile).ignore(256, '\n');
195 (*pinfile).ignore(256, '\n');
196 (*pinfile).ignore(256, '\n');
197 (*pinfile).ignore(256, ':');
198 (*pinfile) >> _T; // temperature
199 (*pinfile).ignore(256, ':');
200 (*pinfile) >> _p; // pressure
201 (*pinfile).ignore(256, ':');
202 (*pinfile) >> _B; // b field
203 (*pinfile).ignore(256, ':');
204 (*pinfile).ignore(256, ':');
205 (*pinfile) >> noent;
206 return (noent);
207}
208
209int BmnGemGas::ReadGasArrays(std::ifstream* const pinfile,
210 int const noent,
211 double* const e,
212 double* const vdrift,
213 double* const dt,
214 double* const dl,
215 double* const k)
216{
217 int nCSDFile = 0; // Nr. of ClusterSizes
218 for (int i = 0; i < noent; i++)
219 (*pinfile) >> e[i];
220 (*pinfile).ignore(256, ':');
221 for (int i = 0; i < noent; i++)
222 (*pinfile) >> vdrift[i];
223 (*pinfile).ignore(256, ':');
224 for (int i = 0; i < noent; i++)
225 (*pinfile) >> dt[i];
226 (*pinfile).ignore(256, ':');
227 for (int i = 0; i < noent; i++)
228 (*pinfile) >> dl[i];
229 (*pinfile).ignore(256, ':');
230 for (int i = 0; i < noent; i++)
231 (*pinfile) >> k[i];
232 // ignore ion-mobility (in this version)
233 (*pinfile).ignore(256, ':');
234 (*pinfile).ignore(256, '\n');
235 for (int i = 0; i < noent; i++)
236 (*pinfile).ignore(256, '\n');
237 // Cluster size distribution
238 (*pinfile).ignore(512, ':');
239 (*pinfile) >> _W; // effective ionisation
240 (*pinfile).ignore(512, ':');
241 (*pinfile).ignore(256, ':');
242 (*pinfile) >> nCSDFile;
243 return (nCSDFile);
244}
245
246const double BmnGemGas::GetPositionOfE(int const noent, const double* const e)
247{
248 double inTable = 0;
249 for (int i = 0; i < noent; i++) {
250 if (e[i] >= _E && i == 0) {
251 inTable = i - (e[i] - _E) / (e[1] - e[0]);
252 break;
253 }
254 if (i == noent - 1 || (e[i] >= _E && i != 0)) {
255 inTable = i - (e[i] - _E) / (e[i] - e[i - 1]);
256 break;
257 }
258 }
259 return (inTable);
260}
261
262const double BmnGemGas::LinExpolation(double const inTable, const double* const table, int const nTable)
263{
264 if (nTable == 1)
265 return (table[0]);
266 else if (inTable <= 0)
267 return (table[0] + inTable * (table[1] - table[0]));
268 else if (inTable > nTable - 1)
269 return (table[nTable - 1] + (inTable - nTable + 1) * (table[nTable - 1] - table[nTable - 2]));
270 else
271 for (int i = 1; i < nTable; i++) {
272 if (i >= inTable)
273 return (table[i] - (i - inTable) * (table[i] - table[i - 1]));
274 }
275 return (0); // never reached; compiling without this I get an annoying warning
276}
std::ostream & operator<<(std::ostream &stream, const BmnGemGas &g)
vector< Double_t > W(vector< Double_t > dist, Double_t sig)
Definition BmnMath.cxx:878
int i
Definition P4_F32vec4.h:22
double k() const
Definition BmnGemGas.h:39
int GetRandomCS(double const r) const
void operator=(const BmnGemGas &GasToCopy)
const std::vector< double > & CSD() const
Definition BmnGemGas.h:42
int nCSD() const
Definition BmnGemGas.h:43
int GetRandomCSUniform() const
void SetCSD(const std::vector< double > &CSD)