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
dictionary parameters
Definition: Parameters.py:2
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.
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
tuple result
Definition: query.py:137
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