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: 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
68 changes: 45 additions & 23 deletions R/MS_functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ EM <- function(EM_out_dir = NULL, init_loop = TRUE, OM_dat, verbose = FALSE,
#' @return A data frame of future catch
get_EM_catch_df <- function(EM_dir, dat) {
rpt <- readLines(file.path(EM_dir, "Report.sso"))
start <- grep("TIME_SERIES", rpt)
start <- grep("^TIME_SERIES", rpt) # need to not match ANNUAL_TIME_SERIES
start <- start[length(start)] + 1
end <- grep("SPR_series", rpt, ignore.case = TRUE)
end <- end[length(end)] - 1
Expand Down 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 @@ -483,14 +484,19 @@ get_no_EM_catch_df <- function(OM_dir, yrs, MS = "last_yr_catch") {
# TODO: figure out what values should go here; probably not 0.
Fcast_rec_line <- grep("^# Fcast_recruitments:$", par) + 1
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"))
# # Forecast implementation error parameters were included in earlier SS3 version
# # whether specified by the user or not. These changes are not needed in 3.30.24.
# Fcast_impl_err_line <- grep("^# Fcast_impl_error:$", par) + 1
# par[Fcast_impl_err_line] <- paste0(rep(0, fore[["Nforecastyrs"]]), collapse = " ")
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 +535,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 +599,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 @@ -611,12 +622,18 @@ Interim <- function(EM_out_dir = NULL, EM_init_dir = NULL,
temp_forecast[, 1] <- (Reference_dat[["endyr"]] + 1 - forecast_adjust):(Reference_dat[["endyr"]] + Reference_forecast[["Nforecastyrs"]])
colnames(temp_forecast) <- c("year", "recdev")
Reference_par[["recdev_forecast"]] <- as.data.frame(temp_forecast)
temp_impl_error <- matrix(0, nrow = (Reference_forecast[["Nforecastyrs"]]), ncol = 2)
temp_impl_error[, 1] <- (Reference_dat[["endyr"]] + 1):(Reference_dat[["endyr"]] + Reference_forecast[["Nforecastyrs"]])
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)
# # Forecast implementation error parameters were included in earlier SS3 version
# # whether specified by the user or not. These changes are not needed in 3.30.24.
# temp_impl_error <- matrix(0, nrow = (Reference_forecast[["Nforecastyrs"]]), ncol = 2)
# temp_impl_error[, 1] <- (Reference_dat[["endyr"]] + 1):(Reference_dat[["endyr"]] + Reference_forecast[["Nforecastyrs"]])
# 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 = get_ss_par_file(EM_out_dir),
overwrite = TRUE
)

SS_writeforecast(
mylist = Reference_forecast,
Expand Down Expand Up @@ -674,15 +691,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
2 changes: 1 addition & 1 deletion R/calc_F.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#' @importFrom tidyr gather separate
#' @return a list containing: F_df, a long dataframe with F by year, Era, Seas,
#' and fleet; F_rate, a data frame with F for the time frame of the model
#' only by year, Seas, and fleet, ordered as the ss.par file expects; init_F,
#' only by year, Seas, and fleet, ordered as the ss3.par file expects; init_F,
#' a named vector of initial F values by Season and fleet, ordered (and named)
#' as SS expects; and F_rate_fcast, a dataframe of forecasted F by year, Seas,
#' and fleet, ordered as SS would expect in F_rate.
Expand Down
89 changes: 66 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,91 @@ 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)
}
# also delete older name of .par file if they exist
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
Loading
Loading