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