CMS 3D CMS Logo

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