CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/DataFormats/CaloTowers/src/CaloTower.cc

Go to the documentation of this file.
00001 #include "DataFormats/CaloTowers/interface/CaloTower.h"
00002 
00003 
00004 CaloTower::CaloTower() {
00005   emE_=0;
00006   hadE_=0;
00007   outerE_=0;
00008   emLvl1_=0;
00009   hadLvl1_=0;
00010 }
00011 
00012 CaloTower::CaloTower(const CaloTowerDetId& id,
00013                      double emE, double hadE, double outerE,
00014                      int ecal_tp, int hcal_tp,
00015                      const PolarLorentzVector p4,
00016                      GlobalPoint emPos, GlobalPoint hadPos) : 
00017   LeafCandidate(0, p4, Point(0,0,0)),  
00018   id_(id),
00019   emPosition_(emPos), hadPosition_(hadPos), 
00020   emE_(emE), hadE_(hadE), outerE_(outerE),
00021   emLvl1_(ecal_tp), hadLvl1_(hcal_tp) {}
00022 
00023 
00024 CaloTower::CaloTower(const CaloTowerDetId& id,
00025                      double emE, double hadE, double outerE,
00026                      int ecal_tp, int hcal_tp,
00027                      const LorentzVector p4,
00028                      GlobalPoint emPos, GlobalPoint hadPos) : 
00029   LeafCandidate(0, p4, Point(0,0,0)),  
00030   id_(id),
00031   emPosition_(emPos), hadPosition_(hadPos),
00032   emE_(emE), hadE_(hadE), outerE_(outerE),
00033   emLvl1_(ecal_tp), hadLvl1_(hcal_tp) {}
00034 
00035 
00036 // recalculated momentum-related quantities wrt user provided vertex Z position
00037 
00038 
00039 math::PtEtaPhiMLorentzVector CaloTower::hadP4(double vtxZ) const {
00040 
00041 
00042   // note: for now we use the same position for HO as for the other detectors
00043 
00044   double hcalTot;
00045   if (abs(ieta())<16) hcalTot = (energy() - emE_);
00046   else hcalTot = hadE_;
00047 
00048   if (hcalTot>0) {
00049     double ctgTheta = (hadPosition_.z() - vtxZ)/hadPosition_.perp();
00050     double newEta = asinh(ctgTheta);  
00051     double pf = 1.0/cosh(newEta);
00052 
00053     return PolarLorentzVector(hcalTot * pf, newEta, hadPosition_.phi(), 0.0);   
00054   }
00055   
00056   return math::PtEtaPhiMLorentzVector(0,0,0,0);
00057 }
00058 
00059 math::PtEtaPhiMLorentzVector CaloTower::emP4(double vtxZ) const {
00060 
00061   if (emE_>0) {
00062     double ctgTheta = (emPosition_.z() - vtxZ)/emPosition_.perp();
00063     double newEta = asinh(ctgTheta);  
00064     double pf = 1.0/cosh(newEta);
00065   
00066     return math::PtEtaPhiMLorentzVector(emE_ * pf, newEta, emPosition_.phi(), 0.0);   
00067   }
00068   
00069   return math::PtEtaPhiMLorentzVector(0,0,0,0);
00070 }
00071 
00072 
00073 // recalculated momentum-related quantities wrt user provided 3D vertex 
00074 
00075 
00076 math::PtEtaPhiMLorentzVector CaloTower::hadP4(Point v) const {
00077 
00078   // note: for now we use the same position for HO as for the other detectors
00079 
00080   double hcalTot;
00081   if (abs(ieta())<16) hcalTot = (energy() - emE_);
00082   else hcalTot = hadE_;
00083 
00084   if (hcalTot>0) {
00085     GlobalPoint p(v.x(), v.y(), v.z());
00086     math::XYZVector dir = math::XYZVector(hadPosition_ - p);
00087     return math::PtEtaPhiMLorentzVector(hcalTot * sin(dir.theta()), dir.eta(), dir.phi(), 0.0);  
00088   }
00089 
00090   return   math::PtEtaPhiMLorentzVector(0,0,0,0);
00091 }
00092 
00093 math::PtEtaPhiMLorentzVector CaloTower::emP4(Point v) const {
00094 
00095   if (emE_>0) {
00096     GlobalPoint p(v.x(), v.y(), v.z());
00097     math::XYZVector dir = math::XYZVector(emPosition_ - p);
00098     return math::PtEtaPhiMLorentzVector(emE_ * sin(dir.theta()), dir.eta(), dir.phi(), 0.0);   
00099   }
00100   
00101   return   math::PtEtaPhiMLorentzVector(0,0,0,0);
00102 }
00103 
00104 
00105 math::PtEtaPhiMLorentzVector CaloTower::p4(double vtxZ) const {
00106 
00107   if (abs(ieta())<=29) {
00108     return (emP4(vtxZ)+hadP4(vtxZ));
00109   }
00110   // em and had energy in HF are defined in a special way
00111   double ctgTheta = (emPosition_.z() - vtxZ)/emPosition_.perp(); // em and had positions in HF are forced to be the same
00112   double newEta = asinh(ctgTheta);  
00113   double pf = 1.0/cosh(newEta);
00114   return math::PtEtaPhiMLorentzVector(p4().energy() * pf, newEta, emPosition_.phi(), 0.0);   
00115 }
00116 
00117 
00118 math::PtEtaPhiMLorentzVector CaloTower::p4(Point v) const {
00119 
00120   if (abs(ieta())<=29) {
00121     return emP4(v)+hadP4(v);
00122   }
00123   // em and had energy in HF are defined in a special way
00124   GlobalPoint p(v.x(), v.y(), v.z());
00125   math::XYZVector dir = math::XYZVector(emPosition_ - p); // em and had positions in HF are forced to be the same
00126   return math::PtEtaPhiMLorentzVector(p4().energy() * sin(dir.theta()), dir.eta(), dir.phi(), 0.0);   
00127 }
00128 
00129 
00130 // p4 contribution from HO alone (note: direction is always taken to be the same as used for HB.)
00131 
00132 math::PtEtaPhiMLorentzVector CaloTower::p4_HO(Point v) const {
00133 
00134   if (ietaAbs()>15 || outerE_<0) return   math::PtEtaPhiMLorentzVector(0,0,0,0);
00135   
00136   GlobalPoint p(v.x(), v.y(), v.z());
00137   math::XYZVector dir = math::XYZVector(hadPosition_ - p);
00138   return math::PtEtaPhiMLorentzVector(outerE_ * sin(dir.theta()), dir.eta(), dir.phi(), 0.0);  
00139 }
00140 
00141 math::PtEtaPhiMLorentzVector CaloTower::p4_HO(double vtxZ) const {
00142     Point p(0, 0, vtxZ);
00143     return p4_HO(p);
00144 }
00145 
00146 math::PtEtaPhiMLorentzVector CaloTower::p4_HO() const {
00147 
00148   if (ietaAbs()>15 || outerE_<0) return   math::PtEtaPhiMLorentzVector(0.0,0.0,0.0,0.0);
00149   return math::PtEtaPhiMLorentzVector(outerE_ * sin(hadPosition_.theta()), hadPosition_.eta(), hadPosition_.phi(), 0.0);  
00150 }
00151 
00152 
00153 void CaloTower::addConstituents( const std::vector<DetId>& ids ) {
00154   constituents_.reserve(constituents_.size()+ids.size());
00155   constituents_.insert(constituents_.end(),ids.begin(),ids.end());
00156 }
00157 
00158 int CaloTower::numCrystals() const {
00159   if (id_.ietaAbs()>29) return 0;
00160   
00161   int nC = 0;
00162   std::vector<DetId>::const_iterator it = constituents_.begin();
00163   for (; it!=constituents_.end(); ++it) {
00164     if (it->det()==DetId::Ecal) ++nC;
00165   }
00166 
00167   return nC;
00168 }
00169 
00170 
00171 
00172 // Set the CaloTower status word from the number of bad/recovered/problematic
00173 // cells in HCAL and ECAL.
00174 
00175 void CaloTower::setCaloTowerStatus(unsigned int numBadHcalChan,unsigned int numBadEcalChan, 
00176                                    unsigned int numRecHcalChan,unsigned int numRecEcalChan,
00177                                    unsigned int numProbHcalChan,unsigned int numProbEcalChan) {
00178 
00179   twrStatusWord_ = 0x0;
00180 
00181   twrStatusWord_ |= (  numBadEcalChan  & 0x1F);
00182   twrStatusWord_ |= ( (numRecEcalChan  & 0x1F) << 5);
00183   twrStatusWord_ |= ( (numProbEcalChan & 0x1F) << 10); 
00184   twrStatusWord_ |= ( (numBadHcalChan  & 0x7)  << 15);
00185   twrStatusWord_ |= ( (numRecHcalChan  & 0x7)  << 18);
00186   twrStatusWord_ |= ( (numProbHcalChan & 0x7)  << 21);
00187 
00188   return;
00189 }
00190 
00191 
00192 
00193 
00194 // energy in the tower by HCAL subdetector
00195 // This is trivia except for tower 16
00196 // needed by JetMET cleanup in AOD.
00197 
00198 double CaloTower::energyInHB() const  { 
00199   if (id_.ietaAbs()<16) return hadE_;
00200   else if (id_.ietaAbs()==16) return hadE_-outerE_;
00201   else return 0.0;
00202 }
00203 
00204 double CaloTower::energyInHE() const { 
00205   if (id_.ietaAbs()>16 && id_.ietaAbs()<30) return hadE_;
00206   else if (id_.ietaAbs()==16) return outerE_;
00207   else return 0.0;
00208 }
00209  
00210 double CaloTower::energyInHF() const {
00211   if (id_.ietaAbs()>29) return energy();
00212   else return 0.0;
00213 }
00214 
00215 // this is actual energy contributed to the tower
00216 // (outerEnergy() returns HO energy regardless if it is used or not)
00217 // Note: rounding error may lead to values not identically equal to zero
00218 // when HO was not used 
00219 
00220 double CaloTower::energyInHO() const {
00221   if (id_.ietaAbs()>15) return 0.0;
00222   else return (energy() - hadE_ -emE_);
00223 }
00224 
00225 
00226 
00227 
00228 
00229 std::ostream& operator<<(std::ostream& s, const CaloTower& ct) {
00230   return s << ct.id() << ":"  << ct.et()
00231            << " GeV ET (EM=" << ct.emEt() <<
00232     " HAD=" << ct.hadEt() << " OUTER=" << ct.outerEt() << ") (" << ct.eta() << "," << ct.phi() << ")";    
00233 }