phylopomp
Phylodynamics for POMPs
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 *index, int *child) const
 nodelist in data-frame format
 
SEXP gendat (void) const
 nodelist in data-frame 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
 
ball_tmigrate (ball_t *a, slate_t t, name_t d=0)
 movement into deme d
 
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 404 of file genealogy.h.

404 {
405 time() = t;
406 node_t *p = make_node(a->deme());
407 ball_t *b = new ball_t (p,p->uniq,black,d);
408 p->insert(b);
409 p->slate = time();
410 add(p,a);
411 return b;
412 };
@ 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:391
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:176
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 414 of file genealogy.h.

414 {
415 ball_t *b = new ball_t(p,unique(),black,d);
416 p->insert(b);
417 return b;
418 };
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 376 of file genealogy.h.

376 {
377 static size_t maxq = MEMORY_MAX/(sizeof(node_t)+2*sizeof(ball_t));
378 bool ok = true;
379 if (size() > maxq+grace) {
380 err("maximum genealogy size exceeded!"); // #nocov
381 } else if (size() > maxq) {
382 ok = false; // #nocov
383 }
384 return ok;
385 };
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 499 of file genealogy.h.

499 {
500 if (tnew < troot) troot = tnew;
501 if (!empty() && tnew < time()) {
502 node_t *p = back();
503 while (!empty() && p->slate > tnew) {
504 ball_t *b;
505 while (p->size() > 1) {
506 b = p->last_ball();
507 switch (b->color) {
508 case black:
509 p->erase(b); delete b;
510 break;
511 case green: case blue: // #nocov
512 assert(0); // #nocov
513 break; // #nocov
514 }
515 }
516 b = p->last_ball();
517 switch (b->color) {
518 case blue:
519 b->color = black;
520 case black:
521 b->deme() = p->deme();
522 swap(b,p->green_ball());
523 case green:
524 destroy_node(p);
525 break;
526 }
527 if (!empty()) p = back();
528 }
529 }
530 time() = tnew;
531 if (!empty() && troot > timezero()) {
532 node_t *p = front();
533 node_t *q;
534 while (!empty() && p->slate <= troot) {
535 ball_t *b;
536 assert(p->holds_own());
537 while (p->size() > 1) {
538 b = p->last_ball();
539 switch (b->color) {
540 case blue:
541 p->erase(b); delete b;
542 break;
543 case black:
544 q = make_node(b->deme());
545 q->slate = troot;
546 b->holder() = q;
547 q->insert(b); p->erase(b);
548 push_back(q);
549 break;
550 case green:
551 q = b->child();
552 if (q->slate < troot) {
553 q->insert(b); p->erase(b);
554 b->holder() = q;
555 } else {
556 node_t *pp = make_node(b->deme());
557 pp->slate = troot;
558 pp->insert(b); p->erase(b);
559 b->holder() = pp;
560 push_back(pp);
561 }
562 break;
563 }
564 }
565 destroy_node(p);
566 if (!empty()) p = front();
567 }
568 sort();
569 }
570 if (troot > timezero()) timezero() = troot;
571 };
@ 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:110
void destroy_node(node_t *p)
remove a dead root node
Definition nodeseq.h:200
void swap(ball_t *a, ball_t *b)
swap balls a and b, wherever they lie
Definition nodeseq.h:166
ball_t * last_ball(void) const
retrieve the last 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 420 of file genealogy.h.

420 {
421 time() = t;
422 drop(a);
423 };
void drop(ball_t *a)
Definition nodeseq.h:184
Here is the call graph for this function:

◆ describe()

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

human-readable info

Definition at line 345 of file genealogy.h.

345 {
346 std::string o = "t0 = " + std::to_string(double(timezero()))
347 + "\ntime = " + std::to_string(double(time())) + "\n"
349 return o;
350 };
std::string describe(void) const
human-readable info
Definition nodeseq.h:259
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 464 of file genealogy.h.

464 {
465 return std::pair<node_it,node_it>(cbegin(),cend());
466 };
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 * index,
int * child ) const
inline

nodelist in data-frame format

Definition at line 234 of file genealogy.h.

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

nodelist in data-frame format

Definition at line 280 of file genealogy.h.

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

425 {
426 time() = t;
427 node_t *p = make_node(d);
428 ball_t *b = new ball_t (p,p->uniq,black,d);
429 p->insert(b);
430 p->slate = timezero();
431 push_front(p);
432 return b;
433 };
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
static int deme
Definition lbdp.cc:7
#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:138
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 391 of file genealogy.h.

