Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-07 05:53:38

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