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=0, name_t u=0, size_t nd=1)
 
 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
 
SEXP structure (void) const
 R list description.
 
std::string describe (void) const
 human-readable info
 
virtual std::string yaml (std::string tab="") const
 machine-readable info
 
std::string newick (void) 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).
 
node_tmake_node (name_t d)
 
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
 
std::pair< node_it, node_itextant (void) const
 
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+= (genealogy_t &G)
 
genealogy_tparse (const std::string &s, slate_t t0, node_t *p=0)
 Parse a Newick string and create the indicated genealogy.
 
- Public Member Functions inherited from nodeseq_t
 ~nodeseq_t (void)
 destructor
 
size_t bytesize (void) const
 size of serialized binary form
 
nodeseq_toperator+= (nodeseq_t &other)
 merge two node sequences
 
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 swap (ball_t *a, ball_t *b)
 swap balls a and b, wherever they lie
 
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 comb (void)
 
void trace_lineages (void)
 
std::string describe (void) const
 human-readable info
 
SEXP structure (void) const
 R list description.
 
std::string newick (slate_t t) 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
 
size_t scan_color (const std::string &s, color_t *col) const
 
size_t scan_label (const std::string &s, color_t *col, name_t *deme, slate_t *time) const
 
size_t scan_ball (const std::string &s, const slate_t t0, node_t *p)
 
size_t scan_node (const std::string &s, const slate_t t0, node_t **q)
 Scan the Newick string and create the indicated node.
 
size_t scan_tree (const std::string &s, const slate_t t0, node_t **root)
 

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.
 

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
 

Detailed Description

Encodes a genealogy.

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

Definition at line 22 of file genealogy.h.

Constructor & Destructor Documentation

◆ genealogy_t() [1/5]

genealogy_t::genealogy_t ( double t0 = 0,
name_t u = 0,
size_t nd = 1 )
inline

basic constructor for genealogy class t0 = initial time

Definition at line 105 of file genealogy.h.

105 {
106 clean();
107 _ndeme = nd;
108 _unique = u;
109 _time = _t0 = slate_t(t0);
110 };
void clean(void)
clean up
Definition genealogy.h:53
slate_t _time
The current time.
Definition genealogy.h:37
size_t _ndeme
The number of demes.
Definition genealogy.h:39
slate_t _t0
The initial time.
Definition genealogy.h:35
name_t _unique
The next unique name.
Definition genealogy.h:33
double slate_t
Definition internal.h:44
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 112 of file genealogy.h.

112 {
113 o >> *this;
114 };

◆ genealogy_t() [3/5]

genealogy_t::genealogy_t ( SEXP o)
inline

constructor from RAW SEXP (containing binary serialization)

Definition at line 116 of file genealogy.h.

116 {
117 if (LENGTH(o)==0)
118 err("in %s (%s line %d): cannot deserialize a NULL.",
119 __func__,__FILE__,__LINE__);
120 PROTECT(o = AS_RAW(o));
121 RAW(o) >> *this;
122 UNPROTECT(1);
123 };
#define err(...)
Definition internal.h:18

◆ genealogy_t() [4/5]

genealogy_t::genealogy_t ( const genealogy_t & G)
inline

copy constructor

Definition at line 125 of file genealogy.h.

125 {
126 raw_t *o = new raw_t[G.bytesize()];
127 G >> o;
128 o >> *this;
129 delete[] o;
130 };
size_t bytesize(void) const
size of serialized binary form
Definition genealogy.h:73
Rbyte raw_t
Definition internal.h:43
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 145 of file genealogy.h.

145 {
146 clean();
147 };
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 407 of file genealogy.h.

407 {
408 time() = t;
409 node_t *p = make_node(a->deme());
410 ball_t *b = new ball_t (p,p->uniq,black,d);
411 p->insert(b);
412 p->slate = time();
413 add(p,a);
414 return b;
415 };
@ black
Definition ball.h:14
name_t deme(void) const
view deme
Definition ball.h:86
node_t * make_node(name_t d)
Definition genealogy.h:394
slate_t & time(void)
view/set current time.
Definition genealogy.h:150
name_t uniq
Definition node.h:34
slate_t slate
Definition node.h:35
void add(node_t *p, ball_t *a)
Definition nodeseq.h:179
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 417 of file genealogy.h.

