BOSS 7.0.5
BESIII Offline Software System
Loading...
Searching...
No Matches
BesTofDigitizerEcV2.cc
Go to the documentation of this file.
1//---------------------------------------------------------------------------//
2//// BOOST --- BESIII Object_Oriented Simulation Tool //
3////---------------------------------------------------------------------------//
4////Description:
5////Author: Dengzy
6////Created: Mar, 2004
7////Modified:
8////Comment:
9////---------------------------------------------------------------------------//
10////$Id: BesTofDigitizerEcV2.cc
11
12#include "BesTofDigitizerEcV2.hh"
13#include "BesTofHit.hh"
14#include "G4DigiManager.hh"
15#include "G4RunManager.hh"
16#include "Randomize.hh"
17#include "G4Poisson.hh"
18#include "BesTofDigi.hh"
19#include "BesTofGeoParameter.hh"
20#include "GaudiKernel/ISvcLocator.h"
21#include "GaudiKernel/Bootstrap.h"
22#include "GaudiKernel/IDataProviderSvc.h"
23#include "G4Svc/IG4Svc.h"
24#include "G4Svc/G4Svc.h"
25
27{
28 ReadData();
29 m_timeBinSize=0.005;
30
31 //retrieve G4Svc
32 ISvcLocator* svcLocator = Gaudi::svcLocator();
33 IG4Svc* tmpSvc;
34 StatusCode sc = svcLocator->service("G4Svc", tmpSvc);
35 m_G4Svc = dynamic_cast<G4Svc *>(tmpSvc);
36
37}
38
40{
42
43 m_ecR1 = tofPara->GetEcR1();
44 m_tau1Ec = tofPara->GetTau1Ec();
45 m_tau2Ec = tofPara->GetTau2Ec();
46 m_tau3Ec = tofPara->GetTau3Ec();
47 m_tauRatioEc = tofPara->GetTauRatioEc();
48 m_refIndexEc = tofPara->GetRefIndexEc();
49 m_phNConstEc = tofPara->GetPhNConstEc();
50 m_Cpe2pmtEc = tofPara->GetCpe2pmtEc();
51 m_rAngleEc = tofPara->GetRAngleEc();
52 m_QEEc = tofPara->GetQEEc();
53 m_CEEc = tofPara->GetCEEc();
54 m_peCorFacEc = tofPara->GetPeCorFacEc();
55 m_attenEc = tofPara->GetAttenEc();
56
57 m_ttsMeanEc = tofPara->GetTTSmeanEc();
58 m_ttsSigmaEc = tofPara->GetTTSsigmaEc();
59 m_PMTgainEc = tofPara->GetPMTgainEc();
60 m_CeEc = tofPara->GetCeEc();
61 m_riseTimeEc = tofPara->GetRiseTimeEc();
62 m_LLthreshEc = tofPara->GetLLthreshEc();
63 m_HLthreshEc = tofPara->GetHLthreshEc();
64 m_preGainEc = tofPara->GetPreGainEc();
65 m_noiseSigmaEc = tofPara->GetNoiseSigmaEc();
66}
67
69{
70 ;
71}
72
74{
75 m_beamTime = m_G4Svc->GetBeamTime() * ns;
77
78 G4DigiManager* digiManager = G4DigiManager::GetDMpointer();
79
80 G4int THCID = digiManager->GetHitsCollectionID("BesTofHitsCollection");
81 m_THC = (BesTofHitsCollection*) (digiManager->GetHitsCollection(THCID));
82
83 if (m_THC)
84 {
85 //for each digi, compute TDC and ADC
86 G4int partId, scinNb, nHits;
87 G4double edep;
88 BesTofHit* hit;
89 partId=scint->GetPartId();
90 scinNb=scint->GetScinNb();
91 edep = scint->GetEdep();
92 nHits=scint->GetHitIndexes()->size();
93
94 TofPmtInit();
95
96 if (edep>0.01)
97 {
98 for (G4int j=0;j<nHits;j++)
99 {
100 hit= (*m_THC)[( *(scint->GetHitIndexes()) )[j]];
101 TofPmtAccum(hit);
102 }
103
104 //get final tdc and adc
105 TofPmtRspns(partId);
106
107 G4double temp0 = m_ADC[0]+m_TDC[0];
108 G4double temp1 = m_ADC[1]+m_TDC[1];
109 if ( (partId==1&&temp0>0&&temp1>0) || ((partId!=1)&&temp0>0) )
110 {
111 if (m_ADC[0]>1000) m_ADC[0]=1000;
112 if (m_ADC[1]>1000) m_ADC[1]=1000;
113 BesTofDigi* digi = new BesTofDigi;
115 digi->SetPartId(partId);
116 digi->SetScinNb(scinNb);
117 digi->SetForwADC( m_ADC[0]) ;
118 digi->SetBackADC( m_ADC[1]) ;
119 if (m_TDC[0]!=-999)
120 m_TDC[0] = m_TDC[0]+m_beamTime;
121 if (m_TDC[1]!=-999)
122 m_TDC[1] = m_TDC[1]+m_beamTime;
123 digi->SetForwTDC( m_TDC[0]) ;
124 digi->SetBackTDC( m_TDC[1]) ;
125 m_besTofDigitsCollection->insert(digi);
126 }
127 }
128 }
129}
130
132{
133 m_trackIndex=-999;
134 m_globalTime = 9999;
135 m_t1st[0]=100;
136 m_t1st[1]=100;
137 m_tLast[0]=0.;
138 m_tLast[1]=0;
139 m_totalPhot[0]=0;
140 m_totalPhot[1]=0;
141 for (G4int i=0;i<2;i++)
142 for (G4int j=0;j<m_profBinNEcV2;j++)
143 m_nPhot[j][i]=0;
144
145}
146
148{
149 G4double cvelScint=c_light/m_refIndexEc;
150 //Get information of this step
151 G4ThreeVector pos=hit->GetPos();
152 G4int trackIndex = hit->GetTrackIndex();
153 G4int partId =hit->GetPartId();
154 G4double edep=hit->GetEdep();
155 G4double stepL=hit->GetStepL();
156 G4double deltaT=hit->GetDeltaT();
157 G4double timeFlight=hit->GetTime()-m_beamTime;
158 if (timeFlight < m_globalTime)
159 {
160 m_globalTime = timeFlight;
161 m_trackIndex = trackIndex;
162 }
163
164 G4ThreeVector pDirection=hit->GetPDirection();
165 G4double nx=pDirection.x();
166 G4double ny=pDirection.y();
167 G4double nz=pDirection.z();
168
169 //Cpe2pmt=cathode area/scint area
170 //peCorFac=correction factor for eff. of available Npe
171
172 //number of photons generated in this step
173 G4int NphStep;
174 NphStep=G4int(edep*m_phNConstEc*m_Cpe2pmtEc*0.66*m_QEEc*m_CEEc*m_peCorFacEc);
175
176 G4double ddS, ddT;
177 if (NphStep>0)
178 {
179 for (G4int i=0;i<NphStep;i++)
180 {
181 //uniform scintilation in each step
182 ddS=stepL*G4UniformRand();
183 ddT=deltaT*G4UniformRand();
184 G4ThreeVector emtPos;
185 emtPos.setX(pos.x() + nx*ddS);
186 emtPos.setY(pos.y() + ny*ddS);
187 emtPos.setZ(pos.z() + nz*ddS);
188
189 //check scinillation light whether to hit the pmt or not
190 //forb=0/1 for forward(z>0, east) and backward(z<0, west)
191 G4double pathL=0;
192 G4int forb;
193 DirectPh(partId, emtPos, pathL, forb);
194
195 //check if photon can reach PMT or not, after attenuation
196 G4double ran=G4UniformRand();
197 if (pathL>0 && exp(-pathL/m_attenEc) > ran)
198 {
199 //propagation time in scintillator
200 G4double scinSwim=pathL/cvelScint;
201 //scintillation timing
202 //G4double scinTime=GenPhoton(partId);
203 G4double scinTime=Scintillation(partId);
204
205 //PMT transit time
206 G4double transitTime=TransitTime();
207 //sum up all time components
208 G4double endTime= timeFlight + ddT + scinSwim + scinTime + transitTime;
209
210 //store timing into binned buffer
211 AccuSignal(endTime, forb);
212
213 //update 1st and last timings here
214 if (m_t1st[forb]>endTime) m_t1st[forb] = endTime;
215 if (m_tLast[forb]<endTime) m_tLast[forb]= endTime;
216 }
217 }
218 }
219}
220
221
222void BesTofDigitizerEcV2::DirectPh(G4int partId, G4ThreeVector emtPos, G4double& pathL, G4int& forb)
223{
224 //generation photon have random direction
225 //optical parameters of scintillation simulation
226 //G4double cos_spanEc = 1-1/m_refIndex;
227 G4double cos_spanEc = 1;
228 G4double ran;
229 //dcos=cos_span*(ran*2.0-1.0);
230 ran=G4UniformRand();
231 //assuming uniform phi distribution, simulate cos distr only
232 G4double dcosEc = cos_spanEc*(ran*2.0-1.0);
233 G4double r2=sqrt(emtPos.x()*emtPos.x()+emtPos.y()*emtPos.y());
234 if (dcosEc > 0.0 && dcosEc != 1)
235 {
236 forb=0; //forward
237 pathL = (r2-m_ecR1)/(1.0-dcosEc);
238 }
239 else if (dcosEc < 0 && dcosEc != -1)
240 {
241 forb=0;
242 pathL=(2*838-r2-m_ecR1)/(1.0+dcosEc);
243 }
244}
245
247{
248 G4double tmp_tauRatio,tmp_tau1,tmp_tau2,tmp_tau3;
249 tmp_tauRatio = m_tauRatioEc;
250 tmp_tau1 = m_tau1Ec;
251 tmp_tau2 = m_tau2Ec;
252 tmp_tau3 = m_tau3Ec;
253
254 G4double UniformR = tmp_tauRatio/(1+tmp_tauRatio);
255 G4double EmissionTime;
256 if (G4UniformRand()>UniformR) {
257 while (1) {
258 EmissionTime = -tmp_tau2*log( G4UniformRand() );
259 if (G4UniformRand()-exp(EmissionTime/tmp_tau2-EmissionTime/tmp_tau1)>1.E-8)
260 break;
261 }
262 }
263 else EmissionTime = -tmp_tau3*log( G4UniformRand() );
264 return EmissionTime;
265}
266
267/*G4double BesTofDigitizerEcV2::GenPhoton(G4int partId)
268{
269 //get scintilation time
270 G4double scinTime;
271 static G4double scinA[26000];
272 G4double random[2];
273 G4double inverseRegion, ran1, ran2, problive;
274 static G4int istore=-1;
275 if(istore<0)
276 {
277 istore=1;
278 for(G4int i=0;i<26000;i++)
279 scinA[i]=Scintillation( (i+1) *0.001 , partId);
280 }
281 while(1)
282 {
283 HepRandom::getTheEngine()->flatArray(2, random);
284 inverseRegion=random[0]*2.00975218688231;
285 ran1=-4.5*log(1-inverseRegion/(0.45*4.5));
286 ran2=0.45*exp(-1.*ran1/4.5)*random[1];
287 problive=scinA[G4int(ran1*1000)+1];
288 if(problive>=ran2)
289 { scinTime=ran1; break; }
290 }
291 return scinTime;
292}*/
293
295{
296 //get time transit spread
297 return G4RandGauss::shoot(m_ttsMeanEc,m_ttsSigmaEc);
298}
299
300void BesTofDigitizerEcV2::AccuSignal(G4double endTime, G4int forb)
301{
302 G4int ihst;
303 ihst=G4int(endTime/m_timeBinSize);
304 if (ihst>0 &&ihst<m_profBinNEcV2)
305 {
306 m_nPhot[ihst][forb]=m_nPhot[ihst][forb]+1;
307 m_totalPhot[forb]=m_totalPhot[forb]+1;
308 }
309}
310
312{
313 //to generate PMT signal shape for single photoelectron.
314 //only one time for a job.
315 static G4double snpe[m_snpeBinNEcV2];
316 static G4int istore_snpe=-1;
317
318 //Model: f(t)=Gain*mv_1pe* t**2 * exp-(t/tau)**2/normal-const
319 //normalization const =sqrt(pi)*tau*tau*tau/4.0
320 G4double tau = m_riseTimeEc;
321 G4double norma_const=sqrt(M_PI)*tau*tau*tau/4.0; //in unit of ns**3
322 G4double echarge=1.6e-7; //in unit of PC
323
324 //time profile of pmt signals for Back and Forward PMT.
325 G4double profPmt[m_profBinNEcV2][2];
326
327 G4double t;
328 G4int n1, n2, ii;
329 G4int phtn;
330
331 if (istore_snpe<0)
332 {
333 istore_snpe = 1;
334 for (G4int i=0;i<m_snpeBinNEcV2;i++)
335 {
336 t=(i+1)*m_timeBinSize;
337 snpe[i]=m_PMTgainEc*m_CeEc*t*t*exp(- (t/tau) * (t/tau) )/norma_const;
338 }
339 }
340 //for barrel and endcap tof: fb=2 or 1
341 G4int fb=1;
342
343 for (G4int j=0;j<2;j++)
344 {
345 m_TDC[j]=-999.0;
346 m_ADC[j]=-999.0;
347 }
348 for (G4int j=0; j<fb; j++)
349 {
350 if (m_totalPhot[j] > 0)
351 {
352 n1=G4int(m_t1st[j]/m_timeBinSize);
353 n2=G4int(m_tLast[j]/m_timeBinSize);
354
355 for (G4int i=0;i<m_profBinNEcV2;i++)
356 profPmt[i][j]=0.0;
357
358 //generate PMT pulse
360 for (G4int i=n1;i<n2;i++)
361 {
362 phtn=m_nPhot[i][j];
363 if (phtn>0)
364 {
365 for (G4int ihst=0; ihst<m_snpeBinNEcV2; ihst++)
366 {
367 ii=i+ihst;
368 if (ii<m_profBinNEcV2)
369 profPmt[ii][j] += phtn*snpe[ihst];
370 }
371 }
372 }
373
374 //add preamplifier and noise
375 for (int i=0;i<m_profBinNEcV2;i++)
376 {
377 if (profPmt[i][j]>0)
378 profPmt[i][j] = m_preGainEc*profPmt[i][j]+G4RandGauss::shoot(0,m_noiseSigmaEc);
379 }
380
381 //get pulse height
382 G4double max=0;
383 for (int i=0;i<m_profBinNEcV2;i++)
384 {
385 if (profPmt[i][j]>max)
386 max=profPmt[i][j];
387 }
388
389 G4double tmp_HLthresh, tmp_LLthresh;
390 if (partId==1) {
391 tmp_HLthresh = m_HLthreshEc;
392 tmp_LLthresh = m_LLthreshEc;
393 }
394 else {
395 tmp_HLthresh = m_HLthreshEc;
396 tmp_LLthresh = m_LLthreshEc;
397 }
398
399 //get final tdc and adc
400 if (max>=tmp_HLthresh)
401 {
402 for (int i=0;i<m_profBinNEcV2;i++)
403 {
404 if ( profPmt[i][j] >= tmp_LLthresh )
405 {
406 m_TDC[j] = i*m_timeBinSize;
407 m_ADC[j] = m_preGainEc*m_totalPhot[j]*echarge*m_PMTgainEc;
408 break;
409 }
410 }
411 }
412 }
413 }
414}
415
416
417
418
419
420
421
422
423
424
425
EvtComplex exp(const EvtComplex &c)
Definition: EvtComplex.hh:252
G4TDigiCollection< BesTofDigi > BesTofDigitsCollection
G4THitsCollection< BesTofHit > BesTofHitsCollection
int n2
Definition: SD0Tag.cxx:55
int n1
Definition: SD0Tag.cxx:54
#define M_PI
Definition: TConstant.h:4
TTree * t
Definition: binning.cxx:23
void AccuSignal(G4double, G4int)
G4double Scintillation(G4int)
void DirectPh(G4int, G4ThreeVector, G4double &, G4int &)
virtual void Digitize(ScintSingle *, BesTofDigitsCollection *)
void TofPmtAccum(BesTofHit *)
static BesTofGeoParameter * GetInstance()
#define ns(x)
Definition: xmltok.c:1504