391 {
393 name_t u = unique();
394 node_t *p = new node_t(u,_time);
395 ball_t *g = new ball_t(p,u,green,d);
396 p->green_ball() = g;
397 p->insert(g);
398 return p;
399 };
bool check_genealogy_size(size_t grace=0) const
check the size of the genealogy (to prevent memory exhaustion).
Definition genealogy.h:376
Here is the call graph for this function:
Here is the caller graph for this function:

◆ migrate()

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

movement into deme d

Definition at line 454 of file genealogy.h.

454 {
455 time() = t;
456 node_t *p = make_node(a->deme());
457 p->slate = time();
458 add(p,a);
459 a->deme() = d;
460 return a;
461 };
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 367 of file genealogy.h.

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

◆ nsample()

size_t genealogy_t::nsample ( void ) const
inline

number of samples

Definition at line 314 of file genealogy.h.

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

479 {
480 // erase deme information from black balls.
481 pocket_t *blacks = colored(black);
482 while (!blacks->empty()) {
483 ball_t *a = *(blacks->begin());
484 a->deme() = 0;
485 blacks->erase(a);
486 }
487 delete blacks;
488 // erase deme information from nodes.
489 for (node_t *p : *this) {
490 p->deme() = 0;
491 }
492 // drop superfluous nodes (holding just one ball).
493 comb();
494 _ndeme = 1;
495 return *this;
496 };
void comb(void)
Definition nodeseq.h:207
pocket_t * colored(color_t col) const
Get all balls of a color.
Definition nodeseq.h:128
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 577 of file genealogy.h.

577 {
578 reinterpret_cast<nodeseq_t&>(*this) += reinterpret_cast<nodeseq_t&>(G);
579 _t0 = (_t0 > G._t0) ? G._t0 : _t0;
580 _time = (_time < G._time) ? G._time : _time;
581 _unique = (_unique < G._unique) ? G._unique : _unique;
582 _ndeme = (_ndeme < G.ndeme()) ? G.ndeme() : _ndeme;
583 return *this;
584 };
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 737 of file genealogy.h.

737 {
738 size_t i = 0;
739 size_t n = s.size();
740 while (i < n) {
741 switch (s[i]) {
742 case '(':
743 {
744 genealogy_t G(t0,unique());
745 node_t *q = 0;
746 i += G.scan_tree(s.substr(i),t0,&q);
747 *this += G;
748 if (p != 0) {
749 ball_t *g = q->green_ball();
750 q->erase(g); p->insert(g); g->holder() = p;
751 }
752 }
753 break;
754 case 'b':
755 {
756 node_t *q = 0;
757 i += scan_node(s.substr(i),t0,&q);
758 if (p != 0) {
759 ball_t *g = q->green_ball();
760 q->erase(g); p->insert(g); g->holder() = p;
761 }
762 }
763 break;
764 case 'o':
765 i += scan_ball(s.substr(i),t0,p);
766 break;
767 case ',': case ';': case ' ': case '\n': case '\t':
768 i++;
769 break;
770 case ')':
771 err("in '%s': invalid Newick string: unbalanced parentheses.",__func__);
772 break;
773 default:
774 err("in '%s': invalid Newick string.",__func__);
775 break;
776 }
777 }
778 sort();
779 return *this;
780 };
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:666
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:682
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 468 of file genealogy.h.

468 {
469 pocket_t *blacks = colored(black);
470 while (!blacks->empty()) {
471 ball_t *b = *(blacks->begin());
472 blacks->erase(b);
473 drop(b);
474 }
475 delete blacks;
476 return *this;
477 };
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 435 of file genealogy.h.

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

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

666 {
667 color_t col;
668 name_t deme;
669 slate_t t;
670 ball_t *b;
671 size_t i = scan_label(s,&col,&deme,&t);
672 t += t0;
673 _time = (_time < t) ? t : _time;
674 _ndeme = (_ndeme <= deme) ? deme+1 : _ndeme;
675 if (col != black) err("in '%s': bad Newick string (1)",__func__);
676 if (p == 0) err("in '%s': bad Newick string (2)",__func__);
677 b = new ball_t(p,unique(),col,deme);
678 p->insert(b);
679 return i;
680 };
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:593
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 588 of file genealogy.h.

588 {
589 return 1;
590 };

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

