CGEM BOSS 6.6.5.g
BESIII Offline Software System
Loading...
Searching...
No Matches
SamplingGTS.cxx
Go to the documentation of this file.
1// implementation:
2// R. Farinelli (University of Ferrara & INFN of Ferrara)
3// L. Lavezzi (IHEP & INFN of Torino)
5
6#include "GaudiKernel/ISvcLocator.h"
7#include "GaudiKernel/Bootstrap.h"
8#include "GaudiKernel/IDataProviderSvc.h"
9#include "GaudiKernel/SmartDataPtr.h"
10#include "GaudiKernel/DataSvc.h"
11
12#include "G4DigiManager.hh"
13#include "Randomize.hh"
14#include "G4ios.hh"
15
16#include "CLHEP/Units/PhysicalConstants.h"
17
18#include <iomanip>
19#include <iostream>
20#include <fstream>
21#include <sstream>
22#include <cmath>
23#include <time.h>
24
25#include "TFile.h"
26#include "TRandom.h"
27#include "TMath.h"
28#include "TVector3.h"
29
30
31using namespace std;
32
34}
35
37 if(m_testing_sam == true) {
38 output->Write();
39 output->Close();
40 }
41}
42
43void SamplingGTS::init(ICgemGeomSvc* geomSvc, double magConfig){
44 // std::cout << "SamplingGTS::init" << std::endl;
45 double time_spent = 0.;
46 clock_t begin = clock();
47 m_geomSvc = geomSvc;
48 m_magConfig = magConfig;
49
50 // SETTINGS -------------------------------------------------
51 string filePath = getenv("CGEMDIGITIZERSVCROOT");
52 string fileName;
53
54 fileName = filePath + "/dat/par_settings_GTS.txt";
55 ifstream fin(fileName.c_str(), ios::in);
56
57 string strline;
58 string strpar;
59 if( ! fin.is_open() ){
60 std::cout << "SamplingGTS::init ERROR: can not open file " << filePath << endl;
61 }
62 else std::cout << "SamplingGTS::init: open file " << fileName << endl;
63
64
65 while(fin >> strpar){
66
67 if(strpar[0] == '#'){
68 getline(fin, strline);
69 }
70 else if(strpar == "high_voltage") {
71 fin >> m_hv;
72 }
73 else if(strpar == "magnetic_field") {
74 fin >> m_field;
75 }
76 else if(strpar == "tuning_factor_gain") {
77 fin >> m_tuning_factor_gain;
78 }
79 else if(strpar == "tuning_factor_diff_perp") {
80 fin >> m_tuning_factor_diff_perp;
81 }
82 else if(strpar == "tuning_factor_diff_paral") {
83 fin >> m_tuning_factor_diff_paral;
84 }
85 }
86
87 cout << "SamplingGTS::init: drift and avalanche parameters" << endl;
88 cout << "high voltage " << m_hv << "V" << endl;
89 cout << "field " << m_field <<endl;
90 cout << "tuning factors:" << endl;
91 cout << "1) for gain " << m_tuning_factor_gain << endl;
92 cout << "2) for diffusion " << m_tuning_factor_diff_perp << " (for orthogonal) " << m_tuning_factor_diff_paral << " (for parallel)" << endl;
93
94
95 // GAIN
96 bool gempar = readGemParameters();
97 if(!gempar) return; // CHECK ??
98
99 // DIFFUSION & MAG FIELD
100 bool gaspar = readGasParameters();
101 if(!gaspar) return; // CHECK ??
102
103 m_nMulElec = 0;
104
105 if(m_testing_sam == true) {
106 output = new TFile("gem.root", "RECREATE");
107 tree = new TNtuple("tree", "tree", "dphi:darc:dx:dy:dz:z_local");
108 }
109
110
111 clock_t end = clock();
112 time_spent += (double)(end - begin) / CLOCKS_PER_SEC;
113 cout << "Sampling::init " << time_spent << " seconds" << endl;
114
115
116}
117
118void SamplingGTS::setIonElectrons(int layer, int nElectrons, std::vector<double> x, std::vector<double> y, std::vector<double> z, std::vector<double> t){
119 cout << "SamplingGTS::setIonElectrons " << nElectrons << endl;
120 clear();
121
122 double time_spent = 0.;
123 clock_t begin = clock();
124
125 // cout << "drift setIonElectrons " << nElectrons << endl;
126 // cout << endl;
127 // loop on ions from ionization
128 for(int iele = 0; iele < nElectrons; iele++){
129 // cout << "iele " << iele << endl;
130 // does the electron survive to GEM1?
131 if(!is_survived()) continue;
132
133 // in MARS:
134 // 1) the z_local of the GEM is the radial direction
135 // --> the x_local shift and smearing are on the arc
136 // 2) the y_local is the direction parallel to the mag field
137 // --> the y_local shift and smearing are on z_global
138
139 // generate effective gain from POLYA
140 int tot_gain = compute_gain();
141
142 // double time_spent = 0.;
143 // clock_t begin = clock();
144
145 // cout << "tot_gain " << tot_gain << endl;
146 for(int jele = 0; jele < tot_gain; jele++) {
147 double xf, yf, zf, tf;
148
149 compute_diffusion_on_GEM3(x[iele], y[iele], z[iele], t[iele], xf, yf, zf, tf);
150 // cout << "jele " << jele << endl;
151
152 // set output
153 m_eX.push_back(xf);
154 m_eY.push_back(yf);
155 m_eZ.push_back(zf);
156 m_eT.push_back(tf);
157 m_nMulElec++;
158 /**
159 cout << iele << " " << jele << " diffused x " << x[iele] << " to " << xf << endl;
160 cout << iele << " " << jele << " diffused y " << y[iele] << " to " << yf << endl;
161 cout << iele << " " << jele << " diffused z " << z[iele] << " to " << zf << endl;
162 cout << iele << " " << jele << " diffused t " << t[iele] << " to " << tf << endl;
163 **/
164
165 }
166 }
167 clock_t end = clock();
168 time_spent += (double)(end - begin) / CLOCKS_PER_SEC;
169 cout << "Sampling::diffusion " << m_nMulElec << " time " << time_spent << " seconds" << endl;
170
171
172
173}
174
175void SamplingGTS::clear(){
176 m_nMulElec = 0;
177 m_eX.clear();
178 m_eY.clear();
179 m_eZ.clear();
180 m_eT.clear();
181}
182
183// ------------------------------------------------------- set parameters
185
186 string filePath = getenv("CGEMDIGITIZERSVCROOT");
187 // diffusion orthogonal to mag field
188 string fileName;
189 if(m_field) fileName = filePath + "/dat/par_ArIso_1T_GTS.txt";
190 else fileName = filePath + "/dat/par_ArIso_0T_GTS.txt";
191 // diffusion parallel to mag field
192 string fileName2 = filePath + "/dat/par_ArIso_0T_GTS.txt";
193
194 diffusion = new DiffusionGTS(m_geomSvc);
197
198 return true;
199
200}
201
203
204 // TRANSPARENCY -------------------------------------------------
205 string filePath = getenv("CGEMDIGITIZERSVCROOT");
206 string fileName;
207
208 fileName = filePath + "/dat/par_ArIso_GEM_GTS.txt";
209 ifstream fin(fileName.c_str(), ios::in);
210
211 string strline;
212 string strpar;
213 if( ! fin.is_open() ){
214 std::cout << "SamplingGTS::readGemParameters ERROR: can not open file " << filePath << endl;
215 return false;
216 }
217 else std::cout << "SamplingGTS::readGemParameters: open file " << fileName << endl;
218
219 bool is_tra = false;
220 while(fin >> strpar){
221
222 if(strpar[0] == '#'){
223 getline(fin, strline);
224 }
225 else if( atoi(strpar.c_str()) == m_hv) {
226 fin >> m_eff_col[0] >> m_eff_col[1] >> m_eff_col[2] >> m_eff_ext[0] >> m_eff_ext[1] >> m_eff_ext[2];
227 is_tra = true;
228 break;
229 }
230 }
231
232 cout << "SamplingGTS::readGemParameters: parameters of GEM @ HV = " << m_hv << " V" << endl;
233 cout << " collection eff GEM1: " << m_eff_col[0]
234 << " collection eff GEM2: " << m_eff_col[1]
235 << " collection eff GEM3: " << m_eff_col[2] << endl;
236 cout << " extraction eff GEM1: " << m_eff_ext[0]
237 << " extraction eff GEM2: " << m_eff_ext[1]
238 << " extraction eff GEM3: " << m_eff_ext[2] << endl;
239 cout << " is transparent " << is_tra << endl;
240
241 if(!is_tra) return false;
242
243 // GAIN ------------------------------
244 fileName = filePath + "/dat/CHECK_ArIso_EffGain_10M_GTS.root"; // to be substituted (this obtained by gain_c1.C)
245 TFile *file_gain_eff = new TFile(fileName.c_str(), "READ");
246 TString histoname = "h_gain_eff_0_"; histoname += m_hv;
247 h_gain_eff = (TH1F*) file_gain_eff->Get(histoname);
248 return true;
249}
250
251// ----------------------------------------------------------- transparency
253 return (gRandom->Uniform() < m_eff_col[0]); // CHECK 14) TRandom, as in ionization
254}
255
257 return m_tuning_factor_gain * h_gain_eff->GetRandom();
258}
259
260// ----------------------------------------------------------- drifting
261void SamplingGTS::compute_diffusion_on_GEM3(double xi, double yi, double zi, double ti, double &xf, double &yf, double &zf, double &tf) {
262
263
264 double R_catout[3] = {m_geomSvc->getCgemLayer(0)->getInnerROfCgemLayer() + m_geomSvc->getThicknessOfCathode(0),
265 m_geomSvc->getCgemLayer(1)->getInnerROfCgemLayer() + m_geomSvc->getThicknessOfCathode(1),
266 m_geomSvc->getCgemLayer(2)->getInnerROfCgemLayer() + m_geomSvc->getThicknessOfCathode(2)};
267
268 double thick[3] = {m_geomSvc->getThicknessOfGapD(0),
269 m_geomSvc->getThicknessOfGapD(1),
270 m_geomSvc->getThicknessOfGapD(2)};
271
272 double R = TMath::Sqrt(xi*xi + yi*yi);
273 // cout << "xi " << xi << " yi " << yi << " R " << R << endl;
274 int ilayer = 0;
275 if(R < R_catout[1]) ilayer = 0;
276 else if(R < R_catout[2]) ilayer = 1;
277 else ilayer = 2;
278
279 // cout << "xi " << xi << " yi " << yi << " R " << R << " ilayer " << ilayer << endl;
280
281 double drift_thick = thick[ilayer];
282 double cat_rad_out = R_catout[ilayer];
283 double gem3_rad_in = m_geomSvc->getCgemLayer(0)->getCgemFoil(2)->getInnerROfCgemFoil();
284
285 // cout << "drift_thick " << drift_thick << endl;
286 // cout << "cat_rad_out " << cat_rad_out << endl;
287 // cout << "gem3_rad_in " << gem3_rad_in << endl;
288
289
290 // in MARS:
291 // 1) the z_local of the GEM is the radial direction
292 // --> the x_local shift and smearing are on the arc
293 // 2) the y_local is the direction parallel to the mag field
294 // --> the y_local shift and smearing are on z_global
295
296 // 1)
297 double phi = TMath::ATan2(yi, xi);
298 // cout << "phi " << phi << "[rad] -> [deg]" << phi*TMath::RadToDeg() << endl;
299
300 double z_local = R - cat_rad_out;
301 if(z_local < 0 || z_local > drift_thick) cout << "ERRRRRRORE " << z_local << endl;
302 // cout<< "z_local " << z_local << endl;
303
304 double shift_x_drift = diffusion->shift_x_drift(z_local);
305 double shift_x_transf = diffusion->shift_x_transf();
306 double sigma_x_drift = diffusion->sigma_x_drift(z_local);
307 double sigma_x_transf = diffusion->sigma_x_transf();
308
309 double shift_x = shift_x_drift + 2 * shift_x_transf;
310 double sigma_x = m_tuning_factor_diff_perp * TMath::Sqrt(pow(sigma_x_drift, 2) + 2 * pow(sigma_x_transf, 2));
311 // cout << "m_tuning_factor_diff_perp " << m_tuning_factor_diff_perp << endl;
312 // cout << diffusion->sigma_x_drift(z_local) << " " << diffusion->sigma_x_transf() << endl;
313 // cout << "shift_x " << shift_x << " sigma_x " << sigma_x << endl;
314
315 double shift_phi = shift_x/gem3_rad_in;
316 double sigma_phi = sigma_x/gem3_rad_in;
317 // cout << "shift_phi " << shift_phi << " sigma_phi " << sigma_phi << endl;
318 double phif = phi + gRandom->Gaus(shift_phi, sigma_phi);
319 // cout << "phif " << phif << endl;
320 xf = gem3_rad_in * TMath::Cos(phif);
321 yf = gem3_rad_in * TMath::Sin(phif);
322 // cout << "xf " << xf << " yf " << yf << endl;
323
324 // 2)
325 double shift_y = diffusion->shift_y_drift(z_local) + 2 * diffusion->shift_y_transf();
326 double sigma_y = m_tuning_factor_diff_paral * TMath::Sqrt(pow(diffusion->sigma_y_drift(z_local), 2) + 2 * pow(diffusion->sigma_y_transf(), 2));
327 zf = zi + gRandom->Gaus(shift_y, sigma_y);
328
329 // cout<< "shift_y " << shift_y << "sigma_y " << sigma_y << endl;
330 // cout << "zf " << zf << endl;
331
332 // time
333 double shift_t = diffusion->shift_t_drift(z_local) + 2 * diffusion->shift_t_transf();
334 double sigma_t = TMath::Sqrt(pow(diffusion->sigma_t_drift(z_local), 2) + 2 * pow(diffusion->sigma_t_transf(), 2));
335 tf = ti + gRandom->Gaus(shift_t, sigma_t);
336
337 if(m_testing_sam==true) {
338
339 // cout << "z_local " << z_local << " phif " << phif << " xf " << xf << " yf " << yf << " zf " << zf << endl;
340 float dphi = phif-phi;
341 float darc = 1000 * gem3_rad_in * dphi;
342 float dx = 1000*(xf-xi);
343 float dy = 1000*(yf-yi);
344 float dz = 1000*(zf-zi);
345
346 tree->Fill(dphi, darc, dx, dy, dz, z_local);
347
348 // cout << phif-phi << " " << 100*(xf-xi) << " " << 100*(yf-yi) << " " << 100*(zf-zi) << endl;
349 // cout << "delta x " << xf << " " << xi << endl;
350 // cout << "delta y " << yf << " " << yi << endl;
351 // cout << "delta z " << zf << " " << zi << endl;
352 }
353
354
355
356
357
358
359}
Double_t x[10]
#define m_testing_sam
Definition: SamplingGTS.h:16
double getInnerROfCgemFoil() const
Definition: CgemGeoFoil.h:33
CgemGeoFoil * getCgemFoil(int i) const
Definition: CgemGeoLayer.h:115
double getInnerROfCgemLayer() const
Definition: CgemGeoLayer.h:23
double sigma_t_transf()
double sigma_t_drift(double z)
double sigma_x_transf()
double sigma_x_drift(double z)
void readGasPerpParameters(std::string fileName)
void readGasParalParameters(std::string fileName)
double sigma_y_transf()
double shift_t_drift(double z)
double shift_t_transf()
double shift_y_transf()
double shift_y_drift(double z)
double sigma_y_drift(double z)
double shift_x_transf()
double shift_x_drift(double z)
virtual double getThicknessOfCathode(int i) const =0
virtual CgemGeoLayer * getCgemLayer(int i) const =0
virtual double getThicknessOfGapD(int i) const =0
bool readGemParameters()
void init(ICgemGeomSvc *geomSvc, double magConfig)
Definition: SamplingGTS.cxx:43
void compute_diffusion_on_GEM3(double xi, double yi, double zi, double ti, double &xf, double &yf, double &zf, double &tf)
void setIonElectrons(int layer, int nElectrons, std::vector< double > x, std::vector< double > y, std::vector< double > z, std::vector< double > t)
double compute_gain()
bool is_survived()
bool readGasParameters()
DiffusionGTS * diffusion
Definition: SamplingGTS.h:53
int t()
Definition: t.c:1