Skip to content
Open
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: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: SSMSE
Title: Management Strategy Evaluation (MSE) using Stock Synthesis (SS)
Version: 0.3.0
Version: 0.4.0
Authors@R: c(
person("Kathryn", "Doering", , "kathryn.doering@noaa.gov", role = c("aut", "cre")),
person("Nathan", "Vaughan", , "nathan.vaughan@noaa.gov", role = "aut")
Expand Down Expand Up @@ -43,4 +43,4 @@ Remotes:
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
Config/roxygen2/version: 8.0.0
2 changes: 0 additions & 2 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export(plot_comp_sampling)
export(plot_index_sampling)
export(run_EM)
export(run_SSMSE)
export(run_ss_model)
export(set_MSE_seeds)
import(ggplot2)
import(r4ss)
Expand All @@ -32,7 +31,6 @@ importFrom(r4ss,SS_writedat)
importFrom(r4ss,SS_writeforecast)
importFrom(r4ss,SS_writestarter)
importFrom(ss3sim,get_results_all)
importFrom(ss3sim,get_results_iter)
importFrom(ss3sim,get_results_scenario)
importFrom(stats,na.omit)
importFrom(tidyr,gather)
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# SSMSE

## SSMSE 0.4.0

- Update for compatibility with newer Stock Synthesis releases (up to 3.30.24.2), including current file naming conventions such as `ss3.par`, `data_expval.ss`, and `data_boot_001.ss`.

# SSMSE 0.3.0

## Major changes
Expand Down
48 changes: 33 additions & 15 deletions R/MS_functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -408,14 +408,15 @@ get_no_EM_catch_df <- function(OM_dir, yrs, MS = "last_yr_catch") {
verbose = FALSE, readAll = TRUE
)
# read par file (using read lines for simplicity.)
par <- readLines(file.path(OM_dir, "ss.par"))
par_file <- get_ss_par_file(OM_dir)
par <- readLines(par_file)
# use forecasting to find the values desired
# keep old forecasting
file.copy(file.path(OM_dir, "forecast.ss"),
file.path(OM_dir, "forecast_OM.ss"),
overwrite = TRUE
)
file.copy(file.path(OM_dir, "ss.par"), file.path(OM_dir, "ss_OM.par"),
file.copy(par_file, file.path(OM_dir, "ss_OM.par"),
overwrite = TRUE
)
# get the catch values by MS.
Expand Down Expand Up @@ -485,12 +486,15 @@ get_no_EM_catch_df <- function(OM_dir, yrs, MS = "last_yr_catch") {
par[Fcast_rec_line] <- paste0(rep(0, fore[["Nforecastyrs"]]), collapse = " ")
Fcast_impl_err_line <- grep("^# Fcast_impl_error:$", par) + 1
par[Fcast_impl_err_line] <- paste0(rep(0, fore[["Nforecastyrs"]]), collapse = " ")
writeLines(par, file.path(OM_dir, "ss.par"))
writeLines(par, par_file)
# Run SS3 with the new catch set as forecast targets. This will use SS3 to
# calculate the F required in the OM to achieve these catches.
run_ss_model(OM_dir, "-maxfn 0 -phase 50 -nohess",
verbose = FALSE,
debug_par_run = TRUE
r4ss::run(
dir = OM_dir,
exe = get_bin(),
extras = "-maxfn 0 -phase 50 -nohess",
skipfinished = FALSE,
verbose = FALSE
)
# Load the SS3 results
outlist <- r4ss::SS_output(OM_dir,
Expand Down Expand Up @@ -529,7 +533,7 @@ get_no_EM_catch_df <- function(OM_dir, yrs, MS = "last_yr_catch") {
file.path(OM_dir, "forecast.ss"),
overwrite = TRUE
)
file.copy(file.path(OM_dir, "ss_OM.par"), file.path(OM_dir, "ss.par"),
file.copy(file.path(OM_dir, "ss_OM.par"), par_file,
overwrite = TRUE
)
return_list <- list(
Expand Down Expand Up @@ -593,7 +597,12 @@ Interim <- function(EM_out_dir = NULL, EM_init_dir = NULL,
)
Reference_ctl <- SS_readctl(file = file.path(EM_out_dir, start[["ctlfile"]]), use_datlist = TRUE, datlist = Reference_dat, verbose = FALSE)
Reference_forecast <- SS_readforecast(file.path(EM_out_dir, "forecast.ss"), verbose = FALSE)
Reference_par <- SS_readpar_3.30(parfile = file.path(EM_out_dir, "ss.par"), datsource = Reference_dat, ctlsource = Reference_ctl, verbose = FALSE)
Reference_par <- SS_readpar_3.30(
parfile = get_ss_par_file(EM_out_dir),
datsource = Reference_dat,
ctlsource = Reference_ctl,
verbose = FALSE
)
SS_writestarter(
mylist = start,
dir = EM_out_dir,
Expand All @@ -616,7 +625,11 @@ Interim <- function(EM_out_dir = NULL, EM_init_dir = NULL,
colnames(temp_impl_error) <- c("year", "impl_error")
Reference_par[["Fcast_impl_error"]] <- as.data.frame(temp_impl_error)

SS_writepar_3.30(parlist = Reference_par, outfile = file.path(EM_out_dir, "ss.par"), overwrite = TRUE)
SS_writepar_3.30(
parlist = Reference_par,
outfile = get_ss_par_file(EM_out_dir),
overwrite = TRUE
)

SS_writeforecast(
mylist = Reference_forecast,
Expand Down Expand Up @@ -674,15 +687,20 @@ Interim <- function(EM_out_dir = NULL, EM_init_dir = NULL,
run_EM(EM_dir = EM_out_dir, verbose = verbose, check_converged = TRUE)


data_filename <- list.files(file.path(EM_out_dir), pattern = "data.ss_new|data_expval.ss")
if (data_filename == "data.ss_new") {
exp_vals <- SS_readdat(file.path(EM_out_dir, data_filename),
section = 2, # expected values data file in v3.30.21
exp_filename <- get_data_file(EM_out_dir, "expected")
if (is.null(exp_filename)) {
stop(
"Could not find an expected-values data file in ", EM_out_dir,
". Expected data_expval.ss or an older data.ss_new style output."
)
}
if (exp_filename %in% c("data.ss_new", "data_echo.ss_new")) {
exp_vals <- SS_readdat(file.path(EM_out_dir, exp_filename),
section = 2,
verbose = FALSE
)
} else {
# for SS3 v3.30.21
exp_vals <- r4ss::SS_readdat(file.path(EM_out_dir, "data_expval.ss"),
exp_vals <- r4ss::SS_readdat(file.path(EM_out_dir, exp_filename),
verbose = FALSE
)
}
Expand Down
88 changes: 65 additions & 23 deletions R/develop_OMs.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,22 @@
#' @param hess Should the hessian be estimated if reffiting the OMs? defaults to
#' FALSE
#' @export
develop_OMs <- function(OM_name = NULL, OM_in_dir = NULL, out_dir = getwd(), par_name, par_vals,
refit_OMs = TRUE, hess = FALSE) {
develop_OMs <- function(
OM_name = NULL,
OM_in_dir = NULL,
out_dir = getwd(),
par_name,
par_vals,
refit_OMs = TRUE,
hess = FALSE
) {
# check input
if (!is.null(OM_name)) assertive.types::assert_is_a_string(OM_name)
if (!is.null(OM_in_dir)) assertive.types::assert_is_a_string(OM_in_dir)
if (!is.null(OM_name)) {
assertive.types::assert_is_a_string(OM_name)
}
if (!is.null(OM_in_dir)) {
assertive.types::assert_is_a_string(OM_in_dir)
}
assertive.types::assert_is_a_string(out_dir)
assertive.types::assert_is_a_string(par_name)
assertive.properties::assert_is_atomic(par_vals)
Expand All @@ -40,11 +51,16 @@ develop_OMs <- function(OM_name = NULL, OM_in_dir = NULL, out_dir = getwd(), par
OM_in_dir <- pkg_dirs[grep(OM_name, pkg_dirs)]
if (length(OM_in_dir) != 1) {
stop(
"OM_name ", OM_name, " matched ", length(OM_in_dir), " models in ",
"OM_name ",
OM_name,
" matched ",
length(OM_in_dir),
" models in ",
"SSMSE external package data, but should match 1. Please ",
"change OM_name to match (or partially match unambiguously) with 1 ",
"model in the models folder of the SSMSE external package data. ",
"Model options are: ", paste0(basename(pkg_dirs), collapse = ", ")
"Model options are: ",
paste0(basename(pkg_dirs), collapse = ", ")
)
}
}
Expand All @@ -58,7 +74,7 @@ develop_OMs <- function(OM_name = NULL, OM_in_dir = NULL, out_dir = getwd(), par
# " If parameter devs are desired, use refit_OMs = TRUE.")
# read in parfile to save the recdevs.
parfile <- r4ss::SS_readpar_3.30(
parfile = file.path(OM_in_dir, "ss.par"),
parfile = get_ss_par_file(OM_in_dir),
datsource = file.path(OM_in_dir, start[["datfile"]]),
ctlsource = file.path(OM_in_dir, start[["ctlfile"]]),
verbose = FALSE
Expand All @@ -83,64 +99,90 @@ develop_OMs <- function(OM_name = NULL, OM_in_dir = NULL, out_dir = getwd(), par
to = tmp_mod_path
)
r4ss::SS_changepars(
dir = tmp_mod_path, ctlfile = "control.ss_new",
newctlfile = "control_modified.ss", strings = par_name,
newvals = i, verbose = FALSE
dir = tmp_mod_path,
ctlfile = "control.ss_new",
newctlfile = "control_modified.ss",
strings = par_name,
newvals = i,
verbose = FALSE
)
# remove files with old values
file.remove(file.path(tmp_mod_path, "control.ss_new"))
file.remove(file.path(tmp_mod_path, start[["ctlfile"]]))
file.remove(file.path(tmp_mod_path, "ss.par"))
par_file <- get_ss_par_file(tmp_mod_path)
if (file.exists(par_file)) {
file.remove(par_file)
}
if (file.exists(file.path(tmp_mod_path, "ss.par"))) {
file.remove(file.path(tmp_mod_path, "ss.par"))
}
file.rename(
from = file.path(tmp_mod_path, "control_modified.ss"),
to = file.path(tmp_mod_path, start[["ctlfile"]])
)
if (refit_OMs == TRUE) {
run_ss_model(
r4ss::run(
dir = tmp_mod_path,
admb_options = opts,
exe = get_bin(),
extras = opts,
skipfinished = FALSE,
verbose = FALSE
)
if (!file.exists(file.path(tmp_mod_path, "control.ss_new"))) {
warning("Problem refitting model in ", tmp_mod_path)
}
if (file.exists(file.path(tmp_mod_path, "data.ss_new")) && file.exists(file.path(tmp_mod_path, "data_echo.ss_new"))) {
if (
# if redundant files exist, delete the one with the old name
file.exists(file.path(tmp_mod_path, "data.ss_new")) &&
file.exists(file.path(tmp_mod_path, "data_echo.ss_new"))
) {
file.remove(file.path(tmp_mod_path, "data.ss_new"))
}
} else {
# run with no estimation
run_ss_model(
r4ss::run(
dir = tmp_mod_path,
admb_options = "-maxfn 0 -phase 50 -nohess",
exe = get_bin(),
extras = "-maxfn 0 -phase 50 -nohess",
skipfinished = FALSE,
verbose = FALSE
)
if (!file.exists(file.path(tmp_mod_path, "control.ss_new"))) {
warning("Problem running model without estimation in ", tmp_mod_path)
}
if (file.exists(file.path(tmp_mod_path, "data.ss_new")) && file.exists(file.path(tmp_mod_path, "data_echo.ss_new"))) {
if (
# if redundant files exist, delete the one with the old name
file.exists(file.path(tmp_mod_path, "data.ss_new")) &&
file.exists(file.path(tmp_mod_path, "data_echo.ss_new"))
) {
file.remove(file.path(tmp_mod_path, "data.ss_new"))
}
# add back original recdevs into the model (b/c not specified through the ctl file)
new_parfile <- r4ss::SS_readpar_3.30(
parfile = file.path(tmp_mod_path, "ss.par"),
parfile = get_ss_par_file(tmp_mod_path),
datsource = file.path(tmp_mod_path, start[["datfile"]]),
ctlsource = file.path(tmp_mod_path, start[["ctlfile"]]), verbose = FALSE
ctlsource = file.path(tmp_mod_path, start[["ctlfile"]]),
verbose = FALSE
)
if (!is.null(new_parfile[["recdev1"]])) {
recdev_name <- "recdev1"
} else {
recdev_name <- "recdev2"
}
new_parfile[[recdev_name]][, "recdev"] <- parfile[[recdev_name]][, "recdev"]
new_parfile[[recdev_name]][, "recdev"] <- parfile[[recdev_name]][,
"recdev"
]

# add back original F estimates for F method 2 assessments otherwise they all default to 0.05
if (!is.null(new_parfile[["F_rate"]])) {
new_parfile[["F_rate"]][, "F"] <- parfile[["F_rate"]][, "F"]
}

r4ss::SS_writepar_3.30(new_parfile,
outfile = file.path(tmp_mod_path, "ss.par"),
verbose = FALSE, overwrite = TRUE
r4ss::SS_writepar_3.30(
new_parfile,
outfile = get_ss_par_file(tmp_mod_path),
verbose = FALSE,
overwrite = TRUE
)
}
}
Expand Down
49 changes: 45 additions & 4 deletions R/develtools.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,24 @@ test_no_par <- function(orig_mod_dir, new_mod_dir) {
dir = file.path(new_mod_dir), overwrite = TRUE,
verbose = FALSE
)
try(run_ss_model(new_mod_dir, "-maxfn 0 -phase 50 -nohess", verbose = FALSE))
try(r4ss::run(
dir = new_mod_dir,
exe = get_bin(),
extras = "-maxfn 0 -phase 50 -nohess",
skipfinished = FALSE,
verbose = FALSE
))
# read in the 2 par files.
orig_par <- readLines(file.path(orig_mod_dir, "ss.par"))
orig_par <- readLines(get_ss_par_file(orig_mod_dir))

dat_file <- list.files(new_mod_dir, pattern = "data.ss_new|data_echo.ss_new")
dat_file <- list.files(
new_mod_dir,
pattern = "^data(\\.ss_new|_echo\\.ss_new|_expval\\.ss|_boot_[0-9]{3}\\.ss)$"
)

if (length(dat_file) > 0) {
if (file.exists(file.path(new_mod_dir, dat_file))) {
new_par <- readLines(file.path(new_mod_dir, "ss.par"))
new_par <- readLines(get_ss_par_file(new_mod_dir))
if (length(orig_par) != length(new_par)) {
new_par_names <- grep("^# [^N]", new_par, value = TRUE)
orig_par_names <- grep("^# [^N]", orig_par, value = TRUE)
Expand Down Expand Up @@ -71,3 +80,35 @@ test_no_par <- function(orig_mod_dir, new_mod_dir) {
}
invisible(orig_mod_dir)
}

#' function for package developers to update SS3 input files
#'
#' @param dir_models directory containing the model input files

update_ss3_version <- function(dir_models = "inst/extdata/models") {
# get list of models
models <- dir(dir_models, full.names = TRUE)

# get current executable
dir_exe <- r4ss::get_ss3_exe(dir = tempdir())

# run with current SS3 version without estimation
for (i in 1:length(models)) {
r4ss::run(
dir = models[i],
exe = dir_exe,
skipfinished = FALSE,
extras = "-nohess -stopph 0"
)
}

# replace original files with renamed ss_new files
for (i in 1:length(models)) {
r4ss::copy_SS_inputs(
dir.old = models[i],
dir.new = models[i],
use_ss_new = TRUE,
overwrite = TRUE
)
}
}
Loading