417 {
418 ball_t *b = new ball_t(p,unique(),black,d);
419 p->insert(b);
420 return b;
421 };
name_t unique(void)
get the next unique name
Definition genealogy.h:46
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 73 of file genealogy.h.

73 {
74 return 3*sizeof(name_t) +
75 2*sizeof(slate_t) + nodeseq_t::bytesize();
76 };
size_t bytesize(void) const
size of serialized binary form
Definition nodeseq.h:40
size_t name_t
Definition internal.h:45
Here is the call graph for this function:
Here is the caller 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 379 of file genealogy.h.

379 {
380 static size_t maxq = MEMORY_MAX/(sizeof(node_t)+2*sizeof(ball_t));
381 bool ok = true;
382 if (size() > maxq+grace) {
383 err("maximum genealogy size exceeded!"); // #nocov
384 } else if (size() > maxq) {
385 ok = false; // #nocov
386 }
387 return ok;
388 };
static const size_t MEMORY_MAX
Definition genealogy.h:16
Here is the caller graph for this function:

◆ clean()

void genealogy_t::clean ( void )
inlineprivate

clean up

Definition at line 53 of file genealogy.h.

53 {
54 _unique = 0;
55 _t0 = _time = R_NaReal;
56 };
Here is the caller graph for this function:

◆ curtail()

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

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

Definition at line 511 of file genealogy.h.

511 {
512 if (tnew < troot) troot = tnew;
513 if (!empty() && tnew < time()) {
514 node_t *p = back();
515 while (!empty() && p->slate > tnew) {
516 ball_t *b;
517 while (p->size() > 1) {
518 b = p->last_ball();
519 switch (b->color) {
520 case black:
521 p->erase(b); delete b;
522 break;
523 case green: case blue: // #nocov
524 assert(0); // #nocov
525 break; // #nocov
526 }
527 }
528 b = p->last_ball();
529 switch (b->color) {
530 case blue:
531 b->color = black;
532 case black:
533 b->deme() = p->deme();
534 swap(b,p->green_ball());
535 case green:
536 destroy_node(p);
537 break;
538 }
539 if (!empty()) p = back();
540 }
541 }
542 time() = tnew;
543 if (!empty() && troot > timezero()) {
544 node_t *p = front();
545 node_t *q;
546 while (!empty() && p->slate < troot) {
547 ball_t *b;
548 assert(p->holds_own());
549 while (p->size() > 1) {
550 b = p->last_ball();
551 switch (b->color) {
552 case blue:
553 p->erase(b); delete b;
554 break;
555 case black:
556 q = make_node(b->deme());
557 q->slate = troot;
558 q->insert(b); p->erase(b);
559 b->holder() = q;
560 push_back(q);
561 break;
562 case green:
563 q = b->child();
564 if (q == p) {
565 b = p->first_ball();
566 q = b->child();
567 }
568 if (q->slate < troot) {
569 q->insert(b); p->erase(b);
570 b->holder() = q;
571 } else {
572 node_t *pp = make_node(b->deme());
573 pp->slate = troot;
574 pp->insert(b); p->erase(b);
575 b->holder() = pp;
576 push_back(pp);
577 }
578 break;
579 }
580 }
581 destroy_node(p);
582 if (!empty()) p = front();
583 }
584 sort();
585 }
586 if (troot > timezero()) timezero() = troot;
587 };
@ green
Definition ball.h:14
@ blue
Definition ball.h:14
node_t * holder(void) const
in whose pocket do I lie?
Definition ball.h:109
color_t color
Definition ball.h:38
node_t * child(void) const
a child is the owner of a green ball
Definition ball.h:104
slate_t & timezero(void)
view/set zero time.
Definition genealogy.h:158
name_t deme(void) const
view deme
Definition node.h:96
ball_t * green_ball(void) const
pointer to my green ball
Definition node.h:88
bool holds_own(void) const
Definition node.h:118
void sort(void)
order nodes in order of increasing time
Definition nodeseq.h:113
void destroy_node(node_t *p)
remove a dead root node
Definition nodeseq.h:203
void swap(ball_t *a, ball_t *b)
swap balls a and b, wherever they lie
Definition nodeseq.h:169
ball_t * last_ball(void) const
retrieve the last ball
Definition pocket.h:128
ball_t * first_ball(void) const
retrieve the first ball
Definition pocket.h:124
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 423 of file genealogy.h.

