1 // $Id: branch.h,v 1.67 2011/12/15 18:13:37 mkkuhner Exp $
2 
3 /*
4   Copyright 2002  Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein
5 
6   This software is distributed free of charge for non-commercial use
7   and is copyrighted.  Of course, we do not guarantee that the software
8   works, and are not responsible for any damage you may cause or have.
9 */
10 
11 /*******************************************************************
12 
13  Class Branch represents a branch in the tree, and is polymorphic on the type of event at its top
14  (a coalescence, migration, etc.).  It contains auxiliary objects (a Range * and a DLCell) to manage
15  likelihood and site information.
16 
17  A Branch's parents and children are represented by vectors of Branch_ptr.
18  There may be 0, 1 or 2 parents and 0, 1 or 2 children; other values are illegal.
19 
20  As Branches are polymorphic, they are only put in containers as boost::shared_ptrs.
21  To copy a Branch use the Clone() function, which will create a new Branch of appropriate subtype.
22 
23  Branches are either Cuttable (can be cut during rearrangement) or not, and signal this by returning
24  their "count of cuttable branches" which is currently either 0 or 1.  Partition and stick branches
25  are currently non-cuttable.
26 
27  Written by Jim Sloan, heavily revised by Jon Yamato
28  -- dlcell turned into a container Mary 2002/05/28
29  -- derivation hierarchy reworked, TreeBranch class inserted
30     Branch class narrowed Jon 2003/02/24
31  -- Adding semi-unique ID numbers for each branch (the "same" branch
32     in two different trees will share the same ID number).  First
33     implementation via reference counted pointer objects.  Jon 2007/01/09
34 
35 ********************************************************************/
36 
37 #ifndef BRANCH_H
38 #define BRANCH_H
39 
40 #include <cassert>
41 #include <cmath>
42 #include <deque>
43 #include <functional>
44 #include <string>
45 #include <vector>
46 
47 #include "vectorx.h"
48 #include "constants.h"
49 #include "defaults.h"
50 #include "range.h"
51 #include "dlcell.h"
52 #include "locuscell.h"
53 #include "shared_ptr.hpp"               // for Branch_ptr (boost::shared_ptr)
54 #include "enable_shared_from_this.hpp"  // for shared_ptr support
55 #include "branchtag.h"
56 #include "rangex.h"                     // for class Range (and subclass) factory duties
57 #include "fc_status.h"                  // for RevalidateRange debug function
58 
59 // Note that some functions/variables defined here have "_Br" (for "Branch") as a suffix in their name.
60 // This is to distinguish them from functions/variables in class Range (or RecRange) of the same name, which use "_Rg".
61 
62 //------------------------------------------------------------------------------------
63 
64 class TreeSummary;
65 class TipData;
66 class BranchBuffer;
67 class Force;
68 class Branch;
69 class TBranch;
70 class TiXmlElement;
71 
72 enum branch_type {btypeBase, btypeTip, btypeCoal, btypeMig, btypeDivMig, btypeDisease, btypeRec, btypeEpoch};
73 enum branch_group {bgroupTip, bgroupBody};
74 
75 std::string ToString(branch_type btype);
76 
77 typedef boost::shared_ptr<TBranch> TBranch_ptr;
78 
79 //------------------------------------------------------------------------------------
80 
81 class Branch : public boost::enable_shared_from_this<Branch>
82 {
83   private:
84     Branch();                               // Default ctor is undefined.
85     Branch & operator=(const Branch & src); // Assignment operator is undefined.
86     vector<weakBranch_ptr> m_parents;
87     vector<weakBranch_ptr> m_children;
88 
89   protected:
90     bool m_updateDL;
91     BranchTag m_ID;
92     weakBranch_ptr m_equivBranch;
93 
94     // We own what these point to.
95     vector<LocusCell> m_DLcells;
96     vector<LocusCell> m_movingDLcells;
97 
98     virtual void CopyAllMembers(const Branch & src);
99     LongVec1d GetLocalPartitions() const; // Used by ScoreEvent.
100 
101     // Each derived branch must implement some form of Range factory function that will be called
102     // in that branch's ctor to create the new Range for that branch.  We did not implement a pure
103     // virtual base function because of the different signature needs of each of the derived
104     // branch's Range.  The current factory is named CreateRange(), which returns a Range *,
105     // a pointer to a newly-heap-allocated Range.
106     //
107     // NB: the C++ standard does not currently (2010/03/31) allow you to call polymorphically
108     // from within a ctor of base.  You will get the base instantiation of the function; if one
109     // does not exist, the compiler will/should fail.
110 
111   public:
112     LongVec1d m_partitions;
113     double m_eventTime;
114     bool m_marked;
115 
116     //************Panel Correction control parameters
117     // this exists so we don't have to reach all the way back into the xml
118     // 0 if a Panel member
119     // 1 if a Sample member
120     // 2 if a coalescence has only sample tips above it
121     int m_isSample;
122     bool m_wasCoalCalced; // coalescence DLCell has been calculated once
123     // used to prevent recalculation of type 2 coalesences
124     //************Panel Correction control parameters
125 
126     static Branch_ptr NONBRANCH;
127 
128     Range * m_rangePtr;
129 
130     Branch(Range * newrangeptr);
131     Branch(const Branch & src);
132 
133     // Destructor.  Defined to deallocated the Range object in every Branch object.
134     // The destructors for all the derived classes are default dtors which do nothing.
135     // Since this base class dtor gets called after the dtor for each derived class,
136     // this dtor will be the only one which deletes the Range object once and only once.
137     virtual ~Branch();
138 
139     // RTTI
140     virtual branch_type Event()                 const = 0;
141     virtual branch_group BranchGroup()          const = 0;
142 
Clone()143     virtual Branch_ptr Clone() const { return Branch::NONBRANCH; };
144 
145     // Convenience getters and setters.
146     long    GetID() const;
147     weakBranch_ptr GetEquivBranch() const;
148     void    SetEquivBranch(Branch_ptr twin);
149 
150     long    GetPartition(force_type) const;
151     void    SetPartition(force_type force, long val);
152     virtual void    CopyPartitionsFrom(Branch_ptr src);
153 
Child(long which)154     Branch_ptr    Child(long which) { return m_children[which].lock(); };
Parent(long which)155     Branch_ptr    Parent(long which) { return m_parents[which].lock(); };
Child(long which)156     const Branch_ptr Child(long which) const { return m_children[which].lock(); };
Parent(long which)157     const Branch_ptr Parent(long which) const { return m_parents[which].lock(); };
SetChild(long which,Branch_ptr val)158     void    SetChild(long which, Branch_ptr val) { m_children[which] = val; };
SetParent(long which,Branch_ptr val)159     void    SetParent(long which, Branch_ptr val) { m_parents[which] = val; };
NParents()160     long    NParents() const { return m_parents.size(); };
NChildren()161     long    NChildren() const { return m_children.size(); };
162 
163     // Arrangemment helpers.
164     bool    IsAMember(const Force & force, const LongVec1d & membership) const;
Cuttable()165     virtual long    Cuttable()                const { return 0; };
CanRemove(Branch_ptr)166     virtual bool    CanRemove(Branch_ptr)           { return true; };
CountDown()167     virtual long    CountDown()               const { return 0; };
UpdateBranchRange(const rangeset & fcsites,bool dofc)168     virtual void    UpdateBranchRange(const rangeset & fcsites, bool dofc) {};
UpdateRootBranchRange(const rangeset & fcsites,bool dofc)169     virtual void    UpdateRootBranchRange(const rangeset & fcsites, bool dofc) {};
170     virtual bool    IsEquivalentTo(const Branch_ptr)   const;
171     virtual bool    HasSamePartitionsAs(const Branch_ptr) const;
172     virtual bool    PartitionsConsistentWith(const Branch_ptr) const;
Nsites()173     long            Nsites() const { return m_rangePtr->NumTotalSites_Rg(); };
174 
GetLiveSites_Br()175     rangeset        GetLiveSites_Br() const { return m_rangePtr->GetLiveSites_Rg(); };
176 
IsRemovableRecombinationLeg(const rangeset &)177     virtual bool    IsRemovableRecombinationLeg(const rangeset &) const { return false; };
178 
GetRecPartner()179     virtual Branch_ptr GetRecPartner() const { return Branch::NONBRANCH; };
180     void            ResetBuffersForNextRearrangement();
181 
ResetOldTargetSites_Br(const rangeset & fcsites)182     void            ResetOldTargetSites_Br(const rangeset & fcsites) { m_rangePtr->ResetOldTargetSites_Rg(fcsites); };
183 
184     // The following routine is a no-op except in a branch where updateDL is
185     // allowed to be true, in which case it will be overridden.
SetUpdateDL()186     virtual void    SetUpdateDL()                   {};
ClearUpdateDL()187     void    ClearUpdateDL()                 { m_updateDL = false; };
GetUpdateDL()188     bool    GetUpdateDL()             const { return m_updateDL; };
189     void    MarkParentsForDLCalc();
190     virtual void    ReplaceChild(Branch_ptr oldchild, Branch_ptr newchild);
191     virtual bool    HasSameActive(const Branch & br);
192     const Cell_ptr GetDLCell(long loc, long ind, bool moving) const;
193     Cell_ptr GetDLCell(long loc, long ind, bool moving);
194 
SetDLCells(const std::vector<LocusCell> & src)195     void    SetDLCells(const std::vector<LocusCell> & src) { m_DLcells = src; };
GetNcells(long locus)196     long    GetNcells(long locus)  const { return m_DLcells[locus].size(); };
SetMovingDLCells(const std::vector<LocusCell> & src)197     void    SetMovingDLCells(const std::vector<LocusCell> & src) { m_movingDLcells = src; };
198 
199     // long    GetNcells(long locus)  const { return m_DLcells[locus].size(); };
200 
GetTime()201     double          GetTime() { return m_eventTime; };
202 
203     // Subtree maker helper.
GetRecSite_Br()204     virtual long    GetRecSite_Br()             const { return FLAGLONG; };
205 
206     // Likelihood calculation helpers.
207     virtual double  HowFarTo(const Branch & br) const;
CanCalcDL(long)208     virtual bool    CanCalcDL(long)             const { return false; };
CanCalcPanelDL(long)209     virtual bool    CanCalcPanelDL(long)        const { return false; };
ShouldCalcDL(long)210     virtual bool    ShouldCalcDL(long)          const { return false; };
211     Branch_ptr GetValidChild(Branch_ptr br, long whichpos);
212     Branch_ptr GetValidPanelChild(Branch_ptr br, long whichpos);
213     Branch_ptr GetValidParent(long whichpos);
214 
215     // Haplotyping helpers.
216     virtual bool    DiffersInDLFrom(Branch_ptr branch, long locus, long marker) const;
217 
218     // Tree summarization helpers.
219     // Some subclass functions return results via the reference second and third arguments.
220     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const = 0;
221     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const = 0;
222 
223     // Invariant checking.
224     virtual bool    operator==(const Branch & src) const;
225     bool    operator!=(const Branch & src) const { return !(*this == src); };
226 
227     // Debugging functions.
228     virtual bool    CheckInvariant()              const;
229     virtual string  DLCheck(const Branch & other)  const;
InvertUpdateDL()230     void            InvertUpdateDL() { m_updateDL = !m_updateDL; };
231     virtual void    PrintInfo_Br() const;
232     vector<Branch_ptr> GetBranchChildren(); // Used by TimeList::PrintTimeList()
233     virtual bool    IsSameExceptForTimes(const Branch_ptr other) const;
234 
235     // Used by TimeList::IsValidTimeList(), non-const because of
236     // use of boost::shared_from_this()!
237     bool            ConnectedTo(const Branch_ptr family);
238 
239     // Debugging function.
240     // Used by TimeList::RevalidateAllRanges(), must be able to handle "one-legged" forms
241     // of all branchtypes (eg. coalescence and recombination).
242     //
243     // The base class implementation will assume that there exists exactly one child and
244     // that there are no changes in the Range object between parent and child, and no
245     // changes needed to the passed argument.
246     virtual bool    RevalidateRange(FC_Status &) const;
247 
248     // GetActiveChild() is a helper function for GetValidChild()
GetActiveChild(long)249     virtual const Branch_ptr GetActiveChild(long) const { return Child(0); };
250 
251     // GetActivePanelChild() is a helper function for GetValidPanelChild()
GetActivePanelChild(long)252     virtual const Branch_ptr GetActivePanelChild(long) const { return Child(0); };
253 
254     // for writing GraphML output
255     virtual void   AddGraphML(TiXmlElement *) const;
AddNodeInfo(TiXmlElement *)256     virtual void   AddNodeInfo(TiXmlElement *) const {return;} ;
257     virtual string GetGraphMLNodeType() const = 0;
258     virtual string GetParentIDs() const;
259     virtual string GetChildIDs() const;
260     virtual long   GetCanonicalID() const;
261     virtual long   GetCanonicalParentID() const;
262 };
263 
264 //------------------------------------------------------------------------------------
265 //------------------------------------------------------------------------------------
266 
267 class BBranch : public Branch
268 {
269   private:
270     BBranch & operator=(const BBranch & src); // Assignment operator is undefined.
271 
272   protected:
273     virtual Range * CreateRange() const;
274 
275   public:
276     BBranch();                          // Need this for TimeList constructor; will construct using CreateRange().
BBranch(const BBranch & src)277     BBranch(const BBranch & src): Branch(src) {};
~BBranch()278     virtual ~BBranch() {};              // Base-class dtor deletes the Range object pointed to by m_rangePtr.
279 
280     virtual Branch_ptr Clone()               const;
Event()281     virtual branch_type Event()              const { return btypeBase; };
BranchGroup()282     virtual branch_group BranchGroup()       const { return bgroupBody; };
283 
284     // Tree summarization helpers.
285     // Some subclass functions (not this one) return results via the reference third argument.
286     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const;
287     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const;
288 
289     // Debugging function.
290     virtual bool    CheckInvariant()          const;
291 
292     // for writing GraphML output
293     virtual string GetGraphMLNodeType() const;
294 
295 };
296 
297 //------------------------------------------------------------------------------------
298 //------------------------------------------------------------------------------------
299 
300 class TBranch : public Branch
301 {
302   private:
303     TBranch();                                // Default ctor is undefined.
304     TBranch & operator=(const TBranch & src); // Assignment operator is undefined.
305 
306   protected:
307     virtual Range * CreateRange(long nsites, const rangeset & dissites) const;
308 
309   public:
310     string  m_label;
311 
312     TBranch(const TipData & tipdata, long nsites, const rangeset & dsites);
TBranch(const TBranch & src)313     TBranch(const TBranch & src) : Branch(src), m_label(src.m_label) {};
~TBranch()314     virtual ~TBranch() {};              // Base-class dtor deletes the Range object pointed to by m_rangePtr.
315 
316     virtual Branch_ptr Clone()                    const;
Event()317     virtual branch_type Event()                   const { return btypeTip; };
BranchGroup()318     virtual branch_group BranchGroup()            const { return bgroupTip; };
319 
Cuttable()320     virtual long Cuttable()                       const { return 1; };
GetActiveChild(long)321     virtual const Branch_ptr GetActiveChild(long) const { return Branch::NONBRANCH; };
322 
323     // Tree summarization helpers.
324     // Some subclass functions (not this one) return results via the reference third argument.
325     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const;
326     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const;
327 
328     // Debugging functions.
329     virtual bool    CheckInvariant()              const;
330     virtual bool    operator==(const Branch & src) const;
331     virtual bool    IsSameExceptForTimes(const Branch_ptr other) const;
332     virtual bool    RevalidateRange(FC_Status &) const;
333     virtual void    PrintInfo_Br() const;
334 
335     // for writing GraphML output
336     virtual void   AddNodeInfo(TiXmlElement *) const;
337     virtual string GetGraphMLNodeType() const;
338 };
339 
340 //------------------------------------------------------------------------------------
341 //------------------------------------------------------------------------------------
342 
343 class CBranch : public Branch
344 {
345   private:
346     CBranch();                                // Default ctor is undefined.
347     CBranch & operator=(const CBranch & src); // Assignment operator is undefined.
348 
349   protected:
350     // If newbranchisinactive == true, then child1rangeptr is assumed to point to the inactive branch Range
351     // and child2rangeptr to point to the active branch Range.
352     virtual Range * CreateRange(const Range * const child1rangeptr, const Range * const child2rangeptr,
353                                 bool  newbranchisinactive, const rangeset & fcsites) const;
354 
355   public:
356     CBranch(const Range * const child1rangeptr, const Range * const child2rangeptr, bool newbranchisinactive, const rangeset & fcsites);
CBranch(const CBranch & src)357     CBranch(const CBranch & src) : Branch(src) {};
~CBranch()358     virtual ~CBranch() {};              // Base-class dtor deletes the Range object pointed to by m_rangePtr.
359 
360     virtual Branch_ptr Clone()                  const;
Event()361     virtual branch_type Event()                 const { return btypeCoal; };
BranchGroup()362     virtual branch_group BranchGroup()          const { return bgroupBody; };
363 
Cuttable()364     virtual long    Cuttable()                  const { return 1; };
365     virtual bool    CanRemove(Branch_ptr checkchild);
CountDown()366     virtual long    CountDown()                 const { return -2; };
367     virtual void    UpdateBranchRange(const rangeset & fcsites, bool dofc);
368     virtual void    UpdateRootBranchRange(const rangeset & fcsites, bool dofc);
SetUpdateDL()369     virtual void    SetUpdateDL()                     { m_updateDL = true; };
370     virtual void    ReplaceChild(Branch_ptr oldchild, Branch_ptr newchild);
371     virtual Branch_ptr OtherChild(Branch_ptr badchild);
372     virtual bool CanCalcDL(long site) const;
ShouldCalcDL(long site)373     virtual bool ShouldCalcDL(long site) const { return m_updateDL && CanCalcDL(site); };
374     virtual const Branch_ptr GetActiveChild(long site) const;
375 
376     // Tree summarization helpers.
377     // Some subclass functions (this one does) return results via the reference third argument.
378     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const;
379     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const;
380 
381     // Debugging functions.
382     virtual bool    CheckInvariant()          const;
383     virtual bool    RevalidateRange(FC_Status & fcstatus) const;
384 
385     // for writing GraphML output
386     virtual string GetGraphMLNodeType() const;
387 };
388 
389 //------------------------------------------------------------------------------------
390 //------------------------------------------------------------------------------------
391 
392 class PartitionBranch : public Branch
393 {
394   private:
395     PartitionBranch();                                        // Default ctor is undefined.
396     PartitionBranch & operator=(const PartitionBranch & src); // Assignment operator is undefined.
397 
398   protected:
399     Range * CreateRange(const Range * const childrangeptr) const;
400 
401   public:
402     PartitionBranch(const Range * const childrangeptr);
PartitionBranch(const PartitionBranch & src)403     PartitionBranch(const PartitionBranch & src) : Branch(src) {};
~PartitionBranch()404     virtual ~PartitionBranch() {};      // Base-class dtor deletes the Range object pointed to by m_rangePtr.
405 
Cuttable()406     virtual long    Cuttable()             const { return 0; };
BranchGroup()407     virtual branch_group BranchGroup()     const { return bgroupBody; };
408     virtual void    UpdateBranchRange(const rangeset & fcsites, bool dofc);
UpdateRootBranchRange(const rangeset & fcsites,bool dofc)409     virtual void    UpdateRootBranchRange(const rangeset & fcsites, bool dofc) { assert(false); };
410 
411     // Debugging function.
412     virtual bool    CheckInvariant()       const;
413 };
414 
415 //------------------------------------------------------------------------------------
416 //------------------------------------------------------------------------------------
417 // Abstract base class for migration-like branches (MIG, DIVMIG).
418 
419 class MigLikeBranch : public PartitionBranch
420 {
421   private:
422     MigLikeBranch();                                      // Default ctor is undefined.
423     MigLikeBranch & operator=(const MigLikeBranch & src); // Assignment operator is undefined.
424 
425   protected:
426     // We accept PartitionBranch::CreateRange().
427 
428   public:
429     MigLikeBranch(const Range * const protorangeptr);
430     MigLikeBranch(const MigLikeBranch & src);
~MigLikeBranch()431     virtual ~MigLikeBranch() {};        // Base-class dtor deletes the Range object pointed to by m_rangePtr.
432 };
433 
434 //------------------------------------------------------------------------------------
435 //------------------------------------------------------------------------------------
436 
437 class MBranch : public MigLikeBranch
438 {
439   private:
440     MBranch();                                // Default ctor is undefined.
441     MBranch & operator=(const MBranch & src); // Assignment operator is undefined.
442 
443   protected:
444     // We accept PartitionBranch::CreateRange().
445 
446   public:
447     MBranch(const Range * const protorangeptr);
448     MBranch(const MBranch & src);
~MBranch()449     virtual ~MBranch() {};              // Base-class dtor deletes the Range object pointed to by m_rangePtr.
450 
451     virtual Branch_ptr Clone()             const;
Event()452     virtual branch_type Event()            const { return btypeMig; };
453 
454     // Tree summarization helpers.
455     // Some subclass functions (not this one) return results via the reference third argument.
456     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const;
457     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const;
458 
459     // for writing GraphML output
460     virtual string GetGraphMLNodeType() const;
461 };
462 
463 //------------------------------------------------------------------------------------
464 //------------------------------------------------------------------------------------
465 
466 // Migration nodes for Divergence Migration
467 class DivMigBranch : public MigLikeBranch
468 {
469   private:
470     DivMigBranch();                                     // Default ctor is undefined.
471     DivMigBranch & operator=(const DivMigBranch & src); // Assignment operator is undefined.
472 
473   protected:
474     // We accept PartitionBranch::CreateRange().
475 
476   public:
477     DivMigBranch(const Range * const protorangeptr);
478     DivMigBranch(const DivMigBranch & src);
~DivMigBranch()479     virtual ~DivMigBranch() {};         // Base-class dtor deletes the Range object pointed to by m_rangePtr.
480 
481     virtual Branch_ptr Clone()             const;
Event()482     virtual branch_type Event()            const { return btypeDivMig; };
483 
484     // Tree summarization helpers.
485     // Some subclass functions (not this one) return results via the reference third argument.
486     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const;
487     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const;
488 
489     // for writing GraphML output
490     virtual string GetGraphMLNodeType() const;
491 };
492 
493 //------------------------------------------------------------------------------------
494 //------------------------------------------------------------------------------------
495 
496 // Disease mutation branches.  NOT related to Divergence!
497 
498 class DBranch : public PartitionBranch
499 {
500   private:
501     DBranch();                                // Default ctor is undefined.
502     DBranch & operator=(const DBranch & src); // Assignment operator is undefined.
503 
504   protected:
505     // We accept PartitionBranch::CreateRange().
506 
507   public:
508     DBranch(const Range * const protorangeptr);
509     DBranch(const DBranch & src);
~DBranch()510     virtual ~DBranch() {};              // Base-class dtor deletes the Range object pointed to by m_rangePtr.
511 
512     virtual Branch_ptr Clone()             const;
Event()513     virtual branch_type Event()            const { return btypeDisease; };
BranchGroup()514     virtual branch_group BranchGroup()     const { return bgroupBody; };
515 
516     // Tree summarization helpers.
517     // Some subclass functions (not this one) return results via the reference third argument.
518     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const;
519     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const;
520 
521     // for writing GraphML output
522     virtual string GetGraphMLNodeType() const;
523 };
524 
525 //------------------------------------------------------------------------------------
526 //------------------------------------------------------------------------------------
527 
528 class EBranch : public PartitionBranch
529 {
530   private:
531     EBranch();                                // Default ctor is undefined.
532     EBranch & operator=(const EBranch & src); // Assignment operator is undefined.
533 
534   protected:
535     // We accept PartitionBranch::CreateRange().
536 
537   public:
EBranch(const Range * const protorangeptr)538     EBranch(const Range * const protorangeptr) : PartitionBranch(protorangeptr) {};
EBranch(const EBranch & src)539     EBranch(const EBranch & src) : PartitionBranch(src) {};
~EBranch()540     virtual ~EBranch() {};              // Base-class dtor deletes the Range object pointed to by m_rangePtr.
541 
542     virtual Branch_ptr Clone()         const;
Event()543     virtual branch_type Event()        const { return btypeEpoch; };
BranchGroup()544     virtual branch_group BranchGroup() const { return bgroupBody; };
545 
546     // Tree summarization helpers.
547     // Some subclass functions (not this one) return results via the reference third argument.
548     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const;
549     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const;
550 
551     // for writing GraphML output
552     virtual string GetGraphMLNodeType() const;
553 };
554 
555 //------------------------------------------------------------------------------------
556 //------------------------------------------------------------------------------------
557 
558 class RBranch : public Branch
559 {
560   private:
561     RBranch();                                // Default ctor is undefined.
562     RBranch & operator=(const RBranch & src); // Assignment operator is undefined.
563 
564   protected:
565     Range * CreateRange(const Range * const childrangeptr, bool isinactive,
566                         const rangeset & transmittedsites, const rangeset & fcsites) const;
567 
568   public:
569     RBranch(const Range * const childrangeptr, bool isinactive,
570             const rangeset & transmittedsites, const rangeset & fcsites);
RBranch(const RBranch & src)571     RBranch(const RBranch & src) : Branch(src) {};
~RBranch()572     virtual ~RBranch() {};              // Base-class dtor deletes the Range object pointed to by m_rangePtr.
573 
574     virtual Branch_ptr Clone()             const;
Event()575     virtual branch_type Event()            const { return btypeRec; };
BranchGroup()576     virtual branch_group BranchGroup()     const { return bgroupBody; };
577 
578     virtual void    CopyPartitionsFrom(Branch_ptr src);
579     void    RecCopyPartitionsFrom(Branch_ptr src, FPartMap fparts, bool islow);
580 
Cuttable()581     virtual long    Cuttable()             const { return 1; };
CountDown()582     virtual long    CountDown()            const { return 1; };
583     virtual void    UpdateBranchRange(const rangeset & fcsites, bool dofc);
UpdateRootBranchRange(const rangeset & fcsites,bool dofc)584     virtual void    UpdateRootBranchRange(const rangeset & fcsites, bool dofc) { assert(false); };
585     virtual void    ReplaceChild(Branch_ptr oldchild, Branch_ptr newchild);
586     virtual bool    IsRemovableRecombinationLeg(const rangeset &) const;
587     virtual Branch_ptr GetRecPartner()     const;
588 
GetRecSite_Br()589     virtual long    GetRecSite_Br()        const { return m_rangePtr->GetRecSite_Rg(); };
590 
591     // Tree summarization helpers.
592     // Some subclass functions (this one does) return results via the reference third argument.
593     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks) const;
594     virtual void    ScoreEvent(TreeSummary & summary, BranchBuffer & ks, long & s) const;
595 
596     virtual bool    operator==(const Branch & src) const;
597 
598     // Debugging functions.
599     virtual bool    CheckInvariant()          const;
600     virtual bool    IsSameExceptForTimes(const Branch_ptr other) const;
601     virtual bool    RevalidateRange(FC_Status & fcstatus) const;
602 
603     // for writing GraphML output
604     virtual string GetGraphMLNodeType() const;
605     virtual void   AddNodeInfo(TiXmlElement *) const;
606 };
607 
608 //------------------------------------------------------------------------------------
609 //------------------------------------------------------------------------------------
610 
611 // Free functions for use as STL predicates
612 
613 class IsTipGroup : public std::unary_function<Branch_ptr, bool>
614 {
615   public:
operator()616     bool operator()(const Branch_ptr t) { return t->BranchGroup() == bgroupTip; };
617 };
618 
619 //------------------------------------------------------------------------------------
620 
621 class IsBodyGroup : public std::unary_function<Branch_ptr, bool>
622 {
623   public:
operator()624     bool operator()(const Branch_ptr t) { return t->BranchGroup() == bgroupBody; };
625 };
626 
627 //------------------------------------------------------------------------------------
628 
629 class IsCoalGroup : public std::unary_function<Branch_ptr, bool>
630 {
631   public:
operator()632     bool operator()(const Branch_ptr t) { return t->Event() == btypeCoal; };
633 };
634 
635 #endif // BRANCH_H
636 
637 //____________________________________________________________________________________
638