CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HcalSiPMHitResponse.cc
Go to the documentation of this file.
14 
15 #include "CLHEP/Random/RandFlat.h"
16 
17 #include <math.h>
18 #include <list>
19 
21  const CaloShapes * shapes) :
22  CaloHitResponse(parameterMap, shapes), theSiPM(), theRecoveryTime(250.),
23  TIMEMULT(1), Y11RANGE(80.), Y11MAX(0.04), Y11TIMETORISE(16.65) {
24  theSiPM = new HcalSiPM(2500);
25 }
26 
28  if (theSiPM)
29  delete theSiPM;
30 }
31 
33  precisionTimedPhotons.clear();
34 }
35 
36 void HcalSiPMHitResponse::finalizeHits(CLHEP::HepRandomEngine* engine) {
37 
38  photonTimeMap::iterator channelPhotons;
39  for (channelPhotons = precisionTimedPhotons.begin();
40  channelPhotons != precisionTimedPhotons.end();
41  ++channelPhotons) {
42  CaloSamples signal(makeSiPMSignal(channelPhotons->first,
43  channelPhotons->second,
44  engine));
45  bool keep( keepBlank() );
46  if (!keep) {
47  const unsigned int size ( signal.size() ) ;
48  if( 0 != size ) {
49  for( unsigned int i ( 0 ) ; i != size ; ++i ) {
50  keep = keep || signal[i] > 1.e-7 ;
51  }
52  }
53  }
54 
55  LogDebug("HcalSiPMHitResponse") << HcalDetId(signal.id()) << ' ' << signal;
56  // std::cout << HcalDetId(signal.id()) << ' ' << signal;
57  if (keep) add(signal);
58  }
59 }
60 
62  DetId id(signal.id());
63  CaloSamples * oldSignal = findSignal(id);
64  if (oldSignal == 0) {
65  theAnalogSignalMap[id] = signal;
66  } else {
67  (*oldSignal) += signal;
68  }
69 }
70 
71 void HcalSiPMHitResponse::add(const PCaloHit& hit, CLHEP::HepRandomEngine* engine) {
72  if (!edm::isNotFinite(hit.time()) &&
73  ((theHitFilter == 0) || (theHitFilter->accepts(hit)))) {
74  HcalDetId id(hit.id());
75  const HcalSimParameters& pars = dynamic_cast<const HcalSimParameters&>(theParameterMap->simParameters(id));
76  double signal(analogSignalAmplitude(id, hit.energy(), pars, engine));
77  unsigned int photons(signal + 0.5);
78  double time( hit.time() );
79 
80  if (photons > 0)
81  if (precisionTimedPhotons.find(id)==precisionTimedPhotons.end()) {
82  precisionTimedPhotons.insert(
83  std::pair<DetId, photonTimeHist >(id,
85  pars.readoutFrameSize(), 0)
86  )
87  );
88  }
89 
90  LogDebug("HcalSiPMHitResponse") << id;
91  LogDebug("HcalSiPMHitResponse") << " fCtoGeV: " << pars.fCtoGeV(id)
92  << " samplingFactor: " << pars.samplingFactor(id)
93  << " photoelectronsToAnalog: " << pars.photoelectronsToAnalog(id)
94  << " simHitToPhotoelectrons: " << pars.simHitToPhotoelectrons(id);
95  LogDebug("HcalSiPMHitResponse") << " energy: " << hit.energy()
96  << " photons: " << photons
97  << " time: " << time;
98  if (theHitCorrection != 0)
99  time += theHitCorrection->delay(hit, engine);
100  LogDebug("HcalSiPMHitResponse") << " corrected time: " << time;
101  LogDebug("HcalSiPMHitResponse") << " timePhase: " << pars.timePhase()
102  << " tof: " << timeOfFlight(id)
103  << " binOfMaximum: " << pars.binOfMaximum()
104  << " phaseShift: " << thePhaseShift_;
105  double tzero(Y11TIMETORISE + pars.timePhase() -
106  (hit.time() - timeOfFlight(id)) -
107  BUNCHSPACE*( pars.binOfMaximum() - thePhaseShift_));
108  LogDebug("HcalSiPMHitResponse") << " tzero: " << tzero;
109  // tzero += BUNCHSPACE*pars.binOfMaximum() + 75.;
110  //move it back 25ns to bin 4
111  tzero += BUNCHSPACE*pars.binOfMaximum() + 50.;
112  LogDebug("HcalSiPMHitResponse") << " corrected tzero: " << tzero << '\n';
113  double t_pe(0.);
114  int t_bin(0);
115  for (unsigned int pe(0); pe<photons; ++pe) {
116  t_pe = generatePhotonTime(engine);
117  t_bin = int((t_pe + tzero)/(theTDCParams.deltaT()/TIMEMULT) + 0.5);
118  LogDebug("HcalSiPMHitResponse") << "t_pe: " << t_pe << " t_pe + tzero: " << (t_pe+tzero)
119  << " t_bin: " << t_bin << '\n';
120  if ((t_bin >= 0) &&
121  (static_cast<unsigned int>(t_bin) < precisionTimedPhotons[id].size()))
122  precisionTimedPhotons[id][t_bin] += 1;
123  }
124  }
125 }
126 
127 void HcalSiPMHitResponse::run(MixCollection<PCaloHit> & hits, CLHEP::HepRandomEngine* engine) {
128  typedef std::multiset <const PCaloHit *, PCaloHitCompareTimes> SortedHitSet;
129 
130  std::map< DetId, SortedHitSet > sortedhits;
131  for (MixCollection<PCaloHit>::MixItr hitItr = hits.begin();
132  hitItr != hits.end(); ++hitItr) {
133  if (!((hitItr.bunch() < theMinBunch) || (hitItr.bunch() > theMaxBunch)) &&
134  !(edm::isNotFinite(hitItr->time())) &&
135  ((theHitFilter == 0) || (theHitFilter->accepts(*hitItr)))) {
136  DetId id(hitItr->id());
137  if (sortedhits.find(id)==sortedhits.end())
138  sortedhits.insert(std::pair<DetId, SortedHitSet>(id, SortedHitSet()));
139  sortedhits[id].insert(&(*hitItr));
140  }
141  }
142  int pixelIntegral, oldIntegral;
143  HcalSiPMRecovery pixelHistory(theRecoveryTime);
144  for (std::map<DetId, SortedHitSet>::iterator i = sortedhits.begin();
145  i!=sortedhits.end(); ++i) {
146  pixelHistory.clearHistory();
147  for (SortedHitSet::iterator itr = i->second.begin();
148  itr != i->second.end(); ++itr) {
149  const PCaloHit& hit = **itr;
150  pixelIntegral = pixelHistory.getIntegral(hit.time());
151  oldIntegral = pixelIntegral;
152  CaloSamples signal(makeSiPMSignal(i->first, hit, pixelIntegral, engine));
153  pixelHistory.addToHistory(hit.time(), pixelIntegral-oldIntegral);
154  add(signal);
155  }
156  }
157 }
158 
161  int preciseSize(parameters.readoutFrameSize()*theTDCParams.nbins());
162  CaloSamples result(detId, parameters.readoutFrameSize(), preciseSize);
163  result.setPresamples(parameters.binOfMaximum()-1);
164  result.setPrecise(result.presamples()*theTDCParams.nbins(),
165  theTDCParams.deltaT());
166  return result;
167 }
168 
170  const PCaloHit & inHit,
171  int & integral,
172  CLHEP::HepRandomEngine* engine) const {
173 
174  PCaloHit hit = inHit;
175  if (theHitCorrection != 0) {
176  hit.setTime(hit.time() + theHitCorrection->delay(hit, engine));
177  }
178 
179  const HcalSimParameters& pars = dynamic_cast<const HcalSimParameters&>(theParameterMap->simParameters(id));
180  theSiPM->setNCells(pars.pixels());
181 
182  double signal = analogSignalAmplitude(id, hit.energy(), pars, engine);
183  int photons = static_cast<int>(signal + 0.5);
184  int pixels = theSiPM->hitCells(engine, photons, integral);
185  integral += pixels;
186  signal = double(pixels);
187 
189 
190  if(pixels > 0)
191  {
192  const CaloVShape * shape = theShapes->shape(id);
193  double jitter = hit.time() - timeOfFlight(id);
194 
195  const double tzero = pars.timePhase() - jitter -
197  double binTime = tzero;
198 
199  for (int bin = 0; bin < result.size(); bin++) {
200  result[bin] += (*shape)(binTime)*signal;
201  binTime += BUNCHSPACE;
202  }
203  }
204 
205  return result;
206 }
207 
209  photonTimeHist const& photons,
210  CLHEP::HepRandomEngine* engine) const {
211  const HcalSimParameters& pars = dynamic_cast<const HcalSimParameters&>(theParameterMap->simParameters(id));
212  theSiPM->setNCells(pars.pixels());
213  theSiPM->setTau(5.);
214  //use to make signal
215  CaloSamples signal( makeBlankSignal(id) );
216  double const dt(theTDCParams.deltaT()/TIMEMULT);
217  double const invdt(1./theTDCParams.deltaT());
218  int sampleBin(0), preciseBin(0);
219  signal.resetPrecise();
220  unsigned int pe(0);
221  double hitPixels(0.), elapsedTime(0.);
222  unsigned int sumPE(0);
223  double sumHits(0.);
224 
225  HcalSiPMShape sipmPulseShape;
226 
227  std::list< std::pair<double, double> > pulses;
228  std::list< std::pair<double, double> >::iterator pulse;
229  double timeDiff, pulseBit;
230  // std::cout << HcalDetId(id) << '\n';
231  for (unsigned int pt(0); pt < photons.size(); ++pt) {
232  pe = photons[pt];
233  sumPE += pe;
234  preciseBin = pt/TIMEMULT;
235  sampleBin = preciseBin/theTDCParams.nbins();
236  if (pe > 0) {
237  hitPixels = theSiPM->hitCells(engine, pe, 0., elapsedTime);
238  sumHits += hitPixels;
239  // std::cout << " elapsedTime: " << elapsedTime
240  // << " sampleBin: " << sampleBin
241  // << " preciseBin: " << preciseBin
242  // << " pe: " << pe
243  // << " hitPixels: " << hitPixels
244  // << '\n';
245  if (pars.doSiPMSmearing()) {
246  pulses.push_back( std::pair<double, double>(elapsedTime, hitPixels) );
247  } else {
248  signal[sampleBin] += hitPixels;
249  hitPixels *= invdt;
250  signal.preciseAtMod(preciseBin) += 0.6*hitPixels;
251  if (preciseBin > 0)
252  signal.preciseAtMod(preciseBin-1) += 0.2*hitPixels;
253  if (preciseBin < signal.preciseSize() -1)
254  signal.preciseAtMod(preciseBin+1) += 0.2*hitPixels;
255  }
256  }
257 
258  if (pars.doSiPMSmearing()) {
259  pulse = pulses.begin();
260  while (pulse != pulses.end()) {
261  timeDiff = elapsedTime - pulse->first;
262  pulseBit = sipmPulseShape(timeDiff)*pulse->second;
263  // std::cout << "pulse t: " << pulse->first
264  // << " pulse A: " << pulse->second
265  // << " timeDiff: " << timeDiff
266  // << " pulseBit: " << pulseBit
267  // << '\n';
268  signal[sampleBin] += pulseBit;
269  signal.preciseAtMod(preciseBin) += pulseBit*invdt;
270  if (sipmPulseShape(timeDiff) < 1e-6)
271  pulse = pulses.erase(pulse);
272  else
273  ++pulse;
274  }
275  }
276  elapsedTime += dt;
277  }
278 
279  // differentiatePreciseSamples(signal, 1.);
280 
281  // std::cout << "sum pe: " << sumPE
282  // << " sum sipm pixels: " << sumHits
283  // << std::endl;
284 
285  return signal;
286 }
287 
289  double diffNorm) const {
290  static double const invdt(1./samples.preciseDeltaT());
291  // double dy(0.);
292  for (int i(0); i < samples.preciseSize(); ++i) {
293  // dy = samples.preciseAt(i+1) - samples.preciseAt(i);
294  samples.preciseAtMod(i) *= invdt*diffNorm;
295  }
296 }
297 
298 double HcalSiPMHitResponse::generatePhotonTime(CLHEP::HepRandomEngine* engine) const {
299  double result(0.);
300  while (true) {
301  result = CLHEP::RandFlat::shoot(engine, Y11RANGE);
302  if (CLHEP::RandFlat::shoot(engine, Y11MAX) < Y11TimePDF(result))
303  return result;
304  }
305 }
306 
308  return exp(-0.0635-0.1518*t)*pow(t, 2.528)/2485.9;
309 }
#define LogDebug(id)
float dt
Definition: AMPTWrapper.h:126
int i
Definition: DBlmapReader.cc:9
virtual void initializeHits()
Initialize hits.
float deltaT() const
A general implementation for the response of a SiPM.
Definition: HcalSiPM.h:20
double time() const
Definition: PCaloHit.h:36
virtual void finalizeHits(CLHEP::HepRandomEngine *) override
Finalize hits.
double energy() const
Definition: PCaloHit.h:29
virtual CaloSamples makeSiPMSignal(const DetId &id, const PCaloHit &hit, int &integral, CLHEP::HepRandomEngine *) const
double generatePhotonTime(CLHEP::HepRandomEngine *) const
virtual bool keepBlank() const
Electronic response of the preamp.
Definition: CaloVShape.h:11
std::multiset< PCaloHit, PCaloHitCompareTimes > SortedHitSet
static double Y11TimePDF(double t)
void resetPrecise()
Definition: CaloSamples.cc:27
int preciseSize() const
get the size
Definition: CaloSamples.h:62
Main class for Parameters in different subdetectors.
tuple result
Definition: mps_fire.py:83
iterator end()
double timePhase() const
the adjustment you need to apply to get the signal where you want it
const int keep
bool isNotFinite(T x)
Definition: isFinite.h:10
int getIntegral(double time)
Creates electronics signals from hits.
virtual void differentiatePreciseSamples(CaloSamples &samples, double diffNorm=1.0) const
void setNCells(int nCells)
Definition: HcalSiPM.cc:104
void setTau(double tau)
Definition: HcalSiPM.h:42
bool doSiPMSmearing() const
virtual const CaloSimParameters & simParameters(const DetId &id) const =0
virtual void add(const PCaloHit &hit, CLHEP::HepRandomEngine *) override
process a single SimHit
virtual bool accepts(const PCaloHit &hit) const =0
unsigned int id() const
Definition: PCaloHit.h:43
double timeOfFlight(const DetId &detId) const
float preciseDeltaT() const
Definition: CaloSamples.h:64
int readoutFrameSize() const
for now, the LinearFrames and trhe digis will be one-to-one.
const CaloVHitCorrection * theHitCorrection
Integral< F, X >::type integral(const F &f)
Definition: Integral.h:69
virtual double delay(const PCaloHit &hit, CLHEP::HepRandomEngine *) const =0
HcalTDCParameters theTDCParams
AnalogSignalMap theAnalogSignalMap
Definition: DetId.h:18
double analogSignalAmplitude(const DetId &id, float energy, const CaloSimParameters &parameters, CLHEP::HepRandomEngine *) const
iterator begin()
std::vector< unsigned int > photonTimeHist
virtual void run(MixCollection< PCaloHit > &hits, CLHEP::HepRandomEngine *) override
Complete cell digitization.
virtual CaloSamples makeBlankSignal(const DetId &detId) const
const CaloShapes * theShapes
const CaloVSimParameterMap * theParameterMap
int size() const
get the size
Definition: CaloSamples.h:24
HcalSiPMHitResponse(const CaloVSimParameterMap *parameterMap, const CaloShapes *shapes)
virtual int hitCells(CLHEP::HepRandomEngine *, unsigned int photons, unsigned int integral=0) const
Definition: HcalSiPM.cc:22
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
void setTime(float t)
Definition: PCaloHit.h:57
static const double tzero[3]
const CaloVHitFilter * theHitFilter
DetId id() const
get the (generic) id
Definition: CaloSamples.h:21
photonTimeMap precisionTimedPhotons
void addToHistory(double time, int pixels)
int binOfMaximum() const
tuple size
Write out results.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
virtual const CaloVShape * shape(const DetId &detId) const
Definition: CaloShapes.h:15