BOSS 7.0.8
BESIII Offline Software System
Loading...
Searching...
No Matches
CombinatoricList.cc
Go to the documentation of this file.
1#ifndef DCHAIN_COMBINATORICLIST_CC
2#define DCHAIN_COMBINATORICLIST_CC
3// -*- C++ -*-
4//
5// Package: DChain
6// Module: CombinatoricList
7//
8// Description: container used to build Decay subclass objects
9//
10// Implimentation:
11// <Notes on implimentation>
12//
13// Author: Simon Patton
14// Created: Sat Oct 5 17:18:02 EDT 1996
15// $Id: CombinatoricList.cc,v 1.1.1.1 2009/03/03 06:06:56 maqm Exp $
16//
17// Revision history
18//
19// $Log: CombinatoricList.cc,v $
20// Revision 1.1.1.1 2009/03/03 06:06:56 maqm
21// first import of DecayChain
22//
23// Revision 1.1 2006/01/11 20:28:35 cdj
24// massive class renaming, addition of [] for selection and unit tests
25//
26// Revision 1.10 2003/05/15 19:56:12 cdj
27// revamped memory handling so always use a ReferenceHolder to deal with the reference counting
28//
29// Revision 1.9 2003/03/13 20:19:16 cleo3
30// now compiles under Linux
31//
32// Revision 1.8 2002/06/21 14:20:51 cdj
33// previous changes now compile under OSF1
34//
35// Revision 1.7 2002/06/19 20:37:10 cleo3
36// added missing typename and create a copy constructor
37//
38// Revision 1.6 2002/06/18 20:52:04 cdj
39// fixed bug that occurred when mulitplying 3 or more of the same list and conjugation where one of the list was the first list of the combination
40//
41// Revision 1.5 2001/04/20 14:02:09 ajm36
42// plug memory leak associated with makeDecay
43//
44// Revision 1.4 2001/04/10 13:56:48 urner
45// bug fixes
46//
47// Revision 1.3 2001/03/30 19:41:12 cdj
48// improved memory usage when doing combinatorics
49//
50// Revision 1.2 2001/03/29 21:33:38 cdj
51// initial try at bug fix for selfCongugateList*nonSelfCongugateList
52//
53// Revision 1.1.1.1 2000/12/18 22:16:55 cdj
54// imported DChain
55//
56// Revision 1.13 1998/08/21 00:51:54 sjp
57// Modifier to no longer use typedefs
58//
59// Revision 1.12 1998/08/20 20:00:09 sjp
60// Modified to use DChainBoolean
61//
62// Revision 1.11 1998/08/19 20:46:21 sjp
63// Fixed comments and removed report references
64//
65// Revision 1.10 1998/04/17 19:14:49 sjp
66// Modified to use latest type
67//
68// Revision 1.9 1997/09/03 14:58:22 sjp
69// Use new report.h and TBParticlePoint
70//
71// Revision 1.8 1997/08/28 07:00:35 sjp
72// Modified files to handle complete templating
73//
74// Revision 1.7 1997/08/19 23:03:14 sjp
75// Restructured package to be independent of Rock
76//
77// Revision 1.6 1997/08/19 16:19:03 sjp
78// Improved handling of STL containers
79//
80// Revision 1.5 1997/08/15 21:33:35 sjp
81// Updated to use <package>/<file>.h include structure.
82// Updated to use bug flags specified in Experiement.h
83//
84// Revision 1.4 1997/01/31 20:16:24 sjp
85// Modified to use the new `bug' include files
86//
87// Revision 1.3 1997/01/21 20:31:34 sjp
88// Changed CPP flags and include because of library reorganization
89//
90// Revision 1.2 1996/12/20 21:14:01 sjp
91// Changed aPossible to Possible and added dropLink where nec.
92//
93// Revision 1.1 1996/11/04 17:17:12 sjp
94// New file for new `List' module
95//
96
97// system include files
98#include <stdlib.h> // For 'exit'
99
100// user include files
110
112
113//
114// constants, enums and typedefs
115//
116namespace dchain {
117static const conjugation::Label kBaseLabel = conjugation::kHeads ;
118
119//
120// local functions
121//
122
123// The follwing function is local rather than a member of CombinatoricList
124// as that would require the file <vector> to be included in
125// CombinatoricList.h, and thus in many other parts of the code. That
126// inclusion can sieverly slow down compliation and also cause many
127// local copies of the code to be generated. It is best to avoid this.
128//
129// Now, you may ask why make this a static function in a class. The simple
130// answer is it works! I tried this as a simple, normal static
131// (i.e. file-scope) function and my compilers barfed. Why do it work
132// in a class? I don't know, but it does so lets just get one with it!
133
134template < class DecayClass, class CandidateClass >
136public:
137 class ChildList {
138 public:
139
141 m_list.reserve(4);
142 }
143
144 ChildList(const DecayClass* decay) {
145 //fill the m_list with decay
146 uint32_t n = decay->numberChildren();
147 for ( uint32_t i = 0; i < n; i++) m_list.push_back(&(decay->child(i)));
148 }
149
150 void push_back( const CandidateClass* iCandidate ) {
151 m_list.push_back( iCandidate );
152 }
153 void pop_back() {
154 m_list.pop_back();
155 }
156 void eraseAll() {
157 m_list.erase(m_list.begin(), m_list.end());
158 }
159
160 bool overlap( const CandidateClass& iCandidate ) const {
161 for( typename std::vector<const CandidateClass*>::const_iterator itChild =
162 m_list.begin();
163 itChild != m_list.end();
164 ++itChild ) {
165 if( iCandidate.overlap( *(*itChild) ) ) {
166 return true;
167 }
168 }
169 return false;
170 }
171
172 DecayClass* makeDecay() {
173 DecayClass* returnValue = new DecayClass( *(m_list.front()) );
174 for( typename std::vector<const CandidateClass*>::iterator itChild = m_list.begin()+1;
175 itChild != m_list.end();
176 ++itChild ) {
177 returnValue->addChild( *(*itChild) );
178 }
179 return returnValue;
180 }
181 private:
182 std::vector<const CandidateClass*> m_list;
183 };
184
186 const typename _combinatoricloop_vector_::iterator& aBegin ,
187 const typename _combinatoricloop_vector_::iterator& aEnd ,
188 const conjugation::Label aLabel ,
190 {
191 ChildList childList;
192
195 entry != itEnd;
196 ++entry ) {
197
198 iLoop.setCurrentIterator( entry ) ;
199
200 childList.push_back( & (*entry).labeledClass() );
201
202 //
203 // Note: need to cast way `const' to make sure a non-const LabeledParticleList
204 // is returned
205 //
206 doIt( aBegin,
207 aEnd,
208 childList ,
209 aLabel,
210 aDecayList );
211 childList.eraseAll();
212 }
213 }
214
215 static void doIt( const typename _combinatoricloop_vector_::iterator& aBegin ,
216 const typename _combinatoricloop_vector_::iterator& aEnd ,
217 ChildList& iList ,
218 const conjugation::Label aLabel ,
220 {
221 if ( aBegin == aEnd ) {
222 //
223 // if all ConjuagetLists have been used add Decay to the final list
224 //
225 DecayClass* ptr = iList.makeDecay();
226 ReferenceHolder<DecayClass> pHolder(ptr);
228 ptr,
229 aLabel ) ) ;
230 }
231 else {
232 //
233 // make iterator for next ConjugateList loop
234 //
235 const typename _combinatoricloop_vector_::iterator newBegin( aBegin + 1 ) ;
236 //
237 // loop over each entry in the current ConjugateList
238 //
239 typename dchain::CandidateList< CandidateClass >::const_partial_iterator finished( (*(*aBegin)).partial_end() ) ;
240 for ( typename dchain::CandidateList< CandidateClass >::const_partial_iterator entry( (*(*aBegin)).partial_begin() ) ;
241 entry != finished ;
242 ++entry ) {
243 if ( !( iList.overlap( (*entry)() ) ) ) {
244 //
245 // If baseDecay does not overlap current element in the this ConjugateList,
246 // record the current element of this Loop
247 //
248 (*(*aBegin)).setCurrentIterator( entry ) ;
249 //
250 // build new baseDecay with old baseDecay plus the current element
251 //
252 iList.push_back( & (*entry).labeledClass() );
253 //
254 // do all successive ConjugateList loops
255 //
256 doIt( newBegin ,
257 aEnd ,
258 iList ,
259 aLabel ,
260 aDecayList ) ;
261
262 iList.pop_back();
263
264 }
265 }
266 }
267 }
268} ;
269
270//
271// static data member definitions
272//
273
274//
275// constructors and destructor
276//
277
278//the copy constructor is only used for the return value of operator* so
279// we can make things faster by swapping the data stored in the vector
280template < class CandidateClass >
282 m_listOfLists( *(new _combinatoriclist_vector_() ) ),
283 m_listFilled( iRHS.m_listFilled ) ,
284 m_conjugationKnown( iRHS.m_conjugationKnown )
285{
286 m_listOfLists.swap(const_cast<CombinatoricList<CandidateClass>&>(iRHS).m_listOfLists);
287}
288
289template < class CandidateClass >
291 m_listOfLists( *(new _combinatoriclist_vector_( 1 ,
292 &aList ) ) ) ,
293 m_listFilled( false ) ,
294 m_conjugationKnown( false )
295{
296}
297
298template < class CandidateClass >
301 m_listOfLists( *(new _combinatoriclist_vector_( 1 ,
302 &lhs ) ) ) ,
303 m_listFilled( false ) ,
304 m_conjugationKnown( false )
305{
306 //std::cout << "@CombinatoricList::CombinatoricList() 11" << std::endl;
307 //typedef typename ConjugateList< CandidateClass >::const_partial_iterator test_it;
308 //std::cout << "lhs ...................... : " << std::endl;
309 //for ( test_it it = lhs.partial_begin(); it != lhs.partial_end(); it++ ) {
310 // std::cout << (*it)().footPrint() << std::endl;
311 //}
312 //std::cout << "rhs ...................... : " << std::endl;
313 //for ( test_it it = rhs.partial_begin(); it != rhs.partial_end(); it++ ) {
314 // std::cout << (*it)().footPrint() << std::endl;
315 //}
316 m_listOfLists.push_back( &rhs ) ;
317}
318
319template < class CandidateClass >
322 m_listOfLists( *(new _combinatoriclist_vector_( lhs.m_listOfLists ) ) ) ,
323 m_listFilled( false ) ,
324 m_conjugationKnown( false )
325{
326 m_listOfLists.push_back( &rhs ) ;
327}
328
329template < class CandidateClass >
332 m_listOfLists( *(new _combinatoriclist_vector_( 1 ,
333 &lhs ) ) ) ,
334 m_listFilled( false ) ,
335 m_conjugationKnown( false )
336{
337 m_listOfLists.insert( m_listOfLists.end() ,
338 (rhs.m_listOfLists).begin() ,
339 (rhs.m_listOfLists).end() ) ;
340}
341
342template < class CandidateClass >
345 m_listOfLists( *(new _combinatoriclist_vector_( lhs.m_listOfLists ) ) ) ,
346 m_listFilled( false ) ,
347 m_conjugationKnown( false )
348{
349 m_listOfLists.insert( m_listOfLists.end() ,
350 (rhs.m_listOfLists).begin() ,
351 (rhs.m_listOfLists).end() ) ;
352}
353
354template < class CandidateClass >
356{
357 delete &m_listOfLists ;
358}
359
360//
361// assignment operators
362//
363// const CombinatoricList< CandidateClass >& CombinatoricList< CandidateClass >::operator=( const CombinatoricList< CandidateClass >& )
364// {
365// }
366
367//
368// member functions
369//
370
371template < class CandidateClass >
373{
374 fill() ;
376}
377
378template < class CandidateClass >
380{
381 fill() ;
383}
384
385template < class CandidateClass >
387{
388 //std::cout << "@CombinatoricList::particle_begin() -- iterator" << std::endl;
389 fill() ;
391}
392
393template < class CandidateClass >
395 //std::cout << "@CombinatoricList::particle_end() -- iterator" << std::endl;
396 fill() ;
398}
399
400template < class CandidateClass >
402{
403 fill() ;
405}
406
407//
408// const member functions
409//
410
411template < class CandidateClass >
414{
415 fill() ;
416// Need to cast away 'const' to get the right type of LabelList returned
418 (*(CombinatoricList< CandidateClass >*)this).labeledParticleList() ,
419 otherLabel( label() ) ) ) ;
420}
421
422template < class CandidateClass >
425{
426 fill() ;
427// // Need to cast away 'const' to get the right type of LabelList returned
428// return ( dchain::DecayList< DecayClass , CandidateClass >( (*(CombinatoricList< CandidateClass >*)this).labeledDecayList() ,
429// label() ) ) ;
430 return ( *this ) ;
431}
432
433template < class CandidateClass >
434bool
436{
437 determineConjugation() ;
439}
440
441template < class CandidateClass >
443{
444 fill() ;
446}
447
448template < class CandidateClass >
450{
451 fill() ;
453}
454
455template < class CandidateClass >
457{
458 fill() ;
460}
461
462template < class CandidateClass >
464{
465 fill() ;
467}
468
469template < class CandidateClass >
470typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::const_iterator
472{
473 //std::cout << "@CombinatoricList::particle_begin() -- iterator" << std::endl;
474 fill() ;
476}
477
478template < class CandidateClass >
479typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::const_iterator
481{
482 //std::cout << "@CombinatoricList::particle_end() -- const_iterator" << std::endl;
483 fill() ;
485}
486
487template < class CandidateClass >
488typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::const_partial_iterator
490{
491 fill() ;
493}
494
495template < class CandidateClass >
496typename dchain::DecayList< typename DCCandidateTraits<CandidateClass>::DecayClass , CandidateClass >::const_partial_iterator
498{
499 fill() ;
501}
502
503
504template < class CandidateClass >
506{
507 determineConjugation() ;
509}
510
511template < class CandidateClass >
513{
514 fill() ;
516}
517
518template < class CandidateClass >
520{
521 if ( m_conjugationKnown ) {
522 return ;
523 }
524 _combinatoriclist_vector_ unConjugatedLists ;
525 typename _combinatoriclist_vector_::const_iterator finishedTesting ( m_listOfLists.end() ) ;
526 for ( typename _combinatoriclist_vector_::const_iterator list( m_listOfLists.begin() ) ;
527 list != finishedTesting ;
528 ++list ) {
529 if ( ! (*(*list)).isSelfConjugate() ) {
530 bool noMatchFound( !false ) ;
531 typename _combinatoriclist_vector_::iterator matchToCheck( unConjugatedLists.begin() ) ;
532 typename _combinatoriclist_vector_::iterator finishedMatching ( unConjugatedLists.end() ) ;
533 while ( noMatchFound &&
534 ( matchToCheck != finishedMatching ) ) {
535 if ( (*(*list)).isConjugateOf( (*(*matchToCheck)) ) ) {
536 unConjugatedLists.erase( matchToCheck ) ;
537 noMatchFound = false ;
538 }
539 ++matchToCheck ;
540 }
541 if ( noMatchFound ) {
542 unConjugatedLists.push_back( *list ) ;
543 }
544 }
545 }
546 if ( 0 == unConjugatedLists.size() ) {
547// have to cast away 'const' to set the real value of the label
548 (*(CombinatoricList< CandidateClass >*)this).setLabel( conjugation::kNone ) ;
549 }
550 else {
551// have to cast away 'const' to set the real value of the label
552 (*(CombinatoricList< CandidateClass >*)this).setLabel( kBaseLabel ) ;
553 }
554// have to cast away 'const' to set the real value of the flag
555 (*(CombinatoricList< CandidateClass >*)this).m_conjugationKnown = !false ;
556}
557
558template < class CandidateClass >
559void CombinatoricList< CandidateClass >::fill() const
560{
561 //std::cout << "@CombinatoricList::fill(), filled = " << m_listFilled << std::endl;
562 if ( m_listFilled ) {
563 return ;
564 }
565//
566// Create CombinatoricLoop lists for `primary' half of the list.
567// If list is not self-conjugate, fill CombinatoricLoop lists for `conjugate'
568// half of the list as well.
569//
570 const short kPrimary = 0 ;
571 const short kConjugate = 1 ;
572 const short kEndLoopType = 2 ;
573 _combinatoricloop_vector_ loopList[ 2 ] ;
574 typename _combinatoricloop_vector_::iterator initialLoop[ 2 ] ;
575 typename _combinatoricloop_vector_::iterator secondLoop[ 2 ] ;
576 typename _combinatoricloop_vector_::iterator endLoop[ 2 ] ;
577 for ( short loopType( kPrimary ) ;
578 loopType != kEndLoopType ;
579 ++loopType ) {
580 if ( ( kConjugate != loopType ) ||
581 ( ! isSelfConjugate() ) ) {
582 loopList[ loopType ].reserve( m_listOfLists.size() ) ;
583 typename _combinatoriclist_vector_::const_iterator finishedBuilding( m_listOfLists.end() ) ;
584 for ( typename _combinatoriclist_vector_::const_iterator listForLoop( m_listOfLists.begin() ) ;
585 listForLoop != finishedBuilding ;
586 ++listForLoop ) {
587 CombinatoricLoop< CandidateClass >* newLoop ;
588 if ( kPrimary == loopType ) {
589 newLoop = new CombinatoricLoop< CandidateClass >( (*(*listForLoop)).partial_begin() ,
590 (*(*listForLoop)).partial_end() ,
591 loopList[ loopType ] ) ;
592 }
593 else {
594 newLoop = new CombinatoricLoop< CandidateClass >( (*(*listForLoop)).conjugate_partial_begin() ,
595 (*(*listForLoop)).conjugate_partial_end() ,
596 loopList[ loopType ] ) ;
597 }
598 loopList[ loopType ].push_back( newLoop ) ;
599 }
600 initialLoop[ loopType ] = loopList[ loopType ].begin() ;
601 secondLoop[ loopType ] = initialLoop[ loopType ] + 1 ;
602 endLoop[ loopType ] = loopList[ loopType ].end() ;
603 }
604 }
605//
606// do loop through initial ConjugateList
607//
608 conjugation::Label conjugationLabel = kBaseLabel;
609 if( isSelfConjugate() ) {
610 conjugationLabel = conjugation::kNone;
611 }
612
614 *(*initialLoop[ kPrimary ]),
615 secondLoop[ kPrimary ] ,
616 endLoop[ kPrimary ] ,
617 conjugationLabel,
618 const_cast<CombinatoricList< CandidateClass >*>(this)->labeledParticleList() );
619
620 if( !isSelfConjugate() ) {
622 *(*initialLoop[ kConjugate ]),
623 secondLoop[ kConjugate ] ,
624 endLoop[ kConjugate ] ,
625 otherLabel(conjugationLabel),
626 const_cast<CombinatoricList< CandidateClass >*>(this)->labeledParticleList() );
627 }
628 /*
629#if defined(THIS_IS_NEVER_TRUE)
630 conjugation::Label entryLabel[ 2 ] ;
631 if ( ! isSelfConjugate() ) {
632 entryLabel[ 0 ] = kBaseLabel ;
633 entryLabel[ 1 ] = otherLabel( kBaseLabel ) ;
634 }
635 else {
636 entryLabel[ 0 ] = conjugation::kNone ;
637 }
638 const ConjugateList< CandidateClass >& initialList( (*(*(m_listOfLists.begin()))) ) ;
639 typename dchain::CandidateList< CandidateClass >::const_partial_iterator initialListEntry[ 2 ] ;
640 initialListEntry[ kPrimary ] = initialList.partial_begin() ;
641 if ( ! isSelfConjugate() ) {
642 initialListEntry[ kConjugate ] = initialList.conjugate_partial_begin() ;
643 }
644 typename dchain::CandidateList< CandidateClass >::const_iterator finished( initialList.end() ) ;
645 for ( typename dchain::CandidateList< CandidateClass >::const_iterator entry( initialList.begin() ) ;
646 entry != finished ;
647 ++entry ) {
648//
649// if entry is in `primary' half of list build all decays for this
650// entry, otherwise, if list is not self-conjugate build all decays
651// for this `conjugate' entry
652//
653 short entryType( kConjugate ) ;
654 if ( &(*entry) == &(*initialListEntry[ kPrimary ]) ) {
655 entryType = kPrimary ;
656 }
657 if ( ( kConjugate != entryType ) ||
658 ( ! isSelfConjugate() ) ) {
659 (*(*initialLoop[ entryType ])).setCurrentIterator( initialListEntry[ entryType ] ) ;
660 ReferenceHolder<DecayClass> initialDecay( new DecayClass( (*initialListEntry[ entryType ]).labeledClass() ) );
661//
662// Note: need to cast way `const' to make sure a non-const LabeledParticleList
663// is returned
664//
665 typename FillDecayList<DecayClass, CandidateClass>::ChildList childList(initialDecay.pointer());
666
667 FillDecayList< DecayClass , CandidateClass >::
668 doIt( secondLoop[ entryType ] ,
669 endLoop[ entryType ] ,
670 childList,
671 entryLabel[ entryType ] ,
672 (*(CombinatoricList< CandidateClass >*)this).labeledParticleList()
673 //this->labeledParticleList()
674 ) ;
675 ++initialListEntry[ entryType ] ;
676 }
677 }
678#endif
679 */
680//
681// delete contents of CombinatoricLoop lists.
682//
683 for ( short halfType( kPrimary ) ;
684 halfType != kEndLoopType ;
685 ++halfType ) {
686 if ( ( kConjugate != halfType ) ||
687 ( ! isSelfConjugate() ) ) {
688 typename _combinatoricloop_vector_::iterator finishedDeletion( loopList[ halfType ].end() ) ;
689 for ( typename _combinatoricloop_vector_::iterator loopInList( loopList[ halfType ].begin() ) ;
690 loopInList != finishedDeletion ;
691 ++loopInList ) {
692 delete *loopInList ;
693 }
694 }
695 }
696 m_listFilled = !false ;
697}
698
699//
700// static member functions
701//
702}
703#endif /* DCHAIN_COMBINATORICLIST_CC */
704
705
706
707
#define _combinatoriclist_vector_
#define _combinatoricloop_vector_
const Int_t n
void fill(NTuple::Array< double > &nt_p4, const HepLorentzVector &p4)
Definition: MyUtil.cxx:3
virtual dchain::DecayList< DecayClass, CandidateClass >::iterator particle_end()
virtual const dchain::DecayList< DecayClass, CandidateClass > bar() const
virtual const_partial_iterator partial_particle_end() const
virtual dchain::DecayList< DecayClass, CandidateClass >::iterator particle_begin()
virtual dchain::CandidateList< CandidateClass >::iterator end()
virtual const_partial_iterator partial_particle_begin() const
virtual bool isSelfConjugate() const
virtual dchain::CandidateList< CandidateClass >::iterator begin()
virtual dchain::LabeledCandidateList< CandidateClass > & labeledCandidateList()
virtual dchain::CandidateList< CandidateClass >::const_partial_iterator partial_end() const
virtual const dchain::DecayList< DecayClass, CandidateClass > & operator()() const
virtual conjugation::Label label() const
virtual dchain::CandidateList< CandidateClass >::const_partial_iterator partial_begin() const
const dchain::CandidateList< CandidateClass >::const_partial_iterator partial_end() const
const dchain::CandidateList< CandidateClass >::const_partial_iterator partial_begin() const
void setCurrentIterator(typename dchain::CandidateList< CandidateClass >::const_partial_iterator &aIterator)
ChildList(const DecayClass *decay)
void push_back(const CandidateClass *iCandidate)
bool overlap(const CandidateClass &iCandidate) const
static void fill(CombinatoricLoop< CandidateClass > &iLoop, const typename _combinatoricloop_vector_::iterator &aBegin, const typename _combinatoricloop_vector_::iterator &aEnd, const conjugation::Label aLabel, dchain::LabeledParticleList< DecayClass, CandidateClass > &aDecayList)
static void doIt(const typename _combinatoricloop_vector_::iterator &aBegin, const typename _combinatoricloop_vector_::iterator &aEnd, ChildList &iList, const conjugation::Label aLabel, dchain::LabeledParticleList< DecayClass, CandidateClass > &aDecayList)
void push_back(const LabeledParticle< ParticleClass > &aEntry)
conjugation::Label otherLabel(const conjugation::Label &aLabel)
Definition: conjugation.h:51