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