BOSS 6.6.4.p03
BESIII Offline Software System
Loading...
Searching...
No Matches
BesEmcDigitizer.cc
Go to the documentation of this file.
1//---------------------------------------------------------------------------//
2// BOOST --- BESIII Object_Oreiented Simulation Tool //
3//---------------------------------------------------------------------------//
4//Descpirtion: EMC digitizer
5//Author: Hemiao
6//Created: Sep, 2004
7//Comment:
8//---------------------------------------------------------------------------//
9//$Id:BesEmcDigitizer.cc
10
11#include "BesEmcDigitizer.hh"
12#include "BesEmcDigi.hh"
13#include "BesEmcHit.hh"
14#include "BesEmcWaveform.hh"
15#include "G4DigiManager.hh"
16#include "BesEmcParameter.hh"
17#include "Randomize.hh"
18
19#include "GaudiKernel/Bootstrap.h"
20#include "GaudiKernel/ISvcLocator.h"
21#include "G4Svc/G4Svc.h"
23
25:G4VDigitizerModule(modName),m_emcCalibConstSvc(0)
26{
27 collectionName.push_back("BesEmcDigitsCollection");
28 m_besEmcDigitsCollection = 0;
29
30 //retrieve G4Svc
31 ISvcLocator* svcLocator = Gaudi::svcLocator();
32 IG4Svc* iG4Svc;
33 StatusCode sc=svcLocator->service("G4Svc", iG4Svc);
34 m_G4Svc=dynamic_cast<G4Svc *>(iG4Svc);
35
36 //get Emc Ntuple from G4Svc
37 if(m_G4Svc->EmcRootFlag())
38 {
39 m_tupleEmc1 = m_G4Svc->GetTupleEmc1();
40 sc = m_tupleEmc1->addItem("partId",m_partId);
41 sc = m_tupleEmc1->addItem("nTheta",m_nTheta);
42 sc = m_tupleEmc1->addItem("nPhi",m_nPhi);
43 sc = m_tupleEmc1->addItem("edep",m_eDep);
44 sc = m_tupleEmc1->addItem("nHits",m_nHits);
45 sc = m_tupleEmc1->addItem("adc",m_adc);
46 sc = m_tupleEmc1->addItem("tdc",m_tdc);
47
48 m_tupleEmc2 = m_G4Svc->GetTupleEmc2();
49 sc = m_tupleEmc2->addItem("etot",m_eTot);
50 sc = m_tupleEmc2->addItem("nDigi",m_nDigi);
51 }
52
53 // Get EmcCalibConstSvc.
54 sc = svcLocator->service("EmcCalibConstSvc", m_emcCalibConstSvc);
55 if(sc != StatusCode::SUCCESS) {
56 G4cout << "BesEmcDigitizer Error: Can't get EmcCalibConstSvc." << G4endl;
57 }
58
59}
60
62{
63}
64
65void BesEmcDigitizer::Initialize()
66{
67}
68
70{
71 Initialize();
72
73
74 m_besEmcDigitsCollection = new BesEmcDigitsCollection
75 ("BesEmcDigitizer","BesEmcDigitsCollection");
76 G4DigiManager* DigiMan = G4DigiManager::GetDMpointer();
77
78
79 //hits collection ID
80 G4int EHCID;
81 EHCID = DigiMan->GetHitsCollectionID("BesEmcHitsCollection");
82
83 //hits collection
84 BesEmcHitsCollection* EHC = 0;
85 EHC = (BesEmcHitsCollection*) (DigiMan->GetHitsCollection(EHCID));
86
87 if (EHC)
88 {
89 //BesEmcParameter& emcPara=BesEmcParameter::GetInstance();
90 m_crystalGroup = new vector<CrystalSingle*>;
91 GroupHits(EHC);
92 G4int size=m_crystalGroup->size();
93 CrystalSingle* cryst;
94 G4int partId, nTheta, nPhi, nHits;
95 G4double eTot=0, eDigi;
96 BesEmcHit* hit;
97
98 G4double coherentNoise = RandGauss::shoot()*m_G4Svc->EmcCoherentNoise();
99
100 for(G4int i=0;i<size;i++)
101 {
102 cryst = (*m_crystalGroup)[i]; //all hits in a crystal
103 partId = cryst->GetPartId();
104 nTheta = cryst->GetNTheta();
105 nPhi = cryst->GetNPhi();
106 nHits= cryst->GetHitIndexes()->size();
107 eDigi = cryst->GetEdep();
108 eTot += eDigi;
109
110 BesEmcDigi *digi = new BesEmcDigi;
111 BesEmcWaveform *wave = digi->GetWaveform();
112 G4long bin = 0; //time
113
114 const int indexSize = 200;
115 G4double e[indexSize]; //energy of the same index
116 for(G4int i=0;i<indexSize;i++)
117 e[i]=0;
118 G4int index=0;
119 G4double energy=0;
120
121 for(G4int j=0;j<nHits;j++)
122 {
123 hit= (*EHC)[( *(cryst->GetHitIndexes()) )[j]];
124 energy = hit->GetEdepCrystal();
125 index = hit->GetTrackIndex();
126 if(index<indexSize&&index>=0)
127 e[index]+=energy;
128 else
129 G4cout<<"Track index overload!"<<G4endl;
130 }
131
132 G4double maxi=e[0]; //find the index which gives the most energy in one crystal
133 for(G4int i=1;i<indexSize;i++)
134 {
135 if(e[i]>maxi)
136 {
137 maxi = e[i];
138 index = i;
139 }
140 }
141
142 if(eDigi>0)
143 {
144 digi->SetPartId(partId);
145 digi->SetThetaNb(nTheta);
146 digi->SetPhiNb(nPhi);
147 digi->SetEnergy(eDigi);
148 digi->SetTime(m_G4Svc->EmcTime());
149 digi->SetTrackIndex(index);
150
151 wave->updateWaveform(digi);
152 if(m_G4Svc->EmcNoiseLevel()>0)
153 wave->addElecNoise(m_G4Svc->EmcIncoherentNoise(),coherentNoise);
154
155 //to avoid error caused by precision, get energy before digitization
156 m_energy = wave->max(bin);
157 //temp code, subtract pedstal
158 m_energy -= 0.46*MeV;
159 wave->digitize();
160 wave->max(bin);
161
162 if(m_G4Svc->EmcLightOutput())
163 {
164 G4int index = m_emcCalibConstSvc->getIndex(partId,nTheta,nPhi);
165 G4double adc2e = m_emcCalibConstSvc->getDigiCalibConst(index);
166 if(adc2e<=1e-5) // dead channel
167 {
168 m_energy = 0;
169 }
170 else
171 {
172 m_energy /= adc2e;
173 //m_energy /= emcPara.GetLightOutput(partId,nTheta,nPhi);
174 }
175 }
176
177 //fill Emc Ntuple1
178 if(m_G4Svc->EmcRootFlag())
179 {
180 m_partId = partId;
181 m_nTheta = nTheta;
182 m_nPhi = nPhi;
183 m_eDep = eDigi;
184 m_nHits = nHits;
185 m_adc = m_energy;
186 m_tdc = bin;
187 m_tupleEmc1->write();
188 }
189
190 digi->SetEnergy(m_energy);
191 digi->SetTime(bin);
192 digi->SetWaveform(wave);
193 m_besEmcDigitsCollection->insert(digi);
194 }
195 }
196
197 //add to noise to no signal crystals
198 if(m_G4Svc->EmcNoiseLevel()==2)
199 AddNoise5x5(coherentNoise);
200 else if(m_G4Svc->EmcNoiseLevel()==3)
201 ;
202 //AddNoiseAll(coherentNoise);
203
204 //fill Emc Ntuple2
205 if(m_G4Svc->EmcRootFlag())
206 {
207 m_eTot = eTot;
208 m_nDigi = size;
209 m_tupleEmc2->write();
210 }
211
212 StoreDigiCollection(m_besEmcDigitsCollection);
213
214 for(size_t i=0;i<m_crystalGroup->size();i++)
215 {
216 delete (*m_crystalGroup)[i];
217 }
218 m_crystalGroup->clear();
219 delete m_crystalGroup;
220 }
221}
222
224{
225 G4int partId, nTheta, nPhi, size, flag;
226 G4double edep;
227 BesEmcHit* hit;
228 G4int nHits = m_EHC->entries();
229
230 //group the hits which are in the same crystal
231 for(G4int i=0;i<nHits;i++)
232 {
233 hit = (*m_EHC)[i];
234 partId = hit->GetPartId();
235 nTheta = hit->GetNumThetaCrystal();
236 nPhi = hit->GetNumPhiCrystal();
237 edep = hit->GetEdepCrystal();
238 size = m_crystalGroup->size();
239 flag=0;
240
241 if(size>0)
242 {
243 CrystalSingle* oldCryst;
244 for(G4int j=0; j<size;j++)
245 {
246 oldCryst = (*m_crystalGroup)[j];
247 if((oldCryst->GetNTheta()==nTheta)&&(oldCryst->GetNPhi()==nPhi)&&(oldCryst->GetPartId()==partId))
248 {
249 oldCryst->GetHitIndexes()->push_back(i);
250 oldCryst->AddEdep(edep);
251 flag=1;
252 break;
253 }
254 }
255 }
256
257 if(flag==0)
258 {
259 CrystalSingle* newCryst = new CrystalSingle;
260 newCryst->SetPartId(partId);
261 newCryst->SetNTheta(nTheta);
262 newCryst->SetNPhi(nPhi);
263 newCryst->SetEdep(edep);
264 newCryst->GetHitIndexes()->push_back(i);
265 m_crystalGroup->push_back(newCryst);
266 }
267
268 }
269}
270
271void BesEmcDigitizer::AddNoise5x5(G4double coherentNoise)
272{
274 vector<BesEmcDigi*>* vecDC = m_besEmcDigitsCollection->GetVector();
275 G4int nDigi = m_besEmcDigitsCollection->entries();
276 G4int partMax,thetaMax,phiMax;
277 partMax=thetaMax=phiMax=-99;
278 G4double eMax = 0;
279
280 for(G4int i=0;i<nDigi;i++) {
281 BesEmcDigi *digi = (*vecDC)[i];
282 double eDigi = digi->GetEnergy();
283 if(eDigi>eMax) {
284 eMax = eDigi;
285 partMax = digi->GetPartId();
286 thetaMax = digi->GetThetaNb();
287 phiMax = digi->GetPhiNb();
288 }
289 }
290
291 if(partMax==1) { // barrel
292 G4int thetan,thetap,phin,phip;
293 thetan = thetaMax-2;
294 thetap = thetaMax+2;
295 phin = phiMax-2;
296 phip = phiMax+2;
297
298 if(thetaMax==0) { // #0
299 thetan = thetaMax;
300 } else if(thetaMax==1) { // #1
301 thetan = thetaMax-1;
302 } else if(thetaMax==emcPara.GetBSCNbTheta()*2-1) { // #43
303 thetap = thetaMax;
304 } else if(thetaMax==emcPara.GetBSCNbTheta()*2-2) { // #42
305 thetap = thetaMax+1;
306 }
307
308 if(phiMax==0) {
309 phin = emcPara.GetBSCNbPhi()-2;
310 } else if(phiMax==1) {
311 phin = emcPara.GetBSCNbPhi()-2;
312 } else if(phiMax==emcPara.GetBSCNbPhi()-1) { // #119
313 phip = 1;
314 } else if(phiMax==emcPara.GetBSCNbPhi()-2) { // #118
315 phip = 0;
316 }
317
318 for(G4int theta=thetan;theta<=thetap;theta++) {
319 for(G4int phi=phin;phi<=phip;phi++) {
320 G4bool flag = true;
321
322 if(nDigi>0) {
323 for(G4int i=0;i<nDigi;i++) {
324 BesEmcDigi *digi = (*vecDC)[i];
325 if( partMax == digi->GetPartId()
326 && theta == digi->GetThetaNb()
327 && phi == digi->GetPhiNb() ) {
328 flag=false;
329 break;
330 }
331 }
332 }
333
334 if(flag) {
335 BesEmcDigi *digi = new BesEmcDigi;
336 BesEmcWaveform *wave = digi->GetWaveform();
337 digi->SetPartId(partMax);
338 digi->SetThetaNb(theta);
339 digi->SetPhiNb(phi);
340 digi->SetEnergy(0);
341 digi->SetTime(m_G4Svc->EmcTime());
342 digi->SetTrackIndex(-9);
343
344 wave->updateWaveform(digi);
345 wave->addElecNoise(m_G4Svc->EmcIncoherentNoise(),coherentNoise);
346 wave->digitize();
347
348 G4long bin = 0; //time
349 m_energy = wave->max(bin);
350
351 if(m_G4Svc->EmcLightOutput()) {
352 m_energy *= emcPara.GetLightOutput(partMax,theta,phi);
353 }
354
355 digi->SetEnergy(m_energy);
356 digi->SetTime(bin);
357 digi->SetWaveform(wave);
358
359 //Correction of electronics bias
360 G4double ecorr;
361 if(m_energy<625.) {
362 ecorr = -0.1285*log(m_energy/6805.); //noise=0.5
363 } else {
364 ecorr = -2.418+9.513e-4*m_energy;
365 }
366
367 if(m_energy-ecorr>m_G4Svc->EmcNoiseThreshold()) {
368 m_besEmcDigitsCollection->insert(digi);
369 } else {
370 delete digi;
371 }
372 }
373 } //phi
374 } //theta
375
376 } //part==1
377}
378
379void BesEmcDigitizer::AddNoiseAll(G4double coherentNoise)
380{
382 vector<BesEmcDigi*>* vecDC = m_besEmcDigitsCollection->GetVector();
383 G4int nDigi = m_besEmcDigitsCollection->entries();
384 //G4cout<<"nDigi="<<nDigi<<G4endl;
385
386 for(G4int part=0;part<3;part++) {
387
388 G4int thetaNb;
389 if(part == 1) { //barrel
390 thetaNb = emcPara.GetBSCNbTheta()*2;
391 } else { //endcap
392 thetaNb = 6;
393 }
394
395 for(G4int theta=0;theta<thetaNb;theta++) {
396
397 G4int phiNb;
398 if(part == 1) {
399 phiNb = emcPara.GetBSCNbPhi();
400 } else {
401 phiNb = emcPara.GetCryInOneLayer(theta);
402 }
403
404 for(G4int phi=0;phi<phiNb;phi++) {
405
406 G4bool flag = true;
407
408 if(nDigi>0) {
409 //G4cout<<"nDigi="<<nDigi<<"\t";
410
411 for(G4int i=0;i<nDigi;i++) {
412 BesEmcDigi *digi = (*vecDC)[i];
413 if( part == digi->GetPartId()
414 && theta == digi->GetThetaNb()
415 && phi == digi->GetPhiNb() ) {
416 //cout<<theta<<"\t"<<phi<<endl;
417 flag=false;
418 break;
419 }
420 }
421 }
422
423 if(flag) {
424 BesEmcDigi *digi = new BesEmcDigi;
425 digi->SetTrackIndex(-9);
426 digi->SetPartId(part);
427 digi->SetThetaNb(theta);
428 digi->SetPhiNb(phi);
429
430 bool fastSimulation = true;
431 if(fastSimulation) {
432
433 m_energy = RandGauss::shoot()*m_G4Svc->EmcNoiseSigma();
434 m_energy += m_G4Svc->EmcNoiseMean();
435 digi->SetTime((G4int)(G4UniformRand()*60));
436
437 } else {
438
439 BesEmcWaveform *wave = digi->GetWaveform();
440 digi->SetTime(m_G4Svc->EmcTime());
441
442 wave->updateWaveform(digi);
443 wave->addElecNoise(m_G4Svc->EmcIncoherentNoise(),coherentNoise);
444 wave->digitize();
445
446 G4long bin = 0; //time
447 m_energy = wave->max(bin);
448 digi->SetTime(bin);
449 digi->SetWaveform(wave);
450 }
451
452 if(m_G4Svc->EmcLightOutput()) {
453 m_energy *= emcPara.GetLightOutput(part,theta,phi);
454 }
455 digi->SetEnergy(m_energy);
456
457 //Correction of electronics bias
458 G4double ecorr;
459 if(m_energy<625.) {
460 ecorr = -0.1285*log(m_energy/6805.); //noise=0.5
461 } else {
462 ecorr = -2.418+9.513e-4*m_energy;
463 }
464
465 if(m_energy-ecorr>m_G4Svc->EmcNoiseThreshold()) {
466 m_besEmcDigitsCollection->insert(digi);
467 } else {
468 delete digi;
469 }
470 }
471
472 } //phi
473 } //theta
474 } //part
475}
G4TDigiCollection< BesEmcDigi > BesEmcDigitsCollection
Definition: BesEmcDigi.hh:69
G4THitsCollection< BesEmcHit > BesEmcHitsCollection
Definition: BesEmcHit.hh:83
const int nPhi
*******INTEGER m_nBinMax INTEGER m_NdiMax !No of bins in histogram for cell exploration division $ !Last vertex $ !Last active cell $ !Last cell in buffer $ !No of sampling when dividing cell $ !No of function total $ !Flag for random ceel for $ !Flag for type of for WtMax $ !Flag which decides whether vertices are included in the sampling $ entire domain is hyp !Maximum effective eevents per bin
Definition: FoamA.h:85
************Class m_ypar INTEGER m_KeyWgt INTEGER m_nphot INTEGER m_KeyGPS INTEGER m_IsBeamPolarized INTEGER m_EvtGenInterface DOUBLE PRECISION m_Emin DOUBLE PRECISION m_sphot DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_q2 DOUBLE PRECISION m_PolBeam2 DOUBLE PRECISION m_xErrPb *COMMON c_KK2f $ !CMS energy average $ !Spin Polarization vector first beam $ !Spin Polarization vector second beam $ !Beam energy spread[GeV] $ !minimum hadronization energy[GeV] $ !input READ never touch them !$ !debug facility $ !maximum weight $ !inverse alfaQED $ !minimum real photon energy
Definition: KK2f.h:50
void SetTrackIndex(G4int index)
Definition: BesEmcDigi.hh:46
void SetTime(G4double time)
Definition: BesEmcDigi.hh:45
void SetPartId(G4int id)
Definition: BesEmcDigi.hh:41
void SetEnergy(G4double energy)
Definition: BesEmcDigi.hh:44
void SetThetaNb(G4int nTheta)
Definition: BesEmcDigi.hh:42
BesEmcWaveform * GetWaveform()
Definition: BesEmcDigi.hh:55
void SetWaveform(BesEmcWaveform *wave)
Definition: BesEmcDigi.hh:47
void SetPhiNb(G4int nPhi)
Definition: BesEmcDigi.hh:43
G4int GetThetaNb()
Definition: BesEmcDigi.hh:50
G4double GetEnergy()
Definition: BesEmcDigi.hh:52
G4int GetPhiNb()
Definition: BesEmcDigi.hh:51
G4int GetPartId()
Definition: BesEmcDigi.hh:49
virtual void AddNoiseAll(G4double coherentNoise)
virtual void AddNoise5x5(G4double coherentNoise)
virtual void GroupHits(BesEmcHitsCollection *)
virtual void Digitize()
BesEmcDigitizer(G4String modName)
G4int GetNumPhiCrystal()
Definition: BesEmcHit.hh:63
G4double GetEdepCrystal()
Definition: BesEmcHit.hh:56
G4int GetTrackIndex()
Definition: BesEmcHit.hh:64
G4int GetNumThetaCrystal()
Definition: BesEmcHit.hh:62
G4int GetPartId()
Definition: BesEmcHit.hh:61
G4int GetCryInOneLayer(G4int nb)
static BesEmcParameter & GetInstance()
G4double GetLightOutput(G4int i)
void updateWaveform(BesEmcHit *)
void addElecNoise(G4double, G4double)
G4double max(G4long &binOfMax) const
void SetNTheta(G4int theta)
vector< G4int > * GetHitIndexes()
G4double GetEdep()
void SetNPhi(G4int phi)
void AddEdep(G4double e)
void SetPartId(G4int id)
void SetEdep(G4double e)
Definition: G4Svc.h:32
bool EmcLightOutput()
Definition: G4Svc.h:124
double EmcNoiseSigma()
Definition: G4Svc.h:128
double EmcNoiseThreshold()
Definition: G4Svc.h:129
bool EmcRootFlag()
Definition: G4Svc.h:119
double EmcNoiseMean()
Definition: G4Svc.h:127
double EmcIncoherentNoise()
Definition: G4Svc.h:125
double EmcCoherentNoise()
Definition: G4Svc.h:126
NTuple::Tuple * GetTupleEmc2()
Definition: G4Svc.h:111
int EmcNoiseLevel()
Definition: G4Svc.h:130
NTuple::Tuple * GetTupleEmc1()
Definition: G4Svc.h:108
int EmcTime()
Definition: G4Svc.h:131
virtual double getDigiCalibConst(int No) const =0
virtual int getIndex(unsigned int PartId, unsigned int ThetaIndex, unsigned int PhiIndex) const =0
Definition: IG4Svc.h:30