CMS 3D CMS Logo

Public Types | Public Member Functions

CaloSpecificAlgo Class Reference

#include <CaloSpecificAlgo.h>

List of all members.

Public Types

typedef math::XYZTLorentzVector LorentzVector
typedef math::XYZPoint Point
typedef std::vector< const
reco::Candidate * > 
TowerCollection

Public Member Functions

reco::CaloMET addInfo (edm::Handle< edm::View< reco::Candidate > > towers, CommonMETData met, bool noHF, double globalThreshold)
 Make CaloMET. Assumes MET is made from CaloTowerCandidates.

Detailed Description

Adds Calorimeter specific information to MET base class Author: R. Cavanaugh (taken from F.Ratnikov, UMd) 6 June, 2006

Definition at line 13 of file CaloSpecificAlgo.h.


Member Typedef Documentation

Definition at line 16 of file CaloSpecificAlgo.h.

Definition at line 17 of file CaloSpecificAlgo.h.

Definition at line 18 of file CaloSpecificAlgo.h.


Member Function Documentation

reco::CaloMET CaloSpecificAlgo::addInfo ( edm::Handle< edm::View< reco::Candidate > >  towers,
CommonMETData  met,
bool  noHF,
double  globalThreshold 
)

Make CaloMET. Assumes MET is made from CaloTowerCandidates.

Definition at line 18 of file CaloSpecificAlgo.cc.

References reco::LeafCandidate::begin(), SpecificCaloMETData::CaloMETInmHF, SpecificCaloMETData::CaloMETInpHF, SpecificCaloMETData::CaloMETPhiInmHF, SpecificCaloMETData::CaloMETPhiInpHF, SpecificCaloMETData::CaloSETInmHF, SpecificCaloMETData::CaloSETInpHF, CaloTower::constituent(), CaloTower::constituentsSize(), funct::cos(), DetId::Ecal, EcalBarrel, EcalEndcap, CaloTower::emEt(), SpecificCaloMETData::EmEtInEB, SpecificCaloMETData::EmEtInEE, SpecificCaloMETData::EmEtInHF, edm::View< T >::end(), CaloTower::et(), reco::LeafCandidate::eta(), SpecificCaloMETData::EtFractionEm, SpecificCaloMETData::EtFractionHadronic, CaloTower::hadEt(), SpecificCaloMETData::HadEtInHB, SpecificCaloMETData::HadEtInHE, SpecificCaloMETData::HadEtInHF, SpecificCaloMETData::HadEtInHO, DetId::Hcal, HcalBarrel, HcalEndcap, HcalForward, HcalOuter, SpecificCaloMETData::MaxEtInEmTowers, SpecificCaloMETData::MaxEtInHadTowers, CommonMETData::met, SpecificCaloMETData::METSignificance, CommonMETData::mex, CommonMETData::mey, CaloTower::outerEt(), p4, reco::LeafCandidate::phi(), funct::sin(), timingPdfMaker::specific, mathSSE::sqrt(), HcalDetId::subdet(), and CommonMETData::sumet.

Referenced by cms::METProducer::produce().

