Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:27:22

0001 #ifndef RecoParticleFlow_PFClusterProducer_PFEcalRecHitQTests_h
0002 #define RecoParticleFlow_PFClusterProducer_PFEcalRecHitQTests_h
0003 
0004 #include <memory>
0005 #include "RecoParticleFlow/PFClusterProducer/interface/PFRecHitQTestBase.h"
0006 #include "CondFormats/EcalObjects/interface/EcalPFRecHitThresholds.h"
0007 #include "CondFormats/DataRecord/interface/EcalPFRecHitThresholdsRcd.h"
0008 #include "CondFormats/EcalObjects/interface/EcalPFSeedingThresholds.h"
0009 #include "CondFormats/DataRecord/interface/EcalPFSeedingThresholdsRcd.h"
0010 #include "Geometry/Records/interface/HcalRecNumberingRecord.h"
0011 #include "Geometry/CaloTopology/interface/HcalTopology.h"
0012 #include "DataFormats/METReco/interface/HcalPhase1FlagLabels.h"
0013 #include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h"
0014 #include "CondTools/Hcal/interface/HcalPFCutsHandler.h"
0015 
0016 #include <iostream>
0017 
0018 //
0019 //  Quality test that checks threshold
0020 //
0021 class PFRecHitQTestThreshold : public PFRecHitQTestBase {
0022 public:
0023   PFRecHitQTestThreshold() {}
0024 
0025   PFRecHitQTestThreshold(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0026       : PFRecHitQTestBase(iConfig, cc), threshold_(iConfig.getParameter<double>("threshold")) {}
0027 
0028   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {}
0029 
0030   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0031     return fullReadOut or pass(hit);
0032   }
0033   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override { return pass(hit); }
0034 
0035   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override { return pass(hit); }
0036   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override { return pass(hit); }
0037 
0038   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return pass(hit); }
0039 
0040   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return pass(hit); }
0041 
0042 protected:
0043   double threshold_;
0044 
0045   bool pass(const reco::PFRecHit& hit) { return hit.energy() > threshold_; }
0046 };
0047 
0048 //
0049 //  Quality test that checks threshold read from the DB
0050 //
0051 class PFRecHitQTestDBThreshold : public PFRecHitQTestBase {
0052 public:
0053   PFRecHitQTestDBThreshold() {}
0054 
0055   PFRecHitQTestDBThreshold(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0056       : PFRecHitQTestBase(iConfig, cc),
0057         applySelectionsToAllCrystals_(iConfig.getParameter<bool>("applySelectionsToAllCrystals")),
0058         threshToken_(cc.esConsumes()) {}
0059 
0060   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {
0061     ths_ = iSetup.getHandle(threshToken_);
0062   }
0063 
0064   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0065     if (applySelectionsToAllCrystals_)
0066       return pass(hit);
0067     return fullReadOut or pass(hit);
0068   }
0069   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override { return pass(hit); }
0070 
0071   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override { return pass(hit); }
0072   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override { return pass(hit); }
0073 
0074   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return pass(hit); }
0075 
0076   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return pass(hit); }
0077 
0078 protected:
0079   bool applySelectionsToAllCrystals_;
0080   edm::ESHandle<EcalPFRecHitThresholds> ths_;
0081 
0082   bool pass(const reco::PFRecHit& hit) {
0083     float threshold = (*ths_)[hit.detId()];
0084     return hit.energy() > threshold;
0085   }
0086 
0087 private:
0088   edm::ESGetToken<EcalPFRecHitThresholds, EcalPFRecHitThresholdsRcd> threshToken_;
0089 };
0090 
0091 //
0092 //  Quality test that checks kHCAL Severity
0093 //
0094 class PFRecHitQTestHCALChannel : public PFRecHitQTestBase {
0095 public:
0096   PFRecHitQTestHCALChannel() {}
0097 
0098   PFRecHitQTestHCALChannel(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0099       : PFRecHitQTestBase(iConfig, cc),
0100         flagStr_(iConfig.getParameter<std::vector<std::string>>("flags")),
0101         thresholds_(iConfig.getParameter<std::vector<int>>("maxSeverities")),
0102         cleanThresholds_(iConfig.getParameter<std::vector<double>>("cleaningThresholds")),
0103         topoToken_(cc.esConsumes()),
0104         qualityToken_(cc.esConsumes(edm::ESInputTag("", "withTopo"))),
0105         severityToken_(cc.esConsumes()) {
0106     for (auto& flag : flagStr_) {
0107       if (flag == "Standard") {
0108         flags_.push_back(-1);
0109         depths_.push_back(-1);
0110       } else if (flag == "HFInTime") {
0111         flags_.push_back(1 << HcalCaloFlagLabels::HFInTimeWindow);
0112         depths_.push_back(-1);
0113       } else if (flag == "HFDigi") {
0114         flags_.push_back(1 << HcalCaloFlagLabels::HFDigiTime);
0115         depths_.push_back(-1);
0116       } else if (flag == "HFLong") {
0117         flags_.push_back(1 << HcalCaloFlagLabels::HFLongShort);
0118         depths_.push_back(1);
0119       } else if (flag == "HFShort") {
0120         flags_.push_back(1 << HcalCaloFlagLabels::HFLongShort);
0121         depths_.push_back(2);
0122       } else if (flag == "HFSignalAsymmetry") {
0123         flags_.push_back(1 << HcalPhase1FlagLabels::HFSignalAsymmetry);
0124         depths_.push_back(-1);
0125       } else {
0126         flags_.push_back(-1);
0127         depths_.push_back(-1);
0128       }
0129     }
0130   }
0131 
0132   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {
0133     theHcalTopology_ = &iSetup.getData(topoToken_);
0134     theHcalChStatus_ = &iSetup.getData(qualityToken_);
0135     hcalSevLvlComputer_ = &iSetup.getData(severityToken_);
0136   }
0137 
0138   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override { return true; }
0139   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override {
0140     return test(rh.detid(), rh.energy(), rh.flags(), clean);
0141   }
0142 
0143   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override {
0144     return test(rh.detid(), rh.energy(), rh.flags(), clean);
0145   }
0146   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override {
0147     return test(rh.detid(), rh.energy(), rh.flags(), clean);
0148   }
0149 
0150   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return true; }
0151 
0152   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return true; }
0153 
0154 protected:
0155   std::vector<std::string> flagStr_;
0156   std::vector<int> thresholds_;
0157   std::vector<double> cleanThresholds_;
0158   std::vector<int> flags_;
0159   std::vector<int> depths_;
0160   const HcalTopology* theHcalTopology_;
0161   const HcalChannelQuality* theHcalChStatus_;
0162   const HcalSeverityLevelComputer* hcalSevLvlComputer_;
0163 
0164   bool test(unsigned aDETID, double energy, int flags, bool& clean) {
0165     HcalDetId detid = (HcalDetId)aDETID;
0166     if (theHcalTopology_->getMergePositionFlag() and detid.subdet() == HcalEndcap) {
0167       detid = theHcalTopology_->idFront(detid);
0168     }
0169 
0170     const HcalChannelStatus* theStatus = theHcalChStatus_->getValues(detid);
0171     unsigned theStatusValue = theStatus->getValue();
0172     // Now get severity of problems for the given detID, based on the rechit flag word and the channel quality status value
0173     for (unsigned int i = 0; i < thresholds_.size(); ++i) {
0174       int hitSeverity = 0;
0175       if (energy < cleanThresholds_[i])
0176         continue;
0177 
0178       if (flags_[i] < 0) {
0179         hitSeverity = hcalSevLvlComputer_->getSeverityLevel(detid, flags, theStatusValue);
0180       } else {
0181         hitSeverity = hcalSevLvlComputer_->getSeverityLevel(detid, flags & flags_[i], theStatusValue);
0182       }
0183 
0184       if (hitSeverity > thresholds_[i] and ((depths_[i] < 0 or (depths_[i] == detid.depth())))) {
0185         clean = true;
0186         return false;
0187       }
0188     }
0189     return true;
0190   }
0191 
0192 private:
0193   edm::ESGetToken<HcalTopology, HcalRecNumberingRecord> topoToken_;
0194   edm::ESGetToken<HcalChannelQuality, HcalChannelQualityRcd> qualityToken_;
0195   edm::ESGetToken<HcalSeverityLevelComputer, HcalSeverityLevelComputerRcd> severityToken_;
0196 };
0197 
0198 //
0199 //  Quality test that applies threshold and timing as a function of depth
0200 //
0201 class PFRecHitQTestHCALTimeVsDepth : public PFRecHitQTestBase {
0202 public:
0203   PFRecHitQTestHCALTimeVsDepth() {}
0204 
0205   PFRecHitQTestHCALTimeVsDepth(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0206       : PFRecHitQTestBase(iConfig, cc), psets_(iConfig.getParameter<std::vector<edm::ParameterSet>>("cuts")) {
0207     for (auto& pset : psets_) {
0208       depths_.push_back(pset.getParameter<int>("depth"));
0209       minTimes_.push_back(pset.getParameter<double>("minTime"));
0210       maxTimes_.push_back(pset.getParameter<double>("maxTime"));
0211       thresholds_.push_back(pset.getParameter<double>("threshold"));
0212     }
0213   }
0214 
0215   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {}
0216 
0217   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override { return true; }
0218   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override {
0219     return test(rh.detid(), rh.energy(), rh.time(), clean);
0220   }
0221 
0222   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override {
0223     return test(rh.detid(), rh.energy(), rh.time(), clean);
0224   }
0225   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override {
0226     return test(rh.detid(), rh.energy(), rh.time(), clean);
0227   }
0228 
0229   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return true; }
0230 
0231   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return true; }
0232 
0233 protected:
0234   std::vector<edm::ParameterSet> psets_;
0235   std::vector<int> depths_;
0236   std::vector<double> minTimes_;
0237   std::vector<double> maxTimes_;
0238   std::vector<double> thresholds_;
0239 
0240   bool test(unsigned aDETID, double energy, double time, bool& clean) {
0241     HcalDetId detid(aDETID);
0242     for (unsigned int i = 0; i < depths_.size(); ++i) {
0243       if (detid.depth() == depths_[i]) {
0244         if ((time < minTimes_[i] or time > maxTimes_[i]) and energy > thresholds_[i]) {
0245           clean = true;
0246           return false;
0247         }
0248         break;
0249       }
0250     }
0251     return true;
0252   }
0253 };
0254 
0255 //
0256 //  Quality test that applies threshold as a function of depth
0257 //
0258 class PFRecHitQTestHCALThresholdVsDepth : public PFRecHitQTestBase {
0259 public:
0260   PFRecHitQTestHCALThresholdVsDepth() {}
0261 
0262   PFRecHitQTestHCALThresholdVsDepth(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0263       : PFRecHitQTestBase(iConfig, cc),
0264         psets_(iConfig.getParameter<std::vector<edm::ParameterSet>>("cuts")),
0265         cutsFromDB(iConfig.getParameter<bool>("usePFThresholdsFromDB")) {
0266     if (cutsFromDB) {
0267       hcalCutsToken_ = cc.esConsumes<HcalPFCuts, HcalPFCutsRcd>(edm::ESInputTag("", "withTopo"));
0268     }
0269     for (auto& pset : psets_) {
0270       depths_.push_back(pset.getParameter<std::vector<int>>("depth"));
0271       thresholds_.push_back(pset.getParameter<std::vector<double>>("threshold"));
0272       detector_.push_back(pset.getParameter<int>("detectorEnum"));
0273       if (thresholds_[thresholds_.size() - 1].size() != depths_[depths_.size() - 1].size()) {
0274         throw cms::Exception("InvalidPFRecHitThreshold") << "PFRecHitThreshold mismatch with the numbers of depths";
0275       }
0276     }
0277   }
0278 
0279   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {
0280     if (cutsFromDB) {
0281       paramPF = &iSetup.getData(hcalCutsToken_);
0282     }
0283   }
0284 
0285   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override { return true; }
0286   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override {
0287     return test(rh.detid(), rh.energy(), rh.time(), clean);
0288   }
0289 
0290   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override {
0291     return test(rh.detid(), rh.energy(), rh.time(), clean);
0292   }
0293   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override {
0294     return test(rh.detid(), rh.energy(), rh.time(), clean);
0295   }
0296 
0297   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return true; }
0298 
0299   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return true; }
0300 
0301 protected:
0302   std::vector<edm::ParameterSet> psets_;
0303   std::vector<std::vector<int>> depths_;
0304   std::vector<std::vector<double>> thresholds_;
0305   std::vector<int> detector_;
0306   HcalPFCuts const* paramPF = nullptr;
0307 
0308   bool test(unsigned aDETID, double energy, double time, bool& clean) {
0309     HcalDetId detid(aDETID);
0310     const HcalPFCut* item = nullptr;
0311     if (cutsFromDB) {
0312       item = paramPF->getValues(detid.rawId());
0313     }
0314 
0315     for (unsigned int d = 0; d < detector_.size(); ++d) {
0316       if (detid.subdet() != detector_[d])
0317         continue;
0318       for (unsigned int i = 0; i < thresholds_[d].size(); ++i) {
0319         if (detid.depth() == depths_[d][i]) {
0320           float thres = cutsFromDB ? item->noiseThreshold() : thresholds_[d][i];
0321           if (energy < thres) {
0322             clean = false;
0323             return false;
0324           }
0325           break;
0326         }
0327       }
0328     }
0329     return true;
0330   }
0331 
0332 private:
0333   edm::ESGetToken<HcalTopology, HcalRecNumberingRecord> htopoToken_;
0334   edm::ESGetToken<HcalPFCuts, HcalPFCutsRcd> hcalCutsToken_;
0335   bool cutsFromDB;
0336 };
0337 
0338 //
0339 //  Quality test that checks HO threshold applying different threshold in rings
0340 //
0341 class PFRecHitQTestHOThreshold : public PFRecHitQTestBase {
0342 public:
0343   PFRecHitQTestHOThreshold() : threshold0_(0.), threshold12_(0.) {}
0344 
0345   PFRecHitQTestHOThreshold(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0346       : PFRecHitQTestBase(iConfig, cc),
0347         threshold0_(iConfig.getParameter<double>("threshold_ring0")),
0348         threshold12_(iConfig.getParameter<double>("threshold_ring12")) {}
0349 
0350   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {}
0351 
0352   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override { return true; }
0353 
0354   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override { return true; }
0355 
0356   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override { return true; }
0357 
0358   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override {
0359     HcalDetId detid(rh.detid());
0360     if (abs(detid.ieta()) <= 4 and hit.energy() > threshold0_)
0361       return true;
0362     if (abs(detid.ieta()) > 4 and hit.energy() > threshold12_)
0363       return true;
0364 
0365     return false;
0366   }
0367 
0368   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return true; }
0369 
0370   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return true; }
0371 
0372 protected:
0373   const double threshold0_;
0374   const double threshold12_;
0375 };
0376 
0377 //
0378 //  Quality test that checks threshold as a function of ECAL eta-ring
0379 //
0380 #include "Calibration/Tools/interface/EcalRingCalibrationTools.h"
0381 #include "DataFormats/DetId/interface/DetId.h"
0382 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0383 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0384 class PFRecHitQTestECALMultiThreshold : public PFRecHitQTestBase {
0385 public:
0386   PFRecHitQTestECALMultiThreshold() {}
0387 
0388   PFRecHitQTestECALMultiThreshold(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0389       : PFRecHitQTestBase(iConfig, cc),
0390         thresholds_(iConfig.getParameter<std::vector<double>>("thresholds")),
0391         applySelectionsToAllCrystals_(iConfig.getParameter<bool>("applySelectionsToAllCrystals")),
0392         geomToken_(cc.esConsumes()) {
0393     if (thresholds_.size() != EcalRingCalibrationTools::N_RING_TOTAL)
0394       throw edm::Exception(edm::errors::Configuration, "ValueError")
0395           << "thresholds is expected to have " << EcalRingCalibrationTools::N_RING_TOTAL << " elements but has "
0396           << thresholds_.size();
0397   }
0398 
0399   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {
0400     edm::ESHandle<CaloGeometry> pG = iSetup.getHandle(geomToken_);
0401     CaloSubdetectorGeometry const* endcapGeometry = pG->getSubdetectorGeometry(DetId::Ecal, EcalEndcap);
0402     endcapGeometrySet_ = false;
0403     if (endcapGeometry) {
0404       EcalRingCalibrationTools::setCaloGeometry(&(*pG));
0405       endcapGeometrySet_ = true;
0406     }
0407   }
0408 
0409   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0410     if (applySelectionsToAllCrystals_)
0411       return pass(hit);
0412     else
0413       return fullReadOut or pass(hit);
0414   }
0415   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override { return true; }
0416 
0417   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override { return true; }
0418   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override { return true; }
0419 
0420   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return true; }
0421 
0422   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return true; }
0423 
0424 protected:
0425   const std::vector<double> thresholds_;
0426   bool endcapGeometrySet_;
0427 
0428   // apply selections to all crystals
0429   bool applySelectionsToAllCrystals_;
0430 
0431   bool pass(const reco::PFRecHit& hit) {
0432     DetId detId(hit.detId());
0433 
0434     // this is to skip endcap ZS for Phase2 until there is a defined geometry
0435     // apply the loosest ZS threshold, for the first eta-ring in EB
0436     if (not endcapGeometrySet_) {
0437       // there is only ECAL EB in Phase 2
0438       if (detId.subdetId() != EcalBarrel)
0439         return true;
0440 
0441       //   0-169: EB  eta-rings
0442       // 170-208: EE- eta rings
0443       // 209-247: EE+ eta rings
0444       int firstEBRing = 0;
0445       return (hit.energy() > thresholds_[firstEBRing]);
0446     }
0447 
0448     int iring = EcalRingCalibrationTools::getRingIndex(detId);
0449     if (hit.energy() > thresholds_[iring])
0450       return true;
0451 
0452     return false;
0453   }
0454 
0455 private:
0456   edm::ESGetToken<CaloGeometry, CaloGeometryRecord> geomToken_;
0457 };
0458 
0459 //
0460 //  Quality test that checks ecal quality cuts
0461 //
0462 class PFRecHitQTestECAL : public PFRecHitQTestBase {
0463 public:
0464   PFRecHitQTestECAL() {}
0465 
0466   PFRecHitQTestECAL(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0467       : PFRecHitQTestBase(iConfig, cc),
0468         thresholdCleaning_(iConfig.getParameter<double>("cleaningThreshold")),
0469         timingCleaning_(iConfig.getParameter<bool>("timingCleaning")),
0470         topologicalCleaning_(iConfig.getParameter<bool>("topologicalCleaning")),
0471         skipTTRecoveredHits_(iConfig.getParameter<bool>("skipTTRecoveredHits")) {}
0472 
0473   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {}
0474 
0475   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0476     if (skipTTRecoveredHits_ and rh.checkFlag(EcalRecHit::kTowerRecovered)) {
0477       clean = true;
0478       return false;
0479     }
0480     if (timingCleaning_ and rh.energy() > thresholdCleaning_ and rh.checkFlag(EcalRecHit::kOutOfTime)) {
0481       clean = true;
0482       return false;
0483     }
0484 
0485     if (topologicalCleaning_ and (rh.checkFlag(EcalRecHit::kWeird) or rh.checkFlag(EcalRecHit::kDiWeird))) {
0486       clean = true;
0487       return false;
0488     }
0489 
0490     return true;
0491   }
0492 
0493   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override { return true; }
0494 
0495   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override { return true; }
0496 
0497   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override { return true; }
0498 
0499   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return true; }
0500 
0501   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return true; }
0502 
0503 protected:
0504   double thresholdCleaning_;
0505   bool timingCleaning_;
0506   bool topologicalCleaning_;
0507   bool skipTTRecoveredHits_;
0508 };
0509 
0510 //
0511 //  Quality test that checks ES quality cuts
0512 //
0513 class PFRecHitQTestES : public PFRecHitQTestBase {
0514 public:
0515   PFRecHitQTestES() : thresholdCleaning_(0.), topologicalCleaning_(false) {}
0516 
0517   PFRecHitQTestES(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0518       : PFRecHitQTestBase(iConfig, cc),
0519         thresholdCleaning_(iConfig.getParameter<double>("cleaningThreshold")),
0520         topologicalCleaning_(iConfig.getParameter<bool>("topologicalCleaning")) {}
0521 
0522   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {}
0523 
0524   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0525     if (rh.energy() < thresholdCleaning_) {
0526       clean = false;
0527       return false;
0528     }
0529 
0530     if (topologicalCleaning_ and
0531         (rh.checkFlag(EcalRecHit::kESDead) or rh.checkFlag(EcalRecHit::kESTS13Sigmas) or
0532          rh.checkFlag(EcalRecHit::kESBadRatioFor12) or rh.checkFlag(EcalRecHit::kESBadRatioFor23Upper) or
0533          rh.checkFlag(EcalRecHit::kESBadRatioFor23Lower) or rh.checkFlag(EcalRecHit::kESTS1Largest) or
0534          rh.checkFlag(EcalRecHit::kESTS3Largest) or rh.checkFlag(EcalRecHit::kESTS3Negative))) {
0535       clean = false;
0536       return false;
0537     }
0538 
0539     return true;
0540   }
0541 
0542   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override { return true; }
0543 
0544   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override { return true; }
0545 
0546   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override { return true; }
0547 
0548   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return true; }
0549 
0550   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return true; }
0551 
0552 protected:
0553   const double thresholdCleaning_;
0554   const bool topologicalCleaning_;
0555 };
0556 
0557 //
0558 //  Quality test that calibrates tower 29 of HCAL
0559 //
0560 class PFRecHitQTestHCALCalib29 : public PFRecHitQTestBase {
0561 public:
0562   PFRecHitQTestHCALCalib29() : calibFactor_(0.) {}
0563 
0564   PFRecHitQTestHCALCalib29(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0565       : PFRecHitQTestBase(iConfig, cc), calibFactor_(iConfig.getParameter<double>("calibFactor")) {}
0566 
0567   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {}
0568 
0569   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override { return true; }
0570   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override {
0571     HcalDetId detId(hit.detId());
0572     if (abs(detId.ieta()) == 29)
0573       hit.setEnergy(hit.energy() * calibFactor_);
0574     return true;
0575   }
0576 
0577   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override { return true; }
0578   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override { return true; }
0579 
0580   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override {
0581     CaloTowerDetId detId(hit.detId());
0582     if (detId.ietaAbs() == 29)
0583       hit.setEnergy(hit.energy() * calibFactor_);
0584     return true;
0585   }
0586 
0587   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return true; }
0588 
0589 protected:
0590   const float calibFactor_;
0591 };
0592 
0593 class PFRecHitQTestThresholdInMIPs : public PFRecHitQTestBase {
0594 public:
0595   PFRecHitQTestThresholdInMIPs() : recHitEnergy_keV_(false), threshold_(0.), mip_(0.), recHitEnergyMultiplier_(0.) {}
0596 
0597   PFRecHitQTestThresholdInMIPs(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0598       : PFRecHitQTestBase(iConfig, cc),
0599         recHitEnergy_keV_(iConfig.getParameter<bool>("recHitEnergyIs_keV")),
0600         threshold_(iConfig.getParameter<double>("thresholdInMIPs")),
0601         mip_(iConfig.getParameter<double>("mipValueInkeV")),
0602         recHitEnergyMultiplier_(iConfig.getParameter<double>("recHitEnergyMultiplier")) {}
0603 
0604   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {}
0605 
0606   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0607     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0608     return false;
0609   }
0610   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override {
0611     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0612     return false;
0613   }
0614 
0615   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override {
0616     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0617     return false;
0618   }
0619   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override {
0620     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0621     return false;
0622   }
0623 
0624   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override {
0625     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0626     return false;
0627   }
0628 
0629   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override {
0630     const double newE =
0631         (recHitEnergy_keV_ ? 1.0e-6 * rh.energy() * recHitEnergyMultiplier_ : rh.energy() * recHitEnergyMultiplier_);
0632     hit.setEnergy(newE);
0633     return pass(hit);
0634   }
0635 
0636 protected:
0637   const bool recHitEnergy_keV_;
0638   const double threshold_, mip_, recHitEnergyMultiplier_;
0639 
0640   bool pass(const reco::PFRecHit& hit) {
0641     const double hitValueInMIPs = 1e6 * hit.energy() / mip_;
0642     return hitValueInMIPs > threshold_;
0643   }
0644 };
0645 
0646 #include "Geometry/HGCalGeometry/interface/HGCalGeometry.h"
0647 class PFRecHitQTestThresholdInThicknessNormalizedMIPs : public PFRecHitQTestBase {
0648 public:
0649   PFRecHitQTestThresholdInThicknessNormalizedMIPs()
0650       : geometryInstance_(""), recHitEnergy_keV_(0.), threshold_(0.), mip_(0.), recHitEnergyMultiplier_(0.) {}
0651 
0652   PFRecHitQTestThresholdInThicknessNormalizedMIPs(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0653       : PFRecHitQTestBase(iConfig, cc),
0654         geometryInstance_(iConfig.getParameter<std::string>("geometryInstance")),
0655         recHitEnergy_keV_(iConfig.getParameter<bool>("recHitEnergyIs_keV")),
0656         threshold_(iConfig.getParameter<double>("thresholdInMIPs")),
0657         mip_(iConfig.getParameter<double>("mipValueInkeV")),
0658         recHitEnergyMultiplier_(iConfig.getParameter<double>("recHitEnergyMultiplier")),
0659         geomToken_(cc.esConsumes()) {}
0660 
0661   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {
0662     edm::ESHandle<HGCalGeometry> geoHandle = iSetup.getHandle(geomToken_);
0663     ddd_ = &(geoHandle->topology().dddConstants());
0664   }
0665 
0666   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0667     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0668     return false;
0669   }
0670   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override {
0671     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0672     return false;
0673   }
0674 
0675   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override {
0676     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0677     return false;
0678   }
0679   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override {
0680     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0681     return false;
0682   }
0683 
0684   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override {
0685     throw cms::Exception("WrongDetector") << "PFRecHitQTestThresholdInMIPs only works for HGCAL!";
0686     return false;
0687   }
0688 
0689   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override {
0690     const double newE =
0691         (recHitEnergy_keV_ ? 1.0e-6 * rh.energy() * recHitEnergyMultiplier_ : rh.energy() * recHitEnergyMultiplier_);
0692     const int wafer = HGCalDetId(rh.detid()).wafer();
0693     const float mult = (float)ddd_->waferTypeL(wafer);  // 1 for 100um, 2 for 200um, 3 for 300um
0694     hit.setEnergy(newE);
0695     return pass(hit, mult);
0696   }
0697 
0698 protected:
0699   const std::string geometryInstance_;
0700   const bool recHitEnergy_keV_;
0701   const double threshold_, mip_, recHitEnergyMultiplier_;
0702   const HGCalDDDConstants* ddd_;
0703 
0704   bool pass(const reco::PFRecHit& hit, const float mult) {
0705     const double hitValueInMIPs = 1e6 * hit.energy() / (mult * mip_);
0706     return hitValueInMIPs > threshold_;
0707   }
0708 
0709 private:
0710   edm::ESGetToken<HGCalGeometry, IdealGeometryRecord> geomToken_;
0711 };
0712 
0713 class PFRecHitQTestHGCalThresholdSNR : public PFRecHitQTestBase {
0714 public:
0715   PFRecHitQTestHGCalThresholdSNR() : thresholdSNR_(0.) {}
0716 
0717   PFRecHitQTestHGCalThresholdSNR(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0718       : PFRecHitQTestBase(iConfig, cc), thresholdSNR_(iConfig.getParameter<double>("thresholdSNR")) {}
0719 
0720   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {}
0721 
0722   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0723     throw cms::Exception("WrongDetector") << "PFRecHitQTestHGCalThresholdSNR only works for HGCAL!";
0724     return false;
0725   }
0726   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override {
0727     throw cms::Exception("WrongDetector") << "PFRecHitQTestHGCalThresholdSNR only works for HGCAL!";
0728     return false;
0729   }
0730 
0731   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override {
0732     throw cms::Exception("WrongDetector") << "PFRecHitQTestHGCalThresholdSNR only works for HGCAL!";
0733     return false;
0734   }
0735   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override {
0736     throw cms::Exception("WrongDetector") << "PFRecHitQTestHGCalThresholdSNR only works for HGCAL!";
0737     return false;
0738   }
0739 
0740   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override {
0741     throw cms::Exception("WrongDetector") << "PFRecHitQTestHGCalThresholdSNR only works for HGCAL!";
0742     return false;
0743   }
0744 
0745   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override {
0746     return rh.signalOverSigmaNoise() >= thresholdSNR_;
0747   }
0748 
0749 protected:
0750   const double thresholdSNR_;
0751 };
0752 
0753 //  M.G. Quality test that checks seeding threshold read from the DB
0754 //
0755 class PFRecHitQTestDBSeedingThreshold : public PFRecHitQTestBase {
0756 public:
0757   PFRecHitQTestDBSeedingThreshold(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0758       : PFRecHitQTestBase(iConfig, cc),
0759         applySelectionsToAllCrystals_(iConfig.getParameter<bool>("applySelectionsToAllCrystals")),
0760         threshToken_(cc.esConsumes()) {}
0761 
0762   void beginEvent(const edm::Event& event, const edm::EventSetup& iSetup) override {
0763     ths_ = iSetup.getHandle(threshToken_);
0764   }
0765 
0766   bool test(reco::PFRecHit& hit, const EcalRecHit& rh, bool& clean, bool fullReadOut) override {
0767     if (applySelectionsToAllCrystals_)
0768       return pass(hit);
0769     return fullReadOut or pass(hit);
0770   }
0771   bool test(reco::PFRecHit& hit, const HBHERecHit& rh, bool& clean) override { return pass(hit); }
0772 
0773   bool test(reco::PFRecHit& hit, const HFRecHit& rh, bool& clean) override { return pass(hit); }
0774   bool test(reco::PFRecHit& hit, const HORecHit& rh, bool& clean) override { return pass(hit); }
0775 
0776   bool test(reco::PFRecHit& hit, const CaloTower& rh, bool& clean) override { return pass(hit); }
0777 
0778   bool test(reco::PFRecHit& hit, const HGCRecHit& rh, bool& clean) override { return pass(hit); }
0779 
0780 protected:
0781   bool applySelectionsToAllCrystals_;
0782   edm::ESHandle<EcalPFSeedingThresholds> ths_;
0783 
0784   bool pass(const reco::PFRecHit& hit) {
0785     float threshold = (*ths_)[hit.detId()];
0786     return (hit.energy() > threshold);
0787   }
0788 
0789 private:
0790   edm::ESGetToken<EcalPFSeedingThresholds, EcalPFSeedingThresholdsRcd> threshToken_;
0791 };
0792 
0793 #endif