Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

MuonSelector.cpp

Go to the documentation of this file.
00001 #include "caf_util/MuonSelector.hpp"
00002 #include "cafe/Config.hpp"
00003 
00004 #include <string>
00005 #include <sstream>
00006 #include <fstream>
00007 #include <stdexcept>
00008 
00009 using namespace std ;
00010 using namespace cafe ;
00011  
00012 namespace {
00013   bool moreThan(const TMBMuon& a, const TMBMuon& b) {
00014     return a.Pt() > b.Pt();    
00015   }
00016 }
00017 
00018 namespace caf_util {
00019 
00020   MuonSelector::MuonSelector(const char *name) : SelectUserObjects<TMBMuon>(name),
00021                                                  _nselected(0), _event(0),
00022                                                  _jetvars("fX", "fY", "fZ"),_runvar("_runno"),
00023                                                  _chunkvar("_nchunks"), _mc(false)
00024   {
00025     // get parameters from the configuration file
00026     cafe::Config config(name);
00027 
00028     //First have paramters not determined by MuonID definitions
00029     _nmuons = config.get("nMuons", 1);
00030     _nmuonsmax = config.get("nMuonsMax", -1);
00031       
00032     _pTcut = config.get("pT", 0.0);
00033     _eta = config.get("eta", 2.0) ;
00034 
00035     _MinDeltaR = config.get("MinDeltaR", -1.0);
00036     _MaxDeltaR = config.get("MaxDeltaR", -1.0);
00037     _etHalo = config.get("etHalo", -1.0) ;
00038     _etHaloMin = config.get("etHaloMin", -1.0) ;
00039     _etHaloScaled = config.get("etHaloScaled", -1.0) ;
00040     _etHaloScaledMin = config.get("etHaloScaledMin", -1.0) ;
00041     _etTrkCone = config.get("etTrkCone", -1.0) ;
00042     _etTrkConeMin = config.get("etTrkConeMin", -1.0) ;
00043     _etTrkConeScaled = config.get("etTrkConeScaled", -1.0) ;
00044     _etTrkConeScaledMin = config.get("etTrkConeScaledMin", -1.0) ;
00045     _excludeHole = config.get("excludeHole",false);
00046 
00047     _use_muid = config.get("UseMUID",0);
00048 
00049     if(!_use_muid) {
00050 
00051       err() << "WARNING: Standard muon ID not used - MUID group efficiencies not available for these cuts" << endl;
00052       _use_beam_spot = config.get("UseBeamSpot",false);
00053       
00054       _nseg = config.get("Nseg", 3) ;
00055       _useCentralMatched = config.get("UseCentralMatched", true) ;
00056       _chisq = config.get("chisq", 4.0) ;
00057       _cosmicVeto = config.get("cosmicVeto", false) ;
00058       _dcaSignif = config.get("dcaSignif", -1.0) ;
00059       _dcaSMT = config.get("dcaSMT",-1.0);
00060       _dcaNoSMT = config.get("dcaNoSMT",-1.0);
00061       _nSMT = config.get("nSMT",-1);
00062             
00063       string q = config.get("Quality", "medium") ;
00064       if ( q == "LOOSE" || q == "Loose" || q == "loose")
00065         _qual = Loose ;
00066       else if ( q == "TIGHT" || q == "Tight" || q == "tight")
00067         _qual = Tight ;
00068       else if( q == "MEDIUM" || q == "Medium" || q == "medium")
00069         _qual = Medium ;
00070       else {
00071         err() << "MUON SELECTOR WARNING! "
00072               << "Parameter Quality = \"" << q 
00073               << "\" is not recognized. "
00074               << "Must be loose, medium or tight. "
00075               << "Will use default quality MEDIUM."
00076               << endl ;
00077         _qual = Medium ;
00078       }
00079     }
00080     else { // Use standard ID definitions
00081       _path = config.get("Path", "caf_util/configs/");
00082 
00083       _muqual_file = config.get("MuonQualityFile","mucuts.txt");
00084       _muqual_name = config.get("MuonQualityName","MediumNseg3");
00085       _muqual_version = config.get("MuonQualityVersion",1);
00086       
00087       _trkqual_file = config.get("TrkQualityFile","mutrkcuts.txt");
00088       _trkqual_name = config.get("TrkQualityName","None");
00089       _trkqual_version = config.get("TrkQualityVersion",1);
00090     
00091       _isoqual_file = config.get("IsoQualityFile","muisocuts.txt");
00092       _isoqual_name = config.get("IsoQualityName","None");
00093       _isoqual_version = config.get("IsoQualityVersion",1);
00094     
00095       _cuts_set = SetStdCuts(_path, _muqual_file,_muqual_name,_muqual_version,_trkqual_file,_trkqual_name,_trkqual_version, _isoqual_file, _isoqual_name, _isoqual_version);
00096       if(_cuts_set) {
00097         DisplayMuonQualityCuts();
00098         DisplayMuonTrackQualityCuts();
00099         DisplayMuonIsolationQualityCuts();      
00100         out() << endl;
00101         out() << "Muon Cuts were set up successfully" << endl;
00102         out() << "
00103         out() << endl;
00104       } 
00105       else throw runtime_error("Error setting the std muon id cuts");
00106     } //std id
00107 
00108     out() << endl << "Muon cuts:" << endl;
00109     // Cut controlled by std ID only need printing if
00110     // std ID is turned off
00111     if(!_use_muid) {
00112       out() << "Muon quality = ";
00113       if(_qual==Loose) out() << "Loose" << endl;
00114       if(_qual==Medium) out() << "Medium" << endl;
00115       if(_qual==Tight) out() << "Tight" << endl;
00116       out() << "N Seg >= " << _nseg << endl;
00117       if(_useCentralMatched) out() << "Getting central matched muons" << endl;
00118       if(_chisq > 0) out() << "Muon Track Chi2 / NDof < " << _chisq << endl;
00119       if(_cosmicVeto) out() << "Vetoing cosmics" << endl;
00120       if(_dcaSignif > 0) out() << "DCA Significance < " << _dcaSignif << endl;
00121       if(_dcaSMT > 0) out() << "DCA for muon tracks with >0 SMT hits < " << _dcaSMT << endl;
00122       if(_dcaNoSMT > 0) out() << "DCA for muon tracks with 0 SMT hits < " << _dcaNoSMT << endl;;
00123       if(_nSMT > 0) out() << "nSMT hits >= " << _nSMT << endl;
00124       if(_etHalo > 0) out() << "Muon etHalo < " << _etHalo << endl;
00125       if(_etHaloMin > 0) out() << "Muon etHalo >= " << _etHaloMin << endl;
00126       if(_etHaloScaled > 0) out() << "Muon etHaloScaled < " << _etHaloScaled << endl;
00127       if(_etHaloScaledMin > 0) out() << "Muon etHaloScaled >= " << _etHaloScaledMin << endl;
00128       if(_etTrkCone > 0) out() << "Muon etTrkCone < " << _etTrkCone << endl;
00129       if(_etTrkConeMin > 0) out() << "Muon etTrkCone >= " << _etTrkConeMin << endl;
00130       if(_etTrkConeScaled > 0) out() << "Muon etTrkConeScaled < " << _etTrkConeScaled << endl;
00131       if(_etTrkConeScaledMin > 0) out() << "Muon etTrkConeScaled >= " << _etTrkConeScaledMin << endl;
00132       if(_MinDeltaR > 0 || _MaxDeltaR >0) {
00133         out() << "Removing muons near jets from branch " << _JetBranch.c_str();
00134         if(_MinDeltaR > 0) out() << ", dR > " << _MinDeltaR;
00135         if(_MaxDeltaR > 0) out() << ", dR < " << _MaxDeltaR;
00136         out() << endl;
00137       }
00138     }
00139     if(_pTcut > 0) out() << "Muon pT > " << _pTcut << endl;
00140     if(_eta > 0) out() << "Muon deteta < " << _eta << endl;
00141     if(_reject_no_beam_spot) out() << "Recjecting runs not in beam spot file" << endl;
00142     if(_corr_pT_SMT) out() << "Correcting pT of Muons with >0 SMT hits for beam spot posn." << endl;
00143     if(_corr_pT_noSMT) out() << "Correcting pT of Muons with 0 SMT hits for beam spot posn." << endl;
00144 
00145 
00146     out() << "Remove muons in the bottom hole: " ;
00147     if(_excludeHole) out() << "true" << endl ;
00148     else out() << "false" << endl ;
00149 
00150     //If needed setup beam spot file
00151     if(_use_beam_spot) {
00152       _beam = config.get("BeamSpotFile","caf_util/configs/beamSpot-2.09");
00153       _reject_no_beam_spot = config.get("RejectNoBeamSpot",0);
00154       char dataname[50];
00155       sprintf(dataname,"%s",_beam.c_str());
00156       if((_beamspot_file = fopen(dataname,"r")) == NULL) {
00157         cerr << "Can't open beam spot file: " << dataname << endl;
00158         cerr << "Beam spot posn set to 0." << endl;
00159         cerr << "Pt corrections will not be applied." << endl;
00160         _bx=_by=_bsx=_bsy=0; 
00161         _open_beam = false;
00162       }
00163       else {
00164         out() << "Opened beamspot file: " << dataname << endl;
00165         _open_beam = true;
00166         _bx=_by=_bsx=_bsy=0; //set to 0 in case using mc
00167       }
00168     }
00169     else _open_beam = false;
00170 
00171     // If using beam spot have option to correct track pT
00172     if(_open_beam && _use_beam_spot) {
00173       _corr_pT_SMT = config.get("CorrectPtSMT",0);
00174       _corr_pT_noSMT = config.get("CorrectPtNoSMT",1);
00175     }
00176     else {
00177       _corr_pT_SMT = false;
00178       _corr_pT_noSMT = false;
00179     }
00180         
00181     _sort = config.get("Sort", 0);
00182     _JetBranch = config.get("JetBranch", "");
00183 
00184     if( (_MinDeltaR > 0 || _MaxDeltaR > 0) &&
00185         _JetBranch == "" )      
00186       throw runtime_error("caf_util::MuonSelector: DeltaR cut requested, but no JetBranch specified");
00187     
00188     _finder.SetVariablesTrack(Variables("fUniqueID", "_chi2_ndof", "_rdca", "_trerrs")) ;
00189     _finder.addTrackVariable("_z");
00190     _finder.addTrackVariable("_q");
00191     _finder.addTrackVariable("fX");
00192     _finder.addTrackVariable("fY"); 
00193     _finder.addTrackVariable("fZ");
00194     _finder.addTrackVariable("_hitmask");
00195 
00196     _finder.SetVariablesVertex(Variables("fUniqueID","_VertexX","_VertexY","_VertexZ"));
00197     _finder.addVertexVariable("_CovXX");
00198     _finder.addVertexVariable("_CovYY");
00199     _finder.addVertexVariable("_CovZZ");
00200     
00201     _debuglevel = config.get("DebugLevel",0);
00202   };
00203   
00204   bool MuonSelector::processEvent(cafe::Event &event)
00205   {
00206         
00207     //get pointer to statistics collector
00208     event.get("StatPointer", _stat) ;
00209     _event = &event ;
00210     //
00211     // get the jet branch if the DeltaR cut is wanted
00212     //
00213     if (_JetBranch != "" && (_MinDeltaR > 0 || _MaxDeltaR > 0 )) {
00214       _jets = event.getJets(_JetBranch.c_str(),_jetvars);
00215     }
00216     //
00217     // Get Beam Spot if needed
00218     //
00219     if(_use_beam_spot && _open_beam && !_mc) {
00220       int n_mc_chunks = (event.getMCEventInfo(_chunkvar))->nchunks();
00221       // If event is MC don't use beam spot file
00222       if(n_mc_chunks>0) {
00223         out() << "Sample is MC - beam spot file ignored" << endl;
00224         _mc=true;
00225       }
00226       else _mc=false;
00227       if(_use_beam_spot && !_mc) {
00228         int run = (event.getGlobal(_runvar))->runno();
00229         if(run!=_lastrun) { //if same run don't need to load new beamspot
00230           bool use=false;
00231           use = GetBeamSpot(_beamspot_file, run, _bx, _by, _bsx, _bsy);
00232           if(use) _lastrun=run;
00233           //reject event if no beam spot found for that run
00234           if(!use && _reject_no_beam_spot) return false;
00235         }
00236       }
00237       //put beam spot info into event for later processors
00238       event.put("Bx",_bx);
00239       event.put("By",_by);
00240       event.put("Bsx",_bsx);
00241       event.put("Bsy",_bsy);
00242     }
00243     //
00244     // apply selections to the muons
00245     //
00246     // initialize
00247     //
00248     _nselected = 0 ;
00249     SelectUserObjects<TMBMuon>::processEvent(event) ;
00250 
00251     for (int i = 1; i <= _nmuons; i++) {
00252       if (_nselected < i) return false ; 
00253       ostringstream st ;
00254       st << "Number of muons >= " << i ;
00255       _stat.EventSelected(st.str()) ;
00256     }
00257 
00258     if (_nmuonsmax >= 0) {
00259       if (_nselected > _nmuonsmax) return false ; 
00260       ostringstream st ;
00261       st << "Number of muons <= " << _nmuonsmax ;
00262       _stat.EventSelected(st.str()) ;      
00263     }
00264 
00265     return true  ;      
00266   };
00267   
00268   bool MuonSelector::selectObject(const TMBMuon &muon)
00269   {     
00270 
00271     if (_excludeHole) {
00272       if (muon.isInHole()) return false;
00273        {
00274         ostringstream st ;
00275         if (_nmuons>0) _stat.EventSelected("Muon out of bottom hole") ;
00276        }
00277 
00278     }
00279 
00280     if(_eta > 0) {
00281       if (fabs(muon.detectorEta()) >= _eta) return false ;
00282       {
00283         ostringstream st ;
00284         st << "Muon detector eta < " << (float) _eta ;
00285         if (_nmuons>0) _stat.EventSelected(st.str()) ;
00286       }
00287     }
00288 
00289     string qual ;
00290     switch (_qual) {
00291     case Loose : {
00292       if (!muon.isLoose()) return false ;
00293       qual = "loose" ;
00294     } ; break ;
00295     case Medium : {
00296       if (!muon.isMedium()) return false ;
00297       qual = "medium" ;
00298     } ; break ;
00299     case Tight : {
00300       if (!muon.isTight()) return false ;
00301       qual = "tight" ;
00302     } ; break ;
00303     default : return false ; break ;
00304     }
00305     if (_nmuons>0) _stat.EventSelected("Muon quality is " + qual) ;
00306 
00307     if (abs(muon.nseg()) < abs(_nseg)) return false ;
00308     { 
00309       ostringstream st ;
00310       st << "Number of layers >= " << _nseg ;
00311       if (_nmuons>0) _stat.EventSelected(st.str()) ;
00312     }
00313 
00314     if (_cosmicVeto) {
00315       if (muon.isCosmic()) return false ;
00316       if (_nmuons>0)_stat.EventSelected("Veto on cosmic muon") ;
00317     }
00318 
00319     if (_useCentralMatched) {
00320       if (!muon.hasCentral()) return false ;
00321       if (_nmuons>0)_stat.EventSelected("Matched with central track") ;
00322     }
00323 
00324     const TMBTrack* trk = 0 ;
00325     if (muon.hasCentral() && (_chisq > 0. || _dcaSignif > 0. || _dcaSMT >0. || _dcaNoSMT > 0. || _nSMT >= 0 || _corr_pT_SMT || _corr_pT_noSMT)) {
00326       trk =_finder.FindTrack(*_event, muon.GetChargedTrackRef()) ;
00327     
00328       if (!trk) {
00329         err() << "MUON SELECTOR ERROR!"
00330               << " Track pointer from the track matched muon is 0!"
00331               << endl ;
00332         return false ;
00333       }
00334     }
00335     
00336     if (muon.hasCentral() && _nSMT > 0) {
00337       if(trk->nsmt() < _nSMT) return false;
00338       ostringstream st ;
00339       st << "N SMT hits on Muon Track >= " << _nSMT;
00340       if (_nmuons>0)  _stat.EventSelected(st.str()) ;      
00341     }
00342 
00343     if (muon.hasCentral() && _chisq > 0 ) {
00344         if (trk->getChi2Ndf() >= _chisq) return false ;
00345         ostringstream st ;
00346         st << "Muon global fit chi square <  " << (float) _chisq ;
00347         if (_nmuons>0)  _stat.EventSelected(st.str()) ;      
00348     }
00349     
00350     double dca = 0;
00351     if (muon.hasCentral() && (_dcaSignif > 0. || _dcaSMT > 0. || _dcaNoSMT > 0. || _corr_pT_SMT || _corr_pT_noSMT) )  {      
00352       
00353       if(!_use_beam_spot) {
00354         const TMBVertex* vtx = _finder.FindVertex(*_event,
00355                                           muon.GetVertexRef());
00356         
00357         if (!vtx) {
00358           err() << "MUON SELECTOR ERROR!"
00359                 << " Vertex pointer from the track matched muon is 0!"
00360                 << endl ;
00361           if(debug()>0) {
00362             Collection<TMBPrimaryVertex> all_vtxs = (*_event).getPrimaryVertices(_jetvars);
00363             int n_vtx = all_vtxs.size();
00364             err() << "Event has " << n_vtx << " vertices." << endl;
00365           }
00366           return false ;
00367         }
00368         
00369         double ip[2];
00370         double iperr[3];
00371         trk->impact(vtx,ip,iperr);
00372         
00373         if(_dcaSignif >= 0.) {
00374           if (fabs(ip[0])/sqrt(iperr[0]) >= _dcaSignif)
00375             return false ;
00376           ostringstream st ;
00377           st << "DCA significance < " << (float) _dcaSignif ;
00378           if (_nmuons>0) _stat.EventSelected(st.str()) ;
00379         }
00380         dca = ip[0];
00381         if(_dcaSMT >= 0. || _dcaNoSMT >= 0.) {
00382           if(trk->nsmt() > 0 && fabs(dca) >= _dcaSMT && _dcaSMT > 0.) return false;
00383           if (trk->nsmt() == 0 && fabs(dca) >= _dcaNoSMT && _dcaNoSMT > 0.) return false;
00384           ostringstream st ;
00385           if(_dcaNoSMT > 0. && _dcaSMT > 0. )
00386             st << "DCA  < " << (float) _dcaSMT << " for nSMT > 0 and DCA < " << (float) _dcaNoSMT << " for nSMT = 0";
00387           else {
00388             if(_dcaSMT > 0.) st << "DCA  < " << (float) _dcaSMT << " for nSMT > 0";
00389             if(_dcaNoSMT > 0.) st << "DCA  < " << (float) _dcaNoSMT << " for nSMT = 0";
00390           }     
00391           if (_nmuons>0) _stat.EventSelected(st.str());
00392         }
00393       } // !_use_beam_spot
00394       else {
00395         dca = DCAfromBeamSpot(trk);
00396         if(_dcaSignif >0. ) throw runtime_error("DCA Significance cut not cuttently supported for beam spot DCA");
00397         if(_dcaSMT > 0. || _dcaNoSMT > 0.) {
00398           if(trk->nsmt() > 0 && fabs(dca) >= _dcaSMT && _dcaSMT > 0.) return false;
00399           if (trk->nsmt() == 0 && fabs(dca) >= _dcaNoSMT && _dcaNoSMT > 0.) return false;
00400           ostringstream st ;
00401           if(_dcaNoSMT > 0. && _dcaSMT > 0. )
00402             st << "DCA  < " << (float) _dcaSMT << " for nSMT > 0 and DCA < " << (float) _dcaNoSMT << " for nSMT = 0";
00403           else {
00404             if(_dcaSMT > 0.) st << "DCA  < " << (float) _dcaSMT << " for nSMT > 0";
00405             if(_dcaNoSMT > 0.) st << "DCA  < " << (float) _dcaNoSMT << " for nSMT = 0";
00406           }     
00407           if (_nmuons>0) _stat.EventSelected(st.str());
00408         }
00409       } 
00410 
00411     } //If dca cut
00412   
00413     //Since pT correction done in before
00414     //Can now just cut on muon.Pt()
00415     if (muon.Pt() < _pTcut) return false ;
00416     
00417     {
00418       ostringstream st ;
00419       if(_corr_pT_noSMT || _corr_pT_SMT) st << "Corrected ";
00420       st << "Muon pT >= " << _pTcut << " GeV" ;
00421       if (_nmuons>0) _stat.EventSelected(st.str()) ;
00422     }
00423 
00424     if (_etHalo > 0) {
00425       if (muon.etHalo() >= _etHalo) return false ; 
00426       ostringstream st ;
00427       st << "Calorimeter isolation < " << _etHalo << " GeV" ;
00428       if (_nmuons>0) _stat.EventSelected(st.str()) ;     
00429     }
00430     if (_etHaloMin > 0) {
00431       if (muon.etHalo() < _etHaloMin) return false ; 
00432       ostringstream st ;
00433       st << "Calorimeter isolation > " << _etHaloMin << " GeV" ;
00434       if (_nmuons>0) _stat.EventSelected(st.str()) ;     
00435     }
00436 
00437     if (_etHaloScaled > 0) {
00438       if (muon.etHalo() / muon.Pt() >= _etHaloScaled) return false ;
00439       ostringstream st ;
00440       st << "Calorimeter scaled isolation < " << (float) _etHaloScaled  ;
00441       if (_nmuons>0)_stat.EventSelected(st.str()) ;     
00442     }
00443 
00444     if (_etHaloScaledMin > 0) {
00445       if (muon.etHalo() / muon.Pt() < _etHaloScaledMin) return false ;
00446       ostringstream st ;
00447       st << "Calorimeter scaled isolation >= " << (float) _etHaloScaledMin  ;
00448       if (_nmuons>0)_stat.EventSelected(st.str()) ;     
00449     }
00450 
00451     if (_etTrkCone > 0) {
00452       if (muon.etTrkCone5() >= _etTrkCone) return false ;
00453       ostringstream st ;
00454       st << "Track isolation < " << _etTrkCone << " GeV" ;
00455       if (_nmuons>0)_stat.EventSelected(st.str()) ;     
00456     }
00457     if (_etTrkConeMin > 0) {
00458       if (muon.etTrkCone5() < _etTrkConeMin) return false ;
00459       ostringstream st ;
00460       st << "Track isolation > " << _etTrkConeMin << " GeV" ;
00461       if (_nmuons>0)_stat.EventSelected(st.str()) ;     
00462     }
00463 
00464     if (_etTrkConeScaled > 0) {
00465       if (muon.etTrkCone5() / muon.Pt() >= _etTrkConeScaled) return false ;
00466       ostringstream st ;
00467       st << "Track scaled isolation < " << (float) _etTrkConeScaled  ;
00468       if (_nmuons>0)_stat.EventSelected(st.str()) ;     
00469     }
00470 
00471     if (_etTrkConeScaledMin > 0) {
00472       if (muon.etTrkCone5() / muon.Pt() < _etTrkConeScaledMin) return false ;
00473       ostringstream st ;
00474       st << "Track scaled isolation >= " << (float) _etTrkConeScaledMin  ;
00475       if (_nmuons>0)_stat.EventSelected(st.str()) ;     
00476     }
00477 
00478     //
00479     // apply the DeltaR cut
00480     //
00481 
00482     if (_jets.size() > 0){ 
00483       double deltaR;
00484       double deltaR_nearestJet = 100.0;
00485       for (unsigned int i=0; i < _jets.size(); i++) {
00486         deltaR = kinem::delta_R(_jets[i].Eta(), _jets[i].Phi(), muon.Eta(), muon.Phi());
00487         if (deltaR < deltaR_nearestJet) 
00488           deltaR_nearestJet = deltaR;
00489       } // Loop over jets
00490       // Check if user wants to apply cut on DeltaR
00491       if (_MinDeltaR > 0){
00492         if (deltaR_nearestJet <= _MinDeltaR)
00493           return false;
00494         ostringstream st ;
00495         st << "DeltaR(mu, jet) > " << (float) _MinDeltaR ;
00496         if (_nmuons>0)_stat.EventSelected(st.str()) ;  
00497       } // if (_MinDeltaR > 0)
00498       if (_MaxDeltaR > 0){
00499         if (deltaR_nearestJet > _MaxDeltaR)
00500           return false;
00501         ostringstream st ;
00502         st << "DeltaR(mu, jet) <= " << (float) _MaxDeltaR ;
00503         if (_nmuons>0)_stat.EventSelected(st.str()) ;  
00504       } // if (_MaxDeltaR > 0)
00505     } // if (_jets.size() > 0)
00506 
00507     _nselected++ ;
00508 
00509     if (debug()>1) 
00510       out() << "PROCESSOR \"" << name() 
00511            << "\" SELECTED OBJECT: pT = " << muon.Pt() 
00512            << " eta = " << muon.Eta() 
00513            << " phi = " << muon.Phi() 
00514            << endl ;
00515     return true ;
00516 
00517   };
00518   
00519   void MuonSelector::before(cafe::Collection<TMBMuon>& from) {
00520     
00521     //Correct Muon pT for DCA wrt beam spot if required
00522     if(_corr_pT_SMT || _corr_pT_noSMT) {
00523       for(Collection<TMBMuon>::iterator it_muon = from.begin(); it_muon != from.end(); ++it_muon) {
00524         
00525         //only correct muons with central tracks
00526         if(it_muon->hasCentral()) {
00527           const TMBTrack* trk = it_muon->GetChargedTrack();
00528           if(trk) {
00529             int smt = trk->nsmt();
00530             if(_corr_pT_SMT && smt>0) {
00531               double dca = DCAfromBeamSpot(trk);
00532               if(_debuglevel>1) out() << "Muon pT before correction = " << it_muon->Pt() << endl;
00533               it_muon->CorrectPt(dca);
00534               if(_debuglevel>1) out() << "Muon pT after correction = " << it_muon->Pt() << endl;
00535               if(_debuglevel>1) out() << "Correcting track with SMT hits" << endl;
00536             }
00537             else if(_debuglevel>1 && smt>0) out() << "Not Correcting track since nSMT > 0 & _corr_pT_SMT is false" << endl;
00538             if(_corr_pT_noSMT && smt==0) {
00539               double dca = DCAfromBeamSpot(trk);
00540               if(_debuglevel>1) out() << "Muon pT before correction = " << it_muon->Pt() << endl;
00541               it_muon->CorrectPt(dca);
00542               if(_debuglevel>1) out() << "Correcting track with no SMT hits" << endl;
00543               if(_debuglevel>1) out() << "Muon pT after correction = " << it_muon->Pt() << endl;
00544             }
00545           } //if(trk)
00546           else cerr << "A muon with hasCentral() == 1, has no track, it will not be corrected" << endl;
00547         }
00548       }
00549     }
00550     
00551     
00552     if(_sort) {
00553       from.sort(from.begin(),from.end(),::moreThan) ;
00554     }
00555   }
00556 
00557   bool MuonSelector::SetStdCuts(std::string path, std::string mu_file_name, std::string mu_name, int mu_ver, std::string trk_file_name, std::string trk_name, int trk_ver, std::string iso_file_name, std::string iso_name, int iso_ver) {
00558     
00559     out() << endl;
00560     out() << "
00561     out() << "//  Initializing Common Muon ID       //" << endl;
00562     out() << "
00563 
00564     ifstream mu_file;
00565     ifstream trk_file;
00566     ifstream iso_file;
00567     
00568     string mu_path_file = path + mu_file_name;
00569     mu_file.open(mu_path_file.c_str());
00570 
00571     string trk_path_file = path + trk_file_name;
00572     trk_file.open(trk_path_file.c_str());
00573 
00574     string iso_path_file = path + iso_file_name;
00575     iso_file.open(iso_path_file.c_str());
00576 
00577     if(!mu_file) {
00578       cerr << "In Muon Selector - cannot find the muon quality file " << mu_file_name.c_str() << endl;
00579       return false;
00580     }
00581     if(!trk_file) {
00582       cerr << "In Muon Selector - cannot find the muon trk quality file " << trk_file_name.c_str() << endl;
00583       return false;
00584     }
00585     if(!iso_file) {
00586       cerr << "In Muon Selector - cannot find the muon iso quality file " << iso_file_name.c_str() << endl;
00587       return false;
00588     }
00589 
00590     //MuID uses beam spot for DCA correction
00591     _use_beam_spot = true;
00592 
00593     string token = "";
00594     string qual = "";
00595     int ver;
00596 
00597     while(!mu_file.eof()) {
00598       mu_file >> token;
00599 
00600       if(token=="Version:") {
00601         
00602         mu_file >> ver;
00603                 
00604         mu_file >> token;
00605         if(token!="Name:") cerr << "ERROR in setting muon cuts: name did not follow version in muon quality file" <<  endl;
00606         else {
00607           mu_file >> qual;
00608           if((ver==mu_ver)&&(qual==mu_name)) {
00609             //out() << "Using:" << endl;
00610             out() << "Muon ID Name: " << qual << endl;
00611             out() << "Version: " << ver << endl;
00612             break;
00613           }
00614         }
00615       }
00616     } //mu_file.eof()
00617 
00618     if((ver!=mu_ver)||(qual!=mu_name)) {
00619       cerr << "Error no muon quality criteria found for " << mu_name << " and version " << mu_ver << endl;
00620       return false;
00621     }
00622     mu_file >> token;
00623     if(token=="END") {
00624       cerr << "No muon criteria in the muon quality file" << endl;
00625       return false;
00626     }
00627     while((token!="END")&&(!mu_file.eof())) {
00628       if(token=="MuonQuality:") {
00629         string q;
00630         mu_file >> q;
00631         if ( q == "LOOSE" || q == "Loose" || q == "loose")
00632           _qual = Loose ;
00633         else if ( q == "TIGHT" || q == "Tight" || q == "tight")
00634           _qual = Tight ;
00635         else if( q == "MEDIUM" || q == "Medium" || q == "medium")
00636           _qual = Medium ;
00637         else {
00638           err() << "MUON SELECTOR WARNING! "
00639                 << "Parameter Quality = \"" << q 
00640                 << "\" is not recognized. "
00641                 << "Must be loose, medium or tight. "
00642                 << "Will use default quality MEDIUM."
00643                 << endl ;
00644           _qual = Medium ;
00645         }
00646       }//"Muon Quality"
00647       else {
00648         cerr << "Muon Quality not found" << endl;
00649         cerr << "ID file: " << mu_path_file << endl;
00650         return false;
00651       }
00652       mu_file >> token;
00653       if(token=="Nseg:") mu_file >> _nseg;
00654       else {
00655         cerr << "Nseg not found" << endl;
00656         cerr << "ID file: " << mu_path_file << endl;
00657         return false;
00658       }
00659       _useCentralMatched = true; //always want track matched muon
00660       mu_file >> token;
00661       if(token=="Cosmic:") mu_file >> _cosmicVeto;
00662       else {
00663         cerr << "Cosmic not found" << endl;
00664         cerr << "ID file: " << mu_path_file << endl;
00665         return false;
00666       }
00667       mu_file >> token;
00668     }
00669 
00670     mu_file.close();
00671 
00672     token = "";
00673     qual = "";
00674     ver = -1;
00675     
00676     while(!trk_file.eof()) {
00677       trk_file >> token;
00678 
00679       if(token=="Version:") {
00680         
00681         trk_file >> ver;
00682                 
00683         trk_file >> token;
00684         if(token!="Name:") cerr << "ERROR in setting muon trk cuts: name did not follow version in muon trk quality file" <<  endl;
00685         else {
00686           trk_file >> qual;
00687           if((ver==trk_ver)&&(qual==trk_name)) {
00688             //out() << "Using:" << endl;
00689             out() << "Muon Track ID Name: " << qual << endl;
00690             out() << "Version: " << ver << endl;
00691             break;
00692           }
00693         }
00694       }
00695     } //trk_file.eof()
00696 
00697     if((ver!=trk_ver)||(qual!=trk_name)) {
00698       cerr << "Error no muon track criteria found for " << trk_name << " and version " << mu_ver << endl;
00699       return false;
00700     }
00701 
00702     trk_file >> token;
00703     while( (!trk_file.eof()) && (token!="END") ) {
00704       if(token=="ChiSq:") trk_file >> _chisq;
00705       else {
00706         cerr << "ChiSq not found in Muon track file" << endl;
00707         cerr << "Track file: " << trk_path_file << endl;
00708         return false;
00709       }
00710       trk_file >> token;
00711       if(token=="DCASMT:") trk_file >> _dcaSMT;
00712       else {
00713         cerr << "DCASMT not found in Muon Track File" << endl;
00714         cerr << "Track file: " << trk_path_file << endl;
00715         return false;
00716       }
00717       trk_file >> token;
00718       if(token=="DCANoSMT:") trk_file >> _dcaNoSMT;
00719       else {
00720         cerr << "DCANoSMT not found in Muon Track File" << endl;
00721         cerr << "Track file: " << trk_path_file << endl;
00722         return false;
00723       }
00724       trk_file >> token;
00725       if(token=="nSMT:") trk_file >> _nSMT;
00726       else {
00727         cerr << "nSMT not found in Muon Track File" << endl;
00728         cerr << "Track file: " << trk_path_file << endl;
00729         return false;
00730       }
00731       trk_file >> token;
00732     }
00733 
00734     trk_file.close();
00735 
00736     //------------------------------------------------------
00737     // Isolation Values
00738     //------------------------------------------------------
00739     token = "";
00740     qual = "";
00741     ver = -1;
00742     
00743     while(!iso_file.eof()) {
00744       iso_file >> token;
00745 
00746       if(token=="Version:") {
00747         
00748         iso_file >> ver;
00749                 
00750         iso_file >> token;
00751         if(token!="Name:") cerr << "ERROR in setting muon iso cuts: name did not follow version in muon iso quality file" <<  endl;
00752         else {
00753           iso_file >> qual;
00754           if((ver==iso_ver)&&(qual==iso_name)) {
00755             //out() << "Using:" << endl;
00756             out() << "Muon Isolation ID Name: " << qual << endl;
00757             out() << "Version: " << ver << endl;
00758             break;
00759           }
00760         }
00761       }
00762     } //iso_file.eof()
00763 
00764     if((ver!=iso_ver)||(qual!=iso_name)) {
00765       cerr << "Error no muon isolation criteria found for " << iso_name << " and version " << mu_ver << endl;
00766       return false;
00767     }
00768 
00769     iso_file >> token;
00770     while( (!iso_file.eof()) && (token!="END") ) {
00771 
00772       if(token=="etHalo:") iso_file >> _etHalo;
00773       else {
00774         cerr << "etHalo not found Muon Isolation file" << endl;
00775         cerr << "Isolation file: " << iso_path_file << endl;
00776         return false;
00777       }
00778       iso_file >> token;
00779 
00780       if(token=="etHaloMin:") iso_file >> _etHaloMin;
00781       else {
00782         cerr << "etHaloMin not found Muon Isolation file" << endl;
00783         cerr << "Isolation file: " << iso_path_file << endl;
00784         return false;
00785       }
00786       iso_file >> token;
00787 
00788       if(token=="etTrkCone:") iso_file >> _etTrkCone;
00789       else {
00790         cerr << "etTrkCone not found Muon Isolation file" << endl;
00791         cerr << "Isolation file: " << iso_path_file << endl;
00792         return false;
00793       }
00794       iso_file >> token;
00795 
00796       if(token=="etTrkConeMin:") iso_file >> _etTrkConeMin;
00797       else {
00798         cerr << "etTrkConeMin not found Muon Isolation file" << endl;
00799         cerr << "Isolation file: " << iso_path_file << endl;
00800         return false;
00801       }
00802       iso_file >> token;
00803 
00804       if(token=="etHaloScaled:") iso_file >> _etHaloScaled;
00805       else {
00806         cerr << "etHaloScaled not found Muon Isolation file" << endl;
00807         cerr << "Isolation file: " << iso_path_file << endl;
00808         return false;
00809       }
00810       iso_file >> token;
00811 
00812       if(token=="etHaloScaledMin:") iso_file >> _etHaloScaledMin;
00813       else {
00814         cerr << "etHaloScaledMin not found Muon Isolation file" << endl;
00815         cerr << "Isolation file: " << iso_path_file << endl;
00816         return false;
00817       }
00818       iso_file >> token;
00819 
00820       if(token=="etTrkConeScaled:") iso_file >> _etTrkConeScaled;
00821       else {
00822         cerr << "etTrkConeScaled not found Muon Isolation file" << endl;
00823         cerr << "Isolation file: " << iso_path_file << endl;
00824         return false;
00825       }
00826       iso_file >> token;
00827 
00828       if(token=="etTrkConeScaledMin:") iso_file >> _etTrkConeScaledMin;
00829       else {
00830         cerr << "etTrkConeScaledMin not found Muon Isolation file" << endl;
00831         cerr << "Isolation file: " << iso_path_file << endl;
00832         return false;
00833       }
00834       iso_file >> token;
00835 
00836       if(token=="MinDeltaR:") iso_file >> _MinDeltaR;
00837       else {
00838         cerr << "MinDeltaR not found Muon Isolation file" << endl;
00839         cerr << "Isolation file: " << iso_path_file << endl;
00840         return false;
00841       }
00842       iso_file >> token;
00843 
00844       if(token=="MaxDeltaR:") iso_file >> _MaxDeltaR;
00845       else {
00846         cerr << "MaxDeltaR not found Muon Isolation file" << endl;
00847         cerr << "Isolation file: " << iso_path_file << endl;
00848         return false;
00849       }
00850       iso_file >> token;
00851     }
00852 
00853     iso_file.close();
00854 
00855     //Set all cuts that aren't used by muid to -1
00856     _dcaSignif = -1.0; //cut not supported by muo_cert currently
00857     
00858     return true;
00859   }//_SetStdCuts
00860 
00861   void MuonSelector::DisplayMuonQualityCuts() {
00862     out() << endl;
00863     out() << "Muon Defintion corresponds to cuts:" << endl;
00864     string quality = "";
00865     if(_qual==Tight) quality = "Tight";
00866     if(_qual==Medium) quality = "Medium";
00867     if(_qual==Loose) quality = "Loose";
00868     out() << "\tMuon Quality: " << quality << endl;
00869     out() << "\tNseg >= " << _nseg << endl;
00870     out() << "\tHasCentral: " << _useCentralMatched << endl;
00871     out() << "\tCosmicVeto: " << _cosmicVeto << endl;
00872   }
00873 
00874   void MuonSelector::DisplayMuonTrackQualityCuts() {
00875     out() << endl;
00876     out() << "Muon Track Definition corresponds to cuts:" << endl;
00877     if(_chisq>0) out() << "\tChiSq < " << _chisq << endl;
00878     else out() << "\tNo ChiSq cut" << endl;
00879     if(_dcaSMT>0) out() << "\tDCA < " << _dcaSMT << " for nSMT > 0" << endl;
00880     else out() << "\tNo DCA cut for SMT > 0" << endl;
00881     if(_dcaNoSMT>0) out() << "\tDCA < " << _dcaNoSMT << " for nSMT = 0" << endl;
00882     else out() << "\tNo DCA cut for SMT = 0" << endl;
00883     if(_nSMT>0) out() << "\tN SMT hits >= " << _nSMT << endl;
00884     else out() << "\tNo SMT hit cut" << endl;
00885   }
00886 
00887   void MuonSelector::DisplayMuonIsolationQualityCuts() {
00888     out() << endl;
00889     out() << "Muon Isolation Definition corresponds to cuts:" << endl;
00890     if(_etHaloScaled>0) out() << "\tCalorimeter Isolation < " << _etHaloScaled << endl;
00891     else out() << "\tNo calorimeter isolation cut" << endl;
00892     if(_etHaloScaledMin>0) out() << "\tCalorimeter Isolation > " << _etHaloScaled << endl;
00893     else out() << "\tNo calorimeter isolation min cut" << endl;
00894     if(_etTrkConeScaled>0) out() << "\tTrack Isolation < " << _etTrkConeScaled << endl;
00895     else out() << "\tNo track isolation cut" << endl;
00896     if(_etTrkConeScaledMin>0) out() << "\tTrack Isolation > " << _etTrkConeScaled << endl;
00897     else out() << "\tNo track isolation min cut" << endl;
00898     if(_MinDeltaR>0) out() << "\tDeltaR >= " << _MinDeltaR << endl;
00899     else out() << "\tNo DeltaR min cut" << endl;
00900     if(_MaxDeltaR>0) out() << "\tDeltaR < " << _MaxDeltaR << endl;
00901     else out() << "\tNo DeltaR max cut" << endl;
00902   }
00903 
00904   bool MuonSelector::GetBeamSpot(FILE *fp, int run, float &bx, float &by,  float &bsx, float &bsy) {
00905     rewind(fp);
00906     int cont=1, rn, en, pass=0;
00907     float xe, ye, xye;
00908     while(cont) {
00909       bx=by=bsx=bsy=0; 
00910       fscanf(fp,"%i %i %f %f %f %f %f %f %f",&rn,&en,&bx,&by,&xe,&ye,&xye, &bsx, &bsy);
00911       if(rn==run) {
00912         cont=0;
00913         pass=1;
00914       }
00915       if(rn==0) cont=0;
00916     }
00917     if(!pass){
00918       bx = by = 0;
00919       bsx = bsy = 0; 
00920       
00921       std::cerr<<"Could not find run: "<<run<< " in beam spot file" << std::endl;
00922       return false;
00923       
00924     }//run not found;
00925     
00926     return true;
00927     
00928   }
00929 
00930   double MuonSelector::DCAfromBeamSpot(const TMBTrack* muon_trk) {
00931     double z0 = muon_trk->z();
00932     double phi = muon_trk->phid();
00933     double beam_x = _bx + z0*_bsx;
00934     double beam_y = _by + z0*_bsy;
00935     double dca = muon_trk->rdca() - beam_x*sin(phi) + beam_y*cos(phi);
00936     if(_debuglevel>1) out() << "DCA = " << dca << endl;
00937     return dca;
00938   }
00939 
00940   double MuonSelector::GetCorrectedPt(const TMBMuon& muon, double dca) {
00941     if(!muon.hasCentral()) {
00942       if(_debuglevel>0) cerr << "Cannot correct muon pT if muon is not central" << endl;
00943       return muon.Pt();
00944     }
00945     const TMBTrack* trk = muon.GetChargedTrack();
00946     if(trk) {
00947       double err_rqpt = trk->trerrs(4, 0);
00948       double err_rr = trk->trerrs(0, 0);
00949       float qopt = trk->qpt();
00950       qopt -= dca * err_rqpt / err_rr;
00951       double pTcorr = 1 / qopt;
00952       int q = 1;
00953       if(pTcorr < 0) {
00954         pTcorr *= -1;
00955         q = -1;
00956       }
00957       return pTcorr;
00958     }
00959     else cerr << "Cannot get corrected pT for muon with no matched track" << endl;
00960     
00961     return muon.Pt();
00962   }
00963 
00964   
00965       
00966   void MuonSelector::after(cafe::Collection<TMBMuon>& acc, cafe::Collection<TMBMuon>& rej) {
00967     
00968   }
00969 
00970 
00971 }
00972 ClassImp(caf_util::MuonSelector) ;
00973   

Generated on Tue Mar 28 10:13:04 2006 for CAF by doxygen 1.3.4