00001 #ifndef DCHAIN_COMBINATORICLIST_CC
00002 #define DCHAIN_COMBINATORICLIST_CC
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 #include <stdlib.h>
00099
00100
00101 #include "DecayChain/Element/conjugation.h"
00102 #include "DecayChain/Element/LabeledParticle.h"
00103 #include "DecayChain/Iterator/MuteWholeCandidateItr.h"
00104 #include "DecayChain/Iterator/WholeCandidateItr.h"
00105 #include "DecayChain/Iterator/PartialCandidateItr.h"
00106 #include "DecayChain/Iterator/MuteWholeItr.h"
00107 #include "DecayChain/Iterator/WholeItr.h"
00108 #include "DecayChain/Iterator/PartialItr.h"
00109 #include "DecayChain/List/CombinatoricLoop.h"
00110
00111 #include "DecayChain/List/CombinatoricList.h"
00112
00113
00114
00115
00116 namespace dchain {
00117 static const conjugation::Label kBaseLabel = conjugation::kHeads ;
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 template < class DecayClass, class CandidateClass >
00135 class FillDecayList {
00136 public:
00137 class ChildList {
00138 public:
00139
00140 ChildList() {
00141 m_list.reserve(4);
00142 }
00143
00144 ChildList(const DecayClass* decay) {
00145
00146 uint32_t n = decay->numberChildren();
00147 for ( uint32_t i = 0; i < n; i++) m_list.push_back(&(decay->child(i)));
00148 }
00149
00150 void push_back( const CandidateClass* iCandidate ) {
00151 m_list.push_back( iCandidate );
00152 }
00153 void pop_back() {
00154 m_list.pop_back();
00155 }
00156 void eraseAll() {
00157 m_list.erase(m_list.begin(), m_list.end());
00158 }
00159
00160 bool overlap( const CandidateClass& iCandidate ) const {
00161 for( typename std::vector<const CandidateClass*>::const_iterator itChild =
00162 m_list.begin();
00163 itChild != m_list.end();
00164 ++itChild ) {
00165 if( iCandidate.overlap( *(*itChild) ) ) {
00166 return true;
00167 }
00168 }
00169 return false;
00170 }
00171
00172 DecayClass* makeDecay() {
00173 DecayClass* returnValue = new DecayClass( *(m_list.front()) );
00174 for( typename std::vector<const CandidateClass*>::iterator itChild = m_list.begin()+1;
00175 itChild != m_list.end();
00176 ++itChild ) {
00177 returnValue->addChild( *(*itChild) );
00178 }
00179 return returnValue;
00180 }
00181 private:
00182 std::vector<const CandidateClass*> m_list;
00183 };
00184
00185 static void fill( CombinatoricLoop<CandidateClass >& iLoop,
00186 const typename _combinatoricloop_vector_::iterator& aBegin ,
00187 const typename _combinatoricloop_vector_::iterator& aEnd ,
00188 const conjugation::Label aLabel ,
00189 dchain::LabeledParticleList< DecayClass , CandidateClass >& aDecayList )
00190 {
00191 ChildList childList;
00192
00193 typename dchain::CandidateList<CandidateClass >::const_partial_iterator itEnd = iLoop.partial_end();
00194 for( typename dchain::CandidateList<CandidateClass >::const_partial_iterator entry = iLoop.partial_begin();
00195 entry != itEnd;
00196 ++entry ) {
00197
00198 iLoop.setCurrentIterator( entry ) ;
00199
00200 childList.push_back( & (*entry).labeledClass() );
00201
00202
00203
00204
00205
00206 doIt( aBegin,
00207 aEnd,
00208 childList ,
00209 aLabel,
00210 aDecayList );
00211 childList.eraseAll();
00212 }
00213 }
00214
00215 static void doIt( const typename _combinatoricloop_vector_::iterator& aBegin ,
00216 const typename _combinatoricloop_vector_::iterator& aEnd ,
00217 ChildList& iList ,
00218 const conjugation::Label aLabel ,
00219 dchain::LabeledParticleList< DecayClass, CandidateClass >& aDecayList )
00220 {
00221 if ( aBegin == aEnd ) {
00222
00223
00224
00225 DecayClass* ptr = iList.makeDecay();
00226 ReferenceHolder<DecayClass> pHolder(ptr);
00227 aDecayList.push_back(dchain::LabeledParticle< DecayClass >(
00228 ptr,
00229 aLabel ) ) ;
00230 }
00231 else {
00232
00233
00234
00235 const typename _combinatoricloop_vector_::iterator newBegin( aBegin + 1 ) ;
00236
00237
00238
00239 typename dchain::CandidateList< CandidateClass >::const_partial_iterator finished( (*(*aBegin)).partial_end() ) ;
00240 for ( typename dchain::CandidateList< CandidateClass >::const_partial_iterator entry( (*(*aBegin)).partial_begin() ) ;
00241 entry != finished ;
00242 ++entry ) {
00243 if ( !( iList.overlap( (*entry)() ) ) ) {
00244
00245
00246
00247
00248 (*(*aBegin)).setCurrentIterator( entry ) ;
00249
00250
00251
00252 iList.push_back( & (*entry).labeledClass() );
00253
00254
00255
00256 doIt( newBegin ,
00257 aEnd ,
00258 iList ,
00259 aLabel ,
00260 aDecayList ) ;
00261
00262 iList.pop_back();
00263
00264 }
00265 }
00266 }
00267 }
00268 } ;
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 template < class CandidateClass >
00281 CombinatoricList< CandidateClass >::CombinatoricList( const CombinatoricList<CandidateClass >& iRHS) :
00282 m_listOfLists( *(new _combinatoriclist_vector_() ) ),
00283 m_listFilled( iRHS.m_listFilled ) ,
00284 m_conjugationKnown( iRHS.m_conjugationKnown )
00285 {
00286 m_listOfLists.swap(const_cast<CombinatoricList<CandidateClass>&>(iRHS).m_listOfLists);
00287 }
00288
00289 template < class CandidateClass >
00290 CombinatoricList< CandidateClass >::CombinatoricList( const ConjugateList< CandidateClass >& aList ) :
00291 m_listOfLists( *(new _combinatoriclist_vector_( 1 ,
00292 &aList ) ) ) ,
00293 m_listFilled( false ) ,
00294 m_conjugationKnown( false )
00295 {
00296 }
00297
00298 template < class CandidateClass >
00299 CombinatoricList< CandidateClass >::CombinatoricList( const ConjugateList< CandidateClass >& lhs ,
00300 const ConjugateList< CandidateClass >& rhs ) :
00301 m_listOfLists( *(new _combinatoriclist_vector_( 1 ,
00302 &lhs ) ) ) ,
00303 m_listFilled( false ) ,
00304 m_conjugationKnown( false )
00305 {
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 m_listOfLists.push_back( &rhs ) ;
00317 }
00318
00319 template < class CandidateClass >
00320 CombinatoricList< CandidateClass >::CombinatoricList( const CombinatoricList< CandidateClass >& lhs ,
00321 const ConjugateList< CandidateClass >& rhs ) :
00322 m_listOfLists( *(new _combinatoriclist_vector_( lhs.m_listOfLists ) ) ) ,
00323 m_listFilled( false ) ,
00324 m_conjugationKnown( false )
00325 {
00326 m_listOfLists.push_back( &rhs ) ;
00327 }
00328
00329 template < class CandidateClass >
00330 CombinatoricList< CandidateClass >::CombinatoricList( const ConjugateList< CandidateClass >& lhs ,
00331 const CombinatoricList< CandidateClass >& rhs ) :
00332 m_listOfLists( *(new _combinatoriclist_vector_( 1 ,
00333 &lhs ) ) ) ,
00334 m_listFilled( false ) ,
00335 m_conjugationKnown( false )
00336 {
00337 m_listOfLists.insert( m_listOfLists.end() ,
00338 (rhs.m_listOfLists).begin() ,
00339 (rhs.m_listOfLists).end() ) ;
00340 }
00341
00342 template < class CandidateClass >
00343 CombinatoricList< CandidateClass >::CombinatoricList( const CombinatoricList< CandidateClass >& lhs ,
00344 const CombinatoricList< CandidateClass >& rhs ) :
00345 m_listOfLists( *(new _combinatoriclist_vector_( lhs.m_listOfLists ) ) ) ,
00346 m_listFilled( false ) ,
00347 m_conjugationKnown( false )
00348 {
00349 m_listOfLists.insert( m_listOfLists.end() ,
00350 (rhs.m_listOfLists).begin() ,
00351 (rhs.m_listOfLists).end() ) ;
00352 }
00353
00354 template < class CandidateClass >
00355 CombinatoricList< CandidateClass >::~CombinatoricList()
00356 {
00357 delete &m_listOfLists ;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 template < class CandidateClass >
00372 typename dchain::CandidateList< CandidateClass >::iterator CombinatoricList< CandidateClass >::begin()
00373 {
00374 fill() ;
00375 return ( dchain::DecayList< DecayClass , CandidateClass >::begin() ) ;
00376 }
00377
00378 template < class CandidateClass >
00379 typename dchain::CandidateList< CandidateClass >::iterator CombinatoricList< CandidateClass >::end()
00380 {
00381 fill() ;
00382 return ( dchain::DecayList< DecayClass , CandidateClass >::end() ) ;
00383 }
00384
00385 template < class CandidateClass >
00386 typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::iterator CombinatoricList< CandidateClass >::particle_begin()
00387 {
00388
00389 fill() ;
00390 return ( dchain::DecayList< DecayClass , CandidateClass >::particle_begin() ) ;
00391 }
00392
00393 template < class CandidateClass >
00394 typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::iterator CombinatoricList< CandidateClass >::particle_end() {
00395
00396 fill() ;
00397 return ( dchain::DecayList< DecayClass , CandidateClass >::particle_end() ) ;
00398 }
00399
00400 template < class CandidateClass >
00401 dchain::LabeledCandidateList< CandidateClass >& CombinatoricList< CandidateClass >::labeledCandidateList()
00402 {
00403 fill() ;
00404 return ( dchain::DecayList< DecayClass , CandidateClass >::labeledCandidateList() ) ;
00405 }
00406
00407
00408
00409
00410
00411 template < class CandidateClass >
00412 const dchain::DecayList< typename CombinatoricList<CandidateClass>::DecayClass , CandidateClass >
00413 CombinatoricList< CandidateClass >::bar() const
00414 {
00415 fill() ;
00416
00417 return ( dchain::DecayList< DecayClass , CandidateClass >(
00418 (*(CombinatoricList< CandidateClass >*)this).labeledParticleList() ,
00419 otherLabel( label() ) ) ) ;
00420 }
00421
00422 template < class CandidateClass >
00423 const dchain::DecayList< typename CombinatoricList<CandidateClass>::DecayClass , CandidateClass >&
00424 CombinatoricList< CandidateClass >::operator()() const
00425 {
00426 fill() ;
00427
00428
00429
00430 return ( *this ) ;
00431 }
00432
00433 template < class CandidateClass >
00434 bool
00435 CombinatoricList< CandidateClass >::isSelfConjugate() const
00436 {
00437 determineConjugation() ;
00438 return ( dchain::DecayList< DecayClass , CandidateClass >::isSelfConjugate() ) ;
00439 }
00440
00441 template < class CandidateClass >
00442 typename dchain::CandidateList< CandidateClass >::const_iterator CombinatoricList< CandidateClass >::begin() const
00443 {
00444 fill() ;
00445 return ( dchain::DecayList< DecayClass , CandidateClass >::begin() ) ;
00446 }
00447
00448 template < class CandidateClass >
00449 typename dchain::CandidateList< CandidateClass >::const_iterator CombinatoricList< CandidateClass >::end() const
00450 {
00451 fill() ;
00452 return ( dchain::DecayList< DecayClass , CandidateClass >::end() ) ;
00453 }
00454
00455 template < class CandidateClass >
00456 typename dchain::CandidateList< CandidateClass >::const_partial_iterator CombinatoricList< CandidateClass >::partial_begin() const
00457 {
00458 fill() ;
00459 return ( dchain::DecayList< DecayClass , CandidateClass >::partial_begin() ) ;
00460 }
00461
00462 template < class CandidateClass >
00463 typename dchain::CandidateList< CandidateClass >::const_partial_iterator CombinatoricList< CandidateClass >::partial_end() const
00464 {
00465 fill() ;
00466 return ( dchain::DecayList< DecayClass , CandidateClass >::partial_end() ) ;
00467 }
00468
00469 template < class CandidateClass >
00470 typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::const_iterator
00471 CombinatoricList< CandidateClass >::particle_begin() const
00472 {
00473
00474 fill() ;
00475 return ( dchain::DecayList< DecayClass , CandidateClass >::particle_begin() ) ;
00476 }
00477
00478 template < class CandidateClass >
00479 typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::const_iterator
00480 CombinatoricList< CandidateClass >::particle_end() const
00481 {
00482
00483 fill() ;
00484 return ( dchain::DecayList< DecayClass , CandidateClass >::particle_end() ) ;
00485 }
00486
00487 template < class CandidateClass >
00488 typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::const_partial_iterator
00489 CombinatoricList< CandidateClass >::partial_particle_begin() const
00490 {
00491 fill() ;
00492 return ( dchain::DecayList< DecayClass , CandidateClass >::partial_particle_begin() ) ;
00493 }
00494
00495 template < class CandidateClass >
00496 typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::const_partial_iterator
00497 CombinatoricList< CandidateClass >::partial_particle_end() const
00498 {
00499 fill() ;
00500 return ( dchain::DecayList< DecayClass , CandidateClass >::partial_particle_end() ) ;
00501 }
00502
00503
00504 template < class CandidateClass >
00505 conjugation::Label CombinatoricList< CandidateClass >::label() const
00506 {
00507 determineConjugation() ;
00508 return ( dchain::DecayList< DecayClass , CandidateClass >::label() ) ;
00509 }
00510
00511 template < class CandidateClass >
00512 const dchain::LabeledCandidateList< CandidateClass >& CombinatoricList< CandidateClass >::labeledCandidateList() const
00513 {
00514 fill() ;
00515 return ( dchain::DecayList< DecayClass , CandidateClass >::labeledCandidateList() ) ;
00516 }
00517
00518 template < class CandidateClass >
00519 void CombinatoricList< CandidateClass >::determineConjugation() const
00520 {
00521 if ( m_conjugationKnown ) {
00522 return ;
00523 }
00524 _combinatoriclist_vector_ unConjugatedLists ;
00525 typename _combinatoriclist_vector_::const_iterator finishedTesting ( m_listOfLists.end() ) ;
00526 for ( typename _combinatoriclist_vector_::const_iterator list( m_listOfLists.begin() ) ;
00527 list != finishedTesting ;
00528 ++list ) {
00529 if ( ! (*(*list)).isSelfConjugate() ) {
00530 bool noMatchFound( !false ) ;
00531 typename _combinatoriclist_vector_::iterator matchToCheck( unConjugatedLists.begin() ) ;
00532 typename _combinatoriclist_vector_::iterator finishedMatching ( unConjugatedLists.end() ) ;
00533 while ( noMatchFound &&
00534 ( matchToCheck != finishedMatching ) ) {
00535 if ( (*(*list)).isConjugateOf( (*(*matchToCheck)) ) ) {
00536 unConjugatedLists.erase( matchToCheck ) ;
00537 noMatchFound = false ;
00538 }
00539 ++matchToCheck ;
00540 }
00541 if ( noMatchFound ) {
00542 unConjugatedLists.push_back( *list ) ;
00543 }
00544 }
00545 }
00546 if ( 0 == unConjugatedLists.size() ) {
00547
00548 (*(CombinatoricList< CandidateClass >*)this).setLabel( conjugation::kNone ) ;
00549 }
00550 else {
00551
00552 (*(CombinatoricList< CandidateClass >*)this).setLabel( kBaseLabel ) ;
00553 }
00554
00555 (*(CombinatoricList< CandidateClass >*)this).m_conjugationKnown = !false ;
00556 }
00557
00558 template < class CandidateClass >
00559 void CombinatoricList< CandidateClass >::fill() const
00560 {
00561
00562 if ( m_listFilled ) {
00563 return ;
00564 }
00565
00566
00567
00568
00569
00570 const short kPrimary = 0 ;
00571 const short kConjugate = 1 ;
00572 const short kEndLoopType = 2 ;
00573 _combinatoricloop_vector_ loopList[ 2 ] ;
00574 typename _combinatoricloop_vector_::iterator initialLoop[ 2 ] ;
00575 typename _combinatoricloop_vector_::iterator secondLoop[ 2 ] ;
00576 typename _combinatoricloop_vector_::iterator endLoop[ 2 ] ;
00577 for ( short loopType( kPrimary ) ;
00578 loopType != kEndLoopType ;
00579 ++loopType ) {
00580 if ( ( kConjugate != loopType ) ||
00581 ( ! isSelfConjugate() ) ) {
00582 loopList[ loopType ].reserve( m_listOfLists.size() ) ;
00583 typename _combinatoriclist_vector_::const_iterator finishedBuilding( m_listOfLists.end() ) ;
00584 for ( typename _combinatoriclist_vector_::const_iterator listForLoop( m_listOfLists.begin() ) ;
00585 listForLoop != finishedBuilding ;
00586 ++listForLoop ) {
00587 CombinatoricLoop< CandidateClass >* newLoop ;
00588 if ( kPrimary == loopType ) {
00589 newLoop = new CombinatoricLoop< CandidateClass >( (*(*listForLoop)).partial_begin() ,
00590 (*(*listForLoop)).partial_end() ,
00591 loopList[ loopType ] ) ;
00592 }
00593 else {
00594 newLoop = new CombinatoricLoop< CandidateClass >( (*(*listForLoop)).conjugate_partial_begin() ,
00595 (*(*listForLoop)).conjugate_partial_end() ,
00596 loopList[ loopType ] ) ;
00597 }
00598 loopList[ loopType ].push_back( newLoop ) ;
00599 }
00600 initialLoop[ loopType ] = loopList[ loopType ].begin() ;
00601 secondLoop[ loopType ] = initialLoop[ loopType ] + 1 ;
00602 endLoop[ loopType ] = loopList[ loopType ].end() ;
00603 }
00604 }
00605
00606
00607
00608 conjugation::Label conjugationLabel = kBaseLabel;
00609 if( isSelfConjugate() ) {
00610 conjugationLabel = conjugation::kNone;
00611 }
00612
00613 FillDecayList< DecayClass , CandidateClass >::fill(
00614 *(*initialLoop[ kPrimary ]),
00615 secondLoop[ kPrimary ] ,
00616 endLoop[ kPrimary ] ,
00617 conjugationLabel,
00618 const_cast<CombinatoricList< CandidateClass >*>(this)->labeledParticleList() );
00619
00620 if( !isSelfConjugate() ) {
00621 FillDecayList< DecayClass , CandidateClass >::fill(
00622 *(*initialLoop[ kConjugate ]),
00623 secondLoop[ kConjugate ] ,
00624 endLoop[ kConjugate ] ,
00625 otherLabel(conjugationLabel),
00626 const_cast<CombinatoricList< CandidateClass >*>(this)->labeledParticleList() );
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 for ( short halfType( kPrimary ) ;
00684 halfType != kEndLoopType ;
00685 ++halfType ) {
00686 if ( ( kConjugate != halfType ) ||
00687 ( ! isSelfConjugate() ) ) {
00688 typename _combinatoricloop_vector_::iterator finishedDeletion( loopList[ halfType ].end() ) ;
00689 for ( typename _combinatoricloop_vector_::iterator loopInList( loopList[ halfType ].begin() ) ;
00690 loopInList != finishedDeletion ;
00691 ++loopInList ) {
00692 delete *loopInList ;
00693 }
00694 }
00695 }
00696 m_listFilled = !false ;
00697 }
00698
00699
00700
00701
00702 }
00703 #endif
00704
00705
00706
00707