CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DataFormats/EcalRecHit/src/EcalRecHit.cc

Go to the documentation of this file.
00001 #include "DataFormats/EcalRecHit/interface/EcalRecHit.h"
00002 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00003 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00004 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include <cassert>
00007 #include <math.h>
00008 
00009 #include <iostream>
00010 
00011 EcalRecHit::EcalRecHit() : CaloRecHit(), flagBits_(0) {
00012 }
00013 
00014 EcalRecHit::EcalRecHit(const DetId& id, float energy, float time, uint32_t flags, uint32_t flagBits) :
00015   CaloRecHit(id,energy,time,flags),
00016   flagBits_(flagBits)
00017 {
00018 }
00019 
00020 bool EcalRecHit::isRecovered() const {
00021         return (    recoFlag() == kLeadingEdgeRecovered 
00022                  || recoFlag() == kNeighboursRecovered 
00023                  || recoFlag() == kTowerRecovered 
00024                  );
00025 }
00026 
00027 float EcalRecHit::chi2() const
00028 {
00029         uint32_t rawChi2 = 0x7F & (flags()>>4);
00030         return (float)rawChi2 / (float)((1<<7)-1) * 64.;
00031 }
00032 
00033 float EcalRecHit::chi2Prob() const
00034 {
00035         std::cerr << "Please retrieve the chi2 value instead of its probability.\n";
00036         std::cerr << "Use the method EcalRecHit::chi2() for that purpose.\n";
00037         std::cerr << "The chi2 is still in a commissioning phase and further\n";
00038         std::cerr << "actions will be taken in the future. Thanks.\n";
00039         assert(false);
00040         uint32_t rawChi2Prob = 0x7F & (flags()>>4);
00041         return (float)rawChi2Prob / (float)((1<<7)-1);
00042 }
00043 
00044 float EcalRecHit::outOfTimeChi2Prob() const
00045 {
00046         std::cerr << "Please retrieve the chi2 value instead of its probability.\n";
00047         std::cerr << "Use the method EcalRecHit::outOfTimeChi2() for that purpose.\n";
00048         std::cerr << "The chi2 is still in a commissioning phase and further\n";
00049         std::cerr << "actions will be taken in the future. Thanks.\n";
00050         assert(false);
00051         /*
00052         uint32_t rawChi2Prob = 0x7F & (flags()>>24);
00053         return (float)rawChi2Prob / (float)((1<<7)-1);
00054         */
00055         return -1; // will never get here
00056 }
00057 
00058 float EcalRecHit::outOfTimeChi2() const
00059 {
00060         uint32_t rawChi2Prob = 0x7F & (flags()>>24);
00061         return (float)rawChi2Prob / (float)((1<<7)-1) * 64.;
00062 }
00063 
00064 float EcalRecHit::outOfTimeEnergy() const
00065 {
00066         uint32_t rawEnergy = (0x1FFF & flags()>>11);
00067         uint16_t exponent = rawEnergy>>10;
00068         uint16_t significand = ~(0xE<<9) & rawEnergy;
00069         return (float) significand*pow(10,exponent-5);
00070 }
00071 
00072 void EcalRecHit::setRecoFlag( uint32_t flag )
00073 {
00074         setFlags( (~0xF & flags()) | (flag & 0xF) );
00075 }
00076 
00077 void EcalRecHit::setChi2Prob( float chi2Prob )
00078 {
00079         /* not used - store the raw chi2 instead */
00080         std::cerr << "Please store the chi2 value instead of its probability.\n";
00081         std::cerr << "Use the method EcalRecHit::setChi2() for that purpose.\n";
00082         std::cerr << "The chi2 is still in a commissioning phase and further\n";
00083         std::cerr << "actions will be taken in the future. Thanks.\n";
00084         assert(false);
00085         /*
00086         if ( chi2Prob < 0 || chi2Prob > 1 ) {
00087                 edm::LogWarning("EcalRecHit::setChi2Prob") << "chi2Prob outside limits [0, 1] : " << chi2Prob;
00088         } else {
00089                 // use 7 bits
00090                 uint32_t rawChi2Prob = lround( chi2Prob * ((1<<7)-1) );
00091                 // shift by 4 bits (recoFlag)
00092                 setFlags( (~(0x7F<<4) & flags()) | ((rawChi2Prob & 0x7F)<<4) );
00093         }
00094         */
00095 }
00096 
00097 void EcalRecHit::setChi2( float chi2 )
00098 {
00099         // bound the max value of the chi2
00100         if ( chi2 > 64 ) chi2 = 64;
00101         // use 7 bits
00102         uint32_t rawChi2 = lround( chi2 / 64. * ((1<<7)-1) );
00103         // shift by 4 bits (recoFlag)
00104         setFlags( (~(0x7F<<4) & flags()) | ((rawChi2 & 0x7F)<<4) );
00105 }
00106 
00107 void EcalRecHit::setOutOfTimeEnergy( float energy )
00108 {
00109         if ( energy > 0.001 ) {
00110                 uint16_t exponent = lround(floor(log10(energy)))+3;
00111                 uint16_t significand = lround(energy/pow(10,exponent-5));
00112                 // use 13 bits (3 exponent, 10 significand)
00113                 uint32_t rawEnergy = exponent<<10 | significand;
00114                 // shift by 11 bits (recoFlag + chi2)
00115                 setFlags( ( ~(0x1FFF<<11) & flags()) | ((rawEnergy & 0x1FFF)<<11) );
00116         }
00117 }
00118 
00119 void EcalRecHit::setOutOfTimeChi2Prob( float chi2Prob )
00120 {
00121         /* not used - store the raw chi2 instead */
00122         std::cerr << "Please store the chi2 value instead of its probability.\n";
00123         std::cerr << "Use the method EcalRecHit::setOutOfTimeChi2() for that purpose.\n";
00124         std::cerr << "The chi2 is still in a commissioning phase and further\n";
00125         std::cerr << "actions will be taken in the future. Thanks.\n";
00126         assert(false);
00127         /*
00128         if ( chi2Prob < 0 || chi2Prob > 1 ) {
00129                 edm::LogWarning("EcalRecHit::setOutOfTimeChi2Prob") << "chi2Prob outside limits [0, 1] : " << chi2Prob;
00130         } else {
00131                 // use 7 bits
00132                 uint32_t rawChi2Prob = lround( chi2Prob * ((1<<7)-1) );
00133                 // shift by 24 bits (recoFlag + chi2 + outOfTimeEnergy)
00134                 setFlags( (~(0x7F<<24) & flags()) | ((rawChi2Prob & 0x7F)<<24) );
00135         }
00136         */
00137 }
00138 
00139 
00140 void EcalRecHit::setOutOfTimeChi2( float chi2 )
00141 {
00142         // bound the max value of chi2
00143         if ( chi2 > 64 ) chi2 = 64;
00144         // use 7 bits
00145         uint32_t rawChi2 = lround( chi2 / 64. * ((1<<7)-1) );
00146         // shift by 24 bits (recoFlag + chi2 + outOfTimeEnergy)
00147         setFlags( (~(0x7F<<24) & flags()) | ((rawChi2 & 0x7F)<<24) );
00148 }
00149 
00150 
00151 void EcalRecHit::setTimeError( uint8_t timeErrBits )
00152 {
00153         // take the bits and put them in the right spot
00154         setAux( (~0xFF & aux()) | timeErrBits );
00155 }
00156 
00157 
00158 float EcalRecHit::timeError() const
00159 {
00160         uint32_t timeErrorBits = 0xFF & aux();
00161         // all bits off --> time reco bailed out (return negative value)
00162         if( (0xFF & timeErrorBits) == 0x00 )
00163                 return -1;
00164         // all bits on  --> time error over 5 ns (return large value)
00165         if( (0xFF & timeErrorBits) == 0xFF )
00166                 return 10000;
00167 
00168         float LSB = 1.26008;
00169         uint8_t exponent = timeErrorBits>>5;
00170         uint8_t significand = timeErrorBits & ~(0x7<<5);
00171         return pow(2.,exponent)*significand*LSB/1000.;
00172 }
00173 
00174 
00175 bool EcalRecHit::isTimeValid() const
00176 {
00177         if(timeError() <= 0)
00178           return false;
00179         else
00180           return true;
00181 }
00182 
00183 
00184 bool EcalRecHit::isTimeErrorValid() const
00185 {
00186         if(!isTimeValid())
00187           return false;
00188         if(timeError() >= 10000)
00189           return false;
00190 
00191         return true;
00192 }
00193 
00194 std::ostream& operator<<(std::ostream& s, const EcalRecHit& hit) {
00195   if (hit.detid().det() == DetId::Ecal && hit.detid().subdetId() == EcalBarrel) 
00196     return s << EBDetId(hit.detid()) << ": " << hit.energy() << " GeV, " << hit.time() << " ns";
00197   else if (hit.detid().det() == DetId::Ecal && hit.detid().subdetId() == EcalEndcap) 
00198     return s << EEDetId(hit.detid()) << ": " << hit.energy() << " GeV, " << hit.time() << " ns";
00199   else if (hit.detid().det() == DetId::Ecal && hit.detid().subdetId() == EcalPreshower) 
00200     return s << ESDetId(hit.detid()) << ": " << hit.energy() << " GeV, " << hit.time() << " ns";
00201   else
00202     return s << "EcalRecHit undefined subdetector" ;
00203 }