423 {
424 time() = t;
425 drop(a);
426 };
void drop(ball_t *a)
Definition nodeseq.h:187
Here is the call graph for this function:

◆ describe()

std::string genealogy_t::describe ( void ) const
inline

human-readable info

Definition at line 348 of file genealogy.h.

348 {
349 std::string o = "t0 = " + std::to_string(double(timezero()))
350 + "\ntime = " + std::to_string(double(time())) + "\n"
352 return o;
353 };
std::string describe(void) const
human-readable info
Definition nodeseq.h:262
Here is the call graph for this function:

◆ extant()

std::pair< node_it, node_it > genealogy_t::extant ( void ) const
inline

set up for extraction of black balls (see 'inventory.h')

Definition at line 476 of file genealogy.h.

476 {
477 return std::pair<node_it,node_it>(cbegin(),cend());
478 };
Here is the caller 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
inline

genealogy information in list format

Definition at line 233 of file genealogy.h.

235 {
236 int m, n, k;
237 node_it i, j;
238 for (k = 0, n = 0, i = begin(); i != end(); i++, n++) {
239 node_t *p = *i;
240 assert(!p->holds(black)); // tree should be pruned first
241 tout[n] = p->slate;
242 deme[n] = p->deme();
243 if (p->is_root()) {
244 type[n] = 0; // root node
245 } else if (p->holds(blue)) {
246 type[n] = 1; // sample node
247 deme[n] = p->ball(blue)->deme();
248 } else {
249 type[n] = 2; // internal node
250 }
251 lin[n] = p->lineage(); // 0-based indexing
252 sat[n] = p->nchildren();
253 index[n] = k;
254 k += sat[n];
255 child[n] = NA_INTEGER;
256 if (p->is_root()) {
257 anc[n] = n; // 0-based indexing
258 } else {
259 for (m = 0, j = begin(); j != i; j++, m++) {
260 node_t *q = *j;
261 if (p->parent()->uniq == q->uniq) {
262 anc[n] = m;
263 break;
264 }
265 }
266 }
267 }
268 tout[n] = time();
269 for (k = 0, n = 0, i = begin(); i != end(); i++, n++) {
270 node_t *p = *i;
271 j = i; j++;
272 for (m = n+1; j != end(); m++, j++) {
273 node_t *q = *j;
274 if (p->uniq == q->parent()->uniq) {
275 child[k++] = m;
276 }
277 }
278 }
279 };
node_t * parent(void) const
Definition node.h:115
name_t lineage(void) const
view lineage
Definition node.h:104
bool is_root(void) const
Definition node.h:121
int nchildren(void) const
number of descendants
Definition node.h:131
ball_t * ball(const color_t c) const
retrieve the first ball of the specified color.
Definition pocket.h:132
bool holds(ball_t *b) const
does this node hold the given ball?
Definition pocket.h:111
static const int deme
Definition lbdp.cc:7
#define n
Definition lbdp_pomp.c:8
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
inline

genealogy information in list format

Definition at line 281 of file genealogy.h.

