00001 #include <vector>
00002 #include <cmath>
00003
00004 #include "TVectorD.h"
00005 #include "TMatrixD.h"
00006 #include "TMatrixDSym.h"
00007 #include "TMatrixDSymEigen.h"
00008
00009 #include "MessageService/MsgService.h"
00010
00011 #include "MOISolution.h"
00012
00013 const float C45 = sqrt(2.) / 2.;
00014
00015 CVSID("$Id: MOISolution.cxx,v 1.2 2007/02/04 06:16:55 rhatcher Exp $");
00016
00017 MOISolution::MOISolution() {
00018 fWF = 1.0;
00019 Zero();
00020 }
00021
00022 MOISolution::MOISolution(const vector<double> &X, const vector<double> &Y,
00023 const vector<double> &E, double WF) {
00024 fWF = WF;
00025 Fill(X, Y, E);
00026 }
00027
00028 MOISolution::MOISolution(const vector<double> &X, const vector<double> &Y,
00029 const vector<double> &Z, const vector<double> &E,
00030 double WF) {
00031 fWF = WF;
00032 Fill(X, Y, Z, E);
00033 }
00034
00035 void MOISolution::Zero() {
00036 EigenValues.clear();
00037 EigenVectors.clear();
00038 }
00039
00040 void MOISolution::Fill(const vector<double> &X, const vector<double> &Y,
00041 const vector<double> &E) {
00042 Zero();
00043
00044 if (X.size() != Y.size() || X.size() != E.size() ||
00045 X.size() == 0) {
00046 MSG("MOI",Msg::kWarning) << "Mismatch size of vectors input to MOISolution" << endl;
00047 return;
00048 }
00049 const unsigned int NPoints = X.size();
00050 MSG("MOI",Msg::kVerbose) << "MOISolution::Fill 2D for " << NPoints << " points" << endl;
00051
00052 double Cent[2] = {0.};
00053
00054 double ESum = 0.;
00055 double Ethis = 0.;
00056 for (unsigned int i=0; i<NPoints; i++) {
00057 Ethis = pow(E[i],fWF);
00058 ESum += Ethis;
00059
00060 Cent[0] += X[i] * Ethis;
00061 Cent[1] += Y[i] * Ethis;
00062 }
00063 if(ESum == 0.) return;
00064 Cent[0] /= ESum;
00065 Cent[1] /= ESum;
00066
00067 TMatrixDSym Moi(2); Moi.Zero();
00068 double Xthis, Ythis;
00069 for (unsigned int i=0; i<NPoints; i++) {
00070 Xthis = X[i] - Cent[0];
00071 Ythis = Y[i] - Cent[1];
00072
00073 double Ethis = pow(E[i],fWF);
00074
00075 Moi(0,0) += Ethis*(Ythis*Ythis);
00076 Moi(1,1) += Ethis*(Xthis*Xthis);
00077 Moi(0,1) += -1. * Ethis * Xthis * Ythis;
00078 }
00079 Moi(1,0)=Moi(0,1);
00080 Moi *= (1./ESum);
00081
00082
00083 TMatrixDSymEigen Eigen(Moi);
00084 TMatrixD EVec = Eigen.GetEigenVectors();
00085 TVectorD EVal = Eigen.GetEigenValues();
00086
00087
00088 int sorted[2] = {0,1};
00089 if (EVal(0)>=EVal(1)) {
00090 sorted[0] = 1; sorted[1] = 0;
00091 }
00092
00093 for (int i=0;i<2;i++) {
00094 EigenValues.push_back(EVal(sorted[i]));
00095 vector<double> V;
00096 for(int j=0;j<2;j++) V.push_back(EVec(j,sorted[i]));
00097 EigenVectors.push_back(V);
00098 }
00099 }
00100
00101
00102 void MOISolution::Fill(const vector<double> &X, const vector<double> &Y,
00103 const vector<double> &Z, const vector<double> &E) {
00104 Zero();
00105 if (X.size() != Y.size() || X.size() != Z.size() ||
00106 X.size() != E.size() || X.size() == 0) {
00107 MSG("MOI",Msg::kWarning) << "Mismatch size of vectors input to MOISolution" << endl;
00108 return;
00109 }
00110 const unsigned int NPoints = X.size();
00111 MSG("MOI",Msg::kVerbose) << "MOISolution::Fill 3D for " << NPoints << " points" << endl;
00112
00113 double Cent[3] = {0.};
00114
00115 double ESum = 0.;
00116 double Ethis = 0.;
00117 for (unsigned int i=0; i<NPoints; i++) {
00118 Ethis = pow(E[i],fWF);
00119 ESum += Ethis;
00120
00121 Cent[0] += X[i] * Ethis;
00122 Cent[1] += Y[i] * Ethis;
00123 Cent[2] += Z[i] * Ethis;
00124 }
00125 if(ESum == 0.) return;
00126 Cent[0] /= ESum;
00127 Cent[1] /= ESum;
00128 Cent[2] /= ESum;
00129
00130 TMatrixDSym Moi(3); Moi.Zero();
00131 double Xthis, Ythis, Zthis;
00132 for (unsigned int i=0; i<NPoints; i++) {
00133
00134 Xthis = X[i] - Cent[0];
00135 Ythis = Y[i] - Cent[1];
00136 Zthis = Z[i] - Cent[2];
00137
00138 double Ethis = pow(E[i],fWF);
00139
00140 Moi(0,0) += Ethis*(Ythis*Ythis+Zthis*Zthis);
00141 Moi(1,1) += Ethis*(Xthis*Xthis+Zthis*Zthis);
00142 Moi(2,2) += Ethis*(Xthis*Xthis+Ythis*Ythis);
00143 Moi(0,1) += -1. * Ethis * Xthis * Ythis;
00144 Moi(0,2) += -1. * Ethis * Xthis * Zthis;
00145 Moi(1,2) += -1. * Ethis * Ythis * Zthis;
00146 }
00147 Moi(2,0)=Moi(0,2); Moi(1,0)=Moi(0,1); Moi(2,1)=Moi(1,2);
00148 Moi *= (1./ESum);
00149
00150
00151 TMatrixDSymEigen Eigen(Moi);
00152 TMatrixD EVec = Eigen.GetEigenVectors();
00153 TVectorD EVal = Eigen.GetEigenValues();
00154
00155
00156 int sorted[3] = {0,1,2};
00157 if (EVal(0)<=EVal(1) && EVal(0)<=EVal(2)) {
00158 sorted[0] = 0;
00159 if(EVal(1)<EVal(2)) {sorted[1]=1; sorted[2]=2;}
00160 else {sorted[1]=2; sorted[2]=1;}
00161 }
00162 else
00163 if (EVal(1)<=EVal(0) && EVal(1)<=EVal(2)) {
00164 sorted[0] = 1;
00165 if(EVal(0)<EVal(2)) {sorted[1]=0; sorted[2]=2;}
00166 else {sorted[1]=2; sorted[2]=0;}
00167 }
00168 else
00169 if (EVal(2)<=EVal(0) && EVal(2)<=EVal(1)) {
00170 sorted[0] = 2;
00171 if(EVal(0)<EVal(1)) {sorted[1]=0; sorted[2]=1;}
00172 else {sorted[1]=1; sorted[2]=0;}
00173 }
00174
00175 for (int i=0;i<3;i++) {
00176 EigenValues.push_back(EVal(sorted[i]));
00177 vector<double> V;
00178 for(int j=0;j<3;j++) V.push_back(EVec(j,sorted[i]));
00179 EigenVectors.push_back(V);
00180 }
00181 }