Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:50:11

0001 #ifndef CommonTools_UtilAlgos_FwdPtrCollectionFilter_h
0002 #define CommonTools_UtilAlgos_FwdPtrCollectionFilter_h
0003 
0004 /**
0005    \class    edm::FwdPtrCollectionFilter FwdPtrCollectionFilter.h "CommonTools/UtilAlgos/interface/FwdPtrCollectionFilter.h"
0006    \brief    Selects a list of FwdPtr's to a product T (templated) that satisfy a method S(T) (templated). Can also handle input as View<T>.
0007    Can also have a factory class to create new instances of clones if desired.
0008 
0009    \author   Salvatore Rappoccio
0010 */
0011 
0012 #include "CommonTools/UtilAlgos/interface/FwdPtrConversionFactory.h"
0013 #include "DataFormats/Common/interface/FwdPtr.h"
0014 #include "DataFormats/Common/interface/View.h"
0015 #include "FWCore/Framework/interface/stream/EDFilter.h"
0016 #include "FWCore/Framework/interface/Event.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/Utilities/interface/InputTag.h"
0019 
0020 #include <algorithm>
0021 #include <vector>
0022 
0023 namespace edm {
0024 
0025   template <class T, class S, class H = ProductFromFwdPtrFactory<T>>
0026   class FwdPtrCollectionFilter : public edm::stream::EDFilter<> {
0027   public:
0028     explicit FwdPtrCollectionFilter(edm::ParameterSet const& ps)
0029         : srcToken_{consumes<std::vector<edm::FwdPtr<T>>>(ps.getParameter<edm::InputTag>("src"))},
0030           srcViewToken_{mayConsume<edm::View<T>>(ps.getParameter<edm::InputTag>("src"))},
0031           filter_{ps.exists("filter") ? ps.getParameter<bool>("filter") : false},
0032           makeClones_{ps.exists("makeClones") ? ps.getParameter<bool>("makeClones") : false},
0033           selector_{ps} {
0034       produces<std::vector<edm::FwdPtr<T>>>();
0035       if (makeClones_) {
0036         produces<std::vector<T>>();
0037       }
0038     }
0039 
0040     bool filter(edm::Event& iEvent, edm::EventSetup const& iSetup) override {
0041       auto pOutput = std::make_unique<std::vector<edm::FwdPtr<T>>>();
0042 
0043       // First try to access as a vector<FwdPtr<T>>; otherwise try as a View<T>.
0044       edm::Handle<std::vector<edm::FwdPtr<T>>> hSrcAsFwdPtr;
0045       if (iEvent.getByToken(srcToken_, hSrcAsFwdPtr)) {
0046         std::copy_if(
0047             std::cbegin(*hSrcAsFwdPtr), std::cend(*hSrcAsFwdPtr), std::back_inserter(*pOutput), [this](auto const ptr) {
0048               return selector_(*ptr);
0049             });
0050       } else {
0051         edm::Handle<edm::View<T>> hSrcAsView;
0052         iEvent.getByToken(srcViewToken_, hSrcAsView);
0053         for (auto ibegin = std::cbegin(*hSrcAsView), iend = std::cend(*hSrcAsView), i = ibegin; i != iend; ++i) {
0054           if (selector_(*i)) {
0055             auto const p = hSrcAsView->ptrAt(i - ibegin);
0056             pOutput->emplace_back(p, p);
0057           }
0058         }
0059       }
0060 
0061       // Must form pClones *before* std::move(pOutput) has been called.
0062       if (makeClones_) {
0063         H factory;
0064         auto pClones = std::make_unique<std::vector<T>>();
0065         std::transform(std::cbegin(*pOutput), std::cend(*pOutput), std::back_inserter(*pClones), [&factory](auto ptr) {
0066           return factory(ptr);
0067         });
0068         iEvent.put(std::move(pClones));
0069       }
0070 
0071       bool const pass{!pOutput->empty()};
0072       iEvent.put(std::move(pOutput));
0073 
0074       return filter_ ? pass : true;
0075     }
0076 
0077   protected:
0078     edm::EDGetTokenT<std::vector<edm::FwdPtr<T>>> const srcToken_;
0079     edm::EDGetTokenT<edm::View<T>> const srcViewToken_;
0080     bool const filter_;
0081     bool const makeClones_;
0082     S selector_;
0083   };
0084 }  // namespace edm
0085 
0086 #endif