Go to the documentation of this file.00001 #include "DPGAnalysis/SiStripTools/interface/EventShape.h"
00002 #include <DataFormats/TrackReco/interface/Track.h>
00003 #include <TVector3.h>
00004 #include <vector>
00005 #include <TMatrixDSym.h>
00006 #include <TMatrixDSymEigen.h>
00007 #include <TVectorD.h>
00008
00009 using namespace edm;
00010 using namespace reco;
00011 using namespace std;
00012 using reco::TrackCollection;
00013
00014 EventShape::EventShape(reco::TrackCollection& tracks):eigenvalues(3)
00015 {
00016 math::XYZTLorentzVectorF output = math::XYZTLorentzVectorF(0,0,0,0);
00017 for(reco::TrackCollection::const_iterator itTrack = tracks.begin(); itTrack<tracks.end(); ++itTrack) {
00018 p.push_back(TVector3(itTrack->px(),itTrack->py(),itTrack->pz()));
00019 }
00020
00021
00022 TMatrixDSym MomentumTensor(3);
00023 for(std::vector<TVector3>::const_iterator momentum = p.begin();momentum<p.end();++momentum) {
00024 for(unsigned int i=0;i<3;i++)
00025 for(unsigned int j=0;j<=i;j++) {
00026 MomentumTensor[i][j] += momentum[i]*momentum[j];
00027 }
00028 }
00029 MomentumTensor*=1/(MomentumTensor[0][0]+MomentumTensor[1][1]+MomentumTensor[2][2]);
00030
00031 TMatrixDSymEigen eigen(MomentumTensor);
00032 TVectorD eigenvals = eigen.GetEigenValues();
00033 eigenvalues[0] = eigenvals[0];
00034 eigenvalues[1] = eigenvals[1];
00035 eigenvalues[2] = eigenvals[2];
00036 sort(eigenvalues.begin(),eigenvalues.end());
00037 }
00038
00039 math::XYZTLorentzVectorF EventShape::thrust() const
00040 {
00041 math::XYZTLorentzVectorF output = math::XYZTLorentzVectorF(0,0,0,0);
00042 TVector3 qtbo;
00043 TVector3 zero(0.,0.,0.);
00044 float vnew = 0.;
00045 uint32_t Np = p.size();
00046
00047
00048 if (Np > 2) {
00049 float vmax = 0.;
00050 TVector3 vn, vm, vc, vl;
00051 for(unsigned int i=0; i< Np-1; i++)
00052 for(unsigned int j=i+1; j < Np; j++) {
00053 vc = p[i].Cross(p[j]);
00054 vl = zero;
00055 for(unsigned int k=0; k<Np; k++)
00056 if ((k != i) && (k != j)) {
00057 if (p[k].Dot(vc) >= 0.) vl = vl + p[k];
00058 else vl = vl - p[k];
00059 }
00060
00061 vn = vl + p[j] + p[i];
00062 vnew = vn.Mag2();
00063 if (vnew > vmax) {
00064 vmax = vnew;
00065 vm = vn;
00066 }
00067 vn = vl + p[j] - p[i];
00068 vnew = vn.Mag2();
00069 if (vnew > vmax) {
00070 vmax = vnew;
00071 vm = vn;
00072 }
00073 vn = vl - p[j] + p[i];
00074 vnew = vn.Mag2();
00075 if (vnew > vmax) {
00076 vmax = vnew;
00077 vm = vn;
00078 }
00079 vn = vl - p[j] - p[i];
00080 vnew = vn.Mag2();
00081 if (vnew > vmax) {
00082 vmax = vnew;
00083 vm = vn;
00084 }
00085 }
00086
00087 for(int iter=1; iter<=4; iter++) {
00088 qtbo = zero;
00089 for(unsigned int i=0; i< Np; i++)
00090 if (vm.Dot(p[i]) >= 0.)
00091 qtbo = qtbo + p[i];
00092 else
00093 qtbo = qtbo - p[i];
00094 vnew = qtbo.Mag2();
00095 if (vnew == vmax) break;
00096 vmax = vnew;
00097 vm = qtbo;
00098 }
00099 }
00100 else
00101 if (Np == 2)
00102 if (p[0].Dot(p[1]) >= 0.)
00103 qtbo = p[0] + p[1];
00104 else
00105 qtbo = p[0] - p[1];
00106 else if (Np == 1)
00107 qtbo = p[0];
00108 else {
00109 qtbo = zero;
00110 return output;
00111 }
00112
00113 float vsum = 0.;
00114 for(unsigned int i=0; i < Np; i++) vsum = vsum + p[i].Mag();
00115 vnew = qtbo.Mag();
00116 float v = vnew/vsum;
00117 float x = qtbo.X()/vnew;
00118 float y = qtbo.Y()/vnew;
00119 float z = qtbo.Z()/vnew;
00120 output.SetPxPyPzE(x, y, z, v);
00121 return output;
00122 }
00123
00124 math::XYZTLorentzVectorF EventShape::thrust(const reco::TrackCollection& tracks)
00125 {
00126 std::vector<TVector3> pp;
00127 uint32_t Np = tracks.size();
00128 math::XYZTLorentzVectorF output = math::XYZTLorentzVectorF(0,0,0,0);
00129 for(reco::TrackCollection::const_iterator itTrack = tracks.begin(); itTrack<tracks.end(); ++itTrack) {
00130 pp.push_back(TVector3(itTrack->px(),itTrack->py(),itTrack->pz()));
00131 }
00132 TVector3 qtbo;
00133 TVector3 zero(0.,0.,0.);
00134 float vnew = 0.;
00135
00136
00137 if (Np > 2) {
00138 float vmax = 0.;
00139 TVector3 vn, vm, vc, vl;
00140 for(unsigned int i=0; i< Np-1; i++)
00141 for(unsigned int j=i+1; j < Np; j++) {
00142 vc = pp[i].Cross(pp[j]);
00143 vl = zero;
00144 for(unsigned int k=0; k<Np; k++)
00145 if ((k != i) && (k != j)) {
00146 if (pp[k].Dot(vc) >= 0.) vl = vl + pp[k];
00147 else vl = vl - pp[k];
00148 }
00149
00150 vn = vl + pp[j] + pp[i];
00151 vnew = vn.Mag2();
00152 if (vnew > vmax) {
00153 vmax = vnew;
00154 vm = vn;
00155 }
00156 vn = vl + pp[j] - pp[i];
00157 vnew = vn.Mag2();
00158 if (vnew > vmax) {
00159 vmax = vnew;
00160 vm = vn;
00161 }
00162 vn = vl - pp[j] + pp[i];
00163 vnew = vn.Mag2();
00164 if (vnew > vmax) {
00165 vmax = vnew;
00166 vm = vn;
00167 }
00168 vn = vl - pp[j] - pp[i];
00169 vnew = vn.Mag2();
00170 if (vnew > vmax) {
00171 vmax = vnew;
00172 vm = vn;
00173 }
00174 }
00175
00176 for(int iter=1; iter<=4; iter++) {
00177 qtbo = zero;
00178 for(unsigned int i=0; i< Np; i++)
00179 if (vm.Dot(pp[i]) >= 0.)
00180 qtbo = qtbo + pp[i];
00181 else
00182 qtbo = qtbo - pp[i];
00183 vnew = qtbo.Mag2();
00184 if (vnew == vmax) break;
00185 vmax = vnew;
00186 vm = qtbo;
00187 }
00188 }
00189 else
00190 if (Np == 2)
00191 if (pp[0].Dot(pp[1]) >= 0.)
00192 qtbo = pp[0] + pp[1];
00193 else
00194 qtbo = pp[0] - pp[1];
00195 else if (Np == 1)
00196 qtbo = pp[0];
00197 else {
00198 qtbo = zero;
00199 return output;
00200 }
00201
00202 float vsum = 0.;
00203 for(unsigned int i=0; i < Np; i++) vsum = vsum + pp[i].Mag();
00204 vnew = qtbo.Mag();
00205 float v = vnew/vsum;
00206 float x = qtbo.X()/vnew;
00207 float y = qtbo.Y()/vnew;
00208 float z = qtbo.Z()/vnew;
00209 output.SetPxPyPzE(x, y, z, v);
00210 return output;
00211 }
00212
00213 float EventShape::sphericity(const reco::TrackCollection& tracks)
00214 {
00215
00216 if(tracks.size()==0) return 0;
00217
00218
00219 TMatrixDSym MomentumTensor(3);
00220 for(reco::TrackCollection::const_iterator itTrack = tracks.begin(); itTrack<tracks.end(); ++itTrack) {
00221 std::vector<double> momentum(3);
00222 momentum[0] = itTrack->px();
00223 momentum[1] = itTrack->py();
00224 momentum[2] = itTrack->pz();
00225 for(unsigned int i=0;i<3;i++)
00226 for(unsigned int j=0;j<=i;j++) {
00227 MomentumTensor[i][j] += momentum[i]*momentum[j];
00228 }
00229 }
00230 MomentumTensor*=1/(MomentumTensor[0][0]+MomentumTensor[1][1]+MomentumTensor[2][2]);
00231
00232 TMatrixDSymEigen eigen(MomentumTensor);
00233 TVectorD eigenvals = eigen.GetEigenValues();
00234 vector<float> eigenvaluess(3);
00235 eigenvaluess[0] = eigenvals[0];
00236 eigenvaluess[1] = eigenvals[1];
00237 eigenvaluess[2] = eigenvals[2];
00238 sort(eigenvaluess.begin(),eigenvaluess.end());
00239
00240 float sph = ( 1.5*(1-eigenvaluess[2]));
00241 return sph;
00242 }
00243
00244 float EventShape::aplanarity(const reco::TrackCollection& tracks)
00245 {
00246
00247 if (tracks.size()==0) return 0;
00248
00249 TMatrixDSym MomentumTensor(3);
00250 for(reco::TrackCollection::const_iterator itTrack = tracks.begin(); itTrack<tracks.end(); ++itTrack) {
00251 std::vector<double> momentum(3);
00252 momentum[0] = itTrack->px();
00253 momentum[1] = itTrack->py();
00254 momentum[2] = itTrack->pz();
00255 for(unsigned int i=0;i<3;i++)
00256 for(unsigned int j=0;j<=i;j++) {
00257 MomentumTensor[i][j] += momentum[i]*momentum[j];
00258 }
00259 }
00260 MomentumTensor*=1/(MomentumTensor[0][0]+MomentumTensor[1][1]+MomentumTensor[2][2]);
00261
00262 TMatrixDSymEigen eigen(MomentumTensor);
00263 TVectorD eigenvals = eigen.GetEigenValues();
00264 vector<float> eigenvaluess(3);
00265 eigenvaluess[0] = eigenvals[0];
00266 eigenvaluess[1] = eigenvals[1];
00267 eigenvaluess[2] = eigenvals[2];
00268 sort(eigenvaluess.begin(),eigenvaluess.end());
00269
00270 return ( 1.5*eigenvaluess[0]);
00271 }
00272
00273 float EventShape::planarity(const reco::TrackCollection& tracks)
00274 {
00275
00276 if (tracks.size()==0) return 0;
00277
00278 TMatrixDSym MomentumTensor(3);
00279 for(reco::TrackCollection::const_iterator itTrack = tracks.begin(); itTrack<tracks.end(); ++itTrack) {
00280 std::vector<double> momentum(3);
00281 momentum[0] = itTrack->px();
00282 momentum[1] = itTrack->py();
00283 momentum[2] = itTrack->pz();
00284 for(unsigned int i=0;i<3;i++)
00285 for(unsigned int j=0;j<=i;j++) {
00286 MomentumTensor[i][j] += momentum[i]*momentum[j];
00287 }
00288 }
00289 MomentumTensor*=1/(MomentumTensor[0][0]+MomentumTensor[1][1]+MomentumTensor[2][2]);
00290
00291 TMatrixDSymEigen eigen(MomentumTensor);
00292 TVectorD eigenvals = eigen.GetEigenValues();
00293 vector<float> eigenvaluess(3);
00294 eigenvaluess[0] = eigenvals[0];
00295 eigenvaluess[1] = eigenvals[1];
00296 eigenvaluess[2] = eigenvals[2];
00297 sort(eigenvaluess.begin(),eigenvaluess.end());
00298
00299 return (eigenvaluess[0]/eigenvaluess[1]);
00300 }
00301
00302 float EventShape::sphericity() const
00303 {
00304
00305 return ( 1.5*(1-eigenvalues[2]));
00306 }
00307
00308 float EventShape::aplanarity() const
00309 {
00310
00311 return ( 1.5*eigenvalues[0]);
00312 }
00313
00314 float EventShape::planarity() const
00315 {
00316
00317 return (eigenvalues[0]/eigenvalues[1]);
00318 }