BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
BesMdcDigitizer.cc
Go to the documentation of this file.
1//---------------------------------------------------------------------------//
2// BOOST --- BESIII Object_Oriented Simulation Tool //
3//---------------------------------------------------------------------------//
4// Description:
5// Author: Yuan Ye(yuany@mail.ihep.ac.cn)
6// Created: Oct. 26, 2004
7// Modified:
8// Comment:
9//---------------------------------------------------------------------------//
10
11#include "MdcSim/BesMdcDigitizer.hh"
12#include "MdcSim/BesMdcDigitizerMessenger.hh"
13#include "MdcSim/BesMdcHit.hh"
14
15#include "G4DigiManager.hh"
16#include "G4ios.hh"
17#include "Randomize.hh"
18#include <cstdlib>
19#include <string>
20
21#include "TFile.h"
22#include "TH1F.h"
23
24#include "G4Svc/IG4Svc.h"
25#include "GaudiKernel/Bootstrap.h"
26#include "GaudiKernel/IDataProviderSvc.h"
27#include "GaudiKernel/ISvcLocator.h"
28
29BesMdcDigitizer::BesMdcDigitizer( G4String modName ) : G4VDigitizerModule( modName ) {
30 noiseFlag = 0;
31 noiseType = 3;
32 noiseLevel = 0.1; // 10%
33 maxNoiseT = 300.; // ns
34 smearFlag = 1;
35 mdcDRes = 0.13; // mm
36 effFlag = 0;
37 for ( G4int i = 0; i < 43; i++ ) { layerEff.push_back( 1. ); }
38 collectionName.push_back( "BesMdcDigisCollection" );
39 digitizerMessenger = new BesMdcDigitizerMessenger( this );
40 mdcGeoPointer = BesMdcGeoParameter::GetGeo();
41 mdcCalPointer = new BesMdcCalTransfer;
42
43 StatusCode sc = Gaudi::svcLocator()->service( "G4Svc", m_G4Svc );
44 if ( !sc.isSuccess() ) G4cout << " MdcDigitizer::Error,could not open G4Svc" << G4endl;
45
46 sc = Gaudi::svcLocator()->service( "MdcTunningSvc", mdcTunningSvc );
47 if ( !sc.isSuccess() )
48 { G4cout << " MdcDigitizer::Error,could not open Mdc Tunning Service" << G4endl; }
49 else { G4cout << " MdcDigitizer:: Open Mdc Tunning Service" << G4endl; }
50
51 std::string noiseFile = m_G4Svc->GetMdcNoiseFile();
52 f = new TFile( noiseFile.c_str() );
53 h1 = (TH1F*)f->Get( "h703" );
54 h2 = (TH1F*)f->Get( "h501" );
55 h3 = (TH1F*)f->Get( "h801" );
56 /*
57 //get Mdc Ntuple from G4Svc
58 if(m_G4Svc->MdcRootFlag())
59 {
60 m_tupleMdc = m_G4Svc->GetTupleMdc();
61 sc = m_tupleMdc->addItem("NHits",m_NHits);
62 sc = m_tupleMdc->addItem("LayerId",m_layerId);
63 sc = m_tupleMdc->addItem("cellId",m_cellId);
64 sc = m_tupleMdc->addItem("Edep",m_edep);
65 sc = m_tupleMdc->addItem("driftD",m_driftD);
66 // sc = m_tupleMdc->addItem("driftT",m_driftT);
67 sc = m_tupleMdc->addItem("globalT",m_globalT);
68 sc = m_tupleMdc->addItem("theta",m_theta);
69 sc = m_tupleMdc->addItem("enterAngle",m_enterAngle);
70 sc = m_tupleMdc->addItem("driftDNew",m_driftDNew);
71 sc = m_tupleMdc->addItem("driftTNew",m_driftTNew);
72 // sc = m_tupleMdc->addItem("adc",m_adc);
73 // sc = m_tupleMdc->addItem("tdc",m_tdc);
74 }
75 */
76}
77
78BesMdcDigitizer::~BesMdcDigitizer() { delete digitizerMessenger; }
79
80void BesMdcDigitizer::SetEff( G4int layer, G4double eff ) {
81 if ( layer == -1 )
82 {
83 for ( G4int i = 0; i < 43; i++ ) { layerEff[i] = eff; }
84 }
85 else { layerEff[layer] = eff; }
86}
87
89
90 // initialize
91 for ( G4int i = 0; i < 43; i++ )
92 {
93 for ( G4int j = 0; j < 288; j++ ) { digiPointer[i][j] = -1; }
94 }
95
96 G4int NHits, layerId, cellId, posFlag;
97 G4double edep, driftD, driftT, globalT, theta, cosTheta, enterAngle;
98 G4double mean, sigma, mean1, mean2, sigma1, sigma2, f, sig, delSig, fRandom, driftDNew,
99 driftTNew;
100 G4double tempEff;
101 G4double resLargest, resSmallest, resRatio; // added by liukai
102
103 G4DigiManager* DigiMan = G4DigiManager::GetDMpointer();
104
105 // hits collection ID
106 G4int THCID = -1;
107 THCID = DigiMan->GetHitsCollectionID( "BesMdcHitsCollection" );
108
109 // hits collection
110 BesMdcHitsCollection* THC = 0;
111 THC = (BesMdcHitsCollection*)( DigiMan->GetHitsCollection( THCID ) );
112
113 if ( THC )
114 {
115 digisCollection = new BesMdcDigisCollection( moduleName, collectionName[0] );
116 NHits = THC->entries();
117 for ( G4int i = 0; i < NHits; i++ )
118 {
119 layerId = ( *THC )[i]->GetLayerNo();
120 cellId = ( *THC )[i]->GetCellNo();
121 edep = ( *THC )[i]->GetEdep();
122 driftD = ( *THC )[i]->GetDriftD();
123 globalT = ( *THC )[i]->GetGlobalT();
124 theta = ( *THC )[i]->GetTheta();
125 cosTheta = cos( theta );
126 enterAngle = ( *THC )[i]->GetEnterAngle();
127 posFlag = ( *THC )[i]->GetPosFlag();
128
129 // Transfer hit pointer to BesMdcCalTransfer
130 mdcCalPointer->SetHitPointer( ( *THC )[i] );
131
132 // Filter with wire efficiency
133 if ( effFlag == 0 )
134 {
135 // tempEff = mdcCalPointer->GetEff();
136 tempEff = mdcTunningSvc->GetEff( layerId, cellId, driftD, cosTheta, posFlag );
137 }
138 else { tempEff = layerEff[layerId]; }
139 fRandom = G4UniformRand();
140 if ( fRandom > tempEff ) continue;
141
142 // cout<<"layerid "<<layerId<<" cellid "<<cellId<<" theta "<<cosTheta<<" enterangle
143 // "<<enterAngle<<endl; Drift distance smear
144 if ( smearFlag == 0 )
145 { // No smear
146 driftDNew = driftD;
147 }
148 else if ( smearFlag == 1 )
149 { // Smear from TuningSvc
150 // mdcTunningSvc->GetRes(layerId,cellId,driftD,cosTheta,posFlag,enterAngle,mean,sigma);
151 // mdcTunningSvc->GetRes2(layerId,cellId,driftD,cosTheta,posFlag,enterAngle,f,mean1,sigma1,mean2,sigma2);
152 mdcTunningSvc->GetRes3( layerId, cellId, driftD, cosTheta, posFlag, enterAngle, f,
153 mean1, sigma1, mean2, sigma2, resLargest, resSmallest,
154 resRatio );
155
156 // driftDNew = Smear(driftD,f,mean1,sigma1,mean2,sigma2);
157 // driftDNew = Smear(driftD-(f*mean1+(1-f)*mean2),f,mean1,sigma1,mean2,sigma2);//new
158 // method
159
160 driftDNew =
161 Smear( driftD - ( f * mean1 + ( 1 - f ) * mean2 ), f, mean1, sigma1, mean2, sigma2,
162 resLargest, resSmallest, resRatio ); //----added by liukai 2012-6-4
163 }
164 else if ( smearFlag == 2 )
165 { // Smear with fixed resolution
166 driftDNew = Smear( driftD );
167 }
168 else
169 {
170 G4cerr << "MdcDigitizer::wrong smearFlag: " << smearFlag << G4endl;
171 abort();
172 }
173
174 // Do X-T conversion
175 driftTNew = mdcCalPointer->D2T( driftDNew );
176
177 // Do Q-T correct
178 driftTNew += mdcCalPointer->GetTimeWalk();
179
180 // Add T0
181 driftTNew += mdcCalPointer->GetT0();
182
183 // Add TOF
184 driftTNew += globalT;
185
186 // Signal transfer time on wire
187 // transferT=Transfer(layerId,cellId,hitPosition);
188 // driftTNew+=transferT;
189
190 if ( std::isnan( driftTNew ) )
191 {
192 G4cout << "MdcDigitizer::error, driftT is nan" << G4endl;
193 continue;
194 }
195
196 /*
197 if(m_G4Svc->MdcRootFlag())
198 {
199 m_NHits= NHits;
200 m_layerId= layerId;
201 m_cellId= cellId;
202 m_edep= edep;
203 m_driftD= driftD;
204 // m_driftT= driftT;
205 m_globalT = globalT;
206 m_enterAngle = enterAngle;
207 m_driftDNew = driftDNew;
208 m_driftTNew = driftTNew;
209 m_theta = theta;
210 m_tupleMdc ->write();
211 }
212 */
213 BesMdcDigi* newDigi = new BesMdcDigi();
214 newDigi->SetTrackID( ( *THC )[i]->GetTrackID() );
215 newDigi->SetLayerNo( layerId );
216 newDigi->SetCellNo( cellId );
217 newDigi->SetEdep( edep );
218 newDigi->SetDriftT( driftTNew );
219 G4int NbDigis = digisCollection->insert( newDigi );
220 digiPointer[layerId][cellId] = NbDigis - 1;
221 }
222
223 if ( noiseFlag == 1 ) AddNoise();
224 if ( noiseFlag == 2 )
225 {
226 ifstream readNoiseLevel( "$MDCSIMROOT/share/noiselevel.txt" );
227 if ( !readNoiseLevel.good() )
228 { std::cout << " Error , noiselevel file not exist " << std::endl; }
229 else { std::cout << " MdcDigitizer:: Open noiselevel file " << std::endl; }
230 G4int NLayer = mdcGeoPointer->SignalLayerNo();
231 G4double level;
232 for ( G4int i = 0; i < NLayer; i++ )
233 {
234 readNoiseLevel >> level;
235 mixLevel.push_back( level );
236 }
237 AddNoise2();
238 }
239
240 if ( verboseLevel > 0 )
241 {
242 G4cout << "\n-------->digis Collection: in this event they are "
243 << digisCollection->entries() << " digis in the MDC chambers: " << G4endl;
244 digisCollection->PrintAllDigi();
245 }
246 StoreDigiCollection( digisCollection );
247 }
248}
249
250G4double BesMdcDigitizer::Smear( G4double driftD ) {
251 G4double r, driftDNew;
252 r = G4RandGauss::shoot();
253 driftDNew = driftD + mdcDRes * r;
254 while ( driftDNew <= 0 )
255 {
256 r = G4RandGauss::shoot();
257 driftDNew = driftD + mdcDRes * r;
258 }
259 return driftDNew;
260}
261
262G4double BesMdcDigitizer::Smear( G4double driftD, G4double sigma, G4double mean ) {
263 G4double r, driftDNew;
264 r = G4RandGauss::shoot();
265 driftDNew = driftD + sigma * r + mean;
266 while ( driftDNew <= 0 )
267 {
268 r = G4RandGauss::shoot();
269 driftDNew = driftD + sigma * r + mean;
270 }
271 return driftDNew;
272}
273
274G4double BesMdcDigitizer::Smear( G4double driftD, G4double f, G4double mean1, G4double sigma1,
275 G4double mean2, G4double sigma2 ) {
276 G4double r, driftDNew, mean, sigma;
277 r = G4UniformRand();
278 if ( r <= f )
279 {
280 mean = mean1;
281 sigma = sigma1;
282 }
283 else
284 {
285 mean = mean2;
286 sigma = sigma2;
287 }
288 int times = 0;
289 r = G4RandGauss::shoot();
290 driftDNew = driftD + sigma * r + mean;
291 while ( driftDNew <= 0 )
292 {
293 r = G4RandGauss::shoot();
294 driftDNew = driftD + sigma * r + mean;
295 times++;
296 if ( times > 10 ) driftDNew = 0.01;
297 }
298 return driftDNew;
299}
300
301G4double BesMdcDigitizer::Smear( G4double driftD, G4double f, G4double mean1, G4double sigma1,
302 G4double mean2, G4double sigma2, G4double resLargest,
303 G4double resSmallest, G4double resRatio ) {
304 G4double r, driftDNew, mean = 0, sigma = 0;
305 G4double ratio, tempd;
306 ratio = G4UniformRand();
307 int times;
308 if ( ratio <= resRatio )
309 {
310 // for hitOnTrk distribution
311 r = G4UniformRand();
312 if ( r <= f )
313 {
314 mean = mean1;
315 sigma = sigma1;
316 }
317 else
318 {
319 mean = mean2;
320 sigma = sigma2;
321 }
322 times = 0;
323 r = G4RandGauss::shoot();
324 driftDNew = driftD + sigma * r + mean;
325 }
326 else // for hitNotOnTrk
327 {
328 tempd = G4UniformRand() * 2.0 + resLargest;
329 times = 0;
330 driftDNew = driftD + tempd;
331 }
332 while ( driftDNew <= 0 )
333 {
334 r = G4RandGauss::shoot();
335 driftDNew = driftD + sigma * r + mean;
336 times++;
337 if ( times > 10 ) driftDNew = 0.01;
338 }
339 return driftDNew;
340}
341
342void BesMdcDigitizer::AddNoise2( void ) {
343 G4int wireNo;
344 G4double random;
345 G4double randomT;
346 G4double randomQ;
347 G4int NLayer = mdcGeoPointer->SignalLayerNo();
348 for ( G4int i = 0; i < NLayer; i++ )
349 {
350 wireNo = mdcGeoPointer->SignalLayer( i ).WireNo() / 2;
351 for ( G4int j = 0; j < wireNo; j++ )
352 {
353 random = G4UniformRand();
354 if ( random < mixLevel[i] )
355 {
356 randomT = G4UniformRand() * 2000;
357 if ( std::isnan( randomT ) )
358 {
359 G4cout << "MdcDigitizer: error, randomT is nan" << G4endl;
360 continue;
361 }
362
363 randomQ = 200.;
364 if ( digiPointer[i][j] != -1 )
365 {
366 G4int pointer = digiPointer[i][j];
367 G4double preDriftT = ( *digisCollection )[pointer]->GetDriftT();
368 if ( preDriftT <= randomT ) continue;
369 ( *digisCollection )[pointer]->SetDriftT( randomT );
370 ( *digisCollection )[pointer]->SetTrackID( -1 );
371 }
372 else
373 {
374 BesMdcDigi* newDigi = new BesMdcDigi();
375 newDigi->SetTrackID( -1 );
376 newDigi->SetLayerNo( i );
377 newDigi->SetCellNo( j );
378 newDigi->SetEdep( randomQ );
379 newDigi->SetDriftT( randomT );
380 digisCollection->insert( newDigi );
381 }
382 }
383 }
384 }
385}
386
387void BesMdcDigitizer::AddNoise( void ) {
388 G4double r0, r;
389 vector<G4double> noise; // Noise level of each layer
390
391 G4int NLayer = mdcGeoPointer->SignalLayerNo();
392 if ( noiseType == 0 )
393 {
394 for ( G4int i = 0; i < NLayer; i++ ) { noise.push_back( noiseLevel ); }
395 }
396 else if ( noiseType == 1 )
397 {
398 r0 = mdcGeoPointer->SignalLayer( 0 ).R();
399 for ( G4int i = 0; i < NLayer; i++ )
400 {
401 r = mdcGeoPointer->SignalLayer( i ).R();
402 noise.push_back( noiseLevel * r0 / r );
403 }
404 }
405 else if ( noiseType == 2 )
406 {
407 r0 = mdcGeoPointer->SignalLayer( 0 ).R();
408 for ( G4int i = 0; i < NLayer; i++ )
409 {
410 r = mdcGeoPointer->SignalLayer( i ).R();
411 noise.push_back( noiseLevel * r0 * r0 / r / r );
412 }
413 }
414 else if ( noiseType == 3 )
415 { // liugc add 22:11 4/14/06
416 Int_t Nbins = (Int_t)h1->GetNbinsX();
417
418 double xmax = h1->GetXaxis()->GetXmax();
419 double xmin = h1->GetXaxis()->GetXmin();
420 double dx = ( xmax - xmin ) / Nbins;
421 G4double y;
422 for ( G4int i = 0; i < Nbins; i++ )
423 {
424 double x = double( i + 1 ) * dx;
425 y = (G4double)h1->GetBinContent( x );
426 y = y * noiseLevel /
427 0.05608559; // Normalize use noise level of 1st layer in "run23096noise.root"
428 noise.push_back( y );
429 }
430 }
431
432 G4int wireNo;
433 G4double random;
434 G4double randomT;
435 G4double randomQ;
436 G4double T0 = m_G4Svc->GetBeamStartTime();
437 for ( G4int i = 0; i < NLayer; i++ )
438 {
439 wireNo = mdcGeoPointer->SignalLayer( i ).WireNo() / 2;
440 for ( G4int j = 0; j < wireNo; j++ )
441 {
442 random = G4UniformRand();
443 if ( random < noise[i] )
444 {
445 // randomT=G4UniformRand() * maxNoiseT;
446 randomT = h2->GetRandom() + T0;
447 // randomT=randomT;
448 // randomQ=h3->GetRandom();
449 // randomQ=randomQ*0.001*0.001; //Transfer from TDC channels to Mev, coef. is
450 // temporary one.
451 if ( std::isnan( randomT ) )
452 {
453 G4cout << "MdcDigitizer: error, randomT is nan" << G4endl;
454 continue;
455 }
456
457 randomQ = 0.;
458 if ( digiPointer[i][j] != -1 )
459 {
460 G4int pointer = digiPointer[i][j];
461 G4double signalEdep = ( *digisCollection )[pointer]->GetEdep();
462 ( *digisCollection )[pointer]->SetEdep( randomQ + signalEdep );
463 G4double preDriftT = ( *digisCollection )[pointer]->GetDriftT();
464 if ( preDriftT <= randomT ) continue;
465 ( *digisCollection )[pointer]->SetDriftT( randomT );
466 ( *digisCollection )[pointer]->SetTrackID( -1 );
467 }
468 else
469 {
470 BesMdcDigi* newDigi = new BesMdcDigi();
471 newDigi->SetTrackID( -1 );
472 newDigi->SetLayerNo( i );
473 newDigi->SetCellNo( j );
474 newDigi->SetEdep( randomQ );
475 newDigi->SetDriftT( randomT );
476 digisCollection->insert( newDigi );
477 }
478 }
479 }
480 }
481}
TFile f("ana_bhabha660a_dqa_mcPat_zy_old.root")
Double_t x[10]
const int wireNo
G4TDigiCollection< BesMdcDigi > BesMdcDigisCollection
G4THitsCollection< BesMdcHit > BesMdcHitsCollection
virtual void Digitize()
BesMdcDigitizer(G4String modName)
void SetEff(G4int layer, G4double eff)
static BesMdcGeoParameter * GetGeo(void)