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 
15 #include "CLHEP/Random/RandPoissonQ.h"
16 #include "CLHEP/Units/GlobalPhysicalConstants.h"
17 #include "CLHEP/Units/GlobalSystemOfUnits.h"
18 
19 #include<iostream>
20 
22  const CaloVShape * shape)
23 : theAnalogSignalMap(),
24  theParameterMap(parametersMap),
25  theShapes(0),
26  theShape(shape),
27  theHitCorrection(0),
28  thePECorrection(0),
29  theHitFilter(0),
30  theGeometry(0),
31  theMinBunch(-10),
32  theMaxBunch(10),
33  thePhaseShift_(1.),
34  storePrecise(false),
35  ignoreTime(false) {}
36 
38  const CaloShapes * shapes)
39 : theAnalogSignalMap(),
40  theParameterMap(parametersMap),
41  theShapes(shapes),
42  theShape(0),
43  theHitCorrection(0),
44  thePECorrection(0),
45  theHitFilter(0),
46  theGeometry(0),
47  theMinBunch(-10),
48  theMaxBunch(10),
49  thePhaseShift_(1.),
50  storePrecise(false),
51  ignoreTime(false) {}
52 
54 }
55 
56 void CaloHitResponse::setBunchRange(int minBunch, int maxBunch) {
57  theMinBunch = minBunch;
58  theMaxBunch = maxBunch;
59 }
60 
61 void CaloHitResponse::run(MixCollection<PCaloHit> & hits, CLHEP::HepRandomEngine* engine) {
62 
63  for(MixCollection<PCaloHit>::MixItr hitItr = hits.begin();
64  hitItr != hits.end(); ++hitItr) {
65  if(withinBunchRange(hitItr.bunch())) {
66  add(*hitItr, engine);
67  } // loop over hits
68  }
69 }
70 
71 void CaloHitResponse::add( const PCaloHit& hit, CLHEP::HepRandomEngine* engine ) {
72  // check the hit time makes sense
73  if ( edm::isNotFinite(hit.time()) ) { return; }
74 
75  // maybe it's not from this subdetector
76  if(theHitFilter == 0 || theHitFilter->accepts(hit)) {
77  LogDebug("CaloHitResponse") << hit;
78  CaloSamples signal( makeAnalogSignal( hit, engine ) ) ;
79  bool keep ( keepBlank() ) ; // here we check for blank signal if not keeping them
80  if( !keep )
81  {
82  const unsigned int size ( signal.size() ) ;
83  if( 0 != size )
84  {
85  for( unsigned int i ( 0 ) ; i != size ; ++i )
86  {
87  keep = keep || signal[i] > 1.e-7 ;
88  }
89  }
90  }
91 
92  if( keep ) add(signal);
93  }
94 }
95 
96 
97 void CaloHitResponse::add(const CaloSamples & signal)
98 {
99  DetId id(signal.id());
100  CaloSamples * oldSignal = findSignal(id);
101  if (oldSignal == 0) {
102  theAnalogSignalMap[id] = signal;
103 
104  } else {
105  // need a "+=" to CaloSamples
106  int sampleSize = oldSignal->size();
107  assert(sampleSize <= signal.size());
108  assert(signal.presamples() == oldSignal->presamples());
109 
110  for(int i = 0; i < sampleSize; ++i) {
111  (*oldSignal)[i] += signal[i];
112  }
113  }
114 }
115 
116 
117 CaloSamples CaloHitResponse::makeAnalogSignal(const PCaloHit & hit, CLHEP::HepRandomEngine* engine) const {
118 
119  DetId detId(hit.id());
121  double signal = analogSignalAmplitude(detId, hit.energy(), parameters, engine);
122 
123  double time = hit.time();
124  double tof = timeOfFlight(detId);
125  if(ignoreTime) time = tof;
126  if(theHitCorrection != 0) {
127  time += theHitCorrection->delay(hit, engine);
128  }
129  double jitter = time - tof;
130 
131  const CaloVShape * shape = theShape;
132  if(!shape) {
133  shape = theShapes->shape(detId);
134  }
135  // assume bins count from zero, go for center of bin
136  const double tzero = ( shape->timeToRise()
137  + parameters.timePhase()
138  - jitter
139  - BUNCHSPACE*( parameters.binOfMaximum()
140  - thePhaseShift_ ) ) ;
141  double binTime = tzero;
142 
144 
145  if(storePrecise){
146  result.resetPrecise();
147  int sampleBin(0);
148  //use 1ns binning for precise sample
149  for(int bin = 0; bin < result.size()*BUNCHSPACE; bin++) {
150  sampleBin = bin/BUNCHSPACE;
151  double pulseBit = (*shape)(binTime)* signal;
152  result[sampleBin] += pulseBit;
153  result.preciseAtMod(bin) += pulseBit;
154  binTime += 1.0;
155  }
156  }
157  else {
158  for(int bin = 0; bin < result.size(); bin++) {
159  result[bin] += (*shape)(binTime)* signal;
160  binTime += BUNCHSPACE;
161  }
162  }
163  return result;
164 }
165 
166 double CaloHitResponse::analogSignalAmplitude(const DetId & detId, float energy, const CaloSimParameters & parameters, CLHEP::HepRandomEngine* engine) const {
167 
168  // OK, the "energy" in the hit could be a real energy, deposited energy,
169  // or pe count. This factor converts to photoelectrons
170  //GMA Smeared in photon production it self
171  double npe = energy * parameters.simHitToPhotoelectrons(detId);
172  // do we need to doPoisson statistics for the photoelectrons?
173  if(parameters.doPhotostatistics()) {
174  npe = CLHEP::RandPoissonQ::shoot(engine,npe);
175  }
176  if(thePECorrection) npe = thePECorrection->correctPE(detId, npe, engine);
177  return npe;
178 }
179 
180 
182  CaloSamples * result = 0;
183  AnalogSignalMap::iterator signalItr = theAnalogSignalMap.find(detId);
184  if(signalItr == theAnalogSignalMap.end()) {
185  result = 0;
186  } else {
187  result = &(signalItr->second);
188  }
189  return result;
190 }
191 
192 
195  int preciseSize(storePrecise ? parameters.readoutFrameSize()*BUNCHSPACE : 0);
196  CaloSamples result(detId, parameters.readoutFrameSize(),preciseSize);
197  result.setPresamples(parameters.binOfMaximum()-1);
198  if(storePrecise) result.setPrecise(result.presamples()*BUNCHSPACE,1.0);
199  return result;
200 }
201 
202 
203 double CaloHitResponse::timeOfFlight(const DetId & detId) const {
204  // not going to assume there's one of these per subdetector.
205  // Take the whole CaloGeometry and find the right subdet
206  double result = 0.;
207  if(theGeometry == 0) {
208  edm::LogWarning("CaloHitResponse") << "No Calo Geometry set, so no time of flight correction";
209  }
210  else {
211  const CaloCellGeometry* cellGeometry = theGeometry->getSubdetectorGeometry(detId)->getGeometry(detId);
212  if(cellGeometry == 0) {
213  edm::LogWarning("CaloHitResponse") << "No Calo cell found for ID"
214  << detId.rawId() << " so no time-of-flight subtraction will be done";
215  }
216  else {
217  double distance = cellGeometry->getPosition().mag();
218  result = distance * cm / c_light; // Units of c_light: mm/ns
219  }
220  }
221  return result;
222 }
223 
224 
#define LogDebug(id)
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:45
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:36
virtual ~CaloHitResponse()
doesn&#39;t delete the pointers passed in
bool withinBunchRange(int bunchCrossing) const
check if crossing is within bunch range:
double energy() const
Definition: PCaloHit.h:29
assert(m_qm.get())
virtual void run(MixCollection< PCaloHit > &hits, CLHEP::HepRandomEngine *)
Complete cell digitization.
int presamples() const
access presample information
Definition: CaloSamples.h:36
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
void resetPrecise()
Definition: CaloSamples.cc:27
CaloHitResponse(const CaloVSimParameterMap *parameterMap, const CaloVShape *shape)
Main class for Parameters in different subdetectors.
const CaloGeometry * theGeometry
virtual double correctPE(const DetId &detId, double npe, CLHEP::HepRandomEngine *) const =0
virtual const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
tuple result
Definition: mps_fire.py:84
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
iterator end()
const CaloVPECorrection * thePECorrection
const int keep
T mag() const
Definition: PV3DBase.h:67
bool isNotFinite(T x)
Definition: isFinite.h:10
virtual CaloSamples makeAnalogSignal(const PCaloHit &inputHit, CLHEP::HepRandomEngine *) const
creates the signal corresponding to this hit
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:43
double timeOfFlight(const DetId &detId) const
int readoutFrameSize() const
for now, the LinearFrames and trhe digis will be one-to-one.
const CaloVHitCorrection * theHitCorrection
virtual double delay(const PCaloHit &hit, CLHEP::HepRandomEngine *) const =0
AnalogSignalMap theAnalogSignalMap
Definition: DetId.h:18
double analogSignalAmplitude(const DetId &id, float energy, const CaloSimParameters &parameters, CLHEP::HepRandomEngine *) const
iterator begin()
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
float & preciseAtMod(int i)
mutable function to access precise samples
Definition: CaloSamples.h:31
virtual void add(const PCaloHit &hit, CLHEP::HepRandomEngine *)
process a single SimHit
static const double tzero[3]
const CaloVHitFilter * theHitFilter
volatile std::atomic< bool > shutdown_flag false
const CaloVShape * theShape
DetId id() const
get the (generic) id
Definition: CaloSamples.h:21
const GlobalPoint & getPosition() const
Returns the position of reference for this cell.
int binOfMaximum() const
tuple size
Write out results.
virtual const CaloVShape * shape(const DetId &detId) const
Definition: CaloShapes.h:15