CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoTauTag/TauTagTools/plugins/CandViewRefRandomSelector.cc

Go to the documentation of this file.
00001 /*
00002  * CandViewRefRandomSelector
00003  *
00004  * Author: Evan K. Friis (UC Davis)
00005  *
00006  * Takes a collection of objects inheriting from Candidates and returns up to
00007  * N=<choose> candidates.  The N output elements are selected randomly.  If
00008  * the collection contains N or fewer elements, the entire collection is
00009  * returned.
00010  *
00011  */
00012 
00013 #include <vector>
00014 
00015 #include "FWCore/Framework/interface/Frameworkfwd.h"
00016 #include "FWCore/Framework/interface/EDFilter.h"
00017 #include "FWCore/Framework/interface/Event.h"
00018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00019 
00020 #include "DataFormats/Candidate/interface/Candidate.h"
00021 #include "DataFormats/Candidate/interface/CandidateFwd.h"
00022 
00023 #include "TRandom3.h"
00024 
00025 class CandViewRefRandomSelector : public edm::EDFilter {
00026   public:
00027     explicit CandViewRefRandomSelector(const edm::ParameterSet &pset);
00028     bool filter(edm::Event&, const edm::EventSetup&);
00029   private:
00030     edm::InputTag src_;
00031     unsigned int choose_;
00032     unsigned int seed_;
00033     bool filter_;
00034     TRandom3 randy_;
00035 };
00036 
00037 CandViewRefRandomSelector::CandViewRefRandomSelector(
00038     const edm::ParameterSet &pset) {
00039   src_ = pset.getParameter<edm::InputTag>("src");
00040   choose_ = pset.getParameter<unsigned int>("choose");
00041   filter_ = pset.getParameter<bool>("filter");
00042   seed_ = pset.exists("seed") ? pset.getParameter<unsigned int>("seed") : 123;
00043   randy_ = TRandom3(seed_);
00044   produces<reco::CandidateBaseRefVector>();
00045 }
00046 
00047 bool CandViewRefRandomSelector::filter(edm::Event& evt,
00048                                        const edm::EventSetup& es) {
00049   edm::Handle<edm::View<reco::Candidate> > cands;
00050   evt.getByLabel(src_, cands);
00051   std::auto_ptr<reco::CandidateBaseRefVector> output(
00052       new reco::CandidateBaseRefVector(cands));
00053   // If we don't have enough elements to select, just copy what we have
00054   const reco::CandidateBaseRefVector &inputRefs = cands->refVector();
00055   if (inputRefs.size() <= choose_) {
00056     *output = inputRefs;
00057   } else {
00058     for (size_t i = 0; i < inputRefs.size() && output->size() < choose_; ++i) {
00059       // based on http://stackoverflow.com/questions/48087/
00060       // select-a-random-n-elements-from-listt-in-c/48089#48089
00061       double selectionProb =
00062           (choose_ - output->size())*1.0/(inputRefs.size() - i);
00063       // throw a number to see if we select this element
00064       if (randy_.Rndm() < selectionProb)
00065         output->push_back(inputRefs[i]);
00066     }
00067   }
00068   size_t outputSize = output->size();
00069   evt.put(output);
00070   return ( !filter_ || outputSize );
00071 }
00072 
00073 #include "FWCore/Framework/interface/MakerMacros.h"
00074 DEFINE_FWK_MODULE(CandViewRefRandomSelector);