CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DPGAnalysis/SiStripTools/src/EventShape.cc

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   // first fill the momentum tensor
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   // find the eigen values
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   // for more than 2 tracks
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             // make all four sign-combinations for i,j
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       // sum momenta of all particles and iterate
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     }  // of if Np > 2
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   // normalize thrust -division by total momentum-
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   // for more than 2 tracks
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             // make all four sign-combinations for i,j
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       // sum momenta of all particles and iterate
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     }  // of if Np > 2
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   // normalize thrust -division by total momentum-
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   // a critical check
00215   if(tracks.size()==0) return 0;
00216   
00217   // first fill the momentum tensor
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   // find the eigen values
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   // compute spericity
00239   float sph = ( 1.5*(1-eigenvaluess[2]));
00240   return sph;
00241 }
00242 
00243 float EventShape::aplanarity(const reco::TrackCollection& tracks)
00244 {
00245   // a critical check
00246   if (tracks.size()==0) return 0;
00247   // first fill the momentum tensor
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   // find the eigen values
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   // compute aplanarity
00269   return ( 1.5*eigenvaluess[0]);
00270 }
00271 
00272 float EventShape::planarity(const reco::TrackCollection& tracks)
00273 {
00274   // First a critical check
00275   if (tracks.size()==0) return 0;
00276   // first fill the momentum tensor
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   // find the eigen values
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   // compute planarity
00298   return (eigenvaluess[0]/eigenvaluess[1]);
00299 }
00300 
00301 float EventShape::sphericity() const
00302 {
00303   // compute sphericity
00304   return ( 1.5*(1-eigenvalues[2]));
00305 }
00306 
00307 float EventShape::aplanarity() const
00308 {
00309   // compute aplanarity
00310   return ( 1.5*eigenvalues[0]);
00311 }
00312 
00313 float EventShape::planarity() const
00314 {
00315   // compute planarity
00316   return (eigenvalues[0]/eigenvalues[1]);
00317 }