phylopomp
Phylodynamics for POMPs
Loading...
Searching...
No Matches
genealogy_t Class Reference

Encodes a genealogy. More...

#include <genealogy.h>

Inheritance diagram for genealogy_t:
Collaboration diagram for genealogy_t:

Public Member Functions

size_t ndeme (void) const
 number of demes
 
size_t & ndeme (void)
 number of demes
 
size_t bytesize (void) const
 size of serialized binary form
 
 genealogy_t (double t0=R_NaReal, size_t ndeme=0)
 
 genealogy_t (raw_t *o)
 constructor from serialized binary form
 
 genealogy_t (SEXP o)
 constructor from RAW SEXP (containing binary serialization)
 
 genealogy_t (const genealogy_t &G)
 copy constructor
 
genealogy_toperator= (const genealogy_t &G)
 copy assignment operator
 
 genealogy_t (genealogy_t &&)=default
 move constructor
 
genealogy_toperator= (genealogy_t &&)=default
 move assignment operator
 
 ~genealogy_t (void)
 destructor
 
slate_ttime (void)
 view/set current time.
 
slate_t time (void) const
 view current time.
 
slate_ttimezero (void)
 view/set zero time.
 
slate_t timezero (void) const
 get zero time.
 
void lineage_count (double *tout, int *deme, int *ell, int *sat, int *etype) const
 
SEXP lineage_count (void) const
 lineage count and saturation
 
void gendat (double *tout, int *anc, int *lin, int *sat, int *type, int *deme, int *index, int *child) const
 genealogy information in list format
 
SEXP gendat (void) const
 genealogy information in list format
 
size_t nsample (void) const
 number of samples
 
size_t nroot (void) const
 number of roots
 
string_t yaml (string_t tab="") const
 human/machine-readable info
 
SEXP structure (void) const
 R list description.
 
string_t newick (bool extended=true) const
 put genealogy at current time into Newick format.
 
void valid (void) const
 check the validity of the genealogy.
 
bool check_genealogy_size (size_t grace=0) const
 check the size of the genealogy (to prevent memory exhaustion).
 
ball_tbirth (ball_t *a, slate_t t, name_t d)
 birth into deme d
 
ball_tbirth (node_t *p, name_t d)
 birth of second or subsequent sibling into deme d
 
void death (ball_t *a, slate_t t)
 death
 
ball_tgraft (slate_t t, name_t d)
 graft a new lineage into deme d
 
void sample (ball_t *a, slate_t t)
 insert a sample node
 
void sample_death (ball_t *a, slate_t t)
 insert a sample node and simultaneously terminate the lineage
 
void migrate (ball_t *a, slate_t t, name_t d=0)
 movement into deme d
 
void sample_migrate (ball_t *a, slate_t t, name_t d=0)
 insert a sample node and simultaneously migrate the lineage
 
genealogy_tprune (void)
 prune the tree (drop all black balls)
 
genealogy_tobscure (void)
 erase all deme information
 
void curtail (slate_t tnew, slate_t troot)
 
genealogy_toperator+= (const genealogy_t &other)
 merges two genealogies, adjusting time, t0, and ndeme as needed
 
genealogy_tinsert_zlb (void)
 insert zero-length branches for samples where needed
 
genealogy_tparse (const string_t &)
 Parse a Newick string and create the indicated genealogy.
 
void time_rescale (slate_t scale, slate_t origin=0)
 
genealogy_tparse_cblv (const double *, const double *, int, double)
 parse a CBLV representation in the vectors x and y.
 
- Public Member Functions inherited from nodeseq_t
 ~nodeseq_t (void)
 destructor
 
size_t bytesize (void) const
 size of serialized binary form
 
void sort (void)
 order nodes in order of increasing time
 
pocket_tcolored (color_t col) const
 Get all balls of a color.
 
size_t ntime (slate_t t) const
 Number of distinct timepoints.
 
size_t length (void) const
 Number of nodes in the sequence.
 
node_tposition (int n)
 traverse to nth node, retrieve pointer
 
void move (ball_t *b, node_t *p, node_t *q)
 move ball b from p to q
 
void swap (ball_t *a, ball_t *b)
 swap balls a and b, wherever they lie
 
void attach (node_t *p, node_t *q)
 
void detach (node_t *p)
 
void add (node_t *p, ball_t *a)
 
void drop (ball_t *a)
 
void destroy_node (node_t *p)
 remove a dead root node
 
void weed (void)
 drop all dead roots
 
void comb (void)
 
std::unordered_map< name_t, std::vector< node_t * > > children_map (void) const
 map nodes onto vector of children
 
std::vector< node_t * > sorted_roots (const std::unordered_map< name_t, slate_t > &height) const
 collect root nodes and sort them in order of decreasing subtree height
 
std::vector< node_t * > ladderize (std::unordered_map< name_t, std::vector< node_t * > > &children) const
 
void trace_lineages (void)
 
string_t yaml (string_t tab="") const
 human/machine-readable info
 
SEXP structure (void) const
 R list description.
 
string_t newick (slate_t t, slate_t te, bool showdeme, bool extended) const
 put genealogy at time t into Newick format.
 

Private Member Functions

name_t unique (void)
 get the next unique name
 
void clean (void)
 clean up
 
node_tmake_node (name_t d=undeme)
 
void reuniqify (name_t shift)
 shifts names to avoid overlap
 
void clip_zlb (void)
 clip out all zero-length branches
 
void cap_tips (void)
 
void cap_roots (void)
 roots are added at zero time if needed
 
node_tscan_branch_label (string_t::const_iterator b, string_t::const_iterator e, node_t *p, slate_t bl)
 
std::pair< std::vector< slate_t >, std::vector< slate_t > > cblv (void) const
 

Private Attributes

name_t _unique
 The next unique name.
 
slate_t _t0
 The initial time.
 
slate_t _time
 The current time.
 
size_t _ndeme
 The number of demes (excluding the undeme).
 

Static Private Attributes

static const name_t magic = 1123581321
 

Friends

raw_toperator>> (const genealogy_t &G, raw_t *o)
 binary serialization
 
