CGEM BOSS 6.6.5.i
BESIII Offline Software System
Loading...
Searching...
No Matches
IonizationGTS.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)
4
6
7#include "GaudiKernel/ISvcLocator.h"
8#include "GaudiKernel/Bootstrap.h"
9#include "GaudiKernel/IDataProviderSvc.h"
10#include "GaudiKernel/SmartDataPtr.h"
11#include "GaudiKernel/DataSvc.h"
12
13#include "CLHEP/Units/PhysicalConstants.h"
14
15#include <iomanip>
16#include <iostream>
17#include <fstream>
18#include <cmath>
19
20#include "TRandom.h"
21#include "TMath.h"
22
23// using namespace std;
24
25// mean number of clusters in 5 mm
26#define N_PRI_AVE 18.0016 // CHECK 2) deve essere letto da un file di settaggi
27
28// n_electron per cluster ArIso CHECK 2)
29const double int_prob_electron_per_cluster[100]={0.902864,0.920309,0.93045,0.936283,0.940138,0.943808,0.948277,0.954485,0.96098,0.966479,
30 0.970936,0.974523,0.977442,0.979843,0.981959,0.983657,0.985152,0.986421,0.987404,0.988233,
31 0.990002,0.990783,0.991482,0.992107,0.992666,0.993168,0.99362,0.994028,0.994397,0.994731,
32 0.995036,0.995313,0.995567,0.9958,0.996015,0.996212,0.996395,0.996564,0.996721,0.996867,
33 0.997003,0.99713,0.997248,0.99736,0.997464,0.997562,0.997655,0.997742,0.997825,0.997903,
34 0.997976,0.998046,0.998113,0.998176,0.998236,0.998293,0.998348,0.9984,0.998449,0.998497,
35 0.998542,0.998586,0.998628,0.998668,0.998706,0.998743,0.998779,0.998813,0.998846,0.998877,
36 0.998908,0.998938,0.998966,0.998993,0.99902,0.999046,0.999071,0.999095,0.999118,0.99914,
37 0.999162,0.999183,0.999204,0.999224,0.999243,0.999262,0.99928,0.999298,0.999315,0.999332,
38 0.999348,0.999364,0.99938,0.999395,0.99941,0.999424,0.999438,0.999452,0.999465,0.999478};
39
40
41
44
46 if(m_testing == true) {
47 output->Write();
48 output->Close();
49 }
50}
51
52void IonizationGTS::init(unsigned int random, ICgemGeomSvc* geomSvc, double magConfig){
53 double time_spent = 0.;
54 clock_t begin = clock();
55
56 // std::cout << "IonizationGTS::init" << std::endl;
57 m_random = random;
58 gRandom->SetSeed(m_random); // CHECK 6) TRandom
59 m_geomSvc = geomSvc;
60 m_magConfig = magConfig;
61
62 cout << "IonizationGTS::init: m_testing " << m_testing << endl;
63
64
65 if(m_testing==true) {
66 output = new TFile("ionization.root", "RECREATE");
67 h_distance_cluster = new TH1F("h_distance_cluster", "distance between two consecutive clusters", 100, 0, 5);
68 h_nof_cluster = new TH1F("h_nof_cluster", "number of clusters", 100, 0, 100);
69 }
70
71 clock_t end = clock();
72 time_spent += (double)(end - begin) / CLOCKS_PER_SEC;
73 }
74
75// CHECK 7) not using particle now
76// CHECK 8) not using momentum now
77void IonizationGTS::setTrack(int particle, int charge, double p, double trkPosIn[], double trkPosOut[]) {
78
79 double time_spent = 0.;
80 clock_t begin = clock();
81
82 clear();
83 // cout << "IonizationGTS setTrack" << endl;
84
85 // CHECK 1) 3D
86 m_track_length_limit = TMath::Sqrt((trkPosOut[0] - trkPosIn[0])*(trkPosOut[0] - trkPosIn[0]) + (trkPosOut[1] - trkPosIn[1])*(trkPosOut[1] - trkPosIn[1]) + (trkPosOut[2] - trkPosIn[2])*(trkPosOut[2] - trkPosIn[2]));
87 m_track_length = 0;
88
89 m_n_ion_mm = N_PRI_AVE/m_track_length_limit; // CHECK 2) N_PRI_AVE
90
91 /**
92 cout << "m_n_ion_mm " << m_n_ion_mm << " N_PRI_AVE " << N_PRI_AVE << " m_track_length_limit " << m_track_length_limit << endl;
93 cout << "xIN " << trkPosIn[0] << " yIN " << trkPosIn[1] << " zIN " << trkPosIn[2] << endl;
94 cout << "xOUT " << trkPosOut[0] << " yOUT " << trkPosOut[1] << " zOUT " << trkPosOut[2] << endl;
95 **/
96
97 // loop over ionization clusters
98 int counter = 0;
99
100 double last_x;
101 double last_y;
102 double last_z;
103 double last_t;
104
105 while(1) {
106
107 // primary ionization
108 bool is_inside = generate_primary_ele();
109 if(!is_inside) break;
110
111 // secondary ionization
112 int nof_sec_ele = generate_secondary_ele();
113 m_nIonE += nof_sec_ele;
114
115 // compute position
116 double x = 0;
117 double y = 0;
118 double z = 0;
119 double t = 0; // <-track_time; // CHECK 3) add the track time
120 compute_pos(trkPosIn, trkPosOut, x, y, z);
121 // cout << "ionization electron pos " << x << " " << y << " " << z << endl;
122
123 // set cluster pos
124 m_cx.push_back(x); // CHECK 5) cluster info
125 m_cy.push_back(y); // CHECK 5) cluster info
126 m_cz.push_back(z); // CHECK 5) cluster info
127 m_ct.push_back(t); // CHECK 5) cluster info
128
129 // cout << "x " << x << " y " << y << " z " << z << " t " << t << endl;
130
131 if(m_testing==true && counter > 0) {
132 double distance = TMath::Sqrt((last_x - x)*(last_x - x) + (last_y - y)*(last_y - y) + (last_z - z)*(last_z - z));
133 h_distance_cluster->Fill(distance);
134 last_x = x;
135 last_y = y;
136 last_z = z;
137 last_t = t;
138 }
139
140 // set ele pos
141 for(int iele = 0; iele < nof_sec_ele + 1; iele++)
142 {
143 m_ex.push_back(x);
144 m_ey.push_back(y);
145 m_ez.push_back(z);
146 m_et.push_back(t);
147
148 }
149 counter++;
150 // cout << "ion position " << x << " " << y << " " << z << endl;
151
152 }
153
154 if(m_nIonE != m_ex.size()) std::cout << "IonizationGTS::setTrack ERRRRRRRRRRRRRROR" << std::endl; // CHECK delete this
155
156 if(m_testing==true) h_nof_cluster->Fill(counter-1);
157
158 clock_t end = clock();
159 time_spent += (double)(end - begin) / CLOCKS_PER_SEC;
160 cout << "Sampling::ionization " << m_nIonE << " time " << time_spent << " seconds" << endl;
161
162
163
164
165}
166
167// computation of the ionization clusters:
168// the number of clusters is Poissonian -> the inder-distance is neg-exponential
170
171 double u = gRandom->Uniform(0, 1); // CHECK 6) TRandom
172 // step along the trajectory, that for now is a straight line [x0, z0] -> [x1, z1]
173 double dl_extracted = -(1./m_n_ion_mm) * TMath::Log(1 - u);
174 m_track_length += dl_extracted;
175
176 // cout << "m_track_length " << m_track_length << " dl_extracted " << dl_extracted << endl;
177
178
179 if(m_track_length > m_track_length_limit) return false;
180
181 m_nIonC++;
182 m_nIonE++;
183 return true;
184}
185
186// computation of the number of secondary elecrons per primary ionization:
187// they are all generated in the same position of the prim cluster
189 int n_elec=0;
190 double prob = gRandom->Uniform(0, 1); // CHECK 6) TRandom
191
192 for(int iele = 0; iele < 100; iele++) { // CHECK 4) cut at 100
193 n_elec = iele + 1;
194 if(prob < int_prob_electron_per_cluster[iele]) break;
195 }
196
197 if(n_elec>100) {
198 std::cout << "IonizationGTS::generate_secondary_ele: increase the size above 100"<<endl; // CHECK 4)
199 n_elec=100;
200 }
201
202 return n_elec;
203}
204
205void IonizationGTS::compute_pos(double posin[], double posout[], double &x, double &y, double &z) {
206
207 double t = (m_track_length_limit - m_track_length)/m_track_length_limit;
208 x = posin[0] * t + posout[0] * (1 - t);
209 y = posin[1] * t + posout[1] * (1 - t);
210 z = posin[2] * t + posout[2] * (1 - t);
211
212}
213
214/**
215// from global to local frame
216// xl = coordinate along the cylinder circunference (parallel to the electrodes) = (yg/xg) * sqrt(xg**2 + yg**2)
217// yl = coordinate along the cylinder axis (coincident with zg)
218// zl = coordinate along the cylinder radius (orthogonal to the electrodes - [inner_radius_layer + cathode_thick]) = sqrt(xg**2 + yg**2) - [inner_radius_layer + cathode_thick])
219void IonizationGTS::port_track_to_loc(double xg_in, double yg_in, double zg_in, double xg_out, double yg_out, double zg_out,
220 double &xl_in, double &yl_in, double &zl_in, double &xl_out, double &yl_out, double &zl_out)
221{
222
223 xl_in = 0;
224 yl_in = 0;
225 zl_in = 0;
226
227 // ---------------------------------------------------
228 double R_catout[3] = {m_geomSvc->getCgemLayer(0)->getInnerROfCgemLayer() + m_geomSvc->getThicknessOfCathode(),
229 m_geomSvc->getCgemLayer(1)->getInnerROfCgemLayer() + m_geomSvc->getThicknessOfCathode(),
230 m_geomSvc->getCgemLayer(2)->getInnerROfCgemLayer() + m_geomSvc->getThicknessOfCathode()};
231
232 double thick[3] = {m_geomSvc->getCgemLayer(0)->getThicknessOfGapD(),
233 m_geomSvc->getCgemLayer(1)->getThicknessOfGapD(),
234 m_geomSvc->getCgemLayer(2)->getThicknessOfGapD()};
235
236 TVector3 vg_in_xy(xg_in, yg_in, 0);
237 TVector3 vg_out_xy(xg_out, yg_out, 0);
238 // radial distance
239 double radg_in = vg_in_xy.Perp();
240 if(radg_in < R_catout[1]) zl_out = thick[0];
241 else if(radg_in < R_catout[2]) zl_out = thick[1];
242 else zl_out = thick[2];
243
244 // direction xy
245 TVector3 d_xy = vg_out_xy - vg_in_xy;
246 // direction vin, with magnitute=thick
247 TVector3 r_xy = vg_in_xy; r_xy.SetMag(zl_out);
248 double alpha = TMath::ACos(d_xy.Dot(r_xy)/(d_xy.Mag()*r_xy.Mag()));
249 double sign = d_xy.Cross(r_xy).Z()/fabs(d_xy.Cross(r_xy).Z());
250 if(fabs(yg_out) < 1e-7) xl_out = 0;
251 else xl_out = sign * zl_out * TMath::Tan(alpha);
252
253 // much easier procedure for yl_out
254 double delta_z = zg_out - zg_in;
255 yl_out = delta_z;
256
257}
258**/
259
260void IonizationGTS::clear(){
261 m_track_length_limit = 0;
262 m_track_length = 0;
263 // cluster
264 m_nIonC = 0;
265 m_cx.clear();
266 m_cy.clear();
267 m_cz.clear();
268 m_ct.clear();
269 // electron
270 m_nIonE = 0;
271 m_ex.clear();
272 m_ey.clear();
273 m_ez.clear();
274 m_et.clear();
275}
276
Double_t x[10]
#define N_PRI_AVE
const double int_prob_electron_per_cluster[100]
#define m_testing
void init(unsigned int random, ICgemGeomSvc *geomSvc, double magConfig)
void setTrack(int particle, int charge, double p, double trkPosIn[], double trkPosOut[])
void compute_pos(double trkPosIn[], double trkPosOut[], double &x, double &y, double &z)
bool generate_primary_ele()
int generate_secondary_ele()
int t()
Definition t.c:1