CMS 3D CMS Logo

EBHitResponse.cc
Go to the documentation of this file.
8 #include "CLHEP/Random/RandPoissonQ.h"
9 #include "CLHEP/Random/RandGaussQ.h"
14 
15 
17  const CaloVShape* shape ,
18  bool apdOnly ,
19  const APDSimParameters* apdPars = nullptr ,
20  const CaloVShape* apdShape = nullptr ) :
21 
22  EcalHitResponse( parameterMap, shape ) ,
23 
24  m_apdOnly ( apdOnly ) ,
25  m_apdPars ( apdPars ) ,
26  m_apdShape ( apdShape ) ,
27  m_timeOffVec ( kNOffsets, apdParameters()->timeOffset() ) ,
28  pcub ( nullptr == apdPars ? 0 : apdParameters()->nonlParms()[0] ) ,
29  pqua ( nullptr == apdPars ? 0 : apdParameters()->nonlParms()[1] ) ,
30  plin ( nullptr == apdPars ? 0 : apdParameters()->nonlParms()[2] ) ,
31  pcon ( nullptr == apdPars ? 0 : apdParameters()->nonlParms()[3] ) ,
32  pelo ( nullptr == apdPars ? 0 : apdParameters()->nonlParms()[4] ) ,
33  pehi ( nullptr == apdPars ? 0 : apdParameters()->nonlParms()[5] ) ,
34  pasy ( nullptr == apdPars ? 0 : apdParameters()->nonlParms()[6] ) ,
35  pext ( nullptr == apdPars ? 0 : nonlFunc1( pelo ) ) ,
36  poff ( nullptr == apdPars ? 0 : nonlFunc1( pehi ) ) ,
37  pfac ( nullptr == apdPars ? 0 : ( pasy - poff )*2./M_PI ),
38  m_isInitialized(false)
39 {
40  const EBDetId detId ( EBDetId::detIdFromDenseIndex( 0 ) ) ;
41  const CaloSimParameters& parameters ( parameterMap->simParameters( detId ) ) ;
42 
43  const unsigned int rSize ( parameters.readoutFrameSize() ) ;
44  const unsigned int nPre ( parameters.binOfMaximum() - 1 ) ;
45 
46  const unsigned int size ( EBDetId::kSizeForDenseIndexing ) ;
47 
48  m_vSam.reserve( size ) ;
49 
50  for( unsigned int i ( 0 ) ; i != size ; ++i )
51  {
52  m_vSam.emplace_back(CaloGenericDetId( detId.det(), detId.subdetId(), i ) ,
53  rSize, nPre );
54  }
55 }
56 
58 {
59 }
60 
61 void
62 EBHitResponse::initialize(CLHEP::HepRandomEngine* engine)
63 {
64  m_isInitialized = true;
65  for( unsigned int i ( 0 ) ; i != kNOffsets ; ++i )
66  {
67  m_timeOffVec[ i ] +=
68  CLHEP::RandGaussQ::shoot(engine, 0, apdParameters()->timeOffWidth() ) ;
69  }
70 }
71 
72 const APDSimParameters*
74 {
75  assert ( nullptr != m_apdPars ) ;
76  return m_apdPars ;
77 }
78 
79 const CaloVShape*
81 {
82  assert( nullptr != m_apdShape ) ;
83  return m_apdShape ;
84 }
85 
86 void
88  double npe ,
89  double time )
90 {
91  const CaloSimParameters& parameters ( *params( detId ) ) ;
92 
93  const double energyFac ( 1./parameters.simHitToPhotoelectrons( detId ) ) ;
94 
95 // std::cout<<"******** Input APD Npe="<<npe<<", Efactor="<<energyFac
96 // <<", Energy="<<npe*energyFac
97 // <<", nonlFunc="<<nonlFunc( npe*energyFac )<<std::endl ;
98 
99  const double signal ( npe*nonlFunc( npe*energyFac ) ) ;
100 
101  const double jitter ( time - timeOfFlight( detId ) ) ;
102 
103  if(!m_isInitialized) {
104  throw cms::Exception("LogicError")
105  << "EBHitResponse::putAPDSignal called without initializing\n";
106  }
107 
108  const double tzero ( apdShape()->timeToRise()
109  - jitter
110  - offsets()[ EBDetId( detId ).denseIndex()%kNOffsets ]
111  - BUNCHSPACE*( parameters.binOfMaximum()
112  - phaseShift() ) ) ;
113 
114  double binTime ( tzero ) ;
115 
116  EcalSamples& result ( *findSignal( detId ) );
117 
118  for( unsigned int bin ( 0 ) ; bin != result.size(); ++bin )
119  {
120  result[bin] += (*apdShape())(binTime)*signal ;
121  binTime += BUNCHSPACE ;
122  }
123 }
124 
125 double
126 EBHitResponse::apdSignalAmplitude( const PCaloHit& hit, CLHEP::HepRandomEngine* engine ) const
127 {
128  int iddepth = (hit.depth() & PCaloHit::kEcalDepthIdMask);
129  assert( 1 == iddepth || 2 == iddepth ) ;
130 
131  double npe ( hit.energy()*( 2 == iddepth ?
133  apdParameters()->simToPEHigh() ) ) ;
134 
135  // do we need to do Poisson statistics for the photoelectrons?
136  if( apdParameters()->doPEStats() &&
137  !m_apdOnly ) {
138 
139  CLHEP::RandPoissonQ randPoissonQ(*engine, npe);
140  npe = randPoissonQ.fire();
141  }
142  assert( nullptr != m_intercal ) ;
143  double fac ( 1 ) ;
144  findIntercalibConstant( hit.id(), fac ) ;
145 
146  npe *= fac ;
147 
148 // edm::LogError( "EBHitResponse" ) << "--- # photoelectrons for "
149 /* std::cout << "--- # photoelectrons for "
150  << EBDetId( hit.id() )
151  <<" is " << npe //;
152  <<std::endl ;*/
153 
154  return npe ;
155 }
156 
157 void
159 {
160  m_intercal = ical ;
161 }
162 
163 void
165  double& icalconst ) const
166 {
167  EcalIntercalibConstantMC thisconst ( 1. ) ;
168 
169  if( nullptr == m_intercal )
170  {
171  edm::LogError( "EBHitResponse" ) <<
172  "No intercal constant defined for EBHitResponse" ;
173  }
174  else
175  {
176  const EcalIntercalibConstantMCMap& icalMap ( m_intercal->getMap() ) ;
177  EcalIntercalibConstantMCMap::const_iterator icalit ( icalMap.find( detId ) ) ;
178  if( icalit != icalMap.end() )
179  {
180  thisconst = *icalit ;
181  if ( thisconst == 0. ) thisconst = 1. ;
182  }
183  else
184  {
185  edm::LogError("EBHitResponse") << "No intercalib const found for xtal "
186  << detId.rawId()
187  << "! something wrong with EcalIntercalibConstants in your DB? ";
188  }
189  }
190  icalconst = thisconst ;
191 }
192 
193 void
195  if( !index().empty() ) blankOutUsedSamples() ;
196 
197  const unsigned int bSize ( EBDetId::kSizeForDenseIndexing ) ;
198 
199  if( m_apdNpeVec.empty() )
200  {
201  m_apdNpeVec = std::vector<double>( bSize, (double)0.0 ) ;
202  m_apdTimeVec = std::vector<double>( bSize, (double)0.0 ) ;
203  }
204 }
205 
206 void
208  const unsigned int bSize ( EBDetId::kSizeForDenseIndexing ) ;
209  if( apdParameters()->addToBarrel() ||
210  m_apdOnly )
211  {
212  for( unsigned int i ( 0 ) ; i != bSize ; ++i )
213  {
214  if( 0 < m_apdNpeVec[i] )
215  {
217  m_apdNpeVec[i] ,
218  m_apdTimeVec[i] ) ;
219 
220  // now zero out for next time
221  m_apdNpeVec[i] = 0. ;
222  m_apdTimeVec[i] = 0. ;
223  }
224  }
225  }
226 }
227 
228 void
229 EBHitResponse::add( const PCaloHit& hit, CLHEP::HepRandomEngine* engine )
230 {
231  if (!edm::isNotFinite( hit.time() ) && ( nullptr == hitFilter() || hitFilter()->accepts( hit ) ) ) {
232  int iddepth = (hit.depth() & PCaloHit::kEcalDepthIdMask);
233  if ( 0 == iddepth ) // for now take only nonAPD hits
234  {
235  if( !m_apdOnly ) putAnalogSignal( hit, engine ) ;
236  }
237  else // APD hits here
238  {
239  if( apdParameters()->addToBarrel() ||
240  m_apdOnly )
241  {
242  const unsigned int icell ( EBDetId( hit.id() ).denseIndex() ) ;
243  m_apdNpeVec[ icell ] += apdSignalAmplitude( hit, engine ) ;
244  if( 0 == m_apdTimeVec[ icell ] ) m_apdTimeVec[ icell ] = hit.time() ;
245  }
246  }
247  }
248 }
249 
250 void
251 EBHitResponse::run( MixCollection<PCaloHit>& hits, CLHEP::HepRandomEngine* engine )
252 {
253  if( !index().empty() ) blankOutUsedSamples() ;
254 
255  const unsigned int bSize ( EBDetId::kSizeForDenseIndexing ) ;
256 
257  if( m_apdNpeVec.empty() )
258  {
259  m_apdNpeVec = std::vector<double>( bSize, (double)0.0 ) ;
260  m_apdTimeVec = std::vector<double>( bSize, (double)0.0 ) ;
261  }
262 
263  for( MixCollection<PCaloHit>::MixItr hitItr ( hits.begin() ) ;
264  hitItr != hits.end() ; ++hitItr )
265  {
266  const PCaloHit& hit ( *hitItr ) ;
267  const int bunch ( hitItr.bunch() ) ;
268  if( minBunch() <= bunch &&
269  maxBunch() >= bunch &&
270  !edm::isNotFinite( hit.time() ) &&
271  ( nullptr == hitFilter() ||
272  hitFilter()->accepts( hit ) ) )
273  {
274  int iddepth = (hit.depth() & PCaloHit::kEcalDepthIdMask);
275  if( 0 == iddepth ) // for now take only nonAPD hits
276  {
277  if( !m_apdOnly ) putAnalogSignal( hit, engine ) ;
278  }
279  else // APD hits here
280  {
281  if( apdParameters()->addToBarrel() ||
282  m_apdOnly )
283  {
284  const unsigned int icell ( EBDetId( hit.id() ).denseIndex() ) ;
285  m_apdNpeVec[ icell ] += apdSignalAmplitude( hit, engine ) ;
286  if( 0 == m_apdTimeVec[ icell ] ) m_apdTimeVec[ icell ] = hit.time() ;
287  }
288  }
289  }
290  }
291 
292  if( apdParameters()->addToBarrel() ||
293  m_apdOnly )
294  {
295  for( unsigned int i ( 0 ) ; i != bSize ; ++i )
296  {
297  if( 0 < m_apdNpeVec[i] )
298  {
300  m_apdNpeVec[i] ,
301  m_apdTimeVec[i] ) ;
302 
303  // now zero out for next time
304  m_apdNpeVec[i] = 0. ;
305  m_apdTimeVec[i] = 0. ;
306  }
307  }
308  }
309 }
310 
311 unsigned int
313 {
314  return m_vSam.size() ;
315 }
316 
317 unsigned int
319 {
320  return m_vSam.size() ;
321 }
322 
324 EBHitResponse::operator[]( unsigned int i ) const
325 {
326  return &m_vSam[ i ] ;
327 }
328 
331 {
332  return &m_vSam[ i ] ;
333 }
334 
336 EBHitResponse::vSam( unsigned int i )
337 {
338  return &m_vSam[ i ] ;
339 }
340 
342 EBHitResponse::vSamAll( unsigned int i )
343 {
344  return &m_vSam[ i ] ;
345 }
346 
348 EBHitResponse::vSamAll( unsigned int i ) const
349 {
350  return &m_vSam[ i ] ;
351 }
size
Write out results.
double time() const
Definition: PCaloHit.h:36
double simToPEHigh() const
const self & getMap() const
std::vector< EBSamples > m_vSam
EcalSamples * operator[](unsigned int i) override
double energy() const
Definition: PCaloHit.h:29
const CaloVShape * m_apdShape
Definition: EBHitResponse.h:90
void putAPDSignal(const DetId &detId, double npe, double time)
unsigned int samplesSize() const override
virtual void putAnalogSignal(const PCaloHit &inputHit, CLHEP::HepRandomEngine *)
Electronic response of the preamp.
Definition: CaloVShape.h:11
uint16_t depth() const
Definition: PCaloHit.h:49
double timeOfFlight(const DetId &detId) const
#define nullptr
const APDSimParameters * apdParameters() const
const APDSimParameters * m_apdPars
Definition: EBHitResponse.h:89
Main class for Parameters in different subdetectors.
const CaloSimParameters * params(const DetId &detId) const
static EBDetId detIdFromDenseIndex(uint32_t di)
Definition: EBDetId.h:111
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
void findIntercalibConstant(const DetId &detId, double &icalconst) const
virtual bool accepts(const PCaloHit &hit) const =0
unsigned int samplesSizeAll() const override
bool isNotFinite(T x)
Definition: isFinite.h:10
double phaseShift() const
~EBHitResponse() override
void setIntercal(const EcalIntercalibConstantsMC *ical)
const CaloVHitFilter * hitFilter() const
const VecD & offsets() const
Definition: EBHitResponse.h:67
void initializeHits() override
int maxBunch() const
virtual const CaloSimParameters & simParameters(const DetId &id) const =0
double apdSignalAmplitude(const PCaloHit &hit, CLHEP::HepRandomEngine *) const
double simHitToPhotoelectrons() const
iterator end() const
int minBunch() const
unsigned int id() const
Definition: PCaloHit.h:43
const EcalIntercalibConstantsMC * m_intercal
Definition: EBHitResponse.h:91
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
std::vector< double > m_timeOffVec
Definition: EBHitResponse.h:93
EcalSamples * vSamAll(unsigned int i) override
#define M_PI
bin
set the eta bin as selection string.
EBHitResponse(const CaloVSimParameterMap *parameterMap, const CaloVShape *shape, bool apdOnly, const APDSimParameters *apdPars, const CaloVShape *apdShape)
Definition: DetId.h:18
EcalSamples * vSam(unsigned int i) override
std::vector< Item >::const_iterator const_iterator
const double nonlFunc(double enr) const
Definition: EBHitResponse.h:69
uint32_t size() const
void initialize(CLHEP::HepRandomEngine *)
static const double tzero[3]
EcalSamples * findSignal(const DetId &detId)
float EcalIntercalibConstantMC
iterator begin() const
const bool m_apdOnly
Definition: EBHitResponse.h:88
Detector det() const
get the detector field from this detid
Definition: DetId.h:35
void run(MixCollection< PCaloHit > &hits, CLHEP::HepRandomEngine *) override
int binOfMaximum() const
double simToPELow() const
void finalizeHits() override
std::vector< double > m_apdTimeVec
Definition: EBHitResponse.h:96
std::vector< double > m_apdNpeVec
Definition: EBHitResponse.h:95
const CaloVShape * apdShape() const
void add(const PCaloHit &hit, CLHEP::HepRandomEngine *) override
static const int kEcalDepthIdMask
Definition: PCaloHit.h:67