Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-29 02:42:48

0001 #ifndef CandAlgos_CandCombiner_h
0002 #define CandAlgos_CandCombiner_h
0003 /** \class CandCombiner
0004  *
0005  * performs all possible and selected combinations
0006  * of particle pairs using the CandCombiner utility
0007  *
0008  * \author Luca Lista, INFN
0009  *
0010  * \version $Revision: 1.2 $
0011  *
0012  * $Id: CandCombiner.h,v 1.2 2009/04/22 17:51:05 kaulmer Exp $
0013  *
0014  */
0015 #include "FWCore/Framework/interface/stream/EDProducer.h"
0016 #include "FWCore/Framework/interface/Frameworkfwd.h"
0017 #include "CommonTools/CandUtils/interface/CandCombiner.h"
0018 #include "CommonTools/CandAlgos/interface/decayParser.h"
0019 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0020 #include "DataFormats/Common/interface/Handle.h"
0021 #include "FWCore/Framework/interface/Event.h"
0022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0023 #include "CommonTools/UtilAlgos/interface/ParameterAdapter.h"
0024 #include "CommonTools/UtilAlgos/interface/EventSetupInitTrait.h"
0025 #include "CommonTools/Utils/interface/cutParser.h"
0026 #include "DataFormats/Candidate/interface/Candidate.h"
0027 #include "FWCore/Utilities/interface/EDMException.h"
0028 #include "FWCore/Utilities/interface/transform.h"
0029 #include "CommonTools/CandUtils/interface/AddFourMomenta.h"
0030 #include <string>
0031 #include <vector>
0032 #include <algorithm>
0033 
0034 namespace edm {
0035   class ParameterSet;
0036 }
0037 
0038 namespace reco {
0039   namespace modules {
0040 
0041     struct RoleNames {
0042       explicit RoleNames(const edm::ParameterSet& cfg) {
0043         if (cfg.exists("name"))
0044           name_ = cfg.getParameter<std::string>("name");
0045         else
0046           name_ = "";
0047         if (cfg.exists("roles"))
0048           roles_ = cfg.getParameter<std::vector<std::string> >("roles");
0049         else
0050           roles_ = std::vector<std::string>();
0051       }
0052       const std::vector<std::string> roles() const { return roles_; }
0053       void set(reco::CompositeCandidate& c) const {
0054         c.setName(name_);
0055         c.setRoles(roles_);
0056         c.applyRoles();
0057       }
0058 
0059     private:
0060       /// Name of this candidate
0061       std::string name_;
0062       // Name of the roles
0063       std::vector<std::string> roles_;
0064     };
0065 
0066     struct CandCombinerBase : public edm::stream::EDProducer<> {
0067       CandCombinerBase(const edm::ParameterSet& cfg)
0068           : setLongLived_(false), setMassConstraint_(false), setPdgId_(false) {
0069         using namespace cand::parser;
0070         using namespace std;
0071         string decay(cfg.getParameter<string>("decay"));
0072         if (decayParser(decay, labels_))
0073           for (vector<ConjInfo>::iterator label = labels_.begin(); label != labels_.end(); ++label)
0074             if (label->mode_ == ConjInfo::kPlus)
0075               dauCharge_.push_back(1);
0076             else if (label->mode_ == ConjInfo::kMinus)
0077               dauCharge_.push_back(-1);
0078             else
0079               dauCharge_.push_back(0);
0080         else
0081           throw edm::Exception(edm::errors::Configuration, "failed to parse \"" + decay + "\"");
0082 
0083         int lists = labels_.size();
0084         if (lists != 2 && lists != 3 && lists != 4)
0085           throw edm::Exception(edm::errors::LogicError, "invalid number of collections");
0086         bool found;
0087         const string setLongLived("setLongLived");
0088         vector<string> vBoolParams = cfg.getParameterNamesForType<bool>();
0089         found = find(vBoolParams.begin(), vBoolParams.end(), setLongLived) != vBoolParams.end();
0090         if (found)
0091           setLongLived_ = cfg.getParameter<bool>("setLongLived");
0092         const string setMassConstraint("setMassConstraint");
0093         found = find(vBoolParams.begin(), vBoolParams.end(), setMassConstraint) != vBoolParams.end();
0094         if (found)
0095           setMassConstraint_ = cfg.getParameter<bool>("setMassConstraint");
0096         const string setPdgId("setPdgId");
0097         vector<string> vIntParams = cfg.getParameterNamesForType<int>();
0098         found = find(vIntParams.begin(), vIntParams.end(), setPdgId) != vIntParams.end();
0099         if (found) {
0100           setPdgId_ = true;
0101           pdgId_ = cfg.getParameter<int>("setPdgId");
0102         }
0103         tokens_ =
0104             edm::vector_transform(labels_, [this](ConjInfo const& cI) { return consumes<CandidateView>(cI.tag_); });
0105       }
0106 
0107     protected:
0108       /// label vector
0109       std::vector<cand::parser::ConjInfo> labels_;
0110       std::vector<edm::EDGetTokenT<CandidateView> > tokens_;
0111       /// daughter charges
0112       std::vector<int> dauCharge_;
0113       /// set long lived flag
0114       bool setLongLived_;
0115       /// set mass constraint flag
0116       bool setMassConstraint_;
0117       /// set pdgId flag
0118       bool setPdgId_;
0119       /// which pdgId to set
0120       int pdgId_;
0121     };
0122 
0123     template <typename Selector,
0124               typename PairSelector = AnyPairSelector,
0125               typename Cloner = ::combiner::helpers::NormalClone,
0126               typename OutputCollection = reco::CompositeCandidateCollection,
0127               typename Setup = AddFourMomenta,
0128               typename Init = typename ::reco::modules::EventSetupInit<Setup>::type>
0129     class CandCombiner : public CandCombinerBase {
0130     public:
0131       /// constructor from parameter settypedef
0132       explicit CandCombiner(const edm::ParameterSet& cfg)
0133           : CandCombinerBase(cfg),
0134             combinerInit_(consumesCollector()),
0135             combiner_(reco::modules::make<Selector>(cfg, consumesCollector()),
0136                       reco::modules::make<PairSelector>(cfg),
0137                       Setup(cfg),
0138                       cfg.existsAs<bool>("checkCharge") ? cfg.getParameter<bool>("checkCharge") : true,
0139                       cfg.existsAs<bool>("checkOverlap") ? cfg.getParameter<bool>("checkOverlap") : true,
0140                       dauCharge_),
0141             names_(cfg) {
0142         produces<OutputCollection>();
0143       }
0144       /// destructor
0145       ~CandCombiner() override {}
0146 
0147     private:
0148       /// process an event
0149       void produce(edm::Event& evt, const edm::EventSetup& es) override {
0150         combinerInit_.init(combiner_.setup(), evt, es);
0151         int n = labels_.size();
0152         std::vector<edm::Handle<CandidateView> > colls(n);
0153         for (int i = 0; i < n; ++i)
0154           evt.getByToken(tokens_[i], colls[i]);
0155 
0156         std::unique_ptr<OutputCollection> out = combiner_.combine(colls, names_.roles());
0157         if (setLongLived_ || setMassConstraint_ || setPdgId_) {
0158           typename OutputCollection::iterator i = out->begin(), e = out->end();
0159           for (; i != e; ++i) {
0160             names_.set(*i);
0161             if (setLongLived_)
0162               i->setLongLived();
0163             if (setMassConstraint_)
0164               i->setMassConstraint();
0165             if (setPdgId_)
0166               i->setPdgId(pdgId_);
0167           }
0168         }
0169         evt.put(std::move(out));
0170       }
0171       /// combiner utility
0172       Init combinerInit_;
0173       ::CandCombiner<Selector, PairSelector, Cloner, OutputCollection, Setup> combiner_;
0174 
0175       RoleNames names_;
0176     };
0177 
0178   }  // namespace modules
0179 }  // namespace reco
0180 
0181 #endif