raw_toperator>> (raw_t *o, genealogy_t &G)
 binary deserialization
 
SEXP cblv (genealogy_t &A)
 return the CBLV representation as an R matrix
 

Additional Inherited Members

- Static Public Member Functions inherited from nodeseq_t
static bool compare (node_t *p, node_t *q)
 

Detailed Description

Encodes a genealogy.

A genealogy consists of a sequence of nodes and the current time.

Definition at line 20 of file genealogy.h.

Constructor & Destructor Documentation

◆ genealogy_t() [1/5]

genealogy_t::genealogy_t ( double t0 = R_NaReal,
size_t ndeme = 0 )
inline

basic constructor for genealogy class

  • t0 = initial time
  • ndeme = number of demes (excluding the undeme)

Definition at line 103 of file genealogy.h.

103 {
104 clean();
105 _time = _t0 = slate_t(t0);
106 _ndeme = ndeme;
107 };
void clean(void)
clean up
Definition genealogy.h:51
size_t ndeme(void) const
number of demes
Definition genealogy.h:60
slate_t _time
The current time.
Definition genealogy.h:35
size_t _ndeme
The number of demes (excluding the undeme).
Definition genealogy.h:37
slate_t _t0
The initial time.
Definition genealogy.h:33
double slate_t
Definition internal.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ genealogy_t() [2/5]

genealogy_t::genealogy_t ( raw_t * o)
inline

constructor from serialized binary form

Definition at line 109 of file genealogy.h.

109 {
110 o >> *this;
111 };

◆ genealogy_t() [3/5]

genealogy_t::genealogy_t ( SEXP o)
inline

constructor from RAW SEXP (containing binary serialization)

Definition at line 113 of file genealogy.h.

113 {
114 if (LENGTH(o)==0)
115 err("in %s: cannot deserialize a NULL.",__func__);
116 PROTECT(o = AS_RAW(o));
117 RAW(o) >> *this;
118 UNPROTECT(1);
119 };
#define err(...)
Definition internal.h:18

◆ genealogy_t() [4/5]

genealogy_t::genealogy_t ( const genealogy_t & G)
inline

copy constructor

Definition at line 121 of file genealogy.h.

121 {
122 raw_t *o = new raw_t[G.bytesize()];
123 G >> o;
124 o >> *this;
125 delete[] o;
126 };
size_t bytesize(void) const
size of serialized binary form
Definition genealogy.h:72
Rbyte raw_t
Definition internal.h:52
Here is the call graph for this function:

◆ genealogy_t() [5/5]

genealogy_t::genealogy_t ( genealogy_t && )
default

move constructor

Here is the call graph for this function:

◆ ~genealogy_t()

genealogy_t::~genealogy_t ( void )
inline

destructor

Definition at line 141 of file genealogy.h.

141 {
142 clean();
143 };
Here is the call graph for this function:

Member Function Documentation

◆ birth() [1/2]

ball_t * genealogy_t::birth ( ball_t * a,
slate_t t,
name_t d )
inline

birth into deme d

Definition at line 243 of file genealogy.h.

243 {
244 time() = t;
245 node_t *p = make_node(a->deme());
246 ball_t *b = new ball_t (p,p->uniq,black,d);
247 p->insert(b);
248 p->slate = time();
249 add(p,a);
250 return b;
251 };
@ black
Definition ball.h:12
name_t deme(void) const
view deme
Definition ball.h:84
slate_t & time(void)
view/set current time.
Definition genealogy.h:146
node_t * make_node(name_t d=undeme)
Definition genealogy.h:230
name_t uniq
Definition node.h:34
void insert(ball_t *a)
insert a ball into the pocket of a node
Definition node.h:167
slate_t slate
Definition node.h:35
void add(node_t *p, ball_t *a)
Definition nodeseq.h:181
Here is the call graph for this function:

◆ birth() [2/2]

ball_t * genealogy_t::birth ( node_t * p,
name_t d )
inline

birth of second or subsequent sibling into deme d

Definition at line 253 of file genealogy.h.

253 {
254 ball_t *b = new ball_t(p,unique(),black,d);
255 p->insert(b);
256 return b;
257 };
name_t unique(void)
get the next unique name
Definition genealogy.h:44
Here is the call graph for this function:

◆ bytesize()

size_t genealogy_t::bytesize ( void ) const
inline

size of serialized binary form

Definition at line 72 of file genealogy.h.

72 {
73 return 3*sizeof(name_t) +
74 2*sizeof(slate_t) + nodeseq_t::bytesize();
75 };
size_t bytesize(void) const
size of serialized binary form
Definition nodeseq.h:40
size_t name_t
Definition internal.h:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cap_roots()

void genealogy_t::cap_roots ( void )
inlineprivate

roots are added at zero time if needed

Definition at line 382 of file genealogy.h.

382 {
383 node_nit j = begin();
384 while (j != end()) {
385 if ((*j)->is_root() && (*j)->slate > timezero()) {
386 node_t *q = make_node();
387 q->slate = timezero();
388 attach(q,*j);
389 push_front(q);
390 }
391 j++;
392 }
393 sort();
394 };
slate_t & timezero(void)
view/set zero time.
Definition genealogy.h:154
void sort(void)
order nodes in order of increasing time
Definition nodeseq.h:111
void attach(node_t *p, node_t *q)
Definition nodeseq.h:171
std::list< node_t * >::iterator node_nit
Definition nodeseq.h:15
Here is the call graph for this function:

◆ cap_tips()

void genealogy_t::cap_tips ( void )
private
  • tips without descendants are reclassified as samples.
  • tips with black balls are swapped out.

Definition at line 8 of file parse.cc.

10{
11 for (node_t *p : *this) {
12 if (p->empty()) {
13 ball_t *b = new ball_t(p,p->uniq,blue,p->deme());
14 p->insert(b);
15 } else if (p->holds(black))
16 swap(p->last_ball(),p->green_ball());
17 }
18}
@ blue
Definition ball.h:12
name_t deme(void) const
view deme
Definition node.h:98
ball_t * green_ball(void) const
pointer to my green ball
Definition node.h:90
void swap(ball_t *a, ball_t *b)
swap balls a and b, wherever they lie
Definition nodeseq.h:161
ball_t * last_ball(void) const
retrieve the last ball
Definition pocket.h:118
bool holds(ball_t *b) const
does this node hold the given ball?
Definition pocket.h:101
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cblv()

