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.
14 #include "CLHEP/Random/RandPoissonQ.h"
15 #include "CLHEP/Random/RandFlat.h"
17 
18 #include "CLHEP/Units/GlobalPhysicalConstants.h"
19 #include "CLHEP/Units/GlobalSystemOfUnits.h"
20 #include<iostream>
21 
22 
24  const CaloVShape * shape)
25 : theAnalogSignalMap(),
26  theParameterMap(parametersMap),
27  theShapes(0),
28  theShape(shape),
29  theHitCorrection(0),
30  thePECorrection(0),
31  theHitFilter(0),
32  theGeometry(0),
33  theRandPoisson(0),
34  theMinBunch(-10),
35  theMaxBunch(10),
36  thePhaseShift_(1.)
37 {
38 }
39 
40 
42  const CaloShapes * shapes)
43 : theAnalogSignalMap(),
44  theParameterMap(parametersMap),
45  theShapes(shapes),
46  theShape(0),
47  theHitCorrection(0),
48  thePECorrection(0),
49  theHitFilter(0),
50  theGeometry(0),
51  theRandPoisson(0),
52  theMinBunch(-10),
53  theMaxBunch(10),
54  thePhaseShift_(1.)
55 {
56 }
57 
58 
60 {
61  delete theRandPoisson;
62 }
63 
64 
65 void CaloHitResponse::setBunchRange(int minBunch, int maxBunch) {
66  theMinBunch = minBunch;
67  theMaxBunch = maxBunch;
68 }
69 
70 
71 void CaloHitResponse::setRandomEngine(CLHEP::HepRandomEngine & engine)
72 {
73  theRandPoisson = new CLHEP::RandPoissonQ(engine);
74 }
75 
76 
78 
79  for(MixCollection<PCaloHit>::MixItr hitItr = hits.begin();
80  hitItr != hits.end(); ++hitItr)
81  {
82  // check the bunch crossing range
83  if ( hitItr.bunch() < theMinBunch || hitItr.bunch() > theMaxBunch )
84  { continue; }
85 
86  add(*hitItr);
87  } // loop over hits
88 }
89 
90 
91 void
93 {
94  // check the hit time makes sense
95  if ( isnan(hit.time()) ) { return; }
96 
97  // maybe it's not from this subdetector
98  if(theHitFilter == 0 || theHitFilter->accepts(hit)) {
99  LogDebug("CaloHitResponse") << hit;
100  CaloSamples signal( makeAnalogSignal( hit ) ) ;
101 
102  bool keep ( keepBlank() ) ; // here we check for blank signal if not keeping them
103  if( !keep )
104  {
105  const unsigned int size ( signal.size() ) ;
106  if( 0 != size )
107  {
108  for( unsigned int i ( 0 ) ; i != size ; ++i )
109  {
110  keep = keep || signal[i] > 1.e-7 ;
111  }
112  }
113  }
114  LogDebug("CaloHitResponse") << signal;
115  if( keep ) add(signal);
116  }
117 }
118 
119 
120 void CaloHitResponse::add(const CaloSamples & signal)
121 {
122  DetId id(signal.id());
123  CaloSamples * oldSignal = findSignal(id);
124  if (oldSignal == 0) {
125  theAnalogSignalMap[id] = signal;
126  } else {
127  // need a "+=" to CaloSamples
128  int sampleSize = oldSignal->size();
129  assert(sampleSize == signal.size());
130  assert(signal.presamples() == oldSignal->presamples());
131 
132  for(int i = 0; i < sampleSize; ++i) {
133  (*oldSignal)[i] += signal[i];
134  }
135  }
136 }
137 
138 
140 
141  // see if we need to correct the hit
142  PCaloHit hit = inputHit;
143 
144  if(theHitCorrection != 0) {
146  }
147 
148  DetId detId(hit.id());
150 
151  double signal = analogSignalAmplitude(hit, parameters);
152 
153  double jitter = hit.time() - timeOfFlight(detId);
154 
155  const CaloVShape * shape = theShape;
156  if(!shape) {
157  shape = theShapes->shape(detId);
158  }
159  // assume bins count from zero, go for center of bin
160  const double tzero = ( shape->timeToRise()
161  + parameters.timePhase()
162  - jitter
163  - BUNCHSPACE*( parameters.binOfMaximum()
164  - thePhaseShift_ ) ) ;
165  double binTime = tzero;
166 
168 
169  for(int bin = 0; bin < result.size(); bin++) {
170  result[bin] += (*shape)(binTime)* signal;
171  binTime += BUNCHSPACE;
172  }
173  return result;
174 }
175 
176 
178 
179  if(!theRandPoisson)
180  {
182  if ( ! rng.isAvailable()) {
183  throw cms::Exception("Configuration")
184  << "CaloHitResponse requires the RandomNumberGeneratorService\n"
185  "which is not present in the configuration file. You must add the service\n"
186  "in the configuration file or remove the modules that require it.";
187  }
188  theRandPoisson = new CLHEP::RandPoissonQ(rng->getEngine());
189  }
190 
191  // OK, the "energy" in the hit could be a real energy, deposited energy,
192  // or pe count. This factor converts to photoelectrons
193  DetId detId(hit.id());
194  double npe = hit.energy() * parameters.simHitToPhotoelectrons(detId);
195  // do we need to doPoisson statistics for the photoelectrons?
196  if(parameters.doPhotostatistics()) {
197  npe = theRandPoisson->fire(npe);
198  }
199  if(thePECorrection) npe = thePECorrection->correctPE(detId, npe);
200  return npe;
201 }
202 
203 
205  CaloSamples * result = 0;
206  AnalogSignalMap::iterator signalItr = theAnalogSignalMap.find(detId);
207  if(signalItr == theAnalogSignalMap.end()) {
208  result = 0;
209  }
210  else {
211  result = &(signalItr->second);
212  }
213  return result;
214 }
215 
216 
219  CaloSamples result(detId, parameters.readoutFrameSize());
220  result.setPresamples(parameters.binOfMaximum()-1);
221  return result;
222 }
223 
224 
225 double CaloHitResponse::timeOfFlight(const DetId & detId) const {
226  // not going to assume there's one of these per subdetector.
227  // Take the whole CaloGeometry and find the right subdet
228  double result = 0.;
229  if(theGeometry == 0) {
230  edm::LogWarning("CaloHitResponse") << "No Calo Geometry set, so no time of flight correction";
231  }
232  else {
233  const CaloCellGeometry* cellGeometry = theGeometry->getSubdetectorGeometry(detId)->getGeometry(detId);
234  if(cellGeometry == 0) {
235  edm::LogWarning("CaloHitResponse") << "No Calo cell found for ID"
236  << detId.rawId() << " so no time-of-flight subtraction will be done";
237  }
238  else {
239  double distance = cellGeometry->getPosition().mag();
240  result = distance * cm / c_light; // Units of c_light: mm/ns
241  }
242  }
243  return result;
244 }
245 
246 
#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
dictionary parameters
Definition: Parameters.py:2
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)
const GlobalPoint & getPosition() const
Returns the position of reference for this cell.
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:66
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 CaloShapes * theShapes
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
int binOfMaximum() const
tuple size
Write out results.
virtual const CaloVShape * shape(const DetId &detId) const
Definition: CaloShapes.h:15