CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoVertex/KinematicFit/interface/ConstrainedTreeBuilderT.h

Go to the documentation of this file.
00001 #ifndef ConstrainedTreeBuilderT_H
00002 #define ConstrainedTreeBuilderT_H
00003 
00004 #include "RecoVertex/KinematicFitPrimitives/interface/RefCountedKinematicTree.h"
00005 #include "RecoVertex/KinematicFitPrimitives/interface/VirtualKinematicParticleFactory.h"
00006 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicVertexFactory.h"
00007 
00015 class ConstrainedTreeBuilderT
00016 {
00017 
00018 public:
00019 
00020   ConstrainedTreeBuilderT(){}
00021  
00022   ~ConstrainedTreeBuilderT(){}
00023 
00029   template<int nTrk>
00030   RefCountedKinematicTree 
00031   buildTree(const std::vector<RefCountedKinematicParticle> & initialParticles, 
00032             const std::vector<KinematicState> & finalStates,
00033             const RefCountedKinematicVertex vtx, 
00034             const ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> >& fCov) const;
00035 
00036 private:
00037 
00038   RefCountedKinematicTree buildRealTree(const RefCountedKinematicParticle virtualParticle, 
00039         const RefCountedKinematicVertex vtx, const std::vector<RefCountedKinematicParticle> & particles) const;
00040 
00044   template<int nTrk>
00045   static AlgebraicSymMatrix77 
00046   covarianceMatrix(const std::vector<RefCountedKinematicParticle> &rPart, 
00047                    const AlgebraicVector7& newPar,
00048                    const ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> >& fitCov);
00049                                        
00050  VirtualKinematicParticleFactory pFactory;                                     
00051  KinematicVertexFactory vFactory;
00052 };
00053 
00054 
00055 #include "DataFormats/CLHEP/interface/Migration.h"
00056 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00057 
00058 template<int nTrk>
00059 RefCountedKinematicTree 
00060 ConstrainedTreeBuilderT::buildTree(const std::vector<RefCountedKinematicParticle> & initialParticles, 
00061                                    const std::vector<KinematicState> & finalStates,
00062                                    const RefCountedKinematicVertex vertex, 
00063                                    const ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> >& fullCov) const
00064 {
00065   if (!vertex->vertexIsValid()) {
00066        LogDebug("RecoVertex/ConstrainedTreeBuilder")
00067         << "Vertex is invalid\n";
00068        return ReferenceCountingPointer<KinematicTree>(new KinematicTree());
00069   }
00070   AlgebraicVector3 vtx;
00071   vtx(0) = vertex->position().x();
00072   vtx(1) = vertex->position().y();
00073   vtx(2) = vertex->position().z();
00074   AlgebraicMatrix33 vertexCov = fullCov.template Sub<ROOT::Math::SMatrix<double, 3> >(0,0);
00075 
00076 // cout << fullCov<<endl;
00077 //  cout << "RecoVertex/ConstrainedTreeBuilder"<<vtx<<endl;
00078 
00079  double ent = 0.;
00080  int charge = 0;
00081   AlgebraicVector7 virtualPartPar;
00082   virtualPartPar(0) = vertex->position().x();
00083   virtualPartPar(1) = vertex->position().y();
00084   virtualPartPar(2) = vertex->position().z();
00085 
00086 //making refitted particles out of refitted states.
00087 //none of the operations above violates the order of particles
00088 
00089   ROOT::Math::SMatrix<double,7,7,ROOT::Math::MatRepStd<double,7,7> >  aMatrix;
00090   ROOT::Math::SMatrix<double,7,7,ROOT::Math::MatRepStd<double,7,7> >  aMatrixT;
00091   aMatrix(3,3) =  aMatrixT(3,3) = 1;
00092   aMatrix(4,4) =  aMatrixT(4,4)  = 1;
00093   aMatrix(5,5) =  aMatrixT(5,5)  = 1;
00094   aMatrix(6,6) =  aMatrixT(6,6)  = 1;
00095   ROOT::Math::SMatrix<double,7,3,ROOT::Math::MatRepStd<double,7,3> > bMatrix;
00096   ROOT::Math::SMatrix<double,3,7,ROOT::Math::MatRepStd<double,3,7> > bMatrixT;
00097   bMatrix(0,0) =  bMatrixT(0,0) = 1;
00098   bMatrix(1,1) =  bMatrixT(1,1) = 1;
00099   bMatrix(2,2) =  bMatrixT(2,2) = 1;
00100   AlgebraicSymMatrix77 trackParCov;
00101   ROOT::Math::SMatrix<double,3,7,ROOT::Math::MatRepStd<double,3,7> > vtxTrackCov;
00102   AlgebraicSymMatrix77 nCovariance;
00103   // AlgebraicSymMatrix77 tmp;
00104 
00105   std::vector<RefCountedKinematicParticle>::const_iterator i = initialParticles.begin();
00106   std::vector<KinematicState>::const_iterator iStates = finalStates.begin();
00107   std::vector<RefCountedKinematicParticle> rParticles;
00108   int n=0;
00109   // assert(initialParticles.size()==nTrk);
00110   for( ; i != initialParticles.end(), iStates != finalStates.end(); ++i,++iStates)
00111   {
00112     AlgebraicVector7 p = iStates->kinematicParameters().vector();
00113     double a = - iStates->particleCharge() *
00114         iStates->magneticField()->inInverseGeV(iStates->globalPosition()).z();
00115 
00116     aMatrix(4,0) = aMatrixT(0,4) = -a;
00117     aMatrix(3,1) = aMatrixT(1,3) =  a;
00118     bMatrix(4,0) = bMatrixT(0,4) =  a;
00119     bMatrix(3,1) = bMatrixT(1,3) = -a;
00120 
00121     AlgebraicVector7 par = aMatrix*p + bMatrix * vtx;
00122 
00123     trackParCov = fullCov.template Sub<AlgebraicSymMatrix77>(3+n*7,3+n*7);
00124     vtxTrackCov = fullCov.template Sub<ROOT::Math::SMatrix<double, 3, 7> >(0,3+n*7);
00125     ROOT::Math::AssignSym::Evaluate(nCovariance,
00126                                     aMatrix * trackParCov * aMatrixT
00127                                     + aMatrix * ROOT::Math::Transpose(vtxTrackCov) * bMatrixT
00128                                     + bMatrix * vtxTrackCov * aMatrixT 
00129                                     + bMatrix * vertexCov * bMatrixT
00130                                     );
00131     /*
00132     ROOT::Math::AssignSym::Evaluate(tmp, aMatrix * ROOT::Math::Transpose(vtxTrackCov) * bMatrixT);
00133     nCovariance+=tmp;
00134     ROOT::Math::AssignSym::Evaluate(tmp, bMatrix * vtxTrackCov * aMatrixT);
00135     nCovariance+=tmp;
00136     ROOT::Math::AssignSym::Evaluate(tmp, bMatrix * vertexCov * bMatrixT);
00137     nCovariance+=tmp;
00138     */
00139 
00140     KinematicState stateAtVertex(KinematicParameters(par),
00141                                  KinematicParametersError(nCovariance),
00142                                  iStates->particleCharge(), iStates->magneticField());
00143     rParticles.push_back((*i)->refittedParticle(stateAtVertex, vertex->chiSquared(), vertex->degreesOfFreedom()));
00144     
00145     virtualPartPar(3) += par(3);
00146     virtualPartPar(4) += par(4);
00147     virtualPartPar(5) += par(5);
00148     ent += sqrt(par(6)*par(6) +  par(3)*par(3)+par(4)*par(4)+par(5)*par(5) );
00149     charge += iStates->particleCharge();
00150 
00151     ++n;
00152 
00153   }
00154 
00155  //total reconstructed mass
00156   double differ = ent*ent - (virtualPartPar(3)*virtualPartPar(3) + virtualPartPar(5)*virtualPartPar(5) + virtualPartPar(4)*virtualPartPar(4));
00157   if(differ>0.) {
00158     virtualPartPar(6) = sqrt(differ);
00159   } else {
00160    LogDebug("ConstrainedTreeBuilder")
00161         << "Fit failed: Current precision does not allow to calculate the mass\n";
00162    return ReferenceCountingPointer<KinematicTree>(new KinematicTree());
00163   }
00164 
00165  // covariance matrix:
00166 
00167   AlgebraicSymMatrix77 cov = this->covarianceMatrix<nTrk>(rParticles,virtualPartPar,fullCov);
00168 
00169   KinematicState nState(KinematicParameters(virtualPartPar),
00170                         KinematicParametersError(cov),
00171                         charge, initialParticles[0]->magneticField());
00172 
00173  //newborn kinematic particle
00174   float chi2 = vertex->chiSquared();
00175   float ndf = vertex->degreesOfFreedom();
00176   KinematicParticle * zp = 0;
00177   RefCountedKinematicParticle virtualParticle = pFactory.particle(nState,chi2,ndf,zp);
00178 
00179   return buildRealTree(virtualParticle, vertex, rParticles);
00180 }
00181 
00182 template<int nTrk>
00183 AlgebraicSymMatrix77 
00184 ConstrainedTreeBuilderT::covarianceMatrix(const std::vector<RefCountedKinematicParticle> &rPart, 
00185                                           const AlgebraicVector7& newPar,
00186                                           const ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> >& fitCov)
00187  {
00188 
00189    typedef ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> > FitCov;
00190   //constructing the full matrix using the simple fact
00191   //that we have never broken the order of tracks
00192   // during our fit.
00193   
00194   int size = nTrk;  
00195 
00196   if ( int(rPart.size())!=size) throw "error in ConstrainedTreeBuilderT ";
00197 
00198   //global propagation to the vertex position
00199   //Jacobian is done for all the parameters together
00200   ROOT::Math::SMatrix<double,3+7*nTrk> jac;
00201   jac(0,0) = 1;
00202   jac(1,1) = 1;
00203   jac(2,2) = 1;
00204   ROOT::Math::SMatrix<double,3,7> upper;
00205   ROOT::Math::SMatrix<double,7>  diagonal;
00206   for(  int i_int=0; i_int!=size; ++i_int) {
00207     RefCountedKinematicParticle const & i = rPart[i_int];   
00208     //vertex position related components of the matrix
00209     double a_i = - (i)->currentState().particleCharge() *
00210       (i)->magneticField()->inInverseGeV((i)->currentState().globalPosition()).z();
00211     upper(0,0) = 1;
00212     upper(1,1) = 1;
00213     upper(2,2) = 1;
00214     upper(1,3) = -a_i;
00215     upper(0,4) = a_i;
00216     jac.Place_at(upper,0,3+i_int*7);
00217     
00218     diagonal(3,3) = 1;
00219     diagonal(4,4) = 1;
00220     diagonal(5,5) = 1;
00221     diagonal(6,6) = 1;
00222     diagonal(1,3) = a_i;
00223     diagonal(0,4) = -a_i;
00224     jac.Place_at(diagonal,3+i_int*7,3+i_int*7);
00225   }
00226   
00227   // jacobian is constructed in such a way, that
00228   // right operation for transformation will be
00229   // fitCov.similarityT(jac)
00230   // WARNING: normal similarity operation is
00231   // not valid in this case
00232   //now making reduced matrix:
00233   // int vSize = rPart.size();
00234   FitCov const & fit_cov_sym = fitCov;
00235   /*
00236     for(int i = 0; i<7*vSize+3; ++i)
00237     {
00238     for(int j = 0; j<7*vSize+3; ++j)
00239     {if(i<=j) fit_cov_sym(i,j) = fitCov(i,j);}
00240     }
00241   */
00242   
00243   ROOT::Math::SMatrix<double,4*nTrk+3,4*nTrk+3, ROOT::Math::MatRepSym<double,4*nTrk+3> > reduced;
00244   FitCov transform=ROOT::Math::SimilarityT(jac,fit_cov_sym); // similarityT???
00245   
00246   //jacobian to add matrix components
00247   ROOT::Math::SMatrix<double,7,4*nTrk+3> jac_t;
00248   jac_t(0,0) = 1.;
00249   jac_t(1,1) = 1.;
00250   jac_t(2,2) = 1.;
00251   
00252 
00253   
00254   double energy_global = sqrt(newPar(3)*newPar(3)+newPar(4)*newPar(4) + newPar(5)*newPar(5)+newPar(6)*newPar(6));
00255   for(int il_int = 0; il_int!=size; ++il_int) {
00256     RefCountedKinematicParticle const & rs = rPart[il_int];
00257     //jacobian components:
00258     int off1=3; int off2=il_int*4+3;
00259     jac_t(off1+0,off2+0) = 1.;
00260     jac_t(off1+1,off2+1) = 1.;
00261     jac_t(off1+2,off2+2) = 1.;
00262     
00263     //non-trival elements: mass correlations:
00264     AlgebraicVector7 l_Par = (rs)->currentState().kinematicParameters().vector();
00265     double energy_local  = sqrt(l_Par(6)*l_Par(6) + l_Par(3)*l_Par(3) + l_Par(4)*l_Par(4) + l_Par(5)*l_Par(5));
00266     jac_t(off1+3,off2+3) = energy_global*l_Par(6)/(newPar(6)*energy_local);
00267     jac_t(off1+3,off2+0) = ((energy_global*l_Par(3)/energy_local) - newPar(3))/newPar(6);
00268     jac_t(off1+3,off2+1) = ((energy_global*l_Par(4)/energy_local) - newPar(4))/newPar(6);
00269     jac_t(off1+3,off2+2) = ((energy_global*l_Par(5)/energy_local) - newPar(5))/newPar(6);
00270   }
00271 
00272   for(int i = 0; i<7;++i)
00273     for(int j =0; j<7; ++j)
00274       reduced(i,j)  = transform(i+3, j+3);
00275 
00276   for(int i = 1; i<size; i++) {
00277     //non-trival elements: mass correlations:
00278     //upper row and right column
00279 
00280     int off1=0;
00281     int off2=3+4*i;
00282     for(int l1 = 0; l1<3;++l1) 
00283       for(int l2 = 0; l2<4;++l2)
00284         reduced(off1+l1,off2+l2) = transform(3+l1,6+7*i +l2);
00285 
00286     //diagonal elements
00287     off1=off2=3+4*i;
00288     for(int l1 = 0; l1<4;++l1)
00289       for(int l2 = 0; l2<4;++l2)
00290         reduced(off1+l1,off2+l2) = transform(6+7*i+l1, 6+7*i+l2);
00291 
00292      //off diagonal elements
00293    for(int j = 1; j<size; j++) {
00294       off1 =  3+4*(i-1); off2=3+4*j;
00295       for(int l1 = 0; l1<4;++l1)
00296         for(int l2 = 0; l2<4;++l2)
00297           reduced(off1+l1,off2+l2)  = transform(6+7*(i-1)+l1,6+7*j+l2);
00298     }
00299 
00300   }
00301     
00302   AlgebraicSymMatrix77 ret;
00303   ROOT::Math::AssignSym::Evaluate(ret, jac_t*reduced*ROOT::Math::Transpose(jac_t));
00304   return ret;
00305 }
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 #endif