std::pair< std::vector< slate_t >, std::vector< slate_t > > genealogy_t::cblv ( void ) const
private

return the CBLV representation in the vectors x and y:

  • x[i] = branch length added by the i-th sample leaf
  • y[i] = height above t0 of the i-th internal branching event

Definition at line 72 of file cblv.cc.

74{
75 auto children = children_map();
76 auto roots = ladderize(children);
77 std::vector<slate_t> x, y;
78 x.reserve(nsample());
79 y.reserve(nsample());
80 std::unordered_map<name_t, bool> memo;
81 memo.reserve(size());
82 for (node_t* p : *this) memo[p->uniq] = false;
83 slate_t t0 = timezero();
84 for (node_t* p : roots) {
85 p->cblv(x, y, memo, children, t0);
86 y.push_back(slate_t(0));
87 memo[p->uniq] = true;
88 }
89 return {x, y};
90}
size_t nsample(void) const
number of samples
Definition genealogy.h:184
void cblv(std::vector< slate_t > &, std::vector< slate_t > &, std::unordered_map< name_t, bool > &, const std::unordered_map< name_t, std::vector< node_t * > > &, slate_t) const
Definition cblv.cc:44
std::unordered_map< name_t, std::vector< node_t * > > children_map(void) const
map nodes onto vector of children
Definition nodeseq.h:249
std::vector< node_t * > ladderize(std::unordered_map< name_t, std::vector< node_t * > > &children) const
Definition nodeseq.h:283
Here is the call graph for this function:

◆ check_genealogy_size()

bool genealogy_t::check_genealogy_size ( size_t grace = 0) const
inline

check the size of the genealogy (to prevent memory exhaustion).

Definition at line 215 of file genealogy.h.

215 {
216 static size_t maxq = MEMORY_MAX/(sizeof(node_t)+2*sizeof(ball_t));
217 bool ok = true;
218 if (size() > maxq+grace) {
219 err("maximum genealogy size exceeded!"); // #nocov
220 } else if (size() > maxq) {
221 ok = false; // #nocov
222 }
223 return ok;
224 };
static const size_t MEMORY_MAX
Definition genealogy.h:14
Here is the caller graph for this function:

◆ clean()

void genealogy_t::clean ( void )
inlineprivate

clean up

Definition at line 51 of file genealogy.h.

51 {
52 _unique = 0;
53 _ndeme = 0;
54 _t0 = _time = R_NaReal;
55 };
name_t _unique
The next unique name.
Definition genealogy.h:31
Here is the caller graph for this function:

◆ clip_zlb()

void genealogy_t::clip_zlb ( void )
private

clip out all zero-length branches

Definition at line 21 of file parse.cc.

23{
24 for (node_t *p : *this) {
25 if (!p->is_root() &&
26 p->slate == p->parent()->slate &&
27 p->deme() == p->parent()->deme()) {
28 while (!p->empty()) {
29 ball_t *b = p->last_ball();
30 p->erase(b); p->parent()->insert(b);
31 }
32 detach(p);
33 }
34 }
35}
node_t * parent(void) const
Definition node.h:117
bool is_root(void) const
Definition node.h:120
void detach(node_t *p)
Definition nodeseq.h:176
Here is the call graph for this function:
Here is the caller graph for this function:

◆ curtail()

void genealogy_t::curtail ( slate_t tnew,
slate_t troot )

curtail the genealogy by removing nodes with times later than tnew and/or earlier than troot

Definition at line 11 of file curtail.cc.

13{
14 if (tnew < troot) troot = tnew;
15 if (!empty() && tnew < time()) {
16 node_t *p = back();
17 while (!empty() && p->slate > tnew) {
18 ball_t *b;
19 while (p->size() > 1) {
20 b = p->last_ball();
21 switch (b->color) {
22 case black:
23 p->erase(b); delete b;
24 break;
25 case green: case blue: // #nocov
26 assert(0); // #nocov
27 break; // #nocov
28 }
29 }
30 b = p->last_ball();
31 switch (b->color) {
32 case blue:
33 b->color = black;
34 case black:
35 b->deme() = p->deme();
36 swap(b,p->green_ball());
37 case green:
38 destroy_node(p);
39 break;
40 }
41 if (!empty()) p = back();
42 }
43 }
44 time() = tnew;
45 if (!empty() && troot > timezero()) {
46 node_t *p = front();
47 node_t *q;
48 while (!empty() && p->slate < troot) {
49 ball_t *b;
50 assert(p->is_root());
51 while (p->size() > 1) {
52 b = p->last_ball();
53 switch (b->color) {
54 case blue:
55 p->erase(b); delete b;
56 break;
57 case black:
58 q = make_node(b->deme());
59 q->slate = troot;
60 move(b,p,q); push_back(q);
61 break;
62 case green:
63 q = b->child();
64 if (q == p) {
65 b = p->first_ball();
66 q = b->child();
67 }
68 if (q->slate < troot) {
69 move(b,p,q);
70 } else {
71 node_t *pp = make_node(b->deme());
72 pp->slate = troot;
73 move(b,p,pp); push_back(pp);
74 }
75 break;
76 }
77 }
78 destroy_node(p);
79 if (!empty()) p = front();
80 }
81 sort();
82 }
83 if (troot > timezero()) timezero() = troot;
84}
@ green
Definition ball.h:12
color_t color
Definition ball.h:36
node_t * child(void) const
a child is the owner of a green ball
Definition ball.h:102
void destroy_node(node_t *p)
remove a dead root node
Definition nodeseq.h:205
void move(ball_t *b, node_t *p, node_t *q)
move ball b from p to q
Definition nodeseq.h:156
ball_t * first_ball(void) const
retrieve the first ball
Definition pocket.h:114
Here is the call graph for this function:
Here is the caller graph for this function:

◆ death()

void genealogy_t::death ( ball_t * a,
slate_t t )
inline

death

Definition at line 259 of file genealogy.h.

