Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
S3method(base::`$`, hyperion_nonmem_model)
S3method(base::`[[`, hyperion_nonmem_model)
S3method(base::names, hyperion_nonmem_model)
S3method(base::print, hyperion_nonmem_dataset)
S3method(base::print, hyperion_nonmem_model)
S3method(base::print, hyperion_nonmem_summary)
S3method(base::print, hyperion_nonmem_tree)
S3method(base::print, parameter_audit)
S3method(base::summary, hyperion_nonmem_model)
S3method(knitr::knit_print,hyperion_nonmem_dataset)
S3method(knitr::knit_print,hyperion_nonmem_model)
S3method(knitr::knit_print,hyperion_nonmem_summary)
S3method(knitr::knit_print,hyperion_nonmem_tree)
Expand All @@ -33,14 +35,17 @@ export(format_hyperion_sigfig_string)
export(format_omega_display_name)
export(get_comment)
export(get_comment_type)
export(get_data_path)
export(get_eps_shrinkage)
export(get_eta_labels)
export(get_eta_shrinkage)
export(get_final_estimates)
export(get_gradients)
export(get_model_ancestors)
export(get_model_descendants)
export(get_model_dir)
export(get_model_lineage)
export(get_model_name)
export(get_model_parameter_info)
export(get_model_summary)
export(get_parameter_names)
Expand Down
11 changes: 11 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,22 @@
- Expand NONMEM example data bundled with the package.
- Refresh documentation, man pages, and vignettes to cover new APIs and examples.

### Model Utilities

- New model accessor functions:
- `get_model_name()` - Get the model name (filename without extension)
- `get_model_dir()` - Get the model directory path (relative to pharos.toml)
- `get_data_path()` - Get the dataset path from the model
- `check_dataset()` now automatically derives the model directory from the
`model_source` attribute, removing the need for the `model_dir` argument.

## Breaking Changes

- `get_model_summary()` is deprecated in favor of `summary(mod)`.
- Parameter data frame column renamed: `value` is now `estimate`.
- Test data relocated from `vignettes/test_data/` to `inst/extdata/`.
- `check_dataset()` no longer accepts a `model_dir` argument; the directory is
now derived automatically from the model's `model_source` attribute.

## Dependencies

