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"
34 PropertyMgr m_propMgr;
35 m_propMgr.declareProperty(
"FileName", m_fileName =
"mrpc.root");
36 m_propMgr.declareProperty(
"RootFlag", m_rootFlag =
false);
37 m_propMgr.declareProperty(
"E", m_V = 7000);
38 m_propMgr.declareProperty(
"Threshold", m_threshold = 5.5e+08);
40 m_propMgr.declareProperty(
"nstep", m_nstep = -1);
41 m_propMgr.declareProperty(
"E_weight", m_E_weight = -1);
42 m_propMgr.declareProperty(
"saturationFlag", m_saturationFlag =
true);
43 m_propMgr.declareProperty(
"tdcRes_const", tdcRes_const = -1);
44 m_propMgr.declareProperty(
"adcRes_const", adcRes_const = -1);
45 m_propMgr.declareProperty(
"calTdcRes_charge_flag", m_calTdcRes_charge_flag=0);
46 m_propMgr.declareProperty(
"charge2Time_flag", m_charge2Time_flag=0);
47 m_propMgr.declareProperty(
"calAdcRes_charge_flag", m_calAdcRes_charge_flag=0);
49 IJobOptionsSvc* jobSvc;
50 Gaudi::svcLocator()->service(
"JobOptionsSvc", jobSvc);
51 jobSvc->setMyProperties(
"BesTofDigitizerEcV4", &m_propMgr);
57 m_file =
new TFile(m_fileName.c_str(),
"RECREATE");
58 m_tree =
new TTree(
"mrpc",
"mrpc");
60 m_tree->Branch(
"event", &m_event,
"event/D");
61 m_tree->Branch(
"partId", &m_partId,
"partId/D");
62 m_tree->Branch(
"module", &m_module,
"module/D");
63 m_tree->Branch(
"time_leading_sphi", &m_time_leading_sphi,
"time_leading_sphi/D");
64 m_tree->Branch(
"time_leading_xphi", &m_time_leading_xphi,
"time_leading_xphi/D");
65 m_tree->Branch(
"time_trailing_sphi", &m_time_trailing_sphi,
"time_trailing_sphi/D");
66 m_tree->Branch(
"time_trailing_xphi", &m_time_trailing_xphi,
"time_trailing_xphi/D");
67 m_tree->Branch(
"tdcRes", &m_tdcRes,
"tdcRes/D");
68 m_tree->Branch(
"tdcRes_charge", &m_tdcRes_charge,
"tdcRes_charge/D");
69 m_tree->Branch(
"adc", &m_adc,
"adc/D");
70 m_tree->Branch(
"adcRes", &m_adcRes,
"adcRes/D");
71 m_tree->Branch(
"adcRes_charge", &m_adcRes_charge,
"adcRes_charge/D");
72 m_tree->Branch(
"strip", &m_strip,
"strip/D");
73 m_tree->Branch(
"trkIndex", &m_trkIndex,
"trkIndex/D");
74 m_tree->Branch(
"tStart", &m_tStart,
"tStart/D");
75 m_tree->Branch(
"tPropagate_sphi", &m_tPropagate_sphi,
"tPropagate_sphi/D");
76 m_tree->Branch(
"tPropagate_xphi", &m_tPropagate_xphi,
"tPropagate_xphi/D");
77 m_tree->Branch(
"tThreshold", &m_tThreshold,
"tThreshold/D");
78 m_tree->Branch(
"charge", &m_charge,
"charge/D");
79 m_tree->Branch(
"nhit", &m_nhit,
"nhit/I");
80 m_tree->Branch(
"ions_hit", m_ions_hit,
"ions_hit[nhit]/D");
81 m_tree->Branch(
"trkIndex_hit", m_trkIndex_hit,
"trkIndex_hit[nhit]/D");
82 m_tree->Branch(
"pdgCode_hit", m_pdgCode_hit,
"pdgCode_hit[nhit]/D");
83 m_tree->Branch(
"gap_hit", m_gap_hit,
"gap_hit[nhit]/D");
84 m_tree->Branch(
"underStrip_hit", m_underStrip_hit,
"underStrip_hit[nhit]/D");
85 m_tree->Branch(
"locx_hit", m_locx_hit,
"locx_hit[nhit]/D");
86 m_tree->Branch(
"locy_hit", m_locy_hit,
"locy_hit[nhit]/D");
87 m_tree->Branch(
"locz_hit", m_locz_hit,
"locz_hit[nhit]/D");
88 m_tree->Branch(
"x_hit", m_x_hit,
"x_hit[nhit]/D");
89 m_tree->Branch(
"y_hit", m_y_hit,
"y_hit[nhit]/D");
90 m_tree->Branch(
"z_hit", m_z_hit,
"z_hit[nhit]/D");
91 m_tree->Branch(
"px_hit", m_px_hit,
"px_hit[nhit]/D");
92 m_tree->Branch(
"py_hit", m_py_hit,
"py_hit[nhit]/D");
93 m_tree->Branch(
"pz_hit", m_pz_hit,
"pz_hit[nhit]/D");
110 m_param.
setPar(m_nstep, m_E_weight, m_V);
117 if(tdcRes_const<0) tdcRes_const = 38;
122 if(adcRes_const<0) adcRes_const = 27;
125 time_leading_sphi = -999;
126 time_leading_xphi = -999;
127 time_trailing_sphi = -999;
128 time_trailing_xphi = -999;
130 cout<<
"Property:"<<endl
131 <<
" FileName= "<<m_fileName
133 <<
" Threshold= "<<m_threshold
134 <<
" nstep= "<<m_nstep
135 <<
" E_weight= "<<m_E_weight
136 <<
" saturationFlag= "<<m_saturationFlag
137 <<
" tdcRes_const= "<<tdcRes_const
138 <<
" adcRes_const= "<<adcRes_const
139 <<
" calTdcRes_charge_flag= "<<m_calTdcRes_charge_flag
140 <<
" charge2Time_flag= "<<m_charge2Time_flag
141 <<
" calAdcRes_charge_flag= "<<m_calAdcRes_charge_flag
148 G4DigiManager* digiManager = G4DigiManager::GetDMpointer();
149 G4int THCID = digiManager->GetHitsCollectionID(
"BesTofHitsCollection");
158 int nstrip = m_param.
nstrip;
160 for(
int i=0; i<nstrip; i++)
162 stripStruct[i].
m_param = m_param;
184 hitStruct.
x = hit->
GetPos().x()/mm;
185 hitStruct.
y = hit->
GetPos().y()/mm;
186 hitStruct.
z = hit->
GetPos().z()/mm;
201 for(
int i=0; i<nstrip; i++)
203 if(stripStruct[i].hitStructCol.size()==0)
continue;
204 stripStruct[i].
strip = i;
209 if(stripStruct[i].tThreshold<=0)
continue;
214 double tdcRes_charge;
215 if(m_calTdcRes_charge_flag==0)
219 else if(m_calTdcRes_charge_flag==1)
223 else if(m_calTdcRes_charge_flag==2)
228 tdcRes = sqrt(tdcRes_charge*tdcRes_charge+tdcRes_const*tdcRes_const)/1000;
230 tdc_sphi = G4RandGauss::shoot(tdc_sphi, tdcRes);
231 tdc_xphi = G4RandGauss::shoot(tdc_xphi, tdcRes);
233 if(m_charge2Time_flag==0)
237 else if(m_charge2Time_flag==1)
242 double adcRes_charge;
243 if(m_calAdcRes_charge_flag==0)
247 else if(m_calAdcRes_charge_flag==1)
251 else if(m_calAdcRes_charge_flag==2)
256 adcRes = sqrt(adcRes_charge*adcRes_charge+adcRes_const*adcRes_const)/1000;
257 adc = G4RandGauss::shoot(adc, adcRes);
260 time_leading_sphi = tdc_sphi;
261 time_leading_xphi = tdc_xphi;
262 time_trailing_sphi = tdc_sphi+adc;
263 time_trailing_xphi = tdc_xphi+adc;
271 digi->
SetStrip(stripStruct[i].strip);
272 int mo = (partId-3)*36+module;
273 int st = stripStruct[i].
strip;
312 m_time_leading_sphi = time_leading_sphi;
313 m_time_leading_xphi = time_leading_xphi;
314 m_time_trailing_sphi = time_trailing_sphi;
315 m_time_trailing_xphi = time_trailing_xphi;
317 m_tdcRes_charge = tdcRes_charge;
320 m_adcRes_charge = adcRes_charge;
322 m_strip = stripStruct[i].
strip;
323 m_trkIndex = stripStruct[i].
trkIndex;
324 m_tStart = stripStruct[i].
tStart;
328 m_charge = stripStruct[i].
charge;
332 for(
int j=0; j<m_nhit; j++)
335 m_trkIndex_hit[j] = stripStruct[i].
hitStructCol[j].trkIndex;
336 m_pdgCode_hit[j] = stripStruct[i].
hitStructCol[j].pdgCode;
338 m_underStrip_hit[j] = stripStruct[i].
hitStructCol[j].underStrip;
358 int nstrip = m_param.
nstrip;
360 double length = locZ+stripWidth*nstrip/2-0.5;
365 else if(length<stripWidth*nstrip)
367 for(
int i=0; i<nstrip; i++)
369 if(length>i*stripWidth && length<(i+1)*stripWidth)
381 if(strip>nstrip-1) strip=nstrip-1;
391 int nstrip = m_param.
nstrip;
393 double length = locZ+stripWidth*nstrip/2-0.5;
394 if(length<stripWidth*nstrip)
396 for(
int i=0; i<nstrip; i++)
398 if(length>i*stripWidth && length<(i+1)*stripWidth)
401 if(length>i*stripWidth+m_param.
strip_gap/2 && length<(i+1)*stripWidth-m_param.
strip_gap/2
429 if(strip<0 || strip>m_param.
nstrip-1)
431 cout<<
"!! BesTofDigitizerEcV4::HitStruct::calTPropagate Wrong Strip !!!"<<endl;
436 double length_sphi = m_param.
strip_x[strip]/2-locx;
437 tPropagate_sphi =
abs(length_sphi)/v_propagate;
439 double length_xphi = m_param.
strip_x[strip]/2+locx;
440 tPropagate_xphi =
abs(length_xphi)/v_propagate;
449 if(gap>=0 && gap<m_param.
ngap/2) length = m_param.
gapWidth/2+locy;
450 else if(gap<m_param.
ngap) length = m_param.
gapWidth/2-locy;
453 cout<<
"BesTofDigitizerEcV4::StripStruct::calAvaLength Wrong gap calculation !!!"<<endl;
463 for(
unsigned int i=0; i<hitStructCol.size(); i++)
465 hitStructCol[i].ava_pos.clear();
466 hitStructCol[i].ava_num.clear();
468 hitStructCol[i].ava_pos[0] = hitStructCol[i].calAvaLength();
469 hitStructCol[i].ava_num[0] = hitStructCol[i].ions;
471 for(
int j=1; j<m_param.
nstep; j++)
473 hitStructCol[i].ava_pos[j] = hitStructCol[i].ava_pos[j-1] + m_param.
stepWidth;
474 if(saturationFlag==
true && hitStructCol[i].ava_num[j-1]>1.5e+07)
476 hitStructCol[i].ava_num[j] = hitStructCol[i].ava_num[j-1];
480 hitStructCol[i].ava_num[j] = calNextN(hitStructCol[i].ava_num[j-1]);
482 if(hitStructCol[i].ava_pos[j]>m_param.
gapWidth)
break;
487 bool over_threshold =
false;
489 for(
int i=0; i<m_param.
nstep; i++)
491 for(
unsigned int j=0; j<hitStructCol.size(); j++)
493 if(i<hitStructCol[j].ava_pos.size() && hitStructCol[j].ava_pos[i]<m_param.
gapWidth)
495 sum += hitStructCol[j].ava_num[i];
500 if(over_threshold==
false)
504 over_threshold =
true;
505 tThreshold = (m_param.
gapWidth)/(m_param.
nstep)/v_drift*(i+1);
520 for(
int i=0; i<
num; i++)
522 rdm = G4UniformRand();
523 nextN += multiply(rdm);
530 double sigma = calSigma();
531 double mean =
num*nbar;
532 double resolution = G4RandGauss::shoot(0,(sqrt(
num)*
sigma));
533 long int nextN = mean+resolution;
541 double k = eta/
alpha;
542 double rdm_border = k*(nbar-1)/(nbar-k);
549 long int number = 1.+1./log((nbar-1.)/(nbar-k))*log((nbar-k)*(rdm-1)/(k-1)/nbar);
557 double k = eta/
alpha;
558 double sigma = sqrt((1+k)/(1-k)*nbar*(nbar-1));
567 time = 100.764*
exp(-charge_fC*0.0413966+0.377154)+ 13.814;
571 time = 12.8562+0.000507299*charge_fC;
580 time=-120.808/log(charge_fC*30.1306)+26.6024;
590 time = 72.6005*
exp(-charge_fC*0.0302626 + 1.49059) + 40.8627;
594 time = 32.6233+0.00404149*charge_fC;
605 result = 67.6737*
exp(-charge_fC/50.9995-0.27755)+9.06223;
609 result = 176.322-2.98345*charge_fC;
611 if(result<0) result=0;
618 time=-4.50565/log(charge_fC*0.0812208)+16.6653;
625 double time = 64.3326*
exp(-charge_fC/25.4638 + 0.944184)+19.4846;
654 v_propagate = 0.5*0.299792458e+3;
655 tPropagate_sphi = -999.0;
656 tPropagate_xphi = -999.0;
670 tPropagate_sphi = -999.0;
671 tPropagate_xphi = -999.0;
677 alpha = 144800./1000;
682 hitStructCol.clear();
690 threshold = threshold_n;
692 saturationFlag = saturationFlag_n;
697 if(nstep_n>0) nstep = nstep_n;
698 if(E_weight_n>0) E_weight = E_weight_n;
701 double E_eff = E/1000*2/6/(gapWidth/10);
702 alpha = getAlpha(E_eff);
704 v_drift = getV(E_eff);
713 std::stringstream ss;
714 for(
int i=0; i<nstrip; i++)
717 ss<<
"strip_x["<<i<<
"]";
718 strip_x[i] = tofPara->Get(ss.str().c_str());
720 strip_z = tofPara->Get(
"strip_z");
721 strip_gap = tofPara->Get(
"strip_gap");
726 stepWidth = gapWidth/nstep;
727 E_weight = 1./(6.*0.22+(5.*0.4+2*0.55)/3.7);
728 eCharge = 1.60217733e-7;
729 tofPara->Get_deadChannel(deadChannel);
791 TSpline3* sp_alpha =
new TSpline3(
"sp_alpha", e,
alpha, 22);
792 double alphaVal = sp_alpha->Eval(E);
854 TSpline3* sp_eta =
new TSpline3(
"sp_eta", e, eta, 22);
855 double etaVal = sp_eta->Eval(E);
917 TSpline3* sp_v =
new TSpline3(
"sp_v", e,
v, 22);
918 double vVal = sp_v->Eval(E);
925 cout<<
"Fixed parameters: "<<endl;
926 for(
int i=0; i<nstrip; i++)
928 cout<<
" strip_x["<<i<<
"]= "<<strip_x[i];
930 for(
int i=0; i<nmodule; i++)
932 for(
int j=0; j<nstrip; j++)
934 if(deadChannel[i][j]!=-999)
936 cout<<
" deadChannel["<<i<<
"]["<<j<<
"]= "<<deadChannel[i][j];
941 cout<<
" strip_z= "<<strip_z
942 <<
" strip_gap= "<<strip_gap
944 <<
" gapWidth= "<<gapWidth
946 <<
" stepWidth= "<<stepWidth
947 <<
" E_weight= "<<E_weight
948 <<
" eCharge= "<<eCharge
952 <<
" v_drift= "<<v_drift
958 cout<<
"Hit information: "<<endl;
959 cout<<
" trkIndex= "<<trkIndex
960 <<
" pdgCode= "<<pdgCode
964 <<
" glbTime= "<<glbTime
974 <<
" v_propagate= "<<v_propagate
975 <<
" tPropagate_sphi= "<<tPropagate_sphi
976 <<
" tPropagate_xphi= "<<tPropagate_xphi
982 cout<<
"Strip information: "<<endl;
983 cout<<
" strip= "<<strip
984 <<
" trkIndex= "<<trkIndex
985 <<
" tStart= "<<tStart
986 <<
" tPropagate_sphi= "<<tPropagate_sphi
987 <<
" tPropagate_xphi= "<<tPropagate_xphi
988 <<
" tThreshold "<<tThreshold
992 <<
" threshold= "<<threshold
993 <<
" 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)