diff --git a/DESCRIPTION b/DESCRIPTION index 398a7d5e0..579ec18fc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -122,7 +122,7 @@ Remotes: Additional_repositories: https://noaa-fisheries-integrated-toolbox.r-universe.dev Config/Rcpp/registration: none -Config/roxygen2/version: 8.0.0 +Config/roxygen2/version: 8.1.0 Config/testthat/edition: 3 Config/testthat/parallel: false Encoding: UTF-8 @@ -130,5 +130,4 @@ Language: en-US LazyData: true NeedsCompilation: yes Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.3 SystemRequirements: GNU make diff --git a/NAMESPACE b/NAMESPACE index d01e27e12..9cbdc2a93 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -101,11 +101,15 @@ exportMethods(plot) import(methods) import(stats) importFrom(TMB,MakeADFun) -importFrom(generics,augment) -importFrom(generics,glance) -importFrom(generics,tidy) +importFrom(generics, + augment, + glance, + tidy +) importFrom(graphics,plot) -importFrom(rlang,":=") -importFrom(rlang,.data) -importFrom(rlang,.env) +importFrom(rlang, + ":=", + .data, + .env +) useDynLib(FIMS, .registration = TRUE) diff --git a/inst/include/common/fims_vector.hpp b/inst/include/common/fims_vector.hpp index 176ae7c11..16b298ece 100644 --- a/inst/include/common/fims_vector.hpp +++ b/inst/include/common/fims_vector.hpp @@ -10,6 +10,7 @@ #include "../interface/interface.hpp" #include +#include #include namespace fims { @@ -82,6 +83,8 @@ class Vector { for (size_t i = 0; i < this->vec_m.size(); i++) { this->vec_m[i] = other[i]; } + this->tag_m = other.tag_m; + this->variable_name_m = other.variable_name_m; } /** @@ -142,7 +145,7 @@ class Vector { */ inline Type &operator[](size_t pos) { if (pos >= this->size()) { - throw std::invalid_argument("fims::Vector out of bounds"); + throw std::invalid_argument(this->get_out_of_bounds_error_message(pos)); } return this->vec_m[pos]; } @@ -153,7 +156,7 @@ class Vector { */ inline const Type &operator[](size_t n) const { if (n >= this->size()) { - throw std::invalid_argument("fims::Vector out of bounds"); + throw std::invalid_argument(this->get_out_of_bounds_error_message(n)); } return this->vec_m[n]; } @@ -480,8 +483,33 @@ class Vector { */ void set_tag(const std::string &tag) { this->tag_m = tag; } + /** + * @brief Gets the variable name for the vector. + * @return The variable name. + */ + std::string get_variable_name() const { return this->variable_name_m; } + + /** + * @brief Sets the variable name for the vector. + */ + void set_variable_name(const std::string &name) { + this->variable_name_m = name; + } + private: - std::string tag_m; /*!< The tag for the vector. */ + std::string get_out_of_bounds_error_message(size_t pos) const { + std::string error_msg = "fims::Vector out of bounds"; + if (!this->variable_name_m.empty()) { + error_msg += " for " + this->variable_name_m; + } + error_msg += ": index " + std::to_string(pos + 1) + " >= size " + + std::to_string(this->size()); + return error_msg; + } + + std::string tag_m; /*!< The tag for the vector. */ + std::string variable_name_m; /*!< The name of the variable represented by the + vector. */ }; // end fims::Vector class /** diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_data.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_data.hpp index 5a5caec43..81985b86b 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_data.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_data.hpp @@ -181,6 +181,8 @@ class AgeCompDataInterface : public DataInterfaceBase { this->amax); age_comp_data->id = this->id; + std::string data_name = "age_comp_data"; + age_comp_data->data.set_variable_name(data_name); for (int y = 0; y < ymax; y++) { for (int a = 0; a < amax; a++) { int i_age_year = y * amax + a; @@ -312,6 +314,8 @@ class LengthCompDataInterface : public DataInterfaceBase { std::make_shared>(this->ymax, this->lmax); length_comp_data->id = this->id; + std::string data_name = "length_comp_data"; + length_comp_data->data.set_variable_name(data_name); for (int y = 0; y < ymax; y++) { for (int l = 0; l < lmax; l++) { int i_length_year = y * lmax + l; @@ -433,6 +437,8 @@ class IndexDataInterface : public DataInterfaceBase { std::make_shared>(this->ymax); data->id = this->id; + std::string data_name = "index_data"; + data->data.set_variable_name(data_name); for (int y = 0; y < ymax; y++) { data->at(y) = this->index_data[y]; @@ -554,6 +560,8 @@ class LandingsDataInterface : public DataInterfaceBase { std::make_shared>(this->ymax); data->id = this->id; + std::string data_name = "landings_data"; + data->data.set_variable_name(data_name); for (int y = 0; y < ymax; y++) { data->at(y) = this->landings_data[y]; diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_distribution.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_distribution.hpp index 6822530f5..18ec20c12 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_distribution.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_distribution.hpp @@ -460,17 +460,28 @@ class DnormDistributionsInterface : public DistributionsInterfaceBase { distribution->key[i] = this->key_m->at(i); } distribution->id = this->id_m; + ss.str(""); + ss << "dnorm." << this->id_m << ".observed_values"; + distribution->observed_values.set_variable_name(ss.str()); distribution->observed_values.resize(this->observed_values.size()); for (size_t i = 0; i < this->observed_values.size(); i++) { distribution->observed_values[i] = this->observed_values[i].initial_value_m; } + // set relative info + ss.str(""); + ss << "dnorm." << this->id_m << ".expected_values"; + distribution->expected_values.set_variable_name(ss.str()); distribution->expected_values.resize(this->expected_values.size()); for (size_t i = 0; i < this->expected_values.size(); i++) { distribution->expected_values[i] = this->expected_values[i].initial_value_m; } + + ss.str(""); + ss << "dnorm." << this->id_m << ".log_sd"; + distribution->log_sd.set_variable_name(ss.str()); distribution->log_sd.resize(this->log_sd.size()); for (size_t i = 0; i < this->log_sd.size(); i++) { distribution->log_sd[i] = this->log_sd[i].initial_value_m; @@ -487,13 +498,14 @@ class DnormDistributionsInterface : public DistributionsInterfaceBase { info->variable_map[this->log_sd.id_m] = &(distribution)->log_sd; distribution->use_mean = this->use_mean_m.get(); + ss.str(""); + ss << "dnorm." << this->id_m << ".expected_mean"; + distribution->expected_mean.set_variable_name(ss.str()); distribution->expected_mean.resize(this->expected_mean.size()); for (size_t i = 0; i < this->expected_mean.size(); i++) { distribution->expected_mean[i] = this->expected_mean[i].initial_value_m; if (this->expected_mean[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "dnorm." << this->id_m << ".expected_mean." - << this->expected_mean[i].id_m; + ss << "." << this->expected_mean[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(distribution->expected_mean[i]); } @@ -799,17 +811,26 @@ class DlnormDistributionsInterface : public DistributionsInterfaceBase { for (size_t i = 0; i < this->key_m->size(); i++) { distribution->key[i] = this->key_m->at(i); } + ss.str(""); + ss << "dlnorm." << this->id_m << ".observed_values"; + distribution->observed_values.set_variable_name(ss.str()); distribution->observed_values.resize(this->observed_values.size()); for (size_t i = 0; i < this->observed_values.size(); i++) { distribution->observed_values[i] = this->observed_values[i].initial_value_m; } // set relative info + ss.str(""); + ss << "dlnorm." << this->id_m << ".expected_values"; + distribution->expected_values.set_variable_name(ss.str()); distribution->expected_values.resize(this->expected_values.size()); for (size_t i = 0; i < this->expected_values.size(); i++) { distribution->expected_values[i] = this->expected_values[i].initial_value_m; } + ss.str(""); + ss << "dlnorm." << this->id_m << ".log_sd"; + distribution->log_sd.set_variable_name(ss.str()); distribution->log_sd.resize(this->log_sd.size()); for (size_t i = 0; i < this->log_sd.size(); i++) { distribution->log_sd[i] = this->log_sd[i].initial_value_m; @@ -1095,7 +1116,7 @@ class DmultinomDistributionsInterface : public DistributionsInterfaceBase { std::shared_ptr> distribution = std::make_shared>(); - + std::stringstream ss; distribution->id = this->id_m; distribution->observed_data_id_m = interface_observed_data_id_m; distribution->input_type = this->input_type_m; @@ -1103,12 +1124,18 @@ class DmultinomDistributionsInterface : public DistributionsInterfaceBase { for (size_t i = 0; i < this->key_m->size(); i++) { distribution->key[i] = this->key_m->at(i); } + ss.str(""); + ss << "dmultinom." << this->id_m << ".observed_values"; + distribution->observed_values.set_variable_name(ss.str()); distribution->observed_values.resize(this->observed_values.size()); for (size_t i = 0; i < this->observed_values.size(); i++) { distribution->observed_values[i] = this->observed_values[i].initial_value_m; } // set relative info + ss.str(""); + ss << "dmultinom." << this->id_m << ".expected_values"; + distribution->expected_values.set_variable_name(ss.str()); distribution->expected_values.resize(this->expected_values.size()); for (size_t i = 0; i < this->expected_values.size(); i++) { distribution->expected_values[i] = diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_fleet.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_fleet.hpp index c52d09556..f7503a7ac 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_fleet.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_fleet.hpp @@ -454,19 +454,18 @@ class FleetInterface : public FleetInterfaceBase { fleet->fleet_selectivity_id_m = interface_selectivity_id_m.get(); + ss.str(""); + ss << "Fleet." << this->id << ".log_q"; + fleet->log_q.set_variable_name(ss.str()); fleet->log_q.resize(this->log_q.size()); for (size_t i = 0; i < this->log_q.size(); i++) { fleet->log_q[i] = this->log_q[i].initial_value_m; - + ss << "." << this->log_q[i].id_m; if (this->log_q[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Fleet." << this->id << ".log_q." << this->log_q[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(fleet->log_q[i]); } if (this->log_q[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Fleet." << this->id << ".log_q." << this->log_q[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(fleet->log_q[i]); } @@ -484,18 +483,17 @@ class FleetInterface : public FleetInterfaceBase { fims::to_string(this->n_years.get())); } fleet->log_Fmort.resize(static_cast(this->log_Fmort.size())); + ss.str(""); + ss << "Fleet." << this->id << ".log_Fmort"; + fleet->log_Fmort.set_variable_name(ss.str()); for (size_t i = 0; i < log_Fmort.size(); i++) { fleet->log_Fmort[i] = this->log_Fmort[i].initial_value_m; - + ss << "." << this->log_Fmort[i].id_m; if (this->log_Fmort[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Fleet." << this->id << ".log_Fmort." << this->log_Fmort[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(fleet->log_Fmort[i]); } if (this->log_Fmort[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Fleet." << this->id << ".log_Fmort." << this->log_Fmort[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(fleet->log_Fmort[i]); } @@ -504,6 +502,9 @@ class FleetInterface : public FleetInterfaceBase { info->variable_map[this->log_Fmort.id_m] = &(fleet)->log_Fmort; if (this->n_lengths.get() > 0) { + ss.str(""); + ss << "Fleet." << this->id << ".age_to_length_conversion"; + fleet->age_to_length_conversion.set_variable_name(ss.str()); fleet->age_to_length_conversion.resize( this->age_to_length_conversion.size()); @@ -518,12 +519,9 @@ class FleetInterface : public FleetInterfaceBase { for (size_t i = 0; i < fleet->age_to_length_conversion.size(); i++) { fleet->age_to_length_conversion[i] = this->age_to_length_conversion[i].initial_value_m; - + ss << "." << this->age_to_length_conversion[i].id_m; if (this->age_to_length_conversion[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Fleet." << this->id << ".age_to_length_conversion." - << this->age_to_length_conversion[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(fleet->age_to_length_conversion[i]); } diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_maturity.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_maturity.hpp index f0a782687..06ab90997 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_maturity.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_maturity.hpp @@ -226,39 +226,37 @@ class LogisticMaturityInterface : public MaturityInterfaceBase { // set relative info maturity->id = this->id; std::stringstream ss; + ss.str(""); + ss << "Maturity." << this->id << ".inflection_point"; + maturity->inflection_point.set_variable_name(ss.str()); maturity->inflection_point.resize(this->inflection_point.size()); for (size_t i = 0; i < this->inflection_point.size(); i++) { maturity->inflection_point[i] = this->inflection_point[i].initial_value_m; + ss << "." << this->inflection_point[i].id_m; if (this->inflection_point[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Maturity." << this->id << ".inflection_point." - << this->inflection_point[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(maturity->inflection_point[i]); } if (this->inflection_point[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Maturity." << this->id << ".inflection_point." - << this->inflection_point[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(maturity->inflection_point[i]); } } + ss.str(""); + ss << "Maturity." << this->id << ".slope"; + maturity->slope.set_variable_name(ss.str()); maturity->slope.resize(this->slope.size()); for (size_t i = 0; i < this->slope.size(); i++) { maturity->slope[i] = this->slope[i].initial_value_m; + ss << "." << this->slope[i].id_m; if (this->slope[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Maturity." << this->id << ".slope." << this->slope[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(maturity->slope[i]); } if (this->slope[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Maturity." << this->id << ".slope." << this->slope[i].id_m; info->RegisterRandomEffect(maturity->slope[i]); info->RegisterRandomEffectName(ss.str()); } diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_models.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_models.hpp index 8feb6b0b8..f118184cc 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_models.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_models.hpp @@ -998,10 +998,15 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { &derived_quantities_dim_info = model->GetPopulationDimensionInfo(population_interface->id); - std::stringstream ss; + auto set_population_dq_name = [&](const std::string &name) { + derived_quantities[name].set_variable_name( + "Population." + fims::to_string(population_interface->id) + "." + + name); + }; derived_quantities["total_landings_weight"] = fims::Vector(population_interface->n_years.get()); + set_population_dq_name("total_landings_weight"); derived_quantities_dim_info["total_landings_weight"] = fims_popdy::DimensionInfo( @@ -1013,6 +1018,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["total_landings_numbers"] = fims::Vector(population_interface->n_years.get()); + set_population_dq_name("total_landings_numbers"); derived_quantities_dim_info["total_landings_numbers"] = fims_popdy::DimensionInfo( @@ -1025,6 +1031,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["mortality_F"] = fims::Vector(population_interface->n_years.get() * population_interface->n_ages.get()); + set_population_dq_name("mortality_F"); derived_quantities_dim_info["mortality_F"] = fims_popdy::DimensionInfo( "mortality_F", fims::Vector{population_interface->n_years.get(), @@ -1036,6 +1043,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["mortality_M"] = fims::Vector(population_interface->n_years.get() * population_interface->n_ages.get()); + set_population_dq_name("mortality_M"); derived_quantities_dim_info["mortality_M"] = fims_popdy::DimensionInfo( "mortality_M", fims::Vector{population_interface->n_years.get(), @@ -1047,6 +1055,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["mortality_Z"] = fims::Vector(population_interface->n_years.get() * population_interface->n_ages.get()); + set_population_dq_name("mortality_Z"); derived_quantities_dim_info["mortality_Z"] = fims_popdy::DimensionInfo( "mortality_Z", fims::Vector{population_interface->n_years.get(), @@ -1058,6 +1067,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["numbers_at_age"] = fims::Vector((population_interface->n_years.get() + 1) * population_interface->n_ages.get()); + set_population_dq_name("numbers_at_age"); derived_quantities_dim_info["numbers_at_age"] = fims_popdy::DimensionInfo( "numbers_at_age", fims::Vector{(population_interface->n_years.get() + 1), @@ -1069,6 +1079,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["unfished_numbers_at_age"] = fims::Vector((population_interface->n_years.get() + 1) * population_interface->n_ages.get()); + set_population_dq_name("unfished_numbers_at_age"); derived_quantities_dim_info["unfished_numbers_at_age"] = fims_popdy::DimensionInfo( "unfished_numbers_at_age", @@ -1080,6 +1091,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["biomass"] = fims::Vector((population_interface->n_years.get() + 1)); + set_population_dq_name("biomass"); derived_quantities_dim_info["biomass"] = fims_popdy::DimensionInfo( "biomass", fims::Vector{(population_interface->n_years.get() + 1)}, @@ -1089,6 +1101,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["spawning_biomass"] = fims::Vector((population_interface->n_years.get() + 1)); + set_population_dq_name("spawning_biomass"); derived_quantities_dim_info["spawning_biomass"] = fims_popdy::DimensionInfo( "spawning_biomass", @@ -1099,6 +1112,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["unfished_biomass"] = fims::Vector((population_interface->n_years.get() + 1)); + set_population_dq_name("unfished_biomass"); derived_quantities_dim_info["unfished_biomass"] = fims_popdy::DimensionInfo( "unfished_biomass", @@ -1109,6 +1123,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["unfished_spawning_biomass"] = fims::Vector((population_interface->n_years.get() + 1)); + set_population_dq_name("unfished_spawning_biomass"); derived_quantities_dim_info["unfished_spawning_biomass"] = fims_popdy::DimensionInfo( "unfished_spawning_biomass", @@ -1120,6 +1135,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["proportion_mature_at_age"] = fims::Vector((population_interface->n_years.get() + 1) * population_interface->n_ages.get()); + set_population_dq_name("proportion_mature_at_age"); derived_quantities_dim_info["proportion_mature_at_age"] = fims_popdy::DimensionInfo( "proportion_mature_at_age", @@ -1131,6 +1147,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["expected_recruitment"] = fims::Vector((population_interface->n_years.get() + 1)); + set_population_dq_name("expected_recruitment"); derived_quantities_dim_info["expected_recruitment"] = fims_popdy::DimensionInfo( "expected_recruitment", @@ -1142,6 +1159,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["sum_selectivity"] = fims::Vector(population_interface->n_years.get() * population_interface->n_ages.get()); + set_population_dq_name("sum_selectivity"); derived_quantities_dim_info["sum_selectivity"] = fims_popdy::DimensionInfo( "sum_selectivity", @@ -1182,11 +1200,16 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { std::map &derived_quantities_dim_info = model->GetFleetDimensionInfo(fleet_interface->id); + auto set_fleet_dq_name = [&](const std::string &name) { + derived_quantities[name].set_variable_name( + "Fleet." + fims::to_string(fleet_interface->id) + "." + name); + }; // initialize derive quantities // landings derived_quantities["landings_numbers_at_age"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_ages.get()); + set_fleet_dq_name("landings_numbers_at_age"); derived_quantities_dim_info["landings_numbers_at_age"] = fims_popdy::DimensionInfo( "landings_numbers_at_age", @@ -1198,6 +1221,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["landings_weight_at_age"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_ages.get()); + set_fleet_dq_name("landings_weight_at_age"); derived_quantities_dim_info["landings_weight_at_age"] = fims_popdy::DimensionInfo( "landings_weight_at_age", @@ -1209,6 +1233,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["landings_numbers_at_length"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_lengths.get()); + set_fleet_dq_name("landings_numbers_at_length"); derived_quantities_dim_info["landings_numbers_at_length"] = fims_popdy::DimensionInfo( "landings_numbers_at_length", @@ -1220,6 +1245,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["landings_weight"] = fims::Vector(fleet_interface->n_years.get()); + set_fleet_dq_name("landings_weight"); derived_quantities_dim_info["landings_weight"] = fims_popdy::DimensionInfo( "landings_weight", @@ -1230,6 +1256,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["landings_numbers"] = fims::Vector(fleet_interface->n_years.get()); + set_fleet_dq_name("landings_numbers"); derived_quantities_dim_info["landings_numbers"] = fims_popdy::DimensionInfo( "landings_numbers", @@ -1240,6 +1267,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["landings_expected"] = fims::Vector(fleet_interface->n_years.get()); + set_fleet_dq_name("landings_expected"); derived_quantities_dim_info["landings_expected"] = fims_popdy::DimensionInfo( "landings_expected", @@ -1250,6 +1278,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["log_landings_expected"] = fims::Vector(fleet_interface->n_years.get()); + set_fleet_dq_name("log_landings_expected"); derived_quantities_dim_info["log_landings_expected"] = fims_popdy::DimensionInfo( "log_landings_expected", @@ -1260,6 +1289,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["agecomp_proportion"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_ages.get()); + set_fleet_dq_name("agecomp_proportion"); derived_quantities_dim_info["agecomp_proportion"] = fims_popdy::DimensionInfo( "agecomp_proportion", @@ -1271,6 +1301,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["lengthcomp_proportion"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_lengths.get()); + set_fleet_dq_name("lengthcomp_proportion"); derived_quantities_dim_info["lengthcomp_proportion"] = fims_popdy::DimensionInfo( "lengthcomp_proportion", @@ -1283,6 +1314,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { // index derived_quantities["index_numbers_at_age"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_ages.get()); + set_fleet_dq_name("index_numbers_at_age"); derived_quantities_dim_info["index_numbers_at_age"] = fims_popdy::DimensionInfo( "index_numbers_at_age", @@ -1294,6 +1326,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["index_weight_at_age"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_ages.get()); + set_fleet_dq_name("index_weight_at_age"); derived_quantities_dim_info["index_weight_at_age"] = fims_popdy::DimensionInfo( "index_weight_at_age", @@ -1305,6 +1338,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["index_numbers_at_length"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_lengths.get()); + set_fleet_dq_name("index_numbers_at_length"); derived_quantities_dim_info["index_numbers_at_length"] = fims_popdy::DimensionInfo( "index_numbers_at_length", @@ -1316,6 +1350,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["index_weight"] = fims::Vector(fleet_interface->n_years.get()); + set_fleet_dq_name("index_weight"); derived_quantities_dim_info["index_weight"] = fims_popdy::DimensionInfo( "index_weight", fims::Vector{(fleet_interface->n_years.get())}, fims::Vector{"n_years"}); @@ -1324,6 +1359,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["index_numbers"] = fims::Vector(fleet_interface->n_years.get()); + set_fleet_dq_name("index_numbers"); derived_quantities_dim_info["index_numbers"] = fims_popdy::DimensionInfo( "index_numbers", fims::Vector{(fleet_interface->n_years.get())}, fims::Vector{"n_years"}); @@ -1332,6 +1368,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["index_expected"] = fims::Vector(fleet_interface->n_years.get()); + set_fleet_dq_name("index_expected"); derived_quantities_dim_info["index_expected"] = fims_popdy::DimensionInfo( "index_expected", fims::Vector{(fleet_interface->n_years.get())}, fims::Vector{"n_years"}); @@ -1340,6 +1377,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["log_index_expected"] = fims::Vector(fleet_interface->n_years.get()); + set_fleet_dq_name("log_index_expected"); derived_quantities_dim_info["log_index_expected"] = fims_popdy::DimensionInfo( "log_index_expected", @@ -1350,6 +1388,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["agecomp_expected"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_ages.get()); + set_fleet_dq_name("agecomp_expected"); derived_quantities_dim_info["agecomp_expected"] = fims_popdy::DimensionInfo( "agecomp_expected", @@ -1361,6 +1400,7 @@ class CatchAtAgeInterface : public FisheryModelInterfaceBase { derived_quantities["lengthcomp_expected"] = fims::Vector( fleet_interface->n_years.get() * fleet_interface->n_lengths.get()); + set_fleet_dq_name("lengthcomp_expected"); derived_quantities_dim_info["lengthcomp_expected"] = fims_popdy::DimensionInfo( "lengthcomp_expected", diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_population.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_population.hpp index 255af7bab..38023c253 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_population.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_population.hpp @@ -431,8 +431,10 @@ class PopulationInterface : public PopulationInterfaceBase { population->growth_id = this->growth_id.get(); population->recruitment_id = this->recruitment_id.get(); population->maturity_id = this->maturity_id.get(); - population->log_M.resize(this->log_M.size()); + ss.str(""); + ss << "Population." << this->id << ".log_f_multiplier"; + population->log_f_multiplier.set_variable_name(ss.str()); if (this->log_f_multiplier.size() == static_cast(this->n_years.get())) { population->log_f_multiplier.resize(this->log_f_multiplier.size()); @@ -447,6 +449,23 @@ class PopulationInterface : public PopulationInterfaceBase { } population->log_f_multiplier.resize(this->log_f_multiplier.size()); } + for (size_t i = 0; i < log_f_multiplier.size(); i++) { + population->log_f_multiplier[i] = + this->log_f_multiplier[i].initial_value_m; + ss << "." << this->log_f_multiplier[i].id_m; + if (this->log_f_multiplier[i].estimation_type_m.get() == + "fixed_effects") { + info->RegisterParameterName(ss.str()); + info->RegisterParameter(population->log_f_multiplier[i]); + } + if (this->log_f_multiplier[i].estimation_type_m.get() == + "random_effects") { + info->RegisterRandomEffectName(ss.str()); + info->RegisterRandomEffect(population->log_f_multiplier[i]); + } + } + info->variable_map[this->log_f_multiplier.id_m] = + &(population)->log_f_multiplier; if (this->spawning_biomass_ratio.size() == static_cast(this->n_years.get() + 1)) { @@ -459,63 +478,42 @@ class PopulationInterface : public PopulationInterfaceBase { population->spawning_biomass_ratio.resize( this->spawning_biomass_ratio.size()); } + ss.str(""); + ss << "Population." << this->id << ".spawning_biomass_ratio"; + population->spawning_biomass_ratio.set_variable_name(ss.str()); info->variable_map[this->spawning_biomass_ratio.id_m] = &(population)->spawning_biomass_ratio; - population->log_init_naa.resize(this->log_init_naa.size()); + ss.str(""); + ss << "Population." << this->id << ".log_M"; + population->log_M.set_variable_name(ss.str()); + population->log_M.resize(this->log_M.size()); for (size_t i = 0; i < log_M.size(); i++) { population->log_M[i] = this->log_M[i].initial_value_m; + ss << "." << this->log_M[i].id_m; if (this->log_M[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Population." << this->id << ".log_M." << this->log_M[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(population->log_M[i]); } if (this->log_M[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Population." << this->id << ".log_M." << this->log_M[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(population->log_M[i]); } } info->variable_map[this->log_M.id_m] = &(population)->log_M; - for (size_t i = 0; i < log_f_multiplier.size(); i++) { - population->log_f_multiplier[i] = - this->log_f_multiplier[i].initial_value_m; - if (this->log_f_multiplier[i].estimation_type_m.get() == - "fixed_effects") { - ss.str(""); - ss << "Population." << this->id << ".log_f_multiplier." - << this->log_f_multiplier[i].id_m; - info->RegisterParameterName(ss.str()); - info->RegisterParameter(population->log_f_multiplier[i]); - } - if (this->log_f_multiplier[i].estimation_type_m.get() == - "random_effects") { - ss.str(""); - ss << "Population." << this->id << ".log_f_multiplier." - << this->log_f_multiplier[i].id_m; - info->RegisterRandomEffectName(ss.str()); - info->RegisterRandomEffect(population->log_f_multiplier[i]); - } - } - info->variable_map[this->log_f_multiplier.id_m] = - &(population)->log_f_multiplier; - + ss.str(""); + ss << "Population." << this->id << ".log_init_naa"; + population->log_init_naa.set_variable_name(ss.str()); + population->log_init_naa.resize(this->log_init_naa.size()); for (size_t i = 0; i < log_init_naa.size(); i++) { population->log_init_naa[i] = this->log_init_naa[i].initial_value_m; + ss << "." << this->log_init_naa[i].id_m; if (this->log_init_naa[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Population." << this->id << ".log_init_naa." - << this->log_init_naa[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(population->log_init_naa[i]); } if (this->log_init_naa[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Population." << this->id << ".log_init_naa." - << this->log_init_naa[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(population->log_init_naa[i]); } @@ -536,6 +534,9 @@ class PopulationInterface : public PopulationInterfaceBase { population->proportion_female.resize(this->proportion_female.size()); } + ss.str(""); + ss << "Population." << this->id << ".proportion_female"; + population->proportion_female.set_variable_name(ss.str()); for (size_t i = 0; i < this->proportion_female.size(); i++) { if (this->proportion_female[i].initial_value_m < 0.0 || this->proportion_female[i].initial_value_m > 1.0) { @@ -546,19 +547,14 @@ class PopulationInterface : public PopulationInterfaceBase { } population->proportion_female[i] = this->proportion_female[i].initial_value_m; + ss << "." << this->proportion_female[i].id_m; if (this->proportion_female[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Population." << this->id << ".proportion_female." - << this->proportion_female[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(population->proportion_female[i]); } if (this->proportion_female[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Population." << this->id << ".proportion_female." - << this->proportion_female[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(population->proportion_female[i]); } diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_recruitment.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_recruitment.hpp index 6f7da9ae5..0ffc7475b 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_recruitment.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_recruitment.hpp @@ -321,21 +321,18 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { recruitment->id = this->id; recruitment->process_id = this->process_id.get(); // set logit_steep + ss.str(""); + ss << "Recruitment." << this->id << ".logit_steep"; + recruitment->logit_steep.set_variable_name(ss.str()); recruitment->logit_steep.resize(this->logit_steep.size()); for (size_t i = 0; i < this->logit_steep.size(); i++) { recruitment->logit_steep[i] = this->logit_steep[i].initial_value_m; - + ss << "." << this->logit_steep[i].id_m; if (this->logit_steep[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Recruitment." << this->id << ".logit_steep." - << this->logit_steep[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(recruitment->logit_steep[i]); } if (this->logit_steep[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Recruitment." << this->id << ".logit_steep." - << this->logit_steep[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(recruitment->logit_steep[i]); } @@ -343,42 +340,36 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { info->variable_map[this->logit_steep.id_m] = &(recruitment)->logit_steep; // set log_rzero + ss.str(""); + ss << "Recruitment." << this->id << ".log_rzero"; + recruitment->log_rzero.set_variable_name(ss.str()); recruitment->log_rzero.resize(this->log_rzero.size()); for (size_t i = 0; i < this->log_rzero.size(); i++) { recruitment->log_rzero[i] = this->log_rzero[i].initial_value_m; - + ss << "." << this->log_rzero[i].id_m; if (this->log_rzero[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Recruitment." << this->id << ".log_rzero." - << this->log_rzero[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(recruitment->log_rzero[i]); } if (this->log_rzero[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Recruitment." << this->id << ".log_rzero." - << this->log_rzero[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(recruitment->log_rzero[i]); } } info->variable_map[this->log_rzero.id_m] = &(recruitment)->log_rzero; // set log_recruit_devs + ss.str(""); + ss << "Recruitment." << this->id << ".log_devs"; + recruitment->log_recruit_devs.set_variable_name(ss.str()); recruitment->log_recruit_devs.resize(this->log_devs.size()); for (size_t i = 0; i < this->log_devs.size(); i++) { recruitment->log_recruit_devs[i] = this->log_devs[i].initial_value_m; - + ss << "." << this->log_devs[i].id_m; if (this->log_devs[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Recruitment." << this->id << ".log_devs." - << this->log_devs[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(recruitment->log_recruit_devs[i]); } if (this->log_devs[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Recruitment." << this->id << ".log_devs." - << this->log_devs[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(recruitment->log_recruit_devs[i]); } @@ -387,19 +378,18 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { info->variable_map[this->log_devs.id_m] = &(recruitment)->log_recruit_devs; // set log_r + ss.str(""); + ss << "Recruitment." << this->id << ".log_r"; + recruitment->log_r.set_variable_name(ss.str()); recruitment->log_r.resize(this->log_r.size()); for (size_t i = 0; i < log_r.size(); i++) { recruitment->log_r[i] = this->log_r[i].initial_value_m; - + ss << "." << this->log_r[i].id_m; if (this->log_r[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Recruitment." << this->id << ".log_r." << this->log_r[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(recruitment->log_r[i]); } if (this->log_r[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Recruitment." << this->id << ".log_r." << this->log_r[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(recruitment->log_r[i]); } @@ -407,6 +397,9 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { info->variable_map[this->log_r.id_m] = &(recruitment)->log_r; // set log_expected_recruitment + ss.str(""); + ss << "Recruitment." << this->id << ".log_expected_recruitment"; + recruitment->log_expected_recruitment.set_variable_name(ss.str()); recruitment->log_expected_recruitment.resize(this->n_years.get() - 1); for (size_t i = 0; i < static_cast(this->n_years.get() - 1); i++) { recruitment->log_expected_recruitment[i] = 0; diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp index f9cd8d64e..abf36a960 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp @@ -228,23 +228,21 @@ class LogisticSelectivityInterface : public SelectivityInterfaceBase { std::stringstream ss; // set relative info selectivity->id = this->id; + ss.str(""); + ss << "Selectivity." << this->id << ".inflection_point"; + selectivity->inflection_point.set_variable_name(ss.str()); selectivity->inflection_point.resize(this->inflection_point.size()); for (size_t i = 0; i < this->inflection_point.size(); i++) { selectivity->inflection_point[i] = this->inflection_point[i].initial_value_m; + ss << "." << this->inflection_point[i].id_m; if (this->inflection_point[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".inflection_point." - << this->inflection_point[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(selectivity->inflection_point[i]); } if (this->inflection_point[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".inflection_point." - << this->inflection_point[i].id_m; info->RegisterRandomEffect(selectivity->inflection_point[i]); info->RegisterRandomEffectName(ss.str()); } @@ -252,18 +250,18 @@ class LogisticSelectivityInterface : public SelectivityInterfaceBase { info->variable_map[this->inflection_point.id_m] = &(selectivity)->inflection_point; + ss.str(""); + ss << "Selectivity." << this->id << ".slope"; + selectivity->slope.set_variable_name(ss.str()); selectivity->slope.resize(this->slope.size()); for (size_t i = 0; i < this->slope.size(); i++) { selectivity->slope[i] = this->slope[i].initial_value_m; + ss << "." << this->slope[i].id_m; if (this->slope[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".slope." << this->slope[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(selectivity->slope[i]); } if (this->slope[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".slope." << this->slope[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(selectivity->slope[i]); } @@ -487,23 +485,21 @@ class DoubleLogisticSelectivityInterface : public SelectivityInterfaceBase { std::stringstream ss; // set relative info selectivity->id = this->id; + ss.str(""); + ss << "Selectivity." << this->id << ".inflection_point_asc"; + selectivity->inflection_point_asc.set_variable_name(ss.str()); selectivity->inflection_point_asc.resize(this->inflection_point_asc.size()); for (size_t i = 0; i < this->inflection_point_asc.size(); i++) { selectivity->inflection_point_asc[i] = this->inflection_point_asc[i].initial_value_m; + ss << "." << this->inflection_point_asc[i].id_m; if (this->inflection_point_asc[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".inflection_point_asc." - << this->inflection_point_asc[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(selectivity->inflection_point_asc[i]); } if (this->inflection_point_asc[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".inflection_point_asc." - << this->inflection_point_asc[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(selectivity->inflection_point_asc[i]); } @@ -511,46 +507,40 @@ class DoubleLogisticSelectivityInterface : public SelectivityInterfaceBase { info->variable_map[this->inflection_point_asc.id_m] = &(selectivity)->inflection_point_asc; + ss.str(""); + ss << "Selectivity." << this->id << ".slope_asc"; + selectivity->slope_asc.set_variable_name(ss.str()); selectivity->slope_asc.resize(this->slope_asc.size()); for (size_t i = 0; i < this->slope_asc.size(); i++) { selectivity->slope_asc[i] = this->slope_asc[i].initial_value_m; - + ss << "." << this->slope_asc[i].id_m; if (this->slope_asc[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".slope_asc." - << this->slope_asc[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(selectivity->slope_asc[i]); } if (this->slope_asc[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".slope_asc." - << this->slope_asc[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(selectivity->slope_asc[i]); } } info->variable_map[this->slope_asc.id_m] = &(selectivity)->slope_asc; + ss.str(""); + ss << "Selectivity." << this->id << ".inflection_point_desc"; + selectivity->inflection_point_desc.set_variable_name(ss.str()); selectivity->inflection_point_desc.resize( this->inflection_point_desc.size()); for (size_t i = 0; i < this->inflection_point_desc.size(); i++) { selectivity->inflection_point_desc[i] = this->inflection_point_desc[i].initial_value_m; - + ss << "." << this->inflection_point_desc[i].id_m; if (this->inflection_point_desc[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".inflection_point_desc." - << this->inflection_point_desc[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(selectivity->inflection_point_desc[i]); } if (this->inflection_point_desc[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".inflection_point_desc." - << this->inflection_point_desc[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(selectivity->inflection_point_desc[i]); } @@ -558,21 +548,18 @@ class DoubleLogisticSelectivityInterface : public SelectivityInterfaceBase { info->variable_map[this->inflection_point_desc.id_m] = &(selectivity)->inflection_point_desc; + ss.str(""); + ss << "Selectivity." << this->id << ".slope_desc"; + selectivity->slope_desc.set_variable_name(ss.str()); selectivity->slope_desc.resize(this->slope_desc.size()); for (size_t i = 0; i < this->slope_desc.size(); i++) { selectivity->slope_desc[i] = this->slope_desc[i].initial_value_m; - + ss << "." << this->slope_desc[i].id_m; if (this->slope_desc[i].estimation_type_m.get() == "fixed_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".slope_desc." - << this->slope_desc[i].id_m; info->RegisterParameterName(ss.str()); info->RegisterParameter(selectivity->slope_desc[i]); } if (this->slope_desc[i].estimation_type_m.get() == "random_effects") { - ss.str(""); - ss << "Selectivity." << this->id << ".slope_desc." - << this->slope_desc[i].id_m; info->RegisterRandomEffectName(ss.str()); info->RegisterRandomEffect(selectivity->slope_desc[i]); } diff --git a/tests/gtest/CMakeLists.txt b/tests/gtest/CMakeLists.txt index 59a1326c0..b0260ec7f 100644 --- a/tests/gtest/CMakeLists.txt +++ b/tests/gtest/CMakeLists.txt @@ -91,6 +91,17 @@ target_link_libraries(fimsObject_MemoryTracker ) gtest_discover_tests(fimsObject_MemoryTracker) +# test_fimsVector_Operator.cpp +add_executable(fimsVector_Operator + test_fimsVector_Operator.cpp +) +add_as_invoker_manifest(fimsVector_Operator) +target_link_libraries(fimsVector_Operator + gtest_main + fims_test +) +gtest_discover_tests(fimsVector_Operator) + # test_growth_EWAAGrowth_evaluate.cpp add_executable(growth_EWAAGrowth_evaluate test_growth_EWAAGrowth_evaluate.cpp diff --git a/tests/gtest/test_fimsVector_Operator.cpp b/tests/gtest/test_fimsVector_Operator.cpp new file mode 100644 index 000000000..afad41fe0 --- /dev/null +++ b/tests/gtest/test_fimsVector_Operator.cpp @@ -0,0 +1,39 @@ +#include "gtest/gtest.h" +#include "fims_vector.hpp" + +namespace { + +TEST(fimsVector_Operator, ReportsDetailedBoundsError) { + fims::Vector values(2, 0.0); + values.set_variable_name("Recruitment.1.log_devs"); + + try { + (void)values[2]; + FAIL() << "Expected std::invalid_argument"; + } catch (const std::invalid_argument &error) { + const std::string message = error.what(); + EXPECT_NE(message.find("fims::Vector out of bounds"), std::string::npos); + EXPECT_NE(message.find("Recruitment.1.log_devs"), std::string::npos); + EXPECT_NE(message.find("index 3"), std::string::npos); + EXPECT_NE(message.find("size 2"), std::string::npos); + } +} + +TEST(fimsVector_Operator, ReportsDetailedConstBoundsError) { + fims::Vector mutable_values(4, 0.0); + mutable_values.set_variable_name("Selectivity.9.slope"); + const fims::Vector &values = mutable_values; + + try { + (void)values[4]; + FAIL() << "Expected std::invalid_argument"; + } catch (const std::invalid_argument &error) { + const std::string message = error.what(); + EXPECT_NE(message.find("fims::Vector out of bounds"), std::string::npos); + EXPECT_NE(message.find("Selectivity.9.slope"), std::string::npos); + EXPECT_NE(message.find("index 5"), std::string::npos); + EXPECT_NE(message.find("size 4"), std::string::npos); + } +} + +} // namespace diff --git a/tests/testthat/test-fimsfit.R b/tests/testthat/test-fimsfit.R index 8a573ed86..e31f281b5 100644 --- a/tests/testthat/test-fimsfit.R +++ b/tests/testthat/test-fimsfit.R @@ -252,3 +252,28 @@ test_that("fit_fims() errors when optimization fails to converge", { clear() }) + +test_that("fit_fims() produces informative error when throwing a fims::Vector bounding error", { + #' @description Test that fit_fims() throws an informative error when variable bounds are not set up correctly + data("data_big", package = "FIMS") + data_4_model <- FIMSFrame(data_big) + # Create parameters + initialized_model <- create_default_configurations(data_4_model) |> + create_default_parameters(data = data_4_model) |> + tidyr::unnest(cols = data) |> + dplyr::rows_delete( + tibble::tibble( + module_name = "Population", + label = c("log_init_naa"), + age = 1 + ), + by = c("module_name", "label", "age") + ) |> + initialize_fims(data = data_4_model) + + expect_error( + object = fit_fims(initialized_model, optimize = TRUE), + regexp = "fims::Vector out of bounds for Population.1.log_init_naa: index 12 >= size 11" + ) + clear() +})