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 "PhysicsTools/CandUtils/interface/CandCombiner.h"
00018 #include "PhysicsTools/CandAlgos/interface/decayParser.h"
00019 #include "PhysicsTools/Utilities/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 "PhysicsTools/UtilAlgos/interface/ParameterAdapter.h"
00024 #include "PhysicsTools/UtilAlgos/interface/EventSetupInitTrait.h"
00025 #include "PhysicsTools/Utilities/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 setPdgId_(false) {
00070 using namespace cand::parser;
00071 using namespace std;
00072 string decay(cfg.getParameter<string>("decay"));
00073 if(decayParser(decay, labels_))
00074 for(vector<ConjInfo>::iterator label = labels_.begin();
00075 label != labels_.end(); ++label)
00076 if(label->mode_ == ConjInfo::kPlus)
00077 dauCharge_.push_back(1);
00078 else if (label->mode_ == ConjInfo::kMinus)
00079 dauCharge_.push_back(-1);
00080 else
00081 dauCharge_.push_back(0);
00082 else
00083 throw edm::Exception(edm::errors::Configuration,
00084 "failed to parse \"" + decay + "\"");
00085
00086 int lists = labels_.size();
00087 if(lists != 2 && lists != 3)
00088 throw edm::Exception(edm::errors::LogicError,
00089 "invalid number of collections");
00090 bool found;
00091 const string setLongLived("setLongLived");
00092 vector<string> vBoolParams = cfg.getParameterNamesForType<bool>();
00093 found = find(vBoolParams.begin(), vBoolParams.end(), setLongLived) != vBoolParams.end();
00094 if(found) setLongLived_ = cfg.getParameter<bool>("setLongLived");
00095 const string setPdgId("setPdgId");
00096 vector<string> vIntParams = cfg.getParameterNamesForType<int>();
00097 found = find(vIntParams.begin(), vIntParams.end(), setPdgId) != vIntParams.end();
00098 if(found) { setPdgId_ = true; pdgId_ = cfg.getParameter<int>("setPdgId"); }
00099 }
00100 protected:
00102 std::vector<cand::parser::ConjInfo> labels_;
00104 std::vector<int> dauCharge_;
00106 bool setLongLived_;
00108 bool setPdgId_;
00110 int pdgId_;
00111 };
00112
00113 template<typename Selector,
00114 typename PairSelector = AnyPairSelector,
00115 typename Cloner = ::combiner::helpers::NormalClone,
00116 typename OutputCollection = reco::CompositeCandidateCollection,
00117 typename Setup = AddFourMomenta,
00118 typename Init = typename ::reco::modules::EventSetupInit<Setup>::type
00119 >
00120 class CandCombiner : public CandCombinerBase {
00121 public:
00123 explicit CandCombiner(const edm::ParameterSet & cfg) :
00124 CandCombinerBase(cfg),
00125 combiner_(reco::modules::make<Selector>(cfg),
00126 reco::modules::make<PairSelector>(cfg),
00127 Setup(cfg),
00128 checkCharge(cfg),
00129 dauCharge_),
00130 names_(cfg) {
00131 produces<OutputCollection>();
00132 }
00134 virtual ~CandCombiner() { }
00135
00136 private:
00138 void produce(edm::Event& evt, const edm::EventSetup& es) {
00139 using namespace std;
00140 using namespace reco;
00141 Init::init(combiner_.setup(), evt, es);
00142 int n = labels_.size();
00143 vector<edm::Handle<CandidateView> > colls(n);
00144 for(int i = 0; i < n; ++i)
00145 evt.getByLabel(labels_[i].tag_, colls[i]);
00146
00147 auto_ptr<OutputCollection> out = combiner_.combine(colls, names_.roles());
00148 if(setLongLived_ || setPdgId_) {
00149 typename OutputCollection::iterator i = out->begin(), e = out->end();
00150 for(; i != e; ++i) {
00151 names_.set(*i);
00152 if(setLongLived_) i->setLongLived();
00153 if(setPdgId_) i->setPdgId(pdgId_);
00154 }
00155 }
00156 evt.put(out);
00157 }
00158 bool checkCharge(const edm::ParameterSet & cfg) const {
00159 using namespace std;
00160 const string par("checkCharge");
00161 vector<string> bools = cfg.getParameterNamesForType<bool>();
00162 bool found = find(bools.begin(), bools.end(), "checkCharge") != bools.end();
00163 if (found) return cfg.getParameter<bool>(par);
00164
00165 return true;
00166 }
00168 ::CandCombiner<Selector, PairSelector, Cloner, OutputCollection, Setup> combiner_;
00169
00170 RoleNames names_;
00171 };
00172
00173 }
00174 }
00175
00176 #endif