CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoVertex/KinematicFit/src/ConstrainedTreeBuilder.cc

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