CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/PhysicsTools/PatAlgos/plugins/PATSingleVertexSelector.cc

Go to the documentation of this file.
00001 #include "PhysicsTools/PatAlgos/plugins/PATSingleVertexSelector.h"
00002 #include "DataFormats/Common/interface/View.h"
00003 #include "DataFormats/Candidate/interface/VertexCompositeCandidate.h"
00004 #include <DataFormats/BeamSpot/interface/BeamSpot.h>
00005 
00006 #include <algorithm>
00007 
00008 using pat::PATSingleVertexSelector;
00009 
00010 
00011 PATSingleVertexSelector::Mode
00012 PATSingleVertexSelector::parseMode(const std::string &mode) {
00013     if (mode == "firstVertex") {
00014         return First;
00015     } else if (mode == "nearestToCandidate") {
00016         return NearestToCand;
00017     } else if (mode == "fromCandidate") {
00018         return FromCand;
00019     } else if (mode == "beamSpot") {
00020         return FromBeamSpot;
00021     } else {
00022         throw cms::Exception("Configuration") << "PATSingleVertexSelector: Mode '" << mode << "' not recognized or not supported.\n";
00023     }
00024 }
00025 
00026 
00027 PATSingleVertexSelector::PATSingleVertexSelector(const edm::ParameterSet & iConfig)
00028   : doFilterEvents_(false)
00029 {
00030    using namespace std;
00031 
00032    modes_.push_back( parseMode(iConfig.getParameter<std::string>("mode")) );
00033    if (iConfig.exists("fallbacks")) {
00034       vector<string> modes = iConfig.getParameter<vector<string> >("fallbacks");
00035       for (vector<string>::const_iterator it = modes.begin(), ed = modes.end(); it != ed; ++it) {
00036         modes_.push_back( parseMode(*it) );
00037       }
00038    }
00039    if (hasMode_(First) || hasMode_(NearestToCand)) {
00040         vertices_ = iConfig.getParameter<edm::InputTag>("vertices");
00041         if (iConfig.existsAs<string>("vertexPreselection")) {
00042             string presel = iConfig.getParameter<string>("vertexPreselection");
00043             if (!presel.empty()) vtxPreselection_ = auto_ptr<VtxSel>(new VtxSel(presel));
00044         }
00045    }
00046    if (hasMode_(NearestToCand) || hasMode_(FromCand)) {
00047         candidates_ = iConfig.getParameter<vector<edm::InputTag> >("candidates");
00048         if (iConfig.existsAs<string>("candidatePreselection")) {
00049             string presel = iConfig.getParameter<string>("candidatePreselection");
00050             if (!presel.empty()) candPreselection_ = auto_ptr<CandSel>(new CandSel(presel));
00051         }
00052    }
00053    if (hasMode_(FromBeamSpot)) {
00054         beamSpot_ = iConfig.getParameter<edm::InputTag>("beamSpot");
00055    }
00056 
00057    if ( iConfig.exists("filter") ) doFilterEvents_ = iConfig.getParameter<bool>("filter");
00058 
00059    produces<vector<reco::Vertex> >();
00060 }
00061 
00062 
00063 PATSingleVertexSelector::~PATSingleVertexSelector()
00064 {
00065 }
00066 
00067 bool PATSingleVertexSelector::hasMode_(Mode mode) const {
00068     return (std::find(modes_.begin(), modes_.end(), mode) != modes_.end());
00069 }
00070 
00071 bool
00072 PATSingleVertexSelector::filter(edm::Event & iEvent, const edm::EventSetup & iSetup) {
00073     using namespace edm;
00074     using namespace std;
00075 
00076     // Clear
00077     selVtxs_.clear(); bestCand_ = 0;
00078 
00079     // Gather data from the Event
00080     // -- vertex data --
00081     if (hasMode_(First) || hasMode_(NearestToCand)) {
00082         Handle<vector<reco::Vertex> > vertices;
00083         iEvent.getByLabel(vertices_, vertices);
00084         for (vector<reco::Vertex>::const_iterator itv = vertices->begin(), edv = vertices->end(); itv != edv; ++itv) {
00085             if ((vtxPreselection_.get() != 0) && !((*vtxPreselection_)(*itv)) ) continue;
00086             selVtxs_.push_back( &*itv );
00087         }
00088     }
00089     // -- candidate data --
00090     if (hasMode_(NearestToCand) || hasMode_(FromCand)) {
00091        vector<pair<double, const reco::Candidate *> > cands;
00092        for (vector<edm::InputTag>::const_iterator itt = candidates_.begin(), edt = candidates_.end(); itt != edt; ++itt) {
00093           Handle<View<reco::Candidate> > theseCands;
00094           iEvent.getByLabel(*itt, theseCands);
00095           for (View<reco::Candidate>::const_iterator itc = theseCands->begin(), edc = theseCands->end(); itc != edc; ++itc) {
00096             if ((candPreselection_.get() != 0) && !((*candPreselection_)(*itc))) continue;
00097             cands.push_back( pair<double, const reco::Candidate *>(-itc->pt(), &*itc) );
00098           }
00099        }
00100        if (!cands.empty()) bestCand_ = cands.front().second;
00101     }
00102 
00103     bool passes = false;
00104     auto_ptr<vector<reco::Vertex> > result;
00105     // Run main mode + possible fallback modes
00106     for (std::vector<Mode>::const_iterator itm = modes_.begin(), endm = modes_.end(); itm != endm; ++itm) {
00107         result = filter_(*itm, iEvent, iSetup);
00108         // Check if we got any vertices.  If so, take them.
00109         if (result->size()) {
00110           passes = true;
00111           break;
00112         }
00113     }
00114     iEvent.put(result);
00115     // Check if we want to apply the EDFilter
00116     if (doFilterEvents_)
00117       return passes;
00118     else return true;
00119 }
00120 
00121 std::auto_ptr<std::vector<reco::Vertex> >
00122 PATSingleVertexSelector::filter_(Mode mode, const edm::Event &iEvent, const edm::EventSetup & iSetup) {
00123     using namespace edm;
00124     using namespace std;
00125     std::auto_ptr<std::vector<reco::Vertex> > result(
00126         new std::vector<reco::Vertex>());
00127     switch(mode) {
00128         case First: {
00129             if (selVtxs_.empty()) return result;
00130             result->push_back(*selVtxs_.front());
00131             return result;
00132             }
00133         case FromCand: {
00134             if (bestCand_ == 0) return result;
00135             reco::Vertex vtx;
00136             if (typeid(*bestCand_) == typeid(reco::VertexCompositeCandidate)) {
00137                 vtx = reco::Vertex(bestCand_->vertex(), bestCand_->vertexCovariance(),
00138                         bestCand_->vertexChi2(), bestCand_->vertexNdof(), bestCand_->numberOfDaughters() );
00139             } else {
00140                 vtx = reco::Vertex(bestCand_->vertex(), reco::Vertex::Error(), 0, 0, 0);
00141             }
00142             result->push_back(vtx);
00143             return result;
00144             }
00145         case NearestToCand: {
00146             if (selVtxs_.empty() || (bestCand_ == 0)) return result;
00147             const reco::Vertex * which = 0;
00148             float dzmin = 9999.0;
00149             for (vector<const reco::Vertex *>::const_iterator itv = selVtxs_.begin(), edv = selVtxs_.end(); itv != edv; ++itv) {
00150                 float dz = std::abs((*itv)->z() - bestCand_->vz());
00151                 if (dz < dzmin) { dzmin = dz; which = *itv; }
00152             }
00153             if (which != 0) // actually it should not happen, but better safe than sorry
00154               result->push_back(*which);
00155             return result;
00156             }
00157         case FromBeamSpot: {
00158             Handle<reco::BeamSpot> beamSpot;
00159             iEvent.getByLabel(beamSpot_, beamSpot);
00160             reco::Vertex bs(beamSpot->position(), beamSpot->covariance3D(), 0, 0, 0);
00161             result->push_back(bs);
00162             return result;
00163             }
00164         default:
00165             // Return an empty vector signifying no vertices found.
00166             return result;
00167     }
00168 }
00169 
00170 #include "FWCore/Framework/interface/MakerMacros.h"
00171 DEFINE_FWK_MODULE(PATSingleVertexSelector);