CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/HLTrigger/JetMET/src/HLTRHemisphere.cc

Go to the documentation of this file.
00001 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00002 #include "FWCore/Framework/interface/ESHandle.h"
00003 #include "FWCore/Framework/interface/EventSetup.h"
00004 
00005 #include "DataFormats/Common/interface/Handle.h"
00006 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
00007 
00008 #include "DataFormats/Common/interface/Ref.h"
00009 
00010 #include "DataFormats/Common/interface/View.h"
00011 #include "DataFormats/JetReco/interface/CaloJet.h"
00012 #include "DataFormats/JetReco/interface/CaloJetCollection.h"
00013 
00014 #include "DataFormats/METReco/interface/CaloMET.h"
00015 #include "DataFormats/METReco/interface/CaloMETCollection.h"
00016 
00017 #include "DataFormats/MuonReco/interface/Muon.h"
00018 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
00019 
00020 #include "FWCore/Framework/interface/MakerMacros.h"
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 
00023 #include "TVector3.h"
00024 #include "TLorentzVector.h"
00025 
00026 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00027 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00028 #include "FWCore/Utilities/interface/InputTag.h"
00029 
00030 #include "HLTrigger/JetMET/interface/HLTRHemisphere.h"
00031 
00032 #include<vector>
00033 
00034 //
00035 // constructors and destructor
00036 //
00037 HLTRHemisphere::HLTRHemisphere(const edm::ParameterSet& iConfig) :
00038   inputTag_    (iConfig.getParameter<edm::InputTag>("inputTag")),
00039   muonTag_    (iConfig.getParameter<edm::InputTag>("muonTag")),
00040   doMuonCorrection_(iConfig.getParameter<bool>         ("doMuonCorrection" )),
00041   muonEta_     (iConfig.getParameter<double>       ("maxMuonEta" )),
00042   min_Jet_Pt_  (iConfig.getParameter<double>       ("minJetPt" )),
00043   max_Eta_     (iConfig.getParameter<double>       ("maxEta" )),
00044   max_NJ_      (iConfig.getParameter<int>          ("maxNJ" )),
00045   accNJJets_   (iConfig.getParameter<bool>         ("acceptNJ" ))
00046 {
00047    LogDebug("") << "Input/minJetPt/maxEta/maxNJ/acceptNJ : "
00048                 << inputTag_.encode() << " "
00049                 << min_Jet_Pt_ << "/"
00050                 << max_Eta_ << "/"
00051                 << max_NJ_ << "/"
00052                 << accNJJets_ << ".";
00053 
00054    //register your products
00055    produces<std::vector<math::XYZTLorentzVector> >();
00056 }
00057 
00058 HLTRHemisphere::~HLTRHemisphere()
00059 {
00060 }
00061 
00062 void
00063 HLTRHemisphere::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
00064   edm::ParameterSetDescription desc;
00065   desc.add<edm::InputTag>("inputTag",edm::InputTag("hltMCJetCorJetIcone5HF07"));
00066   desc.add<edm::InputTag>("muonTag",edm::InputTag(""));
00067   desc.add<bool>("doMuonCorrection",false);
00068   desc.add<double>("maxMuonEta",2.1);
00069   desc.add<double>("minJetPt",30.0);
00070   desc.add<double>("maxEta",3.0);
00071   desc.add<int>("maxNJ",7);
00072   desc.add<bool>("acceptNJ",true);
00073   descriptions.add("hltRHemisphere",desc);
00074 }
00075 
00076 //
00077 // member functions
00078 //
00079 
00080 // ------------ method called to produce the data  ------------
00081 bool 
00082 HLTRHemisphere::filter(edm::Event& iEvent, const edm::EventSetup& iSetup)
00083 {
00084    using namespace std;
00085    using namespace edm;
00086    using namespace reco;
00087    using namespace math;
00088    using namespace trigger;
00089    
00090    typedef XYZTLorentzVector LorentzVector;
00091 
00092    // get hold of collection of objects
00093    //   Handle<CaloJetCollection> jets;
00094    Handle<View<Jet> > jets;
00095    iEvent.getByLabel (inputTag_,jets);
00096 
00097    // get hold of the muons, if necessary
00098    Handle<vector<reco::RecoChargedCandidate> > muons;
00099    if(doMuonCorrection_) iEvent.getByLabel( muonTag_,muons );
00100 
00101    // The output Collection
00102    std::auto_ptr<vector<math::XYZTLorentzVector> > Hemispheres(new vector<math::XYZTLorentzVector> );
00103 
00104    // look at all objects, check cuts and add to filter object
00105    int n(0);
00106    vector<math::XYZTLorentzVector> JETS;
00107    for (unsigned int i=0; i<jets->size(); i++) {
00108      if(std::abs(jets->at(i).eta()) < max_Eta_ && jets->at(i).pt() >= min_Jet_Pt_){
00109        JETS.push_back(jets->at(i).p4());
00110        n++;
00111      }
00112    }
00113 
00114   if(n>max_NJ_ && max_NJ_!=-1){
00115     iEvent.put(Hemispheres);
00116     return accNJJets_; // too many jets, accept for timing
00117   }
00118 
00119   if(doMuonCorrection_){
00120     const int nMu = 2;
00121     int muonIndex[nMu] = { -1, -1 };
00122     std::vector<reco::RecoChargedCandidate>::const_iterator muonIt;
00123     int index   = 0;
00124     int nPassMu = 0;
00125     for(muonIt = muons->begin(); muonIt!=muons->end(); muonIt++,index++){ 
00126       if(std::abs(muonIt->eta()) > muonEta_ || muonIt->pt() < min_Jet_Pt_) continue; // skip muons out of eta range or too low pT
00127       if(nPassMu >= 2){ // if we have already accepted two muons, accept the event
00128         iEvent.put(Hemispheres); // too many muons, accept for timing      
00129         return true;
00130       }
00131       muonIndex[nPassMu++] = index;    
00132     }
00133     //muons as MET
00134     this->ComputeHemispheres(Hemispheres,JETS);
00135     //lead muon as jet
00136     if(nPassMu>0){
00137       std::vector<math::XYZTLorentzVector> muonJets;
00138       reco::RecoChargedCandidate leadMu = muons->at(muonIndex[0]);
00139       muonJets.push_back(leadMu.p4());
00140       Hemispheres->push_back(leadMu.p4());
00141       this->ComputeHemispheres(Hemispheres,JETS,&muonJets); // lead muon as jet
00142       if(nPassMu>1){ // two passing muons
00143         muonJets.pop_back();
00144         reco::RecoChargedCandidate secondMu = muons->at(muonIndex[1]);
00145         muonJets.push_back(secondMu.p4());
00146         Hemispheres->push_back(secondMu.p4());
00147         this->ComputeHemispheres(Hemispheres,JETS,&muonJets); // lead muon as v, second muon as jet
00148         muonJets.push_back(leadMu.p4());
00149         this->ComputeHemispheres(Hemispheres,JETS,&muonJets); // both muon as jets
00150       }
00151     }
00152   }else{ // do MuonCorrection==false
00153     if(n<2) return false; // not enough jets and not adding in muons
00154     this->ComputeHemispheres(Hemispheres,JETS); // don't do the muon isolation, just run once and done
00155   }
00156   //Format: 
00157   // 0 muon: 2 hemispheres (2)
00158   // 1 muon: 2 hemisheress + leadMuP4 + 2 hemispheres (5)
00159   // 2 muon: 2 hemispheres + leadMuP4 + 2 hemispheres + 2ndMuP4 + 4 Hemispheres (10)
00160   iEvent.put(Hemispheres);
00161   return true;
00162 }
00163 
00164 void
00165 HLTRHemisphere::ComputeHemispheres(std::auto_ptr<std::vector<math::XYZTLorentzVector> >& hlist, const std::vector<math::XYZTLorentzVector>& JETS,
00166                                    std::vector<math::XYZTLorentzVector>* extraJets){
00167   using namespace math;
00168   using namespace reco;
00169   XYZTLorentzVector j1R(0.1, 0., 0., 0.1);
00170   XYZTLorentzVector j2R(0.1, 0., 0., 0.1);
00171   int nJets = JETS.size();
00172   if(extraJets) nJets+=extraJets->size();
00173 
00174   if(nJets<2){ // put empty hemispheres if not enough jets
00175     hlist->push_back(j1R);
00176     hlist->push_back(j2R);
00177     return;
00178   }
00179   unsigned int N_comb = pow(2,nJets); // compute the number of combinations of jets possible
00180   //Make the hemispheres
00181   double M_minR = 9999999999.0;
00182   unsigned int j_count;
00183   for (unsigned int i = 0; i < N_comb; i++) {       
00184     XYZTLorentzVector j_temp1, j_temp2;
00185     unsigned int itemp = i;
00186     j_count = N_comb/2;
00187     unsigned int count = 0;
00188     while (j_count > 0) {
00189       if (itemp/j_count == 1){
00190         if(count<JETS.size()) j_temp1 += JETS.at(count);
00191         else j_temp1 +=extraJets->at(count-JETS.size());
00192       } else {
00193         if(count<JETS.size()) j_temp2 += JETS.at(count);
00194         else j_temp2 +=extraJets->at(count-JETS.size());
00195       }
00196       itemp -= j_count * (itemp/j_count);
00197       j_count /= 2;
00198       count++;
00199     }
00200     double M_temp = j_temp1.M2() + j_temp2.M2();
00201     if (M_temp < M_minR) {
00202       M_minR = M_temp;
00203       j1R = j_temp1; 
00204       j2R = j_temp2; 
00205     }
00206   }
00207 
00208   hlist->push_back(j1R);
00209   hlist->push_back(j2R);
00210   return;
00211 }
00212 
00213 DEFINE_FWK_MODULE(HLTRHemisphere);