Skip to content

Commit

Permalink
Merge pull request #21 from calico/issue-19
Browse files Browse the repository at this point in the history
Issue 19 - add `n_iterations` as a parameter in `estimate_timecourse_params_tf()`
  • Loading branch information
shackett authored May 29, 2024
2 parents e45cb30 + 2b71cf8 commit 4daa906
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 6 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ jobs:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-r@v1
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}

Expand Down
11 changes: 11 additions & 0 deletions R/data.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#' Example Timecourse
#'
#' An example timecourse of fluorescent reporter dynamics in yeast.
#'
#' @format A tibble with 24 rows and 3 columns:
#' \describe{
#' \item{tc_id}{A number representing a distinct timecourse}
#' \item{time}{Time (in divisions)}
#' \item{abundance}{Relative expression of the reporter}
#' }
"example_timecourse"
14 changes: 13 additions & 1 deletion R/impulse_fitting.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#' }
#' @param fit_intercept If TRUE, the intercept will be fit, if FALSE, the intercept will be constrainted to zero
#' @param learning_rate learning rate for the Adams optimizer
#' @param n_iterations the number of iterations to run the optimizer
#' @param verbose if TRUE then print additional information
#'
#' @return a timecourse list:
Expand Down Expand Up @@ -77,6 +78,7 @@ estimate_timecourse_params_tf <- function(
"time_scale" = 15),
fit_intercept = FALSE,
learning_rate = 0.1,
n_iterations = 100,
verbose = FALSE
) {

Expand Down Expand Up @@ -105,6 +107,7 @@ estimate_timecourse_params_tf <- function(
checkmate::assertLogical(use_prior, len = 1)
checkmate::assertLogical(fit_intercept, len = 1)
checkmate::assertNumber(learning_rate, lower = 0)
checkmate::assertNumber(n_iterations, lower = 1)
checkmate::assertLogical(verbose, len = 1)

# test parameters supplied for parameter initialization / priors
Expand Down Expand Up @@ -153,6 +156,7 @@ estimate_timecourse_params_tf <- function(
prior_pars = prior_pars,
fit_intercept = fit_intercept,
learning_rate = learning_rate,
n_iterations = n_iterations,
verbose = verbose
)

Expand Down Expand Up @@ -197,6 +201,7 @@ estimate_one_timecourse_params_tf <- function (
prior_pars = NULL,
fit_intercept = FALSE,
learning_rate = 0.1,
n_iterations = 100,
verbose = FALSE
) {

Expand All @@ -207,6 +212,7 @@ estimate_one_timecourse_params_tf <- function (
checkmate::assertNumber(learning_rate, lower = 0)
checkmate::assertLogical(verbose, len = 1)
checkmate::assertLogical(fit_intercept, len = 1)
checkmate::assertNumber(n_iterations, lower = 1)

tfp <- reticulate::import("tensorflow_probability")

Expand Down Expand Up @@ -368,6 +374,12 @@ estimate_one_timecourse_params_tf <- function (
)
} else {
# constant noise

noise_value <- ifelse(use_prior, 0.2, 1)
if (verbose) {
cli::cli_alert("No noise variable is present so setting noise to {.field {noise_value}}")
}

noise_entry <- matrix(
ifelse(use_prior, 0.2, 1),
nrow = nrow(one_timecourse),
Expand Down Expand Up @@ -407,7 +419,7 @@ estimate_one_timecourse_params_tf <- function (
continue <- TRUE
while (continue) {
# train
for (i in 1:100) {
for (i in 1:n_iterations) {
sess$run(
train,
feed_dict = timecourse_dict
Expand Down
Binary file added data/example_timecourse.rda
Binary file not shown.
3 changes: 3 additions & 0 deletions man/estimate_one_timecourse_params_tf.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/estimate_timecourse_params_tf.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions man/example_timecourse.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ test_that("prior-free minimizing weighted-MSE", {
tolerance = 0.0001
)

})
})

test_that("Bayesian impulse minimizes MAP estimate", {

Expand Down Expand Up @@ -107,9 +107,55 @@ test_that("Bayesian impulse minimizes MAP estimate", {
object = abund_vs_fit$eval_logLik,
expected = as.numeric(abund_vs_fit$logLik),
tolerance = 0.001
)
)
})

test_that("Sigmoid Likelihood is correct", {

fitted_kinetics <- impulse::estimate_timecourse_params_tf(
measurements = example_timecourse,
prior_pars = c(v_sd = 1.2, rate_shape = 2, rate_scale = 0.25, time_shape = 2, time_scale = 15),
model = "sigmoid",
use_prior = TRUE,
n_initializations = 300L,
learning_rate = 0.2,
n_iterations = 1000,
fit_intercept = TRUE
)

# select a consensus parameter set
consensus_kinetics <- impulse::reduce_best_timecourse_params(fitted_kinetics)

# calculate logLik

### TO DO - compare MAP parameters to prior estimates
fitted_timecourses <- fit_timecourse(
consensus_kinetics$parameters %>%
dplyr::select(variable, value) %>%
tidyr::spread(variable, value),
timepts = unique(example_timecourse$time),
model = "sigmoid"
)

combined_data <- example_timecourse %>%
dplyr::left_join(fitted_timecourses, by = "time")

#ggplot(combined_data, aes(x = time, y = abundance)) +
# geom_point() +
# geom_line(aes(y = fit), color = "red") +
# ggtitle("Example timecourse with sigmoid fit") +
# theme_minimal()

timecourse_logLik <- combined_data %>%
dplyr::mutate(
normal_logLik = dnorm(abundance, fit, sd = 0.2, log = TRUE)
) %>%
dplyr::summarize(logLik = sum(normal_logLik))

testthat::expect_equal(
object = timecourse_logLik$logLik,
expected = consensus_kinetics$loss$logLik[1],
tolerance = 0.01
)

})

Expand Down

0 comments on commit 4daa906

Please sign in to comment.