259 {
260 time() = t;
261 drop(a);
262 };
void drop(ball_t *a)
Definition nodeseq.h:189
Here is the call graph for this function:

◆ gendat() [1/2]

void genealogy_t::gendat ( double * tout,
int * anc,
int * lin,
int * sat,
int * type,
int * deme,
int * index,
int * child ) const

genealogy information in list format

Definition at line 8 of file gendat.cc.

11 {
12 int m, n, k;
13 node_it i, j;
14 for (k = 0, n = 0, i = begin(); i != end(); i++, n++) {
15 node_t *p = *i;
16 assert(!p->holds(black)); // tree should be pruned first
17 tout[n] = p->slate;
18 deme[n] = p->deme();
19 if (p->is_root()) {
20 type[n] = 0; // root node
21 } else if (p->holds(blue)) {
22 type[n] = 1; // sample node
23 deme[n] = p->ball(blue)->deme();
24 } else {
25 type[n] = 2; // internal node
26 }
27 lin[n] = p->lineage(); // 0-based indexing
28 sat[n] = p->nchildren();
29 index[n] = k;
30 k += sat[n];
31 child[n] = NA_INTEGER;
32 if (p->is_root()) {
33 anc[n] = n; // 0-based indexing
34 } else {
35 for (m = 0, j = begin(); j != i; j++, m++) {
36 node_t *q = *j;
37 if (p->parent()->uniq == q->uniq) {
38 anc[n] = m;
39 break;
40 }
41 }
42 }
43 }
44 tout[n] = time();
45 for (k = 0, n = 0, i = begin(); i != end(); i++, n++) {
46 node_t *p = *i;
47 j = i; j++;
48 for (m = n+1; j != end(); m++, j++) {
49 node_t *q = *j;
50 if (p->uniq == q->parent()->uniq) {
51 child[k++] = m;
52 }
53 }
54 }
55}
name_t lineage(void) const
view lineage
Definition node.h:106
int nchildren(void) const
number of descendants
Definition node.h:130
ball_t * ball(const color_t c) const
retrieve the first ball of the specified color.
Definition pocket.h:122
static const int deme
Definition lbdp.cc:7
#define n
Definition lbdp_pomp.c:9
std::list< node_t * >::const_iterator node_it
Definition nodeseq.h:14
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gendat() [2/2]

SEXP genealogy_t::gendat ( void ) const

genealogy information in list format

Definition at line 59 of file gendat.cc.

60 {
61 SEXP t0, tout, anc, lin, sat, type, deme, index, child, ns, nr, nn;
62 SEXP out, outn;
63 size_t n = length();
64 PROTECT(t0 = NEW_NUMERIC(1));
65 PROTECT(tout = NEW_NUMERIC(n+1));
66 PROTECT(type = NEW_INTEGER(n));
67 PROTECT(deme = NEW_INTEGER(n));
68 PROTECT(lin = NEW_INTEGER(n));
69 PROTECT(sat = NEW_INTEGER(n));
70 PROTECT(index = NEW_INTEGER(n));
71 PROTECT(child = NEW_INTEGER(n));
72 PROTECT(anc = NEW_INTEGER(n));
73 PROTECT(ns = NEW_INTEGER(1));
74 PROTECT(nr = NEW_INTEGER(1));
75 PROTECT(nn = NEW_INTEGER(1));
76 PROTECT(out = NEW_LIST(12));
77 PROTECT(outn = NEW_CHARACTER(12));
78 set_list_elem(out,outn,t0,"t0",0);
79 set_list_elem(out,outn,tout,"nodetime",1);
80 set_list_elem(out,outn,type,"nodetype",2);
81 set_list_elem(out,outn,deme,"deme",3);
82 set_list_elem(out,outn,lin,"lineage",4);
83 set_list_elem(out,outn,sat,"saturation",5);
84 set_list_elem(out,outn,index,"index",6);
85 set_list_elem(out,outn,child,"child",7);
86 set_list_elem(out,outn,anc,"ancestor",8);
87 set_list_elem(out,outn,ns,"nsample",9);
88 set_list_elem(out,outn,nr,"nroot",10);
89 set_list_elem(out,outn,nn,"nnode",11);
90 SET_NAMES(out,outn);
91 gendat(REAL(tout),INTEGER(anc),INTEGER(lin),INTEGER(sat),
92 INTEGER(type),INTEGER(deme),INTEGER(index),INTEGER(child));
93 *REAL(t0) = double(timezero()); // zero-time
94 *INTEGER(ns) = nsample(); // number of samples
95 *INTEGER(nr) = nroot(); // number of roots
96 *INTEGER(nn) = length(); // number of nodes
97 UNPROTECT(14);
98 return out;
99}
SEXP gendat(void) const
genealogy information in list format
Definition gendat.cc:60
size_t nroot(void) const
number of roots
Definition genealogy.h:193
size_t length(void) const
Number of nodes in the sequence.
Definition nodeseq.h:139
static int set_list_elem(SEXP list, SEXP names, SEXP element, const char *name, int pos)
Definition internal.h:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ graft()

ball_t * genealogy_t::graft ( slate_t t,
name_t d )
inline

graft a new lineage into deme d

Definition at line 264 of file genealogy.h.

264 {
265 time() = t;
266 node_t *p = make_node();
267 ball_t *b = new ball_t (p,p->uniq,black,d);
268 p->insert(b);
269 p->slate = timezero();
270 push_front(p);
271 return b;
272 };
Here is the call graph for this function:

◆ insert_zlb()

genealogy_t & genealogy_t::insert_zlb ( void )
inline

insert zero-length branches for samples where needed

Definition at line 359 of file genealogy.h.

359 {
360 for (node_t *p : *this) {
361 if (p->holds(green) && p->holds(blue)) {
362 assert(!p->holds(black)); // genealogy should have already been pruned
363 ball_t *b = p->last_ball();
364 assert(b->is(blue));
365 node_t *q = make_node(p->deme());
366 q->slate = p->slate;
367 swap(q->green_ball(),b);
368 push_back(q);
369 }
370 }
371 sort();
372 return *this;
373 };
bool is(color_t c) const
is a given ball of the given color?
Definition ball.h:115
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lineage_count() [1/2]

