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/GlobalSystemOfUnits.h"
18 #include <iostream>
19 
20 
21 
23  const CaloVShape* shape ) :
24  m_parameterMap ( parameterMap ) ,
25  m_shape ( shape ) ,
26  m_hitCorrection ( nullptr ) ,
27  m_PECorrection ( nullptr ) ,
28  m_hitFilter ( nullptr ) ,
29  m_geometry ( nullptr ) ,
30  m_lasercals ( nullptr ) ,
31  m_minBunch ( -32 ) ,
32  m_maxBunch ( 10 ) ,
33  m_phaseShift ( 1 ) ,
34  m_iTime ( 0 ) ,
35  m_useLCcorrection ( false )
36 {
37 }
38 
40 {
41 }
42 
43 const CaloSimParameters*
44 EcalHitResponse::params( const DetId& detId ) const
45 {
46  assert( nullptr != m_parameterMap ) ;
47  return &m_parameterMap->simParameters( detId ) ;
48 }
49 
50 const CaloVShape*
52 {
53  assert( nullptr != m_shape ) ;
54  return m_shape ;
55 }
56 
59 {
60  assert( nullptr != m_geometry ) ;
61  return m_geometry ;
62 }
63 
64 void
66  int maxBunch )
67 {
70 }
71 
72 void
74 {
76 }
77 
78 void
80 {
82 }
83 
84 double
86 {
87  return m_phaseShift ;
88 }
89 
90 void
92 {
94 }
95 
96 void
98 {
99  m_hitCorrection = hitCorrection ;
100 }
101 
102 void
104 {
105  m_PECorrection = peCorrection ;
106 }
107 
108 void
110 {
111  m_iTime = iTime;
112  //clear the laser cache for each event time
113  CalibCache().swap(m_laserCalibCache);
114 }
115 
116 void
117 EcalHitResponse::setLaserConstants(const EcalLaserDbService* laser, bool& useLCcorrection)
118 {
119  m_lasercals = laser;
120  m_useLCcorrection = useLCcorrection;
121 }
122 
123 void
124 EcalHitResponse::blankOutUsedSamples() // blank out previously used elements
125 {
126  const unsigned int size ( m_index.size() ) ;
127 
128  for( unsigned int i ( 0 ) ; i != size ; ++i )
129  {
130  vSamAll( m_index[i] )->setZero() ;
131  }
132  m_index.erase( m_index.begin() , // done and make ready to start over
133  m_index.end() ) ;
134 }
135 
136 void
137 EcalHitResponse::add( const PCaloHit& hit, CLHEP::HepRandomEngine* engine )
138 {
139  if (!edm::isNotFinite( hit.time() ) && ( nullptr == m_hitFilter || m_hitFilter->accepts( hit ) ) ) {
140  putAnalogSignal( hit, engine ) ;
141  }
142 }
143 
144 void
146 {
147  const DetId detId ( hit.id() ) ;
148 
149  EcalSamples& result ( *findSignal( detId ) ) ;
150 
151  const int rsize ( result.size() ) ;
152 
153  if(rsize != hit.size()) {
154  throw cms::Exception("EcalDigitization")
155  << "CaloSamples and EcalSamples have different sizes. Type Mismatach";
156  }
157 
158  for( int bin ( 0 ) ; bin != rsize ; ++bin )
159  {
160  result[ bin ] += hit[ bin ] ;
161  }
162 
163 }
164 
165 
166 bool
167 EcalHitResponse::withinBunchRange(int bunchCrossing) const
168 {
169  return(m_minBunch <= bunchCrossing && m_maxBunch >= bunchCrossing);
170 }
171 
172 void
174 {
176 }
177 
178 void
180 {
181 }
182 
183 void
184 EcalHitResponse::run( MixCollection<PCaloHit>& hits, CLHEP::HepRandomEngine* engine )
185 {
187 
188  for( MixCollection<PCaloHit>::MixItr hitItr ( hits.begin() ) ;
189  hitItr != hits.end() ; ++hitItr )
190  {
191  const PCaloHit& hit ( *hitItr ) ;
192  const int bunch ( hitItr.bunch() ) ;
193  if( withinBunchRange(bunch) &&
194  !edm::isNotFinite( hit.time() ) &&
195  ( nullptr == m_hitFilter ||
196  m_hitFilter->accepts( hit ) ) ) putAnalogSignal( hit, engine ) ;
197  }
198 
199 }
200 
201 void
202 EcalHitResponse::putAnalogSignal( const PCaloHit& hit, CLHEP::HepRandomEngine* engine )
203 {
204  const DetId detId ( hit.id() ) ;
205 
206  const CaloSimParameters* parameters ( params( detId ) ) ;
207 
208  const double signal ( analogSignalAmplitude( detId, hit.energy(), engine ) ) ;
209 
210  double time = hit.time();
211 
212  if(m_hitCorrection) {
213  time += m_hitCorrection->delay( hit, engine ) ;
214  }
215 
216  const double jitter ( time - timeOfFlight( detId ) ) ;
217 
218  const double tzero = ( shape()->timeToRise()
219  + parameters->timePhase()
220  - jitter
221  - BUNCHSPACE*( parameters->binOfMaximum()
222  - m_phaseShift ) ) ;
223  double binTime ( tzero ) ;
224 
225  EcalSamples& result ( *findSignal( detId ) ) ;
226 
227  const unsigned int rsize ( result.size() ) ;
228 
229  for( unsigned int bin ( 0 ) ; bin != rsize ; ++bin )
230  {
231  result[ bin ] += (*shape())( binTime )*signal ;
232  binTime += BUNCHSPACE ;
233  }
234 }
235 
236 double
238 {
239  const edm::Timestamp& evtTimeStamp = edm::Timestamp(m_iTime);
240  return (m_lasercals->getLaserCorrection(detId, evtTimeStamp));
241 }
242 
245 {
246  const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
247  EcalSamples* result ( vSamAll( di ) ) ;
248  if( result->zero() ) m_index.push_back( di ) ;
249  return result ;
250 }
251 
252 double
253 EcalHitResponse::analogSignalAmplitude( const DetId& detId, double energy, CLHEP::HepRandomEngine* engine )
254 {
255  const CaloSimParameters& parameters ( *params( detId ) ) ;
256 
257  // OK, the "energy" in the hit could be a real energy, deposited energy,
258  // or pe count. This factor converts to photoelectrons
259 
260  double lasercalib = 1.;
261  if(m_useLCcorrection == true && detId.subdetId() != 3) {
262  auto cache = m_laserCalibCache.find(detId);
263  if( cache != m_laserCalibCache.end() ) {
264  lasercalib = cache->second;
265  } else {
266  lasercalib = 1.0/findLaserConstant(detId);
267  m_laserCalibCache.emplace(detId,lasercalib);
268  }
269  }
270 
271  double npe ( energy*lasercalib*parameters.simHitToPhotoelectrons( detId ) ) ;
272 
273  // do we need to doPoisson statistics for the photoelectrons?
274  if( parameters.doPhotostatistics() ) {
275  npe = CLHEP::RandPoissonQ::shoot(engine, npe);
276  }
277  if( nullptr != m_PECorrection ) npe = m_PECorrection->correctPE( detId, npe, engine ) ;
278 
279  return npe ;
280 }
281 
282 double
283 EcalHitResponse::timeOfFlight( const DetId& detId ) const
284 {
285  auto cellGeometry ( geometry()->getGeometry( detId ) ) ;
286  assert( nullptr != cellGeometry ) ;
287  return cellGeometry->getPosition().mag()*cm/c_light ; // Units of c_light: mm/ns
288 }
289 
290 void
292 {
293  EcalSamples& sam ( *findSignal( pSam->id() ) ) ;
294  sam += (*pSam) ;
295 }
296 
297 int
299 {
300  return m_minBunch ;
301 }
302 
303 int
305 {
306  return m_maxBunch ;
307 }
308 
311 {
312  return m_index ;
313 }
314 
317 {
318  return m_index ;
319 }
320 
321 const CaloVHitFilter*
323 {
324  return m_hitFilter ;
325 }
326 
328 EcalHitResponse::findDetId( const DetId& detId ) const
329 {
330  const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
331  return vSamAll( di ) ;
332 }
size
Write out results.
const CaloVShape * m_shape
virtual void run(MixCollection< PCaloHit > &hits, CLHEP::HepRandomEngine *)
double time() const
Definition: PCaloHit.h:36
double analogSignalAmplitude(const DetId &id, double energy, CLHEP::HepRandomEngine *)
const CaloVShape * shape() const
double findLaserConstant(const DetId &detId) const
std::vector< unsigned int > VecInd
void setEventTime(const edm::TimeValue_t &iTime)
double energy() const
Definition: PCaloHit.h:29
virtual ~EcalHitResponse()
edm::TimeValue_t m_iTime
float getLaserCorrection(DetId const &xid, edm::Timestamp const &iTime) const
virtual void initializeHits()
virtual void putAnalogSignal(const PCaloHit &inputHit, CLHEP::HepRandomEngine *)
bool doPhotostatistics() const
whether or not to apply Poisson statistics to photoelectrons
virtual double delay(const PCaloHit &hit, CLHEP::HepRandomEngine *) const =0
Electronic response of the preamp.
Definition: CaloVShape.h:11
double timeOfFlight(const DetId &detId) const
#define nullptr
CaloGeometry const * getGeometry()
Main class for Parameters in different subdetectors.
void setHitFilter(const CaloVHitFilter *filter)
const CaloSimParameters * params(const DetId &detId) const
void setHitCorrection(const CaloVHitCorrection *hitCorrection)
void setBunchRange(int minBunch, int maxBunch)
void setLaserConstants(const EcalLaserDbService *laser, bool &useLCcorrection)
const EcalSamples * findDetId(const DetId &detId) const
virtual bool accepts(const PCaloHit &hit) const =0
virtual double timeToRise() const =0
bool isNotFinite(T x)
Definition: isFinite.h:10
double phaseShift() const
const CaloVHitFilter * hitFilter() const
EcalHitResponse(const CaloVSimParameterMap *parameterMap, const CaloVShape *shape)
DetId id() const
int maxBunch() const
virtual const CaloSimParameters & simParameters(const DetId &id) const =0
void setPhaseShift(double phaseShift)
const CaloVHitCorrection * m_hitCorrection
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
double simHitToPhotoelectrons() const
iterator end() const
int minBunch() const
unsigned int id() const
Definition: PCaloHit.h:43
const EcalLaserDbService * m_lasercals
unsigned long long TimeValue_t
Definition: Timestamp.h:28
def cache(function)
void setGeometry(const CaloSubdetectorGeometry *geometry)
bin
set the eta bin as selection string.
Definition: DetId.h:18
const CaloSubdetectorGeometry * m_geometry
const CaloSubdetectorGeometry * geometry() const
int size() const
get the size
Definition: CaloSamples.h:24
const CaloVSimParameterMap * m_parameterMap
virtual double correctPE(const DetId &detId, double npe, CLHEP::HepRandomEngine *) const =0
void setPECorrection(const CaloVPECorrection *peCorrection)
const CaloVPECorrection * m_PECorrection
CalibCache m_laserCalibCache
std::unordered_map< uint32_t, double > CalibCache
uint32_t size() const
static const double tzero[3]
EcalSamples * findSignal(const DetId &detId)
DetId id() const
get the (generic) id
Definition: CaloSamples.h:21
iterator begin() const
virtual EcalSamples * vSamAll(unsigned int i)=0
void add(const EcalSamples *pSam)
const CaloVHitFilter * m_hitFilter
bool withinBunchRange(int bunchCrossing) const
virtual void finalizeHits()
bool zero() const