CMS 3D CMS Logo

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 
00007 PositionCalc::PositionCalc(std::map<std::string,double> providedParameters)
00008 {
00009   param_LogWeighted_ = providedParameters.find("LogWeighted")->second;
00010   param_T0_barl_ = providedParameters.find("T0_barl")->second; 
00011   param_T0_endc_ = providedParameters.find("T0_endc")->second; 
00012   param_T0_endcPresh_ = providedParameters.find("T0_endcPresh")->second; 
00013   param_W0_ = providedParameters.find("W0")->second;
00014   param_X0_ = providedParameters.find("X0")->second;
00015 
00016   //storedRecHitsMap_ = passedRecHitsMap;
00017   //storedSubdetectorGeometry_ = passedGeometry;
00018 }
00019 
00020 const PositionCalc& PositionCalc::operator=(const PositionCalc& rhs) {
00021   param_LogWeighted_ = rhs.param_LogWeighted_;
00022   param_T0_barl_ = rhs.param_T0_barl_;
00023   param_T0_endc_ = rhs.param_T0_endc_;
00024   param_T0_endcPresh_ = rhs.param_T0_endcPresh_;
00025   param_W0_ = rhs.param_W0_;
00026   param_X0_ = rhs.param_X0_;
00027   return *this;
00028 }
00029 
00030 math::XYZPoint PositionCalc::Calculate_Location(std::vector<DetId> passedDetIds,
00031                                                 EcalRecHitCollection const * storedRecHitsMap_,
00032                                                 const CaloSubdetectorGeometry * storedSubdetectorGeometry_,
00033                                                 const CaloSubdetectorGeometry * storedESGeometry_)
00034 {
00035 
00036   // Throw an error if the cluster was not initialized properly
00037 
00038   if(storedRecHitsMap_ == NULL || storedSubdetectorGeometry_ == NULL)
00039     throw(std::runtime_error("\n\nPositionCalc::Calculate_Location called uninitialized or wrong initialization.\n\n"));
00040 
00041   std::vector<DetId> validDetIds;
00042 
00043   // Check that DetIds are nonzero
00044   std::vector<DetId>::iterator n;
00045   for (n = passedDetIds.begin(); n != passedDetIds.end(); n++) {
00046     if (((*n) != DetId(0)) 
00047         && (storedRecHitsMap_->find(*n) != storedRecHitsMap_->end()))
00048       validDetIds.push_back(*n);
00049   }
00050 
00051   passedDetIds.clear();
00052   passedDetIds = validDetIds;
00053 
00054   // Figure out what the central crystal is and also calculate the 
00055   // total energy
00056 
00057   double eTot = 0;
00058 
00059   DetId maxId_ = (*(passedDetIds.begin()));
00060   EcalRecHitCollection::const_iterator itm = storedRecHitsMap_->find(maxId_);
00061 
00062   double eMax = itm->energy();
00063 
00064   DetId id_;
00065   double e_i = 0;
00066 
00067   std::vector<DetId>::iterator i;
00068   for (i = passedDetIds.begin(); i !=  passedDetIds.end(); i++) {
00069     id_ = (*i);
00070     EcalRecHitCollection::const_iterator itt = storedRecHitsMap_->find(id_);
00071 
00072     e_i = itt->energy();
00073     if (e_i > eMax) {
00074       eMax = e_i;
00075       maxId_ = id_;
00076     }
00077     
00078     eTot += e_i;
00079   }
00080   
00081   //Select the correct value of the T0 parameter depending on subdetector
00082   float T0;
00083   const CaloCellGeometry* center_cell = storedSubdetectorGeometry_->getGeometry(maxId_);
00084   GlobalPoint p = center_cell->getPosition();
00085   if (fabs(p.eta())<1.479) {
00086     //barrel
00087     T0 = param_T0_barl_;
00088   } else {
00089     DetId preshDet;
00090     if (storedESGeometry_) {
00091       preshDet = (dynamic_cast<const EcalPreshowerGeometry*>(storedESGeometry_))->getClosestCell(p);
00092     }
00093     if (preshDet.null()) {
00094       //endcap, not behind preshower
00095       T0 = param_T0_endc_;
00096     } else {
00097       //endcap, behind preshower
00098       T0 = param_T0_endcPresh_;
00099     }
00100   }
00101 
00102   // Calculate shower depth
00103   float depth = 0.;
00104   if(eTot<=0.) {
00105     LogDebug("NegativeClusterEnergy") << "cluster with negative energy: " << eTot
00106                                            << " setting depth to 0.";
00107   } else {
00108     depth = param_X0_ * (T0 + log(eTot));
00109   }
00110 
00111   // Get position of center cell from shower depth
00112   GlobalPoint center_pos = 
00113     (dynamic_cast<const TruncatedPyramid*>(center_cell))->getPosition(depth);
00114   
00115 
00116   // Loop over hits and get weights
00117   double weight = 0;
00118   double total_weight = 0;
00119 
00120   double center_phi = center_pos.phi();
00121   double center_theta = center_pos.theta();
00122 
00123   double delta_theta = 0;
00124   double delta_phi = 0;
00125 
00126   double dphi = 0;
00127 
00128   std::vector<DetId>::iterator j;
00129   for (j = passedDetIds.begin(); j != passedDetIds.end(); j++) {
00130     id_ = (*j);
00131     EcalRecHitCollection::const_iterator itj = storedRecHitsMap_->find(id_);
00132     double e_j = itj->energy();
00133 
00134     if (param_LogWeighted_) {
00135        if(eTot<=0.) {
00136          weight = 0.;
00137        } else {
00138          if (e_j > 0.)
00139            weight = std::max(0., param_W0_ + log( e_j/eTot) );
00140          else
00141            weight = 0.;
00142        }
00143     } else {
00144       weight = e_j/eTot;
00145     }
00146     
00147     total_weight += weight;
00148   
00149     const CaloCellGeometry* jth_cell = 
00150       storedSubdetectorGeometry_->getGeometry(id_);
00151     GlobalPoint jth_pos = 
00152       dynamic_cast<const TruncatedPyramid*>(jth_cell)->getPosition(depth);
00153 
00154     delta_theta += weight * (jth_pos.theta() - center_theta);
00155     dphi = (jth_pos.phi() - center_phi);
00156 
00157     // Check the 2*pi problem for delta_phi
00158     if (dphi > M_PI)
00159       dphi -= 2.*M_PI;
00160     if (dphi < -M_PI)
00161       dphi += 2.*M_PI;
00162 
00163     delta_phi += dphi*weight;    
00164   }
00165 
00166   delta_theta /= total_weight;
00167   delta_phi /= total_weight;
00168   
00169   double cluster_theta = center_theta + delta_theta;
00170   double cluster_phi = center_phi + delta_phi;
00171 
00172   // Check the 2*pi problem for cluster_phi
00173   if (cluster_phi > M_PI)
00174     cluster_phi -= 2.*M_PI;
00175   if (cluster_phi < -M_PI)
00176     cluster_phi += 2.*M_PI;
00177 
00178   double radius = sqrt(center_pos.x()*center_pos.x()
00179                        + center_pos.y()*center_pos.y()
00180                        + center_pos.z()*center_pos.z());
00181 
00182   double xpos = radius*cos(cluster_phi)*sin(cluster_theta);
00183   double ypos = radius*sin(cluster_phi)*sin(cluster_theta);
00184   double zpos = radius*cos(cluster_theta);
00185 
00186   return math::XYZPoint(xpos, ypos, zpos);
00187   
00188 }
00189 

Generated on Tue Jun 9 17:43:16 2009 for CMSSW by  doxygen 1.5.4