CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/RecoEgamma/EgammaTools/src/ggPFESClusters.cc

Go to the documentation of this file.
00001 #include "RecoEgamma/EgammaTools/interface/ggPFESClusters.h"
00002 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00003 #include "TMath.h"
00004 using namespace edm;
00005 using namespace std;
00006 using namespace reco;
00007 /*
00008 class by Rishi Patel rpatel@cern.ch 
00009 and Eleni Petrakou Eleni.Petrakou@cern.ch
00010 */
00011 ggPFESClusters::ggPFESClusters(
00012                                edm::Handle<EcalRecHitCollection>& ESRecHits,
00013                                const CaloSubdetectorGeometry* geomEnd
00014                                ):
00015   ESRecHits_(ESRecHits),
00016   geomEnd_(geomEnd)
00017 {
00018   
00019 }
00020 
00021 ggPFESClusters::~ggPFESClusters(){
00022 
00023 }
00024 
00025 // Returns ES clusters for a PF supercluster 
00026 vector<reco::PreshowerCluster> ggPFESClusters::getPFESClusters(
00027                                                               reco::SuperCluster sc 
00028                                                               ){
00029   std::vector<PreshowerCluster>PFPreShowerClust;
00030   int jj = 0;
00031   float energies[100];
00032   for(reco::CaloCluster_iterator ps=sc.preshowerClustersBegin(); ps!=sc.preshowerClustersEnd(); ++ps){
00033     if(jj>99)
00034       cout << endl << "Attention! More than 100 ES clusters!" << endl;
00035     else {
00036       energies[jj] = (*ps)->energy();
00037       bool doubl = false;
00038       for(int kk=0; kk<jj; kk++){
00039         if(fabs(energies[kk]-(*ps)->energy())<0.0000001){
00040           //cout << endl << "Duplicate cluster";
00041           doubl = true;
00042           break;
00043         }
00044       }
00045       jj++;
00046       if(doubl) continue;
00047     }
00048 
00049     std::vector< std::pair<DetId, float> > psCells=(*ps)->hitsAndFractions();
00050     float PS1E=0;
00051     float PS2E=0;       
00052     int plane=0;
00053     for(unsigned int s=0; s<psCells.size(); ++s){
00054       for(EcalRecHitCollection::const_iterator es=ESRecHits_->begin(); es!= ESRecHits_->end(); ++es){
00055         if(es->id().rawId()==psCells[s].first.rawId()){ 
00056           ESDetId id=ESDetId(psCells[s].first.rawId());
00057           plane=id.plane();
00058           if(id.plane()==1)PS1E=PS1E + es->energy() * psCells[s].second;
00059           if(id.plane()==2)PS2E=PS2E + es->energy() * psCells[s].second;
00060           break;
00061         }                 
00062       }
00063     }
00064     //make PreShower object storing plane PSEnergy and Position
00065     if(plane==1){
00066       PreshowerCluster PS1=PreshowerCluster(PS1E,(*ps)->position(),(*ps)->hitsAndFractions(),plane);
00067       PFPreShowerClust.push_back(PS1);  
00068     }
00069     if(plane==2){
00070       PreshowerCluster PS2=PreshowerCluster(PS2E,(*ps)->position(),(*ps)->hitsAndFractions(),plane);
00071       PFPreShowerClust.push_back(PS2);      
00072     }
00073   }  
00074   return PFPreShowerClust;  
00075 }
00076 
00077 
00078 // Maps each ES cluster to its closest linked EE cluster. 
00079 std::map<unsigned int,unsigned int> ggPFESClusters::getClosestEECls(vector<reco::PreshowerCluster> PFPS, vector<reco::CaloCluster> PF){
00080   std::map<unsigned int,unsigned int> linkedIndices;
00081   std::map<double, unsigned int> links;
00082 
00083   for(unsigned int j=0; j<PFPS.size(); ++j){
00084     for(unsigned int i=0; i<PF.size(); ++i){
00085       double link_ = getLinkDist(PFPS[j], PF[i]);
00086       if(link_!=-1.)
00087         links.insert(std::make_pair(link_,i));
00088     }
00089     std::map<double,unsigned int>::iterator itlinks = links.begin();
00090     if((*itlinks).first>=0.)
00091       linkedIndices.insert(std::make_pair(j, (*itlinks).second));
00092     links.clear();
00093   }
00094 
00095   return linkedIndices;
00096 }
00097 
00098 
00099 // Returns PF link distance between ES-EE clusters. 
00100 double ggPFESClusters::getLinkDist(reco::PreshowerCluster clusterPS, reco::CaloCluster clusterECAL){
00101 
00102   static double resPSpitch = 0.19/sqrt(12.);
00103   static double resPSlength = 6.1/sqrt(12.);
00104 
00105   // ECAL cluster position
00106   double zECAL  = clusterECAL.position().Z(); // cluster centroid position 
00107   double xECAL  = clusterECAL.position().X();
00108   double yECAL  = clusterECAL.position().Y();
00109 
00110   // PS cluster position 
00111   double zPS = clusterPS.position().Z();
00112   double xPS = clusterPS.position().X();
00113   double yPS = clusterPS.position().Y();
00114 
00115   // Check that zEcal and zPs have the same sign
00116   if (zECAL*zPS < 0.) return -1.;
00117   double deltaX = 0.;
00118   double deltaY = 0.;
00119   double sqr12 = std::sqrt(12.);
00120   switch (clusterPS.plane()) {
00121   case 1:
00122     // vertical strips, measure x with pitch precision
00123     deltaX = resPSpitch * sqr12;
00124     deltaY = resPSlength * sqr12;
00125     break;
00126   case 2:
00127     // horizontal strips, measure y with pitch precision
00128     deltaY = resPSpitch * sqr12;
00129     deltaX = resPSlength * sqr12;
00130     break;
00131   default:
00132     break;
00133   }
00134 
00135   // Get the rechits
00136   const std::vector< std::pair<DetId, float> > fracs = clusterECAL.hitsAndFractions();
00137   bool linkedbyrechit = false;
00138   //loop rechits
00139   for(unsigned int rhit = 0; rhit < fracs.size(); rhit++){
00140     double fraction = fracs[rhit].second;
00141     if(fraction < 1E-4) continue;
00142     if(fracs[rhit].first.null()) continue;
00143 
00144     //getting rechit center position
00145     DetId eehitid=DetId(fracs[rhit].first.rawId());
00146     const CaloCellGeometry *xtal = geomEnd_->getGeometry(eehitid);
00147     if(!xtal) continue;
00148     
00149     //getting rechit corners
00150     const CaloCellGeometry::CornersVec& corners_vec = xtal->getCorners();
00151     math::XYZPoint corners[4];
00152     // They have this order just for compatibility with the original function. 
00153     corners[0] = math::XYZPoint(corners_vec[3].x(), corners_vec[3].y(), corners_vec[3].z() );
00154     corners[1] = math::XYZPoint(corners_vec[2].x(), corners_vec[2].y(), corners_vec[2].z() );
00155     corners[2] = math::XYZPoint(corners_vec[1].x(), corners_vec[1].y(), corners_vec[1].z() );
00156     corners[3] = math::XYZPoint(corners_vec[0].x(), corners_vec[0].y(), corners_vec[0].z() );
00157     const GlobalPoint p = geomEnd_->getGeometry(eehitid)->getPosition();
00158 
00159     // Extrapolating from the xtal's surface (because of working with DetId's) 
00160     const math::XYZPoint& posxyz = math::XYZPoint(p.x()*zPS/p.z(), p.y()*zPS/p.z(), p.z()*zPS/p.z());
00161 
00162     double x[5];
00163     double y[5];
00164     for ( unsigned jc=0; jc<4; ++jc ) {
00165       // corner position projected onto the preshower
00166       math::XYZPoint cornerpos = corners[jc] * zPS/p.z();
00167       // Inflate the size by the size of the PS strips, and by 5% to include ECAL cracks.
00168       x[jc] = cornerpos.X() + (cornerpos.X()-posxyz.X()) * (0.05 +1.0/fabs((cornerpos.X()-posxyz.X()))*deltaX/2.);
00169       y[jc] = cornerpos.Y() + (cornerpos.Y()-posxyz.Y()) * (0.05 +1.0/fabs((cornerpos.Y()-posxyz.Y()))*deltaY/2.);
00170     }//loop corners
00171 
00172     //need to close the polygon in order to use the TMath::IsInside fonction from root lib
00173     x[4] = x[0];
00174     y[4] = y[0];
00175 
00176     //Check if the extrapolation point of the track falls within the rechit boundaries
00177     bool isinside = TMath::IsInside(xPS,yPS,5,x,y);
00178       
00179     if( isinside ){
00180       linkedbyrechit = true;
00181       break;
00182     }
00183 
00184   }//loop rechits
00185   
00186   if( linkedbyrechit ) {
00187     double dist = std::sqrt( (xECAL/1000. - xPS/1000.)*(xECAL/1000. - xPS/1000.) 
00188                           + (yECAL/1000. - yPS/1000.)*(yECAL/1000. - yPS/1000.) );
00189     return dist;
00190   } else { 
00191     return -1.;
00192   }
00193   
00194 }