281 {
282 SEXP tout, anc, lin, sat, type, deme, index, child, ns, nn;
283 SEXP out, outn;
284 size_t n = length();
285 PROTECT(tout = NEW_NUMERIC(n+1));
286 PROTECT(type = NEW_INTEGER(n));
287 PROTECT(deme = NEW_INTEGER(n));
288 PROTECT(lin = NEW_INTEGER(n));
289 PROTECT(sat = NEW_INTEGER(n));
290 PROTECT(index = NEW_INTEGER(n));
291 PROTECT(child = NEW_INTEGER(n));
292 PROTECT(anc = NEW_INTEGER(n));
293 PROTECT(ns = NEW_INTEGER(1));
294 PROTECT(nn = NEW_INTEGER(1));
295 PROTECT(out = NEW_LIST(10));
296 PROTECT(outn = NEW_CHARACTER(10));
297 set_list_elem(out,outn,tout,"nodetime",0);
298 set_list_elem(out,outn,type,"nodetype",1);
299 set_list_elem(out,outn,deme,"deme",2);
300 set_list_elem(out,outn,lin,"lineage",3);
301 set_list_elem(out,outn,sat,"saturation",4);
302 set_list_elem(out,outn,index,"index",5);
303 set_list_elem(out,outn,child,"child",6);
304 set_list_elem(out,outn,anc,"ancestor",7);
305 set_list_elem(out,outn,ns,"nsample",8);
306 set_list_elem(out,outn,nn,"nnode",9);
307 SET_NAMES(out,outn);
308 gendat(REAL(tout),INTEGER(anc),INTEGER(lin),INTEGER(sat),
309 INTEGER(type),INTEGER(deme),INTEGER(index),INTEGER(child));
310 *INTEGER(ns) = nsample(); // number of samples
311 *INTEGER(nn) = length(); // number of nodes
312 UNPROTECT(12);
313 return out;
314 };
size_t nsample(void) const
number of samples
Definition genealogy.h:317
SEXP gendat(void) const
genealogy information in list format
Definition genealogy.h:281
size_t length(void) const
Number of nodes in the sequence.
Definition nodeseq.h:152
static int set_list_elem(SEXP list, SEXP names, SEXP element, const char *name, int pos)
Definition internal.h:67
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 428 of file genealogy.h.

428 {
429 time() = t;
430 node_t *p = make_node(d);
431 ball_t *b = new ball_t (p,p->uniq,black,d);
432 p->insert(b);
433 p->slate = timezero();
434 push_front(p);
435 return b;
436 };
Here is the call graph for this function:

◆ lineage_count() [1/2]

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

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 175 of file genealogy.h.

176 {
177 slate_t tcur = timezero();
178 for (size_t j = 0; j < _ndeme; j++) {
179 tout[j] = tcur;
180 deme[j] = j+1;
181 sat[j] = ell[j] = 0;
182 etype[j] = 0;
183 }
184 for (const node_t *p : *this) {
185 if (tcur < p->slate) {
186 tout += _ndeme; ell += _ndeme; sat += _ndeme;
187 deme += _ndeme; etype += _ndeme;
188 tcur = p->slate;
189 for (size_t j = 0; j < _ndeme; j++) {
190 tout[j] = tcur;
191 deme[j] = j+1;
192 ell[j] = (ell-_ndeme)[j];
193 sat[j] = 0;
194 etype[j] = 0;
195 }
196 }
197 p->lineage_incr(ell,sat,etype);
198 }
199 tout += _ndeme; ell += _ndeme; sat += _ndeme;
200 deme += _ndeme; etype += _ndeme;
201 tcur = time();
202 for (size_t j = 0; j < _ndeme; j++) {
203 tout[j] = tcur;
204 sat[j] = ell[j] = 0;
205 deme[j] = j+1;
206 etype[j] = 3;
207 }
208 };
void lineage_incr(int *incr, int *sat, int *etype) const
Definition node.h:151
#define ell
Definition lbdp_pomp.c:10
Here is the call graph for this function:

◆ lineage_count() [2/2]

SEXP genealogy_t::lineage_count ( void ) const
inline

lineage count and saturation

Definition at line 210 of file genealogy.h.