void genealogy_t::lineage_count ( double * tout,
int * deme,
int * ell,
int * sat,
int * etype ) const

lineage count, saturation, and event-type. types are:

  • 0 = non-event
  • -1 = root
  • 1 = sample
  • 2 = non-sample node
  • 3 = end of interval

Definition at line 39 of file lineages.cc.

42{
43 size_t nd = ndeme()+1;
44 slate_t tcur = timezero();
45 for (size_t j = 0; j < nd; j++) {
46 tout[j] = tcur;
47 deme[j] = j;
48 sat[j] = ell[j] = 0;
49 etype[j] = 0;
50 }
51 for (const node_t *p : *this) {
52 if (tcur < p->slate) {
53 tout += nd; ell += nd; sat += nd;
54 deme += nd; etype += nd;
55 tcur = p->slate;
56 for (size_t j = 0; j < nd; j++) {
57 tout[j] = tcur;
58 deme[j] = j;
59 ell[j] = (ell-nd)[j];
60 sat[j] = 0;
61 etype[j] = 0;
62 }
63 }
64 p->lineage_incr(ell,sat,etype);
65 }
66 tout += nd; ell += nd; sat += nd;
67 deme += nd; etype += nd;
68 tcur = time();
69 for (size_t j = 0; j < nd; j++) {
70 tout[j] = tcur;
71 sat[j] = ell[j] = 0;
72 deme[j] = j;
73 etype[j] = 3;
74 }
75}
void lineage_incr(int *incr, int *sat, int *etype) const
Definition lineages.cc:14
#define ell
Definition lbdp_pomp.c:11
Here is the call graph for this function:

◆ lineage_count() [2/2]

SEXP genealogy_t::lineage_count ( void ) const

lineage count and saturation

Definition at line 79 of file lineages.cc.

81{
82 SEXP tout, deme, ell, sat, etype, out, outn;
83 int nt = ntime(timezero())+1;
84 int nl = (ndeme()+1)*nt;
85 PROTECT(tout = NEW_NUMERIC(nl));
86 PROTECT(deme = NEW_INTEGER(nl));
87 PROTECT(ell = NEW_INTEGER(nl));
88 PROTECT(sat = NEW_INTEGER(nl));
89 PROTECT(etype = NEW_INTEGER(nl));
90 PROTECT(out = NEW_LIST(5));
91 PROTECT(outn = NEW_CHARACTER(5));
92 set_list_elem(out,outn,tout,"time",0);
93 set_list_elem(out,outn,deme,"deme",1);
94 set_list_elem(out,outn,ell,"lineages",2);
95 set_list_elem(out,outn,sat,"saturation",3);
96 set_list_elem(out,outn,etype,"event_type",4);
97 SET_NAMES(out,outn);
98 lineage_count(REAL(tout),INTEGER(deme),INTEGER(ell),
99 INTEGER(sat),INTEGER(etype));
100 UNPROTECT(7);
101 return out;
102}
SEXP lineage_count(void) const
lineage count and saturation
Definition lineages.cc:80
size_t ntime(slate_t t) const
Number of distinct timepoints.
Definition nodeseq.h:128
Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_node()

node_t * genealogy_t::make_node ( name_t d = undeme)
inlineprivate

create a node holding its own green ball. this does not insert into the genealogy.

Definition at line 230 of file genealogy.h.

230 {
232 name_t u = unique();
233 node_t *p = new node_t(u,_time);
234 ball_t *g = new ball_t(p,u,green,d);
235 p->green_ball() = g;
236 p->insert(g);
237 return p;
238 };
bool check_genealogy_size(size_t grace=0) const
check the size of the genealogy (to prevent memory exhaustion).
Definition genealogy.h:215
Here is the call graph for this function:
Here is the caller graph for this function:

◆ migrate()

void genealogy_t::migrate ( ball_t * a,
slate_t t,
name_t d = 0 )
inline

movement into deme d

Definition at line 293 of file genealogy.h.

293 {
294 time() = t;
295 node_t *p = make_node(a->deme());
296 p->slate = time();
297 add(p,a);
298 a->deme() = d;
299 };
Here is the call graph for this function:

◆ ndeme() [1/2]

size_t & genealogy_t::ndeme ( void )
inline

number of demes

Definition at line 64 of file genealogy.h.

64 {
65 return _ndeme;
66 };

◆ ndeme() [2/2]

size_t genealogy_t::ndeme ( void ) const
inline

number of demes

Definition at line 60 of file genealogy.h.

60 {
61 return _ndeme;
62 };
Here is the caller graph for this function:

◆ newick()

string_t genealogy_t::newick ( bool extended = true) const

put genealogy at current time into Newick format.

Definition at line 106 of file newick.cc.

108{
109 return nodeseq_t::newick(time(),timezero(),(ndeme() > 0),extended);
110}
string_t newick(slate_t t, slate_t te, bool showdeme, bool extended) const
put genealogy at time t into Newick format.
Definition newick.cc:93
Here is the call graph for this function:

◆ nroot()

size_t genealogy_t::nroot ( void ) const
inline

number of roots

Definition at line 193 of file genealogy.h.

193 {
194 size_t n = 0;
195 for (const node_t *p : *this) {
196 if (p->is_root()) n++;
197 }
198 return n;
199 };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nsample()

size_t genealogy_t::nsample ( void ) const
inline

number of samples

Definition at line 184 of file genealogy.h.

184 {
185 size_t n = 0;
186 for (const node_t *p : *this) {
187 if (p->holds(blue)) n++;
188 }
189 return n;
190 };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ obscure()

genealogy_t & genealogy_t::obscure ( void )
inline

erase all deme information

Definition at line 322 of file genealogy.h.

