diff --git a/.github/workflows/build-doxygen.yml b/.github/workflows/build-doxygen.yml
index 1522f3f1c..7da888230 100644
--- a/.github/workflows/build-doxygen.yml
+++ b/.github/workflows/build-doxygen.yml
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Get repository
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: Installing build dependencies
run: |
diff --git a/.github/workflows/call-allcontributors.yml b/.github/workflows/call-allcontributors.yml
index bfcb2c1aa..1cc1d16d2 100644
--- a/.github/workflows/call-allcontributors.yml
+++ b/.github/workflows/call-allcontributors.yml
@@ -19,7 +19,7 @@ jobs:
pull-requests: write
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: Setup R
uses: r-lib/actions/setup-r@v2
diff --git a/.github/workflows/get-gtest-codecov.yml b/.github/workflows/get-gtest-codecov.yml
index 2ae853afd..102395be1 100644
--- a/.github/workflows/get-gtest-codecov.yml
+++ b/.github/workflows/get-gtest-codecov.yml
@@ -19,7 +19,7 @@ jobs:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Install Ninja
run: sudo apt-get install ninja-build
- uses: r-lib/actions/setup-r@v2
diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml
index 3f05adcae..399bb22b3 100644
--- a/.github/workflows/greetings.yml
+++ b/.github/workflows/greetings.yml
@@ -2,6 +2,10 @@ name: Greetings
on: [pull_request_target, issues]
+permissions:
+ issues: write
+ pull-requests: write
+
jobs:
greeting:
runs-on: ubuntu-latest
@@ -9,7 +13,7 @@ jobs:
issues: write
pull-requests: write
steps:
- - uses: actions/first-interaction@v1
+ - uses: actions/first-interaction@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: >
diff --git a/.github/workflows/run-clang-format.yml b/.github/workflows/run-clang-format.yml
index a09276910..2f6e89b65 100644
--- a/.github/workflows/run-clang-format.yml
+++ b/.github/workflows/run-clang-format.yml
@@ -27,7 +27,7 @@ jobs:
# Format hpp and cpp files under inst/include, src/, and test/gtest
# We use Google style to format code.
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- uses: DoozyX/clang-format-lint-action@v0.20
with:
source: './inst/include ./src ./tests/gtest'
diff --git a/.github/workflows/run-clang-tidy.yml b/.github/workflows/run-clang-tidy.yml
index 52fb09eed..7d741534f 100644
--- a/.github/workflows/run-clang-tidy.yml
+++ b/.github/workflows/run-clang-tidy.yml
@@ -27,7 +27,7 @@ jobs:
strategy:
fail-fast: false
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: install clang-tidy
run: sudo apt update && sudo apt -y install clang-tidy
diff --git a/.github/workflows/run-googletest.yml b/.github/workflows/run-googletest.yml
index db967153b..d996feb72 100644
--- a/.github/workflows/run-googletest.yml
+++ b/.github/workflows/run-googletest.yml
@@ -16,7 +16,7 @@ jobs:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Install Ninja
shell: bash
run: ${{ runner.os == 'macOS' && 'brew install ninja' || runner.os == 'Windows' && 'choco install ninja' || 'sudo apt-get install ninja-build' }}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e99a9ca8a..69dad3468 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,33 +54,6 @@ IF(BUILD_DOC)
COMMENT "Building documentation with Doxygen.")
ENDIF()
-# Set up Rcpp
-FetchContent_Declare(
- rcpp
- URL https://github.com/RcppCore/Rcpp/archive/refs/tags/1.0.8.zip
-)
-FetchContent_MakeAvailable(rcpp)
-
-# Set up R
-MESSAGE(STATUS "Looking for R executable")
-
-EXECUTE_PROCESS(
- COMMAND which R
- OUTPUT_VARIABLE R_EXECUTABLE)
-
-MESSAGE(STATUS "R_EXECUTABLE is ${R_EXECUTABLE}")
-
-EXECUTE_PROCESS(
- COMMAND R "--slave" "--no-save" "-e" "cat(R.home())"
- OUTPUT_VARIABLE R_HOME)
-
-MESSAGE(STATUS "R_HOME is ${R_HOME}")
-
-EXECUTE_PROCESS(
- COMMAND R "--slave" "--no-save" "-e" "remotes::install_local(upgrade = 'always')")
-EXECUTE_PROCESS(
- COMMAND R "--slave" "--no-save" "-e" "FIMS:::setup_gtest()")
-
# Enable testing for current directory and below
enable_testing()
@@ -91,8 +64,6 @@ add_library(fims_test INTERFACE)
target_include_directories(fims_test
INTERFACE
inst/include
- ${rcpp_SOURCE_DIR}/inst/include
- ${R_HOME}/include
)
# Add compile definition STD_LIB to the fims_test target.
diff --git a/NAMESPACE b/NAMESPACE
index b737001a8..cab5cf7f4 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -64,7 +64,6 @@ export(initialize_process_distribution)
export(initialize_process_structure)
export(inv_logit)
export(is.FIMSFit)
-export(is.FIMSFits)
export(log_error)
export(log_info)
export(log_warning)
diff --git a/R/check_fims.R b/R/check_fims.R
index 4ab7ea338..0a6fd8903 100644
--- a/R/check_fims.R
+++ b/R/check_fims.R
@@ -66,8 +66,7 @@ setup_gtest <- function() {
#' @keywords developer
#' @examples
#' \dontrun{
-#' # TODO: add examples of strings passed to `...`
-#' setup_and_run_gtest()
+#' setup_and_run_gtest("--rerun-failed --output-on-failure")
#' }
setup_and_run_gtest <- function(...) {
setup_gtest()
diff --git a/R/data.R b/R/data.R
new file mode 100644
index 000000000..5ac52511d
--- /dev/null
+++ b/R/data.R
@@ -0,0 +1,76 @@
+#' FIMS input data frame
+#'
+#' A dataset containing information necessary to run an age-structured stock
+#' assessment model in FIMS. This data was generated using
+#' the `ASSAMC` package written for the [model comparison project](
+#' www.github.com/NOAA-FIMS/Age_Structured_Stock_Assessment_Model_Comparison).
+#'
+#' @format
+#' A data frame with `r NROW(data1)` observations of `r NCOL(data1)`
+#' variables:
+#' \describe{ \item{type}{The type of data the row contains. Allowed types
+#' include `age`, `length`, `index`, `landings`, `age-to-length-conversion`,
+#' and `weight-at-age` data.}
+#' \item{name}{A character string providing the name of the information source
+#' that the data was collected from, e.g., `"Trawl fishery"`.}
+#' \item{age}{An integer age. Entry can be `NA` if information pertains to
+#' multiple ages, e.g., total landings rather than landings of age-4 fish.}
+#' \item{length}{A numeric length. Entry can be `NA` if information doesn't
+#' pertain to length.}
+#' \item{datestart,dateend}{Start and end dates of the data collection period.
+#' Format all dates using `yyyy-mm-dd`, which can accommodate fake years
+#' such as `0001-01-01`.}
+#' \item{value}{The measurement of interest.}
+#' \item{unit}{A character string specifying the units of `value`. Allowed
+#' units for each data type are as follows. `mt` is used for `index`,
+#' `landings`, and `weight-at-age` data. `number` or `proportion` are each
+#' viable units for the composition data, where the former is the preferred
+#' unit of measurement.}
+#' \item{uncertainty}{A real value providing a measurement of uncertainty
+#' for value. For landings and indices of abundance this should be
+#' the standard deviation of the logged observations if you are using the
+#' lognormal distribution to fit your data. For composition data it will
+#' be your input sample size.
+#' }
+#' }
+#' @source \url{www.github.com/NOAA-FIMS/Age_Structured_Stock_Assessment_Model_Comparison}
+"data1"
+
+#' small FIMS input data frame
+#'
+#' A dataset containing minimal information necessary to run an
+#' age-structured stock
+#' assessment model in FIMS. This data was generated using the script in
+#' `/data-raw/data_small.R` and does not correspond to any realistic population
+#' or sampling method (the values are mostly arbitrary).
+#'
+#' @format
+#' A data frame with `r NROW(data_small)` observations of `r NCOL(data_small)`
+#' variables:
+#' \describe{ \item{type}{The type of data the row contains. Allowed types
+#' include `age`, `length`, `index`, `landings`, `age-to-length-conversion`,
+#' and `weight-at-age` data.}
+#' \item{name}{A character string providing the name of the information source
+#' that the data was collected from, e.g., `"Trawl fishery"`.}
+#' \item{age}{An integer age. Entry can be `NA` if information pertains to
+#' multiple ages, e.g., total landings rather than landings of age-4 fish.}
+#' \item{length}{A numeric length. Entry can be `NA` if information doesn't
+#' pertain to length.}
+#' \item{datestart,dateend}{Start and end dates of the data collection period.
+#' Format all dates using `yyyy-mm-dd`, which can accommodate fake years
+#' such as `0001-01-01`.}
+#' \item{value}{The measurement of interest.}
+#' \item{unit}{A character string specifying the units of `value`. Allowed
+#' units for each data type are as follows. `mt` is used for `index`,
+#' `landings`, and `weight-at-age` data. `number` or `proportion` are each
+#' viable units for the composition data, where the former is the preferred
+#' unit of measurement.}
+#' \item{uncertainty}{A real value providing a measurement of uncertainty
+#' for value. For landings and indices of abundance this should be
+#' the standard deviation of the logged observations if you are using the
+#' lognormal distribution to fit your data. For composition data it will
+#' be your input sample size.
+#' }
+#' }
+#' @source None, this is a simulated dataset full of arbitrary values as defined in `/data-raw/data_small.R`.
+"data_small"
diff --git a/R/data1.R b/R/data1.R
deleted file mode 100644
index 9980357d4..000000000
--- a/R/data1.R
+++ /dev/null
@@ -1,37 +0,0 @@
-#' FIMS input data frame
-#'
-#' A dataset containing information necessary to run an age-structured stock
-#' assessment model in FIMS. This data was generated using
-#' the `ASSAMC` package written for the [model comparison project](
-#' www.github.com/NOAA-FIMS/Age_Structured_Stock_Assessment_Model_Comparison).
-#'
-#' @format
-#' A data frame with `r NROW(data1)` observations of `r NCOL(data1)`
-#' variables:
-#' \describe{ \item{type}{The type of data the row contains. Allowed types
-#' include `age`, `length`, `index`, `landings`, `age-to-length-conversion`,
-#' and `weight-at-age` data.}
-#' \item{name}{A character string providing the name of the information source
-#' that the data was collected from, e.g., `"Trawl fishery"`.}
-#' \item{age}{An integer age. Entry can be `NA` if information pertains to
-#' multiple ages, e.g., total landings rather than landings of age-4 fish.}
-#' \item{length}{A numeric length. Entry can be `NA` if information doesn't
-#' pertain to length.}
-#' \item{datestart,dateend}{Start and end dates of the data collection period.
-#' Format all dates using `yyyy-mm-dd`, which can accommodate fake years
-#' such as `0001-01-01`.}
-#' \item{value}{The measurement of interest.}
-#' \item{unit}{A character string specifying the units of `value`. Allowed
-#' units for each data type are as follows. `mt` is used for `index`,
-#' `landings`, and `weight-at-age` data. `number` or `proportion` are each
-#' viable units for the composition data, where the former is the preferred
-#' unit of measurement.}
-#' \item{uncertainty}{A real value providing a measurement of uncertainty
-#' for value. For landings and indices of abundance this should be
-#' the standard deviation of the logged observations if you are using the
-#' lognormal distribution to fit your data. For composition data it will
-#' be your input sample size.
-#' }
-#' }
-#' @source \url{www.github.com/NOAA-FIMS/Age_Structured_Stock_Assessment_Model_Comparison}
-"data1"
diff --git a/R/distribution_formulas.R b/R/distribution_formulas.R
index e3b1623d8..97672b494 100644
--- a/R/distribution_formulas.R
+++ b/R/distribution_formulas.R
@@ -290,7 +290,7 @@ initialize_data_distribution <- function(
new_module <- methods::new(DlnormDistribution)
# populate logged standard deviation parameter with log of input
- # Using resize() and then assigning value to each element of log_sd diretly
+ # Using resize() and then assigning value to each element of log_sd directly
# is correct, as creating a new ParameterVector for log_sd here would
# trigger an error in integration tests with wrappers.
new_module$log_sd$resize(length(sd[["value"]]))
diff --git a/R/fimsfit.R b/R/fimsfit.R
index 31c5fa802..9f17be9d6 100644
--- a/R/fimsfit.R
+++ b/R/fimsfit.R
@@ -22,11 +22,6 @@ utils::globalVariables(c(
# TODO: Fix "no metadata object found to revise superClass" in sdreportOrList
# TODO: Write more validity checks for FIMSFit
# TODO: Better document the return of [get_estimates()], i.e., columns
-# TODO: Decide if the error from is.FIMSFits should be a single FALSE or stop
-# TODO: Decide if "total" should be a part of number_of_parameters because it
-# can be calculated from fixed_effects + random_effects and would need to
-# be calculated in print.FITFims()
-# TODO: Determine if report should always use last.par.best
# TODO: Make a helper function to add lower and upper CI for users in estimates
# methods::setClass: ----
@@ -95,6 +90,12 @@ methods::setMethod(
x@number_of_parameters,
sep = "="
)
+ total_parameters <- sum(x@number_of_parameters)
+ all_parameters_info <- c(number_of_parameters, paste(
+ "total",
+ total_parameters,
+ sep = "="
+ ))
div_digit <- cli::cli_div(theme = list(.val = list(digits = 5)))
terminal_ssb <- sapply(
x@report[["ssb"]],
@@ -103,7 +104,7 @@ methods::setMethod(
cli::cli_inform(c(
"i" = "FIMS model version: {.val {x@version}}",
"i" = "Total run time was {.val {rt}} {ru}",
- "i" = "Number of parameters: {number_of_parameters}",
+ "i" = "Number of parameters: {all_parameters_info}",
"i" = "Maximum gradient= {.val {x@max_gradient}}",
"i" = "Negative log likelihood (NLL):",
"*" = "Marginal NLL= {.val {x@opt$objective}}",
@@ -343,21 +344,6 @@ is.FIMSFit <- function(x) {
inherits(x, "FIMSFit")
}
-#' Check if an object is a list of FIMSFit objects
-#'
-#' @param x List of fits returned from multiple calls to [fit_fims()].
-#' @keywords fit_fims
-#' @export
-is.FIMSFits <- function(x) {
- if (!is.list(x)) {
- cli::cli_warn(
- message = c("x" = "{.par x} is not a list -- something went wrong.")
- )
- return(FALSE)
- }
- all(sapply(x, function(i) inherits(i, "FIMSFit")))
-}
-
# Constructors ----
#' Class constructors for class `FIMSFit` and associated child classes
@@ -431,7 +417,6 @@ FIMSFit <- function(
n_fixed_effects <- length(obj[["par"]])
n_random_effects <- length(obj[["env"]][["parList()"]][["re"]])
number_of_parameters <- c(
- total = n_total,
fixed_effects = n_fixed_effects,
random_effects = n_random_effects
)
@@ -712,6 +697,13 @@ fit_fims <- function(input,
trace = 0
),
filename = NULL) {
+ # See issue 455 of sdmTMB to see what should be used.
+ # https://github.com/pbs-assess/sdmTMB/issues/455
+ # NOTE: When we add implementation for newton step we need to
+ # review the above github issue to make sure we maintain continuity
+ # between outputs as last.par may not equal last.par.best due to
+ # the smallest newton gradient solution not matching the smallest
+ # likelihood value. This can cause sanity issues in output reporting.
if (number_of_newton_steps > 0) {
cli::cli_abort("Newton steps not implemented yet.")
}
diff --git a/R/initialize_modules.R b/R/initialize_modules.R
index 66a61abb5..9030fad8c 100644
--- a/R/initialize_modules.R
+++ b/R/initialize_modules.R
@@ -820,15 +820,6 @@ initialize_fims <- function(parameters, data) {
data_type = "landings"
)
}
- # TODO (Matthew): Determine if the "dims" field is required for DmultinomDistribution.
- # We need to decide whether to:
- # 1. Remove the "dims" field to maintain consistency with other distributions, or
- # 2. Update all relevant R functions (e.g., initialize_data_distribution())
- # that call DmultinomDistribution to set the "dims" field.
- # AMH comment:
- # 1. dims field is needed to track the dimension of multivariate input
- # 2. the pattern for multinomial is different because it is a multivariate distribution.
- # Other multivariate distributions (e.g. MVNORM) will likely also need a dims field
if ("age" %in% fleet_types &&
"AgeComp" %in% data_distribution_names_for_fleet_i) {
diff --git a/R/reshape_output.R b/R/reshape_output.R
index 4f22256ca..a25460e93 100644
--- a/R/reshape_output.R
+++ b/R/reshape_output.R
@@ -120,7 +120,7 @@ reshape_tmb_estimates <- function(obj,
opt = NULL,
parameter_names) {
# Outline for the estimates table
- # TODO: The fleet_name, age, length, and time columns are currently emplty. Matthew
+ # TODO: The fleet_name, age, length, and time columns are currently empty. Matthew
# has started adding information to the JSON output in the dev-model-families branch.
# We can populate these columns once the dev-model-families branch is merged
# into dev.
diff --git a/R/use-gtest-template.R b/R/use-gtest-template.R
new file mode 100644
index 000000000..6d8b4c23c
--- /dev/null
+++ b/R/use-gtest-template.R
@@ -0,0 +1,114 @@
+#' Create tests/gtest/test_*.cpp test file and register it in CMakeLists.txt
+#'
+#' This helper function generates a GoogleTest (gtest) C++ template file for a
+#' given function and appends lines to `CMakeLists.txt` to register the test.
+#'
+#' @param name A string representing the combined name for the C++ test file
+#' and CMake executable target. It must follow the format
+#' `FileName_ClassName_FunctionName`, where
+#' - `FileName` is the C++ source file name (e.g., "Logistic")
+#' - `ClassName` is the C++ class name (e.g., "LogisticSelectivity")
+#' - `FunctionName` is the C++ function name (e.g., "Evaluate")
+#' and use underscores to separate each component. For example:
+#' `Logistic_LogisticSelectivity_Evaluate`.
+#'
+#' If the function is not a member of a class, use a placeholder for
+#' `ClassName`. For example: `FIMSMath_ClassName_Logistic`.
+#'
+#' The default is `FileName_ClassName_FunctionName`.
+#'
+#' @return
+#' If successful, this function invisibly returns `TRUE` to allow for the
+#' chaining of commands. If the function is unsuccessful, an error message is
+#' returned.
+#'
+#' Three messages are also returned from the usethis package, which is used by
+#' this function. The first states where the FIMS project is on your computer.
+#' The second states the file path of the newly created file. The file will not
+#' be automatically opened. The third states the test has been registered in
+#' `tests/gtest/CMakeLists.txt`.
+#'
+#' @examples
+#' \dontrun{
+#' # Create a new test file named
+#' # "test_Logistic_LogisticSelectivity_Evaluate.cpp" for
+#' # `LogisticSelectivity::evaluate()` in
+#' # `inst/include/population_dynamics/selectivity/functors/logistic.hpp`.
+#'
+#' FIMS:::use_gtest_template(name = "Logistic_LogisticSelectivity_Evaluate")
+#' }
+#'
+#' @keywords developer
+use_gtest_template <- function(name = "FileName_ClassName_FunctionName") {
+ cmakelist_path <- file.path("tests", "gtest", "CMakeLists.txt")
+ # Check if the CMakeLists.txt file exists
+ if (!file.exists(cmakelist_path)) {
+ cli::cli_abort(
+ c("{.file {cmakelist_path}} does not exist.",
+ "i" = "Please ensure that the CMakeLists.txt file is present in the
+ {.file tests/gtest} directory."
+ )
+ )
+ }
+
+ # TODO: add the ability to add a function to a file that already exists
+ # TODO: add the ability to also pass the arguments for the function or find
+ # them within the code base and ensure that the template includes the
+ # necessary structure for each input argument
+ # TODO: Change the paste calls to use glue::glue() to increase readability
+
+ # Validate the name format
+ name_parts_list <- strsplit(x = name, split = "_")[[1]]
+ if (length(name_parts_list) != 3) {
+ cli::cli_abort(
+ c("Invalid {.var name} format.",
+ "i" = "Expected format: {.val FileName_ClassName_FunctionName}.",
+ "x" = "Received name: {.val {name}}."
+ )
+ )
+ }
+ # Extract parts from the name
+ file_name <- name_parts_list[[1]][1]
+ class_name <- name_parts_list[[1]][2]
+ function_name <- name_parts_list[[1]][3]
+
+ # Create the test file
+ path <- file.path("tests", "gtest", paste0("test_", name, ".cpp"))
+ if (!file.exists(path)) {
+ usethis::use_template(
+ template = "gtest_template.cpp",
+ save_as = path,
+ data = list(
+ class_name = class_name,
+ function_name = function_name
+ ),
+ package = "FIMS"
+ )
+ } else {
+ cli::cli_abort("{.file {path}} already exists.")
+ }
+
+ # Register the test in tests/gtest/CMakeLists.txt
+ # Open in append mode
+ CON <- file(cmakelist_path, "a")
+ on.exit(close(CON), add = TRUE)
+ writeLines(
+ c(
+ paste0("\n\n# test_", name, ".cpp"),
+ paste0("add_executable(", name),
+ paste0(" test_", name, ".cpp"),
+ paste0(")\n"),
+ paste0("target_link_libraries(", name),
+ paste0(" gtest_main"),
+ paste0(" fims_test"),
+ paste0(")\n"),
+ paste0("gtest_discover_tests(", name, ")")
+ ),
+ CON
+ )
+ cli::cli_alert_success(
+ "Registering test {.val {name}} in {.file {cmakelist_path}}."
+ )
+
+ invisible(TRUE)
+}
diff --git a/R/use_template.R b/R/use-testthat-template.R
similarity index 99%
rename from R/use_template.R
rename to R/use-testthat-template.R
index 215e4b2c4..7eda4bcc9 100644
--- a/R/use_template.R
+++ b/R/use-testthat-template.R
@@ -42,6 +42,8 @@
#' \dontrun{
#' FIMS:::use_testthat_template("new_function")
#' }
+#'
+#' @keywords developer
use_testthat_template <- function(name) {
# TODO: add the ability to add a function to a file that already exists
# TODO: add the ability to also pass the arguments for the function or find
diff --git a/R/zzz.R b/R/zzz.R
index c20f4fbe6..d277dcaf8 100644
--- a/R/zzz.R
+++ b/R/zzz.R
@@ -1,4 +1,30 @@
-Rcpp::loadModule(module = "fims", what = TRUE)
+# Note
+#
+# Placing `Rcpp::loadModule(module = "fims", what = TRUE)` inside the
+# `.onLoad` function has been observed to fix R session crashes when running
+# `devtools::load_all()` followed by `devtools::test()` in the package
+# development workflow.
+#
+# `Rcpp::loadModule()` is called to make all objects from C++ module
+# "fims" accessible in R.
+# `loadNamespace` calls `.onLoad()` before sealing the namespace and processing
+# exports.
+# This might provide `pkgload` (used by `devtools::load_all()` and
+# `devtools::test()`) a more consistent state to manage the dynamic library
+# during its unload/reload cycles in a development environment (Source: Gemini).
+#
+# There is no direct or explicit documentation stating that `Rcpp::loadModule()`
+# must be called in `.onLoad()`. The `Rcpp` documentation mentions that for
+# R 2.15.1 and later (e.g., from
+# `https://github.com/RcppCore/Rcpp/blob/29b3b78df547e55dbcceb1c5e81a978f441dd58b/inst/skeleton/zzz.R`)
+# `loadModule()` does not strictly need to be in `.onLoad()`
+# because it "triggers a load action" internally. However, packages like
+# `stan-dev/rstan` and several others do call `Rcpp::loadModule()` within
+# their `.onLoad()` functions. See examples from
+# https://github.com/search?q=Rcpp%3A%3AloadModule%28+zzz.R&type=code.
+.onLoad <- function(libname, pkgname) {
+ Rcpp::loadModule(module = "fims", what = TRUE)
+}
.onUnload <- function(libpath) {
library.dynam.unload("FIMS", libpath)
diff --git a/README.md b/README.md
index e356bcc07..d8deb22a7 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
[](https://noaa-fims.r-universe.dev/FIMS)
- [](https://github.com/NOAA-FIMS/FIMS/actions)
+ [](https://github.com/NOAA-FIMS/FIMS/actions/workflows/call-r-cmd-check.yml)
[](https://app.codecov.io/gh/NOAA-FIMS/FIMS?branch=main)
[](https://lifecycle.r-lib.org/articles/stages.html#experimental)
@@ -35,6 +35,7 @@ All contributors participating and contributing to the FIMS project are expected
+
@@ -139,12 +140,24 @@ All contributions to this project are gratefully acknowledged using the [`allcon
+
+
+
+abhinav-1305
+ |
+
KyleShertzer-NOAA
|
+
+
+
+alexjensen-NOAA
+ |
+
@@ -162,12 +175,6 @@ All contributions to this project are gratefully acknowledged using the [`allcon
Srajald
|
-
-
-
-
-alexjensen-NOAA
- |
@@ -315,6 +322,7 @@ All contributions to this project are gratefully acknowledged using the [`allcon
+
## NOAA Disclaimer
This repository is a scientific product and is not official communication of the National Oceanic and Atmospheric Administration, or the United States Department of Commerce. All NOAA GitHub project code is provided on an 'as is' basis and the user assumes responsibility for its use. Any claims against the Department of Commerce or Department of Commerce bureaus stemming from the use of this GitHub project will be governed by all applicable Federal law. Any reference to specific commercial products, processes, or services by service mark, trademark, manufacturer, or otherwise, does not constitute or imply their endorsement, recommendation or favoring by the Department of Commerce. The Department of Commerce seal and logo, or the seal and logo of a DOC bureau, shall not be used in any manner to imply endorsement of any commercial product or activity by DOC or the United States Government.
diff --git a/data-raw/data1.R b/data-raw/data1.R
index 897acab89..17f16691d 100644
--- a/data-raw/data1.R
+++ b/data-raw/data1.R
@@ -458,13 +458,6 @@ write.csv(
file.path("FIMS_input_data.csv"),
row.names = FALSE
)
-# check csv can be read into R well
-test_read <- utils::read.csv(file.path("FIMS_input_data.csv"))
-# TODO: check if the following is needed before running expect_equal()
-test_read[["datestart"]] <- as.Date(test_read[["datestart"]])
-test_read[["dateend"]] <- as.Date(test_read[["dateend"]])
-testthat::expect_equal(test_read, data1)
-unlink("FIMS_input_data.csv")
usethis::use_data(data1, overwrite = TRUE)
on.exit(unlink(main_dir, recursive = TRUE), add = TRUE)
diff --git a/data-raw/data_small.R b/data-raw/data_small.R
new file mode 100644
index 000000000..f2b7c3ef4
--- /dev/null
+++ b/data-raw/data_small.R
@@ -0,0 +1,177 @@
+#' Create a small simulated data set using arbitrary inputs
+#'
+#' This data set isn't a realistic example like data1 but is much smaller
+#' which may be useful for debugging.
+#'
+#' @details
+#' * Currently has 3 years of data, 3 ages bins, 3 length bins, and 1 fleet.
+#' * Contains landings, indices, age composition, length composition,
+#' weight-at-age, and age-to-length conversion data.
+#' * See also data-raw/data1.R
+#'
+#' @author Ian G. Taylor
+
+# set dimensions
+years <- 1:3
+lengths <- c(10, 20, 30)
+ages <- 1:3
+fleets <- 1
+
+# create landings data (slowly increasing over 3 years)
+landings <- tibble::tibble(
+ type = "landings",
+ name = paste0("fleet", fleets),
+ age = NA,
+ length = NA,
+ datestart = paste0(years, "-01-01"),
+ dateend = paste0(years, "-12-31"),
+ value = 1000 + 100 * years,
+ unit = "mt",
+ uncertainty = 0.01
+)
+
+# create indices data (slowly decreasing over 3 years)
+indices <- tibble::tibble(
+ type = "index",
+ name = paste0("fleet", fleets),
+ age = NA,
+ length = NA,
+ datestart = paste0(years, "-01-01"),
+ dateend = paste0(years, "-12-31"),
+ value = 4000 - 100 * years,
+ unit = "mt",
+ uncertainty = 0.25
+)
+
+# age composition data (equal proportions across ages)
+agecomps <- tidyr::expand_grid(
+ year = years,
+ age = ages
+) |>
+ dplyr::mutate(
+ type = "age",
+ name = paste0("fleet", fleets),
+ age = age,
+ length = NA,
+ datestart = paste0(year, "-01-01"),
+ dateend = paste0(year, "-12-31"),
+ value = 1 / length(ages),
+ unit = "proportion",
+ uncertainty = 60
+ ) |>
+ dplyr::select(-year)
+
+# length composition data (equal proportions across lengths)
+lencomps <- tidyr::expand_grid(
+ year = years,
+ length = lengths
+) |>
+ dplyr::mutate(
+ type = "length",
+ name = paste0("fleet", fleets),
+ age = NA,
+ length = length,
+ datestart = paste0(year, "-01-01"),
+ dateend = paste0(year, "-12-31"),
+ value = 1 / length(lengths),
+ unit = "proportion",
+ uncertainty = 120
+ ) |>
+ dplyr::select(-year)
+
+# weight-at-age data (weight in kg equal to age, converted to mt)
+weight_at_age <- tidyr::expand_grid(
+ year = years,
+ age = ages
+) |>
+ dplyr::mutate(
+ type = "weight-at-age",
+ name = paste0("fleet", fleets),
+ age = age,
+ length = NA,
+ datestart = paste0(year, "-01-01"),
+ dateend = paste0(year, "-12-31"),
+ value = age / 1000,
+ unit = "mt",
+ uncertainty = NA
+ ) |>
+ dplyr::select(-year)
+
+# make up an age-to-length conversion matrix if 3 ages and 3 lengths
+len_at_age_matrix <- matrix(
+ c(1.0, 0.0, 0.0, 0.1, 0.8, 0.1, 0.0, 0.3, 0.7),
+ nrow = length(ages),
+ byrow = TRUE
+)
+# if dimensions don't match (if not 3 x 3 as above),
+# create simple diagonal matrix instead
+if (
+ nrow(len_at_age_matrix) != length(ages) ||
+ ncol(len_at_age_matrix) != length(lengths)
+) {
+ len_at_age_matrix <- matrix(
+ 0,
+ nrow = length(ages),
+ ncol = length(lengths)
+ )
+ diag(len_at_age_matrix) <- 1
+ # any ages beyond the number of lengths map to the final length bin
+ if (length(ages) > length(lengths)) {
+ len_at_age_matrix[
+ (length(lengths) + 1):length(ages),
+ length(lengths)
+ ] <- 1
+ }
+}
+
+# simple function to get values from the age-to-length conversion matrix
+# given age and length to use in the mutate() command with expand_grid() below
+get_len_at_age_value <- function(age, length) {
+ age_idx <- match(age, ages)
+ length_idx <- match(length, lengths)
+ mapply(function(a, l) len_at_age_matrix[a, l], age_idx, length_idx)
+}
+
+# create age-to-length conversion data
+age_to_length_conversion <- tidyr::expand_grid(
+ year = years,
+ age = ages,
+ length = lengths
+) |>
+ dplyr::mutate(
+ type = "age-to-length-conversion",
+ name = paste0("fleet", fleets),
+ age = age,
+ length = length,
+ datestart = paste0(year, "-01-01"),
+ dateend = paste0(year, "-12-31"),
+ value = get_len_at_age_value(age, length),
+ unit = "mt",
+ uncertainty = NA
+ ) |>
+ # reorder columns to match FIMSFrame format used in other tibbles above
+ dplyr::select(
+ type,
+ name,
+ age,
+ length,
+ datestart,
+ dateend,
+ value,
+ unit,
+ uncertainty
+ )
+
+# combine all data sources and convert to FIMSFrame
+data_small <- rbind(
+ landings,
+ indices,
+ agecomps,
+ lencomps,
+ weight_at_age,
+ age_to_length_conversion
+)
+
+# save as .rda file for use in the package
+usethis::use_data(data_small, overwrite = TRUE)
+rm(list = ls())
diff --git a/data/data_small.rda b/data/data_small.rda
new file mode 100644
index 000000000..9329b3b2a
Binary files /dev/null and b/data/data_small.rda differ
diff --git a/inst/WORDLIST b/inst/WORDLIST
index ec2d1b093..afe4c5209 100644
--- a/inst/WORDLIST
+++ b/inst/WORDLIST
@@ -1,6 +1,8 @@
Arith
Beverton
BevertonHoltRecruitment
+CMake
+CMakeLists
CMD
CppAD
CPUE
@@ -11,6 +13,7 @@ EWAAgrowth
FIMSFit
FIMSFrame
Fmort
+GoogleTest
JSON
Lifecycle
LogEntry
@@ -36,6 +39,7 @@ cli
cmake
codebase
cov
+cpp
cv
cyclomatic
dateend
@@ -53,6 +57,7 @@ ggplot
github
googletest
grey
+gtest
hpp
init
json
diff --git a/inst/include/common/def.hpp b/inst/include/common/def.hpp
index fcdc44d4d..92d7d9f46 100644
--- a/inst/include/common/def.hpp
+++ b/inst/include/common/def.hpp
@@ -74,7 +74,7 @@
#endif
#endif
-// The following rows initialize default log files for outputing model progress
+// The following rows initialize default log files for outputting model progress
// comments used to assist in diagnosing model issues and tracking progress.
// These files will only be created if a logs folder is added to the root model
// directory.
diff --git a/inst/include/common/fims_vector.hpp b/inst/include/common/fims_vector.hpp
index ffc21de55..6037adfd7 100644
--- a/inst/include/common/fims_vector.hpp
+++ b/inst/include/common/fims_vector.hpp
@@ -26,7 +26,7 @@ class Vector {
std::vector vec_m;
/**
- * @brief friend comparison operator. Allows the operartor to see private
+ * @brief friend comparison operator. Allows the operator to see private
* members of fims::Vector.
*/
template
@@ -46,10 +46,10 @@ class Vector {
typedef typename std::vector::reference
reference; /*!*/
typedef typename std::vector::const_reference
- const_reference; /*!*/
+ const_reference; /*!*/
typedef typename std::vector::pointer pointer; /*!*/
typedef typename std::vector::const_pointer
- const_pointer; /*!*/
+ const_pointer; /*!*/
typedef typename std::vector::iterator iterator; /*!*/
typedef typename std::vector::const_iterator
const_iterator; /*!*/
diff --git a/inst/include/common/information.hpp b/inst/include/common/information.hpp
index 3872976e2..99d357468 100644
--- a/inst/include/common/information.hpp
+++ b/inst/include/common/information.hpp
@@ -464,7 +464,7 @@ class Information {
}
/**
- * @brief Set pointers to the recruitment module referened in the population
+ * @brief Set pointers to the recruitment module referenced in the population
* module.
*
* @param &valid_model reference to true/false boolean indicating whether
@@ -503,7 +503,7 @@ class Information {
}
/**
- * @brief Set pointers to the recruitment process module referened in the
+ * @brief Set pointers to the recruitment process module referenced in the
* population module.
*
* @param &valid_model reference to true/false boolean indicating whether
@@ -543,7 +543,7 @@ class Information {
}
/**
- * @brief Set pointers to the growth module referened in the population
+ * @brief Set pointers to the growth module referenced in the population
* module.
*
* @param &valid_model reference to true/false boolean indicating whether
@@ -582,7 +582,7 @@ class Information {
}
/**
- * @brief Set pointers to the maturity module referened in the population
+ * @brief Set pointers to the maturity module referenced in the population
* module.
*
* @param &valid_model reference to true/false boolean indicating whether
diff --git a/inst/include/common/model.hpp b/inst/include/common/model.hpp
index a343d1332..901d80b07 100644
--- a/inst/include/common/model.hpp
+++ b/inst/include/common/model.hpp
@@ -147,7 +147,7 @@ class Model { // may need singleton
// Prepare recruitment
p->recruitment->Prepare();
- FIMS_INFO_LOG("Recruitmnt successfully prepared.")
+ FIMS_INFO_LOG("Recruitment successfully prepared.")
}
// Loop over and evaluate populations
@@ -175,15 +175,15 @@ class Model { // may need singleton
#ifdef TMB_MODEL
f->of = this->of;
#endif
- FIMS_INFO_LOG("Begin evalulation for fleet " + fims::to_string(f->id));
+ FIMS_INFO_LOG("Begin evaluation for fleet " + fims::to_string(f->id));
f->evaluate_age_comp();
if (f->nlengths > 0) {
f->evaluate_length_comp();
}
- FIMS_INFO_LOG("Begin evalulation of landings for fleet " +
+ FIMS_INFO_LOG("Begin evaluation of landings for fleet " +
fims::to_string(f->id));
f->evaluate_landings();
- FIMS_INFO_LOG("Begin evalulation of index for fleet " +
+ FIMS_INFO_LOG("Begin evaluation of index for fleet " +
fims::to_string(f->id));
f->evaluate_index();
}
diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_interface_base.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_interface_base.hpp
index 69771ca24..c46b9c2de 100644
--- a/inst/include/interface/rcpp/rcpp_objects/rcpp_interface_base.hpp
+++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_interface_base.hpp
@@ -56,7 +56,7 @@ class Parameter {
*/
double max_m = std::numeric_limits::infinity();
/**
- * @brief A string indicationg the estimation type. Options are: constant,
+ * @brief A string indicating the estimation type. Options are: constant,
* fixed_effects, or random_effects, where the default is constant.
*/
SharedString estimation_type_m = SharedString("constant");
@@ -252,7 +252,6 @@ class ParameterVector {
SEXP at(R_xlen_t pos) {
if (static_cast(pos) == 0 ||
static_cast(pos) > this->storage_m->size()) {
- Rcpp::Rcerr << "ParameterVector: Index out of range.\n";
throw std::invalid_argument("ParameterVector: Index out of range");
FIMS_ERROR_LOG(fims::to_string(pos) + "!<" +
fims::to_string(this->size()));
@@ -270,7 +269,6 @@ class ParameterVector {
*/
Parameter& get(size_t pos) {
if (pos >= this->storage_m->size()) {
- Rcpp::Rcerr << "ParameterVector: Index out of range.\n";
throw std::invalid_argument("ParameterVector: Index out of range");
}
return (this->storage_m->at(pos));
@@ -539,7 +537,7 @@ class RealVector {
SEXP at(R_xlen_t pos) {
if (static_cast(pos) == 0 ||
static_cast(pos) > this->storage_m->size()) {
- Rcpp::Rcout << "RealVector: Index out of range.\n";
+ throw std::invalid_argument("RealVector: Index out of range");
FIMS_ERROR_LOG(fims::to_string(pos) + "!<" +
fims::to_string(this->size()));
return NULL;
@@ -556,7 +554,6 @@ class RealVector {
*/
double& get(size_t pos) {
if (pos >= this->storage_m->size()) {
- Rcpp::Rcout << "RealVector: Index out of range.\n";
throw std::invalid_argument("RealVector: Index out of range");
}
return (this->storage_m->at(pos));
diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_models.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_models.hpp
index b80bdc3eb..7a11375a6 100644
--- a/inst/include/interface/rcpp/rcpp_objects/rcpp_models.hpp
+++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_models.hpp
@@ -115,7 +115,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase {
population_ids(other.population_ids) {}
/**
- * Metthod to add a population id to the set of population ids.
+ * Method to add a population id to the set of population ids.
*/
void AddPopulation(uint32_t id) {
this->population_ids->insert(id);
@@ -504,7 +504,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase {
}
/**
- * @brief Minimimum method to calculate the minimum of an array or vector
+ * @brief Minimum method to calculate the minimum of an array or vector
* of doubles.
*
* @param v
@@ -544,7 +544,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase {
Rcpp::List calculate_reference_points_population(
PopulationInterface *population_interface, double maxF = 1.0,
double step = 0.01) {
- // //note: this algoritm is ported from the Meta-population
+ // //note: this algorithm is ported from the Meta-population
// assessment system project and
// //needs review
@@ -662,7 +662,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase {
// Z_age[nages - 1]));
// spr[i] = sum(N_age * reprod);
- // #warning This is propbably not correct
+ // #warning This is probably not correct
// R_eq[i] = pop->recruitment->evaluate(spr[i], spr_F0);
// // R_eq[i] = (R0 / ((5.0 * steep - 1.0) * spr[i])) *
// // (BC * 4.0 * steep * spr[i] - spr_F0 * (1.0 -
diff --git a/inst/include/models/functors/catch_at_age.hpp b/inst/include/models/functors/catch_at_age.hpp
index 899367944..ce5fb06cf 100644
--- a/inst/include/models/functors/catch_at_age.hpp
+++ b/inst/include/models/functors/catch_at_age.hpp
@@ -975,7 +975,7 @@ class CatchAtAge : public FisheryModelBase {
for (size_t y = 0; y < fleet->nyears; y++) {
Type sum = static_cast(0.0);
Type sum_obs = static_cast(0.0);
- // robust_add is a small value to add to expected compostion
+ // robust_add is a small value to add to expected composition
// proportions at age to stabilize likelihood calculations
// when the expected proportions are close to zero.
// Type robust_add = static_cast(0.0); // zeroed out before
@@ -989,7 +989,7 @@ class CatchAtAge : public FisheryModelBase {
// should be calculated from the retained landings or
// the total population. These values are slightly different.
// In the future this will have more impact as we implement
- // timing rather than everything occuring at the start of
+ // timing rather than everything occurring at the start of
// the year.
if (fleet->fleet_observed_landings_data_id_m == -999) {
this->fleet_derived_quantities[fleet->GetId()]["agecomp_expected"]
@@ -1056,7 +1056,7 @@ class CatchAtAge : public FisheryModelBase {
for (size_t y = 0; y < fleet->nyears; y++) {
Type sum = static_cast(0.0);
Type sum_obs = static_cast(0.0);
- // robust_add is a small value to add to expected compostion
+ // robust_add is a small value to add to expected composition
// proportions at age to stabilize likelihood calculations
// when the expected proportions are close to zero.
// Type robust_add = static_cast(0.0); // 0.0001; zeroed out
@@ -1209,14 +1209,14 @@ class CatchAtAge : public FisheryModelBase {
code for initial structure and recruitment 0 loops. Could also have started
loops at 1 with initial structure and recruitment setup outside the loops.
- year loop is extended to <= nyears because SSB is calculted as the start of
- the year value and by extending one extra year we get estimates of the
+ year loop is extended to <= nyears because SSB is calculated as the start
+ of the year value and by extending one extra year we get estimates of the
population structure at the end of the final year. An alternative approach
would be to keep initial numbers at age in it's own vector and each year to
include the population structure at the end of the year. This is likely a
null point given that we are planning to modify to an event/stanza based
- structure in later milestones which will elimitate this confusion by
- explicity referencing the exact date (or period of averaging) at which any
+ structure in later milestones which will eliminate this confusion by
+ explicitly referencing the exact date (or period of averaging) at which any
calculation or output is being made.
*/
for (size_t p = 0; p < this->populations.size(); p++) {
diff --git a/inst/include/population_dynamics/README.md b/inst/include/population_dynamics/README.md
index 4475dced2..898b27a41 100644
--- a/inst/include/population_dynamics/README.md
+++ b/inst/include/population_dynamics/README.md
@@ -2,7 +2,7 @@
This directory contains header files related to the population dynamics specified in FIMS. The population dynamics modules are responsible for modeling the growth, reproduction, and survival of populations over time. It includes classes and functions that define the population structure, life-history traits, and environmental factors that influence population dynamics.
-Each folder in `population_dynamics` corresponds to a component of the population dynamics model. Given the complexity of the component, the structure in these folders within `population_dynamics` may differ. At a minimum there will be a .hpp file with the same name as the subfolder, e.g., `fleet/fleet.hpp`. This file will include an `ifndef` directive and `#include` statements. If the folder is empty other than this file, then the remainder of the file will define the component. If there are additional subdirectors along side the .hpp file, the file will end after the include statements that point to each of the files in the functions folder that sits next to this .hpp file.
+Each folder in `population_dynamics` corresponds to a component of the population dynamics model. Given the complexity of the component, the structure in these folders within `population_dynamics` may differ. At a minimum there will be a .hpp file with the same name as the subfolder, e.g., `fleet/fleet.hpp`. This file will include an `ifndef` directive and `#include` statements. If the folder is empty other than this file, then the remainder of the file will define the component. If there are additional subdirectories along side the .hpp file, the file will end after the include statements that point to each of the files in the functions folder that sits next to this .hpp file.
For the latter scenario, where a `functor` folder exists, inside the `functor` folder will be a .hpp file with _base attached to the component name, e.g., `population_dynamics/maturity/functors/maturity_base.hpp`. This _base.hpp file will define the base class for the module type. The base class should only need a constructor method and a number of methods (e.g., `evaluate()`) that are not specific to the type of functions available under the subfolders but reused for all objects of that class type. This is important for life-history processes where there is structural uncertainty in the model and users may wish to investigate different forms, e.g., Beverton--Holt versus Ricker stock--recruitment relationships. Often, there will only be one functor in the subfolder but there will still be a subfolder structure. This structure is to allow for future expansion of the module type.
diff --git a/inst/include/population_dynamics/fleet/fleet.hpp b/inst/include/population_dynamics/fleet/fleet.hpp
index 382a34ab2..562439ad6 100644
--- a/inst/include/population_dynamics/fleet/fleet.hpp
+++ b/inst/include/population_dynamics/fleet/fleet.hpp
@@ -128,7 +128,7 @@ struct Fleet : public fims_model_object::FIMSObject {
virtual ~Fleet() {}
/**
- * @brief Intialize Fleet Class
+ * @brief Initialize Fleet Class
* @param nyears The number of years in the model.
* @param nages The number of ages in the model.
* @param nlengths The number of lengths in the model.
@@ -246,7 +246,7 @@ struct Fleet : public fims_model_object::FIMSObject {
for (size_t y = 0; y < this->nyears; y++) {
Type sum = static_cast(0.0);
Type sum_obs = static_cast(0.0);
- // robust_add is a small value to add to expected compostion
+ // robust_add is a small value to add to expected composition
// proportions at age to stabilize likelihood calculations
// when the expected proportions are close to zero.
// Type robust_add = static_cast(0.0); // zeroed out before testing
@@ -261,7 +261,7 @@ struct Fleet : public fims_model_object::FIMSObject {
// should be calculated from the retained landings or
// the total population. These values are slightly different.
// In the future this will have more impact as we implement
- // timing rather than everything occuring at the start of
+ // timing rather than everything occurring at the start of
// the year.
if (this->fleet_observed_landings_data_id_m == -999) {
this->agecomp_expected[i_age_year] =
@@ -309,7 +309,7 @@ struct Fleet : public fims_model_object::FIMSObject {
for (size_t y = 0; y < this->nyears; y++) {
Type sum = static_cast(0.0);
Type sum_obs = static_cast(0.0);
- // robust_add is a small value to add to expected compostion
+ // robust_add is a small value to add to expected composition
// proportions at age to stabilize likelihood calculations
// when the expected proportions are close to zero.
// Type robust_add = static_cast(0.0); // 0.0001; zeroed out
diff --git a/inst/include/population_dynamics/population/population.hpp b/inst/include/population_dynamics/population/population.hpp
index 924dd8e24..0decf0f79 100644
--- a/inst/include/population_dynamics/population/population.hpp
+++ b/inst/include/population_dynamics/population/population.hpp
@@ -64,9 +64,9 @@ struct Population : public fims_model_object::FIMSObject {
fims::Vector
biomass; /*!< Derived quantity: total population biomass in each year*/
fims::Vector spawning_biomass; /*!< Derived quantity: Spawning_biomass*/
- fims::Vector unfished_biomass; /*!< Derived quanity
+ fims::Vector unfished_biomass; /*!< Derived quantity
biomass assuming unfished*/
- fims::Vector unfished_spawning_biomass; /*!< Derived quanity Spawning
+ fims::Vector unfished_spawning_biomass; /*!< Derived quantity Spawning
biomass assuming unfished*/
fims::Vector proportion_mature_at_age; /*!< Derived quantity: Proportion
mature at age */
@@ -529,14 +529,14 @@ struct Population : public fims_model_object::FIMSObject {
code for initial structure and recruitment 0 loops. Could also have started
loops at 1 with initial structure and recruitment setup outside the loops.
- year loop is extended to <= nyears because SSB is calculted as the start of
- the year value and by extending one extra year we get estimates of the
+ year loop is extended to <= nyears because SSB is calculated as the start
+ of the year value and by extending one extra year we get estimates of the
population structure at the end of the final year. An alternative approach
would be to keep initial numbers at age in it's own vector and each year to
include the population structure at the end of the year. This is likely a
null point given that we are planning to modify to an event/stanza based
- structure in later milestones which will elimitate this confusion by
- explicity referencing the exact date (or period of averaging) at which any
+ structure in later milestones which will eliminate this confusion by
+ explicitly referencing the exact date (or period of averaging) at which any
calculation or output is being made.
*/
for (size_t y = 0; y <= this->nyears; y++) {
diff --git a/inst/include/population_dynamics/recruitment/functors/log_devs.hpp b/inst/include/population_dynamics/recruitment/functors/log_devs.hpp
index f54e7729e..55f9989da 100644
--- a/inst/include/population_dynamics/recruitment/functors/log_devs.hpp
+++ b/inst/include/population_dynamics/recruitment/functors/log_devs.hpp
@@ -1,6 +1,6 @@
/**
* @file log_devs.hpp
- * @brief Encorporates error using the log recruitment deviations approach.
+ * @brief Incorporates error using the log recruitment deviations approach.
* @details This function inherits from recruitment base.
* @copyright This file is part of the NOAA, National Marine Fisheries Service
* Fisheries Integrated Modeling System project. See LICENSE in the source
diff --git a/inst/include/population_dynamics/recruitment/functors/log_r.hpp b/inst/include/population_dynamics/recruitment/functors/log_r.hpp
index 60d01a1b9..2f46ee00e 100644
--- a/inst/include/population_dynamics/recruitment/functors/log_r.hpp
+++ b/inst/include/population_dynamics/recruitment/functors/log_r.hpp
@@ -1,6 +1,6 @@
/**
* @file log_r.hpp
- * @brief Encorporates error using the log recruitment approach.
+ * @brief Incorporates error using the log recruitment approach.
* @details This function inherits from recruitment base.
* @copyright This file is part of the NOAA, National Marine Fisheries Service
* Fisheries Integrated Modeling System project. See LICENSE in the source
diff --git a/inst/include/utilities/fims_json.hpp b/inst/include/utilities/fims_json.hpp
index 5a68a991b..94f500a9b 100644
--- a/inst/include/utilities/fims_json.hpp
+++ b/inst/include/utilities/fims_json.hpp
@@ -12,6 +12,7 @@
*/
#include
#include
+#include
#include