210 {
211 SEXP tout, deme, ell, sat, etype, out, outn;
212 int nt = ntime(timezero())+1;
213 int nl = _ndeme*nt;
214 PROTECT(tout = NEW_NUMERIC(nl));
215 PROTECT(deme = NEW_INTEGER(nl));
216 PROTECT(ell = NEW_INTEGER(nl));
217 PROTECT(sat = NEW_INTEGER(nl));
218 PROTECT(etype = NEW_INTEGER(nl));
219 PROTECT(out = NEW_LIST(5));
220 PROTECT(outn = NEW_CHARACTER(5));
221 set_list_elem(out,outn,tout,"time",0);
222 set_list_elem(out,outn,deme,"deme",1);
223 set_list_elem(out,outn,ell,"lineages",2);
224 set_list_elem(out,outn,sat,"saturation",3);
225 set_list_elem(out,outn,etype,"event_type",4);
226 SET_NAMES(out,outn);
227 lineage_count(REAL(tout),INTEGER(deme),INTEGER(ell),
228 INTEGER(sat),INTEGER(etype));
229 UNPROTECT(7);
230 return out;
231 };
SEXP lineage_count(void) const
lineage count and saturation
Definition genealogy.h:210
size_t ntime(slate_t t) const
Number of distinct timepoints.
Definition nodeseq.h:141
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)
inline

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

Definition at line 394 of file genealogy.h.

394 {
396 name_t u = unique();
397 node_t *p = new node_t(u,_time);
398 ball_t *g = new ball_t(p,u,green,d);
399 p->green_ball() = g;
400 p->insert(g);
401 return p;
402 };
bool check_genealogy_size(size_t grace=0) const
check the size of the genealogy (to prevent memory exhaustion).
Definition genealogy.h:379
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 457 of file genealogy.h.

457 {
458 time() = t;
459 node_t *p = make_node(a->deme());
460 p->slate = time();
461 add(p,a);
462 a->deme() = d;
463 };
Here is the call graph for this function:

◆ ndeme() [1/2]

size_t & genealogy_t::ndeme ( void )
inline

number of demes

Definition at line 65 of file genealogy.h.

65 {
66 return _ndeme;
67 };

◆ ndeme() [2/2]

size_t genealogy_t::ndeme ( void ) const
inline

number of demes

Definition at line 61 of file genealogy.h.

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

◆ newick()

std::string genealogy_t::newick ( void ) const
inline

put genealogy at current time into Newick format.

Definition at line 370 of file genealogy.h.

370 {
371 return nodeseq_t::newick(time());
372 };
std::string newick(slate_t t) const
put genealogy at time t into Newick format.
Definition nodeseq.h:290
Here is the call graph for this function:

◆ nsample()

size_t genealogy_t::nsample ( void ) const
inline

number of samples

Definition at line 317 of file genealogy.h.

317 {
318 size_t n = 0;
319 for (const node_t *p : *this) {
320 if (p->holds(blue)) n++;
321 }
322 return n;
323 };
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 491 of file genealogy.h.

491 {
492 // erase deme information from black balls.
493 pocket_t *blacks = colored(black);
494 while (!blacks->empty()) {
495 ball_t *a = *(blacks->begin());
496 a->deme() = 0;
497 blacks->erase(a);
498 }
499 delete blacks;
500 // erase deme information from nodes.
501 for (node_t *p : *this) {
502 p->deme() = 0;
503 }
504 // drop superfluous nodes (holding just one ball).
505 comb();
506 _ndeme = 1;
507 return *this;
508 };
void comb(void)
Definition nodeseq.h:210
pocket_t * colored(color_t col) const
Get all balls of a color.
Definition nodeseq.h:131
Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator+=()

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

merge two genealogies:

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

Definition at line 593 of file genealogy.h.

593 {
594 reinterpret_cast<nodeseq_t&>(*this) += reinterpret_cast<nodeseq_t&>(G);
595 _t0 = (_t0 > G._t0) ? G._t0 : _t0;
596 _time = (_time < G._time) ? G._time : _time;
597 _unique = (_unique < G._unique) ? G._unique : _unique;
598 _ndeme = (_ndeme < G.ndeme()) ? G.ndeme() : _ndeme;
599 return *this;
600 };
size_t ndeme(void) const
number of demes
Definition genealogy.h:61
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 132 of file genealogy.h.

132 {
133 clean();
134 raw_t *o = new raw_t[G.bytesize()];
135 G >> o;
136 o >> *this;
137 delete[] o;
138 return *this;
139 };
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 std::string & s,
slate_t t0,
node_t * p = 0 )
inline

