File indexing completed on 2023-10-25 10:01:44
0001 #include "RecoParticleFlow/PFProducer/interface/BlockElementImporterBase.h"
0002 #include "RecoParticleFlow/PFProducer/interface/PhotonSelectorAlgo.h"
0003 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
0004 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementSuperCluster.h"
0005 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0006 #include "RecoParticleFlow/PFProducer/interface/PFBlockElementSCEqual.h"
0007 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0008
0009 #include "RecoEgamma/EgammaIsolationAlgos/interface/EgammaHadTower.h"
0010
0011
0012 inline double ptFast(const double energy, const math::XYZPoint& position, const math::XYZPoint& origin) {
0013 const auto v = position - origin;
0014 return energy * std::sqrt(v.perp2() / v.mag2());
0015 }
0016
0017 #include <memory>
0018
0019 #include <unordered_map>
0020
0021 class SuperClusterImporter : public BlockElementImporterBase {
0022 public:
0023 SuperClusterImporter(const edm::ParameterSet&, edm::ConsumesCollector&);
0024
0025 void updateEventSetup(const edm::EventSetup& es) override;
0026
0027 void importToBlock(const edm::Event&, ElementList&) const override;
0028
0029 private:
0030 edm::EDGetTokenT<reco::SuperClusterCollection> _srcEB, _srcEE;
0031 edm::EDGetTokenT<CaloTowerCollection> _srcTowers;
0032 const double _maxHoverE, _pTbyPass, _minSCPt;
0033 CaloTowerConstituentsMap const* towerMap_;
0034 bool _superClustersArePF;
0035 static const math::XYZPoint _zero;
0036
0037 const edm::ESGetToken<CaloTowerConstituentsMap, CaloGeometryRecord> _ctmapToken;
0038 };
0039
0040 const math::XYZPoint SuperClusterImporter::_zero = math::XYZPoint(0, 0, 0);
0041
0042 DEFINE_EDM_PLUGIN(BlockElementImporterFactory, SuperClusterImporter, "SuperClusterImporter");
0043
0044 SuperClusterImporter::SuperClusterImporter(const edm::ParameterSet& conf, edm::ConsumesCollector& cc)
0045 : BlockElementImporterBase(conf, cc),
0046 _srcEB(cc.consumes<reco::SuperClusterCollection>(conf.getParameter<edm::InputTag>("source_eb"))),
0047 _srcEE(cc.consumes<reco::SuperClusterCollection>(conf.getParameter<edm::InputTag>("source_ee"))),
0048 _srcTowers(cc.consumes<CaloTowerCollection>(conf.getParameter<edm::InputTag>("source_towers"))),
0049 _maxHoverE(conf.getParameter<double>("maximumHoverE")),
0050 _pTbyPass(conf.getParameter<double>("minPTforBypass")),
0051 _minSCPt(conf.getParameter<double>("minSuperClusterPt")),
0052 _superClustersArePF(conf.getParameter<bool>("superClustersArePF")),
0053 _ctmapToken(cc.esConsumes<edm::Transition::BeginLuminosityBlock>()) {}
0054
0055 void SuperClusterImporter::updateEventSetup(const edm::EventSetup& es) { towerMap_ = &es.getData(_ctmapToken); }
0056
0057 void SuperClusterImporter::importToBlock(const edm::Event& e, BlockElementImporterBase::ElementList& elems) const {
0058 auto eb_scs = e.getHandle(_srcEB);
0059 auto ee_scs = e.getHandle(_srcEE);
0060 auto const& towers = e.get(_srcTowers);
0061 elems.reserve(elems.size() + eb_scs->size() + ee_scs->size());
0062
0063 auto SCs_end =
0064 std::partition(elems.begin(), elems.end(), [](auto const& a) { return a->type() == reco::PFBlockElement::SC; });
0065
0066 auto bsc = eb_scs->cbegin();
0067 auto esc = eb_scs->cend();
0068 reco::PFBlockElementSuperCluster* scbe = nullptr;
0069 reco::SuperClusterRef scref;
0070 for (auto sc = bsc; sc != esc; ++sc) {
0071 scref = reco::SuperClusterRef(eb_scs, std::distance(bsc, sc));
0072 PFBlockElementSCEqual myEqual(scref);
0073 auto sc_elem = std::find_if(elems.begin(), SCs_end, myEqual);
0074 const double scpT = ptFast(sc->energy(), sc->position(), _zero);
0075 const auto towersBehindCluster = egamma::towersOf(*sc, *towerMap_);
0076 const double H_tower =
0077 (egamma::depth1HcalESum(towersBehindCluster, towers) + egamma::depth2HcalESum(towersBehindCluster, towers));
0078 const double HoverE = H_tower / sc->energy();
0079 if (sc_elem == SCs_end && scpT > _minSCPt && (scpT > _pTbyPass || HoverE < _maxHoverE)) {
0080 scbe = new reco::PFBlockElementSuperCluster(scref);
0081 scbe->setFromPFSuperCluster(_superClustersArePF);
0082 SCs_end = elems.emplace(SCs_end, scbe);
0083 ++SCs_end;
0084 }
0085 }
0086
0087 bsc = ee_scs->cbegin();
0088 esc = ee_scs->cend();
0089 for (auto sc = bsc; sc != esc; ++sc) {
0090 scref = reco::SuperClusterRef(ee_scs, std::distance(bsc, sc));
0091 PFBlockElementSCEqual myEqual(scref);
0092 auto sc_elem = std::find_if(elems.begin(), SCs_end, myEqual);
0093 const double scpT = ptFast(sc->energy(), sc->position(), _zero);
0094 const auto towersBehindCluster = egamma::towersOf(*sc, *towerMap_);
0095 const double H_tower =
0096 (egamma::depth1HcalESum(towersBehindCluster, towers) + egamma::depth2HcalESum(towersBehindCluster, towers));
0097 const double HoverE = H_tower / sc->energy();
0098 if (sc_elem == SCs_end && scpT > _minSCPt && (scpT > _pTbyPass || HoverE < _maxHoverE)) {
0099 scbe = new reco::PFBlockElementSuperCluster(scref);
0100 scbe->setFromPFSuperCluster(_superClustersArePF);
0101 SCs_end = elems.emplace(SCs_end, scbe);
0102 ++SCs_end;
0103 }
0104 }
0105 elems.shrink_to_fit();
0106 }