File indexing completed on 2025-03-29 02:42:48
0001 #ifndef CandAlgos_CandCombiner_h
0002 #define CandAlgos_CandCombiner_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
0061 std::string name_;
0062
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
0109 std::vector<cand::parser::ConjInfo> labels_;
0110 std::vector<edm::EDGetTokenT<CandidateView> > tokens_;
0111
0112 std::vector<int> dauCharge_;
0113
0114 bool setLongLived_;
0115
0116 bool setMassConstraint_;
0117
0118 bool setPdgId_;
0119
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
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
0145 ~CandCombiner() override {}
0146
0147 private:
0148
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
0172 Init combinerInit_;
0173 ::CandCombiner<Selector, PairSelector, Cloner, OutputCollection, Setup> combiner_;
0174
0175 RoleNames names_;
0176 };
0177
0178 }
0179 }
0180
0181 #endif