File indexing completed on 2024-04-06 12:27:21
0001 #ifndef RecoParticleFlow_PFClusterProducer_PFHFRecHitCreator_h
0002 #define RecoParticleFlow_PFClusterProducer_PFHFRecHitCreator_h
0003
0004 #include "RecoParticleFlow/PFClusterProducer/interface/PFRecHitCreatorBase.h"
0005
0006 #include "DataFormats/HcalRecHit/interface/HORecHit.h"
0007 #include "DataFormats/HcalRecHit/interface/HFRecHit.h"
0008 #include "DataFormats/HcalRecHit/interface/HBHERecHit.h"
0009 #include "DataFormats/HcalRecHit/interface/HcalRecHitCollections.h"
0010 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
0011
0012 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
0013 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0014 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
0015 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0016 #include "Geometry/CaloTopology/interface/HcalTopology.h"
0017 #include "Geometry/CaloGeometry/interface/IdealZPrism.h"
0018
0019 #include "RecoCaloTools/Navigation/interface/CaloNavigator.h"
0020
0021 class PFHFRecHitCreator final : public PFRecHitCreatorBase {
0022 public:
0023 PFHFRecHitCreator(const edm::ParameterSet& iConfig, edm::ConsumesCollector& cc)
0024 : PFRecHitCreatorBase(iConfig, cc),
0025 recHitToken_(cc.consumes<edm::SortedCollection<HFRecHit> >(iConfig.getParameter<edm::InputTag>("src"))),
0026 EM_Depth_(iConfig.getParameter<double>("EMDepthCorrection")),
0027 HAD_Depth_(iConfig.getParameter<double>("HADDepthCorrection")),
0028 shortFibre_Cut(iConfig.getParameter<double>("ShortFibre_Cut")),
0029 longFibre_Fraction(iConfig.getParameter<double>("LongFibre_Fraction")),
0030 longFibre_Cut(iConfig.getParameter<double>("LongFibre_Cut")),
0031 shortFibre_Fraction(iConfig.getParameter<double>("ShortFibre_Fraction")),
0032 thresh_HF_(iConfig.getParameter<double>("thresh_HF")),
0033 HFCalib_(iConfig.getParameter<double>("HFCalib29")),
0034 geomToken_(cc.esConsumes()) {}
0035
0036 void importRecHits(std::unique_ptr<reco::PFRecHitCollection>& out,
0037 std::unique_ptr<reco::PFRecHitCollection>& cleaned,
0038 const edm::Event& iEvent,
0039 const edm::EventSetup& iSetup) override {
0040 reco::PFRecHitCollection tmpOut;
0041
0042 beginEvent(iEvent, iSetup);
0043
0044 edm::Handle<edm::SortedCollection<HFRecHit> > recHitHandle;
0045
0046 edm::ESHandle<CaloGeometry> geoHandle = iSetup.getHandle(geomToken_);
0047
0048
0049 const CaloSubdetectorGeometry* hcalGeo = geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalForward);
0050
0051 iEvent.getByToken(recHitToken_, recHitHandle);
0052 for (const auto& erh : *recHitHandle) {
0053 const HcalDetId& detid = (HcalDetId)erh.detid();
0054 auto depth = detid.depth();
0055
0056
0057 if (depth > 2)
0058 continue;
0059
0060 auto energy = erh.energy();
0061 auto time = erh.time();
0062
0063 std::shared_ptr<const CaloCellGeometry> thisCell = hcalGeo->getGeometry(detid);
0064 auto zp = dynamic_cast<IdealZPrism const*>(thisCell.get());
0065 assert(zp);
0066 thisCell = zp->forPF();
0067
0068
0069 if (!thisCell) {
0070 edm::LogError("PFHFRecHitCreator")
0071 << "warning detid " << detid.rawId() << " not found in geometry" << std::endl;
0072 continue;
0073 }
0074
0075 PFLayer::Layer layer = depth == 1 ? PFLayer::HF_EM : PFLayer::HF_HAD;
0076
0077 reco::PFRecHit rh(thisCell, detid.rawId(), layer, energy);
0078 rh.setTime(time);
0079 rh.setDepth(depth);
0080
0081 bool rcleaned = false;
0082 bool keep = true;
0083
0084
0085 for (const auto& qtest : qualityTests_) {
0086 if (!qtest->test(rh, erh, rcleaned)) {
0087 keep = false;
0088 }
0089 }
0090
0091 if (keep) {
0092 tmpOut.push_back(std::move(rh));
0093 } else if (rcleaned)
0094 cleaned->push_back(std::move(rh));
0095 }
0096
0097 DetIDSorter sorter;
0098 if (!tmpOut.empty())
0099 std::sort(tmpOut.begin(), tmpOut.end(), sorter);
0100
0101
0102
0103 for (auto& hit : tmpOut) {
0104 reco::PFRecHit newHit = hit;
0105 const HcalDetId& detid = (HcalDetId)hit.detId();
0106 if (detid.depth() == 1) {
0107 double lONG = hit.energy();
0108
0109 HcalDetId shortID(HcalForward, detid.ieta(), detid.iphi(), 2);
0110 auto found_hit =
0111 std::lower_bound(tmpOut.begin(), tmpOut.end(), shortID, [](const reco::PFRecHit& a, HcalDetId b) {
0112 return a.detId() < b.rawId();
0113 });
0114 if (found_hit != tmpOut.end() && found_hit->detId() == shortID.rawId()) {
0115 double sHORT = found_hit->energy();
0116
0117 double energy = lONG - sHORT;
0118
0119 if (abs(detid.ieta()) <= 32)
0120 energy *= HFCalib_;
0121 newHit.setEnergy(energy);
0122 if (!(lONG > longFibre_Cut && (sHORT / lONG < shortFibre_Fraction)))
0123 if (energy > thresh_HF_)
0124 out->push_back(newHit);
0125 } else {
0126
0127 double energy = lONG;
0128 if (abs(detid.ieta()) <= 32)
0129 energy *= HFCalib_;
0130 newHit.setEnergy(energy);
0131
0132 if (energy > thresh_HF_)
0133 out->push_back(newHit);
0134 }
0135
0136 } else {
0137 double sHORT = hit.energy();
0138 HcalDetId longID(HcalForward, detid.ieta(), detid.iphi(), 1);
0139 auto found_hit =
0140 std::lower_bound(tmpOut.begin(), tmpOut.end(), longID, [](const reco::PFRecHit& a, HcalDetId b) {
0141 return a.detId() < b.rawId();
0142 });
0143 double energy = sHORT;
0144 if (found_hit != tmpOut.end() && found_hit->detId() == longID.rawId()) {
0145 double lONG = found_hit->energy();
0146
0147
0148
0149 if ((lONG - sHORT) < thresh_HF_)
0150 energy += lONG;
0151 else
0152 energy += sHORT;
0153
0154 if (abs(detid.ieta()) <= 32)
0155 energy *= HFCalib_;
0156
0157 newHit.setEnergy(energy);
0158 if (!(sHORT > shortFibre_Cut && (lONG / sHORT < longFibre_Fraction)))
0159 if (energy > thresh_HF_)
0160 out->push_back(newHit);
0161
0162 } else {
0163
0164 if (abs(detid.ieta()) <= 32)
0165 energy *= HFCalib_;
0166 newHit.setEnergy(energy);
0167 if (energy > thresh_HF_)
0168 out->push_back(newHit);
0169 }
0170 }
0171 }
0172 }
0173
0174 protected:
0175 edm::EDGetTokenT<edm::SortedCollection<HFRecHit> > recHitToken_;
0176 double EM_Depth_;
0177 double HAD_Depth_;
0178
0179 double shortFibre_Cut;
0180 double longFibre_Fraction;
0181
0182
0183 double longFibre_Cut;
0184 double shortFibre_Fraction;
0185 double thresh_HF_;
0186 double HFCalib_;
0187
0188 class DetIDSorter {
0189 public:
0190 DetIDSorter() = default;
0191 ~DetIDSorter() = default;
0192
0193 bool operator()(const reco::PFRecHit& a, const reco::PFRecHit& b) {
0194 if (DetId(a.detId()).det() == DetId::Hcal || DetId(b.detId()).det() == DetId::Hcal)
0195 return (HcalDetId)(a.detId()) < (HcalDetId)(b.detId());
0196 else
0197 return a.detId() < b.detId();
0198 }
0199 };
0200
0201 private:
0202 edm::ESGetToken<CaloGeometry, CaloGeometryRecord> geomToken_;
0203 };
0204 #endif