CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoEcal/EgammaCoreTools/src/PositionCalc.cc

Go to the documentation of this file.
00001 #include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h"
00002 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00003 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include "Geometry/EcalAlgo/interface/EcalPreshowerGeometry.h"
00006 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00008 
00009 
00010 
00011 PositionCalc::PositionCalc(const edm::ParameterSet& par) :
00012   param_LogWeighted_   ( par.getParameter<bool>("LogWeighted")) ,
00013   param_T0_barl_       ( par.getParameter<double>("T0_barl")) , 
00014   param_T0_endc_       ( par.getParameter<double>("T0_endc")) , 
00015   param_T0_endcPresh_  ( par.getParameter<double>("T0_endcPresh")) , 
00016   param_W0_            ( par.getParameter<double>("W0")) ,
00017   param_X0_            ( par.getParameter<double>("X0")) ,
00018   m_esGeom             ( 0 ) ,
00019   m_esPlus             ( false ) ,
00020   m_esMinus            ( false )
00021 {
00022 }
00023 
00024 const PositionCalc& PositionCalc::operator=( const PositionCalc& rhs ) 
00025 {
00026    param_LogWeighted_ = rhs.param_LogWeighted_;
00027    param_T0_barl_ = rhs.param_T0_barl_;
00028    param_T0_endc_ = rhs.param_T0_endc_;
00029    param_T0_endcPresh_ = rhs.param_T0_endcPresh_;
00030    param_W0_ = rhs.param_W0_;
00031    param_X0_ = rhs.param_X0_;
00032 
00033    m_esGeom = rhs.m_esGeom ;
00034    m_esPlus = rhs.m_esPlus ;
00035    m_esMinus = rhs.m_esMinus ;
00036    return *this;
00037 }
00038 
00039 math::XYZPoint 
00040 PositionCalc::Calculate_Location( const std::vector< std::pair<DetId, float> >&      iDetIds  ,
00041                                   const EcalRecHitCollection*    iRecHits ,
00042                                   const CaloSubdetectorGeometry* iSubGeom ,
00043                                   const CaloSubdetectorGeometry* iESGeom   )
00044 {
00045    math::XYZPoint returnValue ( 0, 0, 0 ) ;
00046 
00047    // Throw an error if the cluster was not initialized properly
00048 
00049    if( 0 == iRecHits || 
00050        0 == iSubGeom    )
00051    {
00052       throw(std::runtime_error("\n\nPositionCalc::Calculate_Location called uninitialized or wrong initialization.\n\n"));
00053    }
00054 
00055    if( 0 != iDetIds.size()   &&
00056        0 != iRecHits->size()     )
00057    {
00058       typedef std::vector<DetId> DetIdVec ;
00059 
00060       DetIdVec detIds ;
00061       detIds.reserve( iDetIds.size() ) ;
00062 
00063       double eTot  ( 0 ) ;
00064       double eMax  ( 0 ) ;
00065       DetId  maxId ;
00066 
00067       // Check that DetIds are nonzero
00068       EcalRecHitCollection::const_iterator endRecHits ( iRecHits->end() ) ;
00069       for( std::vector< std::pair<DetId, float> >::const_iterator n ( iDetIds.begin() ) ; n != iDetIds.end() ; ++n ) 
00070       {
00071          const DetId dId ( (*n).first ) ;
00072          if( !dId.null() )
00073          {
00074             EcalRecHitCollection::const_iterator iHit ( iRecHits->find( dId ) ) ;
00075             if( iHit != endRecHits )
00076             {
00077                detIds.push_back( dId );
00078 
00079                const double energy ( iHit->energy() ) ;
00080 
00081                if( 0 < energy ) // only save positive energies
00082                {
00083                   if( eMax < energy )
00084                   {
00085                      eMax  = energy ;
00086                      maxId = dId    ;
00087                   }
00088                   eTot += energy ;
00089                }
00090             }
00091          }
00092       }
00093 
00094       if( 0 >= eTot )
00095       {
00096          LogDebug("ZeroClusterEnergy") << "cluster with 0 energy: " << eTot
00097                                        << ", returning (0,0,0)";
00098       }
00099       else
00100       {
00101          // first time or when es geom changes set flags
00102          if( 0        != iESGeom &&
00103              m_esGeom != iESGeom    )
00104          {
00105             m_esGeom = iESGeom ;
00106             for( uint32_t ic ( 0 ) ;
00107                  ( ic != m_esGeom->getValidDetIds().size() ) &&
00108                     ( (!m_esPlus) || (!m_esMinus) ) ; ++ic )
00109             {
00110                const double z ( m_esGeom->getGeometry( m_esGeom->getValidDetIds()[ic] )->getPosition().z() ) ;
00111                m_esPlus  = m_esPlus  || ( 0 < z ) ;
00112                m_esMinus = m_esMinus || ( 0 > z ) ;
00113             }
00114          }
00115 
00116          //Select the correct value of the T0 parameter depending on subdetector
00117 
00118          const CaloCellGeometry* center_cell ( iSubGeom->getGeometry( maxId ) ) ;
00119      const double ctreta (center_cell->getPosition().eta());
00120 
00121          // for barrel, use barrel T0; 
00122          // for endcap: if preshower present && in preshower fiducial, 
00123          //             use preshower T0
00124          // else use endcap only T0
00125 
00126      const double preshowerStartEta =  1.653;
00127      const int subdet = maxId.subdetId();
00128          const double T0 ( subdet == EcalBarrel ? param_T0_barl_ :
00129                            ( ( ( preshowerStartEta < fabs( ctreta ) ) &&
00130                                ( ( ( 0 < ctreta ) && 
00131                                    m_esPlus          ) ||
00132                                  ( ( 0 > ctreta ) &&
00133                                    m_esMinus         )   )    ) ?
00134                              param_T0_endcPresh_ : param_T0_endc_ ) ) ;
00135 
00136          // Calculate shower depth
00137          const float maxDepth ( param_X0_ * ( T0 + log( eTot ) ) ) ;
00138          const float maxToFront ( center_cell->getPosition().mag() ) ; // to front face
00139 
00140          // Loop over hits and get weights
00141          double total_weight = 0;
00142 
00143          double xw ( 0 ) ;
00144          double yw ( 0 ) ;
00145          double zw ( 0 ) ;
00146 
00147          for( DetIdVec::const_iterator j ( detIds.begin() ) ; j != detIds.end() ; ++j ) 
00148          {
00149             const DetId dId ( *j ) ;
00150             EcalRecHitCollection::const_iterator iR ( iRecHits->find( dId ) ) ;
00151             const double e_j ( iR->energy() ) ;
00152 
00153             double weight = 0;
00154             if ( param_LogWeighted_ ) {
00155                     if ( e_j > 0 ) {
00156                             weight = std::max( 0., param_W0_ + log(e_j/eTot) );
00157                     } else {
00158                             weight = 0;
00159                     }
00160             } else {
00161                     weight = e_j/eTot;
00162             }
00163 
00164             const CaloCellGeometry* cell ( iSubGeom->getGeometry( dId ) ) ;
00165             const float depth ( maxDepth + maxToFront - cell->getPosition().mag() ) ;
00166 
00167             const GlobalPoint pos (
00168                dynamic_cast<const TruncatedPyramid*>( cell )->getPosition( depth ) );
00169 
00170             xw += weight*pos.x() ;
00171             yw += weight*pos.y() ;
00172             zw += weight*pos.z() ;
00173       
00174             total_weight += weight ;
00175          }
00176          returnValue = math::XYZPoint( xw/total_weight, 
00177                                        yw/total_weight, 
00178                                        zw/total_weight ) ;
00179       }
00180    }
00181    return returnValue ;
00182 }