00001 00002 // $Id: NavSet.cxx,v 1.15 2005/03/16 16:06:35 west Exp $ 00003 // 00004 // NavSet 00005 // 00006 // Package: Nav (Navigational Model). 00007 00008 // Begin_Html<img src="../../pedestrians.gif" align=center> 00009 // <a href="../source_warning.html">Warning for beginners</a>.<br> 00010 // Also see <a href="../../root_crib/index.html">The ROOT Crib</a> and 00011 // <a href="../index.html">The MINOS Class User Guide</a>End_Html 00012 // 00013 // N. West 03/20000 00014 // 00015 // Concept: Sharable, mapable, sortable, selectable, sliceable 00016 // array of void* derived from set or relationship. 00017 // 00018 // Purpose: A NavSet is a a generic set that can be:- 00019 // 00020 // o Shareable by any number of iterators. 00021 // o Can represent a mapping across a relationship 00022 // i.e. the set of class A objects associated with 00023 // a specific object of class B. 00024 // o Ordered via a user configured ordering object. 00025 // o Individual members can be selected via a user 00026 // configured selection object. 00027 // o Access can be restricted to those members whose 00028 // ordering value is within a user supplied range. 00029 // 00030 // The underlying set are void* pointers but all accesss to 00031 // the set is via a type safe XxxItr class inheriting from 00032 // NavItr. 00033 // 00035 00036 #include <algorithm> 00037 00038 #include "Navigation/NavItr.h" 00039 #include "Navigation/NavKeyFunc.h" 00040 #include "Navigation/NavSet.h" 00041 #include "LeakChecker/Lea.h" 00042 #include "Lattice/Lattice.h" 00043 #include "MessageService/MsgService.h" 00044 #include "TCollection.h" 00045 00046 typedef NavSet::SliceLimits SliceLimits; 00047 typedef list<NavItr*>::const_iterator ConstItrItr; 00048 typedef list<NavItr*>::iterator ItrItr; 00049 typedef vector<void*>::iterator ObjItr; 00050 typedef vector<SliceLimits>::iterator SliceLimitsItr; 00051 00052 ClassImp(NavSet) 00053 00054 // Definition of static data members 00055 // ********************************* 00056 00057 CVSID("$Id: NavSet.cxx,v 1.15 2005/03/16 16:06:35 west Exp $"); 00058 00059 NavSet* NavSet::fgCurrent = 0; 00060 NavSet::EXLessThanYAmbResolve NavSet::fgXLessThanYAmbResolve = NavSet::kFirstGreater; 00061 00062 // Definition of member functions (alphabetical order) 00063 // *************************************************** 00064 00065 00066 //..................................................................... 00067 00068 Bool_t NavSet::AdoptSelectKeyFunc(NavKeyFunc* keyFunc, 00069 Bool_t update) { 00070 // 00071 // 00072 // Purpose: Replace current selection function with supplied. 00073 // 00074 // Arguments: 00075 // keyFunc in New key function or 0 to cancel selection. 00076 // NB NavKey takes control of the NavKey and 00077 // will eventually delete it. The user must 00078 // not access the object again. 00079 // update in Set kTRUE (default) if set to be updated. 00080 // 00081 // Return: kTRUE if keyFunc was compatible with this NavSet. 00082 // 00083 // Contact: N. West 00084 // 00085 // Specification:- 00086 // ============= 00087 // 00088 // o Delete any current selection object. 00089 // 00090 // o If supplied NavKeyFunc is compatible, adopt it otherwise delete 00091 // it. 00092 // 00093 // o Update the set and Reset all iterators if required. 00094 00095 00096 // Program Notes:- 00097 // ============= 00098 00099 // Suppressing updating saves time if further select/sort functions are 00100 // to be applied. 00101 // The user must subsquently call Update() to bring the set up to date. 00102 00103 Bool_t mustUpdate = kFALSE; 00104 if ( fSelectFunc ) { 00105 delete fSelectFunc; 00106 fSelectFunc = 0; 00107 fSelectFuncInvert = kFALSE; 00108 mustUpdate = kTRUE; 00109 } 00110 00111 Bool_t funcOK = kTRUE; 00112 fSelectFunc = keyFunc; 00113 fSelectFuncInvert = kFALSE; 00114 if ( fSelectFunc && ! KeyFunAcceptable(keyFunc) ) { 00115 delete fSelectFunc; 00116 fSelectFunc = 0; 00117 funcOK = kFALSE; 00118 } 00119 00120 if ( update ) { 00121 if ( mustUpdate) Update(); 00122 else DoSelectFunction(); 00123 } 00124 00125 return funcOK; 00126 00127 } 00128 00129 //..................................................................... 00130 00131 Bool_t NavSet::AdoptSortKeyFunc(NavKeyFunc* keyFunc, 00132 Bool_t dropExisting, 00133 Bool_t update) { 00134 // 00135 // 00136 // Purpose: Replace current ordering function with supplied and 00137 // resort if required. 00138 // 00139 // Arguments: 00140 // keyFunc in New key function or 0 to cancel sorting. 00141 // NB NavKey takes control of the NavKey and 00142 // will eventually delete it. The user must 00143 // not access the object again. 00144 // dropExisting in Set kTRUE (default) if existing functions are 00145 // to be dropped (also done if keyFunc = 0). 00146 // update in Set kTRUE (default) if set to be updated. 00147 // 00148 // Return: kTRUE if keyFunc was compatible with this NavSet. 00149 // 00150 // Contact: N. West 00151 // 00152 // Specification:- 00153 // ============= 00154 // 00155 // o Delete any current set ordering objects. 00156 // 00157 // o If supplied NavKeyFunc is compatible, adopt it otherwise 00158 // delete it. 00159 // 00160 // o Resort set if reqired (sort == kTRUE). 00161 00162 00163 // Program Notes:- 00164 // ============= 00165 00166 // Suppressing updating saves time if further select/sort functions are 00167 // to be applied. 00168 // The user must subsquently call Update() to bring the set up to date. 00169 00170 // Must do a full update (rather than just resort the current selected 00171 // set) if selection may have changed i.e. if the ordering associated 00172 // with any slice changes. 00173 Bool_t mustUpdate = kFALSE; 00174 00175 if ( dropExisting || ! keyFunc ) { 00176 mustUpdate = fSliceLimits.size() > 0; 00177 DeleteOrderFuncs(); 00178 } 00179 00180 Bool_t funcOK = kTRUE; 00181 if ( keyFunc && ! KeyFunAcceptable(keyFunc) ) { 00182 funcOK = kFALSE; 00183 delete keyFunc; 00184 keyFunc = 0; 00185 } 00186 if ( keyFunc ) { 00187 if ( fSliceLimits.size() > fOrderFuncs.size() ) mustUpdate = kTRUE; 00188 fOrderFuncs.push_back(keyFunc); 00189 } 00190 00191 if ( update ) { 00192 if ( mustUpdate) Update(); 00193 else DoSort(); 00194 } 00195 00196 return funcOK; 00197 00198 } 00199 00200 //..................................................................... 00201 00202 UInt_t NavSet::Attach(NavItr* itr) { 00203 // 00204 // 00205 // Purpose: Attach iterator. 00206 // 00207 // Arguments: 00208 // itr in Attaching iterator. 00209 // 00210 // Return: Number of iterators attached (including the current one) 00211 // 00212 // Contact: N. West 00213 // 00214 // Specification:- 00215 // ============= 00216 // 00217 // o Add iterator to the list of attached iterators and return the new 00218 // size of the set. 00219 00220 // Program Notes:- 00221 // ============= 00222 00223 // None. 00224 00225 fItrs.push_back(itr); 00226 return fItrs.size(); 00227 00228 } 00229 00230 //..................................................................... 00231 00232 void NavSet::DeleteOrderFuncs() { 00233 // 00234 // 00235 // Purpose: Delete any owned sort functions 00236 // 00237 // Arguments: None. 00238 // 00239 // Return: n/a 00240 // 00241 // Contact: N. West 00242 // 00243 // Specification:- 00244 // ============= 00245 // 00246 // o Delete any owned sort functions 00247 00248 // Program Notes:- 00249 // ============= 00250 00251 // None. 00252 00253 for ( vec_key_funcs_itr_t itr = fOrderFuncs.begin(); 00254 itr != fOrderFuncs.end(); 00255 ++itr ) delete *itr; 00256 fOrderFuncs.clear(); 00257 } 00258 00259 //..................................................................... 00260 00261 UInt_t NavSet::Detach(NavItr* itr) { 00262 // 00263 // 00264 // Purpose: Detach iterator. 00265 // 00266 // Arguments: 00267 // itr in Detaching iterator. 00268 // 00269 // Return: Number of iterators still attached (excluding the current one) 00270 // 00271 // Contact: N. West 00272 // 00273 // Specification:- 00274 // ============= 00275 // 00276 // o Remove iterator to the list of detached iterators and return the new 00277 // size of the set. 00278 00279 // Program Notes:- 00280 // ============= 00281 00282 // When the value 0 is returned the calling NavItr must delete the NavSet. 00283 00284 00285 ItrItr entry = find(fItrs.begin(), fItrs.end(), itr); 00286 00287 if ( entry == fItrs.end() ) { 00288 MSG("Nav", Msg::kError) << "Cannot find detaching iterator " 00289 << itr << endl; 00290 } 00291 else { 00292 fItrs.erase(entry); 00293 } 00294 00295 return fItrs.size(); 00296 00297 } 00298 00299 00300 //..................................................................... 00301 00302 void NavSet::DoSelectFunction() { 00303 // 00304 // 00305 // Purpose: Remove set members that fail the current selection function. 00306 // 00307 // Arguments: None 00308 // 00309 // Return: n/a. 00310 // 00311 // Contact: N. West 00312 // 00313 // Specification:- 00314 // ============= 00315 // 00316 // o Apply the latest selection function and reset all iterators. 00317 00318 // Program Notes:- 00319 // ============= 00320 00321 // This member function is used when a new selection function is added as 00322 // this can only reduce set membership and consequently sorting can be 00323 // avoided. 00324 00325 // No action if there is no function. 00326 if ( ! fSelectFunc ) return; 00327 00328 // Select into a temporay array. 00329 00330 vector<void*> temp; 00331 for ( ObjItr itr = fArraySel.begin(); itr != fArraySel.end(); itr++ ) { 00332 void* obj = *itr; 00333 if ( ( (*fSelectFunc)(obj).ForceLong_t() == 0 ) 00334 == fSelectFuncInvert ) temp.push_back(obj); 00335 } 00336 00337 // Copy back to selected array. 00338 00339 fArraySel = temp; 00340 00341 // Inform all iterators. 00342 00343 ResetItrs(); 00344 00345 } 00346 00347 //..................................................................... 00348 00349 void NavSet::DoSelectSlice() { 00350 // 00351 // 00352 // Purpose: Remove set members that fail the latest slice. 00353 // 00354 // Arguments: None 00355 // 00356 // Return: n/a. 00357 // 00358 // Contact: N. West 00359 // 00360 // Specification:- 00361 // ============= 00362 // 00363 // o Apply the latest slice to the current set and reset all iterators. 00364 00365 // Program Notes:- 00366 // ============= 00367 00368 // This member function is used when a new slice is added as this can 00369 // only reduce set membership and consequently sorting can be avoided. 00370 00371 // No action if there are no slice limits or no corresponding order function. 00372 00373 Int_t rank = fSliceLimits.size(); 00374 rank--; 00375 int size = fOrderFuncs.size(); 00376 if ( rank < 0 || rank+1 > size ) { 00377 if ( rank+1 > size ) MSG("Nav", Msg::kWarning) 00378 << "Attempting to slice in dimension " << rank +1 00379 << " (i.e. rank " << rank << "),\n " 00380 << " but sort functions only defined for first " << size 00381 << " dimension(s)" << endl; 00382 return; 00383 } 00384 00385 NavKeyFunc* func = fOrderFuncs[rank]; 00386 SliceLimits& lim = fSliceLimits[rank]; 00387 NavKey& keyLo = lim.Lo; 00388 NavKey& keyHi = lim.Hi; 00389 00390 // Select into a temporay array. 00391 00392 vector<void*> temp; 00393 for ( ObjItr itr = fArraySel.begin(); itr != fArraySel.end(); itr++ ) { 00394 void* obj = *itr; 00395 NavKey key = (*func)(obj); 00396 if ( keyLo.CompareValue(key) <= 0 && keyHi.CompareValue(key) >= 0 00397 ) temp.push_back(obj); 00398 } 00399 00400 // Copy back to selected array. 00401 00402 fArraySel = temp; 00403 00404 // Inform all iterators. 00405 00406 ResetItrs(); 00407 00408 } 00409 00410 //..................................................................... 00411 00412 void NavSet::DoMap() { 00413 // 00414 // 00415 // Purpose: Map (select) set associated with object on far side 00416 // of Lattice. 00417 // 00418 // Arguments: None. 00419 // 00420 // Return: n/a. 00421 // 00422 // Contact: N. West 00423 // 00424 // Specification:- 00425 // ============= 00426 // 00427 // o If fFar = 0 cancel association with far side object. 00428 // 00429 // o Otherwise search for far object on other side of Lattice 00430 // and if found replace set with that associated with it, 00431 // otherwise make set empty. 00432 // 00433 // o Resestablish sort order and slice, if any, and reset all associated 00434 // iterators to the start of their range. 00435 00436 // Program Notes:- 00437 // ============= 00438 00439 // Mapping only applies to sets based on Lattices, but for 00440 // this operation TClonesArrays are treated as one-sided 00441 // Lattices i.e. mapping returns a null set but cancelling 00442 // restores the full set. 00443 00444 if ( fFar ) { 00445 if ( fLattice ) Fill( fLattice, fSide, fFar); 00446 else { 00447 fArrayFull.clear(); 00448 fArraySel.clear(); 00449 } 00450 } 00451 else { 00452 if ( fLattice ) Fill( fLattice, fSide); 00453 else if ( fTCollection ) Fill( fTCollection, fClassname, fOffset); 00454 } 00455 00456 Update(); 00457 00458 } 00459 00460 //..................................................................... 00461 00462 void NavSet::DoSort() { 00463 // 00464 // 00465 // Purpose: Sort object set using current set ordering function. 00466 // 00467 // Arguments: None 00468 // 00469 // Return: n/a. 00470 // 00471 // Contact: N. West 00472 // 00473 // Specification:- 00474 // ============= 00475 // 00476 // o If there currently is an associated ordering function resort 00477 // set. 00478 // 00479 // o Reset all iterators. 00480 00481 00482 // Program Notes:- 00483 // ============= 00484 00485 // None. 00486 00487 if ( fOrderFuncs.size() ) { 00488 // Prepare the static function XLessThanY. 00489 fgCurrent = this; 00490 sort(fArraySel.begin(), fArraySel.end(), NavSet::XLessThanY); 00491 } 00492 00493 ResetItrs(); 00494 00495 } 00496 00497 //..................................................................... 00498 00499 UInt_t NavSet::Fill(const TCollection* source, 00500 const Text_t* classname, 00501 Int_t offset){ 00502 // 00503 // 00504 // Purpose: Fill vector from source, offsetting each object address 00505 // 00506 // Arguments: 00507 // source in Source set 00508 // classname in Name of class objects. 00509 // offset in Pointer offset: Object adr - TObject adr 00510 // 00511 // Return: Number of objects in vector. 00512 // 00513 // Contact: N. West 00514 // 00515 // Specification:- 00516 // ============= 00517 // 00518 // o Fill vector from TCollection, checking that each object is, or 00519 // inherits from, classname. 00520 // 00521 // o Offset each object address by offset. 00522 00523 00524 // Program Notes:- 00525 // ============= 00526 00527 // The offset is needed because all object's are stored by their 00528 // TObject address which may not be the same as the target object's 00529 // address. 00530 00531 // N.B. objects whose TObject address is not the same as the target 00532 // may cause problems in TClonesArrays, for there is an implicit 00533 // assumption in TClonesArray the address returned by new is the 00534 // TObject address. 00535 00536 00537 // Vector may not be empty, e.g. after breaking a mapping. 00538 00539 fArrayFull.clear(); 00540 00541 TIter sourceIter(source); 00542 TObject* sourceObj; 00543 00544 Bool_t ok = kTRUE; 00545 Bool_t suppressClassCheck = kFALSE; 00546 00547 if ( strcmp(classname,"???") == 0 ) { 00548 MSG("Nav", Msg::kWarning) << "Class name set to ??? - cannot validate set!" << endl; 00549 suppressClassCheck = kTRUE; 00550 } 00551 while ( (sourceObj = sourceIter.Next()) ) { 00552 if ( ok && ( suppressClassCheck || sourceObj->InheritsFrom(classname) ) 00553 ) { 00554 void* targetObj = (void*) ( (Char_t*) sourceObj + offset ); 00555 fArrayFull.push_back(targetObj); 00556 } 00557 else if ( ok ) { 00558 MSG("Nav", Msg::kError) << "Cannot construct " << classname 00559 << " iterator, supplied TCollection contains " 00560 << sourceObj->ClassName()<< " objects; set will be empty." 00561 << endl; 00562 fArrayFull.clear(); 00563 ok = kFALSE; 00564 } 00565 } 00566 00567 // Transfer to selected and sorted array. 00568 fArraySel = fArrayFull; 00569 00570 return fArraySel.size(); 00571 } 00572 00573 //..................................................................... 00574 00575 UInt_t NavSet::Fill(const Lattice* source, ESide side){ 00576 // 00577 // 00578 // Purpose: Fill vector from one side of a Lattice. 00579 // 00580 // Arguments: 00581 // source in Source relationship set 00582 // side in Side of relationship (either kLeft or kRight). 00583 // 00584 // Return: Number of objects in vector. 00585 // 00586 // Contact: N. West 00587 // 00588 // Specification:- 00589 // ============= 00590 // 00591 // o Fill vector from one side of a lattice.. 00592 00593 00594 // Program Notes:- 00595 // ============= 00596 00597 // None.. 00598 00599 00600 00601 // Vector may not be empty, e.g. after breaking a mapping. 00602 00603 fArrayFull.clear(); 00604 00605 if ( side != kLeft && side != kRight ) { 00606 MSG("Lat", Msg::kError) << "Illegal value for side: " << (Int_t) side 00607 << endl; 00608 } 00609 else if ( ! source ) { 00610 MSG("Lat", Msg::kError) << "No Lattice supplied" << endl; 00611 } 00612 else { 00613 source->GetAllIDs( (Lattice::ESide) side, fArrayFull); 00614 } 00615 00616 // Transfer to selected and sorted array. 00617 fArraySel = fArrayFull; 00618 00619 return fArraySel.size(); 00620 00621 } 00622 00623 //..................................................................... 00624 00625 UInt_t NavSet::Fill(const Lattice* source, ESide side, const void* far){ 00626 // 00627 // 00628 // Purpose: Fill vector from one side of a Lattice that associates 00629 // one member on the far side of the Lattice. 00630 // 00631 // Arguments: 00632 // source in Source relationship set 00633 // side in Side of reltionship (either kLeft or kRight). 00634 // far in member on far side of Lattice. 00635 // 00636 // Return: Number of objects in set. 00637 // 00638 // Contact: N. West 00639 // 00640 // Specification:- 00641 // ============= 00642 // 00643 // o Fill vector from one side of a lattice that associates 00644 // one member on the far side of the Lattice. 00645 00646 00647 // Program Notes:- 00648 // ============= 00649 00650 // None. 00651 00652 00653 00654 // Vector may not be empty, e.g. if called from Map. 00655 00656 fArrayFull.clear(); 00657 00658 if ( side != kLeft && side != kRight ) { 00659 MSG("Lat", Msg::kError) << "Illegal value for side: " << (Int_t) side 00660 << endl; 00661 } 00662 else if ( ! source ) { 00663 MSG("Lat", Msg::kError) << "No Lattice supplied" << endl; 00664 } 00665 else { 00666 ESide otherSide = ESide(kLeft + kRight - side); 00667 // The casting away of const on far is unavoidable but harmless; 00668 // Lattice passes ID by value but in MINOS these IDs are void*. 00669 source->GetFarIDs( (Lattice::ESide) otherSide, (void*)far, fArrayFull); 00670 } 00671 00672 // Transfer to selected and sorted array. 00673 fArraySel = fArrayFull; 00674 00675 return fArraySel.size(); 00676 00677 } 00678 00679 //..................................................................... 00680 00681 NavKey NavSet::GetNavKey(Int_t index, Int_t keyRank) const { 00682 // 00683 // 00684 // Purpose: Return NavKey associated with supplied index and rank. 00685 // 00686 // Arguments: 00687 // index in Index to be tsted 00688 // keyRank in Rank of key (=0 primary, =1 secondary etc.) 00689 // 00690 // 00691 // Return: NavKey associated with supplied index and rank or NavKey(0) 00692 // if none. 00693 // 00694 // Contact: N. West 00695 // 00696 // Specification:- 00697 // ============= 00698 // 00699 // o Return NavKey associated with supplied index and rank. 00700 00701 // Program Notes:- 00702 // ============= 00703 00704 // None. 00705 00706 int size = fOrderFuncs.size(); 00707 if ( IsWithinLimits(index) 00708 && keyRank >= 0 00709 && keyRank < size 00710 ) return fOrderFuncs[keyRank]->GetKey(fArraySel[index]); 00711 return 0; 00712 00713 } 00714 00715 //..................................................................... 00716 00717 void NavSet::GetZone(Int_t limLo, Int_t limHi, 00718 Int_t index, Int_t rank, 00719 Int_t& zoneLo, Int_t& zoneHi) const { 00720 // 00721 // 00722 // Purpose: Find zone limits around a given index of specified rank. 00723 // 00724 // Arguments: 00725 // limLo in Lower possible limit on zone 00726 // limHi in Upper possible limit on zone 00727 // index in Start point for search 00728 // rank in Rank of order function 00729 // zoneLo out Lower limit on zone 00730 // zoneHi out Upper limit on zone 00731 // 00732 // Return: n/a (output via zoneLo and zoneHi) 00733 // 00734 // Contact: N. West 00735 // 00736 // Specification:- 00737 // ============= 00738 // 00739 // o Starting at supplied index find zone i.e. region limited by 00740 // (limLo,limHi) within which the NavKey for order function of 00741 // supplied rank remains constant. 00742 // 00743 // o If there is no order function of supplied rank, then treat 00744 // the supplied region as a single zone. 00745 00746 // Program Notes:- 00747 // ============= 00748 00749 // None. 00750 00751 // Protect against silly values. 00752 00753 if ( limLo < 0 ) limLo = 0; 00754 if ( index < limLo ) index = limLo; 00755 if ( limHi > GetMaxIndex() ) limHi = GetMaxIndex(); 00756 if ( index > limHi ) index = limHi; 00757 00758 // If no ordering function, or null range return the full range 00759 00760 int size = fOrderFuncs.size(); 00761 if ( rank >= size || limLo > limHi ) { 00762 zoneLo = limLo; 00763 zoneHi = limHi; 00764 return; 00765 } 00766 00767 NavKeyFunc* func = fOrderFuncs[rank]; 00768 NavKey key = (*func)(fArraySel[index]); 00769 00770 zoneLo = index; 00771 while ( zoneLo > limLo 00772 && key.CompareValue((*func)(fArraySel[zoneLo-1])) == 0 00773 ) --zoneLo; 00774 00775 zoneHi = index; 00776 while ( zoneHi < limHi 00777 && key.CompareValue((*func)(fArraySel[zoneHi+1])) == 0 00778 ) ++zoneHi; 00779 00780 } 00781 00782 //..................................................................... 00783 00784 void NavSet::Init() { 00785 // 00786 // 00787 // Purpose: Initialise empty object. 00788 // 00789 // Arguments: None. 00790 // 00791 // Return: n/a 00792 // 00793 // Contact: N. West 00794 // 00795 // Specification:- 00796 // ============= 00797 // 00798 // o Initialise empty object. 00799 00800 // Program Notes:- 00801 // ============= 00802 00803 // None. 00804 00805 fArrayFull.clear(); 00806 fArraySel.clear(); 00807 fFar = 0; 00808 fItrs.clear(); 00809 fSelectFunc = 0; 00810 fSelectFuncInvert = kFALSE; 00811 fSetSize = 0; 00812 00813 fLattice = 0; 00814 fSide = kLeft; 00815 00816 fClassname = 0; 00817 fOffset = 0; 00818 fTCollection = 0; 00819 00820 00821 } 00822 00823 //..................................................................... 00824 00825 Bool_t NavSet::IsSelected(Int_t index) const { 00826 // 00827 // 00828 // Purpose: Determine if supplied index addresses to a selected 00829 // object. 00830 // 00831 // Arguments: 00832 // index in Supplied index. 00833 // 00834 // Return: kTRUE if index addresses to a selected object. 00835 // 00836 // Contact: N. West 00837 // 00838 // Specification:- 00839 // ============= 00840 // 00841 // o Return kTRUE if supplied index addresses to a selected object, 00842 // otherwise return kFALSE. 00843 00844 // Program Notes:- 00845 // ============= 00846 00847 // None. 00848 00849 return IsWithinLimits(index); 00850 } 00851 //..................................................................... 00852 00853 void NavSet::InvertSelection(Bool_t set, Bool_t update) { 00854 // 00855 // 00856 // Purpose: Set or clear the select function iverter and update if required 00857 00858 if ( fSelectFuncInvert == set ) return; 00859 fSelectFuncInvert = set; 00860 if ( update && fSelectFunc ) this->Update(); 00861 00862 } 00863 00864 //..................................................................... 00865 00866 Bool_t NavSet::IsWithinLimits(Int_t index) const { 00867 // 00868 // 00869 // Purpose: Determine if supplied index is within limits. 00870 // 00871 // Arguments: 00872 // index in Supplied index. 00873 // 00874 // Return: kTRUE if index is within limits. 00875 // 00876 // Contact: N. West 00877 // 00878 // Specification:- 00879 // ============= 00880 // 00881 // o Return kTRUE if supplied index is within limits, otherwise 00882 // return kFALSE. 00883 00884 // Program Notes:- 00885 // ============= 00886 00887 // None. 00888 00889 int size = fArraySel.size(); 00890 return ( index >= 0 00891 && index+1 <= size ) ? kTRUE : kFALSE; 00892 00893 } 00894 //..................................................................... 00895 00896 Bool_t NavSet::KeyFunAcceptable(NavKeyFunc* keyFunc) const { 00897 // 00898 // 00899 // Purpose: See if key function can be adopted. 00900 // 00901 // Arguments: 00902 // keyFunc in New key function or 0. 00903 // 00904 // Return: kTRUE if keyFunc can be used with this NavSet. 00905 // 00906 // Contact: N. West 00907 // 00908 // Specification:- 00909 // ============= 00910 // 00911 // o 0 is always acceptable. Other are if compatible and have 00912 // defined functions. 00913 00914 // Program Notes:- 00915 // ============= 00916 00917 // None. 00918 00919 if ( ! keyFunc ) return 1; 00920 00921 if ( ! keyFunc->IsCompatible(this) ) { 00922 MSG("Nav", Msg::kError) << "XxxKeyFunc is not compatible." << endl; 00923 return 0; 00924 } 00925 00926 if ( ! keyFunc->FunDefined() ) { 00927 MSG("Nav", Msg::kError) << "XxxKeyFunc has no function defined." << endl; 00928 return 0; 00929 } 00930 00931 return 1; 00932 00933 } 00934 //..................................................................... 00935 00936 NavSet::NavSet(const TCollection* source, 00937 const Text_t* classname, 00938 Int_t offset/*=0*/ ) { 00939 // 00940 // 00941 // Purpose: Constructor 00942 // 00943 // Arguments: 00944 // source in Source set 00945 // classname in Name of class objects. 00946 // offset in Pointer offset: Object adr - TObject adr 00947 // 00948 // Return: n/a 00949 // 00950 // Contact: N. West 00951 // 00952 // Specification:- 00953 // ============= 00954 // 00955 // o Fill vector from TCollection. 00956 00957 00958 // Program Notes:- 00959 // ============= 00960 00961 // None. 00962 00963 LEA_CTOR //Leak Checker 00964 00965 Init(); 00966 fClassname = classname; 00967 fOffset = offset; 00968 fTCollection = source; 00969 Fill(source, classname, offset); 00970 fSetSize = fArrayFull.size(); 00971 00972 } 00973 00974 //..................................................................... 00975 00976 NavSet::NavSet(const Lattice* source, ESide side) { 00977 // 00978 // 00979 // Purpose: Constructor 00980 // 00981 // Arguments: 00982 // source in Source relationship. 00983 // side in Side of reltionship (either kLeft or kRight). 00984 // 00985 // Return: n/a 00986 // 00987 // Contact: N. West 00988 // 00989 // Specification:- 00990 // ============= 00991 // 00992 // o Fill vector from one side of a lattice.. 00993 00994 00995 // Program Notes:- 00996 // ============= 00997 00998 // None. 00999 01000 LEA_CTOR //Leak Checker 01001 01002 Init(); 01003 fLattice = source; 01004 fSide = side; 01005 Fill(source, side); 01006 fSetSize = fArrayFull.size(); 01007 01008 } 01009 //..................................................................... 01010 01011 NavSet::~NavSet() { 01012 // 01013 // 01014 // Purpose: Destructor 01015 // 01016 // Arguments: 01017 // None. 01018 // 01019 // Return: n/a 01020 // 01021 // Contact: N. West 01022 // 01023 // Specification:- 01024 // ============= 01025 // 01026 // o Destroy object. 01027 01028 01029 // Program Notes:- 01030 // ============= 01031 01032 // None. 01033 01034 LEA_DTOR //Leak Checker 01035 01036 DeleteOrderFuncs(); 01037 delete fSelectFunc; 01038 fSelectFunc = 0; 01039 01040 } 01041 01042 //..................................................................... 01043 01044 void NavSet::ResetItrs() const { 01045 // 01046 // 01047 // Purpose: Reset all associated NavItrs 01048 // 01049 // Arguments: None. 01050 // 01051 // Return: n/a 01052 // 01053 // Contact: N. West 01054 // 01055 // Specification:- 01056 // ============= 01057 // 01058 // o Send all associated NavItrs their ResetSet message. 01059 01060 // Program Notes:- 01061 // ============= 01062 01063 // None. 01064 01065 for (ConstItrItr itr = fItrs.begin(); itr != fItrs.end(); itr++) { 01066 (*itr)->ResetSet(); 01067 } 01068 01069 } 01070 //..................................................................... 01071 01072 UInt_t NavSet::Size() const{ 01073 // 01074 // 01075 // Purpose: Return the total set size disregarding selection. 01076 // 01077 // Arguments: None 01078 // 01079 // Return: The total set size disregarding selection. 01080 // 01081 // Contact: N. West 01082 // 01083 // Specification:- 01084 // ============= 01085 // 01086 // o Return the total set size disregarding selection. 01087 01088 01089 // Program Notes:- 01090 // ============= 01091 01092 // None. 01093 01094 return fSetSize; 01095 } 01096 //..................................................................... 01097 01098 UInt_t NavSet::SizeSelect() const{ 01099 // 01100 // 01101 // Purpose: Return the number currently selected. 01102 // 01103 // Arguments: None 01104 // 01105 // Return: The number currently selected. 01106 // 01107 // Contact: N. West 01108 // 01109 // Specification:- 01110 // ============= 01111 // 01112 // o Return the number currently selected. 01113 01114 // Program Notes:- 01115 // ============= 01116 01117 // None. 01118 01119 return fArraySel.size(); 01120 01121 } 01122 //..................................................................... 01123 01124 void NavSet::Slice(NavKey lo, NavKey hi, Bool_t update) { 01125 // 01126 // 01127 // Purpose: Define and appply new slice limits. 01128 // 01129 // Arguments: 01130 // lo in Lower slice limit. 01131 // hi in Upper slice limit. 01132 // update in Set kTRUE (default) if set to be updated. 01133 // 01134 // Return: n/a. 01135 // 01136 // Contact: N. West 01137 // 01138 // Specification:- 01139 // ============= 01140 // 01141 // o Set slice limits and reslice set. 01142 01143 // Program Notes:- 01144 // ============= 01145 01146 // Suppressing updating saves time if further select/sort functions are 01147 // to be applied. 01148 // The user must subsquently call Update() to bring the set up to date. 01149 01150 fSliceLimits.push_back(SliceLimits(lo,hi)); 01151 if ( update ) DoSelectSlice(); 01152 01153 } 01154 01155 //..................................................................... 01156 01157 void NavSet::Update() { 01158 // 01159 // 01160 // Purpose: Reapply all current selection and sorting. 01161 // 01162 // Arguments: None. 01163 // 01164 // Return: n/a 01165 // 01166 // Contact: N. West 01167 // 01168 // Specification:- 01169 // ============= 01170 // 01171 // o Starting from unselected, unsorted array, fill out selected array 01172 // applying all current selection and sorting. 01173 01174 // Program Notes:- 01175 // ============= 01176 01177 // None. 01178 01179 fArraySel.clear(); 01180 01181 Int_t rankMax = fSliceLimits.size() < fOrderFuncs.size() 01182 ? fSliceLimits.size() : fOrderFuncs.size(); 01183 01184 for ( ObjItr itr = fArrayFull.begin(); itr != fArrayFull.end(); itr++ ) { 01185 void* obj = *itr; 01186 01187 // Test function. 01188 if ( fSelectFunc 01189 && ( (*fSelectFunc)(obj).ForceLong_t() != 0 ) == fSelectFuncInvert ) continue; 01190 01191 // Test slices. 01192 Bool_t withinLimits = kTRUE; 01193 for ( Int_t rank = 0; rank < rankMax; ++rank ) { 01194 NavKey key = (*fOrderFuncs[rank])(obj); 01195 SliceLimits& lim = fSliceLimits[rank]; 01196 if ( lim.Lo.CompareValue(key) > 0 01197 || lim.Hi.CompareValue(key) < 0 ) { 01198 withinLimits = kFALSE; 01199 break; 01200 } 01201 } 01202 if ( withinLimits ) fArraySel.push_back(obj); 01203 } 01204 01205 DoSort(); 01206 01207 } 01208 01209 //..................................................................... 01210 01211 Bool_t NavSet::XLessThanY(void* x, void* y) { 01212 // 01213 // 01214 // Purpose: Static function to compare two set objects 01215 // 01216 // Arguments: 01217 // x in First set object. 01218 // y in Second set object. 01219 // 01220 // Return: kTRUE if x < y. 01221 // 01222 // Contact: N. West 01223 // 01224 // Specification:- 01225 // ============= 01226 // 01227 // o If there is a current NavSet object that has set ordering 01228 // NavKeyFuncs, get and compare the two NavKey values and return 01229 // the result, using lower level NavKeyFuncs to break ambiguity 01230 // otherwise resolve using fgXLessThanYAmbResolve. 01231 01232 // Program Notes:- 01233 // ============= 01234 01235 // NavSet objects pass this function to the STL sort algorithm. 01236 01237 // The only purpose of fgXLessThanYAmbResolve is to change the way 01238 // order degeneracies are broken in an attempt to uncover bugs that 01239 // produce different results dependent on such ordering changes. 01240 // 01241 // To change add the following to your job macro:- 01242 // 01243 // NavSet::fgXLessThanYAmbResolve = NavSet::kChooseByAddress; 01244 // 01245 // This changes from the default(kFirstGreater). If the results 01246 // change in a significant way then this indicates a bug. 01247 01248 // Caution: It's tempting to define kSecondGreater as this would be reproducible, 01249 // unlike kChooseByAddress which, because the heap manager can return a 01250 // different addresses when presented with the same sequence of requests, 01251 // is not. Indeed the temptation has been succumbed to but it ends in 01252 // tears (and a SegV). kSecondGreater would mean that XLessThanY is no 01253 // longer strict weak ordering - it would be possible for the function to 01254 // return true for x<y and y<x and this breaks the sorting algorithm! 01255 01256 01257 if ( !x || !y ) MSG("Nav",Msg::kError) << "Passed null: " << x << " " << y << endl; 01258 if ( fgCurrent && fgCurrent->fOrderFuncs.size() ) { 01259 int size = fgCurrent->fOrderFuncs.size(); 01260 for (Int_t ifunc = 0; ifunc < size; ++ifunc ) { 01261 NavKeyFunc* keyFunc = fgCurrent->fOrderFuncs[ifunc]; 01262 NavKey keyX = keyFunc->GetKey(x); 01263 NavKey keyY = keyFunc->GetKey(y); 01264 Int_t comp = keyX.CompareValue(keyY); 01265 if ( comp ) return ( comp < 0 ) ? kTRUE : kFALSE; 01266 } 01267 } 01268 01269 if ( fgXLessThanYAmbResolve == kFirstGreater ) return kFALSE; 01270 return ( x < y ) ? kTRUE : kFALSE; 01271 01272 } 01273 01274 /* Template for New Member Function 01275 01276 //..................................................................... 01277 01278 NavSet:: { 01279 // 01280 // 01281 // Purpose: 01282 // 01283 // Arguments: 01284 // xxxxxxxxx in yyyyyy 01285 // 01286 // Return: 01287 // 01288 // Contact: N. West 01289 // 01290 // Specification:- 01291 // ============= 01292 // 01293 // o 01294 01295 // Program Notes:- 01296 // ============= 01297 01298 // None. 01299 01300 01301 } 01302 01303 */ 01304
1.3.9.1