322 {
323 // erase deme information from black balls.
324 pocket_t *blacks = colored(black);
325 while (!blacks->empty()) {
326 ball_t *a = *(blacks->begin());
327 a->deme() = undeme;
328 blacks->erase(a);
329 }
330 delete blacks;
331 // erase deme information from nodes.
332 for (node_t *p : *this) {
333 p->deme() = undeme;
334 }
335 // drop superfluous nodes (holding just one ball).
336 comb();
337 ndeme() = 0;
338 return *this;
339 };
static const name_t undeme
Definition ball.h:15
void comb(void)
Definition nodeseq.h:223
pocket_t * colored(color_t col) const
Get all balls of a color.
Definition nodeseq.h:118
Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator+=()

genealogy_t & genealogy_t::operator+= ( const genealogy_t & other)

merges two genealogies, adjusting time, t0, and ndeme as needed

merge two genealogies:

  1. the node-sequences are merged;
  2. the root time advances as necessary;
  3. the current time retreats as necessary;
  4. the unique-name stack advances as necessary.

Definition at line 29 of file sum.cc.

31{
32 genealogy_t G = other;
33 slate_t t0 = timezero();
34 slate_t t = time();
35 t0 = (t0 < G.timezero()) ? t0 : G.timezero();
36 t = (t > G.time()) ? t : G.time();
38 merge(G,compare);
39 timezero() = t0;
40 time() = t;
41 ndeme() = (ndeme() > G.ndeme()) ? ndeme() : G.ndeme();
42 _unique = G._unique;
43 return *this;
44}
void reuniqify(name_t shift)
shifts names to avoid overlap
Definition sum.cc:21
genealogy_t(double t0=R_NaReal, size_t ndeme=0)
Definition genealogy.h:103
static bool compare(node_t *p, node_t *q)
Definition nodeseq.h:103
Here is the call graph for this function:

◆ operator=() [1/2]

genealogy_t & genealogy_t::operator= ( const genealogy_t & G)
inline

copy assignment operator

Definition at line 128 of file genealogy.h.

128 {
129 clean();
130 raw_t *o = new raw_t[G.bytesize()];
131 G >> o;
132 o >> *this;
133 delete[] o;
134 return *this;
135 };
Here is the call graph for this function:

◆ operator=() [2/2]

genealogy_t & genealogy_t::operator= ( genealogy_t && )
default

move assignment operator

Here is the call graph for this function:

◆ parse()

genealogy_t & genealogy_t::parse ( const string_t & s)

Parse a Newick string and create the indicated genealogy.

Definition at line 153 of file parse.cc.

155{
156 node_t *p = 0, *q;
157 slate_t tf = timezero();
158 slate_t bl = 0.0;
159 string_t::const_reverse_iterator f = s.crend(), e = s.crbegin(), b = e;
160 bool open = false; // branch-string reading-frame open?
161 int stack = 0, sqstack = 0;
162 if (!s.empty() && *b != ';')
163 err("in '%s': invalid Newick: no final semicolon.",__func__);
164 while (b != f) {
165 switch (*b) {
166 case ';': // root
167 if (stack != 0)
168 err("in '%s': invalid Newick: unbalanced parentheses.",__func__);
169 if (open) {
170 q = scan_branch_label(b.base(),e.base(),p,bl);
171 tf = (q->slate > tf) ? q->slate : tf;
172 bl = 0.0;
173 }
174 p = make_node();
175 p->slate = timezero();
176 push_front(p);
177 b++; e = b;
178 open = true;
179 bl = 0.0;
180 break;
181 case ')': // internal node
182 if (open) {
183 q = scan_branch_label(b.base(),e.base(),p,bl);
184 if (q->holds(black))
185 err("in '%s': 'type=extant' on internal node.",__func__);
186 tf = (q->slate > tf) ? q->slate : tf;
187 bl = 0.0;
188 p = q;
189 } else {
190 err("in '%s': invalid Newick: missing comma or semicolon.",__func__);
191 }
192 b++; e = b;
193 stack++;
194 open = true;
195 break;
196 case '(': // tip node, eldest sister
197 if (open) {
198 q = scan_branch_label(b.base(),e.base(),p,bl);
199 tf = (q->slate > tf) ? q->slate : tf;
200 bl = 0.0;
201 }
202 p = p->parent();
203 b++;
204 e = b;
205 stack--;
206 open = false;
207 break;
208 case ',': // tip node, younger sister
209 if (stack <= 0)
210 err("in '%s': invalid Newick: misplaced comma or unbalanced parentheses.",__func__);
211 if (open) {
212 q = scan_branch_label(b.base(),e.base(),p,bl);
213 tf = (q->slate > tf) ? q->slate : tf;
214 bl = 0.0;
215 }
216 b++; e = b;
217 open = true;
218 bl = 0.0;
219 break;
220 case ']': // skip metadata
221 sqstack++;
222 while (b != f && sqstack > 0) {
223 b++;
224 if (*b == ']') sqstack++;
225 if (*b == '[') sqstack--;
226 }
227 if (sqstack != 0)
228 err("in '%s': invalid Newick: unbalanced square brackets.",__func__);
229 else
230 b++;
231 break;
232 case '[':
233 err("in '%s': invalid Newick: unbalanced square brackets.",__func__);
234 break;
235 case ':':
236 if (open) {
237 bl = scan_branch_length(b.base(),e.base());
238 b++; e = b;
239 } else {
240 err("in '%s': invalid Newick: misplaced colon.",__func__);
241 }
242 break;
243 default:
244 b++;
245 break;
246 }
247 }
248 if (stack != 0)
249 err("in '%s': invalid Newick: unbalanced parentheses.",__func__);
250 if (open) {
251 q = scan_branch_label(b.base(),e.base(),p,bl);
252 tf = (q->slate > tf) ? q->slate : tf;
253 bl = 0.0;
254 }
255 time() = tf;
256 sort(); cap_tips(); clip_zlb(); weed();
257 return *this;
258}
void cap_tips(void)
Definition parse.cc:9
void clip_zlb(void)
clip out all zero-length branches
Definition parse.cc:22
node_t * scan_branch_label(string_t::const_iterator b, string_t::const_iterator e, node_t *p, slate_t bl)
Definition parse.cc:125
void weed(void)
drop all dead roots
Definition nodeseq.h:211
static slate_t scan_branch_length(string_t::const_iterator b, string_t::const_iterator e)
Scan the branch length.
Definition parse.cc:91
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_cblv()