{ 
  // Instantiate the container to hold the calorimeter specific information
  SpecificCaloMETData specific;
  // Initialise the container 
  specific.MaxEtInEmTowers = 0.0;         // Maximum energy in EM towers
  specific.MaxEtInHadTowers = 0.0;        // Maximum energy in HCAL towers
  specific.HadEtInHO = 0.0;          // Hadronic energy fraction in HO
  specific.HadEtInHB = 0.0;          // Hadronic energy in HB
  specific.HadEtInHF = 0.0;          // Hadronic energy in HF
  specific.HadEtInHE = 0.0;          // Hadronic energy in HE
  specific.EmEtInEB = 0.0;           // Em energy in EB
  specific.EmEtInEE = 0.0;           // Em energy in EE
  specific.EmEtInHF = 0.0;           // Em energy in HF
  specific.EtFractionHadronic = 0.0; // Hadronic energy fraction
  specific.EtFractionEm = 0.0;       // Em energy fraction
  specific.CaloSETInpHF = 0.0;        // CaloSET in HF+ 
  specific.CaloSETInmHF = 0.0;        // CaloSET in HF- 
  specific.CaloMETInpHF = 0.0;        // CaloMET in HF+ 
  specific.CaloMETInmHF = 0.0;        // CaloMET in HF- 
  specific.CaloMETPhiInpHF = 0.0;     // CaloMET-phi in HF+ 
  specific.CaloMETPhiInmHF = 0.0;     // CaloMET-phi in HF- 
  specific.METSignificance = 0.0;

  double totalEt = 0.0; 
  double totalEm     = 0.0;
  double totalHad    = 0.0;
  double MaxTowerEm  = 0.0;
  double MaxTowerHad = 0.0;
  double sumEtInpHF = 0.0;
  double sumEtInmHF = 0.0;
  double MExInpHF = 0.0;
  double MEyInpHF = 0.0;
  double MExInmHF = 0.0;
  double MEyInmHF = 0.0;

  if( towers->size() == 0 )  // if there are no towers, return specific = 0
    {
      //   LogDebug("CaloMET") << "Number of Candidate CaloTowers is zero : Unable to calculate calo specific info. " ;
      const LorentzVector p4( met.mex, met.mey, 0.0, met.met );
      const Point vtx( 0.0, 0.0, 0.0 );
      CaloMET specificmet( specific, met.sumet, p4, vtx );
      return specificmet;
    }

  edm::View<Candidate>::const_iterator towerCand = towers->begin();
  for( ; towerCand != towers->end(); towerCand++ ) 
    {
      const Candidate* candidate = &(*towerCand);
      if (candidate) {
        const CaloTower* calotower = dynamic_cast<const CaloTower*> (candidate);
        if (calotower)
          {
            double caloTowerEt=calotower->et();
            double caloTowerHadEt=calotower->hadEt();
            double caloTowerEmEt=calotower->emEt();
            if(caloTowerEt < globalThreshold) continue;
            totalEt  += caloTowerEt;
            totalEm  += caloTowerEmEt;
                   
            //totalHad += caloTowerHadEt + calotower->outerEt() ;
                   
            bool hadIsDone = false;
            bool emIsDone = false;
            int cell = calotower->constituentsSize();
            while ( --cell >= 0 && (!hadIsDone || !emIsDone) ) 
              {
                DetId id = calotower->constituent( cell );
                if( !hadIsDone && id.det() == DetId::Hcal ) 
                  {
                    HcalSubdetector subdet = HcalDetId(id).subdet();
                    if( subdet == HcalBarrel || subdet == HcalOuter )
                      {
                        if( caloTowerHadEt > MaxTowerHad ) MaxTowerHad = caloTowerHadEt;
                        specific.HadEtInHB   += caloTowerHadEt;
                        specific.HadEtInHO   += calotower->outerEt();
                      }
                    else if( subdet == HcalEndcap )
                      {
                        if( caloTowerHadEt > MaxTowerHad ) MaxTowerHad = caloTowerHadEt;
                        specific.HadEtInHE   += caloTowerHadEt;
                      }
                    else if( subdet == HcalForward )
                      {
                        if (!noHF)
                          {
                            if( caloTowerHadEt > MaxTowerHad ) MaxTowerHad = caloTowerHadEt;
                            if( caloTowerEmEt  > MaxTowerEm  ) MaxTowerEm  = caloTowerEmEt;
                            //These quantities should be nonzero only if HF is included, i.e., noHF == false
                            specific.HadEtInHF   += caloTowerHadEt;
                            specific.EmEtInHF    += caloTowerEmEt;
                          }
                        else
                          {
                            //These quantities need to be corrected from above if HF is excluded
                            // totalHad             -= caloTowerHadEt;  
                            totalEm              -= caloTowerEmEt;
                            totalEt              -= caloTowerEt;
                          }
                        // These get calculate regardless of NoHF == true or not.
                        // They are needed below for either case. 
                        if (calotower->eta()>=0)
                          {
                            sumEtInpHF  += caloTowerEt;
                            MExInpHF    -= (caloTowerEt * cos(calotower->phi()));
                            MEyInpHF    -= (caloTowerEt * sin(calotower->phi()));
                          }
                        else
                          {
                            sumEtInmHF  += caloTowerEt;
                            MExInmHF    -= (caloTowerEt * cos(calotower->phi()));
                            MEyInmHF    -= (caloTowerEt * sin(calotower->phi()));
                          }
                      }
                    hadIsDone = true;
                  }
                else if( !emIsDone && id.det() == DetId::Ecal )
                  {
                    EcalSubdetector subdet = EcalSubdetector( id.subdetId() );
                    if( caloTowerEmEt  > MaxTowerEm  ) MaxTowerEm  = caloTowerEmEt;
                    if( subdet == EcalBarrel )
                      {
                        specific.EmEtInEB    += caloTowerEmEt; 
                      }
                    else if( subdet == EcalEndcap ) 
                      {
                        specific.EmEtInEE    += caloTowerEmEt;
                      }
                    emIsDone = true;
                  }
              }
          }
      }
    }
  
  //Following Greg L's suggestion to calculate this quantity outside of the loop and to avoid confusion. 
  //This should work regardless of HO's inclusion / exclusion .
  totalHad += (totalEt - totalEm);
  
  if(!noHF)
    { // Form sub-det specific MET-vectors
      LorentzVector METpHF(MExInpHF, MEyInpHF, 0, sqrt(MExInpHF*MExInpHF + MEyInpHF*MEyInpHF));
      LorentzVector METmHF(MExInmHF, MEyInmHF, 0, sqrt(MExInmHF*MExInmHF + MEyInmHF*MEyInmHF));
      specific.CaloMETInpHF = METpHF.pt();
      specific.CaloMETInmHF = METmHF.pt();
      specific.CaloMETPhiInpHF = METpHF.Phi();
      specific.CaloMETPhiInmHF = METmHF.Phi();
      specific.CaloSETInpHF = sumEtInpHF;
      specific.CaloSETInmHF = sumEtInmHF;
    }
  else
    { // remove HF from MET calculation 
      met.mex   -= (MExInmHF + MExInpHF);
      met.mey   -= (MEyInmHF + MEyInpHF);
      met.sumet -= (sumEtInpHF + sumEtInmHF);
      met.met    = sqrt(met.mex*met.mex + met.mey*met.mey);   
    } 

  specific.MaxEtInEmTowers         = MaxTowerEm;  
  specific.MaxEtInHadTowers        = MaxTowerHad;         
  specific.EtFractionHadronic = totalHad / totalEt; 
  specific.EtFractionEm       =  totalEm / totalEt;       

  const LorentzVector p4( met.mex, met.mey, 0.0, met.met );
  const Point vtx( 0.0, 0.0, 0.0 );
  // Create and return an object of type CaloMET, which is a MET object with 
  // the extra calorimeter specfic information added
  CaloMET specificmet( specific, met.sumet, p4, vtx );
  return specificmet;
}