CMS 3D CMS Logo

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