CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/CommonTools/CandAlgos/interface/CandCombiner.h

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       // Name of the roles
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