594 {
595 size_t n = s.size();
596 if (n < 1)
597 err("in '%s' (%s line %d): invalid Newick format: empty label.",__func__,__FILE__,__LINE__);
598 size_t sz, i = 1;
599 switch (s[0]) {
600 case 'o':
601 *col = black;
602 break;
603 case 'b':
604 *col = blue;
605 break;
606 case 'g': case 'm':
607 *col = green;
608 break;
609 default:
610 err("in '%s' (%s line %d): invalid Newick label: expected one of 'b','g','m', or 'o', got '%c'.",
611 __func__,__FILE__,__LINE__,s[0]);
612 break;
613 }
614 while (i < n && s[i] == '_') i++;
615 if (i == n)
616 err("in '%s': invalid Newick format: premature termination.",__func__);
617 if (s[i] == '(' || s[i] == ')' || s[i] == ',' || s[i] == ';')
618 err("in '%s' (%s line %d): invalid Newick format.",__func__,__FILE__,__LINE__);
619 if (s[i] == ':') {
620 *deme = 0;
621 } else {
622 try {
623 *deme = name_t(stoi(s.substr(i),&sz));
624 i += sz;
625 }
626 catch (const std::invalid_argument& e) {
627 err("in '%s' (%s line %d): invalid Newick format: deme should be indicated with an integer.",
628 __func__,__FILE__,__LINE__);
629 }
630 catch (const std::out_of_range& e) {
631 err("in '%s': invalid Newick format: deme out of range.",__func__);
632 }
633 catch (const std::exception& e) {
634 err("in '%s': parsing deme label: %s.",__func__,e.what());
635 }
636 catch (...) {
637 err("in '%s': other deme-parsing error.",__func__);
638 }
639 }
640 // skip to branch length
641 while (i < n && s[i] != ':' &&
642 s[i] != '(' && s[i] != ')' && s[i] != ',' && s[i] != ';') i++;
643 if (i == n || s[i] != ':')
644 err("in '%s': invalid Newick format: missing or invalid branch length.",__func__);
645 i++;
646 try {
647 *time = slate_t(stod(s.substr(i),&sz));
648 }
649 catch (const std::invalid_argument& e) {
650 err("in '%s': invalid Newick format: branch length should be a non-negative decimal number.",__func__);
651 }
652 catch (const std::out_of_range& e) {
653 err("in '%s': invalid Newick format: branch length out of range.",__func__);
654 }
655 catch (const std::exception& e) {
656 err("in '%s': parsing branch-length: %s.",__func__,e.what());
657 }
658 catch (...) {
659 err("in '%s': other branch-length parsing error.",__func__);
660 }
661 i += sz;
662 return i;
663 };
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 682 of file genealogy.h.

682 {
683 size_t i;
684 color_t col;
685 name_t deme;
686 slate_t t;
687 name_t u = unique();
688 i = scan_label(s,&col,&deme,&t);
689 t += t0;
690 _ndeme = (_ndeme <= deme) ? deme+1 : _ndeme;
691 _time = (_time < t) ? t : _time;
692 node_t *p = new node_t(u,t);
693 ball_t *g = new ball_t(p,u,green,deme);
694 p->green_ball() = g;
695 p->insert(g);
696 if (col==blue) {
697 ball_t *b = new ball_t(p,p->uniq,blue,deme);
698 p->insert(b);
699 }
700 push_back(p);
701 *q = p;
702 return i;
703 };
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 706 of file genealogy.h.

707 {
708 size_t n = s.size();
709 size_t i = 1, j = 1, k;
710 size_t stack = 1;
711 while (j < n && stack > 0) {
712 switch (s[j]) {
713 case '(':
714 stack++;
715 break;
716 case ')':
717 stack--;
718 break;
719 default:
720 break;
721 }
722 j++;
723 }
724 if (stack > 0)
725 err("in '%s': premature end of Newick string.",__func__);
726 node_t *p = 0;
727 k = j;
728 k += scan_node(s.substr(j),t0,&p);
729 parse(s.substr(i,j-i-1),p->slate,p);
730 *root = p;
731 return k;
732 };
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:737
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 325 of file genealogy.h.

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

374{};

◆ yaml()

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

machine-readable info

Reimplemented from nodeseq_t.

Definition at line 355 of file genealogy.h.

355 {
356 std::string o;
357 std::string t = tab + " ";
358 o = tab + "t0: " + std::to_string(timezero()) + "\n"
359 + tab + "time: " + std::to_string(time()) + "\n"
360 + tab + "nodes:\n" + nodeseq_t::yaml(tab);
361 return o;
362 };
virtual std::string yaml(std::string tab="") const
human- & machine-readable info
Definition nodeseq.h:267
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: