CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoMET/METProducers/src/MuonMETValueMapProducer.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    MuonMETValueMapProducer
00004 // Class:      MuonMETValueMapProducer
00005 // 
00013 //
00014 // Original Author:  Puneeth Kalavase
00015 //         Created:  Sun Mar 15 11:33:20 CDT 2009
00016 // $Id: MuonMETValueMapProducer.cc,v 1.2 2010/10/03 11:25:26 elmer Exp $
00017 //
00018 //
00019 
00020 
00021 // system include files
00022 #include <memory>
00023 
00024 // user include files
00025 #include "RecoMET/METProducers/interface/MuonMETValueMapProducer.h"
00026 #include "RecoMET/METAlgorithms/interface/MuonMETAlgo.h"
00027 #include "DataFormats/MuonReco/interface/Muon.h"
00028 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00029 #include "DataFormats/TrackReco/interface/Track.h"
00030 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00031 #include "DataFormats/Common/interface/ValueMap.h" 
00032 #include "MagneticField/Engine/interface/MagneticField.h"
00033 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00034 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00035 
00036 
00037 #include "DataFormats/MuonReco/interface/MuonMETCorrectionData.h"
00038 #include "FWCore/Framework/interface/MakerMacros.h"
00039 
00040 typedef math::XYZTLorentzVector LorentzVector;
00041 typedef math::XYZPoint Point;
00042 
00043 
00044 namespace cms {
00045   MuonMETValueMapProducer::MuonMETValueMapProducer(const edm::ParameterSet& iConfig) {
00046 
00047     using namespace edm;
00048   
00049     produces<ValueMap<reco::MuonMETCorrectionData> >   ("muCorrData");
00050 
00051     //get configuration parameters
00052     minPt_            = iConfig.getParameter<double>("minPt"               );
00053     maxEta_           = iConfig.getParameter<double>("maxEta"              );
00054     isAlsoTkMu_       = iConfig.getParameter<bool>  ("isAlsoTkMu"          );
00055     maxNormChi2_      = iConfig.getParameter<double>("maxNormChi2"         );
00056     maxd0_            = iConfig.getParameter<double>("maxd0"               );
00057     minnHits_         = iConfig.getParameter<int>   ("minnHits"            );
00058     minnValidStaHits_ = iConfig.getParameter<int>   ("minnValidStaHits"    );
00059   
00060     beamSpotInputTag_            = iConfig.getParameter<InputTag>("beamSpotInputTag"         );
00061     muonInputTag_   = iConfig.getParameter<InputTag>("muonInputTag");
00062   
00063     //Parameters from earlier
00064     useTrackAssociatorPositions_ = iConfig.getParameter<bool>("useTrackAssociatorPositions");
00065     useHO_                       = iConfig.getParameter<bool>("useHO"                      );
00066   
00067     ParameterSet trackAssociatorParams =
00068       iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
00069     trackAssociatorParameters_.loadParameters(trackAssociatorParams);
00070     trackAssociator_.useDefaultPropagator();
00071   
00072     towerEtThreshold_ = iConfig.getParameter<double>("towerEtThreshold");
00073     useRecHits_     = iConfig.getParameter<bool>("useRecHits");
00074   
00075   }
00076 
00077 
00078   MuonMETValueMapProducer::~MuonMETValueMapProducer()
00079   {
00080  
00081     // do anything here that needs to be done at desctruction time
00082     // (e.g. close files, deallocate resources etc.)
00083 
00084   }
00085 
00086 
00087   //
00088   // member functions
00089   //
00090 
00091   // ------------ method called to produce the data  ------------
00092   void MuonMETValueMapProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
00093   
00094     using namespace edm;
00095     using namespace reco;
00096   
00097     //get the Muon collection
00098     Handle<View<reco::Muon> > muons;
00099     iEvent.getByLabel(muonInputTag_,muons);
00100 
00101     //use the BeamSpot
00102     Handle<BeamSpot> beamSpotH;
00103     iEvent.getByLabel(beamSpotInputTag_, beamSpotH);
00104     bool haveBeamSpot = true;
00105     if(!beamSpotH.isValid() )
00106       haveBeamSpot = false;
00107 
00108     //get the Bfield
00109     edm::ESHandle<MagneticField> magneticField;
00110     iSetup.get<IdealMagneticFieldRecord>().get(magneticField);
00111     //get the B-field at the origin
00112     double bfield = magneticField->inTesla(GlobalPoint(0.,0.,0.)).z();
00113 
00114     //make a ValueMap of ints => flags for 
00115     //met correction. The values and meanings of the flags are :
00116     // flag==0 --->    The muon is not used to correct the MET by default
00117     // flag==1 --->    The muon is used to correct the MET. The Global pt is used. For backward compatibility only
00118     // flag==2 --->    The muon is used to correct the MET. The tracker pt is used. For backward compatibility only
00119     // flag==3 --->    The muon is used to correct the MET. The standalone pt is used. For backward compatibility only
00120     // In general, the flag should never be 3. You do not want to correct the MET using
00121     // the pt measurement from the standalone system (unless you really know what you're 
00122     // doing
00123     //flag == 4 -->    The muon was treated as a Pion. This is used for the tcMET producer
00124     //flag == 5 -->    The default fit is used, i.e, we get the pt from muon->pt
00125     std::auto_ptr<ValueMap<MuonMETCorrectionData> > vm_muCorrData(new ValueMap<MuonMETCorrectionData>());
00126     
00127     unsigned int nMuons = muons->size();
00128     
00129     std::vector<MuonMETCorrectionData> v_muCorrData;
00130     for (unsigned int iMu=0; iMu<nMuons; iMu++) {
00131 
00132       const reco::Muon* mu = &(*muons)[iMu];
00133       double deltax = 0.0;
00134       double deltay = 0.0;
00135         
00136       TrackRef mu_track;
00137       if(mu->isGlobalMuon()) {
00138         mu_track = mu->globalTrack();
00139       } else if(mu->isTrackerMuon()) {
00140         mu_track = mu->innerTrack();
00141       } else 
00142         mu_track = mu->outerTrack();
00143     
00144       TrackDetMatchInfo info = trackAssociator_.associate(iEvent, iSetup,
00145                                                           trackAssociator_.getFreeTrajectoryState(iSetup, *mu_track),
00146                                                           trackAssociatorParameters_);
00147       MuonMETAlgo alg;
00148       alg.GetMuDepDeltas(mu, info,
00149                           useTrackAssociatorPositions_, useRecHits_,
00150                           useHO_, towerEtThreshold_, 
00151                           deltax, deltay, bfield);
00152 
00153     
00154       //now we have to figure out the flags
00155       MuonMETCorrectionData muMETCorrData(MuonMETCorrectionData::NotUsed, deltax, deltay);
00156       //have to be a global muon!
00157       if(!mu->isGlobalMuon()) {
00158         v_muCorrData.push_back(muMETCorrData);
00159         continue;
00160       }
00161     
00162       //if we require that the muon be both a global muon and tkmuon
00163       //but the muon fails the tkmuon requirement, we fail it
00164       if(!mu->isTrackerMuon() && isAlsoTkMu_) {
00165         v_muCorrData.push_back(muMETCorrData);
00166         continue;
00167       }
00168 
00169       //if we have gotten here, we only have muons which are both global and tracker
00170         
00171       TrackRef globTk = mu->globalTrack();
00172       TrackRef siTk   = mu->innerTrack();
00173         
00174       if(mu->pt() < minPt_ || fabs(mu->eta()) > maxEta_) {
00175         v_muCorrData.push_back(muMETCorrData);
00176         continue;
00177       }
00178       if(globTk->chi2()/globTk->ndof() > maxNormChi2_) {
00179         v_muCorrData.push_back(muMETCorrData);
00180         continue;
00181       }
00182       if(fabs(globTk->dxy(beamSpotH->position())) > fabs(maxd0_) ) {
00183         v_muCorrData.push_back(muMETCorrData);
00184         continue;
00185       }
00186       if(siTk->numberOfValidHits() < minnHits_) {
00187         v_muCorrData.push_back(muMETCorrData);
00188         continue;
00189       }
00190 
00191       if(globTk->hitPattern().numberOfValidMuonHits() < minnValidStaHits_) {
00192          v_muCorrData.push_back(muMETCorrData);
00193         continue;
00194       }   
00195       //if we've gotten here. the global muon has passed all the tests
00196       v_muCorrData.push_back(MuonMETCorrectionData(MuonMETCorrectionData::MuonCandidateValuesUsed, deltax, deltay));
00197     }
00198     
00199     ValueMap<MuonMETCorrectionData>::Filler dataFiller(*vm_muCorrData);
00200      
00201     dataFiller.insert(muons, v_muCorrData.begin(), v_muCorrData.end());
00202     dataFiller.fill();
00203 
00204     iEvent.put(vm_muCorrData, "muCorrData");
00205     
00206   }
00207   
00208   // ------------ method called once each job just before starting event loop  ------------
00209   void MuonMETValueMapProducer::beginJob()
00210   {
00211   }
00212 
00213   // ------------ method called once each job just after ending the event loop  ------------
00214   void MuonMETValueMapProducer::endJob() {
00215   }
00216 }
00217 
00218