CMS 3D CMS Logo

EcalHitResponse.cc
Go to the documentation of this file.
13 #include "CLHEP/Random/RandPoissonQ.h"
15 
16 #include <CLHEP/Units/GlobalPhysicalConstants.h>
17 #include <CLHEP/Units/SystemOfUnits.h>
18 #include <iostream>
19 
21  : m_parameterMap(parameterMap),
22  m_shape(shape),
23  m_hitCorrection(nullptr),
24  m_PECorrection(nullptr),
25  m_hitFilter(nullptr),
26  m_geometry(nullptr),
27  m_lasercals(nullptr),
28  m_minBunch(-32),
29  m_maxBunch(10),
30  m_phaseShift(1),
31  m_iTime(0),
32  m_useLCcorrection(false) {}
33 
35 
37  assert(nullptr != m_parameterMap);
39 }
40 
42  assert(nullptr != m_shape);
43  return m_shape;
44 }
45 
47  assert(nullptr != m_geometry);
48  return m_geometry;
49 }
50 
54 }
55 
57 
59 
60 double EcalHitResponse::phaseShift() const { return m_phaseShift; }
61 
63 
64 void EcalHitResponse::setHitCorrection(const CaloVHitCorrection* hitCorrection) { m_hitCorrection = hitCorrection; }
65 
66 void EcalHitResponse::setPECorrection(const CaloVPECorrection* peCorrection) { m_PECorrection = peCorrection; }
67 
69  m_iTime = iTime;
70  //clear the laser cache for each event time
72 }
73 
74 void EcalHitResponse::setLaserConstants(const EcalLaserDbService* laser, bool& useLCcorrection) {
76  m_useLCcorrection = useLCcorrection;
77 }
78 
79 void EcalHitResponse::blankOutUsedSamples() // blank out previously used elements
80 {
81  const unsigned int size(m_index.size());
82 
83  for (unsigned int i(0); i != size; ++i) {
84  vSamAll(m_index[i])->setZero();
85  }
86  m_index.erase(m_index.begin(), // done and make ready to start over
87  m_index.end());
88 }
89 
90 void EcalHitResponse::add(const PCaloHit& hit, CLHEP::HepRandomEngine* engine) {
91  if (!edm::isNotFinite(hit.time()) && (nullptr == m_hitFilter || m_hitFilter->accepts(hit))) {
92  putAnalogSignal(hit, engine);
93  }
94 }
95 
97  const DetId detId(hit.id());
98 
100 
101  const int rsize(result.size());
102 
103  if (rsize != hit.size()) {
104  throw cms::Exception("EcalDigitization") << "CaloSamples and EcalSamples have different sizes. Type Mismatach";
105  }
106 
107  for (int bin(0); bin != rsize; ++bin) {
108  result[bin] += hit[bin];
109  }
110 }
111 
112 bool EcalHitResponse::withinBunchRange(int bunchCrossing) const {
113  return (m_minBunch <= bunchCrossing && m_maxBunch >= bunchCrossing);
114 }
115 
117 
119 
120 void EcalHitResponse::run(MixCollection<PCaloHit>& hits, CLHEP::HepRandomEngine* engine) {
122 
123  for (MixCollection<PCaloHit>::MixItr hitItr(hits.begin()); hitItr != hits.end(); ++hitItr) {
124  const PCaloHit& hit(*hitItr);
125  const int bunch(hitItr.bunch());
126  if (withinBunchRange(bunch) && !edm::isNotFinite(hit.time()) &&
127  (nullptr == m_hitFilter || m_hitFilter->accepts(hit)))
128  putAnalogSignal(hit, engine);
129  }
130 }
131 
132 void EcalHitResponse::putAnalogSignal(const PCaloHit& hit, CLHEP::HepRandomEngine* engine) {
133  const DetId detId(hit.id());
134 
136 
137  const double signal(analogSignalAmplitude(detId, hit.energy(), engine));
138 
139  double time = hit.time();
140 
141  if (m_hitCorrection) {
142  time += m_hitCorrection->delay(hit, engine);
143  }
144 
145  const double jitter(time - timeOfFlight(detId));
146 
147  const double tzero = (shape()->timeToRise() + parameters->timePhase() - jitter -
148  kSamplePeriod * (parameters->binOfMaximum() - m_phaseShift));
149  double binTime(tzero);
150 
152 
153  const unsigned int rsize(result.size());
154 
155  for (unsigned int bin(0); bin != rsize; ++bin) {
156  result[bin] += (*shape())(binTime)*signal;
157  binTime += kSamplePeriod;
158  }
159 }
160 
162  const edm::Timestamp& evtTimeStamp = edm::Timestamp(m_iTime);
163  return (m_lasercals->getLaserCorrection(detId, evtTimeStamp));
164 }
165 
167  const unsigned int di(CaloGenericDetId(detId).denseIndex());
168  EcalSamples* result(vSamAll(di));
169  if (result->zero())
170  m_index.push_back(di);
171  return result;
172 }
173 
174 double EcalHitResponse::analogSignalAmplitude(const DetId& detId, double energy, CLHEP::HepRandomEngine* engine) {
176 
177  // OK, the "energy" in the hit could be a real energy, deposited energy,
178  // or pe count. This factor converts to photoelectrons
179 
180  double lasercalib = 1.;
181  if (m_useLCcorrection == true && detId.subdetId() != 3) {
182  auto cache = m_laserCalibCache.find(detId);
183  if (cache != m_laserCalibCache.end()) {
184  lasercalib = cache->second;
185  } else {
186  lasercalib = 1.0 / findLaserConstant(detId);
187  m_laserCalibCache.emplace(detId, lasercalib);
188  }
189  }
190 
191  double npe(energy * lasercalib * parameters.simHitToPhotoelectrons(detId));
192 
193  // do we need to doPoisson statistics for the photoelectrons?
194  if (parameters.doPhotostatistics()) {
195  npe = CLHEP::RandPoissonQ::shoot(engine, npe);
196  }
197  if (nullptr != m_PECorrection)
198  npe = m_PECorrection->correctPE(detId, npe, engine);
199 
200  return npe;
201 }
202 
204  auto cellGeometry(geometry()->getGeometry(detId));
205  assert(nullptr != cellGeometry);
206  return cellGeometry->getPosition().mag() * CLHEP::cm / c_light; // Units of c_light: mm/ns
207 }
208 
210  EcalSamples& sam(*findSignal(pSam->id()));
211  sam += (*pSam);
212 }
213 
214 int EcalHitResponse::minBunch() const { return m_minBunch; }
215 
216 int EcalHitResponse::maxBunch() const { return m_maxBunch; }
217 
219 
221 
223 
225  const unsigned int di(CaloGenericDetId(detId).denseIndex());
226  return vSamAll(di);
227 }
size
Write out results.
const CaloVShape * m_shape
const CaloSubdetectorGeometry * geometry() const
double findLaserConstant(const DetId &detId) const
virtual void run(MixCollection< PCaloHit > &hits, CLHEP::HepRandomEngine *)
double analogSignalAmplitude(const DetId &id, double energy, CLHEP::HepRandomEngine *)
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
const CaloSimParameters * params(const DetId &detId) const
void setEventTime(const edm::TimeValue_t &iTime)
virtual ~EcalHitResponse()
edm::TimeValue_t m_iTime
virtual void initializeHits()
virtual void putAnalogSignal(const PCaloHit &inputHit, CLHEP::HepRandomEngine *)
Electronic response of the preamp.
Definition: CaloVShape.h:11
bool withinBunchRange(int bunchCrossing) const
assert(be >=bs)
Main class for Parameters in different subdetectors.
void setHitFilter(const CaloVHitFilter *filter)
virtual double correctPE(const DetId &detId, double npe, CLHEP::HepRandomEngine *) const =0
void setHitCorrection(const CaloVHitCorrection *hitCorrection)
void setBunchRange(int minBunch, int maxBunch)
double timeOfFlight(const DetId &detId) const
void setLaserConstants(const EcalLaserDbService *laser, bool &useLCcorrection)
std::unordered_map< uint32_t, double > CalibCache
DetId id() const
EcalHitResponse(const CaloVSimParameterMap *parameterMap, const CaloVShape *shape)
std::vector< unsigned int > VecInd
void setPhaseShift(double phaseShift)
void blankOutUsedSamples()
const CaloVHitCorrection * m_hitCorrection
virtual double timeToRise() const =0
virtual const CaloSimParameters & simParameters(const DetId &id) const =0
virtual bool accepts(const PCaloHit &hit) const =0
float getLaserCorrection(DetId const &xid, edm::Timestamp const &iTime) const
const EcalLaserDbService * m_lasercals
unsigned long long TimeValue_t
Definition: Timestamp.h:21
virtual double delay(const PCaloHit &hit, CLHEP::HepRandomEngine *) const =0
void setGeometry(const CaloSubdetectorGeometry *geometry)
unsigned int id
Definition: DetId.h:17
const CaloSubdetectorGeometry * m_geometry
double phaseShift() const
const CaloVSimParameterMap * m_parameterMap
void setPECorrection(const CaloVPECorrection *peCorrection)
const CaloVPECorrection * m_PECorrection
CalibCache m_laserCalibCache
const CaloVHitFilter * hitFilter() const
def cache(function)
Definition: utilities.py:3
static const double tzero[3]
EcalSamples * findSignal(const DetId &detId)
int maxBunch() const
const EcalSamples * findDetId(const DetId &detId) const
int minBunch() const
virtual EcalSamples * vSamAll(unsigned int i)=0
void add(const EcalSamples *pSam)
const CaloVHitFilter * m_hitFilter
virtual void finalizeHits()
const float kSamplePeriod
const CaloVShape * shape() const