00001
00002
00003
00004
00005
00006
00007
00008
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
00022
00023
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;
00073 specific.MaxEtInHadTowers = 0.0;
00074 specific.HadEtInHO = 0.0;
00075 specific.HadEtInHB = 0.0;
00076 specific.HadEtInHF = 0.0;
00077 specific.HadEtInHE = 0.0;
00078 specific.EmEtInEB = 0.0;
00079 specific.EmEtInEE = 0.0;
00080 specific.EmEtInHF = 0.0;
00081 specific.EtFractionHadronic = 0.0;
00082 specific.EtFractionEm = 0.0;
00083 specific.METSignificance = 0.0;
00084 specific.CaloMETInpHF = 0.0;
00085 specific.CaloMETInmHF = 0.0;
00086 specific.CaloSETInpHF = 0.0;
00087 specific.CaloSETInmHF = 0.0;
00088 specific.CaloMETPhiInpHF = 0.0;
00089 specific.CaloMETPhiInmHF = 0.0;
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