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;
90 memcpy(A,o,
sizeof(A)); o +=
sizeof(A);
91 memcpy(B,o,
sizeof(B)); o +=
sizeof(B);
93 err(
"in %s (%s line %d) corrupted genealogy serialization.",
94 __func__,__FILE__,__LINE__);
97 return o >>
reinterpret_cast<nodeseq_t&
>(G);
118 err(
"in %s (%s line %d): cannot deserialize a NULL.",
119 __func__,__FILE__,__LINE__);
120 PROTECT(o = AS_RAW(o));
176 int *
ell,
int *sat,
int *etype)
const {
178 for (
size_t j = 0; j <
_ndeme; j++) {
184 for (
const node_t *p : *
this) {
185 if (tcur < p->slate) {
189 for (
size_t j = 0; j <
_ndeme; j++) {
202 for (
size_t j = 0; j <
_ndeme; j++) {
211 SEXP tout,
deme,
ell, sat, etype, out, outn;
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));
228 INTEGER(sat),INTEGER(etype));
234 void gendat (
double *tout,
int *anc,
int *lin,
236 int *index,
int *child)
const {
239 for (k = 0,
n = 0, i = begin(); i != end(); i++,
n++) {
254 child[
n] = NA_INTEGER;
258 for (m = 0, j = begin(); j != i; j++, m++) {
268 for (k = 0,
n = 0, i = begin(); i != end(); i++,
n++) {
271 for (m =
n+1; j != end(); m++, j++) {
234 void gendat (
double *tout,
int *anc,
int *lin, {
…}
281 SEXP tout, anc, lin, sat, type, index, child, ns, nn;
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));
305 gendat(REAL(tout),INTEGER(anc),INTEGER(lin),INTEGER(sat),
306 INTEGER(type),INTEGER(index),INTEGER(child));
316 for (
const node_t *p : *
this) {
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));
346 std::string o =
"t0 = " + std::to_string(
double(
timezero()))
347 +
"\ntime = " + std::to_string(
double(
time())) +
"\n"
355 virtual std::string
yaml (std::string tab =
"")
const {
357 std::string t = tab +
" ";
358 o = tab +
"t0: " + std::to_string(
timezero()) +
"\n"
359 + tab +
"time: " + std::to_string(
time()) +
"\n"
355 virtual std::string
yaml (std::string tab =
"")
const {
…}
379 if (size() > maxq+grace) {
380 err(
"maximum genealogy size exceeded!");
381 }
else if (size() > maxq) {
464 std::pair<node_it, node_it>
extant (
void)
const {
465 return std::pair<node_it,node_it>(cbegin(),cend());
464 std::pair<node_it, node_it>
extant (
void)
const {
…}
470 while (!blacks->empty()) {
471 ball_t *b = *(blacks->begin());
482 while (!blacks->empty()) {
483 ball_t *a = *(blacks->begin());
500 if (tnew < troot) troot = tnew;
501 if (!empty() && tnew <
time()) {
503 while (!empty() && p->
slate > tnew) {
505 while (p->size() > 1) {
509 p->erase(b);
delete b;
527 if (!empty()) p = back();
531 if (!empty() && troot >
timezero()) {
534 while (!empty() && p->
slate <= troot) {
537 while (p->size() > 1) {
541 p->erase(b);
delete b;
547 q->insert(b); p->erase(b);
552 if (q->
slate < troot) {
553 q->insert(b); p->erase(b);
558 pp->insert(b); p->erase(b);
566 if (!empty()) p = front();
597 err(
"in '%s' (%s line %d): invalid Newick format: empty label.",__func__,__FILE__,__LINE__);
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]);
614 while (i <
n && s[i] ==
'_') i++;
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__);
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__);
630 catch (
const std::out_of_range& e) {
631 err(
"in '%s': invalid Newick format: deme out of range.",__func__);
633 catch (
const std::exception& e) {
634 err(
"in '%s': parsing deme label: %s.",__func__,e.what());
637 err(
"in '%s': other deme-parsing error.",__func__);
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__);
649 catch (
const std::invalid_argument& e) {
650 err(
"in '%s': invalid Newick format: branch length should be a non-negative decimal number.",__func__);
652 catch (
const std::out_of_range& e) {
653 err(
"in '%s': invalid Newick format: branch length out of range.",__func__);
655 catch (
const std::exception& e) {
656 err(
"in '%s': parsing branch-length: %s.",__func__,e.what());
659 err(
"in '%s': other branch-length parsing error.",__func__);
675 if (col !=
black)
err(
"in '%s': bad Newick string (1)",__func__);
676 if (p == 0)
err(
"in '%s': bad Newick string (2)",__func__);
709 size_t i = 1, j = 1, k;
711 while (j < n && stack > 0) {
725 err(
"in '%s': premature end of Newick string.",__func__);
750 q->erase(g); p->insert(g); g->
holder() = p;
760 q->erase(g); p->insert(g); g->
holder() = p;
767 case ',':
case ';':
case ' ':
case '\n':
case '\t':
771 err(
"in '%s': invalid Newick string: unbalanced parentheses.",__func__);
774 err(
"in '%s': invalid Newick string.",__func__);
Balls function as pointers.
name_t deme(void) const
view deme
node_t * holder(void) const
in whose pocket do I lie?
node_t * child(void) const
a child is the owner of a green ball
size_t & ndeme(void)
number of demes
slate_t time(void) const
view current time.
size_t nsample(void) const
number of samples
~genealogy_t(void)
destructor
SEXP structure(void) const
R list description.
std::string newick(void) const
put genealogy at current time into Newick format.
virtual std::string yaml(std::string tab="") const
machine-readable info
genealogy_t(double t0=0, name_t u=0, size_t nd=1)
void valid(void) const
check the validity of the genealogy.
genealogy_t(SEXP o)
constructor from RAW SEXP (containing binary serialization)
genealogy_t & operator=(const genealogy_t &G)
copy assignment operator
void death(ball_t *a, slate_t t)
death
size_t scan_ball(const std::string &s, const slate_t t0, node_t *p)
SEXP lineage_count(void) const
lineage count and saturation
genealogy_t & prune(void)
prune the tree (drop all black balls)
size_t bytesize(void) const
size of serialized binary form
std::string describe(void) const
human-readable info
size_t ndeme(void) const
number of demes
ball_t * migrate(ball_t *a, slate_t t, name_t d=0)
movement into deme d
genealogy_t(const genealogy_t &G)
copy constructor
bool check_genealogy_size(size_t grace=0) const
check the size of the genealogy (to prevent memory exhaustion).
node_t * make_node(name_t d)
size_t scan_label(const std::string &s, color_t *col, name_t *deme, slate_t *time) const
slate_t timezero(void) const
get zero time.
ball_t * graft(slate_t t, name_t d)
graft a new lineage into deme d
genealogy_t & operator+=(genealogy_t &G)
slate_t _time
The current time.
size_t scan_node(const std::string &s, const slate_t t0, node_t **q)
Scan the Newick string and create the indicated node.
SEXP gendat(void) const
nodelist in data-frame format
ball_t * birth(node_t *p, name_t d)
birth of second or subsequent sibling into deme d
size_t _ndeme
The number of demes.
slate_t & timezero(void)
view/set zero time.
void sample_death(ball_t *a, slate_t t)
insert a sample node and simultaneously terminate the lineage
genealogy_t(raw_t *o)
constructor from serialized binary form
slate_t & time(void)
view/set current time.
std::pair< node_it, node_it > extant(void) const
void curtail(slate_t tnew, slate_t troot)
friend raw_t * operator>>(const genealogy_t &G, raw_t *o)
binary serialization
size_t scan_tree(const std::string &s, const slate_t t0, node_t **root)
static const name_t magic
name_t unique(void)
get the next unique name
size_t scan_color(const std::string &s, color_t *col) const
void sample(ball_t *a, slate_t t)
insert a sample node
void lineage_count(double *tout, int *deme, int *ell, int *sat, int *etype) const
slate_t _t0
The initial time.
genealogy_t & parse(const std::string &s, slate_t t0, node_t *p=0)
Parse a Newick string and create the indicated genealogy.
void gendat(double *tout, int *anc, int *lin, int *sat, int *type, int *index, int *child) const
nodelist in data-frame format
name_t _unique
The next unique name.
genealogy_t(genealogy_t &&)=default
move constructor
ball_t * birth(ball_t *a, slate_t t, name_t d)
birth into deme d
genealogy_t & obscure(void)
erase all deme information
Encodes a genealogical node.
node_t * parent(void) const
name_t lineage(void) const
view lineage
name_t deme(void) const
view deme
ball_t * green_ball(void) const
pointer to my green ball
void lineage_incr(int *incr, int *sat, int *etype) const
bool holds_own(void) const
int nchildren(void) const
number of descendants
std::string describe(void) const
human-readable info
virtual std::string yaml(std::string tab="") const
human- & machine-readable info
size_t ntime(slate_t t) const
Number of distinct timepoints.
void sort(void)
order nodes in order of increasing time
void destroy_node(node_t *p)
remove a dead root node
SEXP structure(void) const
R list description.
size_t bytesize(void) const
size of serialized binary form
void swap(ball_t *a, ball_t *b)
swap balls a and b, wherever they lie
size_t length(void) const
Number of nodes in the sequence.
pocket_t * colored(color_t col) const
Get all balls of a color.
std::string newick(slate_t t) const
put genealogy at time t into Newick format.
void add(node_t *p, ball_t *a)
A pocket is a set of balls.
ball_t * last_ball(void) const
retrieve the last ball
bool holds(ball_t *b) const
does this node hold the given ball?
static const size_t MEMORY_MAX
static int set_list_elem(SEXP list, SEXP names, SEXP element, const char *name, int pos)
std::list< node_t * >::const_iterator node_it