CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/ElectroWeakAnalysis/WMuNu/src/WMuNuValidator.cc

Go to the documentation of this file.
00001 
00002 //                                                                                                                      //
00003 //                                    WMuNuValidator                                                                    //
00004 //                                                                                                                      //    
00006 //                                                                                                                      //      
00007 //    Basic plots before & after cuts (without Candidate formalism)                                                     //
00008 //    Intended for a prompt validation of samples.                                                                      // 
00009 //                                                                                                                      //      
00010 //    Use in combination with WMuNuValidatorMacro (in bin/WMuNuValidatorMacro.cpp)                                      //
00011 //                                                                                                                      //
00013 
00014 
00015 #include "FWCore/Framework/interface/EDFilter.h"
00016 #include "FWCore/Utilities/interface/InputTag.h"
00017 #include "FWCore/Framework/interface/Event.h"
00018 #include "TH1D.h"
00019 #include <map>
00020 
00021 class WMuNuValidator : public edm::EDFilter {
00022 public:
00023   WMuNuValidator (const edm::ParameterSet &);
00024   virtual bool filter(edm::Event&, const edm::EventSetup&);
00025   virtual void beginJob();
00026   virtual void endJob();
00027   void init_histograms();
00028   void fill_histogram(const char*, const double&);
00029 private:
00030   bool fastOption_;
00031   edm::InputTag trigTag_;
00032   edm::InputTag muonTag_;
00033   edm::InputTag metTag_;
00034   bool metIncludesMuons_;
00035   edm::InputTag jetTag_;
00036 
00037   const std::string muonTrig_;
00038   double ptCut_;
00039   double etaCut_;
00040   bool isRelativeIso_;
00041   bool isCombinedIso_;
00042   double isoCut03_;
00043   double mtMin_;
00044   double mtMax_;
00045   double metMin_;
00046   double metMax_;
00047   double acopCut_;
00048 
00049   double dxyCut_;
00050   double normalizedChi2Cut_;
00051   int trackerHitsCut_;
00052   bool isAlsoTrackerMuon_;
00053 
00054   double ptThrForZ1_;
00055   double ptThrForZ2_;
00056 
00057   double eJetMin_;
00058   int nJetMax_;
00059 
00060   unsigned int nall;
00061   unsigned int nrec;
00062   unsigned int niso;
00063   unsigned int nhlt;
00064   unsigned int nmet;
00065   unsigned int nsel;
00066 
00067   std::map<std::string,TH1D*> h1_;
00068 };
00069 
00070 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00071 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00072 #include "DataFormats/Common/interface/Handle.h"
00073 
00074 #include "FWCore/ServiceRegistry/interface/Service.h"
00075 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00076 
00077 #include "DataFormats/TrackReco/interface/Track.h"
00078 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00079 
00080 #include "DataFormats/MuonReco/interface/Muon.h"
00081 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
00082 
00083 #include "DataFormats/METReco/interface/MET.h"
00084 #include "DataFormats/JetReco/interface/Jet.h"
00085 
00086 #include "DataFormats/GeometryVector/interface/Phi.h"
00087 
00088 #include "FWCore/Common/interface/TriggerNames.h"
00089 #include "DataFormats/Common/interface/TriggerResults.h"
00090 
00091 #include "DataFormats/Common/interface/View.h"
00092   
00093 using namespace edm;
00094 using namespace std;
00095 using namespace reco;
00096 
00097 WMuNuValidator::WMuNuValidator( const ParameterSet & cfg ) :
00098       // Fast selection (no histograms or book-keeping)
00099       fastOption_(cfg.getUntrackedParameter<bool> ("FastOption", false)),
00100 
00101       // Input collections
00102       trigTag_(cfg.getUntrackedParameter<edm::InputTag> ("TrigTag", edm::InputTag("TriggerResults::HLT"))),
00103       muonTag_(cfg.getUntrackedParameter<edm::InputTag> ("MuonTag", edm::InputTag("muons"))),
00104       metTag_(cfg.getUntrackedParameter<edm::InputTag> ("METTag", edm::InputTag("met"))),
00105       metIncludesMuons_(cfg.getUntrackedParameter<bool> ("METIncludesMuons", false)),
00106       jetTag_(cfg.getUntrackedParameter<edm::InputTag> ("JetTag", edm::InputTag("sisCone5CaloJets"))),
00107 
00108       // Main cuts 
00109       muonTrig_(cfg.getUntrackedParameter<std::string> ("MuonTrig", "HLT_Mu9")),
00110       ptCut_(cfg.getUntrackedParameter<double>("PtCut", 25.)),
00111       etaCut_(cfg.getUntrackedParameter<double>("EtaCut", 2.1)),
00112       isRelativeIso_(cfg.getUntrackedParameter<bool>("IsRelativeIso", true)),
00113       isCombinedIso_(cfg.getUntrackedParameter<bool>("IsCombinedIso", false)),
00114       isoCut03_(cfg.getUntrackedParameter<double>("IsoCut03", 0.1)),
00115       mtMin_(cfg.getUntrackedParameter<double>("MtMin", 50.)),
00116       mtMax_(cfg.getUntrackedParameter<double>("MtMax", 200.)),
00117       metMin_(cfg.getUntrackedParameter<double>("MetMin", -999999.)),
00118       metMax_(cfg.getUntrackedParameter<double>("MetMax", 999999.)),
00119       acopCut_(cfg.getUntrackedParameter<double>("AcopCut", 2.)),
00120 
00121       // Muon quality cuts
00122       dxyCut_(cfg.getUntrackedParameter<double>("DxyCut", 0.2)),
00123       normalizedChi2Cut_(cfg.getUntrackedParameter<double>("NormalizedChi2Cut", 10.)),
00124       trackerHitsCut_(cfg.getUntrackedParameter<int>("TrackerHitsCut", 11)),
00125       isAlsoTrackerMuon_(cfg.getUntrackedParameter<bool>("IsAlsoTrackerMuon", true)),
00126 
00127       // Z rejection
00128       ptThrForZ1_(cfg.getUntrackedParameter<double>("PtThrForZ1", 20.)),
00129       ptThrForZ2_(cfg.getUntrackedParameter<double>("PtThrForZ2", 10.)),
00130 
00131       // Top rejection
00132       eJetMin_(cfg.getUntrackedParameter<double>("EJetMin", 999999.)),
00133       nJetMax_(cfg.getUntrackedParameter<int>("NJetMax", 999999))
00134 {
00135 }
00136 
00137 void WMuNuValidator::beginJob() {
00138       nall = 0;
00139       nsel = 0;
00140 
00141       if (!fastOption_) {
00142             nrec = 0;
00143             niso = 0;
00144             nhlt = 0;
00145             nmet = 0;
00146             init_histograms();
00147       }
00148 }
00149 
00150 void WMuNuValidator::init_histograms() {
00151       edm::Service<TFileService> fs;
00152       TFileDirectory subDir0 = fs->mkdir("BeforeCuts");
00153       TFileDirectory subDir1 = fs->mkdir("LastCut");
00154       TFileDirectory* subDir[2]; subDir[0] = &subDir0; subDir[1] = &subDir1;
00155 
00156       char chname[256] = "";
00157       char chtitle[256] = "";
00158       std::string chsuffix[2] = { "_BEFORECUTS", "_LASTCUT" };
00159 
00160       for (int i=0; i<2; ++i) {
00161             snprintf(chname, 255, "PT%s", chsuffix[i].data());
00162             snprintf(chtitle, 255, "Muon transverse momentum [GeV]");
00163             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,100,0.,100.);
00164 
00165             snprintf(chname, 255, "ETA%s", chsuffix[i].data());
00166             snprintf(chtitle, 255, "Muon pseudo-rapidity");
00167             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,50,-2.5,2.5);
00168 
00169             snprintf(chname, 255, "DXY%s", chsuffix[i].data());
00170             snprintf(chtitle, 255, "Muon transverse distance to beam spot [cm]");
00171             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,100,-0.5,0.5);
00172 
00173             snprintf(chname, 255, "CHI2%s", chsuffix[i].data());
00174             snprintf(chtitle, 255, "Normalized Chi2, inner track fit");
00175             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,100,0.,100.);
00176 
00177             snprintf(chname, 255, "NHITS%s", chsuffix[i].data());
00178             snprintf(chtitle, 255, "Number of hits, inner track");
00179             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,40,-0.5,39.5);
00180 
00181             snprintf(chname, 255, "ValidMuonHits%s", chsuffix[i].data());
00182             snprintf(chtitle, 255, "number Of Valid Muon Hits");
00183             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,40,-0.5,39.5);
00184 
00185             snprintf(chname, 255, "TKMU%s", chsuffix[i].data());
00186             snprintf(chtitle, 255, "Tracker-muon flag (for global muons)");
00187             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,2,-0.5,1.5);
00188 
00189             snprintf(chname, 255, "ISO%s", chsuffix[i].data());
00190             if (isRelativeIso_) {
00191                   if (isCombinedIso_) {
00192                         snprintf(chtitle, 255, "Relative (combined) isolation variable");
00193                   } else {
00194                         snprintf(chtitle, 255, "Relative (tracker) isolation variable");
00195                   }
00196                   h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle, 100, 0., 1.);
00197             } else {
00198                   if (isCombinedIso_) {
00199                         snprintf(chtitle, 255, "Absolute (combined) isolation variable [GeV]");
00200                   } else {
00201                         snprintf(chtitle, 255, "Absolute (tracker) isolation variable [GeV]");
00202                   }
00203                   h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle, 100, 0., 20.);
00204             }
00205 
00206             snprintf(chname, 255, "TRIG%s", chsuffix[i].data());
00207             snprintf(chtitle, 255, "Trigger response (bit %s)", muonTrig_.data());
00208             h1_[chname]  = subDir[i]->make<TH1D>(chname,chtitle,2,-0.5,1.5);
00209 
00210             snprintf(chname, 255, "MT%s", chsuffix[i].data());
00211             snprintf(chtitle, 255, "Transverse mass (%s) [GeV]", metTag_.label().data());
00212             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,150,0.,300.);
00213 
00214             snprintf(chname, 255, "MET%s", chsuffix[i].data());
00215             snprintf(chtitle, 255, "Missing transverse energy (%s) [GeV]", metTag_.label().data());
00216             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,100,0.,200.);
00217 
00218             snprintf(chname, 255, "ACOP%s", chsuffix[i].data());
00219             snprintf(chtitle, 255, "MU-MET (%s) acoplanarity", metTag_.label().data());
00220             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,50,0.,M_PI);
00221 
00222             snprintf(chname, 255, "NZ1%s", chsuffix[i].data());
00223             snprintf(chtitle, 255, "Z rejection: number of muons above %.2f GeV", ptThrForZ1_);
00224             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle, 10, -0.5, 9.5);
00225 
00226             snprintf(chname, 255, "NZ2%s", chsuffix[i].data());
00227             snprintf(chtitle, 255, "Z rejection: number of muons above %.2f GeV", ptThrForZ2_);
00228             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle, 10, -0.5, 9.5);
00229 
00230             snprintf(chname, 255, "NJETS%s", chsuffix[i].data());
00231             snprintf(chtitle, 255, "Number of jets (%s) above %.2f GeV", jetTag_.label().data(), eJetMin_);
00232             h1_[chname] = subDir[i]->make<TH1D>(chname,chtitle,10,-0.5,9.5);
00233 
00234       }
00235 }
00236 
00237 void WMuNuValidator::fill_histogram(const char* name, const double& var) {
00238       if (fastOption_) return;
00239       h1_[name]->Fill(var);
00240 }
00241 
00242 void WMuNuValidator::endJob() {
00243       double all = nall;
00244       double esel = nsel/all;
00245       LogVerbatim("") << "\n>>>>>> W SELECTION SUMMARY BEGIN >>>>>>>>>>>>>>>";
00246       LogVerbatim("") << "Total numer of events analyzed: " << nall << " [events]";
00247       LogVerbatim("") << "Total numer of events selected: " << nsel << " [events]";
00248       LogVerbatim("") << "Overall efficiency:             " << "(" << setprecision(4) << esel*100. <<" +/- "<< setprecision(2) << sqrt(esel*(1-esel)/all)*100. << ")%";
00249 
00250       if (!fastOption_) {
00251         double erec = nrec/all;
00252         double eiso = niso/all;
00253         double ehlt = nhlt/all;
00254         double emet = nmet/all;
00255 
00256         double num = nrec;
00257         double eff = erec;
00258         double err = sqrt(eff*(1-eff)/all);
00259         LogVerbatim("") << "Passing Pt/Eta/Quality cuts:    " << num << " [events], (" << setprecision(4) << eff*100. <<" +/- "<< setprecision(2) << err*100. << ")%";
00260 
00261         num = niso;
00262         eff = eiso;
00263         err = sqrt(eff*(1-eff)/all);
00264         double effstep = 0.;
00265         double errstep = 0.;
00266         if (nrec>0) effstep = eiso/erec;
00267         if (nrec>0) errstep = sqrt(effstep*(1-effstep)/nrec);
00268         LogVerbatim("") << "Passing isolation cuts:         " << num << " [events], (" << setprecision(4) << eff*100. <<" +/- "<< setprecision(2) << err*100. << ")%, to previous step: (" <<  setprecision(4) << effstep*100. << " +/- "<< setprecision(2) << errstep*100. <<")%";
00269   
00270         num = nhlt;
00271         eff = ehlt;
00272         err = sqrt(eff*(1-eff)/all);
00273         effstep = 0.;
00274         errstep = 0.;
00275         if (niso>0) effstep = ehlt/eiso;
00276         if (niso>0) errstep = sqrt(effstep*(1-effstep)/niso);
00277         LogVerbatim("") << "Passing HLT criteria:           " << num << " [events], (" << setprecision(4) << eff*100. <<" +/- "<< setprecision(2) << err*100. << ")%, to previous step: (" <<  setprecision(4) << effstep*100. << " +/- "<< setprecision(2) << errstep*100. <<")%";
00278 
00279         num = nmet;
00280         eff = emet;
00281         err = sqrt(eff*(1-eff)/all);
00282         effstep = 0.;
00283         errstep = 0.;
00284         if (nhlt>0) effstep = emet/ehlt;
00285         if (nhlt>0) errstep = sqrt(effstep*(1-effstep)/nhlt);
00286         LogVerbatim("") << "Passing MET/acoplanarity cuts:  " << num << " [events], (" << setprecision(4) << eff*100. <<" +/- "<< setprecision(2) << err*100. << ")%, to previous step: (" <<  setprecision(4) << effstep*100. << " +/- "<< setprecision(2) << errstep*100. <<")%";
00287 
00288         num = nsel;
00289         eff = esel;
00290         err = sqrt(eff*(1-eff)/all);
00291         effstep = 0.;
00292         errstep = 0.;
00293         if (nmet>0) effstep = esel/emet;
00294         if (nmet>0) errstep = sqrt(effstep*(1-effstep)/nmet);
00295         LogVerbatim("") << "Passing Z/top rejection cuts:   " << num << " [events], (" << setprecision(4) << eff*100. <<" +/- "<< setprecision(2) << err*100. << ")%, to previous step: (" <<  setprecision(4) << effstep*100. << " +/- "<< setprecision(2) << errstep*100. <<")%";
00296       }
00297 
00298       LogVerbatim("") << ">>>>>> W SELECTION SUMMARY END   >>>>>>>>>>>>>>>\n";
00299 }
00300 
00301 bool WMuNuValidator::filter (Event & ev, const EventSetup &) {
00302 
00303       // Reset global event selection flags
00304       bool rec_sel = false;
00305       bool iso_sel = false;
00306       bool hlt_sel = false;
00307       bool met_sel = false;
00308       bool all_sel = false;
00309 
00310       // Muon collection
00311       Handle<View<Muon> > muonCollection;
00312       if (!ev.getByLabel(muonTag_, muonCollection)) {
00313             LogError("") << ">>> Muon collection does not exist !!!";
00314             return false;
00315       }
00316       unsigned int muonCollectionSize = muonCollection->size();
00317 
00318       // Beam spot
00319       Handle<reco::BeamSpot> beamSpotHandle;
00320       if (!ev.getByLabel(InputTag("offlineBeamSpot"), beamSpotHandle)) {
00321             LogTrace("") << ">>> No beam spot found !!!";
00322             return false;
00323       }
00324   
00325       // MET
00326       double met_px = 0.;
00327       double met_py = 0.;
00328       Handle<View<MET> > metCollection;
00329       if (!ev.getByLabel(metTag_, metCollection)) {
00330             LogError("") << ">>> MET collection does not exist !!!";
00331             return false;
00332       }
00333       const MET& met = metCollection->at(0);
00334       met_px = met.px();
00335       met_py = met.py();
00336       if (!metIncludesMuons_) {
00337             for (unsigned int i=0; i<muonCollectionSize; i++) {
00338                   const Muon& mu = muonCollection->at(i);
00339                   if (!mu.isGlobalMuon()) continue;
00340                   met_px -= mu.px();
00341                   met_py -= mu.py();
00342             }
00343       }
00344       double met_et = sqrt(met_px*met_px+met_py*met_py);
00345       LogTrace("") << ">>> MET, MET_px, MET_py: " << met_et << ", " << met_px << ", " << met_py << " [GeV]";
00346       fill_histogram("MET_BEFORECUTS",met_et);
00347 
00348       // Trigger
00349       Handle<TriggerResults> triggerResults;
00350       if (!ev.getByLabel(trigTag_, triggerResults)) {
00351             LogError("") << ">>> TRIGGER collection does not exist !!!";
00352             return false;
00353       }
00354       const edm::TriggerNames & triggerNames = ev.triggerNames(*triggerResults);
00355     /* 
00356       for (unsigned int i=0; i<triggerResults->size(); i++) {
00357             if (triggerResults->accept(i)) {
00358                   LogTrace("") << "Accept by: " << i << ", Trigger: " << triggerNames.triggerName(i);
00359             }
00360       }
00361     */  
00362       bool trigger_fired = false;
00363       int itrig1 = triggerNames.triggerIndex(muonTrig_);
00364       if (triggerResults->accept(itrig1)) trigger_fired = true;
00365       LogTrace("") << ">>> Trigger bit: " << trigger_fired << " (" << muonTrig_ << ")";
00366       fill_histogram("TRIG_BEFORECUTS",trigger_fired);
00367 
00368       // Loop to reject/control Z->mumu is done separately
00369       unsigned int nmuonsForZ1 = 0;
00370       unsigned int nmuonsForZ2 = 0;
00371       for (unsigned int i=0; i<muonCollectionSize; i++) {
00372             const Muon& mu = muonCollection->at(i);
00373             if (!mu.isGlobalMuon()) continue;
00374             double pt = mu.pt();
00375             if (pt>ptThrForZ1_) nmuonsForZ1++;
00376             if (pt>ptThrForZ2_) nmuonsForZ2++;
00377       }
00378       LogTrace("") << "> Z rejection: muons above " << ptThrForZ1_ << " [GeV]: " << nmuonsForZ1;
00379       LogTrace("") << "> Z rejection: muons above " << ptThrForZ2_ << " [GeV]: " << nmuonsForZ2;
00380       fill_histogram("NZ1_BEFORECUTS",nmuonsForZ1);
00381       fill_histogram("NZ2_BEFORECUTS",nmuonsForZ2);
00382       
00383       // Jet collection
00384       Handle<View<Jet> > jetCollection;
00385       if (!ev.getByLabel(jetTag_, jetCollection)) {
00386             LogError("") << ">>> JET collection does not exist !!!";
00387             return false;
00388       }
00389       unsigned int jetCollectionSize = jetCollection->size();
00390       int njets = 0;
00391       for (unsigned int i=0; i<jetCollectionSize; i++) {
00392             const Jet& jet = jetCollection->at(i);
00393             if (jet.et()>eJetMin_) njets++;
00394       }
00395       LogTrace("") << ">>> Total number of jets: " << jetCollectionSize;
00396       LogTrace("") << ">>> Number of jets above " << eJetMin_ << " [GeV]: " << njets;
00397       fill_histogram("NJETS_BEFORECUTS",njets);
00398 
00399       // Start counting, reject already events if possible (under FastOption flag)
00400       nall++;
00401       if (fastOption_ && !trigger_fired) return false;
00402       if (fastOption_ && nmuonsForZ1>=1 && nmuonsForZ2>=2) return false;
00403       if (fastOption_ && njets>nJetMax_) return false;
00404 
00405       // Histograms per event shouldbe done only once, so keep track of them
00406       bool hlt_hist_done = false;
00407       bool met_hist_done = false;
00408       bool nz1_hist_done = false;
00409       bool nz2_hist_done = false;
00410       bool njets_hist_done = false;
00411 
00412       // Central W->mu nu selection criteria
00413       const int NFLAGS = 13;
00414       bool muon_sel[NFLAGS];
00415       for (unsigned int i=0; i<muonCollectionSize; i++) {
00416             for (int j=0; j<NFLAGS; ++j) {
00417                   muon_sel[j] = false;
00418             }
00419 
00420             const Muon& mu = muonCollection->at(i);
00421             if (!mu.isGlobalMuon()) continue;
00422             if (mu.globalTrack().isNull()) continue;
00423             if (mu.innerTrack().isNull()) continue;
00424 
00425             LogTrace("") << "> Wsel: processing muon number " << i << "...";
00426             reco::TrackRef gm = mu.globalTrack();
00427             //reco::TrackRef tk = mu.innerTrack();
00428 
00429             // Pt,eta cuts
00430             double pt = mu.pt();
00431             double eta = mu.eta();
00432             LogTrace("") << "\t... pt, eta: " << pt << " [GeV], " << eta;;
00433             if (pt>ptCut_) muon_sel[0] = true; 
00434             else if (fastOption_) continue;
00435             if (fabs(eta)<etaCut_) muon_sel[1] = true; 
00436             else if (fastOption_) continue;
00437 
00438             // d0, chi2, nhits quality cuts
00439             double dxy = gm->dxy(beamSpotHandle->position());
00440             double normalizedChi2 = gm->normalizedChi2();
00441             double validmuonhits=gm->hitPattern().numberOfValidMuonHits();
00442             //double standalonehits=mu.outerTrack()->numberOfValidHits();
00443             double trackerHits = gm->hitPattern().numberOfValidTrackerHits(); 
00444             LogTrace("") << "\t... dxy, normalizedChi2, trackerHits, isTrackerMuon?: " << dxy << " [cm], " << normalizedChi2 << ", " << trackerHits << ", " << mu.isTrackerMuon();
00445             if (fabs(dxy)<dxyCut_) muon_sel[2] = true; 
00446             else if (fastOption_) continue;
00447             if (muon::isGoodMuon(mu,muon::GlobalMuonPromptTight)) muon_sel[3] = true; 
00448             else if (fastOption_) continue;
00449             if (trackerHits>=trackerHitsCut_) muon_sel[4] = true; 
00450             else if (fastOption_) continue;
00451             if (mu.isTrackerMuon()) muon_sel[5] = true; 
00452             else if (fastOption_) continue;
00453 
00454             fill_histogram("PT_BEFORECUTS",pt);
00455             fill_histogram("ETA_BEFORECUTS",eta);
00456             fill_histogram("DXY_BEFORECUTS",dxy);
00457             fill_histogram("CHI2_BEFORECUTS",normalizedChi2);
00458             fill_histogram("NHITS_BEFORECUTS",trackerHits);
00459             fill_histogram("ValidMuonHits_BEFORECUTS",validmuonhits);
00460             fill_histogram("TKMU_BEFORECUTS",mu.isTrackerMuon());
00461 
00462             // Isolation cuts
00463             double isovar = mu.isolationR03().sumPt;
00464             if (isCombinedIso_) {
00465                   isovar += mu.isolationR03().emEt;
00466                   isovar += mu.isolationR03().hadEt;
00467             }
00468             if (isRelativeIso_) isovar /= pt;
00469             if (isovar<isoCut03_) muon_sel[6] = true; 
00470             else if (fastOption_) continue;
00471             LogTrace("") << "\t... isolation value" << isovar <<", isolated? " << muon_sel[6];
00472             fill_histogram("ISO_BEFORECUTS",isovar);
00473 
00474             // HLT (not mtched to muon for the time being)
00475             if (trigger_fired) muon_sel[7] = true; 
00476             else if (fastOption_) continue;
00477 
00478             // MET/MT cuts
00479             double w_et = met_et+ mu.pt();
00480             double w_px = met_px+ mu.px();
00481             double w_py = met_py+mu.py();
00482             double massT = w_et*w_et - w_px*w_px - w_py*w_py;
00483             massT = (massT>0) ? sqrt(massT) : 0;
00484 
00485             LogTrace("") << "\t... W mass, W_et, W_px, W_py: " << massT << ", " << w_et << ", " << w_px << ", " << w_py << " [GeV]";
00486             if (massT>mtMin_ && massT<mtMax_) muon_sel[8] = true; 
00487             else if (fastOption_) continue;
00488             fill_histogram("MT_BEFORECUTS",massT);
00489             if (met_et>metMin_ && met_et<metMax_) muon_sel[9] = true; 
00490             else if (fastOption_) continue;
00491 
00492             // Acoplanarity cuts
00493             Geom::Phi<double> deltaphi(mu.phi()-atan2(met_py,met_px));
00494             double acop = deltaphi.value();
00495             if (acop<0) acop = - acop;
00496             acop = M_PI - acop;
00497             LogTrace("") << "\t... acoplanarity: " << acop;
00498             if (acop<acopCut_) muon_sel[10] = true; 
00499             else if (fastOption_) continue;
00500             fill_histogram("ACOP_BEFORECUTS",acop);
00501 
00502             // Remaining flags (from global event information)
00503             if (nmuonsForZ1<1 || nmuonsForZ2<2) muon_sel[11] = true; 
00504             else if (fastOption_) continue;
00505             if (njets<=nJetMax_) muon_sel[12] = true; 
00506             else if (fastOption_) continue;
00507 
00508             if (fastOption_) {
00509                   all_sel = true;
00510                   break;
00511             } else {
00512               // Collect necessary flags "per muon"
00513               int flags_passed = 0;
00514               bool rec_sel_this = true;
00515               bool iso_sel_this = true;
00516               bool hlt_sel_this = true;
00517               bool met_sel_this = true;
00518               bool all_sel_this = true;
00519               for (int j=0; j<NFLAGS; ++j) {
00520                   if (muon_sel[j]) flags_passed += 1;
00521                   if (j<6 && !muon_sel[j]) rec_sel_this = false;
00522                   if (j<7 && !muon_sel[j]) iso_sel_this = false;
00523                   if (j<8 && !muon_sel[j]) hlt_sel_this = false;
00524                   if (j<11 && !muon_sel[j]) met_sel_this = false;
00525                   if (!muon_sel[j]) all_sel_this = false;
00526               }
00527 
00528               // "rec" => pt,eta and quality cuts are satisfied
00529               if (rec_sel_this) rec_sel = true;
00530               // "iso" => "rec" AND "muon is isolated"
00531               if (iso_sel_this) iso_sel = true;
00532               // "hlt" => "iso" AND "event is triggered"
00533               if (hlt_sel_this) hlt_sel = true;
00534               // "met" => "hlt" AND "MET/MT and acoplanarity cuts"
00535               if (met_sel_this) met_sel = true;
00536               // "all" => "met" AND "Z/top rejection cuts"
00537               if (all_sel_this) all_sel = true;
00538 
00539               // Do N-1 histograms now (and only once for global event quantities)
00540               if (flags_passed >= (NFLAGS-1)) {
00541                   if (!muon_sel[0] || flags_passed==NFLAGS) 
00542                         fill_histogram("PT_LASTCUT",pt);
00543                   if (!muon_sel[1] || flags_passed==NFLAGS) 
00544                         fill_histogram("ETA_LASTCUT",eta);
00545                   if (!muon_sel[2] || flags_passed==NFLAGS) 
00546                         fill_histogram("DXY_LASTCUT",dxy);
00547                   if (!muon_sel[3] || flags_passed==NFLAGS) 
00548                         fill_histogram("CHI2_LASTCUT",normalizedChi2);
00549                         fill_histogram("ValidMuonHits_LASTCUT",validmuonhits);
00550                   if (!muon_sel[4] || flags_passed==NFLAGS) 
00551                         fill_histogram("NHITS_LASTCUT",trackerHits);
00552                   if (!muon_sel[5] || flags_passed==NFLAGS) 
00553                         fill_histogram("TKMU_LASTCUT",mu.isTrackerMuon());
00554                   if (!muon_sel[6] || flags_passed==NFLAGS) 
00555                         fill_histogram("ISO_LASTCUT",isovar);
00556                   if (!muon_sel[7] || flags_passed==NFLAGS) 
00557                         if (!hlt_hist_done) fill_histogram("TRIG_LASTCUT",trigger_fired);
00558                         hlt_hist_done = true;
00559                   if (!muon_sel[8] || flags_passed==NFLAGS) 
00560                         fill_histogram("MT_LASTCUT",massT);
00561                   if (!muon_sel[9] || flags_passed==NFLAGS) 
00562                         if (!met_hist_done) fill_histogram("MET_LASTCUT",met_et);
00563                         met_hist_done = true;
00564                   if (!muon_sel[10] || flags_passed==NFLAGS) 
00565                         fill_histogram("ACOP_LASTCUT",acop);
00566                   if (!muon_sel[11] || flags_passed==NFLAGS) 
00567                         if (!nz1_hist_done) fill_histogram("NZ1_LASTCUT",nmuonsForZ1);
00568                         nz1_hist_done = true;
00569                   if (!muon_sel[11] || flags_passed==NFLAGS) 
00570                         if (!nz2_hist_done) fill_histogram("NZ2_LASTCUT",nmuonsForZ2);
00571                         nz2_hist_done = true;
00572                   if (!muon_sel[12] || flags_passed==NFLAGS) 
00573                         if (!njets_hist_done) fill_histogram("NJETS_LASTCUT",njets);
00574                         njets_hist_done = true;
00575               }
00576             }
00577 
00578       }
00579 
00580       // Collect final flags
00581       if (!fastOption_) {     
00582             if (rec_sel) nrec++;
00583             if (iso_sel) niso++;
00584             if (hlt_sel) nhlt++;
00585             if (met_sel) nmet++;
00586       }
00587 
00588       if (all_sel) {
00589             nsel++;
00590             LogTrace("") << ">>>> Event ACCEPTED";
00591       } else {
00592             LogTrace("") << ">>>> Event REJECTED";
00593       }
00594 
00595       return all_sel;
00596 
00597 }
00598 
00599 #include "FWCore/Framework/interface/MakerMacros.h"
00600 
00601       DEFINE_FWK_MODULE( WMuNuValidator );