ATLAS Offline Software
LUCID_DigitizationToolBox.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
8 #include <algorithm>
9 #include <utility>
10 
11 #include "CLHEP/Random/RandFlat.h"
12 #include "CLHEP/Random/RandGaussQ.h"
13 #include "CLHEP/Random/RandPoissonQ.h"
14 #include "GaudiKernel/MsgStream.h"
15 
16 //--------------------------------------------------------------------------
18  m_tubeID(0),
19  m_npe (0),
20  m_npeGas(0),
21  m_npePmt(0),
22  m_qdc (0),
23  m_tdcTot(0),
24  m_tdc (0)
25 {
26  m_digitContainer = nullptr;
27  m_tubeInfo = nullptr;
28 
29  m_numTubes = 0;
31  m_qdcPedestal = 0;
35 
36  m_TotalPMTgain = 0;
37  m_AmpFactor = 0;
38  m_Q1bin = 0;
39  m_NoiseCharge = 0;
40  m_numDyinodes = 0;
42  m_gainPerDynode = 0;
44 
45  m_fillRootTree = 0;
46 }
47 
48 //--------------------------------------------------------------------------
50  double qdcChannelsPerPE,
51  double qdcPedestal,
52  double qdcFedNoiseFactor,
53  double tdcPmtNoiseFactor,
54  double tdcFedNoiseFactor,
55  double TotalPMTgain,
56  double AmpFactor,
57  double Q1bin,
58  int NoiseCharge,
59  int numDyinodes,
60  double dynodeGammaFactor,
61  std::vector<double> pmtSmearing,
62  std::vector<double> pmtScaling,
63  std::vector<double> gasScaling,
64  std::vector<double> npeThreshold,
65  bool fillRootTree):
66  m_numTubes (numTubes),
67  m_qdcChannelsPerPE (qdcChannelsPerPE),
68  m_qdcPedestal (qdcPedestal),
69  m_qdcFedNoiseFactor (qdcFedNoiseFactor),
70  m_tdcPmtNoiseFactor (tdcPmtNoiseFactor),
71  m_tdcFedNoiseFactor (tdcFedNoiseFactor),
72  m_TotalPMTgain (TotalPMTgain),
73  m_AmpFactor (AmpFactor),
74  m_Q1bin (Q1bin),
75  m_NoiseCharge (NoiseCharge),
76  m_numDyinodes (numDyinodes),
77  m_dynodeGammaFactor (dynodeGammaFactor),
78  m_pmtSmearing (std::move(pmtSmearing)),
79  m_pmtScaling (std::move(pmtScaling)),
80  m_gasScaling (std::move(gasScaling)),
81  m_npeThreshold (std::move(npeThreshold)),
82  m_fillRootTree (fillRootTree),
83  m_tubeID (0),
84  m_npe (0),
85  m_npeGas (0),
86  m_npePmt (0),
87  m_qdc (0),
88  m_tdcTot (0),
89  m_tdc (0)
90 {
93 
94  m_digitContainer = nullptr;
95  m_tubeInfo = nullptr;
96 }
97 
98 //--------------------------------------------------------------------------
100 
101  m_tubeInfo = new TTree("t", "LUCID_LUMI_SUMMARY");
102 
103  StatusCode sc = digitHistSvc->regTree("/AANT/LUCID_LUMI_SUMMARY", m_tubeInfo);
104 
105  if (sc.isFailure()) return StatusCode::FAILURE;
106 
107  m_tubeInfo->Branch("tubeID", &m_tubeID, "tubeID/s");
108  m_tubeInfo->Branch("npe" , &m_npe , "npe/D");
109  m_tubeInfo->Branch("npeGas", &m_npeGas, "npeGas/s");
110  m_tubeInfo->Branch("npePmt", &m_npePmt, "npePmt/s");
111  m_tubeInfo->Branch("qdc" , &m_qdc , "qdc/s");
112  m_tubeInfo->Branch("tdc" , &m_tdc , "tdc/s");
113 
114  return StatusCode::SUCCESS;
115 }
116 
117 //--------------------------------------------------------------------------
119 
120  assert(x >= INT_MIN-0.5);
121  assert(x <= INT_MAX+0.5);
122 
123  if (x >= 0) return static_cast<int>(x+0.5);
124 
125  return static_cast<int>(x-0.5);
126 }
127 
128 //--------------------------------------------------------------------------
129 StatusCode LUCID_DigitizationToolBox::createAndStoreDigit(unsigned short tubeID, CLHEP::HepRandomEngine* rndEngine) {
130 
131  double npePmt = m_npePmt * m_pmtScaling[tubeID] * CLHEP::RandGaussQ::shoot(rndEngine, 1, m_pmtSmearing[tubeID]);
132  double npeGas = m_npeGas * m_gasScaling[tubeID];
133  double npeTot = npeGas + npePmt;
134  double qdcSmeared = DynodeChainSimulation(npeTot, rndEngine);
135 
136  m_qdc = roundoff(qdcSmeared);
137 
139 
140  double tdcTotSmeared = 0;
141 
142  tdcTotSmeared = CLHEP::RandGaussQ::shoot(rndEngine, m_tdcTot , m_tdcPmtNoiseFactor);
143  tdcTotSmeared = CLHEP::RandGaussQ::shoot(rndEngine, tdcTotSmeared, m_tdcFedNoiseFactor);
144  tdcTotSmeared = (npeTot) ? tdcTotSmeared/npeTot : tdcTotSmeared;
145  tdcTotSmeared = (tdcTotSmeared < 0) ? 0 : tdcTotSmeared;
146 
147  m_tdc = static_cast<unsigned int>(tdcTotSmeared);
148 
149  if (m_fillRootTree) m_tubeInfo->Fill();
150 
152  m_npe,
153  m_npeGas,
154  m_npePmt,
155  m_qdc,
156  m_tdc,
157  m_npe > m_npeThreshold[tubeID]));
158  return StatusCode::SUCCESS;
159 }
160 
163 
164  for (m_tubeID = 0; m_tubeID < m_numTubes; m_tubeID++) {
165 
166  if (m_tubeID >= 16 && m_tubeID <= 19) continue; // skip fiber tubes on sideA
167  if (m_tubeID >= 36 && m_tubeID <= 39) continue; // skip fiber tubes on sideC
168 
169  m_npe = m_npeGas = m_npePmt = m_qdc = m_tdc = m_tdcTot = 0;
170 
171  TimedHitCollection<LUCID_SimHit> thpc = thpclucid;
173 
174  while (thpc.nextDetectorElement(i, e)) for (hitIt = i; hitIt != e; ++hitIt) {
175 
176  if (m_tubeID != (*hitIt)->GetTubeID()) continue;
177 
178  if (!(*hitIt)->isDetected(rndEngine)) continue; // applying quantum efficiency
179 
180  if ((*hitIt)->GetGenVolume() == 1) m_npeGas++;
181  if ((*hitIt)->GetGenVolume() == 2) m_npeGas++;
182  if ((*hitIt)->GetGenVolume() == 3) m_npePmt++;
183 
184  m_tdcTot += (*hitIt)->GetPreStepTime();
185  }
186 
187  if (createAndStoreDigit(m_tubeID, rndEngine).isFailure()) return StatusCode::FAILURE;
188  }
189 
190  return StatusCode::SUCCESS;
191 
192 }
193 
196 
197  for (m_tubeID = 0; m_tubeID < m_numTubes; m_tubeID++) {
198 
199  if (m_tubeID >= 16 && m_tubeID <= 19) continue; // skip fiber tubes on sideA
200  if (m_tubeID >= 36 && m_tubeID <= 39) continue; // skip fiber tubes on sideC
201 
202  m_npe = m_npeGas = m_npePmt = m_qdc = m_tdc = m_tdcTot = 0;
203 
204  LUCID_SimHitCollection::const_iterator hitIt = thpclucid->begin();
205  LUCID_SimHitCollection::const_iterator hitItE = thpclucid->end();
206 
207  for (; hitIt != hitItE; ++hitIt) {
208 
209  if (m_tubeID != (*hitIt).GetTubeID()) continue;
210 
211  if (!(*hitIt).isDetected(rndEngine)) continue; // applying quantum efficiency
212 
213  if ((*hitIt).GetGenVolume() == 1) m_npeGas++;
214  if ((*hitIt).GetGenVolume() == 2) m_npeGas++;
215  if ((*hitIt).GetGenVolume() == 3) m_npePmt++;
216 
217  m_tdcTot += (*hitIt).GetPreStepTime();
218  }
219 
220  if (createAndStoreDigit(m_tubeID, rndEngine).isFailure()) return StatusCode::FAILURE;
221  }
222 
223  return StatusCode::SUCCESS;
224 }
225 
226 
227 //--------------------------------------------------------------------------
228 StatusCode LUCID_DigitizationToolBox::recordContainers(const ServiceHandle<StoreGateSvc>& digitsStore, const std::string& key_digitCnt) {
229 
231 
232  StatusCode sc = digitsStore->record(m_digitContainer, key_digitCnt);
233 
234  return sc;
235 }
236 
237 //--------------------------------------------------------------------------
238 double LUCID_DigitizationToolBox::DynodeChainSimulation(double npe, CLHEP::HepRandomEngine* rndEngine) const{
239 
240  double smearedQDC = 0;
241 
242  if (npe == 0) return CLHEP::RandGaussQ::shoot(rndEngine, npe, m_ChargeToQdcFactor * m_NoiseCharge) + m_qdcPedestal;
243 
244  for (int i_pe=1; i_pe <= m_numDyinodes; i_pe++ ) {
245 
246  if (i_pe == 1) smearedQDC = DynodeGainSmearing(npe * m_gainPerDynode * m_dynodeGammaFactor, rndEngine);
247  else smearedQDC = DynodeGainSmearing(smearedQDC * m_gainPerDynode , rndEngine);
248  }
249 
250  smearedQDC = smearedQDC*m_ChargeToQdcFactor;
251 
252  return static_cast<double>(CLHEP::RandGaussQ::shoot(rndEngine, smearedQDC, m_NoiseCharge * m_ChargeToQdcFactor)) + m_qdcPedestal;
253 }
254 
255 //--------------------------------------------------------------------------
256 double LUCID_DigitizationToolBox::DynodeGainSmearing(double npe, CLHEP::HepRandomEngine* rndEngine){
257 
258  if (npe < 20) return CLHEP::RandPoissonQ::shoot(rndEngine, npe);
259  else return CLHEP::RandGaussQ::shoot (rndEngine, npe, std::sqrt(npe));
260 }
LUCID_DigitizationToolBox::m_numTubes
int m_numTubes
Definition: LUCID_DigitizationToolBox.h:62
LUCID_DigitizationToolBox::DynodeGainSmearing
static double DynodeGainSmearing(double npe, CLHEP::HepRandomEngine *rndEngine)
Definition: LUCID_DigitizationToolBox.cxx:256
LUCID_DigitizationToolBox::m_gainPerDynode
double m_gainPerDynode
Definition: LUCID_DigitizationToolBox.h:76
LUCID_DigitContainer
Definition: LUCID_DigitContainer.h:13
LUCID_DigitizationToolBox::LUCID_DigitizationToolBox
LUCID_DigitizationToolBox()
Definition: LUCID_DigitizationToolBox.cxx:17
LUCID_DigitizationToolBox::recordContainers
StatusCode recordContainers(const ServiceHandle< StoreGateSvc > &, const std::string &)
Definition: LUCID_DigitizationToolBox.cxx:228
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
LUCID_DigitizationToolBox::m_pmtSmearing
std::vector< double > m_pmtSmearing
Definition: LUCID_DigitizationToolBox.h:79
AtlasHitsVector
Definition: AtlasHitsVector.h:33
LUCID_DigitizationToolBox::m_gasScaling
std::vector< double > m_gasScaling
Definition: LUCID_DigitizationToolBox.h:81
LUCID_DigitizationToolBox::m_tdc
unsigned short m_tdc
Definition: LUCID_DigitizationToolBox.h:92
LUCID_DigitizationToolBox::m_tdcFedNoiseFactor
double m_tdcFedNoiseFactor
Definition: LUCID_DigitizationToolBox.h:67
LUCID_DigitizationToolBox::setDebugTree
StatusCode setDebugTree(ITHistSvc *)
Definition: LUCID_DigitizationToolBox.cxx:99
LUCID_DigitizationToolBox.h
AtlasHitsVector::begin
const_iterator begin() const
Definition: AtlasHitsVector.h:131
x
#define x
TimedHitCollection::nextDetectorElement
bool nextDetectorElement(const_iterator &b, const_iterator &e)
sets an iterator range with the hits of current detector element returns a bool when done
AtlasHitsVector::const_iterator
CONT::const_iterator const_iterator
Definition: AtlasHitsVector.h:43
LUCID_DigitizationToolBox::m_digitContainer
LUCID_DigitContainer * m_digitContainer
Definition: LUCID_DigitizationToolBox.h:60
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
LUCID_DigitizationToolBox::m_tdcTot
double m_tdcTot
Definition: LUCID_DigitizationToolBox.h:91
LUCID_DigitizationToolBox::m_npe
double m_npe
Definition: LUCID_DigitizationToolBox.h:87
LUCID_DigitizationToolBox::m_tubeInfo
TTree * m_tubeInfo
Definition: LUCID_DigitizationToolBox.h:94
LUCID_DigitizationToolBox::m_fillRootTree
bool m_fillRootTree
Definition: LUCID_DigitizationToolBox.h:84
LUCID_Digit
Definition: LUCID_Digit.h:8
lumiFormat.i
int i
Definition: lumiFormat.py:92
LUCID_DigitizationToolBox::m_Q1bin
double m_Q1bin
Definition: LUCID_DigitizationToolBox.h:71
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
LUCID_DigitizationToolBox::createAndStoreDigit
StatusCode createAndStoreDigit(unsigned short tubeID, CLHEP::HepRandomEngine *rndEngine)
Definition: LUCID_DigitizationToolBox.cxx:129
LUCID_DigitizationToolBox::m_npePmt
unsigned short m_npePmt
Definition: LUCID_DigitizationToolBox.h:89
LUCID_DigitizationToolBox::m_dynodeGammaFactor
double m_dynodeGammaFactor
Definition: LUCID_DigitizationToolBox.h:74
LUCID_DigitizationToolBox::fillDigitContainer
StatusCode fillDigitContainer(TimedHitCollection< LUCID_SimHit > &, CLHEP::HepRandomEngine *)
Definition: LUCID_DigitizationToolBox.cxx:162
LUCID_DigitizationToolBox::m_TotalPMTgain
double m_TotalPMTgain
Definition: LUCID_DigitizationToolBox.h:69
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
LUCID_DigitizationToolBox::roundoff
static unsigned int roundoff(double x)
Definition: LUCID_DigitizationToolBox.cxx:118
LUCID_DigitizationToolBox::m_qdc
unsigned short m_qdc
Definition: LUCID_DigitizationToolBox.h:90
LUCID_DigitizationToolBox::m_ChargeToQdcFactor
double m_ChargeToQdcFactor
Definition: LUCID_DigitizationToolBox.h:77
LUCID_DigitizationToolBox::m_NoiseCharge
int m_NoiseCharge
Definition: LUCID_DigitizationToolBox.h:72
LUCID_DigitizationToolBox::m_qdcPedestal
double m_qdcPedestal
Definition: LUCID_DigitizationToolBox.h:64
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
LUCID_DigitizationToolBox::m_tubeID
unsigned short m_tubeID
Definition: LUCID_DigitizationToolBox.h:86
LUCID_DigitizationToolBox::m_npeThreshold
std::vector< double > m_npeThreshold
Definition: LUCID_DigitizationToolBox.h:82
LUCID_DigitizationToolBox::m_qdcChannelsPerPE
double m_qdcChannelsPerPE
Definition: LUCID_DigitizationToolBox.h:63
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
LUCID_DigitizationToolBox::m_tdcPmtNoiseFactor
double m_tdcPmtNoiseFactor
Definition: LUCID_DigitizationToolBox.h:66
PileUpMergeSvc.h
the preferred mechanism to access information from the different event stores in a pileup job.
AtlasHitsVector::end
const_iterator end() const
Definition: AtlasHitsVector.h:134
LUCID_DigitizationToolBox::m_npeGas
unsigned short m_npeGas
Definition: LUCID_DigitizationToolBox.h:88
TimedHitCollection::const_iterator
TimedVector::const_iterator const_iterator
Definition: TimedHitCollection.h:20
LUCID_DigitizationToolBox::m_numDyinodes
int m_numDyinodes
Definition: LUCID_DigitizationToolBox.h:73
LUCID_DigitizationToolBox::m_AmpFactor
double m_AmpFactor
Definition: LUCID_DigitizationToolBox.h:70
LUCID_DigitizationToolBox::DynodeChainSimulation
double DynodeChainSimulation(double npe, CLHEP::HepRandomEngine *rndEngine) const
Definition: LUCID_DigitizationToolBox.cxx:238
LUCID_DigitizationToolBox::m_pmtScaling
std::vector< double > m_pmtScaling
Definition: LUCID_DigitizationToolBox.h:80
LUCID_DigitizationToolBox::m_qdcFedNoiseFactor
double m_qdcFedNoiseFactor
Definition: LUCID_DigitizationToolBox.h:65
TimedHitCollection
Definition: TimedHitCollection.h:15
ServiceHandle< StoreGateSvc >