Parse a Newick string and create the indicated genealogy.

Definition at line 754 of file genealogy.h.

754 {
755 size_t i = 0;
756 size_t n = s.size();
757 while (i < n) {
758 switch (s[i]) {
759 case '(':
760 {
761 genealogy_t G(t0,unique());
762 node_t *q = 0;
763 i += G.scan_tree(s.substr(i),t0,&q);
764 *this += G;
765 if (p != 0) {
766 ball_t *g = q->green_ball();
767 q->erase(g); p->insert(g); g->holder() = p;
768 }
769 }
770 break;
771 case 'b':
772 {
773 node_t *q = 0;
774 i += scan_node(s.substr(i),t0,&q);
775 if (p != 0) {
776 ball_t *g = q->green_ball();
777 q->erase(g); p->insert(g); g->holder() = p;
778 }
779 }
780 break;
781 case 'o':
782 i += scan_ball(s.substr(i),t0,p);
783 break;
784 case ',': case ';': case ' ': case '\n': case '\t':
785 i++;
786 break;
787 case ')':
788 err("in '%s': invalid Newick string: unbalanced parentheses.",__func__);
789 break;
790 default:
791 err("in '%s': invalid Newick string.",__func__);
792 break;
793 }
794 }
795 sort();
796 return *this;
797 };
genealogy_t(double t0=0, name_t u=0, size_t nd=1)
Definition genealogy.h:105
size_t scan_ball(const std::string &s, const slate_t t0, node_t *p)
Definition genealogy.h:683
size_t scan_node(const std::string &s, const slate_t t0, node_t **q)
Scan the Newick string and create the indicated node.
Definition genealogy.h:699
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 480 of file genealogy.h.

480 {
481 pocket_t *blacks = colored(black);
482 while (!blacks->empty()) {
483 ball_t *b = *(blacks->begin());
484 blacks->erase(b);
485 drop(b);
486 }
487 delete blacks;
488 return *this;
489 };
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 438 of file genealogy.h.

438 {
439 time() = t;
440 node_t *p = make_node(a->deme());
441 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
442 p->insert(b);
443 p->slate = time();
444 add(p,a);
445 };
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 447 of file genealogy.h.

447 {
448 time() = t;
449 node_t *p = make_node(a->deme());
450 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
451 p->insert(b);
452 p->slate = time();
453 add(p,a);
454 drop(a);
455 };
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 465 of file genealogy.h.

465 {
466 time() = t;
467 node_t *p = make_node(a->deme());
468 ball_t *b = new ball_t (p,p->uniq,blue,a->deme());
469 p->insert(b);
470 p->slate = time();
471 add(p,a);
472 a->deme() = d;
473 };
Here is the call graph for this function:

◆ scan_ball()

size_t genealogy_t::scan_ball ( const std::string & s,
const slate_t t0,
node_t * p )
inlineprivate

Scan the Newick string and put the ball into the indicated pocket, as appropriate.

Definition at line 683 of file genealogy.h.

683 {
684 color_t col;
685 name_t deme;
686 slate_t t;
687 ball_t *b;
688 size_t i = scan_label(s,&col,&deme,&t);
689 t += t0;
690 _time = (_time < t) ? t : _time;
691 _ndeme = (_ndeme <= deme) ? deme+1 : _ndeme;
692 if (col != black) err("in '%s': bad Newick string (1)",__func__);
693 if (p == 0) err("in '%s': bad Newick string (2)",__func__);
694 b = new ball_t(p,unique(),col,deme);
695 p->insert(b);
696 return i;
697 };
color_t
BALL COLORS.
Definition ball.h:14
size_t scan_label(const std::string &s, color_t *col, name_t *deme, slate_t *time) const
Definition genealogy.h:609
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scan_color()

size_t genealogy_t::scan_color ( const std::string & s,
color_t * col ) const
inlineprivate

Definition at line 604 of file genealogy.h.

604 {
605 return 1;
606 };

◆ scan_label()

