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 HcalDbService& cond,
80  const HcalDetId id,
81  const CaloSamples& cs,
82  const int soi,
83  const DFrame& frame,
84  const int maxTS) {}
85 
86  inline double getRawCharge(const double decodedCharge,
87  const double pedestal) const
88  {return decodedCharge;}
89  };
90 
91  template<>
92  class RawChargeFromSample<QIE11DataFrame>
93  {
94  public:
95  inline RawChargeFromSample(const int sipmQTSShift,
96  const int sipmQNTStoSum,
97  const HcalDbService& cond,
98  const HcalDetId id,
99  const CaloSamples& cs,
100  const int soi,
101  const QIE11DataFrame& frame,
102  const int maxTS)
103  : siPMParameter_(*cond.getHcalSiPMParameter(id)),
104  fcByPE_(siPMParameter_.getFCByPE()),
105  corr_(cond.getHcalSiPMCharacteristics()->getNonLinearities(siPMParameter_.getType()))
106  {
107  if (fcByPE_ <= 0.0)
108  throw cms::Exception("HBHEPhase1BadDB")
109  << "Invalid fC/PE conversion factor for SiPM " << id
110  << std::endl;
111 
112  const HcalCalibrations& calib = cond.getHcalCalibrations(id);
113  const int firstTS = std::max(soi + sipmQTSShift, 0);
114  const int lastTS = std::min(firstTS + sipmQNTStoSum, maxTS);
115  double sipmQ = 0.0;
116 
117  for (int ts = firstTS; ts < lastTS; ++ts)
118  {
119  const double pedestal = calib.pedestal(frame[ts].capid());
120  sipmQ += (cs[ts] - pedestal);
121  }
122 
123  const double effectivePixelsFired = sipmQ/fcByPE_;
124  factor_ = corr_.getRecoCorrectionFactor(effectivePixelsFired);
125  }
126 
127  inline double getRawCharge(const double decodedCharge,
128  const double pedestal) const
129  {
130  return (decodedCharge - pedestal)*factor_ + pedestal;
131 
132  // Old version of TS-by-TS corrections looked as follows:
133  // const double sipmQ = decodedCharge - pedestal;
134  // const double nPixelsFired = sipmQ/fcByPE_;
135  // return sipmQ*corr_.getRecoCorrectionFactor(nPixelsFired) + pedestal;
136  }
137 
138  private:
139  const HcalSiPMParameter& siPMParameter_;
140  double fcByPE_;
141  HcalSiPMnonlinearity corr_;
142  double factor_;
143  };
144 
145  float getTDCTimeFromSample(const QIE11DataFrame::Sample& s)
146  {
147  return HcalSpecialTimes::getTDCTime(s.tdc());
148  }
149 
150  float getTDCTimeFromSample(const HcalQIESample&)
151  {
153  }
154 
155  float getDifferentialChargeGain(const HcalQIECoder& coder,
156  const HcalQIEShape& shape,
157  const unsigned adc,
158  const unsigned capid,
159  const bool isQIE11)
160  {
161  // We have 5-bit ADC mantissa in QIE8 and 6-bit in QIE11
162  static const unsigned mantissaMaskQIE8 = 0x1f;
163  static const unsigned mantissaMaskQIE11 = 0x3f;
164 
165  const float q = coder.charge(shape, adc, capid);
166  const unsigned mantissaMask = isQIE11 ? mantissaMaskQIE11 : mantissaMaskQIE8;
167  const unsigned mantissa = adc & mantissaMask;
168 
169  // First, check if we are in the two lowest or two highest ADC
170  // values for this range. Assume that they have the lowest and
171  // the highest gain in the range, respectively.
172  if (mantissa == 0U || mantissa == mantissaMask - 1U)
173  return coder.charge(shape, adc+1U, capid) - q;
174  else if (mantissa == 1U || mantissa == mantissaMask)
175  return q - coder.charge(shape, adc-1U, capid);
176  else
177  {
178  const float qup = coder.charge(shape, adc+1U, capid);
179  const float qdown = coder.charge(shape, adc-1U, capid);
180  const float upGain = qup - q;
181  const float downGain = q - qdown;
182  const float averageGain = (qup - qdown)/2.f;
183  if (std::abs(upGain - downGain) < 0.01f*averageGain)
184  return averageGain;
185  else
186  {
187  // We are in the gain transition region.
188  // Need to determine if we are in the lower
189  // gain ADC count or in the higher one.
190  // This can be done by figuring out if the
191  // "up" gain is more consistent then the
192  // "down" gain.
193  const float q2up = coder.charge(shape, adc+2U, capid);
194  const float q2down = coder.charge(shape, adc-2U, capid);
195  const float upGain2 = q2up - qup;
196  const float downGain2 = qdown - q2down;
197  if (std::abs(upGain2 - upGain) < std::abs(downGain2 - downGain))
198  return upGain;
199  else
200  return downGain;
201  }
202  }
203  }
204 
205  // The first element of the pair indicates presence of optical
206  // link errors. The second indicated presence of capid errors.
207  std::pair<bool,bool> findHWErrors(const HBHEDataFrame& df,
208  const unsigned len)
209  {
210  bool linkErr = false;
211  bool capidErr = false;
212  if (len)
213  {
214  int expectedCapid = df[0].capid();
215  for (unsigned i=0; i<len; ++i)
216  {
217  if (df[i].er())
218  linkErr = true;
219  if (df[i].capid() != expectedCapid)
220  capidErr = true;
221  expectedCapid = (expectedCapid + 1) % 4;
222  }
223  }
224  return std::pair<bool,bool>(linkErr, capidErr);
225  }
226 
227  std::pair<bool,bool> findHWErrors(const QIE11DataFrame& df,
228  const unsigned /* len */)
229  {
230  return std::pair<bool,bool>(df.linkError(), df.capidError());
231  }
232 
233  std::unique_ptr<HBHEStatusBitSetter> parse_HBHEStatusBitSetter(
234  const edm::ParameterSet& psdigi)
235  {
236  return std::make_unique<HBHEStatusBitSetter>(
237  psdigi.getParameter<double>("nominalPedestal"),
238  psdigi.getParameter<double>("hitEnergyMinimum"),
239  psdigi.getParameter<int>("hitMultiplicityThreshold"),
240  psdigi.getParameter<std::vector<edm::ParameterSet> >("pulseShapeParameterSets"));
241  }
242 
243  std::unique_ptr<HBHEPulseShapeFlagSetter> parse_HBHEPulseShapeFlagSetter(
244  const edm::ParameterSet& psPulseShape, const bool setLegacyFlags)
245  {
246  return std::make_unique<HBHEPulseShapeFlagSetter>(
247  psPulseShape.getParameter<double>("MinimumChargeThreshold"),
248  psPulseShape.getParameter<double>("TS4TS5ChargeThreshold"),
249  psPulseShape.getParameter<double>("TS3TS4ChargeThreshold"),
250  psPulseShape.getParameter<double>("TS3TS4UpperChargeThreshold"),
251  psPulseShape.getParameter<double>("TS5TS6ChargeThreshold"),
252  psPulseShape.getParameter<double>("TS5TS6UpperChargeThreshold"),
253  psPulseShape.getParameter<double>("R45PlusOneRange"),
254  psPulseShape.getParameter<double>("R45MinusOneRange"),
255  psPulseShape.getParameter<unsigned int>("TrianglePeakTS"),
256  psPulseShape.getParameter<std::vector<double> >("LinearThreshold"),
257  psPulseShape.getParameter<std::vector<double> >("LinearCut"),
258  psPulseShape.getParameter<std::vector<double> >("RMS8MaxThreshold"),
259  psPulseShape.getParameter<std::vector<double> >("RMS8MaxCut"),
260  psPulseShape.getParameter<std::vector<double> >("LeftSlopeThreshold"),
261  psPulseShape.getParameter<std::vector<double> >("LeftSlopeCut"),
262  psPulseShape.getParameter<std::vector<double> >("RightSlopeThreshold"),
263  psPulseShape.getParameter<std::vector<double> >("RightSlopeCut"),
264  psPulseShape.getParameter<std::vector<double> >("RightSlopeSmallThreshold"),
265  psPulseShape.getParameter<std::vector<double> >("RightSlopeSmallCut"),
266  psPulseShape.getParameter<std::vector<double> >("TS4TS5LowerThreshold"),
267  psPulseShape.getParameter<std::vector<double> >("TS4TS5LowerCut"),
268  psPulseShape.getParameter<std::vector<double> >("TS4TS5UpperThreshold"),
269  psPulseShape.getParameter<std::vector<double> >("TS4TS5UpperCut"),
270  psPulseShape.getParameter<bool>("UseDualFit"),
271  psPulseShape.getParameter<bool>("TriangleIgnoreSlow"),
272  setLegacyFlags);
273  }
274 }
275 
276 
277 //
278 // class declaration
279 //
281 {
282 public:
284  ~HBHEPhase1Reconstructor() override;
285 
286  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
287 
288 private:
289  void beginRun(edm::Run const&, edm::EventSetup const&) override;
290  void endRun(edm::Run const&, edm::EventSetup const&) override;
291  void produce(edm::Event&, const edm::EventSetup&) override;
292 
293  // Configuration parameters
301  bool tsFromDB_;
306 
307  // Parameters for turning status bit setters on/off
314 
315  // Other members
318  std::unique_ptr<AbsHBHEPhase1Algo> reco_;
319  std::unique_ptr<AbsHcalAlgoData> recoConfig_;
320  std::unique_ptr<HcalRecoParams> paramTS_;
321 
322  // Status bit setters
323  const HBHENegativeEFilter* negEFilter_; // We don't manage this pointer
324  std::unique_ptr<HBHEStatusBitSetter> hbheFlagSetterQIE8_;
325  std::unique_ptr<HBHEStatusBitSetter> hbheFlagSetterQIE11_;
326  std::unique_ptr<HBHEPulseShapeFlagSetter> hbhePulseShapeFlagSetterQIE8_;
327  std::unique_ptr<HBHEPulseShapeFlagSetter> hbhePulseShapeFlagSetterQIE11_;
328 
329  // For the function below, arguments "infoColl" and/or "rechits"
330  // are allowed to be null.
331  template<class DataFrame, class Collection>
332  void processData(const Collection& coll,
333  const HcalDbService& cond,
334  const HcalChannelQuality& qual,
336  const bool isRealData,
338  HBHEChannelInfoCollection* infoColl,
340 
341  // Methods for setting rechit status bits
342  void setAsicSpecificBits(const HBHEDataFrame& frame, const HcalCoder& coder,
343  const HBHEChannelInfo& info, const HcalCalibrations& calib,
344  HBHERecHit* rh);
345  void setAsicSpecificBits(const QIE11DataFrame& frame, const HcalCoder& coder,
346  const HBHEChannelInfo& info, const HcalCalibrations& calib,
347  HBHERecHit* rh);
348  void setCommonStatusBits(const HBHEChannelInfo& info, const HcalCalibrations& calib,
349  HBHERecHit* rh);
350 
351  void runHBHENegativeEFilter(const HBHEChannelInfo& info, HBHERecHit* rh);
352 };
353 
354 //
355 // constructors and destructor
356 //
358  : algoConfigClass_(conf.getParameter<std::string>("algoConfigClass")),
359  processQIE8_(conf.getParameter<bool>("processQIE8")),
360  processQIE11_(conf.getParameter<bool>("processQIE11")),
361  saveInfos_(conf.getParameter<bool>("saveInfos")),
362  saveDroppedInfos_(conf.getParameter<bool>("saveDroppedInfos")),
363  makeRecHits_(conf.getParameter<bool>("makeRecHits")),
364  dropZSmarkedPassed_(conf.getParameter<bool>("dropZSmarkedPassed")),
365  tsFromDB_(conf.getParameter<bool>("tsFromDB")),
366  recoParamsFromDB_(conf.getParameter<bool>("recoParamsFromDB")),
367  saveEffectivePedestal_(conf.getParameter<bool>("saveEffectivePedestal")),
368  sipmQTSShift_(conf.getParameter<int>("sipmQTSShift")),
369  sipmQNTStoSum_(conf.getParameter<int>("sipmQNTStoSum")),
370  setNegativeFlagsQIE8_(conf.getParameter<bool>("setNegativeFlagsQIE8")),
371  setNegativeFlagsQIE11_(conf.getParameter<bool>("setNegativeFlagsQIE11")),
372  setNoiseFlagsQIE8_(conf.getParameter<bool>("setNoiseFlagsQIE8")),
373  setNoiseFlagsQIE11_(conf.getParameter<bool>("setNoiseFlagsQIE11")),
374  setPulseShapeFlagsQIE8_(conf.getParameter<bool>("setPulseShapeFlagsQIE8")),
375  setPulseShapeFlagsQIE11_(conf.getParameter<bool>("setPulseShapeFlagsQIE11")),
376  reco_(parseHBHEPhase1AlgoDescription(conf.getParameter<edm::ParameterSet>("algorithm"))),
377  negEFilter_(nullptr)
378 {
379  // Check that the reco algorithm has been successfully configured
380  if (!reco_.get())
381  throw cms::Exception("HBHEPhase1BadConfig")
382  << "Invalid HBHEPhase1Algo algorithm configuration"
383  << std::endl;
384 
385  // Configure the status bit setters that have been turned on
386  if (setNoiseFlagsQIE8_)
387  hbheFlagSetterQIE8_ = parse_HBHEStatusBitSetter(
388  conf.getParameter<edm::ParameterSet>("flagParametersQIE8"));
389 
391  hbheFlagSetterQIE11_ = parse_HBHEStatusBitSetter(
392  conf.getParameter<edm::ParameterSet>("flagParametersQIE11"));
393 
395  hbhePulseShapeFlagSetterQIE8_ = parse_HBHEPulseShapeFlagSetter(
396  conf.getParameter<edm::ParameterSet>("pulseShapeParametersQIE8"),
397  conf.getParameter<bool>("setLegacyFlagsQIE8"));
398 
400  hbhePulseShapeFlagSetterQIE11_ = parse_HBHEPulseShapeFlagSetter(
401  conf.getParameter<edm::ParameterSet>("pulseShapeParametersQIE11"),
402  conf.getParameter<bool>("setLegacyFlagsQIE11"));
403 
404  // Consumes and produces statements
405  if (processQIE8_)
406  tok_qie8_ = consumes<HBHEDigiCollection>(
407  conf.getParameter<edm::InputTag>("digiLabelQIE8"));
408 
409  if (processQIE11_)
410  tok_qie11_ = consumes<QIE11DigiCollection>(
411  conf.getParameter<edm::InputTag>("digiLabelQIE11"));
412 
413  if (saveInfos_)
414  produces<HBHEChannelInfoCollection>();
415 
416  if (makeRecHits_)
417  produces<HBHERecHitCollection>();
418 }
419 
420 
422 {
423  // do anything here that needs to be done at destruction time
424  // (e.g. close files, deallocate resources etc.)
425 }
426 
427 
428 //
429 // member functions
430 //
431 template<class DFrame, class Collection>
433  const HcalDbService& cond,
434  const HcalChannelQuality& qual,
436  const bool isRealData,
437  HBHEChannelInfo* channelInfo,
440 {
441  // If "saveDroppedInfos_" flag is set, fill the info with something
442  // meaningful even if the database tells us to drop this channel.
443  // Note that this flag affects only "infos", the rechits are still
444  // not going to be constructed from such channels.
445  const bool skipDroppedChannels = !(infos && saveDroppedInfos_);
446 
447  // Iterate over the input collection
448  for (typename Collection::const_iterator it = coll.begin();
449  it != coll.end(); ++it)
450  {
451  const DFrame& frame(*it);
452  const HcalDetId cell(frame.id());
453 
454  // Protection against calibration channels which are not
455  // in the database but can still come in the QIE11DataFrame
456  // in the laser calibs, etc.
457  const HcalSubdetector subdet = cell.subdet();
458  if (!(subdet == HcalSubdetector::HcalBarrel ||
459  subdet == HcalSubdetector::HcalEndcap ||
460  subdet == HcalSubdetector::HcalOuter))
461  continue;
462 
463  // Check if the database tells us to drop this channel
464  const HcalChannelStatus* mydigistatus = qual.getValues(cell.rawId());
465  const bool taggedBadByDb = severity.dropChannel(mydigistatus->getValue());
466  if (taggedBadByDb && skipDroppedChannels)
467  continue;
468 
469  // Check if the channel is zero suppressed
470  bool dropByZS = false;
472  if (frame.zsMarkAndPass())
473  dropByZS = true;
474  if (dropByZS && skipDroppedChannels)
475  continue;
476 
477  // Basic ADC decoding tools
478  const HcalRecoParam* param_ts = paramTS_->getValues(cell.rawId());
479  const HcalCalibrations& calib = cond.getHcalCalibrations(cell);
480  const HcalCalibrationWidths& calibWidth = cond.getHcalCalibrationWidths(cell);
481  const HcalQIECoder* channelCoder = cond.getHcalCoder(cell);
482  const HcalQIEShape* shape = cond.getHcalShape(channelCoder);
483  const HcalCoderDb coder(*channelCoder, *shape);
484 
485  // needed for the dark current in the M2
486  const HcalSiPMParameter& siPMParameter(*cond.getHcalSiPMParameter(cell));
487  const double darkCurrent = siPMParameter.getDarkCurrent();
488  const double fcByPE = siPMParameter.getFCByPE();
489  const double lambda = cond.getHcalSiPMCharacteristics()->getCrossTalk(siPMParameter.getType());
490 
491  // ADC to fC conversion
492  CaloSamples cs;
493  coder.adc2fC(frame, cs);
494 
495  // Prepare to iterate over time slices
496  const int nRead = cs.size();
497  const int maxTS = std::min(nRead, static_cast<int>(HBHEChannelInfo::MAXSAMPLES));
498  const int soi = tsFromDB_ ? param_ts->firstSample() : frame.presamples();
499  const RawChargeFromSample<DFrame> rcfs(sipmQTSShift_, sipmQNTStoSum_,
500  cond, cell, cs, soi, frame, maxTS);
501  int soiCapid = 4;
502 
503  // Go over time slices and fill the samples
504  for (int ts = 0; ts < maxTS; ++ts)
505  {
506  auto s(frame[ts]);
507  const uint8_t adc = s.adc();
508  const int capid = s.capid();
509  //optionally store "effective" pedestal (measured with bias voltage on)
510  // = QIE contribution + SiPM contribution (from dark current + crosstalk)
511  const double pedestal = saveEffectivePedestal_ ? calib.effpedestal(capid) : calib.pedestal(capid);
512  const double pedestalWidth = saveEffectivePedestal_ ? calibWidth.effpedestal(capid) : calibWidth.pedestal(capid);
513  const double gain = calib.respcorrgain(capid);
514  const double gainWidth = calibWidth.gain(capid);
515  //always use QIE-only pedestal for this computation
516  const double rawCharge = rcfs.getRawCharge(cs[ts], calib.pedestal(capid));
517  const float t = getTDCTimeFromSample(s);
518  const float dfc = getDifferentialChargeGain(*channelCoder, *shape, adc,
519  capid, channelInfo->hasTimeInfo());
520  channelInfo->setSample(ts, adc, dfc, rawCharge,
521  pedestal, pedestalWidth,
522  gain, gainWidth, t);
523  if (ts == soi)
524  soiCapid = capid;
525  }
526 
527  // Fill the overall channel info items
528  const int pulseShapeID = param_ts->pulseShapeID();
529  const std::pair<bool,bool> hwerr = findHWErrors(frame, maxTS);
530  channelInfo->setChannelInfo(cell, pulseShapeID, maxTS, soi, soiCapid,
531  darkCurrent, fcByPE, lambda,
532  hwerr.first, hwerr.second,
533  taggedBadByDb || dropByZS);
534 
535  // If needed, add the channel info to the output collection
536  const bool makeThisRechit = !channelInfo->isDropped();
537  if (infos && (saveDroppedInfos_ || makeThisRechit))
538  infos->push_back(*channelInfo);
539 
540  // Reconstruct the rechit
541  if (rechits && makeThisRechit)
542  {
543  const HcalRecoParam* pptr = nullptr;
544  if (recoParamsFromDB_)
545  pptr = param_ts;
546  HBHERecHit rh = reco_->reconstruct(*channelInfo, pptr, calib, isRealData);
547  if (rh.id().rawId())
548  {
549  setAsicSpecificBits(frame, coder, *channelInfo, calib, &rh);
550  setCommonStatusBits(*channelInfo, calib, &rh);
551  rechits->push_back(rh);
552  }
553  }
554  }
555 }
556 
558  const HBHEChannelInfo& /* info */, const HcalCalibrations& /* calib */,
559  HBHERecHit* /* rh */)
560 {
561 }
562 
564  const HBHEDataFrame& frame, const HcalCoder& coder,
565  const HBHEChannelInfo& info, const HcalCalibrations& calib,
566  HBHERecHit* rh)
567 {
568  if (setNoiseFlagsQIE8_)
569  hbheFlagSetterQIE8_->rememberHit(*rh);
570 
572  hbhePulseShapeFlagSetterQIE8_->SetPulseShapeFlags(*rh, frame, coder, calib);
573 
575  runHBHENegativeEFilter(info, rh);
576 }
577 
579  const QIE11DataFrame& frame, const HcalCoder& coder,
580  const HBHEChannelInfo& info, const HcalCalibrations& calib,
581  HBHERecHit* rh)
582 {
584  hbheFlagSetterQIE11_->rememberHit(*rh);
585 
587  hbhePulseShapeFlagSetterQIE11_->SetPulseShapeFlags(*rh, frame, coder, calib);
588 
590  runHBHENegativeEFilter(info, rh);
591 }
592 
594  HBHERecHit* rh)
595 {
596  double ts[HBHEChannelInfo::MAXSAMPLES];
597  const unsigned nRead = info.nSamples();
598  for (unsigned i=0; i<nRead; ++i)
599  ts[i] = info.tsCharge(i);
600  const bool passes = negEFilter_->checkPassFilter(info.id(), &ts[0], nRead);
601  if (!passes)
603 }
604 
605 // ------------ method called to produce the data ------------
606 void
608 {
609  using namespace edm;
610 
611  // Get the Hcal topology
613  eventSetup.get<HcalRecNumberingRecord>().get(htopo);
614  paramTS_->setTopo(htopo.product());
615 
616  // Fetch the calibrations
617  ESHandle<HcalDbService> conditions;
618  eventSetup.get<HcalDbRecord>().get(conditions);
619 
621  eventSetup.get<HcalChannelQualityRcd>().get("withTopo", p);
622 
624  eventSetup.get<HcalSeverityLevelComputerRcd>().get(mycomputer);
625 
626  // Configure the negative energy filter
629  {
630  eventSetup.get<HBHENegativeEFilterRcd>().get(negEHandle);
631  negEFilter_ = negEHandle.product();
632  }
633 
634  // Find the input data
635  unsigned maxOutputSize = 0;
637  if (processQIE8_)
638  {
639  e.getByToken(tok_qie8_, hbDigis);
640  maxOutputSize += hbDigis->size();
641  }
642 
644  if (processQIE11_)
645  {
646  e.getByToken(tok_qie11_, heDigis);
647  maxOutputSize += heDigis->size();
648  }
649 
650  // Create new output collections
651  std::unique_ptr<HBHEChannelInfoCollection> infos;
652  if (saveInfos_)
653  {
654  infos = std::make_unique<HBHEChannelInfoCollection>();
655  infos->reserve(maxOutputSize);
656  }
657 
658  std::unique_ptr<HBHERecHitCollection> out;
659  if (makeRecHits_)
660  {
661  out = std::make_unique<HBHERecHitCollection>();
662  out->reserve(maxOutputSize);
663  }
664 
665  // Process the input collections, filling the output ones
666  const bool isData = e.isRealData();
667  if (processQIE8_)
668  {
669  if (setNoiseFlagsQIE8_)
670  hbheFlagSetterQIE8_->Clear();
671 
672  HBHEChannelInfo channelInfo(false,false);
673  processData<HBHEDataFrame>(*hbDigis, *conditions, *p, *mycomputer,
674  isData, &channelInfo, infos.get(), out.get());
675  if (setNoiseFlagsQIE8_)
676  hbheFlagSetterQIE8_->SetFlagsFromRecHits(*out);
677  }
678 
679  if (processQIE11_)
680  {
682  hbheFlagSetterQIE11_->Clear();
683 
684  HBHEChannelInfo channelInfo(true,saveEffectivePedestal_);
685  processData<QIE11DataFrame>(*heDigis, *conditions, *p, *mycomputer,
686  isData, &channelInfo, infos.get(), out.get());
688  hbheFlagSetterQIE11_->SetFlagsFromRecHits(*out);
689  }
690 
691  // Add the output collections to the event record
692  if (saveInfos_)
693  e.put(std::move(infos));
694  if (makeRecHits_)
695  e.put(std::move(out));
696 }
697 
698 // ------------ method called when starting to processes a run ------------
699 void
701 {
703  es.get<HcalRecoParamsRcd>().get(p);
704  paramTS_ = std::make_unique<HcalRecoParams>(*p.product());
705 
706  if (reco_->isConfigurable())
707  {
709  if (!recoConfig_.get())
710  throw cms::Exception("HBHEPhase1BadConfig")
711  << "Invalid HBHEPhase1Reconstructor \"algoConfigClass\" parameter value \""
712  << algoConfigClass_ << '"' << std::endl;
713  if (!reco_->configure(recoConfig_.get()))
714  throw cms::Exception("HBHEPhase1BadConfig")
715  << "Failed to configure HBHEPhase1Algo algorithm from EventSetup"
716  << std::endl;
717  }
718 
720  {
722  es.get<HcalFrontEndMapRcd>().get(hfemap);
723  if (hfemap.isValid())
724  {
725  if (setNoiseFlagsQIE8_)
726  hbheFlagSetterQIE8_->SetFrontEndMap(hfemap.product());
728  hbheFlagSetterQIE11_->SetFrontEndMap(hfemap.product());
729  }
730  else
731  edm::LogWarning("EventSetup") <<
732  "HBHEPhase1Reconstructor failed to get HcalFrontEndMap!" << std::endl;
733  }
734 
735  reco_->beginRun(r, es);
736 }
737 
738 void
740 {
741  reco_->endRun();
742 }
743 
744 #define add_param_set(name) \
745  edm::ParameterSetDescription name; \
746  name.setAllowAnything(); \
747  desc.add<edm::ParameterSetDescription>(#name, name)
748 
749 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
750 void
752 {
754 
755  desc.add<edm::InputTag>("digiLabelQIE8");
756  desc.add<edm::InputTag>("digiLabelQIE11");
757  desc.add<std::string>("algoConfigClass");
758  desc.add<bool>("processQIE8");
759  desc.add<bool>("processQIE11");
760  desc.add<bool>("saveInfos");
761  desc.add<bool>("saveDroppedInfos");
762  desc.add<bool>("makeRecHits");
763  desc.add<bool>("dropZSmarkedPassed");
764  desc.add<bool>("tsFromDB");
765  desc.add<bool>("recoParamsFromDB");
766  desc.add<bool>("saveEffectivePedestal", false);
767  desc.add<int>("sipmQTSShift", 0);
768  desc.add<int>("sipmQNTStoSum", 3);
769  desc.add<bool>("setNegativeFlagsQIE8");
770  desc.add<bool>("setNegativeFlagsQIE11");
771  desc.add<bool>("setNoiseFlagsQIE8");
772  desc.add<bool>("setNoiseFlagsQIE11");
773  desc.add<bool>("setPulseShapeFlagsQIE8");
774  desc.add<bool>("setPulseShapeFlagsQIE11");
775  desc.add<bool>("setLegacyFlagsQIE8");
776  desc.add<bool>("setLegacyFlagsQIE11");
777 
783 
784  descriptions.addDefault(desc);
785 }
786 
787 //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_
float getTDCTime(const int tdc)
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:136
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:94
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:519
std::unique_ptr< HBHEStatusBitSetter > hbheFlagSetterQIE8_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
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 effpedestal(int fCapId) const
get effective pedestal width for capid=0..3
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
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
double effpedestal(int fCapId) const
get effective pedestal for capid=0..3
void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const override
Definition: HcalCoderDb.cc:68
std::unique_ptr< HcalRecoParams > paramTS_
void addDefault(ParameterSetDescription const &psetDescription)
static const unsigned MAXSAMPLES
double pedestal(int fCapId) const
get pedestal width for capid=0..3
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)
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:58
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
void produce(edm::Event &, const edm::EventSetup &) override
Definition: Run.h:43
#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