genealogy_t & genealogy_t::parse_cblv ( const double * x,
const double * y,
int nin,
double tin )

parse a CBLV representation in the vectors x and y.

Definition at line 93 of file cblv.cc.

100{
101 if (nin <= 0) err("invalid CBLV");
102 size_t n = size_t(nin);
103 slate_t t0 = timezero();
104 slate_t t = slate_t(tin);
105 if (t < t0+slate_t(x[0]))
106 err("invalid CBLV: x[0] = %lg > %lg = time-t0", x[0], t-t0);
107 time() = t;
108 node_t* p = 0;
109 for (size_t k = 0; k < n; k++) {
110 if (p == 0) { // new root node at time t0
111 p = make_node();
112 p->slate = t0;
113 push_back(p);
114 }
115 if (x[k] < 0)
116 err("invalid CBLV: negative tip-edge length in position %zu", k+1);
117 node_t* q = make_node(); // new tip node
118 q->slate = p->slate + slate_t(x[k]);
119 attach(p, q);
120 push_back(q);
121 t = t0 + slate_t(y[k]); // new internal node time
122 if (y[k] < 0)
123 err("invalid CBLV: negative internal branch-time in position %zu", k+1);
124 if (t > t0) {
125 node_t* i = q->parent(); // points to p
126 node_t* j = q;
127 if (j->slate < t) err("invalid CBLV: node %zu cannot attach.", k+1);
128 while (j != i && i->slate > t) {
129 j = i;
130 i = i->parent();
131 }
132 assert(j != i);
133 // Create new internal node at time t
134 node_t* node = make_node();
135 node->slate = t;
136 attach(i, node);
137 move(j->green_ball(), i, node);
138 push_back(node);
139 p = node;
140 } else {
141 p = 0;
142 }
143 }
144 if (p != 0) err("invalid CBLV: last value of y is nonzero.");
145 sort(); cap_tips(); clip_zlb(); weed();
146 return *this;
147}
#define node
Definition lbdp_pomp.c:12
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prune()

genealogy_t & genealogy_t::prune ( void )
inline

prune the tree (drop all black balls)

Definition at line 311 of file genealogy.h.

311 {
312 pocket_t *blacks = colored(black);
313 while (!blacks->empty()) {
314 ball_t *b = *(blacks->begin());
315 blacks->erase(b);
316 drop(b);
317 }
318 delete blacks;
319 return *this;
320 };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reuniqify()

void genealogy_t::reuniqify ( name_t shift)
private

shifts names to avoid overlap

Definition at line 20 of file sum.cc.

22{
23 this->_unique += shift;
24 for (node_t *p : *this) p->reuniqify(shift);
25}
void reuniqify(name_t shift)
shifts name to avoid overlap
Definition sum.cc:10
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sample()

void genealogy_t::sample ( ball_t * a,
slate_t t )
inline

insert a sample node

Definition at line 274 of file genealogy.h.

274 {
275 time() = t;
276 node_t *p = make_node(a->deme());
277 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
278 p->insert(b);
279 p->slate = time();
280 add(p,a);
281 };
Here is the call graph for this function:

◆ sample_death()

void genealogy_t::sample_death ( ball_t * a,
slate_t t )
inline

insert a sample node and simultaneously terminate the lineage

Definition at line 283 of file genealogy.h.

283 {
284 time() = t;
285 node_t *p = make_node(a->deme());
286 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
287 p->insert(b);
288 p->slate = time();
289 add(p,a);
290 drop(a);
291 };
Here is the call graph for this function:

◆ sample_migrate()

void genealogy_t::sample_migrate ( ball_t * a,
slate_t t,
name_t d = 0 )
inline

insert a sample node and simultaneously migrate the lineage

Definition at line 301 of file genealogy.h.

301 {
302 time() = t;
303 node_t *p = make_node(a->deme());
304 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
305 p->insert(b);
306 p->slate = time();
307 add(p,a);
308 a->deme() = d;
309 };
Here is the call graph for this function:

◆ scan_branch_label()

node_t * genealogy_t::scan_branch_label ( string_t::const_iterator b,
string_t::const_iterator e,
node_t * parent,
slate_t bl )
private

Scan the branch-label string. This has format s[&&PhyloPOMP deme=d type=s]s

Scan the branch string. This has format s[&&PhyloPOMP deme=d type=s]s:f

Definition at line 124 of file parse.cc.

129{
130 name_t deme = 0;
131 color_t col = green;
132 if (b != e) {
133 std::smatch m;
134 if (std::regex_match(b,e,m,std::regex("^.*?\\[&&PhyloPOMP.+?deme=(\\w+).*?\\].*$")))
135 deme = scan_name(m[1].str());
136 if (std::regex_match(b,e,m,std::regex("^.*?\\[&&PhyloPOMP.+?type=(\\w+).*?\\].*$")))
137 col = scan_color(m[1].str());
138 }
139 node_t *q = make_node(deme);
140 if (col != green) {
141 ball_t *b = new ball_t(q,q->uniq,col,deme);
142 q->insert(b);
143 }
144 q->slate = bl+parent->slate;
145 attach(parent,q);
146 push_back(q);
147 ndeme() = (ndeme() > q->deme()) ? ndeme() : q->deme();
148 return q;
149}
color_t
BALL COLORS.
Definition ball.h:12
static color_t scan_color(const std::string &s)
simple function for scanning the color
Definition parse.cc:68
static name_t scan_name(const string_t &s)
Definition parse.cc:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ structure()

SEXP genealogy_t::structure ( void ) const

R list description.

Definition at line 84 of file structure.cc.

86{
87 SEXP O, On, T0, Time, Nodes, Ndeme;
88 PROTECT(O = NEW_LIST(4));
89 PROTECT(On = NEW_CHARACTER(4));
90 PROTECT(Time = NEW_NUMERIC(1));
91 *REAL(Time) = double(time());
92 PROTECT(T0 = NEW_NUMERIC(1));
93 *REAL(T0) = double(timezero());
94 PROTECT(Ndeme = NEW_INTEGER(1));
95 *INTEGER(Ndeme) = int(ndeme());
96 PROTECT(Nodes = nodeseq_t::structure());
97 set_list_elem(O,On,Time,"time",0);
98 set_list_elem(O,On,T0,"t0",1);
99 set_list_elem(O,On,Ndeme,"ndeme",2);
100 set_list_elem(O,On,Nodes,"nodes",3);
101 SET_NAMES(O,On);
102 UNPROTECT(6);
103 return O;
104}
SEXP structure(void) const
R list description.
Definition structure.cc:71
Here is the call graph for this function:

