BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
BesTofDigitizerBrV2.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: BesTofDigitizerBrV2.cc
11
12#include "TofSim/BesTofDigitizerBrV2.hh"
13#include "G4DigiManager.hh"
14#include "G4PhysicalConstants.hh"
15#include "G4Poisson.hh"
16#include "G4RunManager.hh"
17#include "G4Svc/IG4Svc.h"
18#include "G4SystemOfUnits.hh"
19#include "GaudiKernel/Bootstrap.h"
20#include "GaudiKernel/IDataProviderSvc.h"
21#include "GaudiKernel/ISvcLocator.h"
22#include "Randomize.hh"
23#include "TMath.h"
24#include "TofSim/BesTofDigi.hh"
25#include "TofSim/BesTofGeoParameter.hh"
26#include "TofSim/BesTofHit.hh"
27
29 ReadData();
30 m_timeBinSize = 0.005;
31
32 // retrieve G4Svc
33 StatusCode sc = Gaudi::svcLocator()->service( "G4Svc", m_G4Svc );
34 if ( !sc.isSuccess() )
35 {
36 std::cout << " Could not initialize Realization Service in BesTofDigitizerBrV2"
37 << std::endl;
38 exit( 1 );
39 }
40
41 StatusCode scReal = Gaudi::svcLocator()->service( "RealizationSvc", m_RealizationSvc );
42 if ( !scReal.isSuccess() )
43 {
44 std::cout << " Could not initialize Realization Service in BesTofDigitizerBrV2"
45 << std::endl;
46 exit( 1 );
47 }
48}
49
52
53 m_scinLength = tofPara->GetBr1L();
54 m_tau1 = tofPara->GetTau1();
55 m_tau2 = tofPara->GetTau2();
56 m_tau3 = tofPara->GetTau3();
57 m_tauRatio = tofPara->GetTauRatio();
58 m_refIndex = tofPara->GetRefIndex();
59 m_phNConst = tofPara->GetPhNConst();
60 m_Cpe2pmt = tofPara->GetCpe2pmt();
61 m_rAngle = tofPara->GetRAngle();
62 m_QE = tofPara->GetQE();
63 m_CE = tofPara->GetCE();
64 m_peCorFac = tofPara->GetPeCorFac();
65
66 m_ttsMean = tofPara->GetTTSmean();
67 m_ttsSigma = tofPara->GetTTSsigma();
68 m_Ce = tofPara->GetCe();
69 m_LLthresh = tofPara->GetLLthresh();
70 m_HLthresh = tofPara->GetHLthresh();
71 m_preGain = tofPara->GetPreGain();
72 m_noiseSigma = tofPara->GetNoiseSigma();
73}
74
76
78 m_beamTime = m_G4Svc->GetBeamTime() * ns;
80
81 G4DigiManager* digiManager = G4DigiManager::GetDMpointer();
82 G4int THCID = digiManager->GetHitsCollectionID( "BesTofHitsCollection" );
83 m_THC = (BesTofHitsCollection*)( digiManager->GetHitsCollection( THCID ) );
84
85 if ( m_G4Svc->TofRootFlag() )
86 {
87 m_eTotal = 0;
88 m_nDigi = 0;
89 m_partIdMPV = -9;
90 m_scinNbMPV = -9;
91 m_edepMPV = 0;
92 m_nDigiOut = 0;
93 }
94
95 if ( m_THC )
96 {
97 // for each digi, compute TDC and ADC
98 G4int partId, scinNb, nHits;
99 G4double edep;
100 BesTofHit* hit;
101 partId = scint->GetPartId();
102 scinNb = scint->GetScinNb();
103 edep = scint->GetEdep();
104 nHits = scint->GetHitIndexes()->size();
105
106 // std::cout << "BesTofDigitizerBrV2 Partid scinNb " << partId << " " <<
107 // scinNb << std::endl; cout << "*** scinNb:" << scinNb << " *** " <<
108 // m_tofCaliSvc->BAtten(scinNb) << "***" << endl; cout << "*****scinNb:"<< scinNb << "
109 // ***** A2:" << m_tofCaliSvc->BGainBackward(scinNb)
110 // << " ***** A1:" << m_tofCaliSvc->BGainForward(scinNb) << endl;
111
112 TofPmtInit();
113
114 // fill tof Ntuple
115 if ( m_G4Svc->TofRootFlag() )
116 {
117 if ( edep > m_edepMPV )
118 {
119 m_partIdMPV = partId;
120 m_scinNbMPV = scinNb;
121 m_edepMPV = edep;
122 }
123 m_eTotal += edep;
124 m_nDigi++;
125
126 m_partId = partId;
127 m_scinNb = scinNb;
128 m_edep = edep;
129 m_nHits = nHits;
130 }
131
132 if ( edep > 0.01 )
133 {
134 for ( G4int j = 0; j < nHits; j++ )
135 {
136 hit = ( *m_THC )[( *( scint->GetHitIndexes() ) )[j]];
137 TofPmtAccum( hit, scinNb );
138 }
139 if ( m_G4Svc->TofRootFlag() )
140 {
141 m_time1st0 = m_t1st[0];
142 m_time1st1 = m_t1st[1];
143 m_timelast0 = m_tLast[0];
144 m_timelast1 = m_tLast[1];
145 m_totalPhot0 = m_totalPhot[0];
146 m_totalPhot1 = m_totalPhot[1];
147 }
148 // get final tdc and adc
149 TofPmtRspns( scinNb );
150 // G4cout<<"pre-cut " << partId << "\nadc0:"<<m_ADC[0]<<"; adc1:"
151 // <<m_ADC[1]<<"; tdc0:"<<m_TDC[0]<<"; tdc1:"
152 // <<m_TDC[1]<<G4endl;
153
154 G4double temp0 = m_ADC[0] + m_TDC[0];
155 G4double temp1 = m_ADC[1] + m_TDC[1];
156 // cout << "partid: " << partId << " temp0: " << temp0 << " temp1: " << temp1 << endl;
157 // if ( partId==1 && m_ADC[0]>255 && m_ADC[1]>255 && m_TDC[0]>0. && m_TDC[1]>0.)
158 if ( partId == 1 && ( temp0 > -1998. || temp1 > -1998. ) )
159 {
160 // const double MAX_ADC = 8191 * 0.3; // channel set up to 8192 will lead to overflow.
161 BesTofDigi* digi = new BesTofDigi;
163 digi->SetPartId( partId );
164 digi->SetScinNb( scinNb );
165 digi->SetForwADC( m_ADC[0] );
166 digi->SetBackADC( m_ADC[1] );
167 if ( m_TDC[0] > 0 ) m_TDC[0] = m_TDC[0] + m_beamTime;
168 if ( m_TDC[1] > 0 ) m_TDC[1] = m_TDC[1] + m_beamTime;
169 digi->SetForwTDC( m_TDC[0] );
170 digi->SetBackTDC( m_TDC[1] );
171 // G4cout<<"+++++++++++++++++++++++++++++barrel\nadc0:"<<m_ADC[0]<<"; adc1:"
172 // <<m_ADC[1]<<"; tdc0:"<<m_TDC[0]<<"; tdc1:"
173 // <<m_TDC[1]<<G4endl;
174
175 m_besTofDigitsCollection->insert( digi );
176
177 if ( m_G4Svc->TofRootFlag() ) m_nDigiOut++;
178 }
179 if ( m_G4Svc->TofRootFlag() ) m_tupleTof1->write();
180 }
181
182 if ( m_G4Svc->TofRootFlag() ) m_tupleTof2->write();
183 }
184}
185
187 Initialize();
188
189 m_t1st[0] = 100;
190 m_t1st[1] = 100;
191 m_tLast[0] = 0.;
192 m_tLast[1] = 0;
193 m_totalPhot[0] = 0;
194 m_totalPhot[1] = 0;
195 for ( G4int i = 0; i < 2; i++ )
196 for ( G4int j = 0; j < m_profBinN; j++ ) m_nPhot[j][i] = 0;
197
198 if ( m_G4Svc->TofRootFlag() )
199 {
200 m_partId = -9;
201 m_scinNb = -9;
202 m_edep = 0;
203 m_nHits = 0;
204 m_time1st0 = 100;
205 m_time1st1 = 100;
206 m_timelast0 = 0;
207 m_timelast1 = 0;
208 m_totalPhot0 = 0;
209 m_totalPhot1 = 0;
210 m_NphAllSteps = 0;
211 m_max0 = 0;
212 m_max1 = 0;
213 m_tdc0 = -999;
214 m_adc0 = -999;
215 m_tdc1 = -999;
216 m_adc1 = -999;
217 }
218}
219
220void BesTofDigitizerBrV2::TofPmtAccum( BesTofHit* hit, G4int scinNb ) {
222 // std::cout << "BesTofDigitizerBrV2::TofPmtAccum()" << std::endl;
223 G4double cvelScint = c_light / m_refIndex / 1.07;
224 // Get information of this step
225 G4ThreeVector pos = hit->GetPos();
226 G4int trackIndex = hit->GetTrackIndex();
227 G4int partId = hit->GetPartId();
228 G4double edep = hit->GetEdep();
229 G4double stepL = hit->GetStepL();
230 G4double deltaT = hit->GetDeltaT();
231 G4double timeFlight = hit->GetTime() - m_beamTime;
232 // std::cout << "timeFlight: " << timeFlight << std::endl;
233 if ( timeFlight < m_globalTime )
234 {
235 m_globalTime = timeFlight;
236 m_trackIndex = trackIndex;
237 }
238
239 G4ThreeVector pDirection = hit->GetPDirection();
240 G4double nx = pDirection.x();
241 G4double ny = pDirection.y();
242 G4double nz = pDirection.z();
243
244 // phNConst=(Nph/MeV)*(QE)*(CE)*(1-cos(crit));
245 // =10000 * 0.2 * 0.6 * (1-cos(39.265))=270.931
246 // asin(1/1.58) = 39.265248
247 // only the light has theta=0---39.265 can go out to PMT, the probability is computed with
248 // solid angle solid angle = phi*(1-cos(theta)), phi=2pi
249
250 // Cpe2pmt=cathode area/scint area
251 // peCorFac=correction factor for eff. of available Npe
252
253 // G4double thetaProb = 1-sqrt(m_refIndex*m_refIndex-1)/m_refIndex;
254 G4double thetaProb = 1 - cos( asin( 1.43 / m_refIndex ) );
255 // G4double thetaProbEc = 1-1/m_refIndex;
256
257 // number of photons generated in this step
258 G4double nMean, nPhoton;
259 // std::cout << "0 BirksLaw(): " << std::endl;
260 nMean = m_phNConst * BirksLaw( hit );
261 G4int runId = m_RealizationSvc->getRunId();
262 if ( ( runId >= -11396 && runId <= -8093 ) || ( runId > -1000000 && runId <= -23463 ) )
263 { nMean = 9000.0 * BirksLaw( hit ); }
264 // std::cout << "1 BirksLaw(): " << std::endl;
265
266 if ( nMean > 10 )
267 {
268 G4double resolutionScale = 1.;
269 G4double sigma = resolutionScale * sqrt( nMean );
270 nPhoton = G4int( G4RandGauss::shoot( nMean, sigma ) + 0.5 );
271 }
272 else nPhoton = G4int( G4Poisson( nMean ) );
273 // G4cout<<"nPhoton:"<<nPhoton<<G4endl;
274
275 G4int NphStep = 0;
276 if ( partId == 1 )
277 NphStep = G4int( nPhoton * thetaProb * m_rAngle * m_QE * m_CE * m_peCorFac );
278 // else
279 // NphStep=G4int(edep*m_phNConstEc*m_Cpe2pmtEc*0.66*m_QEEc*m_CE*m_peCorFac);
280 // introduce poission distribution of Npe
281 // G4double Navr = NphStep;
282 // G4double NpePoiss = G4double(G4Poisson(Navr));
283 // G4double adcW_corr =5.0;
284 // NphStep=G4int( (NpePoiss - Navr)*adcW_corr + Navr );
285
286 if ( m_G4Svc->TofRootFlag() ) m_NphAllSteps += NphStep;
287 // std::cout << "m_G4Svc->TofRootFlag(): " << m_G4Svc->TofRootFlag() << std::endl;
288
289 G4double ddS, ddT;
290 if ( NphStep > 0 )
291 {
292 for ( G4int i = 0; i < NphStep; i++ )
293 {
294 // uniform scintilation in each step
295 ddS = stepL * G4UniformRand();
296 ddT = deltaT * G4UniformRand();
297 G4ThreeVector emtPos;
298 emtPos.setX( pos.x() + nx * ddS );
299 emtPos.setY( pos.y() + ny * ddS );
300 emtPos.setZ( pos.z() + nz * ddS );
301
302 // check scinillation light whether to hit the pmt or not
303 // forb=0/1 for forward(z>0, east) and backward(z<0, west)
304 G4double pathL = 0;
305 G4int forb;
306 DirectPh( partId, emtPos, pathL, forb );
307
308 // check if photon can reach PMT or not, after attenuation
309
310 G4double ran = G4UniformRand();
311 // G4double attenL = tofPara->GetAtten(scinNb);
312 // G4double attenL = 10.*(m_tofCaliSvc->BAtten(scinNb))/0.75; // cm into mm
313 G4double attenL = m_tofSimSvc->BarAttenLength( scinNb );
314 attenL = 10. * attenL / 0.75; // cm into mm
315
316 if ( pathL > 0 && exp( -pathL / attenL ) > ran )
317 {
318 // propagation time in scintillator
319 G4double scinSwim = pathL / cvelScint;
320 // scintillation timing
321 // G4double scinTime=GenPhoton(partId);
322 G4double scinTime = Scintillation( partId );
323
324 // PMT transit time
325 G4double transitTime = TransitTime();
326 // sum up all time components
327 G4double endTime = timeFlight + ddT + scinSwim + scinTime + transitTime;
328 // std::cout << "endtime: " << endTime << std::endl;
329
330 if ( m_G4Svc->TofRootFlag() )
331 {
332 // m_forb = forb;
333 // m_timeFlight = timeFlight;
334 // m_ddT = ddT;
335 m_scinSwim = scinSwim;
336 // m_scinTime = scinTime;
337 // m_transitTime = transitTime;
338 m_endTime = endTime;
339 m_tupleTof3->write();
340 }
341 // store timing into binned buffer
342 AccuSignal( endTime, forb );
343
344 // update 1st and last timings here
345 if ( m_t1st[forb] > endTime ) m_t1st[forb] = endTime;
346 if ( m_tLast[forb] < endTime ) m_tLast[forb] = endTime;
347 }
348 }
349 }
350}
351
353 const G4double kappa = 0.015 * cm / MeV;
354 const G4String brMaterial = "BC408";
355 G4double dE = hit->GetEdep();
356 // G4cout << "The edep is "<< dE << G4endl;
357 G4double dX = hit->GetStepL();
358 // G4Material* materiral = hit->GetMaterial();
359 G4double charge = hit->GetCharge();
360 G4double cor_dE = dE;
361 // if((materiral->GetName()==brMaterial) && charge!=0.&& dX!=0.)
362 if ( charge != 0. && dX != 0. )
363 {
364 cor_dE = dE / ( 1 + kappa * dE / dX );
365 // if(dE>20)
366 //{
367 // G4cout << "\n dE > 20. Details are below:" << G4endl;
368 // G4cout << "dE/dx:" << dE/dX << G4endl;
369 // G4cout << "dE:" << dE << "; dX:" << dX << G4endl;
370 // G4cout << "It is BC408. cor_dE is " << cor_dE << G4endl;
371 // G4double ratio = cor_dE/dE;
372 // G4cout << "The ratio cor_dE/edep is "<< ratio << G4endl;
373 // }
374 // G4cout << "It is BC408. cor_dE is " << cor_dE << G4endl;
375 // G4double ratio = cor_dE/dE;
376 // G4cout << "The ratio cor_dE/edep is "<< ratio << G4endl;
377 }
378 return cor_dE;
379}
380
381G4double BesTofDigitizerBrV2::Reflectivity( G4double n1, G4double n2, G4double n3,
382 G4double theta ) {
383 G4double I1, I2, I3, rp1, rs1, rp2, rs2, Rp1, Rs1, Rp2, Rs2, Rp, Rs;
384 G4double R = 1.0;
385 // n1=m_refIndex;
386 // n2=1.0;
387 I1 = theta;
388 if ( I1 < asin( n2 / n1 ) )
389 {
390 I2 = asin( sin( I1 ) * ( n1 / n2 ) );
391 rp1 = ( n1 / cos( I1 ) - n2 / cos( I2 ) ) / ( n1 / cos( I1 ) + n2 / cos( I2 ) );
392 rs1 = ( n1 * cos( I1 ) - n2 * cos( I2 ) ) / ( n1 * cos( I1 ) + n2 * cos( I2 ) );
393 Rp1 = rp1 * rp1;
394 Rs1 = rs1 * rs1;
395
396 I3 = asin( sin( I1 ) * ( n1 / n3 ) );
397 rp2 = ( n2 / cos( I2 ) - n3 / cos( I3 ) ) / ( n2 / cos( I2 ) + n3 / cos( I3 ) );
398 rs2 = ( n2 * cos( I2 ) - n3 * cos( I3 ) ) / ( n2 * cos( I2 ) + n3 * cos( I3 ) );
399 Rp2 = rp2 * rp2;
400 Rs2 = rs2 * rs2;
401 Rp = ( Rp1 + Rp2 - 2 * Rp1 * Rp2 ) / ( 1 - Rp1 * Rp2 );
402 Rs = ( Rs1 + Rs2 - 2 * Rs1 * Rs2 ) / ( 1 - Rs1 * Rs2 );
403 R = ( Rp + Rs ) / 2.;
404 }
405 return R;
406}
407
408G4double BesTofDigitizerBrV2::Reflectivity( G4double n1, G4double n2, G4double theta ) {
409 G4double I1, I2, rp, rs, Rp, Rs;
410 G4double R = 1.0;
411 // n1=m_refIndex;
412 // n2=1.0;
413 I1 = theta;
414 if ( I1 < asin( n2 / n1 ) )
415 {
416 I2 = asin( sin( I1 ) * ( n1 / n2 ) );
417 rp = ( n1 / cos( I1 ) - n2 / cos( I2 ) ) / ( n1 / cos( I1 ) + n2 / cos( I2 ) );
418 rs = ( n1 * cos( I1 ) - n2 * cos( I2 ) ) / ( n1 * cos( I1 ) + n2 * cos( I2 ) );
419 Rp = rp * rp;
420 Rs = rs * rs;
421 R = ( Rp + Rs ) / 2.;
422 }
423 return R;
424}
425
426void BesTofDigitizerBrV2::DirectPh( G4int partId, G4ThreeVector emtPos, G4double& pathL,
427 G4int& forb ) {
428 // std::cout << "BesTofDigitizerBrV2::DirectPh()" << std::endl;
429 const static G4double silicon_oil_index = 1.43;
430 const static G4double glass_index = 1.532;
431 // generation photon have random direction
432 // optical parameters of scintillation simulation
433 G4double cos_span = 1 - cos( asin( silicon_oil_index / m_refIndex ) );
434 // G4double cos_spanEc = 1;
435 G4double dcos, ran;
436 ran = G4UniformRand();
437 // assuming uniform phi distribution, simulate cos distr only
438 dcos = cos_span * ( ran * 2.0 - 1.0 );
439 // G4double dcosEc = cos_spanEc*(ran*2.0-1.0);
440 G4double r2 = sqrt( emtPos.x() * emtPos.x() + emtPos.y() * emtPos.y() );
441 G4int nRef = 0;
442 G4double costheta, sintheta;
443 G4double theta, thetaR; // thetaR is scin to air full ref angle. about 39.265 degree.
444 costheta = dcos > 0 ? ( 1 - dcos ) : ( 1 + dcos );
445 theta = acos( costheta );
446 sintheta = sin( theta );
447 thetaR = asin( 1 / m_refIndex );
448 G4double R1;
449 R1 = Reflectivity( m_refIndex, 1.0, theta );
450 G4double ratio1Mean = ( CLHEP::pi ) * 25.5 * 25.5 / ( 57.1 + 60.7 ) / 25.0; // 0.693657
451 G4double ratio2Mean = ( 19.5 / 25.5 ) * ( 19.5 / 25.5 ); // 0.584775
452 G4double ratio1 = G4RandGauss::shoot( ratio1Mean, 0.015 );
453 G4double ratio2 = G4RandGauss::shoot( ratio2Mean, 0.015 );
454 G4double ratio3Mean = 0.945 * ratio1Mean * ratio2Mean;
455 G4double ratio3 = G4RandGauss::shoot( ratio3Mean, 0.015 );
456
457 G4double R2 = 1 - Reflectivity( m_refIndex, silicon_oil_index, glass_index, theta );
458 if ( dcos > 0 && dcos != 1 )
459 {
460 if ( theta < thetaR ) // theta < 39.265 degree
461 {
462 if ( G4UniformRand() < ratio1 ) // coup1
463 {
464 if ( G4UniformRand() < R2 )
465 {
466 if ( G4UniformRand() < ratio2 ) // PMT 39mm
467 {
468 forb = 0;
469 pathL = ( m_scinLength / 2 - emtPos.z() ) / costheta;
470 }
471 }
472 else
473 {
474 if ( G4UniformRand() < ratio3 )
475 {
476 forb = 1;
477 pathL = ( 1.5 * m_scinLength - emtPos.z() ) / costheta;
478 }
479 }
480 }
481 else // Air
482 {
483 if ( G4UniformRand() < R1 )
484 {
485 G4double tempran = G4UniformRand();
486 if ( tempran < ratio3 )
487 {
488 forb = 1;
489 pathL = ( 1.5 * m_scinLength - emtPos.z() ) / costheta;
490 }
491 else if ( tempran > ratio1 && G4UniformRand() < R1 && G4UniformRand() < ratio3 )
492 {
493 forb = 0;
494 pathL = ( 2.5 * m_scinLength - emtPos.z() ) / costheta;
495 }
496 }
497 }
498 }
499 else // 39.265 <= theta < 64.832
500 {
501 if ( G4UniformRand() < ratio1 ) // coup1
502 {
503 if ( G4UniformRand() < R2 )
504 {
505 if ( G4UniformRand() < ratio2 ) // PMT 39mm
506 {
507 forb = 0;
508 pathL = ( m_scinLength / 2 - emtPos.z() ) / costheta;
509 }
510 }
511 else
512 {
513 if ( G4UniformRand() < ratio3 )
514 {
515 forb = 1;
516 pathL = ( 1.5 * m_scinLength - emtPos.z() ) / costheta;
517 }
518 }
519 }
520 else // Air
521 {
522 G4double tempran = G4UniformRand();
523 if ( tempran < ratio3 )
524 {
525 forb = 1;
526 pathL = ( 1.5 * m_scinLength - emtPos.z() ) / costheta;
527 }
528 else if ( tempran > ratio1 && G4UniformRand() < ratio3 )
529 {
530 forb = 0;
531 pathL = ( 2.5 * m_scinLength - emtPos.z() ) / costheta;
532 }
533 }
534 }
535 }
536 else if ( dcos < 0 && dcos != -1 )
537 {
538 if ( theta < thetaR ) // theta < 39.265 degree
539 {
540 if ( G4UniformRand() < ratio1 ) // coup1
541 {
542 if ( G4UniformRand() < R2 )
543 {
544 if ( G4UniformRand() < ratio2 ) // PMT 39mm
545 {
546 forb = 1;
547 pathL = ( m_scinLength / 2 + emtPos.z() ) / costheta;
548 }
549 }
550 else
551 {
552 if ( G4UniformRand() < ratio3 )
553 {
554 forb = 0;
555 pathL = ( 1.5 * m_scinLength + emtPos.z() ) / costheta;
556 }
557 }
558 }
559 else // Air
560 {
561 if ( G4UniformRand() < R1 )
562 {
563 G4double tempran = G4UniformRand();
564 if ( tempran < ratio3 )
565 {
566 forb = 0;
567 pathL = ( 1.5 * m_scinLength + emtPos.z() ) / costheta;
568 }
569 else if ( tempran > ratio1 && G4UniformRand() < R1 && G4UniformRand() < ratio3 )
570 {
571 forb = 1;
572 pathL = ( 2.5 * m_scinLength + emtPos.z() ) / costheta;
573 }
574 }
575 }
576 }
577 else // 39.265 <= theta < 64.832
578 {
579 if ( G4UniformRand() < ratio1 ) // coup1
580 {
581 if ( G4UniformRand() < R2 )
582 {
583 if ( G4UniformRand() < ratio2 ) // PMT 39mm
584 {
585 forb = 1;
586 pathL = ( m_scinLength / 2 + emtPos.z() ) / costheta;
587 }
588 }
589 else
590 {
591 if ( G4UniformRand() < ratio3 )
592 {
593 forb = 0;
594 pathL = ( 1.5 * m_scinLength + emtPos.z() ) / costheta;
595 }
596 }
597 }
598 else // Air
599 {
600 G4double tempran = G4UniformRand();
601 if ( tempran < ratio3 )
602 {
603 forb = 0;
604 pathL = ( 1.5 * m_scinLength + emtPos.z() ) / costheta;
605 }
606 else if ( tempran > ratio1 && G4UniformRand() < ratio3 )
607 {
608 forb = 1;
609 pathL = ( 2.5 * m_scinLength + emtPos.z() ) / costheta;
610 }
611 }
612 }
613 }
614
615 G4double convFactor = 180. / 3.1415926;
616 if ( theta > asin( 1 ) - thetaR )
617 {
618 G4double alpha = G4UniformRand() * asin( 1. );
619 G4int nRef1 = pathL * sintheta * cos( alpha ) / 50.0 + 0.5;
620 G4int nRef2 = pathL * sintheta * sin( alpha ) / 58.9 + 0.5;
621 G4double beta1 = acos( sintheta * cos( alpha ) );
622 G4double beta2 = acos( sintheta * sin( alpha ) );
623 beta2 -= 3.75 / convFactor;
624 G4double R21, R22;
625 R21 = Reflectivity( m_refIndex, 1.0, beta1 );
626 R22 = Reflectivity( m_refIndex, 1.0, beta2 );
627 for ( G4int i = 0; i < nRef1; i++ )
628 {
629 if ( G4UniformRand() < ( 1 - R21 ) && G4UniformRand() < 0.15 ) pathL = -9;
630 }
631 for ( G4int i = 0; i < nRef2; i++ )
632 {
633 if ( G4UniformRand() < ( 1 - R22 ) && G4UniformRand() < 0.15 ) pathL = -9;
634 }
635 }
636}
637
638// void BesTofDigitizerBrV2::DirectPh(G4int partId, G4ThreeVector emtPos, G4double& pathL,
639// G4int& forb)
640//{
641// //generation photon have random direction
642// //optical parameters of scintillation simulation
643// G4double cos_span=1-cos( asin(1./m_refIndex) );
644// G4double dcos, ran;
645// ran=G4UniformRand();
646// //assuming uniform phi distribution, simulate cos distr only
647// dcos=cos_span*(ran*2.0-1.0);
648// if (dcos > 0.0&& dcos != 1)
649// {
650// forb=0; //forward
651// pathL=(m_scinLength/2-emtPos.z())/(1.0-dcos);
652// }
653// else if (dcos < 0 && dcos != -1)
654// {
655// forb=1;
656// pathL=(m_scinLength/2+emtPos.z())/(1.0+dcos);
657// }
658// }
659
660G4double BesTofDigitizerBrV2::Scintillation( G4int partId ) {
661 G4double tmp_tauRatio, tmp_tau1, tmp_tau2, tmp_tau3;
662 tmp_tauRatio = m_tauRatio;
663 tmp_tau1 = m_tau1;
664 tmp_tau2 = m_tau2;
665 tmp_tau3 = m_tau3;
666 G4double UniformR = tmp_tauRatio / ( 1 + tmp_tauRatio );
667 G4double EmissionTime;
668 if ( G4UniformRand() > UniformR )
669 {
670 while ( 1 )
671 {
672 EmissionTime = -tmp_tau2 * log( G4UniformRand() );
673 if ( G4UniformRand() - exp( EmissionTime / tmp_tau2 - EmissionTime / tmp_tau1 ) > 1.E-8 )
674 break;
675 }
676 }
677 else EmissionTime = -tmp_tau3 * log( G4UniformRand() );
678 return EmissionTime;
679}
680
681/*G4double BesTofDigitizerBrV2::GenPhoton(G4int partId)
682 {
683//get scintilation time
684G4double scinTime;
685static G4double scinA[26000];
686G4double random[2];
687G4double inverseRegion, ran1, ran2, problive;
688static G4int istore=-1;
689if(istore<0)
690{
691istore=1;
692for(G4int i=0;i<26000;i++)
693scinA[i]=Scintillation( (i+1) *0.001 , partId);
694}
695while(1)
696{
697HepRandom::getTheEngine()->flatArray(2, random);
698inverseRegion=random[0]*2.00975218688231;
699ran1=-4.5*log(1-inverseRegion/(0.45*4.5));
700ran2=0.45*exp(-1.*ran1/4.5)*random[1];
701problive=scinA[G4int(ran1*1000)+1];
702if(problive>=ran2)
703{ scinTime=ran1; break; }
704}
705return scinTime;
706}*/
707
709 // get time transit spread
710 return G4RandGauss::shoot( m_ttsMean, m_ttsSigma );
711}
712
713void BesTofDigitizerBrV2::AccuSignal( G4double endTime, G4int forb ) {
714 G4int ihst;
715 ihst = G4int( endTime / m_timeBinSize );
716 if ( ihst > 0 && ihst < m_profBinN )
717 {
718 m_nPhot[ihst][forb] = m_nPhot[ihst][forb] + 1;
719 m_totalPhot[forb] = m_totalPhot[forb] + 1;
720 }
721}
722
724 // std::cout << "BesTofDigitizerBrV2::TofPmtRspns()" << std::endl;
726 // to generate PMT signal shape for single photoelectron.
727 // only one time for a job.
728 G4double snpe[m_snpeBinN][2];
729
730 // Model: f(t)=Gain*mv_1pe* t**2 * exp-(t/tau)**2/normal-const
731 // normalization const =sqrt(pi)*tau*tau*tau/4.0
732 // G4double tau = m_riseTime;
733 G4double norma_const;
734 G4double echarge = 1.6e-7; // in unit of PC
735
736 // time profile of pmt signals for Back and Forward PMT.
737 G4double profPmt[m_profBinN][2];
738
739 G4double t;
740 G4double tau;
741 G4int n1, n2, ii;
742 G4int phtn;
743 // forb = 0, east
744 for ( G4int i = 0; i < m_snpeBinN; i++ )
745 {
746 tau = tofPara->GetBrERiseTime( scinNb );
747 norma_const = sqrt( CLHEP::pi ) * tau * tau * tau / 4.0; // in unit of ns**3
748 t = ( i + 1 ) * m_timeBinSize;
749 snpe[i][0] = m_Ce * t * t * exp( -( t / tau ) * ( t / tau ) ) /
750 norma_const; // Pulse of one single photoelectron
751 }
752 // forb = 1, west
753 for ( G4int i = 0; i < m_snpeBinN; i++ )
754 {
755 tau = tofPara->GetBrWRiseTime( scinNb );
756 norma_const = sqrt( CLHEP::pi ) * tau * tau * tau / 4.0; // in unit of ns**3
757 t = ( i + 1 ) * m_timeBinSize;
758 snpe[i][1] = m_Ce * t * t * exp( -( t / tau ) * ( t / tau ) ) / norma_const;
759 }
760 // for barrel and endcap tof: fb=2 or 1
761 G4int fb = 2;
762 G4double Npoisson;
763 G4double pmtGain0, pmtGain, relativeGain, smearPMTgain;
764 G4double smearADC[2] = { 0., 0. };
765 G4int runId = m_RealizationSvc->getRunId();
766 pmtGain0 = m_tofSimSvc->BarPMTGain();
767
768 // if(runId>=-80000 && runId<=-9484)
769 // {
770 // // After TOF HV adjustment, PMT Gain of barrel TOF in MC is set to 5.E5
771 // // High/Low Threshold for barrel: 500/125 mV
772 // pmtGain0 = 6.E5;
773 // }
774 // else
775 // {
776 // // Before TOF HV adjustment, PMT Gain of barrel TOF in MC is set to 2.5E5
777 // // High/Low Threshold for barrel: 600/150 mV
778 // pmtGain0 = 5.E5;
779 // }
780
781 G4double timeSmear = G4RandGauss::shoot( 0, 0.020 );
782 if ( runId >= -22913 && runId <= -20448 )
783 { // for 2011-psipp(20448-22913), smear barrel TOF resolution to ~78ps
784 timeSmear = G4RandGauss::shoot( 0, 0.040 );
785 }
786 else if ( ( runId >= -11396 && runId <= -8093 ) || ( runId > -1000000 && runId <= -23463 ) )
787 { timeSmear = G4RandGauss::shoot( 0, 0.025 ); }
788
789 for ( G4int j = 0; j < fb; j++ )
790 {
791 if ( m_totalPhot[j] > 0 )
792 {
793 n1 = G4int( m_t1st[j] / m_timeBinSize );
794 n2 = G4int( m_tLast[j] / m_timeBinSize );
795 // std::cout << "n1: " << n1 << std::endl;
796
797 for ( G4int i = 0; i < m_profBinN; i++ ) profPmt[i][j] = 0.0;
798
799 // generate PMT pulse
800 n2 = n2 < m_profBinN ? n2 : m_profBinN;
801 for ( G4int i = n1; i < n2; i++ )
802 {
803 phtn = m_nPhot[i][j];
804 if ( phtn > 0 )
805 {
806 while ( 1 )
807 {
808 Npoisson = G4Poisson( 10.0 );
809 if ( Npoisson > 0. ) break;
810 }
811 while ( 1 )
812 {
813 // pmtGain = j ? tofPara->GetBrWPMTgain(scinNb) : tofPara->GetBrEPMTgain(scinNb);
814 // relativeGain = j ? m_tofCaliSvc->BGainBackward(scinNb) :
815 // m_tofCaliSvc->BGainForward(scinNb);
816 relativeGain =
817 j ? m_tofSimSvc->BarGain2( scinNb ) : m_tofSimSvc->BarGain1( scinNb );
818 pmtGain = pmtGain0 * relativeGain;
819 smearPMTgain = G4RandGauss::shoot( pmtGain, pmtGain / sqrt( Npoisson ) );
820 // smearPMTgain = pmtGain;
821 if ( smearPMTgain > 0 ) break;
822 }
823 smearADC[j] += phtn * smearPMTgain;
824
825 for ( G4int ihst = 0; ihst < m_snpeBinN; ihst++ )
826 {
827 ii = i + ihst;
828 if ( ii < m_profBinN ) profPmt[ii][j] += smearPMTgain * phtn * snpe[ihst][j];
829 else break;
830 }
831 }
832 }
833
834 // add preamplifier and noise
835 for ( int i = 0; i < m_profBinN; i++ )
836 {
837 if ( profPmt[i][j] > 0 )
838 profPmt[i][j] = m_preGain * profPmt[i][j] + G4RandGauss::shoot( 0, m_noiseSigma );
839 }
840
841 // get pulse height
842 G4double max = 0;
843 for ( int i = n1; i < m_profBinN; i++ )
844 {
845 if ( profPmt[i][j] > max ) max = profPmt[i][j];
846 }
847 if ( m_G4Svc->TofRootFlag() )
848 {
849 if ( j == 0 ) m_max0 = max;
850 else m_max1 = max;
851 }
852
853 G4double tmp_HLthresh, tmp_LLthresh, adcFactor;
854 G4double ratio;
855
856 if ( runId >= -80000 && runId <= -9484 )
857 {
858 // After TOF HV adjustment, PMT Gain of barrel TOF in MC is set to 5.E5
859 // High/Low Threshold for barrel: 500/125 mV
860 tmp_HLthresh = m_HLthresh;
861 tmp_LLthresh = m_LLthresh;
862 adcFactor = 5.89;
863 }
864 else
865 {
866 // Before TOF HV adjustment, PMT Gain of barrel TOF in MC is set to 2.5E5
867 // High/Low Threshold for barrel: 600/150 mV
868 tmp_HLthresh = 600;
869 tmp_LLthresh = 150;
870 adcFactor = 4.8;
871 }
872 // if(runId>=-80000 && runId<=-9484)
873 // {
874 // ratio=2.16*1923.8/2197.8;
875 // }
876 // else
877 // {
878 // ratio = 2.11*2437.0/3102.9;
879 // }
880 tmp_HLthresh = m_tofSimSvc->BarHighThres();
881 tmp_LLthresh = m_tofSimSvc->BarLowThres();
882 ratio = m_tofSimSvc->BarConstant();
883
884 // get final tdc and adc
885 if ( max >= tmp_HLthresh )
886 {
887 for ( int i = 0; i < m_profBinN; i++ )
888 {
889 if ( profPmt[i][j] >= tmp_LLthresh )
890 {
891 m_TDC[j] =
892 i * m_timeBinSize + timeSmear +
893 G4RandGauss::shoot( 0, 0.025 ); // Adding Electronical Uncertainty of 25ps
894 // hhliu 20140724, setting tdc-smear for inner and outer separately
895 if ( ( runId >= -11396 && runId <= -8093 ) ||
896 ( runId > -1000000 && runId <= -23463 ) )
897 {
898 if ( scinNb < 88 )
899 { m_TDC[j] = i * m_timeBinSize + timeSmear + G4RandGauss::shoot( 0, 0.055 ); }
900 else
901 { m_TDC[j] = i * m_timeBinSize + timeSmear + G4RandGauss::shoot( 0, 0.062 ); }
902 }
903
904 if ( m_G4Svc->TofSaturationFlag() )
905 {
906 // get ADC[j] using tofQElecSvc
907 double x = m_preGain * smearADC[j] * echarge * ratio;
908 if ( j == 0 ) { m_ADC[j] = m_tofQElecSvc->BQChannel1( scinNb, x ); }
909 else { m_ADC[j] = m_tofQElecSvc->BQChannel2( scinNb, x ); }
910 }
911 else m_ADC[j] = m_preGain * smearADC[j] * echarge * adcFactor;
912
913 if ( m_G4Svc->TofRootFlag() )
914 {
915 if ( j == 0 )
916 {
917 m_tdc0 = m_TDC[0];
918 m_adc0 = m_ADC[0];
919 }
920 else
921 {
922 m_tdc1 = m_TDC[1];
923 m_adc1 = m_ADC[1];
924 }
925 }
926 break;
927 }
928 }
929 }
930 }
931 }
932}
#define max(a, b)
EvtComplex exp(const EvtComplex &c)
double alpha
G4TDigiCollection< BesTofDigi > BesTofDigitsCollection
G4THitsCollection< BesTofHit > BesTofHitsCollection
int n2
Definition SD0Tag.cxx:59
int n1
Definition SD0Tag.cxx:58
G4double Reflectivity(G4double n1, G4double n2, G4double theta)
void AccuSignal(G4double, G4int)
virtual void Digitize(ScintSingle *, BesTofDigitsCollection *)
G4double Scintillation(G4int)
void DirectPh(G4int, G4ThreeVector, G4double &, G4int &)
G4double BirksLaw(BesTofHit *hit)
void TofPmtAccum(BesTofHit *, G4int)
static BesTofGeoParameter * GetInstance()
int t()
Definition t.c:1
#define ns(x)
Definition xmltok.c:1355