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