Expand Down
6 changes: 3 additions & 3 deletions R/comments-parsing.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ read_model_from_lst_dir <- function(dir_path) {
#' Derive output directory from model path and read from .lst file
#' @noRd
read_model_from_lst_path <- function(mod_path) {
mod_path <- resolve_model_source_path(mod_path)
mod_path <- from_config_relative(mod_path)
# Derive output directory: run001.mod -> run001/
base_name <- tools::file_path_sans_ext(basename(mod_path))
parent_dir <- dirname(mod_path)
Expand Down Expand Up @@ -129,7 +129,7 @@ get_model_parameter_info <- function(mod, lookup_path = NULL) {
} else if (inherits(mod, "hyperion_nonmem_model")) {
mod_path <- attr(mod, "model_source") %||% "unknown"
if (!identical(mod_path, "unknown")) {
mod_path <- resolve_model_source_path(mod_path)
mod_path <- from_config_relative(mod_path)
}
# If model was read from .mod/.ctl file, find and read from .lst instead
if (!grepl("\\.lst$", mod_path, ignore.case = TRUE)) {
Expand All @@ -153,7 +153,7 @@ get_model_parameter_info <- function(mod, lookup_path = NULL) {

mod_path <- attr(mod, "model_source") %||% "unknown"
if (!identical(mod_path, "unknown")) {
mod_path <- resolve_model_source_path(mod_path)
mod_path <- from_config_relative(mod_path)
}

param_names <- get_model_parameter_names(mod)
Expand Down
41 changes: 41 additions & 0 deletions R/dataset.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#' Print method for hyperion_nonmem_dataset objects
#'
#' @param x A hyperion_nonmem_dataset object
#' @param ... Additional arguments (ignored)
#' @return Invisible copy of x
#' @rawNamespace S3method(base::print, hyperion_nonmem_dataset)
print.hyperion_nonmem_dataset <- function(x, ...) {
rel_path <- to_config_relative(x$canonical_path)

cli::cli_h1("Dataset Check")
cli::cli_text("{.strong Path:} {rel_path}")
cli::cli_text("{.strong Hash:} {x$blake3_hash}")

invisible(x)
}

#' Knit print method for hyperion_nonmem_dataset objects
#'
#' @param x A hyperion_nonmem_dataset object
#' @param ... Additional arguments (ignored)
#' @return HTML output for rendered documents
#' @exportS3Method knitr::knit_print
knit_print.hyperion_nonmem_dataset <- function(x, ...) {
rel_path <- to_config_relative(x$canonical_path)

df <- data.frame(
Field = c("Path", "Hash"),
Value = c(rel_path, x$blake3_hash),
stringsAsFactors = FALSE
)

tbl <- knitr::kable(df, format = "html", col.names = NULL, escape = FALSE)

output <- c(
"<strong>Dataset Check</strong>",
"",
tbl
)

knitr::asis_output(paste(output, collapse = "\n"))
}
25 changes: 17 additions & 8 deletions R/extendr-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,16 @@ read_model <- function(path) .Call(wrap__read_model, path)

#' Checks model dataset
#'
#' @param model list of model object from `read_model`
#' @param model_dir directory of model output //TODO check this
#' @param model hyperion_nonmem_model object from `read_model`
#'
#' @return nothing //todo maybe a true/false?
#' @return Dataset check results
#' @export
#'
#' @examples \dontrun{
#' model <- read_model("model/nonmem/run001.mod")
#' model |> check_dataset("model/nonmem/run001")
#' model |> check_dataset()
#' }
check_dataset <- function(model, model_dir) .Call(wrap__check_dataset, model, model_dir)
check_dataset <- function(model) .Call(wrap__check_dataset, model)

#' Gets model object from lst file (internal)
#'
Expand Down Expand Up @@ -421,15 +420,25 @@ get_pharos_config <- function() .Call(wrap__get_pharos_config)
#' }
get_comment_type <- function() .Call(wrap__get_comment_type_wrap)

#' Validate and resolve a model path (.mod or .ctl).
#'
#' @keywords internal
#' @noRd
validate_model_path <- function(path) .Call(wrap__validate_model_path_wrap, path)

#' Convert a config-relative path to absolute.
#'
#' @keywords internal
#' @noRd
resolve_input_model_path <- function(path) .Call(wrap__resolve_input_model_path_wrap, path)
from_config_relative <- function(path) .Call(wrap__from_config_relative_wrap, path)

#' Resolve a model_source string into an absolute or config-relative path.
#' Convert an absolute path to be relative to the pharos config directory.
#'
#' @param path Absolute path to make relative.
#' @return Path relative to pharos.toml directory, or original path if not under config dir.
#' @keywords internal
#' @noRd
resolve_model_source_path <- function(path) .Call(wrap__resolve_model_source_path_wrap, path)
to_config_relative <- function(path) .Call(wrap__to_config_relative_wrap, path)

#' Submits a NONMEM model to SLURM for execution
#'
Expand Down
3 changes: 3 additions & 0 deletions R/hyperion-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#' \item [copy_model()] - Copy a model to a new file with optional parameter updates
#' \item [check_model()] - Validate model syntax
#' \item [check_dataset()] - Validate model dataset
#' \item [get_model_name()] - Get the model name (filename without extension)
#' \item [get_model_dir()] - Get the model directory path
#' \item [get_data_path()] - Get the dataset path from the model
#' }
#'
#' @section Model Summaries:
Expand Down
59 changes: 59 additions & 0 deletions R/model-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -684,3 +684,62 @@ knit_print.hyperion_nonmem_model <- function(x, ...) {
# Return as HTML
knitr::asis_output(paste(output, collapse = "\n"))
}

#' Get model name
#'
#' Extracts the model name from a hyperion_nonmem_model object.
#'
#' @param model A hyperion_nonmem_model object
#' @return Character string with the model name (filename without extension)
#' @export
#'
#' @examples
#' \dontrun{
#' mod <- read_model("models/run001.mod")
#' get_model_name(mod) # "run001"
#' }
get_model_name <- function(model) {
model_source <- attr(model, "model_source")
if (is.null(model_source)) {
stop("Model object is missing model_source attribute")
}
tools::file_path_sans_ext(basename(model_source))
}

#' Get model directory
#'
#' Extracts the directory path from a hyperion_nonmem_model object.
#'
#' @param model A hyperion_nonmem_model object
#' @return Character string with the model directory path (relative to pharos.toml)
#' @export
#'
#' @examples
#' \dontrun{
#' mod <- read_model("models/run001.mod")
#' get_model_dir(mod) # "models"
#' }
get_model_dir <- function(model) {
model_source <- attr(model, "model_source")
if (is.null(model_source)) {
stop("Model object is missing model_source attribute")
}
dirname(model_source)
}

#' Get data path
#'
#' Extracts the dataset path from a hyperion_nonmem_model object.
#'
#' @param model A hyperion_nonmem_model object
#' @return Character string with the data path, or NULL if not found
#' @export
#'
#' @examples
#' \dontrun{
#' mod <- read_model("models/run001.mod")
#' get_data_path(mod) # "../data/derived/pk_data.csv"
#' }
get_data_path <- function(model) {
model$data$path
}
Loading