Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "DataFormats/ParticleFlowReco/interface/CaloEllipse.h"
00009
00010 #include <cmath>
00011
00012
00013 using namespace pftools;
00014
00015 CaloEllipse::CaloEllipse() {
00016
00017
00018 }
00019
00020 CaloEllipse::~CaloEllipse() {
00021
00022 }
00023 double CaloEllipse::getTheta() const {
00024 if (dataPoints_.size() < 2) {
00025 return 0.0;
00026 }
00027
00028 PointVector meanAdj;
00029
00030 Point mean = getPosition();
00031
00032 double sum_dxdx(0.0);
00033 double sum_dydy(0.0);
00034 double sum_dxdy(0.0);
00035 PointCit it = dataPoints_.begin();
00036 for (; it != dataPoints_.end(); ++it) {
00037 const Point& p = *it;
00038 Point q(p.first - mean.first, p.second - mean.second);
00039 meanAdj.push_back(q);
00040 sum_dxdx += q.first * q.first;
00041 sum_dydy += q.second * q.second;
00042 sum_dxdy += q.first * q.second;
00043 }
00044 double theta = 0.5 * atan(2.0 * sum_dxdy / (sum_dydy - sum_dxdx));
00045 return theta;
00046 }
00047
00048 Point CaloEllipse::getMajorMinorAxes(double sigma) const {
00049
00050 if (dataPoints_.size() < 2) {
00051 return Point(0, 0);
00052 }
00053
00054 Point mean = getPosition();
00055
00056 PointCit it = dataPoints_.begin();
00057 double sum_xx(0.0);
00058 double sum_yy(0.0);
00059 double theta = getTheta();
00060
00061 for (; it != dataPoints_.end(); ++it) {
00062 const Point& p = *it;
00063 double X = cos(theta) * (p.first - mean.first) - sin(theta) * (p.second
00064 - mean.second);
00065 double Y = sin(theta) * (p.first - mean.first) + cos(theta) * (p.second
00066 - mean.second);
00067 sum_xx += X * X;
00068 sum_yy += Y * Y;
00069 }
00070
00071 double a = sigma * sqrt(sum_xx / dataPoints_.size());
00072 double b = sigma * sqrt(sum_yy / dataPoints_.size());
00073
00074 double major, minor;
00075
00076 if(a > b) {
00077 major = a;
00078 minor = b;
00079 } else {
00080 major = b;
00081 minor = a;
00082 }
00083
00084 return Point(major, minor);
00085 }
00086
00087 double CaloEllipse::getEccentricity() const {
00088 Point p = getMajorMinorAxes();
00089 double a = p.first;
00090 double b = p.second;
00091 if(a == 0)
00092 return 0;
00093 double ecc = sqrt((a * a - b * b) / (a * a));
00094 return ecc;
00095 }
00096
00097 Point CaloEllipse::getPosition() const {
00098
00099 if (dataPoints_.size() < 1) {
00100 return Point(0, 0);
00101 }
00102
00103 double x_tot(0.0);
00104 double y_tot(0.0);
00105 PointCit it = dataPoints_.begin();
00106 for (; it != dataPoints_.end(); ++it) {
00107 const Point& p = *it;
00108 x_tot += p.first;
00109 y_tot += p.second;
00110
00111 }
00112
00113 return Point(x_tot / dataPoints_.size(), y_tot / dataPoints_.size());
00114 }
00115
00116 void CaloEllipse::resetCaches() {
00117 cachedTheta_ = 0.0;
00118 cachedMinor_ = 0.0;
00119 cachedMajor_ = 0.0;
00120
00121 }
00122
00123 void CaloEllipse::makeCaches() {
00124 cachedTheta_ = getTheta();
00125 Point axes = getMajorMinorAxes();
00126 cachedMajor_ = axes.first;
00127 cachedMinor_ = axes.second;
00128 }
00129
00130 void CaloEllipse::reset() {
00131 dataPoints_.clear();
00132 resetCaches();
00133 }
00134
00135 std::ostream& pftools::operator<<(std::ostream& s, const pftools::CaloEllipse& em) {
00136 s << "CaloEllipse at position = " << toString(em.getPosition()) << ", theta = "
00137 << em.getTheta() << ", major/minor axes = " << toString(
00138 em.getMajorMinorAxes()) << ", eccentricity = " << em.getEccentricity() << "\n";
00139
00140 return s;
00141 }
00142