4#include "CgemDigitizerSvc/InductionGTS.h"
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"
12#include "CLHEP/Units/PhysicalConstants.h"
14#include "G4DigiManager.hh"
15#include "Randomize.hh"
18#include "CLHEP/Units/PhysicalConstants.h"
42 double tminbin = hcollected_charge->FindBin(
apv_tstart);
45 delete hcollected_charge;
54 m_magConfig = magConfig;
57 string filePath = getenv(
"CGEMDIGITIZERSVCROOT");
60 fileName = filePath +
"/dat/par_settings_GTS.txt";
61 ifstream fin(fileName.c_str(), ios::in);
65 if( ! fin.is_open() ){
66 std::cout <<
"InductionGTS::init ERROR: can not open file " << filePath << endl;
68 else std::cout <<
"InductionGTS::init: open file " << fileName << endl;
74 getline(fin, strline);
76 else if(strpar ==
"magnetic_field") {
79 else if(strpar ==
"tuning_factor_diff_perp") {
80 fin >> m_tuning_factor_diff_perp;
82 else if(strpar ==
"tuning_factor_diff_paral") {
83 fin >> m_tuning_factor_diff_paral;
87 cout <<
"InductionGTS::init: drift and avalanche parameters" << endl;
88 cout <<
"field " << m_field <<endl;
89 cout <<
"tuning factors for diffusion " << m_tuning_factor_diff_perp <<
" (for orthogonal) " << m_tuning_factor_diff_paral <<
" (for parallel)" << endl;
92 if(m_field) fileName = filePath +
"/dat/par_ArIso_1T_GTS.txt";
93 else fileName = filePath +
"/dat/par_ArIso_0T_GTS.txt";
97 output =
new TFile(
"induction.root",
"RECREATE");
98 tree =
new TNtuple(
"tree",
"tree",
"dphi:darc");
99 tree_strip =
new TNtuple(
"tree_strip",
"tree for strip",
"evt:id:view:qind:q:t");
103 string fileName2 = filePath +
"/dat/par_ArIso_0T_GTS.txt";
104 hcollected_charge =
new TH1F(
"hcollected_charge",
"hcollected_charge",
hnbin,
hxmin,
hxmax);
106 hcharge =
new TH1F(
"hcharge",
"ASIC measured charge", 28,
hxmin,
hxmax);
107 double tminbin = hcollected_charge->FindBin(
apv_tstart);
108 double dt = hcollected_charge->GetXaxis()->GetBinWidth(1);
110 for(
int it = tminbin; it <
hnbin; it++) {
112 TString name =
"f"; name += it;
113 f[it] =
new TF1(name,
"[0] * ((x - [1]) / [2]) * TMath::Exp(-(x - [1]) / [2])",
t,
hxmax);
116 f_FD =
new TF1(
"f_FD",
"[0] + [1]/(1+TMath::Exp(-(x - [2])/[3]))",
hxmin,
hxmax);
139 m_XstripSheet.clear();
141 m_VstripSheet.clear();
151 double time_spent = 0.;
152 clock_t begin = clock();
156 std::vector < double > stripid_x;
157 std::vector < double > ind_charge_x;
158 std::vector < double > ind_time_x;
160 std::vector < double > stripid_v;
161 std::vector < double > ind_charge_v;
162 std::vector < double > ind_time_v;
167 for(
int iele = 0; iele < nElectrons; iele++){
169 double x_start =
x.at(iele);
170 double y_start = y.at(iele);
171 double z_start = z.at(iele);
172 double t_start =
t.at(iele);
175 double x_end, y_end, z_end, t_end;
176 bool isanode =
drive_to_anode(layer, x_start, y_start, z_start, t_start, x_end, y_end, z_end, t_end);
179 double phi = TMath::ATan2(y_start, x_start);
180 if(layer > 0 && phi > TMath::Pi()) sheet = 1;
185 G4ThreeVector pos(x_end, y_end, z_end);
202 double qele = 1.6e-4;
205 stripid_x.push_back(X_ID);
206 ind_charge_x.push_back(percX * qele);
207 ind_time_x.push_back(t_end);
208 sheetid_x.push_back(sheet);
209 stripid_v.push_back(V_ID);
210 ind_charge_v.push_back(percV * qele);
211 ind_time_v.push_back(t_end);
212 sheetid_v.push_back(sheet);
219 for (std::vector< double >::iterator it = stripid_x.begin() ; it != stripid_x.end(); it++) {
220 double stripid = *it;
221 int ipos = it - stripid_x.begin();
222 double sheetid = sheetid_x.at(ipos);
224 std::vector< double >::iterator it2 = std::find(m_XstripID.begin(), m_XstripID.end(), stripid);
225 std::vector< double >::iterator it3 = std::find(m_XstripSheet.begin(), m_XstripSheet.end(), sheetid);
227 if(it2 == m_XstripID.end() || it3 == m_XstripSheet.end()) {
228 m_XstripID.push_back(stripid);
229 m_XstripSheet.push_back(sheetid);
232 double sheetid3 = *it3;
233 if(sheetid != sheetid3) {
234 m_XstripID.push_back(stripid);
235 m_XstripSheet.push_back(sheetid);
239 m_NXstrips = m_XstripID.size();
243 for(
int istrip = 0; istrip < m_NXstrips; istrip++) {
244 double xID = m_XstripID.at(istrip);
249 bool isASIC =
useAPV(xID, view, stripid_x, ind_charge_x, ind_time_x, strip_charge, strip_time, strip_dtime);
250 m_XstripQ.push_back(strip_charge);
251 m_XstripT.push_back(strip_time);
256 for (std::vector< double >::iterator it = stripid_v.begin() ; it != stripid_v.end(); it++) {
257 double stripid = *it;
258 int ipos = it - stripid_v.begin();
259 double sheetid = sheetid_v.at(ipos);
261 std::vector< double >::iterator it2 = std::find(m_VstripID.begin(), m_VstripID.end(), stripid);
262 std::vector< double >::iterator it3 = std::find(m_VstripSheet.begin(), m_VstripSheet.end(), sheetid);
264 if(it2 == m_VstripID.end() || it3 == m_VstripSheet.end()) {
265 m_VstripID.push_back(stripid);
266 m_VstripSheet.push_back(sheetid);
269 double sheetid3 = *it3;
270 if(sheetid != sheetid3) {
271 m_VstripID.push_back(stripid);
272 m_VstripSheet.push_back(sheetid);
276 m_NVstrips = m_VstripID.size();
281 for(
int istrip = 0; istrip < m_NVstrips; istrip++) {
282 double vID = m_VstripID.at(istrip);
288 bool isASIC =
useAPV(vID, view, stripid_v, ind_charge_v, ind_time_v, strip_charge, strip_time, strip_dtime);
289 m_VstripQ.push_back(strip_charge);
290 m_VstripT.push_back(strip_time);
293 clock_t end = clock();
294 time_spent += (double)(end - begin) / CLOCKS_PER_SEC;
295 cout <<
"InductionGTS::induzione " << time_spent <<
" seconds" << endl;
303bool InductionGTS::useAPV(
int stripid,
int view, std::vector< double > stripidvec, std::vector< double > indchargevec, std::vector< double > indtimevec,
double &charge,
double &
time,
double &dtime)
315 hcollected_charge->Reset();
318 name =
"hcollected_charge";
320 hcollected_charge->SetName(name);
323 std::vector< double >::iterator
iter = stripidvec.begin();
325 if(
iter != stripidvec.end()+1)
iter = std::find(
iter, stripidvec.end(), stripid);
327 int ipos =
iter - stripidvec.begin();
328 std::vector< double >::iterator iter2 = indtimevec.begin() + ipos;
329 std::vector< double >::iterator iter3 = indchargevec.begin() + ipos;
330 hcollected_charge->Fill(*iter2, *iter3);
334 double ind_charge = hcollected_charge->Integral();
336 double dt = hcollected_charge->GetXaxis()->GetBinWidth(1);
338 double tminbin = hcollected_charge->FindBin(
apv_tstart);
339 for(
int it = tminbin; it <
hnbin; it++) {
341 double timebin = hcollected_charge->FindBin(
t);
342 double integral = hcollected_charge->GetBinContent(timebin);
344 name =
"f"; name += it; name +=
"_strip"; name += stripid;
345 f[it]->SetName(name);
347 f[it]->SetParameter(0, TMath::Exp(1.)*integral);
348 f[it]->SetParameter(1,
t);
349 f[it]->SetParameter(2, tau_APV);
352 hintegratore->Reset();
354 name =
"hintegratore";
356 hintegratore->SetName(name);
359 for(
int it = tminbin; it <
hnbin; it++) {
362 for(
int jt = tminbin; jt <
hnbin; jt++) {
364 if(t2 <
t) qmeas += f[jt]->Eval(
t);
366 hintegratore->SetBinContent(it, qmeas);
373 hcharge->SetName(name);
377 for(
int iapv = 0; iapv < ntime; iapv++) {
379 double timebin = hintegratore->FindBin(
t);
380 double qmeas = hintegratore->GetBinContent(timebin);
381 hcharge->AddBinContent(iapv+1, qmeas);
392 charge = hcharge->GetMaximum();
396 double maxbin = hcharge->GetMaximumBin();
397 double QMaxHisto = hcharge->GetMaximum();
401 for(
int ibin = maxbin; ibin > 1; ibin--){
402 if(hcharge->GetBinContent(ibin) < 0.1 * QMaxHisto) {
407 double startvalues[5] = {0};
408 double fitlimup[5] = {0};
409 double fitlimlow[5] = {0};
412 double meanfirstbin = (hcharge->GetBinContent(minbin-1) + hcharge->GetBinContent(minbin-2) + hcharge->GetBinContent(minbin-3))/3.;
413 double sigma_MFB = TMath::Sqrt( ( pow(hcharge->GetBinContent(minbin-1) - meanfirstbin, 2) + pow(hcharge->GetBinContent(minbin-2) - meanfirstbin,2) + pow(hcharge->GetBinContent(minbin-3)- meanfirstbin,2)) / 3);
414 if(sigma_MFB < TMath::Abs(meanfirstbin)) sigma_MFB = TMath::Abs(meanfirstbin);
416 startvalues[0] = meanfirstbin;
417 startvalues[1] = QMaxHisto;
418 startvalues[2] = 0.5* (minbin + maxbin) *
tstep;
419 startvalues[3] = 0.5*
tstep;
422 fitlimlow[0] = startvalues[0] - 2 * sigma_MFB;
423 fitlimlow[1] = startvalues[1] - 0.3 * startvalues[1];
424 fitlimlow[2] = minbin *
tstep;
425 fitlimlow[3] = 0.1*
tstep;
427 fitlimup[0] = startvalues[0] + 2 * sigma_MFB;
428 fitlimup[1] = startvalues[1] + 0.3 * startvalues[1];
429 fitlimup[2] = maxbin *
tstep;
430 fitlimup[3] = 0.9*
tstep;
441 double minFD = minbin - 4;
442 double maxFD = maxbin + 0;
450 f_FD->SetParameters(startvalues[0], startvalues[1], startvalues[2], startvalues[3]);
451 f_FD->SetParLimits(0, fitlimlow[0], fitlimup[0]);
452 f_FD->SetParLimits(1, fitlimlow[1], fitlimup[1]);
453 f_FD->SetParLimits(2, fitlimlow[2], fitlimup[2]);
454 f_FD->SetParLimits(3, fitlimlow[3], fitlimup[3]);
456 hcharge->Fit(f_FD,
"WQRB0");
458 time = gRandom->Gaus(f_FD->GetParameter(2), 8);
461 dtime = f_FD->GetParError(2);
463 if(
m_testing_ind) tree_strip->Fill(evt, stripid, view, ind_charge, charge,
time);
471 double R = TMath::Sqrt(xi*xi + yi*yi);
472 double phi = TMath::ATan2(yi, xi);
478 double shift_phi = shift_x_induct/gem3_rad_out;
479 double sigma_phi = sigma_x_induct/gem3_rad_out;
480 double phif = phi + gRandom->Gaus(shift_phi, sigma_phi);
483 xf = anode_rad_in * TMath::Cos(phif);
484 yf = anode_rad_in * TMath::Sin(phif);
489 zf = zi + gRandom->Gaus(shift_y_induct, sigma_y_induct);
498 tf = ti + gRandom->Gaus(shift_t_induct, sigma_t_induct);
500 double dphi = phif - phi;
501 double darc = anode_rad_in * dphi;
double getOuterROfCgemFoil() const
CgemGeoFoil * getCgemFoil(int i) const
double getInnerROfAnode() const
void getStripID(G4ThreeVector pos, int &X_ID, int &V_ID) const
void readGasPerpParameters(std::string fileName)
void readGasParalParameters(std::string fileName)
virtual CgemGeoReadoutPlane * getReadoutPlane(int iLayer, int iSheet) const =0
virtual CgemGeoLayer * getCgemLayer(int i) const =0
bool useAPV(int stripid, int view, std::vector< double > stripidvec, std::vector< double > indchargevec, std::vector< double > indtimevec, double &charge, double &time, double &dtime)
int getVstripID(int n) const
double getXstripT(int n) const
bool drive_to_anode(int, double, double, double, double, double &, double &, double &, double &)
double getVstripT(int n) const
int getVstripSheet(int n) const
int getXstripSheet(int n) const
void init(ICgemGeomSvc *geomSvc, double magConfig)
void setMultiElectrons(int layer, int nElectrons, std::vector< double > x, std::vector< double > y, std::vector< double > z, std::vector< double > t)
double getVstripQ(int n) const
int getXstripID(int n) const
double getXstripQ(int n) const