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
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
00062
00063 down = leftFinalParticle();
00064 rs.push_back(currentParticle());
00065 }else{
00066
00067
00068 up = movePointerToTheMother();
00069 }
00070
00071
00072 }while(up);
00073 }
00074
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
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
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
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
00172
00173
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
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
00194 down = treeWalker->firstChild();
00195
00196
00197
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
00215
00216 delete treeWalker;
00217 treeWalker = new graphwalker<RefCountedKinematicVertex,
00218 RefCountedKinematicParticle>
00219 (treeGraph);
00220 res = treeWalker->current().first;
00221
00222
00223
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
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
00402
00403
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
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
00441 RefCountedKinematicParticle mP = tr->currentParticle();
00442 RefCountedKinematicVertex dec_vertex = tr->currentDecayVertex();
00443 addParticle(vtx,dec_vertex,mP);
00444
00445
00446 leftBranchAdd(tr,dec_vertex);
00447
00448
00449
00450
00451
00452 bool right = true;
00453 bool up = true;
00454 do
00455 {
00456 right = tr->movePointerToTheNextChild();
00457 if(right)
00458 {
00459
00460
00461
00462 RefCountedKinematicVertex prodVertex = tr->currentProductionVertex();
00463 RefCountedKinematicParticle cPart = tr->currentParticle();
00464 RefCountedKinematicVertex decVertex = tr->currentDecayVertex();
00465 addParticle(prodVertex, decVertex, cPart);
00466
00467
00468 leftBranchAdd(tr,decVertex);
00469 }else{
00470 up = tr->movePointerToTheMother();
00471 }
00472 }while(up);
00473 }
00474