CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/QCDAnalysis/ChargedHadronSpectra/src/EcalShowerProperties.cc

Go to the documentation of this file.
00001 #include "QCDAnalysis/ChargedHadronSpectra/interface/EcalShowerProperties.h"
00002 
00003 #include "FWCore/Framework/interface/Event.h"
00004 #include "FWCore/Framework/interface/EventSetup.h"
00005 #include "FWCore/Framework/interface/ESHandle.h"
00006 
00007 #include "DataFormats/TrackReco/interface/Track.h"
00008 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00009 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00010 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00011 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00012 
00013 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00014 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00015 
00016 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00017 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00018 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00019 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00020 
00021 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00022 #include "MagneticField/Engine/interface/MagneticField.h"
00023 
00024 using namespace std;
00025 
00026 const double R_M = 2.2;
00027 //const double R_M = 4.;
00028 
00029 /*****************************************************************************/
00030 EcalShowerProperties::EcalShowerProperties
00031   (const edm::Event & ev, const edm::EventSetup & es)
00032 {
00033   // Get magnetic field
00034   edm::ESHandle<MagneticField> theMagneticFieldHandle;
00035   es.get<IdealMagneticFieldRecord>().get(theMagneticFieldHandle);
00036   theMagneticField = theMagneticFieldHandle.product();
00037 
00038   // Get propagator
00039   edm::ESHandle<Propagator> thePropagatorHandle;
00040   es.get<TrackingComponentsRecord>().get("PropagatorWithMaterial",
00041                                           thePropagatorHandle);
00042   thePropagator = thePropagatorHandle.product();
00043 
00044   // Get calorimetry
00045   edm::ESHandle<CaloGeometry> theCaloGeometryHandle;
00046   es.get<IdealGeometryRecord>().get(theCaloGeometryHandle);
00047   theCaloGeometry = (const CaloGeometry*)theCaloGeometryHandle.product();
00048 
00049   // Get ecal rechits
00050   ev.getByLabel("ecalRecHit", "EcalRecHitsEB", recHitsBarrel);
00051   ev.getByLabel("ecalRecHit", "EcalRecHitsEE", recHitsEndcap);
00052 }
00053 
00054 /*****************************************************************************/
00055 FreeTrajectoryState EcalShowerProperties::getTrajectoryAtOuterPoint
00056   (const reco::Track & track)
00057 {
00058   GlobalPoint  pos(track.outerX() , track.outerY() , track.outerZ() );
00059   GlobalVector mom(track.outerPx(), track.outerPy(), track.outerPz());
00060 
00061   GlobalTrajectoryParameters gtp(pos,mom, track.charge(), theMagneticField);
00062 
00063   return FreeTrajectoryState(gtp, track.outerStateCovariance());
00064 }
00065 
00066 /*****************************************************************************/
00067 Plane::PlanePointer EcalShowerProperties::getSurface
00068   (const CaloCellGeometry* cell, int i)
00069 {
00070   int j = i * 4;
00071 
00072   // Get corners
00073   const CaloCellGeometry::CornersVec & c(cell->getCorners());
00074 
00075   // Get center
00076   GlobalPoint center( (c[j].x() + c[j+1].x() + c[j+2].x() + c[j+3].x()) / 4,
00077                       (c[j].y() + c[j+1].y() + c[j+2].y() + c[j+3].y()) / 4,
00078                       (c[j].z() + c[j+1].z() + c[j+2].z() + c[j+3].z()) / 4);
00079 
00080   // Get plane
00081   Surface::PositionType pos(center);
00082   Surface::RotationType rot(c[j+1]-c[j], c[j+3]-c[j]);
00083   return Plane::build(pos, rot);
00084 }
00085 
00086 /*****************************************************************************/
00087 vector<TrajectoryStateOnSurface> EcalShowerProperties::getEndpoints
00088   (const FreeTrajectoryState & ftsAtLastPoint,
00089    const TrajectoryStateOnSurface & tsosBeforeEcal, int subDet)
00090 {
00091   std::vector<TrajectoryStateOnSurface> tsosEnds;
00092 
00093   const CaloSubdetectorGeometry* geom =
00094     theCaloGeometry->getSubdetectorGeometry(DetId::Ecal,subDet);
00095 
00096   // Get closest cell 
00097   DetId detId(geom->getClosestCell(ftsAtLastPoint.position()));
00098 
00099   if(!geom->present(detId)) return tsosEnds;
00100 
00101   const CaloCellGeometry* cell = geom->getGeometry(detId);
00102   const CaloCellGeometry* oldcell;
00103   TrajectoryStateOnSurface tsos;
00104 
00105   // Front and back
00106   for(int i = 0; i < 2; i++)
00107   {
00108     int step = 0;
00109 
00110     do
00111     {
00112       oldcell = cell;
00113 
00114       Plane::PlanePointer thePlane  = getSurface(oldcell, i);
00115       tsos = thePropagator->propagate(ftsAtLastPoint,*thePlane);
00116 
00117       if(!tsos.isValid()) return tsosEnds;
00118 
00119       detId = geom->getClosestCell(tsos.globalPosition());
00120 
00121       if(!geom->present(detId)) return tsosEnds;
00122       cell  = geom->getGeometry(detId);
00123     }
00124     while(cell != oldcell && step++ < 5);
00125 
00126     if(step++ < 5) 
00127       tsosEnds.push_back(tsos);
00128   }
00129 
00130   return tsosEnds;
00131 }
00132 
00133 /*****************************************************************************/
00134 double EcalShowerProperties::getDistance
00135   (const std::vector<TrajectoryStateOnSurface> & tsosEnds,
00136    const CaloCellGeometry* cell)
00137 {
00138   double dmin = 1e+9;
00139   LocalPoint p;
00140 
00141   // Project to entry surface, 'p1p2' segment
00142   p = tsosEnds[0].surface().toLocal(tsosEnds[0].globalPosition());
00143   LocalPoint p1(p.x(), p.y(), 0);
00144 
00145   p = tsosEnds[0].surface().toLocal(tsosEnds[1].globalPosition());
00146   LocalPoint p2(p.x(), p.y(), 0);
00147 
00148   const CaloCellGeometry::CornersVec & c(cell->getCorners());
00149 
00150   // Project to entry surface, 'c' corners
00151   for(int i = 0; i < 4; i++)
00152   {
00153     p = tsosEnds[0].surface().toLocal(GlobalPoint(c[i].x(),c[i].y(),c[i].z()));
00154     LocalPoint c(p.x(), p.y(), 0);
00155 
00156     // Calculate distance of 'c' from endpoints 'p1' and 'p2'
00157     double d1 = (p1 - c).mag2(); // distance from end
00158     double d2 = (p2 - c).mag2(); // distance from end
00159     double dm = min(d1,d2);
00160 
00161     // distance from segment
00162     double lambda = (c - p1) * (p2 - p1) / (p2 - p1).mag2();
00163     if(lambda > 0 && lambda < 1)
00164     {
00165       double dp = (c - p1 - lambda * (p2 - p1)).mag2();
00166       dm = min (dm,dp);
00167     }
00168 
00169     dmin = min(dm, dmin);
00170   }
00171 
00172   return(sqrt(dmin));
00173 }
00174 
00175 /*****************************************************************************/
00176 pair<double,double> EcalShowerProperties::processEcalRecHits
00177   (const std::vector<TrajectoryStateOnSurface> & tsosEnds, int subDet, int & ntime)
00178 {
00179   const CaloSubdetectorGeometry* geom =
00180     theCaloGeometry->getSubdetectorGeometry(DetId::Ecal,subDet);
00181 
00182   std::vector<DetId> detIds;
00183   detIds.push_back(geom->getClosestCell(tsosEnds[0].globalPosition()));
00184   detIds.push_back(geom->getClosestCell(tsosEnds[1].globalPosition()));
00185 
00186   double energy = 0, time = 0;
00187   ntime = 0;
00188 
00189   if(subDet == EcalBarrel)
00190   {
00191     EBDetId frontId(detIds[0]);
00192     EBDetId  backId(detIds[1]);
00193 
00194     double ieta =     (frontId.ieta() + backId.ieta())/2.;
00195     double weta = fabs(frontId.ieta() - backId.ieta())/2.;
00196 
00197     double iphi =     (frontId.iphi() + backId.iphi())/2.;
00198     double wphi = fabs(frontId.iphi() - backId.iphi())/2.;
00199 
00200     for(EBRecHitCollection::const_iterator recHit = recHitsBarrel->begin();
00201                                            recHit!= recHitsBarrel->end();
00202                                            recHit++)
00203     {
00204       EBDetId detId(recHit->id());
00205       const CaloCellGeometry* cell = geom->getGeometry(detId);
00206 
00207       if(fabs(detId.ieta() - ieta) < weta + 4 &&
00208          fabs(detId.iphi() - iphi) < wphi + 4)
00209       if(getDistance(tsosEnds, cell) < R_M)
00210       {
00211         energy += recHit->energy();
00212         time   += recHit->energy() * recHit->time();
00213         ntime++;
00214       }
00215     }
00216   }
00217   else
00218   {
00219     EEDetId frontId(detIds[0]);
00220     EEDetId  backId(detIds[1]);
00221 
00222     double ix =     (frontId.ix() + backId.ix())/2.;
00223     double wx = fabs(frontId.ix() - backId.ix())/2.;
00224 
00225     double iy =     (frontId.iy() + backId.iy())/2.;
00226     double wy = fabs(frontId.iy() - backId.iy())/2.;
00227 
00228     for(EERecHitCollection::const_iterator recHit = recHitsEndcap->begin();
00229                                            recHit!= recHitsEndcap->end();
00230                                            recHit++)
00231     {
00232       EEDetId detId(recHit->id());
00233       const CaloCellGeometry* cell = geom->getGeometry(detId);
00234 
00235       if(detId.zside() == frontId.zside() &&
00236          detId.zside() ==  backId.zside())
00237       if( fabs(detId.ix() - ix) < wx + 4 &&
00238           fabs(detId.iy() - iy) < wy + 4)
00239       if(getDistance(tsosEnds, cell) < R_M)
00240       {
00241         energy += recHit->energy();
00242         time   += recHit->energy() * recHit->time();
00243         ntime++;
00244       }
00245     }
00246   }
00247 
00248   if(energy > 0) time /= energy;
00249 
00250   return std::pair<double,double> (energy,time);
00251 }
00252 
00253 /*****************************************************************************/
00254 pair<double,double> EcalShowerProperties::processTrack
00255   (const reco::Track & track, int & ntime)
00256 {
00257   // Get trajectory at outer point
00258   FreeTrajectoryState ftsAtLastPoint = getTrajectoryAtOuterPoint(track);
00259 
00260   // Ecal cylinder
00261   double radius  = 129.0; // cm
00262   double z       = 320.9; // cm
00263   Surface::RotationType rot;
00264 
00265   // Subdetector
00266   std::vector<int> subDets;
00267   subDets.push_back(EcalBarrel);
00268   subDets.push_back(EcalEndcap);
00269 
00270   std::pair<double,double> result(0,0);
00271 
00272   // Take barrel and endcap
00273   for(std::vector<int>::const_iterator subDet = subDets.begin();
00274                                   subDet!= subDets.end(); subDet++)
00275   {
00276     TrajectoryStateOnSurface tsosBeforeEcal;
00277 
00278     if(*subDet == EcalBarrel)
00279     { 
00280       Surface::PositionType pos(0,0,0);
00281       Cylinder::CylinderPointer theBarrel = Cylinder::build(pos, rot, radius);
00282       tsosBeforeEcal = thePropagator->propagate(ftsAtLastPoint, *theBarrel);
00283 
00284       if(!tsosBeforeEcal.isValid())                     continue;
00285       if(fabs(tsosBeforeEcal.globalPosition().z()) > z) continue;
00286     }
00287     else
00288     {
00289       Surface::PositionType pos(0,0,z);
00290       Plane::PlanePointer theEndcap = Plane::build(pos, rot);
00291       tsosBeforeEcal = thePropagator->propagate(ftsAtLastPoint, *theEndcap);
00292 
00293       if(!tsosBeforeEcal.isValid())                             continue;
00294       if(fabs(tsosBeforeEcal.globalPosition().perp()) > radius) continue;
00295     }
00296 
00297     std::vector<TrajectoryStateOnSurface> tsosEnds =
00298       getEndpoints(ftsAtLastPoint, tsosBeforeEcal, *subDet);
00299 
00300     if(tsosEnds.size() == 2)
00301       result = processEcalRecHits(tsosEnds, *subDet, ntime);
00302   }
00303 
00304   return result;
00305 }