Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-12 23:42:02

0001 #ifndef PhysicsTools_UtilAlgos_interface_EDFilterObjectWrapper_h
0002 #define PhysicsTools_UtilAlgos_interface_EDFilterObjectWrapper_h
0003 
0004 /**
0005   \class    EDFilterObjectWrapper EDFilterObjectWrapper.h "PhysicsTools/UtilAlgos/interface/EDFilterObjectWrapper.h"
0006   \brief    Wrapper class for a class of type BasicFilter to "convert" it into a full EDFilter
0007 
0008    This template class is a wrapper round classes of type Selector<T> and similar signature.
0009    It operates on container classes of type C which roughly satisfy std::vector template
0010    parameters.
0011 
0012    From this class the wrapper expects the following member functions:
0013 
0014    + a contructor with a const edm::ParameterSet& as input.
0015    + a filter function that operates on classes of type C::value_type
0016 
0017    the function is called within the wrapper. The wrapper translates the common class into
0018    a basic EDFilter as shown below:
0019 
0020    #include "PhysicsTools/UtilAlgos/interface/EDFilterObjectWrapper.h"
0021    #include "PhysicsTools/SelectorUtils/interface/PFJetIdSelectionFunctor.h"
0022    typedef edm::FilterWrapper<PFJetIdSelectionFunctor> PFJetIdFilter;
0023 
0024    #include "FWCore/Framework/interface/MakerMacros.h"
0025    DEFINE_FWK_MODULE(PFJetIdFilter);
0026 
0027    You can find this example in PhysicsTools/UtilAlgos/plugins/JetIDSelectionFunctorFilter.cc.
0028    In the first place the module will act as an EDProducer: it will put a new collection
0029    containing the selected objects into the event. Depending on the choice of parameter _filter_
0030    it will discard events for which the collection of selected events is empty. It will such also
0031    act as an EDFilter and thus is specified as such. The parameter _filter_ does not need to be
0032    specified.
0033 
0034    NOTE: in the current implementation this wrapper class does not support use of the EventSetup.
0035    If you want to make use of this feature we recommend you to start from an EDProducer from the
0036    very beginning and just to stay within the full framework.
0037 */
0038 
0039 #include "FWCore/Framework/interface/stream/EDFilter.h"
0040 #include "FWCore/Common/interface/EventBase.h"
0041 #include "FWCore/Framework/interface/Event.h"
0042 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0043 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0044 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0045 
0046 namespace edm {
0047 
0048   template <class T, class C>
0049   class FilterObjectWrapper : public edm::stream::EDFilter<> {
0050   public:
0051     /// some convenient typedefs. Recall that C is a container class.
0052     typename C::iterator iterator;
0053     typename C::const_iterator const_iterator;
0054 
0055     /// default contructor. Declares the output (type "C") and the filter (of type T, operates on C::value_type)
0056     FilterObjectWrapper(const edm::ParameterSet& cfg)
0057         : src_(consumes<C>(cfg.getParameter<edm::InputTag>("src"))), doFilter_(cfg.getParameter<bool>("filter")) {
0058       filter_ = std::shared_ptr<T>(new T(cfg.getParameter<edm::ParameterSet>("filterParams")));
0059       produces<C>();
0060     }
0061     /// default destructor
0062     ~FilterObjectWrapper() override = default;
0063 
0064     /// everything which has to be done during the event loop. NOTE: We can't use the eventSetup in FWLite so ignore it
0065     bool filter(edm::Event& event, const edm::EventSetup& eventSetup) override {
0066       // create a collection of the objects to put into the event
0067       auto objsToPut = std::make_unique<C>();
0068       // get the handle to the objects in the event.
0069       edm::Handle<C> h_c;
0070       event.getByToken(src_, h_c);
0071       // loop through and add passing value_types to the output vector
0072       for (typename C::const_iterator ibegin = h_c->begin(), iend = h_c->end(), i = ibegin; i != iend; ++i) {
0073         if ((*filter_)(*i)) {
0074           objsToPut->push_back(*i);
0075         }
0076       }
0077       // put objs in the event
0078       bool pass = !objsToPut->empty();
0079       event.put(std::move(objsToPut));
0080       if (doFilter_)
0081         return pass;
0082       else
0083         return true;
0084     }
0085 
0086     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0087       edm::ParameterSetDescription desc;
0088       desc.add<edm::InputTag>("src", edm::InputTag(""))->setComment("input collection");
0089       desc.add<edm::ParameterSetDescription>("filterParams", T::getDescription());
0090       desc.add<bool>("filter", false);
0091       descriptions.addWithDefaultLabel(desc);
0092     }
0093 
0094   protected:
0095     /// InputTag of the input source
0096     const edm::EDGetTokenT<C> src_;
0097     /// whether or not to filter based on size
0098     const bool doFilter_;
0099     /// shared pointer to analysis class of type BasicAnalyzer
0100     std::shared_ptr<T> filter_;
0101   };
0102 
0103 }  // namespace edm
0104 
0105 #endif