CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/RecoMET/METAlgorithms/src/CaloSpecificAlgo.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    METAlgorithms
00004 // Class:      CaloSpecificAlgo
00005 // 
00006 // Original Author:  R. Cavanaugh (taken from F.Ratnikov, UMd)
00007 //         Created:  June 6, 2006
00008 // $Id: CaloSpecificAlgo.cc,v 1.32 2012/06/09 21:19:30 sakuma Exp $
00009 //
00010 //
00011 #include "RecoMET/METAlgorithms/interface/CaloSpecificAlgo.h"
00012 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00013 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00014 #include "DataFormats/CaloTowers/interface/CaloTower.h"
00015 
00016 #include <iostream>
00017 
00018 using namespace reco;
00019 
00020 //____________________________________________________________________________||
00021 // This algorithm adds calorimeter specific global event information to 
00022 // the MET object which may be useful/needed for MET Data Quality Monitoring
00023 // and MET cleaning. 
00024 //____________________________________________________________________________||
00025 
00026 //____________________________________________________________________________||
00027 reco::CaloMET CaloSpecificAlgo::addInfo(edm::Handle<edm::View<Candidate> > towers, CommonMETData met, bool noHF, double globalThreshold)
00028 { 
00029   SpecificCaloMETData specific;
00030   initializeSpecificCaloMETData(specific);
00031 
00032   double totalEt = 0.0; 
00033   double totalEm = 0.0;
00034 
00035   double sumEtInpHF = 0.0;
00036   double sumEtInmHF = 0.0;
00037   double MExInpHF = 0.0;
00038   double MEyInpHF = 0.0;
00039   double MExInmHF = 0.0;
00040   double MEyInmHF = 0.0;
00041 
00042   for(edm::View<Candidate>::const_iterator towerCand = towers->begin(); towerCand != towers->end(); ++towerCand ) 
00043     {
00044       const CaloTower* calotower = dynamic_cast<const CaloTower*> (&(*towerCand));
00045       if (!calotower) continue;
00046       if(calotower->et() < globalThreshold) continue;
00047       update_totalEt_totalEm(totalEt, totalEm, calotower, noHF);
00048       update_MaxTowerEm_MaxTowerHad(specific.MaxEtInEmTowers, specific.MaxEtInHadTowers, calotower, noHF);
00049       update_EmEtInEB_EmEtInEE(specific.EmEtInEB, specific.EmEtInEE, calotower);
00050       update_HadEtInHB_HadEtInHE_HadEtInHO_HadEtInHF_EmEtInHF(specific.HadEtInHB, specific.HadEtInHE, specific.HadEtInHO, specific.HadEtInHF, specific.EmEtInHF, calotower, noHF);
00051       update_sumEtInpHF_MExInpHF_MEyInpHF_sumEtInmHF_MExInmHF_MEyInmHF(sumEtInpHF, MExInpHF, MEyInpHF, sumEtInmHF, MExInmHF, MEyInmHF, calotower);
00052     }
00053   
00054   double totalHad = totalEt - totalEm;
00055   
00056   if(noHF) remove_HF_from_MET(met, sumEtInpHF, MExInpHF, MEyInpHF, sumEtInmHF, MExInmHF, MEyInmHF);
00057 
00058   if(!noHF) add_MET_in_HF(specific, sumEtInpHF, MExInpHF, MEyInpHF, sumEtInmHF, MExInmHF, MEyInmHF);
00059 
00060   specific.EtFractionHadronic = (totalEt == 0.0)? 0.0 : totalHad/totalEt;
00061   specific.EtFractionEm = (totalEt == 0.0)? 0.0 : totalEm/totalEt;
00062 
00063   const LorentzVector p4( met.mex, met.mey, 0.0, met.met);
00064   const Point vtx(0.0, 0.0, 0.0);
00065   CaloMET caloMET(specific, met.sumet, p4, vtx);
00066   return caloMET;
00067 }
00068 
00069 //____________________________________________________________________________||
00070 void CaloSpecificAlgo::initializeSpecificCaloMETData(SpecificCaloMETData &specific)
00071 {
00072   specific.MaxEtInEmTowers = 0.0;    // Maximum energy in EM towers
00073   specific.MaxEtInHadTowers = 0.0;   // Maximum energy in HCAL towers
00074   specific.HadEtInHO = 0.0;          // Hadronic energy fraction in HO
00075   specific.HadEtInHB = 0.0;          // Hadronic energy in HB
00076   specific.HadEtInHF = 0.0;          // Hadronic energy in HF
00077   specific.HadEtInHE = 0.0;          // Hadronic energy in HE
00078   specific.EmEtInEB = 0.0;           // Em energy in EB
00079   specific.EmEtInEE = 0.0;           // Em energy in EE
00080   specific.EmEtInHF = 0.0;           // Em energy in HF
00081   specific.EtFractionHadronic = 0.0; // Hadronic energy fraction
00082   specific.EtFractionEm = 0.0;       // Em energy fraction
00083   specific.METSignificance = 0.0;
00084   specific.CaloMETInpHF = 0.0;        // CaloMET in HF+ 
00085   specific.CaloMETInmHF = 0.0;        // CaloMET in HF- 
00086   specific.CaloSETInpHF = 0.0;        // CaloSET in HF+ 
00087   specific.CaloSETInmHF = 0.0;        // CaloSET in HF- 
00088   specific.CaloMETPhiInpHF = 0.0;     // CaloMET-phi in HF+ 
00089   specific.CaloMETPhiInmHF = 0.0;     // CaloMET-phi in HF- 
00090 }
00091 
00092 //____________________________________________________________________________||
00093 void CaloSpecificAlgo::update_totalEt_totalEm(double &totalEt, double& totalEm, const CaloTower* calotower, bool noHF)
00094 {
00095   if( noHF )
00096     {
00097       DetId detIdHcal = find_DetId_of_HCAL_cell_in_constituent_of(calotower);
00098       if(!detIdHcal.null()) 
00099         {
00100           HcalSubdetector subdet = HcalDetId(detIdHcal).subdet();
00101           if( subdet == HcalForward ) return;
00102         }
00103     }
00104 
00105   totalEt += calotower->et();
00106   totalEm += calotower->emEt();
00107 }
00108 
00109 //____________________________________________________________________________||
00110 void CaloSpecificAlgo::update_MaxTowerEm_MaxTowerHad(double &MaxTowerEm, double &MaxTowerHad, const CaloTower* calotower, bool noHF)
00111 {
00112   DetId detIdHcal = find_DetId_of_HCAL_cell_in_constituent_of(calotower);
00113   DetId detIdEcal = find_DetId_of_ECAL_cell_in_constituent_of(calotower);
00114 
00115   if( !detIdHcal.null() )
00116     {
00117       HcalSubdetector subdet = HcalDetId(detIdHcal).subdet();
00118       if( subdet == HcalBarrel || subdet == HcalOuter || subdet == HcalEndcap || (!noHF && subdet == HcalForward))
00119         {
00120           if( calotower->hadEt() > MaxTowerHad ) MaxTowerHad = calotower->hadEt();
00121           if( calotower->emEt() > MaxTowerEm  ) MaxTowerEm  = calotower->emEt();
00122         }
00123 
00124     }
00125 
00126   if( !detIdEcal.null() )
00127     {
00128       if( calotower->emEt() > MaxTowerEm ) MaxTowerEm = calotower->emEt();
00129     }
00130 }
00131 
00132 //____________________________________________________________________________||
00133 void CaloSpecificAlgo::update_EmEtInEB_EmEtInEE(double &EmEtInEB, double &EmEtInEE, const CaloTower* calotower)
00134 {
00135   DetId detIdEcal = find_DetId_of_ECAL_cell_in_constituent_of(calotower);
00136   if(detIdEcal.null()) return;
00137 
00138   EcalSubdetector subdet = EcalSubdetector( detIdEcal.subdetId() );
00139   if( subdet == EcalBarrel )
00140     {
00141       EmEtInEB += calotower->emEt(); 
00142     }
00143   else if( subdet == EcalEndcap ) 
00144     {
00145       EmEtInEE += calotower->emEt();
00146     }
00147 }
00148 
00149 //____________________________________________________________________________||
00150 void CaloSpecificAlgo::update_HadEtInHB_HadEtInHE_HadEtInHO_HadEtInHF_EmEtInHF(double &HadEtInHB, double &HadEtInHE, double &HadEtInHO, double &HadEtInHF, double &EmEtInHF, const CaloTower* calotower, bool noHF)
00151 {
00152   DetId detIdHcal = find_DetId_of_HCAL_cell_in_constituent_of(calotower);
00153   if(detIdHcal.null()) return;
00154 
00155   HcalSubdetector subdet = HcalDetId(detIdHcal).subdet();
00156   if( subdet == HcalBarrel || subdet == HcalOuter )
00157     {
00158       HadEtInHB += calotower->hadEt();
00159       HadEtInHO += calotower->outerEt();
00160     }
00161 
00162   if( subdet == HcalEndcap )
00163     {
00164       HadEtInHE += calotower->hadEt();
00165     }
00166 
00167   if( subdet == HcalForward && !noHF)
00168     {
00169       HadEtInHF += calotower->hadEt();
00170       EmEtInHF += calotower->emEt();
00171     }
00172 }
00173 
00174 //____________________________________________________________________________||
00175 void CaloSpecificAlgo::update_sumEtInpHF_MExInpHF_MEyInpHF_sumEtInmHF_MExInmHF_MEyInmHF(double &sumEtInpHF, double &MExInpHF, double &MEyInpHF, double &sumEtInmHF, double &MExInmHF, double &MEyInmHF, const CaloTower* calotower)
00176 {
00177   DetId detIdHcal = find_DetId_of_HCAL_cell_in_constituent_of(calotower);
00178   if(detIdHcal.null()) return;
00179 
00180   HcalSubdetector subdet = HcalDetId(detIdHcal).subdet();
00181   if( !(subdet == HcalForward) ) return;
00182 
00183   if (calotower->eta() >= 0)
00184     {
00185       sumEtInpHF += calotower->et();
00186       MExInpHF -= (calotower->et() * cos(calotower->phi()));
00187       MEyInpHF -= (calotower->et() * sin(calotower->phi()));
00188     }
00189   else
00190     {
00191       sumEtInmHF += calotower->et();
00192       MExInmHF -= (calotower->et() * cos(calotower->phi()));
00193       MEyInmHF -= (calotower->et() * sin(calotower->phi()));
00194     }
00195 }
00196 
00197 //____________________________________________________________________________||
00198 void CaloSpecificAlgo::remove_HF_from_MET(CommonMETData &met, double sumEtInpHF, double MExInpHF, double MEyInpHF, double sumEtInmHF, double MExInmHF, double MEyInmHF)
00199 {
00200   met.mex -= (MExInmHF + MExInpHF);
00201   met.mey -= (MEyInmHF + MEyInpHF);
00202   met.sumet -= (sumEtInpHF + sumEtInmHF);
00203   met.met = sqrt(met.mex*met.mex + met.mey*met.mey);   
00204 }
00205 
00206 //____________________________________________________________________________||
00207 void CaloSpecificAlgo::add_MET_in_HF(SpecificCaloMETData &specific, double sumEtInpHF, double MExInpHF, double MEyInpHF, double sumEtInmHF, double MExInmHF, double MEyInmHF)
00208 {
00209   LorentzVector METpHF(MExInpHF, MEyInpHF, 0, sqrt(MExInpHF*MExInpHF + MEyInpHF*MEyInpHF));
00210   LorentzVector METmHF(MExInmHF, MEyInmHF, 0, sqrt(MExInmHF*MExInmHF + MEyInmHF*MEyInmHF));
00211   specific.CaloMETInpHF = METpHF.pt();
00212   specific.CaloMETInmHF = METmHF.pt();
00213   specific.CaloMETPhiInpHF = METpHF.Phi();
00214   specific.CaloMETPhiInmHF = METmHF.Phi();
00215   specific.CaloSETInpHF = sumEtInpHF;
00216   specific.CaloSETInmHF = sumEtInmHF;
00217 }
00218 
00219 //____________________________________________________________________________||
00220 DetId CaloSpecificAlgo::find_DetId_of_HCAL_cell_in_constituent_of(const CaloTower* calotower)
00221 {
00222   DetId ret;
00223   for (int cell = calotower->constituentsSize() - 1; cell >= 0; --cell)
00224     {
00225       DetId id = calotower->constituent( cell );
00226       if( id.det() == DetId::Hcal )
00227         {
00228           ret = id;
00229           break;
00230         }
00231     }
00232   return ret;
00233 }
00234 
00235 //____________________________________________________________________________||
00236 DetId CaloSpecificAlgo::find_DetId_of_ECAL_cell_in_constituent_of(const CaloTower* calotower)
00237 {
00238   DetId ret;
00239   for (int cell = calotower->constituentsSize() - 1; cell >= 0; --cell)
00240     {
00241       DetId id = calotower->constituent( cell );
00242       if( id.det() == DetId::Ecal )
00243         {
00244           ret = id;
00245           break;
00246         }
00247     }
00248   return ret;
00249 }
00250 
00251 //____________________________________________________________________________||