Back to home page

Project CMSSW displayed by LXR

 
 

    


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 // for single tower H/E
0009 #include "RecoEgamma/EgammaIsolationAlgos/interface/EgammaHadTower.h"
0010 
0011 //quick pT for superclusters
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   // setup our elements so that all the SCs are grouped together
0063   auto SCs_end =
0064       std::partition(elems.begin(), elems.end(), [](auto const& a) { return a->type() == reco::PFBlockElement::SC; });
0065   // add eb superclusters
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;  // point to element *after* the new one
0084     }
0085   }  // loop on eb superclusters
0086   // add ee superclusters
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;  // point to element *after* the new one
0103     }
0104   }  // loop on ee superclusters
0105   elems.shrink_to_fit();
0106 }