BOSS 7.0.5
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"
22#include "EmcCalibConstSvc/EmcCalibConstSvc.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
167
168 if (m_G4Svc->EmcElecSaturation()==1){
169 G4double emaxData = m_emcCalibConstSvc->getCrystalEmaxData(index);
170
171 if (emaxData>0) {
172
173 adc2e=emaxData/2.5;
174 }
175 }
176
177 if(adc2e<=1e-5) // dead channel
178 {
179 m_energy = 0;
180 }
181 else
182 {
183
184 m_energy /= adc2e;
185
186
187 //m_energy /= emcPara.GetLightOutput(partId,nTheta,nPhi);
188 }
189 }
190
191 //fill Emc Ntuple1
192 if(m_G4Svc->EmcRootFlag())
193 {
194 m_partId = partId;
195 m_nTheta = nTheta;
196 m_nPhi = nPhi;
197 m_eDep = eDigi;
198 m_nHits = nHits;
199 m_adc = m_energy;
200 m_tdc = bin;
201 m_tupleEmc1->write();
202 }
203
204 digi->SetEnergy(m_energy);
205 digi->SetTime(bin);
206 digi->SetWaveform(wave);
207 m_besEmcDigitsCollection->insert(digi);
208 }
209 }
210
211 //add to noise to no signal crystals
212 if(m_G4Svc->EmcNoiseLevel()==2)
213 AddNoise5x5(coherentNoise);
214 else if(m_G4Svc->EmcNoiseLevel()==3)
215 ;
216 //AddNoiseAll(coherentNoise);
217
218 //fill Emc Ntuple2
219 if(m_G4Svc->EmcRootFlag())
220 {
221 m_eTot = eTot;
222 m_nDigi = size;
223 m_tupleEmc2->write();
224 }
225
226 StoreDigiCollection(m_besEmcDigitsCollection);
227
228 for(size_t i=0;i<m_crystalGroup->size();i++)
229 {
230 delete (*m_crystalGroup)[i];
231 }
232 m_crystalGroup->clear();
233 delete m_crystalGroup;
234 }
235}
236
238{
239 G4int partId, nTheta, nPhi, size, flag;
240 G4double edep;
241 BesEmcHit* hit;
242 G4int nHits = m_EHC->entries();
243
244 //group the hits which are in the same crystal
245 for(G4int i=0;i<nHits;i++)
246 {
247 hit = (*m_EHC)[i];
248 partId = hit->GetPartId();
249 nTheta = hit->GetNumThetaCrystal();
250 nPhi = hit->GetNumPhiCrystal();
251 edep = hit->GetEdepCrystal();
252 size = m_crystalGroup->size();
253 flag=0;
254
255 if(size>0)
256 {
257 CrystalSingle* oldCryst;
258 for(G4int j=0; j<size;j++)
259 {
260 oldCryst = (*m_crystalGroup)[j];
261 if((oldCryst->GetNTheta()==nTheta)&&(oldCryst->GetNPhi()==nPhi)&&(oldCryst->GetPartId()==partId))
262 {
263 oldCryst->GetHitIndexes()->push_back(i);
264 oldCryst->AddEdep(edep);
265 flag=1;
266 break;
267 }
268 }
269 }
270
271 if(flag==0)
272 {
273 CrystalSingle* newCryst = new CrystalSingle;
274 newCryst->SetPartId(partId);
275 newCryst->SetNTheta(nTheta);
276 newCryst->SetNPhi(nPhi);
277 newCryst->SetEdep(edep);
278 newCryst->GetHitIndexes()->push_back(i);
279 m_crystalGroup->push_back(newCryst);
280 }
281
282 }
283}
284
285void BesEmcDigitizer::AddNoise5x5(G4double coherentNoise)
286{
288 vector<BesEmcDigi*>* vecDC = m_besEmcDigitsCollection->GetVector();
289 G4int nDigi = m_besEmcDigitsCollection->entries();
290 G4int partMax,thetaMax,phiMax;
291 partMax=thetaMax=phiMax=-99;
292 G4double eMax = 0;
293
294 for(G4int i=0;i<nDigi;i++) {
295 BesEmcDigi *digi = (*vecDC)[i];
296 double eDigi = digi->GetEnergy();
297 if(eDigi>eMax) {
298 eMax = eDigi;
299 partMax = digi->GetPartId();
300 thetaMax = digi->GetThetaNb();
301 phiMax = digi->GetPhiNb();
302 }
303 }
304
305 if(partMax==1) { // barrel
306 G4int thetan,thetap,phin,phip;
307 thetan = thetaMax-2;
308 thetap = thetaMax+2;
309 phin = phiMax-2;
310 phip = phiMax+2;
311
312 if(thetaMax==0) { // #0
313 thetan = thetaMax;
314 } else if(thetaMax==1) { // #1
315 thetan = thetaMax-1;
316 } else if(thetaMax==emcPara.GetBSCNbTheta()*2-1) { // #43
317 thetap = thetaMax;
318 } else if(thetaMax==emcPara.GetBSCNbTheta()*2-2) { // #42
319 thetap = thetaMax+1;
320 }
321
322 if(phiMax==0) {
323 phin = emcPara.GetBSCNbPhi()-2;
324 } else if(phiMax==1) {
325 phin = emcPara.GetBSCNbPhi()-2;
326 } else if(phiMax==emcPara.GetBSCNbPhi()-1) { // #119
327 phip = 1;
328 } else if(phiMax==emcPara.GetBSCNbPhi()-2) { // #118
329 phip = 0;
330 }
331
332 for(G4int theta=thetan;theta<=thetap;theta++) {
333 for(G4int phi=phin;phi<=phip;phi++) {
334 G4bool flag = true;
335
336 if(nDigi>0) {
337 for(G4int i=0;i<nDigi;i++) {
338 BesEmcDigi *digi = (*vecDC)[i];
339 if( partMax == digi->GetPartId()
340 && theta == digi->GetThetaNb()
341 && phi == digi->GetPhiNb() ) {
342 flag=false;
343 break;
344 }
345 }
346 }
347
348 if(flag) {
349 BesEmcDigi *digi = new BesEmcDigi;
350 BesEmcWaveform *wave = digi->GetWaveform();
351 digi->SetPartId(partMax);
352 digi->SetThetaNb(theta);
353 digi->SetPhiNb(phi);
354 digi->SetEnergy(0);
355 digi->SetTime(m_G4Svc->EmcTime());
356 digi->SetTrackIndex(-9);
357
358 wave->updateWaveform(digi);
359 wave->addElecNoise(m_G4Svc->EmcIncoherentNoise(),coherentNoise);
360 wave->digitize();
361
362 G4long bin = 0; //time
363 m_energy = wave->max(bin);
364
365 if(m_G4Svc->EmcLightOutput()) {
366 m_energy *= emcPara.GetLightOutput(partMax,theta,phi);
367 }
368
369 digi->SetEnergy(m_energy);
370 digi->SetTime(bin);
371 digi->SetWaveform(wave);
372
373 //Correction of electronics bias
374 G4double ecorr;
375 if(m_energy<625.) {
376 ecorr = -0.1285*log(m_energy/6805.); //noise=0.5
377 } else {
378 ecorr = -2.418+9.513e-4*m_energy;
379 }
380
381 if(m_energy-ecorr>m_G4Svc->EmcNoiseThreshold()) {
382 m_besEmcDigitsCollection->insert(digi);
383 } else {
384 delete digi;
385 }
386 }
387 } //phi
388 } //theta
389
390 } //part==1
391}
392
393void BesEmcDigitizer::AddNoiseAll(G4double coherentNoise)
394{
396 vector<BesEmcDigi*>* vecDC = m_besEmcDigitsCollection->GetVector();
397 G4int nDigi = m_besEmcDigitsCollection->entries();
398 //G4cout<<"nDigi="<<nDigi<<G4endl;
399
400 for(G4int part=0;part<3;part++) {
401
402 G4int thetaNb;
403 if(part == 1) { //barrel
404 thetaNb = emcPara.GetBSCNbTheta()*2;
405 } else { //endcap
406 thetaNb = 6;
407 }
408
409 for(G4int theta=0;theta<thetaNb;theta++) {
410
411 G4int phiNb;
412 if(part == 1) {
413 phiNb = emcPara.GetBSCNbPhi();
414 } else {
415 phiNb = emcPara.GetCryInOneLayer(theta);
416 }
417
418 for(G4int phi=0;phi<phiNb;phi++) {
419
420 G4bool flag = true;
421
422 if(nDigi>0) {
423 //G4cout<<"nDigi="<<nDigi<<"\t";
424
425 for(G4int i=0;i<nDigi;i++) {
426 BesEmcDigi *digi = (*vecDC)[i];
427 if( part == digi->GetPartId()
428 && theta == digi->GetThetaNb()
429 && phi == digi->GetPhiNb() ) {
430 //cout<<theta<<"\t"<<phi<<endl;
431 flag=false;
432 break;
433 }
434 }
435 }
436
437 if(flag) {
438 BesEmcDigi *digi = new BesEmcDigi;
439 digi->SetTrackIndex(-9);
440 digi->SetPartId(part);
441 digi->SetThetaNb(theta);
442 digi->SetPhiNb(phi);
443
444 bool fastSimulation = true;
445 if(fastSimulation) {
446
447 m_energy = RandGauss::shoot()*m_G4Svc->EmcNoiseSigma();
448 m_energy += m_G4Svc->EmcNoiseMean();
449 digi->SetTime((G4int)(G4UniformRand()*60));
450
451 } else {
452
453 BesEmcWaveform *wave = digi->GetWaveform();
454 digi->SetTime(m_G4Svc->EmcTime());
455
456 wave->updateWaveform(digi);
457 wave->addElecNoise(m_G4Svc->EmcIncoherentNoise(),coherentNoise);
458 wave->digitize();
459
460 G4long bin = 0; //time
461 m_energy = wave->max(bin);
462 digi->SetTime(bin);
463 digi->SetWaveform(wave);
464 }
465
466 if(m_G4Svc->EmcLightOutput()) {
467 m_energy *= emcPara.GetLightOutput(part,theta,phi);
468 }
469 digi->SetEnergy(m_energy);
470
471 //Correction of electronics bias
472 G4double ecorr;
473 if(m_energy<625.) {
474 ecorr = -0.1285*log(m_energy/6805.); //noise=0.5
475 } else {
476 ecorr = -2.418+9.513e-4*m_energy;
477 }
478
479 if(m_energy-ecorr>m_G4Svc->EmcNoiseThreshold()) {
480 m_besEmcDigitsCollection->insert(digi);
481 } else {
482 delete digi;
483 }
484 }
485
486 } //phi
487 } //theta
488 } //part
489}
*******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
G4TDigiCollection< BesEmcDigi > BesEmcDigitsCollection
G4THitsCollection< BesEmcHit > BesEmcHitsCollection
************Class m_ypar INTEGER m_KeyWgt INTEGER m_KeyIHVP 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 SetWaveform(BesEmcWaveform *wave)
virtual void AddNoiseAll(G4double coherentNoise)
virtual void AddNoise5x5(G4double coherentNoise)
virtual void GroupHits(BesEmcHitsCollection *)
virtual void Digitize()
BesEmcDigitizer(G4String modName)
static BesEmcParameter & GetInstance()
void updateWaveform(BesEmcHit *)
void addElecNoise(G4double, G4double)
G4double max(G4long &binOfMax) const
NTuple::Tuple * GetTupleEmc2()
NTuple::Tuple * GetTupleEmc1()
virtual double getDigiCalibConst(int No) const =0
virtual int getIndex(unsigned int PartId, unsigned int ThetaIndex, unsigned int PhiIndex) const =0
virtual double getCrystalEmaxData(int Index) const =0