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"
18#include "BesTofDigitizerEcV4.hh"
19#include "BesTofDigi.hh"
20#include "BesTofHit.hh"
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 = 6e+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);
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(
"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);
115 if(tdcRes_const<0) tdcRes_const = sqrt(27*27.+10.*10+20.*20)+18.;
119 if(adcRes_const<0) adcRes_const = 27;
122 time_leading_sphi = -999;
123 time_leading_xphi = -999;
124 time_trailing_sphi = -999;
125 time_trailing_xphi = -999;
131 G4DigiManager* digiManager = G4DigiManager::GetDMpointer();
132 G4int THCID = digiManager->GetHitsCollectionID(
"BesTofHitsCollection");
141 int nstrip = m_param.
nstrip;
143 for(
int i=0; i<nstrip; i++)
145 stripStruct[i].
m_param = m_param;
146 stripStruct[i].
setPar(m_V, m_threshold, m_saturationFlag);
166 hitStruct.
x = hit->
GetPos().x()/mm;
167 hitStruct.
y = hit->
GetPos().y()/mm;
168 hitStruct.
z = hit->
GetPos().z()/mm;
180 for(
int i=0; i<nstrip; i++)
182 if(stripStruct[i].hitStructCol.size()==0)
continue;
183 stripStruct[i].
strip = i;
188 if(stripStruct[i].tThreshold<=0)
continue;
193 double tdcRes_charge;
194 if(m_calTdcRes_charge_flag==0)
198 else if(m_calTdcRes_charge_flag==1)
202 else if(m_calTdcRes_charge_flag==2)
207 tdcRes = sqrt(tdcRes_charge*tdcRes_charge+tdcRes_const*tdcRes_const)/1000;
209 tdc_sphi = G4RandGauss::shoot(tdc_sphi, tdcRes);
210 tdc_xphi = G4RandGauss::shoot(tdc_xphi, tdcRes);
212 if(m_charge2Time_flag==0)
216 else if(m_charge2Time_flag==1)
221 double adcRes_charge;
222 if(m_calAdcRes_charge_flag==0)
226 else if(m_calAdcRes_charge_flag==1)
230 else if(m_calAdcRes_charge_flag==2)
235 adcRes = sqrt(adcRes_charge*adcRes_charge+adcRes_const*adcRes_const)/1000;
236 adc = G4RandGauss::shoot(adc, adcRes);
238 time_leading_sphi = tdc_sphi;
239 time_leading_xphi = tdc_xphi;
240 time_trailing_sphi = tdc_sphi+adc;
241 time_trailing_xphi = tdc_xphi+adc;
249 digi->
SetStrip(stripStruct[i].strip);
271 m_time_leading_sphi = time_leading_sphi;
272 m_time_leading_xphi = time_leading_xphi;
273 m_time_trailing_sphi = time_trailing_sphi;
274 m_time_trailing_xphi = time_trailing_xphi;
276 m_tdcRes_charge = tdcRes_charge;
279 m_adcRes_charge = adcRes_charge;
281 m_strip = stripStruct[i].
strip;
282 m_trkIndex = stripStruct[i].
trkIndex;
283 m_tStart = stripStruct[i].
tStart;
287 m_charge = stripStruct[i].
charge;
291 for(
int j=0; j<m_nhit; j++)
294 m_trkIndex_hit[j] = stripStruct[i].
hitStructCol[j].trkIndex;
295 m_pdgCode_hit[j] = stripStruct[i].
hitStructCol[j].pdgCode;
297 m_underStrip_hit[j] = stripStruct[i].
hitStructCol[j].underStrip;
317 int nstrip = m_param.
nstrip;
319 double length = locZ+stripWidth*nstrip/2-0.5;
324 else if(length<stripWidth*nstrip)
326 for(
int i=0; i<nstrip; i++)
328 if(length>i*stripWidth && length<(i+1)*stripWidth)
340 if(strip>nstrip-1) strip=nstrip-1;
350 int nstrip = m_param.
nstrip;
352 double length = locZ+stripWidth*nstrip/2-0.5;
353 if(length<stripWidth*nstrip)
355 for(
int i=0; i<nstrip; i++)
357 if(length>i*stripWidth && length<(i+1)*stripWidth)
360 if(length>i*stripWidth+m_param.
strip_gap/2 && length<(i+1)*stripWidth-m_param.
strip_gap/2
388 if(strip<0 || strip>m_param.
nstrip-1)
390 cout<<
"!! BesTofDigitizerEcV4::HitStruct::calTPropagate Wrong Strip !!!"<<endl;
395 double length_sphi = m_param.
strip_x[strip]/2-locx;
396 tPropagate_sphi =
abs(length_sphi)/v_propagate;
398 double length_xphi = m_param.
strip_x[strip]/2+locx;
399 tPropagate_xphi =
abs(length_xphi)/v_propagate;
408 if(gap>=0 && gap<m_param.
ngap/2) length = m_param.
gapWidth/2+locy;
409 else if(gap<m_param.
ngap) length = m_param.
gapWidth/2-locy;
412 cout<<
"BesTofDigitizerEcV4::StripStruct::calAvaLength Wrong gap calculation !!!"<<endl;
422 for(
unsigned int i=0; i<hitStructCol.size(); i++)
424 hitStructCol[i].ava_pos.clear();
425 hitStructCol[i].ava_num.clear();
427 hitStructCol[i].ava_pos[0] = hitStructCol[i].calAvaLength();
428 hitStructCol[i].ava_num[0] = hitStructCol[i].ions;
430 for(
int j=1; j<m_param.
nstep; j++)
432 hitStructCol[i].ava_pos[j] = hitStructCol[i].ava_pos[j-1] + m_param.
stepWidth;
433 if(saturationFlag==
true && hitStructCol[i].ava_num[j-1]>1.5e+07)
435 hitStructCol[i].ava_num[j] = hitStructCol[i].ava_num[j-1];
439 hitStructCol[i].ava_num[j] = calNextN(hitStructCol[i].ava_num[j-1]);
441 if(hitStructCol[i].ava_pos[j]>m_param.
gapWidth)
break;
446 bool over_threshold =
false;
448 for(
int i=0; i<m_param.
nstep; i++)
450 for(
unsigned int j=0; j<hitStructCol.size(); j++)
452 if(i<hitStructCol[j].ava_pos.size() && hitStructCol[j].ava_pos[i]<m_param.
gapWidth)
454 sum += hitStructCol[j].ava_num[i];
459 if(over_threshold==
false)
463 over_threshold =
true;
464 tThreshold = (m_param.
gapWidth)/(m_param.
nstep)/v_drift*(i+1);
479 for(
int i=0; i<
num; i++)
481 rdm = G4UniformRand();
482 nextN += multiply(rdm);
489 double sigma = calSigma();
490 double mean =
num*nbar;
491 double resolution = G4RandGauss::shoot(0,(sqrt(
num)*sigma));
492 long int nextN = mean+resolution;
500 double k = eta/
alpha;
501 double rdm_border = k*(nbar-1)/(nbar-k);
508 long int number = 1.+1./log((nbar-1.)/(nbar-k))*log((nbar-k)*(rdm-1)/(k-1)/nbar);
516 double k = eta/
alpha;
517 double sigma = sqrt((1+k)/(1-k)*nbar*(nbar-1));
524 if( charge_fC>=13. && charge_fC<250)
526 time = 100.764*
exp(-charge_fC*0.0413966+0.377154)+ 13.814;
528 else if(charge_fC>=250)
530 time = 12.8562+0.000507299*charge_fC;
538 if(charge_fC>=13)
time=-120.808/log(charge_fC*30.1306)+26.6024;
545 if( charge_fC>=13. && charge_fC<250)
547 time = 72.6005*
exp(-charge_fC*0.0302626 + 1.49059) + 40.8627;
549 else if(charge_fC>=250)
551 time = 32.6233+0.00404149*charge_fC;
561 result = 67.6737*
exp(-charge_fC/50.9995-0.27755)+9.06223;
565 result = 176.322-2.98345*charge_fC;
573 if(charge_fC>=13)
time=-4.50565/log(charge_fC*0.0812208)+16.6653;
579 double time = 64.3326*
exp(-charge_fC/25.4638 + 0.944184)+19.4846;
607 v_propagate = 0.5*0.299792458e+3;
608 tPropagate_sphi = -999.0;
609 tPropagate_xphi = -999.0;
623 tPropagate_sphi = -999.0;
624 tPropagate_xphi = -999.0;
630 alpha = 144800./1000;
635 hitStructCol.clear();
640 threshold = threshold_n;
641 E = E_V/1000*2/6/(m_param.
gapWidth/10);
646 saturationFlag = saturationFlag_n;
651 if(nstep_n>0) nstep = nstep_n;
652 if(E_weight_n>0) E_weight = E_weight_n;
660 std::stringstream ss;
661 for(
int i=0; i<nstrip; i++)
664 ss<<
"strip_x["<<i<<
"]";
665 strip_x[i] = tofPara->Get(ss.str().c_str());
667 strip_z = tofPara->Get(
"strip_z");
668 strip_gap = tofPara->Get(
"strip_gap");
673 stepWidth = gapWidth/nstep;
674 E_weight = 1./(6.*0.22+(5.*0.4+2*0.55)/3.7);
675 eCharge = 1.60217733e-7;
737 TSpline3* sp_alpha =
new TSpline3(
"sp_alpha", e,
alpha, 22);
738 double alphaVal = sp_alpha->Eval(E);
799 TSpline3* sp_eta =
new TSpline3(
"sp_eta", e, eta, 22);
800 double etaVal = sp_eta->Eval(E);
861 TSpline3* sp_v =
new TSpline3(
"sp_v", e,
v, 22);
862 double vVal = sp_v->Eval(E);
868 cout<<
"Fixed parameters: "<<endl;
869 for(
int i=0; i<nstrip; i++)
871 cout<<
" strip_x["<<i<<
"]= "<<strip_x[i];
873 cout<<
" strip_z= "<<strip_z
874 <<
" strip_gap= "<<strip_gap
876 <<
" gapWidth= "<<gapWidth
878 <<
" stepWidth= "<<stepWidth
879 <<
" E_weight= "<<E_weight
880 <<
" eCharge= "<<eCharge
886 cout<<
"Hit information: "<<endl;
887 cout<<
" trkIndex= "<<trkIndex
888 <<
" pdgCode= "<<pdgCode
892 <<
" glbTime= "<<glbTime
902 <<
" v_propagate= "<<v_propagate
903 <<
" tPropagate_sphi= "<<tPropagate_sphi
904 <<
" tPropagate_xphi= "<<tPropagate_xphi
910 cout<<
"Strip information: "<<endl;
911 cout<<
" strip= "<<strip
912 <<
" trkIndex= "<<trkIndex
913 <<
" tStart= "<<tStart
914 <<
" tPropagate_sphi= "<<tPropagate_sphi
915 <<
" tPropagate_xphi= "<<tPropagate_xphi
916 <<
" tThreshold "<<tThreshold
917 <<
" charge= "<<charge
921 <<
" threshold= "<<threshold
922 <<
" v_drift= "<<v_drift
EvtComplex exp(const EvtComplex &c)
G4TDigiCollection< BesTofDigi > BesTofDigitsCollection
G4THitsCollection< BesTofHit > BesTofHitsCollection
**********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)
BesTofHitsCollection * m_THC
BesTofDigitsCollection * m_besTofDigitsCollection
static BesTofGeoParameter * GetInstance()
G4ThreeVector GetLocPos()
G4ThreeVector GetMomentum()
vector< G4int > * GetHitIndexes_mrpc()
void setPar(int nstep, double E_weight)
vector< HitStruct > hitStructCol
double getAlpha(double E)
long int calNextN(int num)
long int multiply(double rdm)
void setPar(double V, double threshold, bool saturationFlag=true)