size_t genealogy_t::scan_label ( const std::string & s,
color_t * col,
name_t * deme,
slate_t * time ) const
inlineprivate

Scan the Newick-format label string. This has format c_d_d:f

Definition at line 609 of file genealogy.h.

610 {
611 size_t n = s.size();
612 if (n < 1)
613 err("in '%s' (%s line %d): invalid Newick format: empty label.",__func__,__FILE__,__LINE__);
614 size_t sz, i = 1;
615 switch (s[0]) {
616 case 'o':
617 *col = black;
618 break;
619 case 'b':
620 *col = blue;
621 break;
622 case 'g': case 'm':
623 *col = green;
624 break;
625 default:
626 err("in '%s' (%s line %d): invalid Newick label: expected one of 'b','g','m', or 'o', got '%c'.",
627 __func__,__FILE__,__LINE__,s[0]);
628 break;
629 }
630 while (i < n && s[i] == '_') i++;
631 if (i == n)
632 err("in '%s': invalid Newick format: premature termination.",__func__);
633 if (s[i] == '(' || s[i] == ')' || s[i] == ',' || s[i] == ';')
634 err("in '%s' (%s line %d): invalid Newick format.",__func__,__FILE__,__LINE__);
635 if (s[i] == ':') {
636 *deme = 0;
637 } else {
638 try {
639 *deme = name_t(stoi(s.substr(i),&sz));
640 i += sz;
641 }
642 catch (const std::invalid_argument& e) {
643 err("in '%s' (%s line %d): invalid Newick format: deme should be indicated with an integer.",
644 __func__,__FILE__,__LINE__);
645 }
646 catch (const std::out_of_range& e) {
647 err("in '%s': invalid Newick format: deme out of range.",__func__);
648 }
649 catch (const std::exception& e) {
650 err("in '%s': parsing deme label: %s.",__func__,e.what());
651 }
652 catch (...) {
653 err("in '%s': other deme-parsing error.",__func__);
654 }
655 }
656 // skip to branch length
657 while (i < n && s[i] != ':' &&
658 s[i] != '(' && s[i] != ')' && s[i] != ',' && s[i] != ';') i++;
659 if (i == n || s[i] != ':')
660 err("in '%s': invalid Newick format: missing or invalid branch length.",__func__);
661 i++;
662 try {
663 *time = slate_t(stod(s.substr(i),&sz));
664 }
665 catch (const std::invalid_argument& e) {
666 err("in '%s': invalid Newick format: branch length should be a non-negative decimal number.",__func__);
667 }
668 catch (const std::out_of_range& e) {
669 err("in '%s': invalid Newick format: branch length out of range.",__func__);
670 }
671 catch (const std::exception& e) {
672 err("in '%s': parsing branch-length: %s.",__func__,e.what());
673 }
674 catch (...) {
675 err("in '%s': other branch-length parsing error.",__func__);
676 }
677 if (*time < 0.0) err("in '%s': negative branch length detected.",__func__);
678 i += sz;
679 return i;
680 };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scan_node()

size_t genealogy_t::scan_node ( const std::string & s,
const slate_t t0,
node_t ** q )
inlineprivate

Scan the Newick string and create the indicated node.

Definition at line 699 of file genealogy.h.

699 {
700 size_t i;
701 color_t col;
702 name_t deme;
703 slate_t t;
704 name_t u = unique();
705 i = scan_label(s,&col,&deme,&t);
706 t += t0;
707 _ndeme = (_ndeme <= deme) ? deme+1 : _ndeme;
708 _time = (_time < t) ? t : _time;
709 node_t *p = new node_t(u,t);
710 ball_t *g = new ball_t(p,u,green,deme);
711 p->green_ball() = g;
712 p->insert(g);
713 if (col==blue) {
714 ball_t *b = new ball_t(p,p->uniq,blue,deme);
715 p->insert(b);
716 }
717 push_back(p);
718 *q = p;
719 return i;
720 };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scan_tree()

size_t genealogy_t::scan_tree ( const std::string & s,
const slate_t t0,
node_t ** root )
inlineprivate

