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_;
304  bool use8ts_;
307 
308  // Parameters for turning status bit setters on/off
315 
316  // Other members
319  std::unique_ptr<AbsHBHEPhase1Algo> reco_;
320  std::unique_ptr<AbsHcalAlgoData> recoConfig_;
321  std::unique_ptr<HcalRecoParams> paramTS_;
322 
323  // Status bit setters
324  const HBHENegativeEFilter* negEFilter_; // We don't manage this pointer
325  std::unique_ptr<HBHEStatusBitSetter> hbheFlagSetterQIE8_;
326  std::unique_ptr<HBHEStatusBitSetter> hbheFlagSetterQIE11_;
327  std::unique_ptr<HBHEPulseShapeFlagSetter> hbhePulseShapeFlagSetterQIE8_;
328  std::unique_ptr<HBHEPulseShapeFlagSetter> hbhePulseShapeFlagSetterQIE11_;
329 
330  // For the function below, arguments "infoColl" and/or "rechits"
331  // are allowed to be null.
332  template<class DataFrame, class Collection>
333  void processData(const Collection& coll,
334  const HcalDbService& cond,
335  const HcalChannelQuality& qual,
337  const bool isRealData,
339  HBHEChannelInfoCollection* infoColl,
341  const bool use8ts);
342 
343  // Methods for setting rechit status bits
344  void setAsicSpecificBits(const HBHEDataFrame& frame, const HcalCoder& coder,
345  const HBHEChannelInfo& info, const HcalCalibrations& calib,
346  HBHERecHit* rh);
347  void setAsicSpecificBits(const QIE11DataFrame& frame, const HcalCoder& coder,
348  const HBHEChannelInfo& info, const HcalCalibrations& calib,
349  HBHERecHit* rh);
350  void setCommonStatusBits(const HBHEChannelInfo& info, const HcalCalibrations& calib,
351  HBHERecHit* rh);
352 
353  void runHBHENegativeEFilter(const HBHEChannelInfo& info, HBHERecHit* rh);
354 };
355 
356 //
357 // constructors and destructor
358 //
360  : algoConfigClass_(conf.getParameter<std::string>("algoConfigClass")),
361  processQIE8_(conf.getParameter<bool>("processQIE8")),
362  processQIE11_(conf.getParameter<bool>("processQIE11")),
363  saveInfos_(conf.getParameter<bool>("saveInfos")),
364  saveDroppedInfos_(conf.getParameter<bool>("saveDroppedInfos")),
365  makeRecHits_(conf.getParameter<bool>("makeRecHits")),
366  dropZSmarkedPassed_(conf.getParameter<bool>("dropZSmarkedPassed")),
367  tsFromDB_(conf.getParameter<bool>("tsFromDB")),
368  recoParamsFromDB_(conf.getParameter<bool>("recoParamsFromDB")),
369  saveEffectivePedestal_(conf.getParameter<bool>("saveEffectivePedestal")),
370  use8ts_(conf.getParameter<bool>("use8ts")),
371  sipmQTSShift_(conf.getParameter<int>("sipmQTSShift")),
372  sipmQNTStoSum_(conf.getParameter<int>("sipmQNTStoSum")),
373  setNegativeFlagsQIE8_(conf.getParameter<bool>("setNegativeFlagsQIE8")),
374  setNegativeFlagsQIE11_(conf.getParameter<bool>("setNegativeFlagsQIE11")),
375  setNoiseFlagsQIE8_(conf.getParameter<bool>("setNoiseFlagsQIE8")),
376  setNoiseFlagsQIE11_(conf.getParameter<bool>("setNoiseFlagsQIE11")),
377  setPulseShapeFlagsQIE8_(conf.getParameter<bool>("setPulseShapeFlagsQIE8")),
378  setPulseShapeFlagsQIE11_(conf.getParameter<bool>("setPulseShapeFlagsQIE11")),
379  reco_(parseHBHEPhase1AlgoDescription(conf.getParameter<edm::ParameterSet>("algorithm"))),
380  negEFilter_(nullptr)
381 {
382  // Check that the reco algorithm has been successfully configured
383  if (!reco_.get())
384  throw cms::Exception("HBHEPhase1BadConfig")
385  << "Invalid HBHEPhase1Algo algorithm configuration"
386  << std::endl;
387 
388  // Configure the status bit setters that have been turned on
389  if (setNoiseFlagsQIE8_)
390  hbheFlagSetterQIE8_ = parse_HBHEStatusBitSetter(
391  conf.getParameter<edm::ParameterSet>("flagParametersQIE8"));
392 
394  hbheFlagSetterQIE11_ = parse_HBHEStatusBitSetter(
395  conf.getParameter<edm::ParameterSet>("flagParametersQIE11"));
396 
398  hbhePulseShapeFlagSetterQIE8_ = parse_HBHEPulseShapeFlagSetter(
399  conf.getParameter<edm::ParameterSet>("pulseShapeParametersQIE8"),
400  conf.getParameter<bool>("setLegacyFlagsQIE8"));
401 
403  hbhePulseShapeFlagSetterQIE11_ = parse_HBHEPulseShapeFlagSetter(
404  conf.getParameter<edm::ParameterSet>("pulseShapeParametersQIE11"),
405  conf.getParameter<bool>("setLegacyFlagsQIE11"));
406 
407  // Consumes and produces statements
408  if (processQIE8_)
409  tok_qie8_ = consumes<HBHEDigiCollection>(
410  conf.getParameter<edm::InputTag>("digiLabelQIE8"));
411 
412  if (processQIE11_)
413  tok_qie11_ = consumes<QIE11DigiCollection>(
414  conf.getParameter<edm::InputTag>("digiLabelQIE11"));
415 
416  if (saveInfos_)
417  produces<HBHEChannelInfoCollection>();
418 
419  if (makeRecHits_)
420  produces<HBHERecHitCollection>();
421 }
422 
423 
425 {
426  // do anything here that needs to be done at destruction time
427  // (e.g. close files, deallocate resources etc.)
428 }
429 
430 
431 //
432 // member functions
433 //
434 template<class DFrame, class Collection>
436  const HcalDbService& cond,
437  const HcalChannelQuality& qual,
439  const bool isRealData,
440  HBHEChannelInfo* channelInfo,
443  const bool use8ts_)
444 {
445  // If "saveDroppedInfos_" flag is set, fill the info with something
446  // meaningful even if the database tells us to drop this channel.
447  // Note that this flag affects only "infos", the rechits are still
448  // not going to be constructed from such channels.
449  const bool skipDroppedChannels = !(infos && saveDroppedInfos_);
450 
451  // Iterate over the input collection
452  for (typename Collection::const_iterator it = coll.begin();
453  it != coll.end(); ++it)
454  {
455  const DFrame& frame(*it);
456  const HcalDetId cell(frame.id());
457 
458  // Protection against calibration channels which are not
459  // in the database but can still come in the QIE11DataFrame
460  // in the laser calibs, etc.
461  const HcalSubdetector subdet = cell.subdet();
462  if (!(subdet == HcalSubdetector::HcalBarrel ||
463  subdet == HcalSubdetector::HcalEndcap ||
464  subdet == HcalSubdetector::HcalOuter))
465  continue;
466 
467  // Check if the database tells us to drop this channel
468  const HcalChannelStatus* mydigistatus = qual.getValues(cell.rawId());
469  const bool taggedBadByDb = severity.dropChannel(mydigistatus->getValue());
470  if (taggedBadByDb && skipDroppedChannels)
471  continue;
472 
473  // Check if the channel is zero suppressed
474  bool dropByZS = false;
476  if (frame.zsMarkAndPass())
477  dropByZS = true;
478  if (dropByZS && skipDroppedChannels)
479  continue;
480 
481  // Basic ADC decoding tools
482  const HcalRecoParam* param_ts = paramTS_->getValues(cell.rawId());
483  const HcalCalibrations& calib = cond.getHcalCalibrations(cell);
484  const HcalCalibrationWidths& calibWidth = cond.getHcalCalibrationWidths(cell);
485  const HcalQIECoder* channelCoder = cond.getHcalCoder(cell);
486  const HcalQIEShape* shape = cond.getHcalShape(channelCoder);
487  const HcalCoderDb coder(*channelCoder, *shape);
488 
489  // needed for the dark current in the M2
490  const HcalSiPMParameter& siPMParameter(*cond.getHcalSiPMParameter(cell));
491  const double darkCurrent = siPMParameter.getDarkCurrent();
492  const double fcByPE = siPMParameter.getFCByPE();
493  const double lambda = cond.getHcalSiPMCharacteristics()->getCrossTalk(siPMParameter.getType());
494 
495  // ADC to fC conversion
496  CaloSamples cs;
497  coder.adc2fC(frame, cs);
498 
499  // Prepare to iterate over time slices
500  const bool saveEffectivePeds = channelInfo->hasEffectivePedestals();
501  const int nRead = cs.size();
502  const int maxTS = std::min(nRead, static_cast<int>(HBHEChannelInfo::MAXSAMPLES));
503  const int soi = tsFromDB_ ? param_ts->firstSample() : frame.presamples();
504  const RawChargeFromSample<DFrame> rcfs(sipmQTSShift_, sipmQNTStoSum_,
505  cond, cell, cs, soi, frame, maxTS);
506  int soiCapid = 4;
507 
508  // Use only 8 TSs when there are 10 TSs
509  const int shiftOneTS = use8ts_ && maxTS == static_cast<int>(HBHEChannelInfo::MAXSAMPLES) ? 1 : 0;
510  const int nCycles = maxTS - shiftOneTS;
511 
512  // Go over time slices and fill the samples
513  for (int inputTS = shiftOneTS; inputTS < nCycles; ++inputTS)
514  {
515  auto s(frame[inputTS]);
516  const uint8_t adc = s.adc();
517  const int capid = s.capid();
518  //optionally store "effective" pedestal (measured with bias voltage on)
519  // = QIE contribution + SiPM contribution (from dark current + crosstalk)
520  const double pedestal = saveEffectivePeds ? calib.effpedestal(capid) : calib.pedestal(capid);
521  const double pedestalWidth = saveEffectivePeds ? calibWidth.effpedestal(capid) : calibWidth.pedestal(capid);
522  const double gain = calib.respcorrgain(capid);
523  const double gainWidth = calibWidth.gain(capid);
524  //always use QIE-only pedestal for this computation
525  const double rawCharge = rcfs.getRawCharge(cs[inputTS], calib.pedestal(capid));
526  const float t = getTDCTimeFromSample(s);
527  const float dfc = getDifferentialChargeGain(*channelCoder, *shape, adc,
528  capid, channelInfo->hasTimeInfo());
529  const int fitTS = inputTS-shiftOneTS;
530  channelInfo->setSample(fitTS, adc, dfc, rawCharge,
531  pedestal, pedestalWidth,
532  gain, gainWidth, t);
533  if (inputTS == soi)
534  soiCapid = capid;
535  }
536 
537  // Fill the overall channel info items
538  const int maxFitTS = maxTS-2*shiftOneTS;
539  const int fitSoi = soi-shiftOneTS;
540  const int pulseShapeID = param_ts->pulseShapeID();
541  const std::pair<bool,bool> hwerr = findHWErrors(frame, maxTS);
542  channelInfo->setChannelInfo(cell, pulseShapeID, maxFitTS, fitSoi, soiCapid,
543  darkCurrent, fcByPE, lambda,
544  hwerr.first, hwerr.second,
545  taggedBadByDb || dropByZS);
546 
547  // If needed, add the channel info to the output collection
548  const bool makeThisRechit = !channelInfo->isDropped();
549  if (infos && (saveDroppedInfos_ || makeThisRechit))
550  infos->push_back(*channelInfo);
551 
552  // Reconstruct the rechit
553  if (rechits && makeThisRechit)
554  {
555  const HcalRecoParam* pptr = nullptr;
556  if (recoParamsFromDB_)
557  pptr = param_ts;
558  HBHERecHit rh = reco_->reconstruct(*channelInfo, pptr, calib, isRealData);
559  if (rh.id().rawId())
560  {
561  setAsicSpecificBits(frame, coder, *channelInfo, calib, &rh);
562  setCommonStatusBits(*channelInfo, calib, &rh);
563  rechits->push_back(rh);
564  }
565  }
566  }
567 }
568 
570  const HBHEChannelInfo& /* info */, const HcalCalibrations& /* calib */,
571  HBHERecHit* /* rh */)
572 {
573 }
574 
576  const HBHEDataFrame& frame, const HcalCoder& coder,
577  const HBHEChannelInfo& info, const HcalCalibrations& calib,
578  HBHERecHit* rh)
579 {
580  if (setNoiseFlagsQIE8_)
581  hbheFlagSetterQIE8_->rememberHit(*rh);
582 
584  hbhePulseShapeFlagSetterQIE8_->SetPulseShapeFlags(*rh, frame, coder, calib);
585 
587  runHBHENegativeEFilter(info, rh);
588 }
589 
591  const QIE11DataFrame& frame, const HcalCoder& coder,
592  const HBHEChannelInfo& info, const HcalCalibrations& calib,
593  HBHERecHit* rh)
594 {
596  hbheFlagSetterQIE11_->rememberHit(*rh);
597 
599  hbhePulseShapeFlagSetterQIE11_->SetPulseShapeFlags(*rh, frame, coder, calib);
600 
602  runHBHENegativeEFilter(info, rh);
603 }
604 
606  HBHERecHit* rh)
607 {
608  double ts[HBHEChannelInfo::MAXSAMPLES];
609  const unsigned nRead = info.nSamples();
610  for (unsigned i=0; i<nRead; ++i)
611  ts[i] = info.tsCharge(i);
612  const bool passes = negEFilter_->checkPassFilter(info.id(), &ts[0], nRead);
613  if (!passes)
615 }
616 
617 // ------------ method called to produce the data ------------
618 void
620 {
621  using namespace edm;
622 
623  // Get the Hcal topology
625  eventSetup.get<HcalRecNumberingRecord>().get(htopo);
626  paramTS_->setTopo(htopo.product());
627 
628  // Fetch the calibrations
629  ESHandle<HcalDbService> conditions;
630  eventSetup.get<HcalDbRecord>().get(conditions);
631 
633  eventSetup.get<HcalChannelQualityRcd>().get("withTopo", p);
634 
636  eventSetup.get<HcalSeverityLevelComputerRcd>().get(mycomputer);
637 
638  // Configure the negative energy filter
641  {
642  eventSetup.get<HBHENegativeEFilterRcd>().get(negEHandle);
643  negEFilter_ = negEHandle.product();
644  }
645 
646  // Find the input data
647  unsigned maxOutputSize = 0;
649  if (processQIE8_)
650  {
651  e.getByToken(tok_qie8_, hbDigis);
652  maxOutputSize += hbDigis->size();
653  }
654 
656  if (processQIE11_)
657  {
658  e.getByToken(tok_qie11_, heDigis);
659  maxOutputSize += heDigis->size();
660  }
661 
662  // Create new output collections
663  std::unique_ptr<HBHEChannelInfoCollection> infos;
664  if (saveInfos_)
665  {
666  infos = std::make_unique<HBHEChannelInfoCollection>();
667  infos->reserve(maxOutputSize);
668  }
669 
670  std::unique_ptr<HBHERecHitCollection> out;
671  if (makeRecHits_)
672  {
673  out = std::make_unique<HBHERecHitCollection>();
674  out->reserve(maxOutputSize);
675  }
676 
677  // Process the input collections, filling the output ones
678  const bool isData = e.isRealData();
679  if (processQIE8_)
680  {
681  if (setNoiseFlagsQIE8_)
682  hbheFlagSetterQIE8_->Clear();
683 
684  HBHEChannelInfo channelInfo(false,false);
685  processData<HBHEDataFrame>(*hbDigis, *conditions, *p, *mycomputer,
686  isData, &channelInfo, infos.get(), out.get(), use8ts_);
687  if (setNoiseFlagsQIE8_)
688  hbheFlagSetterQIE8_->SetFlagsFromRecHits(*out);
689  }
690 
691  if (processQIE11_)
692  {
694  hbheFlagSetterQIE11_->Clear();
695 
696  HBHEChannelInfo channelInfo(true,saveEffectivePedestal_);
697  processData<QIE11DataFrame>(*heDigis, *conditions, *p, *mycomputer,
698  isData, &channelInfo, infos.get(), out.get(), use8ts_);
700  hbheFlagSetterQIE11_->SetFlagsFromRecHits(*out);
701  }
702 
703  // Add the output collections to the event record
704  if (saveInfos_)
705  e.put(std::move(infos));
706  if (makeRecHits_)
707  e.put(std::move(out));
708 }
709 
710 // ------------ method called when starting to processes a run ------------
711 void
713 {
715  es.get<HcalRecoParamsRcd>().get(p);
716  paramTS_ = std::make_unique<HcalRecoParams>(*p.product());
717 
718  if (reco_->isConfigurable())
719  {
721  if (!recoConfig_.get())
722  throw cms::Exception("HBHEPhase1BadConfig")
723  << "Invalid HBHEPhase1Reconstructor \"algoConfigClass\" parameter value \""
724  << algoConfigClass_ << '"' << std::endl;
725  if (!reco_->configure(recoConfig_.get()))
726  throw cms::Exception("HBHEPhase1BadConfig")
727  << "Failed to configure HBHEPhase1Algo algorithm from EventSetup"
728  << std::endl;
729  }
730 
732  {
734  es.get<HcalFrontEndMapRcd>().get(hfemap);
735  if (hfemap.isValid())
736  {
737  if (setNoiseFlagsQIE8_)
738  hbheFlagSetterQIE8_->SetFrontEndMap(hfemap.product());
740  hbheFlagSetterQIE11_->SetFrontEndMap(hfemap.product());
741  }
742  else
743  edm::LogWarning("EventSetup") <<
744  "HBHEPhase1Reconstructor failed to get HcalFrontEndMap!" << std::endl;
745  }
746 
747  reco_->beginRun(r, es);
748 }
749 
750 void
752 {
753  reco_->endRun();
754 }
755 
756 #define add_param_set(name) \
757  edm::ParameterSetDescription name; \
758  name.setAllowAnything(); \
759  desc.add<edm::ParameterSetDescription>(#name, name)
760 
761 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
762 void
764 {
766 
767  desc.add<edm::InputTag>("digiLabelQIE8");
768  desc.add<edm::InputTag>("digiLabelQIE11");
769  desc.add<std::string>("algoConfigClass");
770  desc.add<bool>("processQIE8");
771  desc.add<bool>("processQIE11");
772  desc.add<bool>("saveInfos");
773  desc.add<bool>("saveDroppedInfos");
774  desc.add<bool>("makeRecHits");
775  desc.add<bool>("dropZSmarkedPassed");
776  desc.add<bool>("tsFromDB");
777  desc.add<bool>("recoParamsFromDB");
778  desc.add<bool>("saveEffectivePedestal", false);
779  desc.add<bool>("use8ts", false);
780  desc.add<int>("sipmQTSShift", 0);
781  desc.add<int>("sipmQNTStoSum", 3);
782  desc.add<bool>("setNegativeFlagsQIE8");
783  desc.add<bool>("setNegativeFlagsQIE11");
784  desc.add<bool>("setNoiseFlagsQIE8");
785  desc.add<bool>("setNoiseFlagsQIE11");
786  desc.add<bool>("setPulseShapeFlagsQIE8");
787  desc.add<bool>("setPulseShapeFlagsQIE11");
788  desc.add<bool>("setLegacyFlagsQIE8");
789  desc.add<bool>("setLegacyFlagsQIE11");
790 
796 
797  descriptions.addDefault(desc);
798 }
799 
800 //define this as a plug-in
HBHEPhase1Reconstructor(const edm::ParameterSet &)
std::unique_ptr< HBHEPulseShapeFlagSetter > hbhePulseShapeFlagSetterQIE8_
T getParameter(std::string const &) const
constexpr unsigned int pulseShapeID() const
Definition: HcalRecoParam.h:34
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:125
int maxTS(DIGI const &digi, double ped=0)
Definition: Utilities.h:102
HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:146
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:517
std::unique_ptr< HBHEStatusBitSetter > hbheFlagSetterQIE8_
unique_ptr< ClusterSequence > cs
void beginRun(edm::Run const &, edm::EventSetup const &) override
HcalDetId id() const
get the id
Definition: HBHERecHit.h:42
#define nullptr
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
void push_back(T const &t)
double effpedestal(int fCapId) const
get effective pedestal width for capid=0..3
const Item * getValues(DetId fId, bool throwOnFail=true) const
bool hasEffectivePedestals() const
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:62
HcalDetId id() const
constexpr void setFlagField(uint32_t value, int base, int width=1)
Definition: CaloRecHit.h:38
float getCrossTalk(int type) const
get cross talk
bool checkPassFilter(const HcalDetId &id, const double *ts, unsigned lenTS) const
constexpr float getTDCTime(const int tdc)
void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const override
Definition: HcalCoderDb.cc:68
std::unique_ptr< HcalRecoParams > paramTS_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
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
was there a link error?
edm::EDGetTokenT< QIE11DigiCollection > tok_qie11_
constexpr double effpedestal(int fCapId) const
get effective pedestal for capid=0..3
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
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
float getDarkCurrent() const
get dark current
void processData(const Collection &coll, const HcalDbService &cond, const HcalChannelQuality &qual, const HcalSeverityLevelComputer &severity, const bool isRealData, HBHEChannelInfo *info, HBHEChannelInfoCollection *infoColl, HBHERecHitCollection *rechits, const bool use8ts)
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
std::unique_ptr< HBHEPulseShapeFlagSetter > hbhePulseShapeFlagSetterQIE11_
constexpr double pedestal(int fCapId) const
get pedestal for capid=0..3
JetCorrectorParametersCollection coll
Definition: classes.h:10
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
int size() const
get the size
Definition: CaloSamples.h:24
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
T get() const
Definition: EventSetup.h:71
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:44
const HcalCalibrations & getHcalCalibrations(const HcalGenericDetId &fId) const
const HcalSiPMParameter * getHcalSiPMParameter(const HcalGenericDetId &fId) const
T const * product() const
Definition: ESHandle.h:86
constexpr double respcorrgain(int fCapId) const
get response corrected gain for capid=0..3
def move(src, dest)
Definition: eostools.py:511
void produce(edm::Event &, const edm::EventSetup &) override
constexpr unsigned int firstSample() const
Definition: HcalRecoParam.h:32
Definition: Run.h:45
#define add_param_set(name)
edm::ParameterSetDescription fillDescriptionForParseHBHEPhase1Algo()
float charge(const HcalQIEShape &fShape, unsigned fAdc, unsigned fCapId) const
ADC [0..127] + capid [0..3] -> fC conversion.
Definition: HcalQIECoder.cc:20