Skip to content

Commit 87b2b14

Browse files
authored
Merge pull request #169 from PoonLab/dev
Dev
2 parents 81c9f1a + f597744 commit 87b2b14

38 files changed

Lines changed: 655 additions & 563 deletions

NAMESPACE

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ S3method(as.phylo,InnerTree)
44
S3method(as.phylo,OuterTree)
55
S3method(plot,Model)
66
S3method(plot,OuterTree)
7-
S3method(plot,twt.counts)
7+
S3method(plot,dynamics)
8+
S3method(print,InnerTree)
89
S3method(print,Model)
10+
S3method(print,OuterTree)
11+
S3method(print,dynamics)
912
S3method(summary,Model)
1013
export(Host)
1114
export(HostSet)

R/Host.R

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,31 @@ Host <- R6Class(
100100
} else {
101101
return(NULL)
102102
}
103+
},
104+
105+
print = function() {
106+
cat("twt Host", self$get.name(), "\n")
107+
cat(" Compartment:", self$get.compartment(), "\n")
108+
cat(" Infection time(s):", paste(self$get.transmission.time()), "\n")
109+
cat(" Sampling time:", self$get.sampling.time(), "\n")
110+
111+
sources <- self$get.source()
112+
if (is.list(sources)) {
113+
host.names <- sapply(sources, function(h) h$get.name())
114+
} else if ("Host" %in% class(sources)) {
115+
host.names <- sources$get.name()
116+
} else {
117+
host.names <- ""
118+
}
119+
cat(" Source(s):", host.names, "\n")
120+
121+
pathogens <- self$get.pathogens()
122+
if (is.list(pathogens)) {
123+
p.names <- sapply(pathogens, function(p) p$get.name())
124+
} else {
125+
p.names <- pathogens$get.name()
126+
}
127+
cat(" Pathogen(s):", p.names, "\n")
103128
}
104129
),
105130

@@ -133,6 +158,14 @@ HostSet <- R6Class(
133158
private$index <- index # unique IDs for members
134159
},
135160

161+
print = function() {
162+
my.name <- self$get.name()
163+
cat("twt HostSet", ifelse(is.na(my.name), "", my.name), "\n")
164+
cat(" ", self$count.type(), "Host objects\n")
165+
},
166+
167+
get.name = function() { private$name },
168+
136169
get.names = function() {
137170
sapply(private$hosts, function(h) { h$get.name() })
138171
},
@@ -273,3 +306,5 @@ HostSet <- R6Class(
273306
index = NULL
274307
)
275308
)
309+
310+

