CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoVertex/KinematicFitPrimitives/src/KinematicTree.cc

Go to the documentation of this file.
00001 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicTree.h"
00002 
00003 KinematicTree::KinematicTree()
00004 {
00005  empt = true;
00006  treeWalker = 0;
00007 }
00008 
00009  KinematicTree::~KinematicTree()
00010 {
00011  delete treeWalker;
00012 }
00013 
00014 
00015 bool KinematicTree::isEmpty() const
00016  {return empt;}
00017  
00018 bool KinematicTree::isConsistent() const
00019 {
00020  movePointerToTheTop();
00021  bool des = false;
00022  if(!treeWalker->nextSibling()) des = true;
00023  return des;
00024 }
00025 
00026 void KinematicTree::addParticle(RefCountedKinematicVertex prodVtx, 
00027                                 RefCountedKinematicVertex  decVtx, 
00028                                  RefCountedKinematicParticle part)
00029 {
00030  part->setTreePointer(this);
00031  treeGraph.addEdge(prodVtx,decVtx,part);
00032  empt = false;
00033  movePointerToTheTop();
00034  prodVtx->setTreePointer(this);
00035  decVtx->setTreePointer(this);
00036 }
00037 
00038 std::vector<RefCountedKinematicParticle> KinematicTree::finalStateParticles() const
00039 {
00040  if(isEmpty() || !(isConsistent()))
00041  {
00042   throw VertexException("KinematicTree::finalStateParticles; tree is empty or not consistent");
00043  }else{
00044   RefCountedKinematicParticle initial = currentParticle();
00045   std::vector<RefCountedKinematicParticle> rs;
00046   movePointerToTheTop();
00047   if(!(leftFinalParticle()))
00048   {
00049    std::cout<<"top particle has no daughters, empty vector returned"<<std::endl;
00050   }else{
00051 //now pointer is at the  most left final particle
00052    rs.push_back(currentParticle()); 
00053    bool next_right = true; 
00054    bool up = true;
00055    do
00056    {
00057     next_right = movePointerToTheNextChild();
00058     if(next_right)
00059     {
00060 //if there's a way to the right,
00061 //we go right and down possible    
00062      leftFinalParticle();
00063      rs.push_back(currentParticle()); 
00064     }else{
00065 //once there's no way to right anymore
00066 //trying to find a way upper    
00067      up = movePointerToTheMother();
00068     }
00069 //loop stops when we are at the top:
00070 //no way up, no way to the right    
00071    }while(up);   
00072   } 
00073 //getting the pointer back  
00074   bool back = findParticle(initial);
00075   if(!back) throw VertexException("KinematicTree::FinalStateParticles; error occured while getting back");
00076   return rs;
00077  }
00078 }
00079 
00080 bool KinematicTree::leftFinalParticle() const
00081 {
00082  bool res = false;
00083  if(movePointerToTheFirstChild())
00084  {
00085   res = true;
00086   bool next = true;
00087   do
00088   {
00089     next = movePointerToTheFirstChild(); 
00090   }while(next);
00091  }else{
00092   res =false;
00093  }
00094  return res;
00095 }
00096 
00097  
00098  RefCountedKinematicParticle KinematicTree::topParticle() const
00099  {
00100    if(isEmpty()) throw VertexException("KinematicTree::topParticle; tree is empty!");
00101 //putting pointer to the top of the tree 
00102    movePointerToTheTop();
00103    return treeWalker->current().second;                                     
00104  }
00105  
00106  
00107  RefCountedKinematicVertex KinematicTree::currentDecayVertex() const
00108  {
00109    if(isEmpty()) throw VertexException("KinematicTree::currentDecayVertex; tree is empty!");
00110    return treeWalker->current().first;
00111  }
00112  
00113  std::pair<bool,RefCountedKinematicParticle>  KinematicTree::motherParticle() const
00114  {
00115   if(isEmpty()) throw VertexException("KinematicTree::motherParticle; tree is empty!");
00116   bool top = currentProductionVertex()->vertexIsValid();
00117    RefCountedKinematicParticle cr  = treeWalker->current().second;
00118    bool up = treeWalker->parent();
00119    std::pair<bool,RefCountedKinematicParticle> res; 
00120    if(up && top){
00121     RefCountedKinematicParticle pr = treeWalker->current().second;
00122     
00123 //now putting the pointer back   
00124     bool fc = treeWalker->firstChild();
00125     if(!fc) throw VertexException("KinematicTree::motherParticle; tree is incorrect!");
00126     if(*(treeWalker->current().second) != *cr)
00127     {
00128      do{
00129       bool nx = treeWalker->nextSibling();
00130       if(!nx) throw VertexException("KinematicTree::motherParticle; tree is incorrect!");
00131      }while(*(treeWalker->current().second) != *cr);
00132     }
00133     res = std::pair<bool,RefCountedKinematicParticle>(true,pr);
00134     return res;
00135    }else{
00136     RefCountedKinematicParticle fk;
00137     return std::pair<bool,RefCountedKinematicParticle>(false,fk);
00138    }
00139  }
00140  
00141  std::vector<RefCountedKinematicParticle>  KinematicTree::daughterParticles() const
00142  {
00143   if(isEmpty()) throw VertexException("KinematicTree::daughterParticles; tree is empty!");
00144   std::vector<RefCountedKinematicParticle> sResult;
00145   RefCountedKinematicParticle initial = currentParticle();
00146   bool down  = treeWalker->firstChild();
00147   if(down)
00148   {
00149     sResult.push_back(treeWalker->current().second);
00150     bool sibling = true;
00151     do
00152     {
00153      sibling = treeWalker->nextSibling();
00154      if(sibling) sResult.push_back(treeWalker->current().second); 
00155     }while(sibling);
00156   }
00157 
00158 //getting the pointer back to the mother  
00159   bool back = findParticle(initial);
00160   if(!back) throw VertexException("KinematicTree::daughterParticles; error occured while getting back");
00161   return sResult;
00162  }
00163 
00164 void KinematicTree::movePointerToTheTop() const
00165 {
00166  if(isEmpty()) throw VertexException("KinematicTree::movePointerToTheTop; tree is empty!");
00167  delete treeWalker;
00168  treeWalker = new graphwalker<RefCountedKinematicVertex,
00169                               RefCountedKinematicParticle>(treeGraph);
00170 //now pointer is a pair: fake vertex and 
00171 //icoming 0 pointer to the particle
00172 //moving it to decayed particle
00173  bool move = treeWalker->firstChild();
00174  if(!move) throw VertexException("KinematicTree::movePointerToTheTop; non consistent tree?");
00175 }
00176 
00177 RefCountedKinematicVertex KinematicTree::currentProductionVertex() const
00178 {
00179   if(isEmpty()) throw VertexException("KinematicTree::currentProductionVertex; tree is empty!");
00180 //current particle
00181   RefCountedKinematicParticle initial = currentParticle();
00182   
00183   bool up;
00184   bool down;
00185   RefCountedKinematicVertex res;
00186   up = movePointerToTheMother();
00187   
00188  if(up)
00189  { 
00190   res = treeWalker->current().first;
00191                                                
00192 //pointer moved so we going back
00193   down = treeWalker->firstChild();
00194    
00195 //_down_ variable is always TRUE here, if
00196 //the tree is valid.
00197   if(down){
00198    if(initial == treeWalker->current().second)
00199    {
00200     return res;
00201    }else{
00202     bool next = true;
00203     do
00204     {
00205      next = treeWalker->nextSibling();
00206      if(treeWalker->current().second == initial) next = false;
00207     }while(next);
00208     return res;
00209    }
00210   }else{throw VertexException("KinematicTree::Navigation failed, tree invalid?");}                      
00211  }else
00212  { 
00213 //very unprobable case. This efectively means that user is
00214 //already out of the tree. Moving back to the top
00215  delete treeWalker;
00216  treeWalker = new graphwalker<RefCountedKinematicVertex,
00217                               RefCountedKinematicParticle>
00218                                               (treeGraph);
00219  res = treeWalker->current().first;                                           
00220 //now pointer is a pair: fake vertex and 
00221 //icoming 0 pointer to the particle
00222 //moving it to decayed particle
00223  bool move = treeWalker->firstChild();
00224  if(!move) throw VertexException("KinematicTree::movePointerToTheTop; non consistent tree?");
00225  return res;
00226  } 
00227 }
00228  
00229 RefCountedKinematicParticle KinematicTree::currentParticle() const
00230 {
00231  if(isEmpty()) throw VertexException("KinematicTree::currentParticle; tree is empty!");
00232  return treeWalker->current().second;
00233 }
00234 
00235 bool KinematicTree::movePointerToTheMother() const
00236 {
00237  if(isEmpty()) throw VertexException("KinematicTree::movePointerToTheMother; tree is empty!");
00238  bool up = treeWalker->parent();
00239  bool cr = treeWalker->current().first->vertexIsValid();
00240  return (up && cr);
00241 }
00242 
00243 bool KinematicTree::movePointerToTheFirstChild() const
00244 {
00245  if(isEmpty()) throw VertexException("KinematicTree::movePointerToTheFirstChild; tree is empty!");
00246  return treeWalker->firstChild();
00247 }
00248  
00249 bool KinematicTree::movePointerToTheNextChild() const
00250 {
00251  if(isEmpty()) throw VertexException("KinematicTree::movePointerToTheNextChild; tree is empty!");
00252  bool res = treeWalker->nextSibling();
00253  return res;
00254 }
00255 
00256 bool KinematicTree::findParticle(const RefCountedKinematicParticle part) const
00257 {
00258  if(isEmpty() || !(isConsistent()))
00259  {
00260   throw VertexException("KinematicTree::findParticle; tree is empty or not consistent");
00261  }else{
00262   bool res = false;
00263   movePointerToTheTop();
00264   if(currentParticle() == part)
00265   {
00266    res = true;
00267   }else if(leftBranchSearch(part)){
00268    res = true;
00269   }else{
00270    bool found = false;
00271    bool up = true;
00272    bool next_right = false;
00273    do
00274    {
00275 //    if(*(currentParticle()) == *part) found = true;
00276     next_right = movePointerToTheNextChild();
00277     if(next_right)
00278     {
00279      found = leftBranchSearch(part);
00280     }else{
00281      up = movePointerToTheMother();
00282      if(currentParticle() == part) found = true;
00283     }
00284    }while(up && !found);
00285    res = found;
00286   } 
00287   return res;
00288  }
00289 }
00290 
00291 
00292 bool KinematicTree::leftBranchSearch(RefCountedKinematicParticle part) const
00293 {
00294  bool found = false;
00295  bool next = true;
00296  if(currentParticle() == part)
00297  {
00298   found = true;
00299  }else{
00300   do
00301   {
00302    next = movePointerToTheFirstChild();
00303    if(currentParticle() == part)
00304    {
00305     found = true;
00306    }
00307   }while(next && !found);
00308   }
00309  return found;
00310 }
00311 
00312 bool KinematicTree::findDecayVertex(const RefCountedKinematicVertex vert)const
00313 {
00314  if(isEmpty() || !(isConsistent()))
00315  {
00316   throw VertexException("KinematicTree::findParticle; tree is empty or not consistent");
00317  }else{
00318  bool res = false;
00319  movePointerToTheTop();
00320  if(currentDecayVertex() == vert)
00321  {
00322   res = true;
00323  }else if(leftBranchVertexSearch(vert)){
00324   res = true;
00325  }else{
00326   bool up = true;
00327   bool fnd = false;
00328   do
00329   {
00330    if(movePointerToTheNextChild())
00331    {
00332     fnd = leftBranchVertexSearch(vert);
00333    }else{
00334     up=movePointerToTheMother();
00335     if(currentDecayVertex() == vert) fnd = true;
00336    }   
00337   }while(up && !fnd);
00338   res = fnd;
00339  }
00340  return res;
00341  }
00342 }
00343 
00344 bool KinematicTree::findDecayVertex(KinematicVertex *vert)const
00345 {
00346  if(isEmpty() || !(isConsistent()))
00347  {
00348   throw VertexException("KinematicTree::findParticle; tree is empty or not consistent");
00349  }else{
00350  bool res = false;
00351  movePointerToTheTop();
00352  if(*currentDecayVertex() == vert)
00353  {
00354   res = true;
00355  }else if(leftBranchVertexSearch(vert)){
00356   res = true;
00357  }else{
00358   bool up = true;
00359   bool fnd = false;
00360   do
00361   {
00362    if(movePointerToTheNextChild())
00363    {
00364     fnd = leftBranchVertexSearch(vert);
00365    }else{
00366     up=movePointerToTheMother();
00367     if(currentDecayVertex() == vert) fnd = true;
00368    }   
00369   }while(up && !fnd);
00370   res = fnd;
00371  }
00372  return res;
00373  }
00374 }
00375 
00376 
00377 bool KinematicTree::leftBranchVertexSearch(RefCountedKinematicVertex vtx) const
00378 {
00379  bool found = false;
00380  if(currentDecayVertex() == vtx)
00381  {
00382   found = true;
00383  }else{
00384   bool next = true;
00385   bool res = false;
00386   do
00387   {
00388    next = movePointerToTheFirstChild();
00389    if(currentDecayVertex() == vtx) res = true;
00390   }while(next && !res); 
00391   found  = res;
00392  }
00393  return found;
00394 }
00395 
00396 void KinematicTree::leftBranchAdd(KinematicTree * otherTree, RefCountedKinematicVertex vtx)
00397 {
00398   RefCountedKinematicVertex previous_decay = otherTree->currentDecayVertex(); 
00399  
00400 //children of current particle of the
00401 //other tree: in the end the whole 
00402 //left branch should be added. 
00403   bool next = true;
00404   do
00405   {
00406    next = otherTree->movePointerToTheFirstChild();
00407    if(next)
00408    {
00409     RefCountedKinematicParticle par = otherTree->currentParticle();
00410     RefCountedKinematicVertex current_decay = otherTree->currentDecayVertex();
00411     addParticle(previous_decay, current_decay, par);
00412     previous_decay = current_decay;
00413    }
00414   }while(next);
00415 }
00416 
00417 void KinematicTree::replaceCurrentParticle(RefCountedKinematicParticle newPart) const
00418 {
00419  RefCountedKinematicParticle cDParticle = currentParticle();
00420  bool replace = treeGraph.replaceEdge(cDParticle,newPart);
00421  if(!replace) throw VertexException("KinematicTree::Particle To Replace not found");
00422 }
00423       
00424 void KinematicTree::replaceCurrentVertex(RefCountedKinematicVertex newVert) const
00425 {
00426  RefCountedKinematicVertex cDVertex = currentDecayVertex();
00427  bool replace = treeGraph.replace(cDVertex,newVert);
00428  if(! replace) throw VertexException("KinematicTree::Vertex To Replace not found");
00429 }
00430 
00431                         
00432 void KinematicTree::addTree(RefCountedKinematicVertex vtx, KinematicTree * tr)
00433 {
00434 //adding new tree to the existing one:
00435  bool fnd = findDecayVertex(vtx);
00436  if(!fnd) throw VertexException("KinematicTree::addTree; Current tree does not contain the vertex passed");
00437  tr->movePointerToTheTop();
00438  
00439 // adding the root of the tree: 
00440  RefCountedKinematicParticle mP = tr->currentParticle(); 
00441  RefCountedKinematicVertex   dec_vertex = tr->currentDecayVertex();
00442  addParticle(vtx,dec_vertex,mP);
00443 
00444 // adding the left branch if any 
00445  leftBranchAdd(tr,dec_vertex);
00446 
00447 //now the pointer is at the left down
00448 //edge of the otherTree.
00449 //current tree pointer is where the
00450 //add operation was stoped last time.
00451  bool right = true;
00452  bool up = true;
00453  do
00454  {
00455   right = tr->movePointerToTheNextChild();
00456   if(right)
00457   {
00458 
00459 //production vertex is already at the current tree  
00460 //adding current partilce
00461    RefCountedKinematicVertex prodVertex = tr->currentProductionVertex();
00462    RefCountedKinematicParticle cPart = tr->currentParticle();
00463    RefCountedKinematicVertex decVertex = tr->currentDecayVertex();
00464    addParticle(prodVertex, decVertex, cPart);
00465    
00466 //adding the rest of the branch   
00467    leftBranchAdd(tr,decVertex);
00468   }else{
00469    up = tr->movePointerToTheMother(); 
00470   }
00471  }while(up);
00472 }                       
00473