Go to the documentation of this file.00001 #ifndef CandAlgos_CandCombiner_h
00002 #define CandAlgos_CandCombiner_h
00003
00015 #include "FWCore/Framework/interface/EDProducer.h"
00016 #include "FWCore/Framework/interface/Frameworkfwd.h"
00017 #include "CommonTools/CandUtils/interface/CandCombiner.h"
00018 #include "CommonTools/CandAlgos/interface/decayParser.h"
00019 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
00020 #include "DataFormats/Common/interface/Handle.h"
00021 #include "FWCore/Framework/interface/Event.h"
00022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00023 #include "CommonTools/UtilAlgos/interface/ParameterAdapter.h"
00024 #include "CommonTools/UtilAlgos/interface/EventSetupInitTrait.h"
00025 #include "CommonTools/Utils/interface/cutParser.h"
00026 #include "DataFormats/Candidate/interface/Candidate.h"
00027 #include "FWCore/Utilities/interface/EDMException.h"
00028 #include <string>
00029 #include <vector>
00030 #include <algorithm>
00031
00032 namespace edm {
00033 class ParameterSet;
00034 }
00035
00036 namespace reco {
00037 namespace modules {
00038
00039
00040 struct RoleNames {
00041 explicit RoleNames(const edm::ParameterSet & cfg) {
00042
00043 if ( cfg.exists("name") )
00044 name_ = cfg.getParameter<std::string>("name");
00045 else
00046 name_ = "";
00047 if ( cfg.exists("roles") )
00048 roles_ = cfg.getParameter<std::vector<std::string> >("roles");
00049 else
00050 roles_ = std::vector<std::string>();
00051 }
00052 const std::vector<std::string> roles() const { return roles_; }
00053 void set(reco::CompositeCandidate &c) const {
00054 c.setName(name_);
00055 c.setRoles(roles_);
00056 c.applyRoles();
00057 }
00058 private:
00060 std::string name_;
00061
00062 std::vector<std::string> roles_;
00063 };
00064
00065
00066 struct CandCombinerBase : public edm::EDProducer {
00067 CandCombinerBase(const edm::ParameterSet & cfg) :
00068 setLongLived_(false),
00069 setMassConstraint_(false),
00070 setPdgId_(false) {
00071 using namespace cand::parser;
00072 using namespace std;
00073 string decay(cfg.getParameter<string>("decay"));
00074 if(decayParser(decay, labels_))
00075 for(vector<ConjInfo>::iterator label = labels_.begin();
00076 label != labels_.end(); ++label)
00077 if(label->mode_ == ConjInfo::kPlus)
00078 dauCharge_.push_back(1);
00079 else if (label->mode_ == ConjInfo::kMinus)
00080 dauCharge_.push_back(-1);
00081 else
00082 dauCharge_.push_back(0);
00083 else
00084 throw edm::Exception(edm::errors::Configuration,
00085 "failed to parse \"" + decay + "\"");
00086
00087 int lists = labels_.size();
00088 if(lists != 2 && lists != 3)
00089 throw edm::Exception(edm::errors::LogicError,
00090 "invalid number of collections");
00091 bool found;
00092 const string setLongLived("setLongLived");
00093 vector<string> vBoolParams = cfg.getParameterNamesForType<bool>();
00094 found = find(vBoolParams.begin(), vBoolParams.end(), setLongLived) != vBoolParams.end();
00095 if(found) setLongLived_ = cfg.getParameter<bool>("setLongLived");
00096 const string setMassConstraint("setMassConstraint");
00097 found = find(vBoolParams.begin(), vBoolParams.end(), setMassConstraint) != vBoolParams.end();
00098 if(found) setMassConstraint_ = cfg.getParameter<bool>("setMassConstraint");
00099 const string setPdgId("setPdgId");
00100 vector<string> vIntParams = cfg.getParameterNamesForType<int>();
00101 found = find(vIntParams.begin(), vIntParams.end(), setPdgId) != vIntParams.end();
00102 if(found) { setPdgId_ = true; pdgId_ = cfg.getParameter<int>("setPdgId"); }
00103 }
00104 protected:
00106 std::vector<cand::parser::ConjInfo> labels_;
00108 std::vector<int> dauCharge_;
00110 bool setLongLived_;
00112 bool setMassConstraint_;
00114 bool setPdgId_;
00116 int pdgId_;
00117 };
00118
00119 template<typename Selector,
00120 typename PairSelector = AnyPairSelector,
00121 typename Cloner = ::combiner::helpers::NormalClone,
00122 typename OutputCollection = reco::CompositeCandidateCollection,
00123 typename Setup = AddFourMomenta,
00124 typename Init = typename ::reco::modules::EventSetupInit<Setup>::type
00125 >
00126 class CandCombiner : public CandCombinerBase {
00127 public:
00129 explicit CandCombiner(const edm::ParameterSet & cfg) :
00130 CandCombinerBase(cfg),
00131 combiner_(reco::modules::make<Selector>(cfg),
00132 reco::modules::make<PairSelector>(cfg),
00133 Setup(cfg),
00134 cfg.existsAs<bool>("checkCharge") ? cfg.getParameter<bool>("checkCharge") : true,
00135 cfg.existsAs<bool>("checkOverlap") ? cfg.getParameter<bool>("checkOverlap") : true,
00136 dauCharge_),
00137 names_(cfg) {
00138 produces<OutputCollection>();
00139 }
00141 virtual ~CandCombiner() { }
00142
00143 private:
00145 void produce(edm::Event& evt, const edm::EventSetup& es) {
00146 using namespace std;
00147 using namespace reco;
00148 Init::init(combiner_.setup(), evt, es);
00149 int n = labels_.size();
00150 vector<edm::Handle<CandidateView> > colls(n);
00151 for(int i = 0; i < n; ++i)
00152 evt.getByLabel(labels_[i].tag_, colls[i]);
00153
00154 auto_ptr<OutputCollection> out = combiner_.combine(colls, names_.roles());
00155 if(setLongLived_ || setMassConstraint_ || setPdgId_) {
00156 typename OutputCollection::iterator i = out->begin(), e = out->end();
00157 for(; i != e; ++i) {
00158 names_.set(*i);
00159 if(setLongLived_) i->setLongLived();
00160 if(setMassConstraint_) i->setMassConstraint();
00161 if(setPdgId_) i->setPdgId(pdgId_);
00162 }
00163 }
00164 evt.put(out);
00165 }
00167 ::CandCombiner<Selector, PairSelector, Cloner, OutputCollection, Setup> combiner_;
00168
00169 RoleNames names_;
00170 };
00171
00172 }
00173 }
00174
00175 #endif