Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef __TrackFromParentImporter_H__
0002 #define __TrackFromParentImporter_H__
0003 
0004 #include "RecoParticleFlow/PFProducer/interface/BlockElementImporterBase.h"
0005 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0006 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementTrack.h"
0007 #include "DataFormats/ParticleFlowReco/interface/PFRecTrack.h"
0008 #include "DataFormats/HGCalReco/interface/TICLSeedingRegion.h"
0009 
0010 namespace pflow {
0011   namespace noop {
0012     // this adaptor class gets redefined later to match the
0013     // needs of the collection and importing cuts we are using
0014     template <class Collection>
0015     class ParentCollectionAdaptor {
0016     public:
0017       static bool check_importable(const typename Collection::value_type&) { return true; }
0018       static const std::vector<reco::PFRecTrackRef>& get_track_refs(const typename Collection::value_type&) {
0019         return empty_;
0020       }
0021       static void set_element_info(reco::PFBlockElement*, const typename edm::Ref<Collection>&) {}
0022       static const std::vector<reco::PFRecTrackRef> empty_;
0023     };
0024   }  // namespace noop
0025   namespace importers {
0026     template <class Collection, class Adaptor = noop::ParentCollectionAdaptor<Collection>>
0027     class TrackFromParentImporter : public BlockElementImporterBase {
0028     public:
0029       TrackFromParentImporter(const edm::ParameterSet& conf, edm::ConsumesCollector& cc)
0030           : BlockElementImporterBase(conf, cc),
0031             src_(cc.consumes<Collection>(conf.getParameter<edm::InputTag>("source"))),
0032             vetoEndcap_(conf.getParameter<bool>("vetoEndcap")) {
0033         if (vetoEndcap_) {
0034           vetoMode_ = conf.getParameter<unsigned>("vetoMode");
0035           switch (vetoMode_) {
0036             case pfRecTrackCollection:
0037               vetoPFTracksSrc_ = cc.consumes<reco::PFRecTrackCollection>(conf.getParameter<edm::InputTag>("vetoSrc"));
0038               break;
0039             case ticlSeedingRegion:
0040               vetoTICLSeedingSrc_ =
0041                   cc.consumes<std::vector<TICLSeedingRegion>>(conf.getParameter<edm::InputTag>("vetoSrc"));
0042               tracksSrc_ = cc.consumes<reco::TrackCollection>(conf.getParameter<edm::InputTag>("tracksSrc"));
0043               break;
0044             case pfCandidateCollection:
0045               vetoPFCandidatesSrc_ =
0046                   cc.consumes<reco::PFCandidateCollection>(conf.getParameter<edm::InputTag>("vetoSrc"));
0047               break;
0048           }  // switch
0049         }    // vetoEndcap_
0050       }
0051 
0052       void importToBlock(const edm::Event&, ElementList&) const override;
0053 
0054     private:
0055       edm::EDGetTokenT<Collection> src_;
0056       edm::InputTag srcTag_;
0057       const bool vetoEndcap_;
0058       unsigned int vetoMode_;
0059       edm::EDGetTokenT<reco::PFRecTrackCollection> vetoPFTracksSrc_;
0060       edm::EDGetTokenT<std::vector<TICLSeedingRegion>> vetoTICLSeedingSrc_;
0061       edm::EDGetTokenT<reco::TrackCollection> tracksSrc_;
0062       edm::EDGetTokenT<reco::PFCandidateCollection> vetoPFCandidatesSrc_;
0063     };
0064 
0065     template <class Collection, class Adaptor>
0066     void TrackFromParentImporter<Collection, Adaptor>::importToBlock(
0067         const edm::Event& e, BlockElementImporterBase::ElementList& elems) const {
0068       typedef BlockElementImporterBase::ElementList::value_type ElementType;
0069       auto pfparents = e.getHandle(src_);
0070       //
0071       // Store tracks to be vetoed
0072       typedef std::pair<edm::ProductID, unsigned> TrackProdIDKey;
0073       std::vector<TrackProdIDKey> vetoed;
0074       edm::ProductID prodIdForVeto;
0075       if (vetoEndcap_) {
0076         switch (vetoMode_) {
0077           case pfRecTrackCollection: {
0078             const auto& vetoes = e.get(vetoPFTracksSrc_);
0079             for (const auto& veto : vetoes) {
0080               vetoed.emplace_back(veto.trackRef().id(), veto.trackRef().key());
0081             }
0082             break;
0083           }
0084           case ticlSeedingRegion: {
0085             const auto& vetoes = e.get(vetoTICLSeedingSrc_);
0086             auto tracksH = e.getHandle(tracksSrc_);
0087             for (const auto& veto : vetoes) {
0088               assert(veto.collectionID == tracksH.id());
0089               vetoed.emplace_back(tracksH.id(), veto.index);  // track prod id and key
0090             }
0091             break;
0092           }
0093           case pfCandidateCollection: {
0094             const auto& vetoes = e.get(vetoPFCandidatesSrc_);
0095             for (const auto& veto : vetoes) {
0096               if (veto.trackRef().isNull())
0097                 continue;
0098               vetoed.emplace_back(veto.trackRef().id(), veto.trackRef().key());
0099             }
0100             break;
0101           }
0102         }  // switch
0103         std::sort(vetoed.begin(), vetoed.end());
0104       }
0105       //
0106       elems.reserve(elems.size() + 2 * pfparents->size());
0107       //
0108       auto TKs_end = std::partition(
0109           elems.begin(), elems.end(), [](const ElementType& a) { return a->type() == reco::PFBlockElement::TRACK; });
0110       // insert tracks into the element list, updating tracks that exist already
0111       auto bpar = pfparents->cbegin();
0112       auto epar = pfparents->cend();
0113       edm::Ref<Collection> parentRef;
0114       reco::PFBlockElement* trkElem = nullptr;
0115       for (auto pfparent = bpar; pfparent != epar; ++pfparent) {
0116         if (Adaptor::check_importable(*pfparent)) {
0117           parentRef = edm::Ref<Collection>(pfparents, std::distance(bpar, pfparent));
0118           const auto& pftracks = Adaptor::get_track_refs(*pfparent);
0119           for (const auto& pftrack : pftracks) {
0120             if (vetoEndcap_) {  // vetoEndcap flag
0121               TrackProdIDKey trk = std::make_pair(pftrack->trackRef().id(), pftrack->trackRef().key());
0122               auto lower = std::lower_bound(vetoed.begin(), vetoed.end(), trk);
0123               bool inVetoList = (lower != vetoed.end() && *lower == trk);
0124               if (inVetoList)
0125                 continue;  // found a track in a veto list
0126             }
0127             //
0128             // Now try to update an entry in pfblock or import
0129             auto tk_elem = std::find_if(
0130                 elems.begin(), TKs_end, [&](const ElementType& a) { return (a->trackRef() == pftrack->trackRef()); });
0131             if (tk_elem != TKs_end) {  // if found flag the track, otherwise import
0132               Adaptor::set_element_info(tk_elem->get(), parentRef);
0133             } else {
0134               trkElem = new reco::PFBlockElementTrack(pftrack);
0135               Adaptor::set_element_info(trkElem, parentRef);
0136               TKs_end = elems.insert(TKs_end, ElementType(trkElem));
0137               ++TKs_end;
0138             }
0139           }  // daughter track loop ends
0140         }    // end of importable check
0141       }      // loop on tracking coming from common parent
0142       elems.shrink_to_fit();
0143     }  // end of importToBlock
0144   }    // namespace importers
0145 }  // namespace pflow
0146 #endif