CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CaloHitResponse.cc
Go to the documentation of this file.
13 #include "CLHEP/Random/RandPoissonQ.h"
14 #include "CLHEP/Random/RandFlat.h"
16 
17 #include "CLHEP/Units/GlobalPhysicalConstants.h"
18 #include "CLHEP/Units/GlobalSystemOfUnits.h"
19 #include<iostream>
20 
21 
23  const CaloVShape * shape)
24 : theAnalogSignalMap(),
25  theParameterMap(parametersMap),
26  theShape(shape),
27  theHitCorrection(0),
28  thePECorrection(0),
29  theHitFilter(0),
30  theGeometry(0),
31  theRandPoisson(0),
32  theMinBunch(-10),
33  theMaxBunch(10),
34  thePhaseShift_(1.)
35 {
36 }
37 
38 
40 {
41  delete theRandPoisson;
42 }
43 
44 
45 void CaloHitResponse::setBunchRange(int minBunch, int maxBunch) {
46  theMinBunch = minBunch;
47  theMaxBunch = maxBunch;
48 }
49 
50 
51 void CaloHitResponse::setRandomEngine(CLHEP::HepRandomEngine & engine)
52 {
53  theRandPoisson = new CLHEP::RandPoissonQ(engine);
54 }
55 
56 
58 
59  for(MixCollection<PCaloHit>::MixItr hitItr = hits.begin();
60  hitItr != hits.end(); ++hitItr)
61  {
62  // check the bunch crossing range
63  if ( hitItr.bunch() < theMinBunch || hitItr.bunch() > theMaxBunch )
64  { continue; }
65 
66  add(*hitItr);
67  } // loop over hits
68 }
69 
70 
71 void
73 {
74  // check the hit time makes sense
75  if ( isnan(hit.time()) ) { return; }
76 
77  // maybe it's not from this subdetector
78  if(theHitFilter == 0 || theHitFilter->accepts(hit)) {
79  LogDebug("CaloHitResponse") << hit;
80  CaloSamples signal( makeAnalogSignal( hit ) ) ;
81 
82  bool keep ( keepBlank() ) ; // here we check for blank signal if not keeping them
83  if( !keep )
84  {
85  const unsigned int size ( signal.size() ) ;
86  if( 0 != size )
87  {
88  for( unsigned int i ( 0 ) ; i != size ; ++i )
89  {
90  keep = keep || signal[i] > 1.e-7 ;
91  }
92  }
93  }
94  LogDebug("CaloHitResponse") << signal;
95  if( keep ) add(signal);
96  }
97 }
98 
99 
100 void CaloHitResponse::add(const CaloSamples & signal)
101 {
102  DetId id(signal.id());
103  CaloSamples * oldSignal = findSignal(id);
104  if (oldSignal == 0) {
105  theAnalogSignalMap[id] = signal;
106  } else {
107  // need a "+=" to CaloSamples
108  int sampleSize = oldSignal->size();
109  assert(sampleSize == signal.size());
110  assert(signal.presamples() == oldSignal->presamples());
111 
112  for(int i = 0; i < sampleSize; ++i) {
113  (*oldSignal)[i] += signal[i];
114  }
115  }
116 }
117 
118 
120 
121  // see if we need to correct the hit
122  PCaloHit hit = inputHit;
123 
124  if(theHitCorrection != 0) {
126  }
127 
128  DetId detId(hit.id());
130 
131  double signal = analogSignalAmplitude(hit, parameters);
132 
133  double jitter = hit.time() - timeOfFlight(detId);
134 
135  // assume bins count from zero, go for center of bin
136  const double tzero = ( theShape->timeToRise()
137  + parameters.timePhase()
138  - jitter
139  - BUNCHSPACE*( parameters.binOfMaximum()
140  - thePhaseShift_ ) ) ;
141  double binTime = tzero;
142 
144 
145  for(int bin = 0; bin < result.size(); bin++) {
146  result[bin] += (*theShape)(binTime)* signal;
147  binTime += BUNCHSPACE;
148  }
149  return result;
150 }
151 
152 
154 
155  if(!theRandPoisson)
156  {
158  if ( ! rng.isAvailable()) {
159  throw cms::Exception("Configuration")
160  << "CaloHitResponse requires the RandomNumberGeneratorService\n"
161  "which is not present in the configuration file. You must add the service\n"
162  "in the configuration file or remove the modules that require it.";
163  }
164  theRandPoisson = new CLHEP::RandPoissonQ(rng->getEngine());
165  }
166 
167  // OK, the "energy" in the hit could be a real energy, deposited energy,
168  // or pe count. This factor converts to photoelectrons
169  DetId detId(hit.id());
170  double npe = hit.energy() * parameters.simHitToPhotoelectrons(detId);
171  // do we need to doPoisson statistics for the photoelectrons?
172  if(parameters.doPhotostatistics()) {
173  npe = theRandPoisson->fire(npe);
174  }
175  if(thePECorrection) npe = thePECorrection->correctPE(detId, npe);
176  return npe;
177 }
178 
179 
181  CaloSamples * result = 0;
182  AnalogSignalMap::iterator signalItr = theAnalogSignalMap.find(detId);
183  if(signalItr == theAnalogSignalMap.end()) {
184  result = 0;
185  }
186  else {
187  result = &(signalItr->second);
188  }
189  return result;
190 }
191 
192 
195  CaloSamples result(detId, parameters.readoutFrameSize());
196  result.setPresamples(parameters.binOfMaximum()-1);
197  return result;
198 }
199 
200 
201 double CaloHitResponse::timeOfFlight(const DetId & detId) const {
202  // not going to assume there's one of these per subdetector.
203  // Take the whole CaloGeometry and find the right subdet
204  double result = 0.;
205  if(theGeometry == 0) {
206  edm::LogWarning("CaloHitResponse") << "No Calo Geometry set, so no time of flight correction";
207  }
208  else {
209  const CaloCellGeometry* cellGeometry = theGeometry->getSubdetectorGeometry(detId)->getGeometry(detId);
210  if(cellGeometry == 0) {
211  edm::LogWarning("CaloHitResponse") << "No Calo cell found for ID"
212  << detId.rawId() << " so no time-of-flight subtraction will be done";
213  }
214  else {
215  double distance = cellGeometry->getPosition().mag();
216  result = distance * cm / c_light; // Units of c_light: mm/ns
217  }
218  }
219  return result;
220 }
221 
222 
#define LogDebug(id)
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:43
int i
Definition: DBlmapReader.cc:9
CaloSamples makeBlankSignal(const DetId &detId) const
creates an empty signal for this DetId
double time() const
Definition: PCaloHit.h:34
virtual ~CaloHitResponse()
doesn&#39;t delete the pointers passed in
CLHEP::RandPoissonQ * theRandPoisson
double energy() const
Definition: PCaloHit.h:29
virtual CaloSamples makeAnalogSignal(const PCaloHit &inputHit) const
creates the signal corresponding to this hit
int presamples() const
access presample information
Definition: CaloSamples.h:31
bool doPhotostatistics() const
whether or not to apply Poisson statistics to photoelectrons
virtual bool keepBlank() const
Electronic response of the preamp.
Definition: CaloVShape.h:11
CaloHitResponse(const CaloVSimParameterMap *parameterMap, const CaloVShape *shape)
Main class for Parameters in different subdetectors.
const CaloGeometry * theGeometry
virtual const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
uint32_t rawId() const
get the raw id
Definition: DetId.h:45
iterator end()
const CaloVPECorrection * thePECorrection
const int keep
T mag() const
Definition: PV3DBase.h:61
virtual void correct(PCaloHit &hit) const =0
bool isnan(float x)
Definition: math.h:13
tuple result
Definition: query.py:137
virtual void add(const PCaloHit &hit)
process a single SimHit
bool isAvailable() const
Definition: Service.h:47
double simHitToPhotoelectrons() const
virtual double timeToRise() const =0
virtual const CaloSimParameters & simParameters(const DetId &id) const =0
virtual bool accepts(const PCaloHit &hit) const =0
unsigned int id() const
Definition: PCaloHit.h:40
double timeOfFlight(const DetId &detId) const
virtual CLHEP::HepRandomEngine & getEngine() const =0
Use this to get the random number engine, this is the only function most users should call...
int readoutFrameSize() const
for now, the LinearFrames and trhe digis will be one-to-one.
const CaloVHitCorrection * theHitCorrection
AnalogSignalMap theAnalogSignalMap
virtual void run(MixCollection< PCaloHit > &hits)
Complete cell digitization.
Definition: DetId.h:20
iterator begin()
double analogSignalAmplitude(const PCaloHit &hit, const CaloSimParameters &parameters) const
const CaloVSimParameterMap * theParameterMap
int size() const
get the size
Definition: CaloSamples.h:24
void setBunchRange(int minBunch, int maxBunch)
tells it which pileup bunches to do
CaloSamples * findSignal(const DetId &detId)
users can look for the signal for a given cell
static const double tzero[3]
const CaloVHitFilter * theHitFilter
virtual void setRandomEngine(CLHEP::HepRandomEngine &engine)
const CaloVShape * theShape
DetId id() const
get the (generic) id
Definition: CaloSamples.h:21
virtual double correctPE(const DetId &detId, double npe) const =0
const GlobalPoint & getPosition() const
int binOfMaximum() const
tuple size
Write out results.