11#include "GaudiKernel/MsgStream.h"
12#include "GaudiKernel/Bootstrap.h"
13#include "GaudiKernel/PropertyMgr.h"
14#include "GaudiKernel/IJobOptionsSvc.h"
15#include "GaudiKernel/ISvcLocator.h"
16#include "GaudiKernel/IDataProviderSvc.h"
21#include "G4DigiManager.hh"
22#include "Randomize.hh"
30#include "G4SystemOfUnits.hh"
31#include "G4PhysicalConstants.hh"
35 PropertyMgr m_propMgr;
36 m_propMgr.declareProperty(
"FileName", m_fileName =
"mrpc.root");
37 m_propMgr.declareProperty(
"RootFlag", m_rootFlag =
false);
38 m_propMgr.declareProperty(
"E", m_V = 7000);
39 m_propMgr.declareProperty(
"Threshold", m_threshold = 5.5e+08);
41 m_propMgr.declareProperty(
"nstep", m_nstep = -1);
42 m_propMgr.declareProperty(
"E_weight", m_E_weight = -1);
43 m_propMgr.declareProperty(
"saturationFlag", m_saturationFlag =
true);
44 m_propMgr.declareProperty(
"tdcRes_const", tdcRes_const = -1);
45 m_propMgr.declareProperty(
"adcRes_const", adcRes_const = -1);
46 m_propMgr.declareProperty(
"calTdcRes_charge_flag", m_calTdcRes_charge_flag=0);
47 m_propMgr.declareProperty(
"charge2Time_flag", m_charge2Time_flag=0);
48 m_propMgr.declareProperty(
"calAdcRes_charge_flag", m_calAdcRes_charge_flag=0);
50 IJobOptionsSvc* jobSvc;
51 Gaudi::svcLocator()->service(
"JobOptionsSvc", jobSvc);
52 jobSvc->setMyProperties(
"BesTofDigitizerEcV4", &m_propMgr);
58 m_file =
new TFile(m_fileName.c_str(),
"RECREATE");
59 m_tree =
new TTree(
"mrpc",
"mrpc");
61 m_tree->Branch(
"event", &m_event,
"event/D");
62 m_tree->Branch(
"partId", &m_partId,
"partId/D");
63 m_tree->Branch(
"module", &m_module,
"module/D");
64 m_tree->Branch(
"time_leading_sphi", &m_time_leading_sphi,
"time_leading_sphi/D");
65 m_tree->Branch(
"time_leading_xphi", &m_time_leading_xphi,
"time_leading_xphi/D");
66 m_tree->Branch(
"time_trailing_sphi", &m_time_trailing_sphi,
"time_trailing_sphi/D");
67 m_tree->Branch(
"time_trailing_xphi", &m_time_trailing_xphi,
"time_trailing_xphi/D");
68 m_tree->Branch(
"tdcRes", &m_tdcRes,
"tdcRes/D");
69 m_tree->Branch(
"tdcRes_charge", &m_tdcRes_charge,
"tdcRes_charge/D");
70 m_tree->Branch(
"adc", &m_adc,
"adc/D");
71 m_tree->Branch(
"adcRes", &m_adcRes,
"adcRes/D");
72 m_tree->Branch(
"adcRes_charge", &m_adcRes_charge,
"adcRes_charge/D");
73 m_tree->Branch(
"strip", &m_strip,
"strip/D");
74 m_tree->Branch(
"trkIndex", &m_trkIndex,
"trkIndex/D");
75 m_tree->Branch(
"tStart", &m_tStart,
"tStart/D");
76 m_tree->Branch(
"tPropagate_sphi", &m_tPropagate_sphi,
"tPropagate_sphi/D");
77 m_tree->Branch(
"tPropagate_xphi", &m_tPropagate_xphi,
"tPropagate_xphi/D");
78 m_tree->Branch(
"tThreshold", &m_tThreshold,
"tThreshold/D");
79 m_tree->Branch(
"charge", &m_charge,
"charge/D");
80 m_tree->Branch(
"nhit", &m_nhit,
"nhit/I");
81 m_tree->Branch(
"ions_hit", m_ions_hit,
"ions_hit[nhit]/D");
82 m_tree->Branch(
"trkIndex_hit", m_trkIndex_hit,
"trkIndex_hit[nhit]/D");
83 m_tree->Branch(
"pdgCode_hit", m_pdgCode_hit,
"pdgCode_hit[nhit]/D");
84 m_tree->Branch(
"gap_hit", m_gap_hit,
"gap_hit[nhit]/D");
85 m_tree->Branch(
"underStrip_hit", m_underStrip_hit,
"underStrip_hit[nhit]/D");
86 m_tree->Branch(
"locx_hit", m_locx_hit,
"locx_hit[nhit]/D");
87 m_tree->Branch(
"locy_hit", m_locy_hit,
"locy_hit[nhit]/D");
88 m_tree->Branch(
"locz_hit", m_locz_hit,
"locz_hit[nhit]/D");
89 m_tree->Branch(
"x_hit", m_x_hit,
"x_hit[nhit]/D");
90 m_tree->Branch(
"y_hit", m_y_hit,
"y_hit[nhit]/D");
91 m_tree->Branch(
"z_hit", m_z_hit,
"z_hit[nhit]/D");
92 m_tree->Branch(
"px_hit", m_px_hit,
"px_hit[nhit]/D");
93 m_tree->Branch(
"py_hit", m_py_hit,
"py_hit[nhit]/D");
94 m_tree->Branch(
"pz_hit", m_pz_hit,
"pz_hit[nhit]/D");
111 m_param.
setPar(m_nstep, m_E_weight, m_V);
118 if(tdcRes_const<0) tdcRes_const = 38;
123 if(adcRes_const<0) adcRes_const = 27;
126 time_leading_sphi = -999;
127 time_leading_xphi = -999;
128 time_trailing_sphi = -999;
129 time_trailing_xphi = -999;
131 cout<<
"Property:"<<endl
132 <<
" FileName= "<<m_fileName
134 <<
" Threshold= "<<m_threshold
135 <<
" nstep= "<<m_nstep
136 <<
" E_weight= "<<m_E_weight
137 <<
" saturationFlag= "<<m_saturationFlag
138 <<
" tdcRes_const= "<<tdcRes_const
139 <<
" adcRes_const= "<<adcRes_const
140 <<
" calTdcRes_charge_flag= "<<m_calTdcRes_charge_flag
141 <<
" charge2Time_flag= "<<m_charge2Time_flag
142 <<
" calAdcRes_charge_flag= "<<m_calAdcRes_charge_flag
149 G4DigiManager* digiManager = G4DigiManager::GetDMpointer();
150 G4int THCID = digiManager->GetHitsCollectionID(
"BesTofHitsCollection");
159 int nstrip = m_param.
nstrip;
161 for(
int i=0; i<nstrip; i++)
163 stripStruct[i].
m_param = m_param;
185 hitStruct.
x = hit->
GetPos().x()/mm;
186 hitStruct.
y = hit->
GetPos().y()/mm;
187 hitStruct.
z = hit->
GetPos().z()/mm;
202 for(
int i=0; i<nstrip; i++)
204 if(stripStruct[i].hitStructCol.size()==0)
continue;
205 stripStruct[i].
strip = i;
210 if(stripStruct[i].tThreshold<=0)
continue;
215 double tdcRes_charge;
216 if(m_calTdcRes_charge_flag==0)
220 else if(m_calTdcRes_charge_flag==1)
224 else if(m_calTdcRes_charge_flag==2)
229 tdcRes = sqrt(tdcRes_charge*tdcRes_charge+tdcRes_const*tdcRes_const)/1000;
231 tdc_sphi = G4RandGauss::shoot(tdc_sphi, tdcRes);
232 tdc_xphi = G4RandGauss::shoot(tdc_xphi, tdcRes);
234 if(m_charge2Time_flag==0)
238 else if(m_charge2Time_flag==1)
243 double adcRes_charge;
244 if(m_calAdcRes_charge_flag==0)
248 else if(m_calAdcRes_charge_flag==1)
252 else if(m_calAdcRes_charge_flag==2)
257 adcRes = sqrt(adcRes_charge*adcRes_charge+adcRes_const*adcRes_const)/1000;
258 adc = G4RandGauss::shoot(adc, adcRes);
261 time_leading_sphi = tdc_sphi;
262 time_leading_xphi = tdc_xphi;
263 time_trailing_sphi = tdc_sphi+adc;
264 time_trailing_xphi = tdc_xphi+adc;
272 digi->
SetStrip(stripStruct[i].strip);
273 int mo = (partId-3)*36+module;
274 int st = stripStruct[i].
strip;
313 m_time_leading_sphi = time_leading_sphi;
314 m_time_leading_xphi = time_leading_xphi;
315 m_time_trailing_sphi = time_trailing_sphi;
316 m_time_trailing_xphi = time_trailing_xphi;
318 m_tdcRes_charge = tdcRes_charge;
321 m_adcRes_charge = adcRes_charge;
323 m_strip = stripStruct[i].
strip;
324 m_trkIndex = stripStruct[i].
trkIndex;
325 m_tStart = stripStruct[i].
tStart;
329 m_charge = stripStruct[i].
charge;
333 for(
int j=0; j<m_nhit; j++)
336 m_trkIndex_hit[j] = stripStruct[i].
hitStructCol[j].trkIndex;
337 m_pdgCode_hit[j] = stripStruct[i].
hitStructCol[j].pdgCode;
339 m_underStrip_hit[j] = stripStruct[i].
hitStructCol[j].underStrip;
359 int nstrip = m_param.
nstrip;
361 double length = locZ+stripWidth*nstrip/2-0.5;
366 else if(length<stripWidth*nstrip)
368 for(
int i=0; i<nstrip; i++)
370 if(length>i*stripWidth && length<(i+1)*stripWidth)
382 if(strip>nstrip-1) strip=nstrip-1;
392 int nstrip = m_param.
nstrip;
394 double length = locZ+stripWidth*nstrip/2-0.5;
395 if(length<stripWidth*nstrip)
397 for(
int i=0; i<nstrip; i++)
399 if(length>i*stripWidth && length<(i+1)*stripWidth)
402 if(length>i*stripWidth+m_param.
strip_gap/2 && length<(i+1)*stripWidth-m_param.
strip_gap/2
430 if(strip<0 || strip>m_param.
nstrip-1)
432 cout<<
"!! BesTofDigitizerEcV4::HitStruct::calTPropagate Wrong Strip !!!"<<endl;
437 double length_sphi = m_param.
strip_x[strip]/2-locx;
438 tPropagate_sphi =
abs(length_sphi)/v_propagate;
440 double length_xphi = m_param.
strip_x[strip]/2+locx;
441 tPropagate_xphi =
abs(length_xphi)/v_propagate;
450 if(gap>=0 && gap<m_param.
ngap/2) length = m_param.
gapWidth/2+locy;
451 else if(gap<m_param.
ngap) length = m_param.
gapWidth/2-locy;
454 cout<<
"BesTofDigitizerEcV4::StripStruct::calAvaLength Wrong gap calculation !!!"<<endl;
464 for(
unsigned int i=0; i<hitStructCol.size(); i++)
466 hitStructCol[i].ava_pos.clear();
467 hitStructCol[i].ava_num.clear();
469 hitStructCol[i].ava_pos[0] = hitStructCol[i].calAvaLength();
470 hitStructCol[i].ava_num[0] = hitStructCol[i].ions;
472 for(
int j=1; j<m_param.
nstep; j++)
474 hitStructCol[i].ava_pos[j] = hitStructCol[i].ava_pos[j-1] + m_param.
stepWidth;
475 if(saturationFlag==
true && hitStructCol[i].ava_num[j-1]>1.5e+07)
477 hitStructCol[i].ava_num[j] = hitStructCol[i].ava_num[j-1];
481 hitStructCol[i].ava_num[j] = calNextN(hitStructCol[i].ava_num[j-1]);
483 if(hitStructCol[i].ava_pos[j]>m_param.
gapWidth)
break;
488 bool over_threshold =
false;
490 for(
int i=0; i<m_param.
nstep; i++)
492 for(
unsigned int j=0; j<hitStructCol.size(); j++)
494 if(i<hitStructCol[j].ava_pos.size() && hitStructCol[j].ava_pos[i]<m_param.
gapWidth)
496 sum += hitStructCol[j].ava_num[i];
501 if(over_threshold==
false)
505 over_threshold =
true;
506 tThreshold = (m_param.
gapWidth)/(m_param.
nstep)/v_drift*(i+1);
521 for(
int i=0; i<
num; i++)
523 rdm = G4UniformRand();
524 nextN += multiply(rdm);
531 double sigma = calSigma();
532 double mean =
num*nbar;
533 double resolution = G4RandGauss::shoot(0,(sqrt(
num)*
sigma));
534 long int nextN = mean+resolution;
542 double k = eta/
alpha;
543 double rdm_border = k*(nbar-1)/(nbar-k);
550 long int number = 1.+1./log((nbar-1.)/(nbar-k))*log((nbar-k)*(rdm-1)/(k-1)/nbar);
558 double k = eta/
alpha;
559 double sigma = sqrt((1+k)/(1-k)*nbar*(nbar-1));
568 time = 100.764*
exp(-charge_fC*0.0413966+0.377154)+ 13.814;
572 time = 12.8562+0.000507299*charge_fC;
581 time=-120.808/log(charge_fC*30.1306)+26.6024;
591 time = 72.6005*
exp(-charge_fC*0.0302626 + 1.49059) + 40.8627;
595 time = 32.6233+0.00404149*charge_fC;
606 result = 67.6737*
exp(-charge_fC/50.9995-0.27755)+9.06223;
610 result = 176.322-2.98345*charge_fC;
612 if(result<0) result=0;
619 time=-4.50565/log(charge_fC*0.0812208)+16.6653;
626 double time = 64.3326*
exp(-charge_fC/25.4638 + 0.944184)+19.4846;
655 v_propagate = 0.5*0.299792458e+3;
656 tPropagate_sphi = -999.0;
657 tPropagate_xphi = -999.0;
671 tPropagate_sphi = -999.0;
672 tPropagate_xphi = -999.0;
678 alpha = 144800./1000;
683 hitStructCol.clear();
691 threshold = threshold_n;
693 saturationFlag = saturationFlag_n;
698 if(nstep_n>0) nstep = nstep_n;
699 if(E_weight_n>0) E_weight = E_weight_n;
702 double E_eff = E/1000*2/6/(gapWidth/10);
703 alpha = getAlpha(E_eff);
705 v_drift = getV(E_eff);
714 std::stringstream ss;
715 for(
int i=0; i<nstrip; i++)
718 ss<<
"strip_x["<<i<<
"]";
719 strip_x[i] = tofPara->Get(ss.str().c_str());
721 strip_z = tofPara->Get(
"strip_z");
722 strip_gap = tofPara->Get(
"strip_gap");
727 stepWidth = gapWidth/nstep;
728 E_weight = 1./(6.*0.22+(5.*0.4+2*0.55)/3.7);
729 eCharge = 1.60217733e-7;
730 tofPara->Get_deadChannel(deadChannel);
792 TSpline3* sp_alpha =
new TSpline3(
"sp_alpha", e,
alpha, 22);
793 double alphaVal = sp_alpha->Eval(E);
855 TSpline3* sp_eta =
new TSpline3(
"sp_eta", e, eta, 22);
856 double etaVal = sp_eta->Eval(E);
918 TSpline3* sp_v =
new TSpline3(
"sp_v", e,
v, 22);
919 double vVal = sp_v->Eval(E);
926 cout<<
"Fixed parameters: "<<endl;
927 for(
int i=0; i<nstrip; i++)
929 cout<<
" strip_x["<<i<<
"]= "<<strip_x[i];
931 for(
int i=0; i<nmodule; i++)
933 for(
int j=0; j<nstrip; j++)
935 if(deadChannel[i][j]!=-999)
937 cout<<
" deadChannel["<<i<<
"]["<<j<<
"]= "<<deadChannel[i][j];
942 cout<<
" strip_z= "<<strip_z
943 <<
" strip_gap= "<<strip_gap
945 <<
" gapWidth= "<<gapWidth
947 <<
" stepWidth= "<<stepWidth
948 <<
" E_weight= "<<E_weight
949 <<
" eCharge= "<<eCharge
953 <<
" v_drift= "<<v_drift
959 cout<<
"Hit information: "<<endl;
960 cout<<
" trkIndex= "<<trkIndex
961 <<
" pdgCode= "<<pdgCode
965 <<
" glbTime= "<<glbTime
975 <<
" v_propagate= "<<v_propagate
976 <<
" tPropagate_sphi= "<<tPropagate_sphi
977 <<
" tPropagate_xphi= "<<tPropagate_xphi
983 cout<<
"Strip information: "<<endl;
984 cout<<
" strip= "<<strip
985 <<
" trkIndex= "<<trkIndex
986 <<
" tStart= "<<tStart
987 <<
" tPropagate_sphi= "<<tPropagate_sphi
988 <<
" tPropagate_xphi= "<<tPropagate_xphi
989 <<
" tThreshold "<<tThreshold
993 <<
" threshold= "<<threshold
994 <<
" v_drift= "<<v_drift
G4TDigiCollection< BesTofDigi > BesTofDigitsCollection
G4THitsCollection< BesTofHit > BesTofHitsCollection
EvtComplex exp(const EvtComplex &c)
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
void SetForwT1(G4double t1)
void SetPartId(G4int partId)
void SetTrackIndex(G4int index)
void SetForwT2(G4double t2)
void SetBackT1(G4double t1)
void SetModule(G4int module)
void SetBackT2(G4double t2)
void SetStrip(G4int strip)
double calTdcRes_charge1(double charge_fC)
double calAdcRes_charge(double charge_fC)
double calAdcRes_charge1(double charge_fC)
bool underStrip(double locX, double locZ)
int calStrip(double locZ)
virtual void Digitize(ScintSingle *, BesTofDigitsCollection *)
double charge2Time1(double charge_fC)
double charge2Time(double charge_fC)
double calTdcRes_charge(double charge_fC)
BesTofDigitsCollection * m_besTofDigitsCollection
BesTofHitsCollection * m_THC
static BesTofGeoParameter * GetInstance()
G4ThreeVector GetLocPos()
G4ThreeVector GetMomentum()
vector< G4int > * GetHitIndexes_mrpc()
double getAlpha(double E)
void setPar(int nstep, double E_weight, double E)
void setPar(double alpha_n, double eta_n, double drift_n, double threshold, bool saturationFlag=true)
vector< HitStruct > hitStructCol
long int calNextN(int num)
long int multiply(double rdm)