R/InnerTree.R

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
InnerTree <- R6Class(
1616
"InnerTree",
1717
public = list(
18-
initialize = function(outer, mod, prefix='P', p.index=1) {
18+
initialize = function(outer, prefix='P', p.index=1) {
1919
private$inner.log <- data.frame(
2020
time=numeric(), # time of event
2121
event=character(), # type of event, e.g., coalescence
@@ -27,7 +27,7 @@ InnerTree <- R6Class(
2727
pathogen2=character()
2828
)
2929

30-
private$mod <- mod
30+
private$mod <- outer$get.model() # inherits model from OuterTree
3131
private$prefix <- prefix
3232
private$p.index <- p.index
3333

@@ -40,7 +40,6 @@ InnerTree <- R6Class(
4040

4141
# inactive Hosts are part of the transmission history
4242
private$inactive <- HostSet$new()
43-
private$inactive$add.host(index.case$clone())
4443
private$sampled <- HostSet$new()
4544

4645
# note there is overlap between `retired` and `sampled` HostSets
@@ -54,6 +53,13 @@ InnerTree <- R6Class(
5453
}
5554
}
5655

56+
# handle index case
57+
if (index.case$get.name() %in% sampled$get.names()) {
58+
private$sampled$add.host(index.case$clone())
59+
} else {
60+
private$inactive$add.host(index.case$clone())
61+
}
62+
5763
# track Hosts with active Pathogen lineages
5864
private$active <- HostSet$new()
5965

@@ -117,7 +123,7 @@ as.phylo.InnerTree <- function(obj) {
117123
events <- obj$get.log()
118124
events$time <- as.numeric(events$time)
119125

120-
active <- inner$get.active()
126+
active <- obj$get.active()
121127
if (active$count.type() != 1) {
122128
stop("Error, expected only one Host in active HostSet")
123129
}
@@ -179,7 +185,8 @@ as.phylo.InnerTree <- function(obj) {
179185
Nnode=length(node.label), edge=edge,
180186
edge.length=as.numeric(edge.list$length),
181187
event=events$event[match(nodes, events$pathogen2)],
182-
compartment=edge.list$compartment
188+
compartment=edge.list$compartment,
189+
host=events$from.host[match(nodes, events$pathogen2)]
183190
)
184191
attr(phy, 'class') <- 'phylo'
185192
phy
@@ -236,7 +243,7 @@ as.phylo.InnerTree <- function(obj) {
236243
#' @param node: character, Pathogen name
237244
#' @param order: character, 'preorder' or 'postorder'
238245
#' @param result: character, vector to append results by recursive calls
239-
#' @result character, Pathogen names ordered by tree traversal
246+
#' @return character, Pathogen names ordered by tree traversal
240247
#'
241248
#' @keywords internal
242249
#' @noRd
@@ -253,3 +260,17 @@ as.phylo.InnerTree <- function(obj) {
253260
}
254261
return(result)
255262
}
263+
264+
265+
#' Generic print function for R6 objects of class `InnerTree`
266+
#' @export
267+
#' @noRd
268+
print.InnerTree <- function(obj) {
269+
cat("twt InnerTree\n") # bold color!
270+
cat(" ", obj$get.sampled()$count.type(), "sampled Pathogens\n")
271+
cat(" ", obj$get.active()$count.type(), "active Pathogens\n")
272+
cat(" ", obj$get.inactive()$count.type(), "inactive Pathogens\n")
273+
events <- obj$get.log()
274+
cat(" ", nrow(events), "events in inner log: ")
275+
print(table(events$event))
276+
}

R/Model.R

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,29 @@ Model <- R6Class(
354354
stop("Sampling field must specify `targets` (compartments)")
355355
}
356356

357+
# check that targeted compartments have been defined by user
358+
if (is.null(private$compartments)) {
359+
load.compartments(settings)
360+
}
361+
for (cn in names(private$sampling$targets)) {
362+
if (!is.element(cn, private$compartments)) {
363+
stop(paste("In Sampling:targets compartment", cn,
364+
"has not been declared in Compartments"))
365+
}
366+
count <- private$sampling$targets[[cn]]
367+
if (!is.numeric(count) | count <= 0) {
368+
stop(paste("Sampling:targets:", cn, "must be a positive integer"))
369+
}
370+
}
371+
372+
} else if (mode == "fraction") {
373+
# contemporaneous sampling occurs at end of simulation time from
374+
# compartments specified by user, to target size or probability
375+
# if value is between 0 and 1, then interpret as a probability
376+
if (is.null(private$sampling$targets)) {
377+
stop("Sampling field must specify `targets` (compartments)")
378+
}
379+
357380
# check that targeted compartments have been defined by user
358381
if (is.null(private$compartments)) {
359382
load.compartments(settings)
@@ -379,15 +402,16 @@ Model <- R6Class(
379402
#' print.Model
380403
#' S3 class function to display contents of a Model object
381404
#' @export
405+
#' @noRd
382406
print.Model <- function(obj) {
383-
cat("twt Model")
384-
cat("Parameters:\n")
407+
cat("twt Model\n") # bold
408+
cat(" Parameters:\n")
385409
params <- obj$get.parameters()
386410
for (key in names(params)) {
387411
value <- params[[key]]
388-
cat(" ", key, ": ", value, "\n")
412+
cat(" ", key, ": ", value, "\n")
389413
}
390-
cat("Compartments: ")
414+
cat(" Compartments: ")
391415
compartments <- obj$get.compartments()
392416
for (cn in compartments) {
393417
cat(cn, " ")
@@ -399,15 +423,31 @@ print.Model <- function(obj) {
399423
#' S3 class function to summarize a Model object - simply a wrapper
400424
#' around print()
401425
#' @export
426+
#' @noRd
402427
summary.Model <- function(obj) {
403428
print(obj)
404429
}
405430

406431

407432
#' plot.Model
408433
#' Plot a graph summarizing compartments and rates
409-
#' TODO: label edges with rate expressions
434+
#' @param obj: R6 object of class `Model`
435+
#' @param bg: character, color for uninfected compartments
436+
#' @param bg2: character, color for infected compartments
437+
#' @param mar: numeric, margin size (default: 1)
438+
#' @param lwd: numeric, line width for edges
410439
#' @export
411-
plot.Model <- function(obj) {
412-
igraph::plot.igraph(obj$get.graph())
440+
plot.Model <- function(obj, bg='skyblue', bg2='pink2', mar=1, lwd=2) {
441+
g <- obj$get.graph()
442+
par(mar=rep(mar, 4))
443+
igraph::plot.igraph(g,
444+
vertex.size=(nchar(names(V(g)))+2)*8,
445+
vertex.size2=20,
446+
vertex.shape='crectangle',
447+
vertex.color=ifelse(obj$get.infected(), bg2, bg),
448+
vertex.label.family='sans',
449+
edge.arrow.size=0.8,
450+
edge.arrow.width=1.2,
451+
edge.width=lwd
452+
)
413453
}

R/OuterTree.R

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ OuterTree <- R6Class(
99
"OuterTree",
1010
public = list(
1111
initialize = function(mod) {
12+
private$model <- mod
13+
1214
private$outer.log <- data.frame(
1315
time=numeric(), # time of event
1416
event=character(), # type of event, e.g., migration
@@ -27,6 +29,7 @@ OuterTree <- R6Class(
2729
},
2830

2931
# accessor functions
32+
get.model = function() { private$model },
3033
get.targets = function() { private$targets },
3134
get.log = function() { private$outer.log },
3235
get.nrow = function() { nrow(private$outer.log) },
@@ -64,6 +67,7 @@ OuterTree <- R6Class(
6467
),
6568

6669
private = list(
70+
model = NULL,
6771
outer.log = NULL,
6872
targets = NULL,
6973
sampled = NULL,
@@ -345,3 +349,17 @@ as.phylo.OuterTree <- function(obj) {
345349
}
346350
events
347351
}
352+
353+
354+
#' Generic print function for R6 objects of class `OuterTree`
355+
#' @export
356+
#' @noRd
357+
print.OuterTree <- function(obj) {
358+
cat("twt OuterTree\n") # bold color!
359+
cat(" ", obj$get.sampled()$count.type(), "sampled Hosts\n")
360+
cat(" ", obj$get.active()$count.type(), "active Hosts\n")
361+
cat(" ", obj$get.retired()$count.type(), "retired Hosts\n")
362+
events <- obj$get.log()
363+
cat(" ", nrow(events), "events in outer log:")
364+
print(table(events$event))
365+
}

R/Pathogen.R

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ Pathogen <- R6Class(
2525
private$children <- children
2626
},
2727

28+
print = function() {
29+
cat("twt Pathogen", self$get.name(), "\n")
30+
cat(" Start time:", self$get.start.time(), "\n")
31+
cat(" End time:", self$get.end.time(), "\n")
32+
cat(" Parent:", self$get.parent()$get.name(), "\n")
33+
children <- sapply(self$get.children(), function(child) child$get.name())
34+
cat(" Children:", children, "\n")
35+
},
36+
2837
# immutable attributes
2938
get.name = function() { private$name },
3039
get.end.time = function() { private$end.time },

0 commit comments

Comments
 (0)