Parse a single-root Newick tree. This assumes the string starts with a '('.

Definition at line 723 of file genealogy.h.

724 {
725 size_t n = s.size();
726 size_t i = 1, j = 1, k;
727 size_t stack = 1;
728 while (j < n && stack > 0) {
729 switch (s[j]) {
730 case '(':
731 stack++;
732 break;
733 case ')':
734 stack--;
735 break;
736 default:
737 break;
738 }
739 j++;
740 }
741 if (stack > 0)
742 err("in '%s': premature end of Newick string.",__func__);
743 node_t *p = 0;
744 k = j;
745 k += scan_node(s.substr(j),t0,&p);
746 parse(s.substr(i,j-i-1),p->slate,p);
747 *root = p;
748 return k;
749 };
genealogy_t & parse(const std::string &s, slate_t t0, node_t *p=0)
Parse a Newick string and create the indicated genealogy.
Definition genealogy.h:754
Here is the call graph for this function:
Here is the caller graph for this function:

◆ structure()

SEXP genealogy_t::structure ( void ) const
inline

R list description.

Definition at line 328 of file genealogy.h.

328 {
329 SEXP O, On, T0, Time, Nodes;
330 PROTECT(O = NEW_LIST(3));
331 PROTECT(On = NEW_CHARACTER(3));
332 PROTECT(Time = NEW_NUMERIC(1));
333 *REAL(Time) = double(time());
334 PROTECT(T0 = NEW_NUMERIC(1));
335 *REAL(T0) = double(timezero());
336 PROTECT(Nodes = nodeseq_t::structure());
337 set_list_elem(O,On,Time,"time",0);
338 set_list_elem(O,On,T0,"t0",1);
339 set_list_elem(O,On,Nodes,"nodes",2);
340 SET_NAMES(O,On);
341 UNPROTECT(5);
342 return O;
343 };
SEXP structure(void) const
R list description.
Definition nodeseq.h:279
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 150 of file genealogy.h.

150 {
151 return _time;
152 };
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 154 of file genealogy.h.

154 {
155 return _time;
156 };

◆ timezero() [1/2]

slate_t & genealogy_t::timezero ( void )
inline

view/set zero time.

Definition at line 158 of file genealogy.h.

158 {
159 return _t0;
160 };
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 162 of file genealogy.h.

162 {
163 return _t0;
164 };

◆ unique()

name_t genealogy_t::unique ( void )
inlineprivate

get the next unique name

Definition at line 46 of file genealogy.h.

46 {
47 name_t u = _unique;
48 _unique++;
49 return u;
50 };
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 377 of file genealogy.h.

377{};

◆ yaml()

virtual std::string genealogy_t::yaml ( std::string tab = "") const
inlinevirtual

machine-readable info

Reimplemented from nodeseq_t.

Definition at line 358 of file genealogy.h.

358 {
359 std::string o;
360 std::string t = tab + " ";
361 o = tab + "t0: " + std::to_string(timezero()) + "\n"
362 + tab + "time: " + std::to_string(time()) + "\n"
363 + tab + "nodes:\n" + nodeseq_t::yaml(tab);
364 return o;
365 };
virtual std::string yaml(std::string tab="") const
human- & machine-readable info
Definition nodeseq.h:270
Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ operator>> [1/2]

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

binary serialization

Definition at line 78 of file genealogy.h.

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

◆ operator>> [2/2]

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

binary deserialization

Definition at line 86 of file genealogy.h.

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

Field Documentation

◆ _ndeme

size_t genealogy_t::_ndeme
private

The number of demes.

Definition at line 39 of file genealogy.h.

◆ _t0

slate_t genealogy_t::_t0
private

The initial time.

Definition at line 35 of file genealogy.h.

◆ _time

slate_t genealogy_t::_time
private

The current time.

Definition at line 37 of file genealogy.h.

◆ _unique

name_t genealogy_t::_unique
private

The next unique name.

Definition at line 33 of file genealogy.h.

◆ magic

const name_t genealogy_t::magic = 1123581321
staticprivate

Definition at line 41 of file genealogy.h.


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