◆ time() [1/2]

slate_t & genealogy_t::time ( void )
inline

view/set current time.

Definition at line 146 of file genealogy.h.

146 {
147 return _time;
148 };
Here is the caller graph for this function:

◆ time() [2/2]

slate_t genealogy_t::time ( void ) const
inline

view current time.

Definition at line 150 of file genealogy.h.

150 {
151 return _time;
152 };

◆ time_rescale()

void genealogy_t::time_rescale ( slate_t scale,
slate_t origin = 0 )
inline

Definition at line 405 of file genealogy.h.

405 {
406 timezero() = scale*(timezero()-origin);
407 for (node_t *p : *this ) {
408 p->slate = scale*(p->slate-origin);
409 }
410 time() = scale*(time()-origin);
411 };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timezero() [1/2]

slate_t & genealogy_t::timezero ( void )
inline

view/set zero time.

Definition at line 154 of file genealogy.h.

154 {
155 return _t0;
156 };
Here is the caller graph for this function:

◆ timezero() [2/2]

slate_t genealogy_t::timezero ( void ) const
inline

get zero time.

Definition at line 158 of file genealogy.h.

158 {
159 return _t0;
160 };

◆ unique()

name_t genealogy_t::unique ( void )
inlineprivate

get the next unique name

Definition at line 44 of file genealogy.h.

44 {
45 name_t u = _unique;
46 _unique++;
47 return u;
48 };
Here is the caller graph for this function:

◆ valid()

void genealogy_t::valid ( void ) const
inline

check the validity of the genealogy.

Definition at line 213 of file genealogy.h.

213{};

◆ yaml()

string_t genealogy_t::yaml ( string_t tab = "") const

human/machine-readable info

Definition at line 63 of file yaml.cc.

65{
66 string_t o;
67 string_t t = tab + " ";
68 o = tab + "t0: " + double2string(timezero()) + "\n"
69 + tab + "time: " + double2string(time()) + "\n"
70 + tab + "ndeme: " + std::to_string(ndeme()) + "\n"
71 + tab + "nodes:\n" + nodeseq_t::yaml(tab);
72 return o;
73}
string_t yaml(string_t tab="") const
human/machine-readable info
Definition yaml.cc:52
std::string double2string(double value)
Definition newick.cc:17
Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ cblv

SEXP cblv ( genealogy_t & A)
friend

return the CBLV representation as an R matrix

Definition at line 150 of file cblv.cc.

152{
153 const char *colnames[] = {"tip","node"};
154 double *x, *y;
155 size_t i, n;
156 SEXP S;
157 std::pair<std::vector<slate_t>, std::vector<slate_t>> rep;
158 rep = A.prune().obscure().insert_zlb().cblv();
159 n = rep.first.size();
160 PROTECT(S = make_matrix(n,2,colnames));
161 x = REAL(S);
162 y = REAL(S)+n;
163 for (i = 0; i < n; i++) {
164 x[i] = rep.first[i];
165 y[i] = rep.second[i];
166 }
167 UNPROTECT(1);
168 return S;
169}
static R_INLINE SEXP make_matrix(size_t nrow, size_t ncol, const char **names)
Definition cblv.cc:13
genealogy_t & prune(void)
prune the tree (drop all black balls)
Definition genealogy.h:311
friend SEXP cblv(genealogy_t &)
return the CBLV representation as an R matrix
Definition cblv.cc:151
genealogy_t & obscure(void)
erase all deme information
Definition genealogy.h:322
genealogy_t & insert_zlb(void)
insert zero-length branches for samples where needed
Definition genealogy.h:359
#define S
Definition seirs_pomp.c:38

◆ operator>> [1/2]

raw_t * operator>> ( const genealogy_t & G,
raw_t * o )
friend

binary serialization

Definition at line 77 of file genealogy.h.

77 {
78 name_t A[3]; A[0] = magic; A[1] = G._unique; A[2] = name_t(G.ndeme());
79 slate_t B[2]; B[0] = G.timezero(); B[1] = G.time();
80 memcpy(o,A,sizeof(A)); o += sizeof(A);
81 memcpy(o,B,sizeof(B)); o += sizeof(B);
82 return reinterpret_cast<const nodeseq_t&>(G) >> o;
83 };
static const name_t magic
Definition genealogy.h:39

◆ operator>> [2/2]

raw_t * operator>> ( raw_t * o,
genealogy_t & G )
friend

binary deserialization

Definition at line 85 of file genealogy.h.

85 {
86 G.clean();
87 name_t A[3];
88 slate_t B[2];
89 memcpy(A,o,sizeof(A)); o += sizeof(A);
90 memcpy(B,o,sizeof(B)); o += sizeof(B);
91 if (A[0] != magic)
92 err("in %s: corrupted genealogy serialization.",__func__);
93 G._unique = A[1]; G.ndeme() = size_t(A[2]);
94 G.timezero() = B[0]; G.time() = B[1];
95 return o >> reinterpret_cast<nodeseq_t&>(G);
96 };

Field Documentation

◆ _ndeme

size_t genealogy_t::_ndeme
private

The number of demes (excluding the undeme).

Definition at line 37 of file genealogy.h.

◆ _t0

slate_t genealogy_t::_t0
private

The initial time.

Definition at line 33 of file genealogy.h.

◆ _time

slate_t genealogy_t::_time
private

The current time.

Definition at line 35 of file genealogy.h.

◆ _unique

name_t genealogy_t::_unique
private

The next unique name.

Definition at line 31 of file genealogy.h.

◆ magic

const name_t genealogy_t::magic = 1123581321
staticprivate

Definition at line 39 of file genealogy.h.


The documentation for this class was generated from the following files: