CMS 3D CMS Logo

HBHEPhase1Reconstructor.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: RecoLocalCalo/HcalRecProducers
4 // Class: HBHEPhase1Reconstructor
5 //
13 //
14 // Original Author: Igor Volobouev
15 // Created: Tue, 21 Jun 2016 00:56:40 GMT
16 //
17 //
18 
19 
20 // system include files
21 #include <cmath>
22 #include <utility>
23 #include <algorithm>
24 
25 // user include files
32 
35 
40 
44 
46 
48 
53 
56 
57 // Parser for Phase 1 HB/HE reco algorithms
59 
60 // Fetcher for reco algorithm data
62 
63 // Some helper functions
64 namespace {
65  // Class for making SiPM/QIE11 look like HPD/QIE8. HPD/QIE8
66  // needs only pedestal and gain to convert charge into energy.
67  // Due to nonlinearities, response of SiPM/QIE11 is substantially
68  // more complicated. It is possible to calculate all necessary
69  // quantities from the charge and the info stored in the DB every
70  // time the raw charge is needed. However, it does not make sense
71  // to retrieve DB contents stored by channel for every time slice.
72  // Because of this, we look things up only once, in the constructor.
73  template<class DFrame>
74  class RawChargeFromSample
75  {
76  public:
77  inline RawChargeFromSample(const int sipmQTSShift,
78  const int sipmQNTStoSum,
79  const bool saveEffectivePedestal,
80  const HcalDbService& cond,
81  const HcalDetId id,
82  const CaloSamples& cs,
83  const int soi,
84  const DFrame& frame,
85  const int maxTS) {}
86 
87  inline double getRawCharge(const double decodedCharge,
88  const double pedestal) const
89  {return decodedCharge;}
90  };
91 
92  template<>
93  class RawChargeFromSample<QIE11DataFrame>
94  {
95  public:
96  inline RawChargeFromSample(const int sipmQTSShift,
97  const int sipmQNTStoSum,
98  const bool saveEffectivePedestal,
99  const HcalDbService& cond,
100  const HcalDetId id,
101  const CaloSamples& cs,
102  const int soi,
103  const QIE11DataFrame& frame,
104  const int maxTS)
105  : siPMParameter_(*cond.getHcalSiPMParameter(id)),
106  fcByPE_(siPMParameter_.getFCByPE()),
107  corr_(cond.getHcalSiPMCharacteristics()->getNonLinearities(siPMParameter_.getType()))
108  {
109  if (fcByPE_ <= 0.0)
110  throw cms::Exception("HBHEPhase1BadDB")
111  << "Invalid fC/PE conversion factor for SiPM " << id
112  << std::endl;
113 
114  const HcalCalibrations& calib = cond.getHcalCalibrations(id);
115  const double darkCurrent = siPMParameter_.getDarkCurrent();
116  const double lambda = cond.getHcalSiPMCharacteristics()->getCrossTalk(siPMParameter_.getType());
117  const int firstTS = std::max(soi + sipmQTSShift, 0);
118  const int lastTS = std::min(firstTS + sipmQNTStoSum, maxTS);
119  double sipmQ = 0.0;
120 
121  for (int ts = firstTS; ts < lastTS; ++ts)
122  {
123  const double pedestal = calib.pedestal(frame[ts].capid()) +
124  (saveEffectivePedestal ? darkCurrent * 25. / (1. - lambda) : 0.);
125  sipmQ += (cs[ts] - pedestal);
126  }
127 
128  const double effectivePixelsFired = sipmQ/fcByPE_;
129  factor_ = corr_.getRecoCorrectionFactor(effectivePixelsFired);
130  }
131 
132  inline double getRawCharge(const double decodedCharge,
133  const double pedestal) const
134  {
135  return (decodedCharge - pedestal)*factor_ + pedestal;
136 
137  // Old version of TS-by-TS corrections looked as follows:
138  // const double sipmQ = decodedCharge - pedestal;
139  // const double nPixelsFired = sipmQ/fcByPE_;
140  // return sipmQ*corr_.getRecoCorrectionFactor(nPixelsFired) + pedestal;
141  }
142 
143  private:
144  const HcalSiPMParameter& siPMParameter_;
145  double fcByPE_;
146  HcalSiPMnonlinearity corr_;
147  double factor_;
148  };
149 
150  float getTDCTimeFromSample(const QIE11DataFrame::Sample& s)
151  {
152  // Conversion from TDC to ns for the QIE11 chip
153  static const float qie11_tdc_to_ns = 0.5f;
154 
155  // TDC values produced in case the pulse is always above/below
156  // the discriminator
157  static const int qie11_tdc_code_overshoot = 62;
158  static const int qie11_tdc_code_undershoot = 63;
159 
160  const int tdc = s.tdc();
161  float t = qie11_tdc_to_ns*tdc;
162  if (tdc == qie11_tdc_code_overshoot)
164  else if (tdc == qie11_tdc_code_undershoot)
166  return t;
167  }
168 
169  float getTDCTimeFromSample(const HcalQIESample&)
170  {
172  }
173 
174  float getDifferentialChargeGain(const HcalQIECoder& coder,
175  const HcalQIEShape& shape,
176  const unsigned adc,
177  const unsigned capid,
178  const bool isQIE11)
179  {
180  // We have 5-bit ADC mantissa in QIE8 and 6-bit in QIE11
181  static const unsigned mantissaMaskQIE8 = 0x1f;
182  static const unsigned mantissaMaskQIE11 = 0x3f;
183 
184  const float q = coder.charge(shape, adc, capid);
185  const unsigned mantissaMask = isQIE11 ? mantissaMaskQIE11 : mantissaMaskQIE8;
186  const unsigned mantissa = adc & mantissaMask;
187 
188  // First, check if we are in the two lowest or two highest ADC
189  // values for this range. Assume that they have the lowest and
190  // the highest gain in the range, respectively.
191  if (mantissa == 0U || mantissa == mantissaMask - 1U)
192  return coder.charge(shape, adc+1U, capid) - q;
193  else if (mantissa == 1U || mantissa == mantissaMask)
194  return q - coder.charge(shape, adc-1U, capid);
195  else
196  {
197  const float qup = coder.charge(shape, adc+1U, capid);
198  const float qdown = coder.charge(shape, adc-1U, capid);
199  const float upGain = qup - q;
200  const float downGain = q - qdown;
201  const float averageGain = (qup - qdown)/2.f;
202  if (std::abs(upGain - downGain) < 0.01f*averageGain)
203  return averageGain;
204  else
205  {
206  // We are in the gain transition region.
207  // Need to determine if we are in the lower
208  // gain ADC count or in the higher one.
209  // This can be done by figuring out if the
210  // "up" gain is more consistent then the
211  // "down" gain.
212  const float q2up = coder.charge(shape, adc+2U, capid);
213  const float q2down = coder.charge(shape, adc-2U, capid);
214  const float upGain2 = q2up - qup;
215  const float downGain2 = qdown - q2down;
216  if (std::abs(upGain2 - upGain) < std::abs(downGain2 - downGain))
217  return upGain;
218  else
219  return downGain;
220  }
221  }
222  }
223 
224  // The first element of the pair indicates presence of optical
225  // link errors. The second indicated presence of capid errors.
226  std::pair<bool,bool> findHWErrors(const HBHEDataFrame& df,
227  const unsigned len)
228  {
229  bool linkErr = false;
230  bool capidErr = false;
231  if (len)
232  {
233  int expectedCapid = df[0].capid();
234  for (unsigned i=0; i<len; ++i)
235  {
236  if (df[i].er())
237  linkErr = true;
238  if (df[i].capid() != expectedCapid)
239  capidErr = true;
240  expectedCapid = (expectedCapid + 1) % 4;
241  }
242  }
243  return std::pair<bool,bool>(linkErr, capidErr);
244  }
245 
246  std::pair<bool,bool> findHWErrors(const QIE11DataFrame& df,
247  const unsigned /* len */)
248  {
249  return std::pair<bool,bool>(df.linkError(), df.capidError());
250  }
251 
252  std::unique_ptr<HBHEStatusBitSetter> parse_HBHEStatusBitSetter(
253  const edm::ParameterSet& psdigi)
254  {
255  return std::make_unique<HBHEStatusBitSetter>(
256  psdigi.getParameter<double>("nominalPedestal"),
257  psdigi.getParameter<double>("hitEnergyMinimum"),
258  psdigi.getParameter<int>("hitMultiplicityThreshold"),
259  psdigi.getParameter<std::vector<edm::ParameterSet> >("pulseShapeParameterSets"));
260  }
261 
262  std::unique_ptr<HBHEPulseShapeFlagSetter> parse_HBHEPulseShapeFlagSetter(
263  const edm::ParameterSet& psPulseShape, const bool setLegacyFlags)
264  {
265  return std::make_unique<HBHEPulseShapeFlagSetter>(
266  psPulseShape.getParameter<double>("MinimumChargeThreshold"),
267  psPulseShape.getParameter<double>("TS4TS5ChargeThreshold"),
268  psPulseShape.getParameter<double>("TS3TS4ChargeThreshold"),
269  psPulseShape.getParameter<double>("TS3TS4UpperChargeThreshold"),
270  psPulseShape.getParameter<double>("TS5TS6ChargeThreshold"),
271  psPulseShape.getParameter<double>("TS5TS6UpperChargeThreshold"),
272  psPulseShape.getParameter<double>("R45PlusOneRange"),
273  psPulseShape.getParameter<double>("R45MinusOneRange"),
274  psPulseShape.getParameter<unsigned int>("TrianglePeakTS"),
275  psPulseShape.getParameter<std::vector<double> >("LinearThreshold"),
276  psPulseShape.getParameter<std::vector<double> >("LinearCut"),
277  psPulseShape.getParameter<std::vector<double> >("RMS8MaxThreshold"),
278  psPulseShape.getParameter<std::vector<double> >("RMS8MaxCut"),
279  psPulseShape.getParameter<std::vector<double> >("LeftSlopeThreshold"),
280  psPulseShape.getParameter<std::vector<double> >("LeftSlopeCut"),
281  psPulseShape.getParameter<std::vector<double> >("RightSlopeThreshold"),
282  psPulseShape.getParameter<std::vector<double> >("RightSlopeCut"),
283  psPulseShape.getParameter<std::vector<double> >("RightSlopeSmallThreshold"),
284  psPulseShape.getParameter<std::vector<double> >("RightSlopeSmallCut"),
285  psPulseShape.getParameter<std::vector<double> >("TS4TS5LowerThreshold"),
286  psPulseShape.getParameter<std::vector<double> >("TS4TS5LowerCut"),
287  psPulseShape.getParameter<std::vector<double> >("TS4TS5UpperThreshold"),
288  psPulseShape.getParameter<std::vector<double> >("TS4TS5UpperCut"),
289  psPulseShape.getParameter<bool>("UseDualFit"),
290  psPulseShape.getParameter<bool>("TriangleIgnoreSlow"),
291  setLegacyFlags);
292  }
293 }
294 
295 
296 //
297 // class declaration
298 //
300 {
301 public:
304 
305  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
306 
307 private:
308  virtual void beginRun(edm::Run const&, edm::EventSetup const&) override;
309  virtual void endRun(edm::Run const&, edm::EventSetup const&) override;
310  virtual void produce(edm::Event&, const edm::EventSetup&) override;
311 
312  // Configuration parameters
320  bool tsFromDB_;
325 
326  // Parameters for turning status bit setters on/off
333 
334  // Other members
337  std::unique_ptr<AbsHBHEPhase1Algo> reco_;
338  std::unique_ptr<AbsHcalAlgoData> recoConfig_;
339  std::unique_ptr<HcalRecoParams> paramTS_;
340 
341  // Status bit setters
342  const HBHENegativeEFilter* negEFilter_; // We don't manage this pointer
343  std::unique_ptr<HBHEStatusBitSetter> hbheFlagSetterQIE8_;
344  std::unique_ptr<HBHEStatusBitSetter> hbheFlagSetterQIE11_;
345  std::unique_ptr<HBHEPulseShapeFlagSetter> hbhePulseShapeFlagSetterQIE8_;
346  std::unique_ptr<HBHEPulseShapeFlagSetter> hbhePulseShapeFlagSetterQIE11_;
347 
348  // For the function below, arguments "infoColl" and/or "rechits"
349  // are allowed to be null.
350  template<class DataFrame, class Collection>
351  void processData(const Collection& coll,
352  const HcalDbService& cond,
353  const HcalChannelQuality& qual,
355  const bool isRealData,
357  HBHEChannelInfoCollection* infoColl,
359 
360  // Methods for setting rechit status bits
361  void setAsicSpecificBits(const HBHEDataFrame& frame, const HcalCoder& coder,
362  const HBHEChannelInfo& info, const HcalCalibrations& calib,
363  HBHERecHit* rh);
364  void setAsicSpecificBits(const QIE11DataFrame& frame, const HcalCoder& coder,
365  const HBHEChannelInfo& info, const HcalCalibrations& calib,
366  HBHERecHit* rh);
367  void setCommonStatusBits(const HBHEChannelInfo& info, const HcalCalibrations& calib,
368  HBHERecHit* rh);
369 
370  void runHBHENegativeEFilter(const HBHEChannelInfo& info, HBHERecHit* rh);
371 };
372 
373 //
374 // constructors and destructor
375 //
377  : algoConfigClass_(conf.getParameter<std::string>("algoConfigClass")),
378  processQIE8_(conf.getParameter<bool>("processQIE8")),
379  processQIE11_(conf.getParameter<bool>("processQIE11")),
380  saveInfos_(conf.getParameter<bool>("saveInfos")),
381  saveDroppedInfos_(conf.getParameter<bool>("saveDroppedInfos")),
382  makeRecHits_(conf.getParameter<bool>("makeRecHits")),
383  dropZSmarkedPassed_(conf.getParameter<bool>("dropZSmarkedPassed")),
384  tsFromDB_(conf.getParameter<bool>("tsFromDB")),
385  recoParamsFromDB_(conf.getParameter<bool>("recoParamsFromDB")),
386  saveEffectivePedestal_(conf.getParameter<bool>("saveEffectivePedestal")),
387  sipmQTSShift_(conf.getParameter<int>("sipmQTSShift")),
388  sipmQNTStoSum_(conf.getParameter<int>("sipmQNTStoSum")),
389  setNegativeFlagsQIE8_(conf.getParameter<bool>("setNegativeFlagsQIE8")),
390  setNegativeFlagsQIE11_(conf.getParameter<bool>("setNegativeFlagsQIE11")),
391  setNoiseFlagsQIE8_(conf.getParameter<bool>("setNoiseFlagsQIE8")),
392  setNoiseFlagsQIE11_(conf.getParameter<bool>("setNoiseFlagsQIE11")),
393  setPulseShapeFlagsQIE8_(conf.getParameter<bool>("setPulseShapeFlagsQIE8")),
394  setPulseShapeFlagsQIE11_(conf.getParameter<bool>("setPulseShapeFlagsQIE11")),
395  reco_(parseHBHEPhase1AlgoDescription(conf.getParameter<edm::ParameterSet>("algorithm"))),
396  negEFilter_(nullptr)
397 {
398  // Check that the reco algorithm has been successfully configured
399  if (!reco_.get())
400  throw cms::Exception("HBHEPhase1BadConfig")
401  << "Invalid HBHEPhase1Algo algorithm configuration"
402  << std::endl;
403 
404  // Configure the status bit setters that have been turned on
405  if (setNoiseFlagsQIE8_)
406  hbheFlagSetterQIE8_ = parse_HBHEStatusBitSetter(
407  conf.getParameter<edm::ParameterSet>("flagParametersQIE8"));
408 
410  hbheFlagSetterQIE11_ = parse_HBHEStatusBitSetter(
411  conf.getParameter<edm::ParameterSet>("flagParametersQIE11"));
412 
414  hbhePulseShapeFlagSetterQIE8_ = parse_HBHEPulseShapeFlagSetter(
415  conf.getParameter<edm::ParameterSet>("pulseShapeParametersQIE8"),
416  conf.getParameter<bool>("setLegacyFlagsQIE8"));
417 
419  hbhePulseShapeFlagSetterQIE11_ = parse_HBHEPulseShapeFlagSetter(
420  conf.getParameter<edm::ParameterSet>("pulseShapeParametersQIE11"),
421  conf.getParameter<bool>("setLegacyFlagsQIE11"));
422 
423  // Consumes and produces statements
424  if (processQIE8_)
425  tok_qie8_ = consumes<HBHEDigiCollection>(
426  conf.getParameter<edm::InputTag>("digiLabelQIE8"));
427 
428  if (processQIE11_)
429  tok_qie11_ = consumes<QIE11DigiCollection>(
430  conf.getParameter<edm::InputTag>("digiLabelQIE11"));
431 
432  if (saveInfos_)
433  produces<HBHEChannelInfoCollection>();
434 
435  if (makeRecHits_)
436  produces<HBHERecHitCollection>();
437 }
438 
439 
441 {
442  // do anything here that needs to be done at destruction time
443  // (e.g. close files, deallocate resources etc.)
444 }
445 
446 
447 //
448 // member functions
449 //
450 template<class DFrame, class Collection>
452  const HcalDbService& cond,
453  const HcalChannelQuality& qual,
455  const bool isRealData,
456  HBHEChannelInfo* channelInfo,
459 {
460  // If "saveDroppedInfos_" flag is set, fill the info with something
461  // meaningful even if the database tells us to drop this channel.
462  // Note that this flag affects only "infos", the rechits are still
463  // not going to be constructed from such channels.
464  const bool skipDroppedChannels = !(infos && saveDroppedInfos_);
465 
466  // Iterate over the input collection
467  for (typename Collection::const_iterator it = coll.begin();
468  it != coll.end(); ++it)
469  {
470  const DFrame& frame(*it);
471  const HcalDetId cell(frame.id());
472 
473  // Protection against calibration channels which are not
474  // in the database but can still come in the QIE11DataFrame
475  // in the laser calibs, etc.
476  const HcalSubdetector subdet = cell.subdet();
477  if (!(subdet == HcalSubdetector::HcalBarrel ||
478  subdet == HcalSubdetector::HcalEndcap ||
479  subdet == HcalSubdetector::HcalOuter))
480  continue;
481 
482  // Check if the database tells us to drop this channel
483  const HcalChannelStatus* mydigistatus = qual.getValues(cell.rawId());
484  const bool taggedBadByDb = severity.dropChannel(mydigistatus->getValue());
485  if (taggedBadByDb && skipDroppedChannels)
486  continue;
487 
488  // Check if the channel is zero suppressed
489  bool dropByZS = false;
491  if (frame.zsMarkAndPass())
492  dropByZS = true;
493  if (dropByZS && skipDroppedChannels)
494  continue;
495 
496  // Basic ADC decoding tools
497  const HcalRecoParam* param_ts = paramTS_->getValues(cell.rawId());
498  const HcalCalibrations& calib = cond.getHcalCalibrations(cell);
499  const HcalCalibrationWidths& calibWidth = cond.getHcalCalibrationWidths(cell);
500  const HcalQIECoder* channelCoder = cond.getHcalCoder(cell);
501  const HcalQIEShape* shape = cond.getHcalShape(channelCoder);
502  const HcalCoderDb coder(*channelCoder, *shape);
503 
504  // needed for the dark current in the M2
505  const HcalSiPMParameter& siPMParameter(*cond.getHcalSiPMParameter(cell));
506  const double darkCurrent = siPMParameter.getDarkCurrent();
507  const double fcByPE = siPMParameter.getFCByPE();
508  const double lambda = cond.getHcalSiPMCharacteristics()->getCrossTalk(siPMParameter.getType());
509 
510  // ADC to fC conversion
511  CaloSamples cs;
512  coder.adc2fC(frame, cs);
513 
514  // Prepare to iterate over time slices
515  const int nRead = cs.size();
516  const int maxTS = std::min(nRead, static_cast<int>(HBHEChannelInfo::MAXSAMPLES));
517  const int soi = tsFromDB_ ? param_ts->firstSample() : frame.presamples();
518  const RawChargeFromSample<DFrame> rcfs(sipmQTSShift_, sipmQNTStoSum_, saveEffectivePedestal_,
519  cond, cell, cs, soi, frame, maxTS);
520  int soiCapid = 4;
521 
522  // Go over time slices and fill the samples
523  for (int ts = 0; ts < maxTS; ++ts)
524  {
525  auto s(frame[ts]);
526  const uint8_t adc = s.adc();
527  const int capid = s.capid();
528  //optionally store "effective" pedestal = QIE contribution (default, from calib.pedestal()) + SiPM contribution (dark current + crosstalk)
529  //only done for pedestal mean, to be used for pedestal subtraction downstream
530  const double pedestal = calib.pedestal(capid) + (saveEffectivePedestal_ ? darkCurrent * 25. / (1. - lambda) : 0.);
531  const double pedestalWidth = calibWidth.pedestal(capid);
532  const double gain = calib.respcorrgain(capid);
533  const double gainWidth = calibWidth.gain(capid);
534  const double rawCharge = rcfs.getRawCharge(cs[ts], pedestal);
535  const float t = getTDCTimeFromSample(s);
536  const float dfc = getDifferentialChargeGain(*channelCoder, *shape, adc,
537  capid, channelInfo->hasTimeInfo());
538  channelInfo->setSample(ts, adc, dfc, rawCharge,
539  pedestal, pedestalWidth,
540  gain, gainWidth, t);
541  if (ts == soi)
542  soiCapid = capid;
543  }
544 
545  // Fill the overall channel info items
546  const int pulseShapeID = param_ts->pulseShapeID();
547  const std::pair<bool,bool> hwerr = findHWErrors(frame, maxTS);
548  channelInfo->setChannelInfo(cell, pulseShapeID, maxTS, soi, soiCapid,
549  darkCurrent, fcByPE, lambda,
550  hwerr.first, hwerr.second,
551  taggedBadByDb || dropByZS);
552 
553  // If needed, add the channel info to the output collection
554  const bool makeThisRechit = !channelInfo->isDropped();
555  if (infos && (saveDroppedInfos_ || makeThisRechit))
556  infos->push_back(*channelInfo);
557 
558  // Reconstruct the rechit
559  if (rechits && makeThisRechit)
560  {
561  const HcalRecoParam* pptr = nullptr;
562  if (recoParamsFromDB_)
563  pptr = param_ts;
564  HBHERecHit rh = reco_->reconstruct(*channelInfo, pptr, calib, isRealData);
565  if (rh.id().rawId())
566  {
567  setAsicSpecificBits(frame, coder, *channelInfo, calib, &rh);
568  setCommonStatusBits(*channelInfo, calib, &rh);
569  rechits->push_back(rh);
570  }
571  }
572  }
573 }
574 
576  const HBHEChannelInfo& /* info */, const HcalCalibrations& /* calib */,
577  HBHERecHit* /* rh */)
578 {
579 }
580 
582  const HBHEDataFrame& frame, const HcalCoder& coder,
583  const HBHEChannelInfo& info, const HcalCalibrations& calib,
584  HBHERecHit* rh)
585 {
586  if (setNoiseFlagsQIE8_)
587  hbheFlagSetterQIE8_->rememberHit(*rh);
588 
590  hbhePulseShapeFlagSetterQIE8_->SetPulseShapeFlags(*rh, frame, coder, calib);
591 
593  runHBHENegativeEFilter(info, rh);
594 }
595 
597  const QIE11DataFrame& frame, const HcalCoder& coder,
598  const HBHEChannelInfo& info, const HcalCalibrations& calib,
599  HBHERecHit* rh)
600 {
602  hbheFlagSetterQIE11_->rememberHit(*rh);
603 
605  hbhePulseShapeFlagSetterQIE11_->SetPulseShapeFlags(*rh, frame, coder, calib);
606 
608  runHBHENegativeEFilter(info, rh);
609 }
610 
612  HBHERecHit* rh)
613 {
614  double ts[HBHEChannelInfo::MAXSAMPLES];
615  const unsigned nRead = info.nSamples();
616  for (unsigned i=0; i<nRead; ++i)
617  ts[i] = info.tsCharge(i);
618  const bool passes = negEFilter_->checkPassFilter(info.id(), &ts[0], nRead);
619  if (!passes)
621 }
622 
623 // ------------ method called to produce the data ------------
624 void
626 {
627  using namespace edm;
628 
629  // Get the Hcal topology
631  eventSetup.get<HcalRecNumberingRecord>().get(htopo);
632  paramTS_->setTopo(htopo.product());
633 
634  // Fetch the calibrations
635  ESHandle<HcalDbService> conditions;
636  eventSetup.get<HcalDbRecord>().get(conditions);
637 
639  eventSetup.get<HcalChannelQualityRcd>().get("withTopo", p);
640 
642  eventSetup.get<HcalSeverityLevelComputerRcd>().get(mycomputer);
643 
644  // Configure the negative energy filter
647  {
648  eventSetup.get<HBHENegativeEFilterRcd>().get(negEHandle);
649  negEFilter_ = negEHandle.product();
650  }
651 
652  // Find the input data
653  unsigned maxOutputSize = 0;
655  if (processQIE8_)
656  {
657  e.getByToken(tok_qie8_, hbDigis);
658  maxOutputSize += hbDigis->size();
659  }
660 
662  if (processQIE11_)
663  {
664  e.getByToken(tok_qie11_, heDigis);
665  maxOutputSize += heDigis->size();
666  }
667 
668  // Create new output collections
669  std::unique_ptr<HBHEChannelInfoCollection> infos;
670  if (saveInfos_)
671  {
672  infos = std::make_unique<HBHEChannelInfoCollection>();
673  infos->reserve(maxOutputSize);
674  }
675 
676  std::unique_ptr<HBHERecHitCollection> out;
677  if (makeRecHits_)
678  {
679  out = std::make_unique<HBHERecHitCollection>();
680  out->reserve(maxOutputSize);
681  }
682 
683  // Process the input collections, filling the output ones
684  const bool isData = e.isRealData();
685  if (processQIE8_)
686  {
687  if (setNoiseFlagsQIE8_)
688  hbheFlagSetterQIE8_->Clear();
689 
690  HBHEChannelInfo channelInfo(false);
691  processData<HBHEDataFrame>(*hbDigis, *conditions, *p, *mycomputer,
692  isData, &channelInfo, infos.get(), out.get());
693  if (setNoiseFlagsQIE8_)
694  hbheFlagSetterQIE8_->SetFlagsFromRecHits(*out);
695  }
696 
697  if (processQIE11_)
698  {
700  hbheFlagSetterQIE11_->Clear();
701 
702  HBHEChannelInfo channelInfo(true);
703  processData<QIE11DataFrame>(*heDigis, *conditions, *p, *mycomputer,
704  isData, &channelInfo, infos.get(), out.get());
706  hbheFlagSetterQIE11_->SetFlagsFromRecHits(*out);
707  }
708 
709  // Add the output collections to the event record
710  if (saveInfos_)
711  e.put(std::move(infos));
712  if (makeRecHits_)
713  e.put(std::move(out));
714 }
715 
716 // ------------ method called when starting to processes a run ------------
717 void
719 {
721  es.get<HcalRecoParamsRcd>().get(p);
722  paramTS_ = std::make_unique<HcalRecoParams>(*p.product());
723 
724  if (reco_->isConfigurable())
725  {
727  if (!recoConfig_.get())
728  throw cms::Exception("HBHEPhase1BadConfig")
729  << "Invalid HBHEPhase1Reconstructor \"algoConfigClass\" parameter value \""
730  << algoConfigClass_ << '"' << std::endl;
731  if (!reco_->configure(recoConfig_.get()))
732  throw cms::Exception("HBHEPhase1BadConfig")
733  << "Failed to configure HBHEPhase1Algo algorithm from EventSetup"
734  << std::endl;
735  }
736 
738  {
740  es.get<HcalFrontEndMapRcd>().get(hfemap);
741  if (hfemap.isValid())
742  {
743  if (setNoiseFlagsQIE8_)
744  hbheFlagSetterQIE8_->SetFrontEndMap(hfemap.product());
746  hbheFlagSetterQIE11_->SetFrontEndMap(hfemap.product());
747  }
748  else
749  edm::LogWarning("EventSetup") <<
750  "HBHEPhase1Reconstructor failed to get HcalFrontEndMap!" << std::endl;
751  }
752 
753  reco_->beginRun(r, es);
754 }
755 
756 void
758 {
759  reco_->endRun();
760 }
761 
762 #define add_param_set(name) \
763  edm::ParameterSetDescription name; \
764  name.setAllowAnything(); \
765  desc.add<edm::ParameterSetDescription>(#name, name)
766 
767 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
768 void
770 {
772 
773  desc.add<edm::InputTag>("digiLabelQIE8");
774  desc.add<edm::InputTag>("digiLabelQIE11");
775  desc.add<std::string>("algoConfigClass");
776  desc.add<bool>("processQIE8");
777  desc.add<bool>("processQIE11");
778  desc.add<bool>("saveInfos");
779  desc.add<bool>("saveDroppedInfos");
780  desc.add<bool>("makeRecHits");
781  desc.add<bool>("dropZSmarkedPassed");
782  desc.add<bool>("tsFromDB");
783  desc.add<bool>("recoParamsFromDB");
784  desc.add<bool>("saveEffectivePedestal", false);
785  desc.add<int>("sipmQTSShift", 0);
786  desc.add<int>("sipmQNTStoSum", 3);
787  desc.add<bool>("setNegativeFlagsQIE8");
788  desc.add<bool>("setNegativeFlagsQIE11");
789  desc.add<bool>("setNoiseFlagsQIE8");
790  desc.add<bool>("setNoiseFlagsQIE11");
791  desc.add<bool>("setPulseShapeFlagsQIE8");
792  desc.add<bool>("setPulseShapeFlagsQIE11");
793  desc.add<bool>("setLegacyFlagsQIE8");
794  desc.add<bool>("setLegacyFlagsQIE11");
795 
801 
802  descriptions.addDefault(desc);
803 }
804 
805 //define this as a plug-in
int adc(sample_type sample)
get the ADC sample (12 bits)
HBHEPhase1Reconstructor(const edm::ParameterSet &)
std::unique_ptr< HBHEPulseShapeFlagSetter > hbhePulseShapeFlagSetterQIE8_
unsigned int firstSample() const
Definition: HcalRecoParam.h:32
T getParameter(std::string const &) const
const HBHENegativeEFilter * negEFilter_
double gain(int fCapId) const
get gain width for capid=0..3
static const TGPicture * info(bool iBackgroundIsBlack)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:122
double respcorrgain(int fCapId) const
get response corrected gain for capid=0..3
auto_ptr< ClusterSequence > cs
int maxTS(DIGI const &digi, double ped=0)
Definition: Utilities.h:51
HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:49
bool hasTimeInfo() const
void setCommonStatusBits(const HBHEChannelInfo &info, const HcalCalibrations &calib, HBHERecHit *rh)
std::unique_ptr< HBHEStatusBitSetter > hbheFlagSetterQIE11_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:460
std::unique_ptr< HBHEStatusBitSetter > hbheFlagSetterQIE8_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
virtual void beginRun(edm::Run const &, edm::EventSetup const &) override
HcalDetId id() const
get the id
Definition: HBHERecHit.h:25
void setFlagField(uint32_t value, int base, int width=1)
Definition: CaloRecHit.cc:20
void push_back(T const &t)
double pedestal(int fCapId) const
get pedestal for capid=0..3
const Item * getValues(DetId fId, bool throwOnFail=true) const
#define nullptr
std::unique_ptr< AbsHcalAlgoData > fetchHcalAlgoData(const std::string &className, const edm::EventSetup &es)
void setSample(const unsigned ts, const uint8_t rawADC, const float differentialChargeGain, const double q, const double ped, const double pedWidth, const double g, const double gainWidth, const float t)
bool isRealData() const
Definition: EventBase.h:64
HcalDetId id() const
constexpr float UNKNOWN_T_UNDERSHOOT
float getCrossTalk(int type) const
get cross talk
bool checkPassFilter(const HcalDetId &id, const double *ts, unsigned lenTS) const
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
std::unique_ptr< HcalRecoParams > paramTS_
void addDefault(ParameterSetDescription const &psetDescription)
constexpr float UNKNOWN_T_OVERSHOOT
static const unsigned MAXSAMPLES
double pedestal(int fCapId) const
get pedestal width for capid=0..3
virtual void endRun(edm::Run const &, edm::EventSetup const &) override
bool linkError() const
void processData(const Collection &coll, const HcalDbService &cond, const HcalChannelQuality &qual, const HcalSeverityLevelComputer &severity, const bool isRealData, HBHEChannelInfo *info, HBHEChannelInfoCollection *infoColl, HBHERecHitCollection *rechits)
virtual void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const
Definition: HcalCoderDb.cc:68
edm::EDGetTokenT< QIE11DigiCollection > tok_qie11_
edm::EDGetTokenT< HBHEDigiCollection > tok_qie8_
std::unique_ptr< AbsHBHEPhase1Algo > parseHBHEPhase1AlgoDescription(const edm::ParameterSet &ps)
HcalSubdetector
Definition: HcalAssistant.h:31
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool dropChannel(const uint32_t &mystatus) const
double f[11][100]
double tsCharge(const unsigned ts) const
std::unique_ptr< AbsHBHEPhase1Algo > reco_
T min(T a, T b)
Definition: MathUtil.h:58
float getDarkCurrent() const
get dark current
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void runHBHENegativeEFilter(const HBHEChannelInfo &info, HBHERecHit *rh)
const HcalCalibrationWidths & getHcalCalibrationWidths(const HcalGenericDetId &fId) const
bool capidError() const
unsigned int pulseShapeID() const
Definition: HcalRecoParam.h:34
std::unique_ptr< HBHEPulseShapeFlagSetter > hbhePulseShapeFlagSetterQIE11_
JetCorrectorParametersCollection coll
Definition: classes.h:10
int size() const
get the size
Definition: CaloSamples.h:24
const T & get() const
Definition: EventSetup.h:56
const HcalSiPMCharacteristics * getHcalSiPMCharacteristics() const
const HcalQIECoder * getHcalCoder(const HcalGenericDetId &fId) const
void setAsicSpecificBits(const HBHEDataFrame &frame, const HcalCoder &coder, const HBHEChannelInfo &info, const HcalCalibrations &calib, HBHERecHit *rh)
const HcalQIEShape * getHcalShape(const HcalGenericDetId &fId) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
constexpr float UNKNOWN_T_NOTDC
Definition: plugin.cc:24
HLT enums.
size_type size() const
void setChannelInfo(const HcalDetId &detId, const int recoShape, const unsigned nSamp, const unsigned iSoi, const int iCapid, const double darkCurrent, const double fcByPE, const double lambda, const bool linkError, const bool capidError, const bool dropThisChannel)
bool isDropped() const
std::unique_ptr< AbsHcalAlgoData > recoConfig_
unsigned nSamples() const
uint32_t getValue() const
bool isValid() const
Definition: ESHandle.h:47
const HcalCalibrations & getHcalCalibrations(const HcalGenericDetId &fId) const
const HcalSiPMParameter * getHcalSiPMParameter(const HcalGenericDetId &fId) const
T const * product() const
Definition: ESHandle.h:86
def move(src, dest)
Definition: eostools.py:510
virtual void produce(edm::Event &, const edm::EventSetup &) override
Definition: Run.h:42
#define add_param_set(name)
float charge(const HcalQIEShape &fShape, unsigned fAdc, unsigned fCapId) const
ADC [0..127] + capid [0..3] -> fC conversion.
Definition: HcalQIECoder.cc:22