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