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
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ be directly added to this file to describe the related changes.
(`minimal`) only prints info to the terminal when an issue with a simulation
occurs

- Improved formatting of output from `write_module`, so that initial value and
parameter lists are alphabetized, equals signs are aligned, and module names
are preserved

# Changes in BioCroValidation Version 0.2.0 (2025-05-23)

- Added 2002 and 2005 SoyFACE biomass and standard deviation data.
Expand Down
34 changes: 27 additions & 7 deletions R/write_model.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,39 @@ write_model <- function(
ode_solver
)
{
# Get the longest name among the initial values and parameters
all_names <- c(
names(initial_values),
names(parameters)
)

name_width <- max(sapply(all_names, nchar))

# Alphabetize the initial values and parameters
initial_values <- initial_values[order(tolower(names(initial_values)))]
parameters <- parameters[order(tolower(names(parameters)))]

# Prepare the module list strings
dir_module_string <- paste(paste0(' ', names(direct_modules), ' = "', direct_modules, '"'), collapse = ',\n')
diff_module_string <- paste(paste0(' ', names(differential_modules), ' = "', differential_modules, '"'), collapse = ',\n')

# Remove any lines without names
dir_module_string <- gsub(' = ', ' ', dir_module_string)
diff_module_string <- gsub(' = ', ' ', diff_module_string)

# Fill in the module definition template (defined below)
model_text <- sprintf(
model_definition_template,
name,
paste(paste0(' "', direct_modules, '"'), collapse = ',\n'),
paste(paste0(' "', differential_modules, '"'), collapse = ',\n'),
dir_module_string,
diff_module_string,
ode_solver[['type']],
ode_solver[['output_step_size']],
ode_solver[['adaptive_rel_error_tol']],
ode_solver[['adaptive_abs_error_tol']],
ode_solver[['adaptive_max_steps']],
paste(paste0(' "', names(initial_values), '" = ', initial_values), collapse = ',\n'),
paste(paste0(' "', names(parameters), '" = ', parameters), collapse = ',\n')
paste(paste0(' ', format(names(initial_values), width = name_width), ' = ', initial_values), collapse = ',\n'),
paste(paste0(' ', format(names(parameters), width = name_width), ' = ', parameters), collapse = ',\n')
)
}

Expand All @@ -31,11 +51,11 @@ model_definition_template <- '%s <- list(
%s
),
ode_solver = list(
type = "%s",
output_step_size = %f,
type = "%s",
output_step_size = %f,
adaptive_rel_error_tol = %e,
adaptive_abs_error_tol = %e,
adaptive_max_steps = %i
adaptive_max_steps = %i
),
initial_values = list(
%s
Expand Down
7 changes: 6 additions & 1 deletion man/write_model.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
output. See examples below. Note that it is customary to name the R script
file as \code{name.R}, where \code{name} is the value provided to the function
itself.

The \code{initial_values} and \code{parameters} will be alphabetized
(case-insensitive). The \code{ode_solver} elements will be printed in the
customary BioCro order. The \code{direct_modules} and
\code{differential_modules} will not be reordered.
}

\value{
Expand All @@ -85,7 +90,7 @@ if (require(BioCro)) {

if (interactive()) {
# Use writeLines to save as a `.R` file
writeLines(out, "./test_soybean_model.h")
writeLines(out, "./test_soybean_model.R")
}
}
}
16 changes: 8 additions & 8 deletions tests/test_data/test_model.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ test_model <- list(
"BioCro:harmonic_oscillator"
),
ode_solver = list(
type = "boost_rkck54",
output_step_size = 1.000000,
type = "boost_rkck54",
output_step_size = 1.000000,
adaptive_rel_error_tol = 1.000000e-04,
adaptive_abs_error_tol = 1.000000e-04,
adaptive_max_steps = 200
adaptive_max_steps = 200
),
initial_values = list(
"position" = 1,
"velocity" = 0
position = 1,
velocity = 0
),
parameters = list(
"timestep" = 1,
"mass" = 1,
"spring_constant" = 0.5
mass = 1,
spring_constant = 0.5,
timestep = 1
)
)
Loading