11#ifndef FIMS_COMMON_INFORMATION_HPP
12#define FIMS_COMMON_INFORMATION_HPP
39template <
typename Type>
45 static std::shared_ptr<Information<Type>>
54 std::vector<std::string>
59 std::map<uint32_t, std::shared_ptr<fims_data_object::DataObject<Type>>>
61 typedef typename std::map<
62 uint32_t, std::shared_ptr<fims_data_object::DataObject<Type>>>::iterator
66 std::map<uint32_t, std::shared_ptr<fims_popdy::RecruitmentBase<Type>>>
69 typedef typename std::map<
70 uint32_t, std::shared_ptr<fims_popdy::RecruitmentBase<Type>>>::iterator
74 std::map<uint32_t, std::shared_ptr<fims_popdy::RecruitmentBase<Type>>>
77 typedef typename std::map<
78 uint32_t, std::shared_ptr<fims_popdy::RecruitmentBase<Type>>>::iterator
82 std::map<uint32_t, std::shared_ptr<fims_popdy::SelectivityBase<Type>>>
85 typedef typename std::map<
86 uint32_t, std::shared_ptr<fims_popdy::SelectivityBase<Type>>>::iterator
90 std::map<uint32_t, std::shared_ptr<fims_popdy::GrowthBase<Type>>>
94 typename std::map<uint32_t,
95 std::shared_ptr<fims_popdy::GrowthBase<Type>>>::iterator
99 std::map<uint32_t, std::shared_ptr<fims_popdy::MaturityBase<Type>>>
102 typedef typename std::map<
103 uint32_t, std::shared_ptr<fims_popdy::MaturityBase<Type>>>::iterator
108 std::map<uint32_t, std::shared_ptr<fims_popdy::Fleet<Type>>>
111 typedef typename std::map<uint32_t,
112 std::shared_ptr<fims_popdy::Fleet<Type>>>::iterator
117 std::map<uint32_t, std::shared_ptr<fims_popdy::Population<Type>>>
121 typename std::map<uint32_t,
122 std::shared_ptr<fims_popdy::Population<Type>>>::iterator
128 std::shared_ptr<fims_distributions::DensityComponentBase<Type>>>
131 typedef typename std::map<
133 std::shared_ptr<fims_distributions::DensityComponentBase<Type>>>::iterator
137 std::unordered_map<uint32_t,
138 std::shared_ptr<fims_popdy::FisheryModelBase<Type>>>
141 typedef typename std::unordered_map<
142 uint32_t, std::shared_ptr<fims_popdy::FisheryModelBase<Type>>>::iterator
145 std::unordered_map<uint32_t, fims::Vector<Type>*>
148 typedef typename std::unordered_map<uint32_t, fims::Vector<Type>*>::iterator
163 void ResetRecruitmentLinks() noexcept {
164 auto detach = [](
auto& models) {
165 for (
auto& entry : models) {
166 const auto& recruitment = entry.second;
168 recruitment->process.reset();
169 recruitment->recruitment.reset();
189 this->parameter_names.clear();
190 this->parameters.clear();
198 ResetRecruitmentLinks();
207 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
210 d->data_observed_values.reset();
211 d->data_expected_values =
nullptr;
213 d->re_expected_values =
nullptr;
228 std::stringstream ss;
229 ss <<
"Information object State:\n";
231 ss <<
"populations: " << this->
populations.size() << std::endl;
234 ss <<
"fleets: " << this->
fleets.size() << std::endl;
235 ss <<
"growth_models: " << this->
growth_models.size() << std::endl;
236 ss <<
"maturity_models: " << this->
maturity_models.size() << std::endl;
237 ss <<
"parameter_names: " << this->parameter_names.size() << std::endl;
238 ss <<
"parameters: " << this->parameters.size() << std::endl;
241 ss <<
"random_effects_parameters: "
245 ss <<
"recruitment_process_models: "
249 ss <<
"models_map: " << this->
models_map.size() << std::endl;
250 ss <<
"n_years: " << this->n_years << std::endl;
251 ss <<
"n_ages: " << this->n_ages << std::endl;
265 std::make_shared<fims_info::Information<Type>>();
294 this->parameter_names.push_back(p_name);
313 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
315 if (d->input_type ==
"prior") {
320 d->priors.resize(d->key.size());
321 for (
size_t i = 0; i < d->key.size(); i++) {
326 d->priors[i] = (*vmit).second;
340 it != this->density_components.end(); ++it) {
341 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
343 if (d->input_type ==
"random_effects") {
351 d->re = (*vmit).second;
352 if (d->key.size() == 2) {
354 d->re_expected_values = (*vmit).second;
356 d->re_expected_values = &d->expected_values;
371 it != this->density_components.end(); ++it) {
372 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
374 if (d->input_type ==
"data") {
375 FIMS_INFO_LOG(
"Setup expected value for data distribution " +
382 d->data_expected_values = (*vmit).second;
399 if (f->fleet_observed_catch_data_id_m !=
static_cast<Type
>(-999)) {
400 uint32_t observed_catch_id =
401 static_cast<uint32_t
>(f->fleet_observed_catch_data_id_m);
404 f->observed_catch_data = (*it).second;
406 " successfully set to " +
426 if (f->fleet_observed_index_data_id_m !=
static_cast<Type
>(-999)) {
427 uint32_t observed_index_id =
428 static_cast<uint32_t
>(f->fleet_observed_index_data_id_m);
431 f->observed_index_data = (*it).second;
433 " successfully set to " +
453 if (f->fleet_observed_agecomp_data_id_m !=
static_cast<Type
>(-999)) {
454 uint32_t observed_agecomp_id =
455 static_cast<uint32_t
>(f->fleet_observed_agecomp_data_id_m);
458 f->observed_agecomp_data = (*it).second;
459 FIMS_INFO_LOG(
"Observed input age-composition data for fleet " +
465 "Expected age-composition observations not defined for fleet " +
480 if (f->fleet_observed_lengthcomp_data_id_m !=
static_cast<Type
>(-999)) {
481 uint32_t observed_lengthcomp_id =
482 static_cast<uint32_t
>(f->fleet_observed_lengthcomp_data_id_m);
485 f->observed_lengthcomp_data = (*it).second;
486 FIMS_INFO_LOG(
"Observed input length-composition data for fleet " +
492 "Expected length-composition observations not defined for fleet " +
508 if (f->fleet_selectivity_id_m !=
static_cast<Type
>(-999)) {
509 uint32_t sel_id =
static_cast<uint32_t
>(
510 f->fleet_selectivity_id_m);
515 f->selectivity = (*it).second;
521 FIMS_ERROR_LOG(
"Expected selectivity pattern not defined for fleet " +
528 ". FIMS requires selectivity be defined for all fleets "
529 "when running a catch at age model.");
545 if (p ==
nullptr || f ==
nullptr) {
548 "Unable to set fleet age-to-length conversion because the population "
550 "pointer was null.");
554 f->age_to_length_conversion_model =
557 if (f->age_to_length_conversion_model !=
nullptr &&
558 f->age_to_length_conversion_model->IsActive()) {
562 if (!f->requires_age_length_mapping) {
566 if (f->n_lengths == 0) {
569 " requires age-to-length conversion but has no fleet "
570 "length observation bins. Provide length_bin rows or "
571 "length_comp rows with length values.");
577 " has fleet length observation bins but no usable "
578 "age-to-length conversion path. Provide fixed "
579 "age-to-length conversion of size " +
582 " for 1 table per year) or use a supported growth-derived "
583 "age-to-length conversion path.");
596 if (p->recruitment_id !=
static_cast<Type
>(-999)) {
597 uint32_t recruitment_uint =
static_cast<uint32_t
>(p->recruitment_id);
603 p->recruitment = (*it).second;
605 " successfully set to population " +
610 "Expected recruitment function not defined for "
617 "No recruitment function defined for population " +
619 ". FIMS requires recruitment functions be defined for all "
620 "populations when running a catch at age model.");
634 std::shared_ptr<fims_popdy::RecruitmentBase<Type>> r = p->recruitment;
637 if (r->process_id !=
static_cast<Type
>(-999)) {
638 uint32_t process_uint =
static_cast<uint32_t
>(r->process_id);
643 r->process = (*it).second;
647 (*it).second->recruitment = r;
651 "Expected recruitment process function not defined for "
658 "No recruitment process function defined for population " +
660 ". FIMS requires recruitment process functions be defined for all "
661 "recruitments when running a catch at age model.");
677 for (std::size_t fleet_index = 0; fleet_index < p->fleets.size();
679 const std::shared_ptr<fims_popdy::Fleet<Type>>& fleet =
680 p->fleets[fleet_index];
682 if (fleet ==
nullptr) {
686 if (!fleet->requires_age_length_mapping || fleet->n_lengths == 0) {
691 if (fleet->lengths.size() != fleet->n_lengths) {
692 throw std::runtime_error(
693 "Fleet length_bin lower edges are not consistent with n_lengths");
696 fleet->length_bin_edges =
723 fleet_edges.size() == 0) {
727 for (std::size_t population_bin_index = 0;
728 population_bin_index < size_grid.
n_bins; ++population_bin_index) {
729 const double population_left = size_grid.
edges[population_bin_index];
730 const double population_right = size_grid.
edges[population_bin_index + 1];
731 const double population_bin_width = population_right - population_left;
732 const double population_tolerance =
733 1e-12 * (population_bin_width > 1.0 ? population_bin_width : 1.0);
735 for (std::size_t fleet_index = 0; fleet_index < fleet_edges.size();
739 for (std::size_t fleet_bin_index = 1; fleet_bin_index < edges.
size();
741 const double fleet_left = edges[fleet_bin_index - 1];
742 const double fleet_right = edges[fleet_bin_index];
743 const double overlap_left = std::max(population_left, fleet_left);
744 const double overlap_right = std::min(population_right, fleet_right);
746 if (!(overlap_right > overlap_left)) {
750 const double fleet_bin_width = fleet_right - fleet_left;
751 if (population_bin_width > fleet_bin_width + population_tolerance) {
752 throw std::runtime_error(
753 "Population biological size grid contains at least one bin "
754 "that is coarser than an overlapping active fleet observation "
755 "bin. Provide a finer biological size-grid override or correct "
756 "the fleet bin setup.");
786 }
catch (
const std::exception& e) {
789 "Failed to prepare fleet observation-bin geometry for population " +
794 if (p->size_grid.IsConsistent() && p->size_grid.n_bins > 0) {
797 }
catch (
const std::exception& e) {
801 " has a biological size grid that is incompatible with active "
802 "fleet observation bins: " +
808 const bool size_grid_missing = p->size_grid.n_bins == 0 &&
809 p->size_grid.edges.
size() == 0 &&
810 p->size_grid.centers.size() == 0;
812 if (size_grid_missing) {
814 if (fleet_edges.
size() == 0) {
815 throw std::runtime_error(
816 "No resolvable fleet observation-bin geometry was available "
817 "to build the default biological size grid");
824 const std::size_t regular_bin_count =
825 p->size_grid.n_bins > 0 ? p->size_grid.n_bins - 1 : 0;
827 if (regular_bin_count > 200) {
829 "Built-in default biological size grid created more than 200 "
830 "regular bins for population " +
832 ". This may slow model evaluation. Consider providing a "
833 "biological size-grid override if needed.");
836 }
catch (
const std::exception& e) {
839 "Failed to initialize default population size grid for "
849 " has an invalid biological size grid. Provide a consistent override "
850 "or leave the grid empty so FIMS can build the default.");
863 growth_observation) {
864 std::shared_ptr<fims_popdy::GrowthDerivedSizeProvider<Type>> size_provider =
865 std::make_shared<fims_popdy::GrowthDerivedSizeProvider<Type>>();
867 size_provider->SetGrowth(growth_observation);
868 size_provider->SetPopulationDimensions(p->n_years, p->n_ages);
869 size_provider->SetPopulationSizeGrid(&(p->size_grid));
871 p->size_distribution_provider = size_provider;
884 if (p->growth_id !=
static_cast<Type
>(-999)) {
885 uint32_t growth_uint =
static_cast<uint32_t
>(p->growth_id);
896 growth_observation = std::dynamic_pointer_cast<
899 growth_observation->Initialize(p->n_years, p->n_ages, 1);
901 if (p->ages.size() > 0) {
902 double min_age = p->ages[0];
903 for (
size_t i = 1; i < p->ages.size(); ++i) {
904 if (p->ages[i] < min_age) {
905 min_age = p->ages[i];
908 growth_observation->SetAgeOffset(
static_cast<double>(min_age));
911 const bool population_has_size_grid_input =
912 p->size_grid.n_bins > 0 || p->size_grid.edges.size() > 0 ||
913 p->size_grid.centers.size() > 0;
915 bool any_length_based_fleet =
false;
916 for (std::size_t i = 0; i < p->fleets.size(); ++i) {
917 if (p->fleets[i] !=
nullptr &&
918 p->fleets[i]->requires_age_length_mapping &&
919 p->fleets[i]->n_lengths > 0) {
920 any_length_based_fleet =
true;
925 if (population_has_size_grid_input || any_length_based_fleet) {
934 " successfully set to population " +
938 FIMS_ERROR_LOG(
"Expected growth function not defined for population " +
945 ". FIMS requires growth functions be defined for all "
946 "populations when running a catch at age model.");
960 if (p->maturity_id !=
static_cast<Type
>(-999)) {
961 uint32_t maturity_uint =
static_cast<uint32_t
>(p->maturity_id);
966 p->maturity = (*it).second;
968 " successfully set to population " +
973 "Expected maturity function not defined for population " +
980 ". FIMS requires maturity functions be defined for all "
981 "populations when running a catch at age model.");
994 std::shared_ptr<fims_popdy::Fleet<Type>> f = (*it).second;
1017 it != this->density_components.end(); ++it) {
1018 std::shared_ptr<fims_distributions::DensityComponentBase<Type>> d =
1022 if (d->input_type ==
"data") {
1023 if (d->observed_data_id_m !=
static_cast<Type
>(-999)) {
1024 uint32_t observed_data_id =
1025 static_cast<uint32_t
>(d->observed_data_id_m);
1029 d->data_observed_values = (*it).second;
1031 " successfully set to density component " +
1034 valid_model =
false;
1036 "Expected data observations not defined for density "
1042 valid_model =
false;
1058 it != this->populations.end(); ++it) {
1059 std::shared_ptr<fims_popdy::Population<Type>> p = (*it).second;
1063 typename std::set<uint32_t>::iterator fleet_ids_it;
1065 for (fleet_ids_it = p->fleet_ids.begin();
1066 fleet_ids_it != p->fleet_ids.end(); ++fleet_ids_it) {
1075 if (it != this->
fleets.end()) {
1077 std::shared_ptr<fims_popdy::Fleet<Type>> f = (*it).second;
1081 p->fleets.push_back(f);
1083 valid_model =
false;
1085 "\" undefined, not found for Population \"" +
1091 this->n_years = std::max(this->n_years, p->n_years);
1092 this->n_ages = std::max(this->n_ages, p->n_ages);
1099 for (
size_t i = 0; i < p->fleets.size(); ++i) {
1112 it != this->models_map.end(); ++it) {
1113 std::shared_ptr<fims_popdy::FisheryModelBase<Type>>& model = (*it).second;
1114 std::set<uint32_t>::iterator jt;
1116 for (jt = model->population_ids.begin();
1117 jt != model->population_ids.end(); ++jt) {
1121 std::shared_ptr<fims_popdy::Population<Type>> p = (*pt).second;
1122 model->populations.push_back(p);
1123 for (
size_t i = 0; i < p->fleets.size(); i++) {
1124 uint32_t local_fleet_id = p->fleets[i]->GetId();
1125 model->fleets[local_fleet_id] = p->fleets[i];
1128 std::string(
" into model id ") +
1132 valid_model =
false;
1137 model->Initialize();
1152 FIMS_INFO_LOG(
"Creating model and checking for required components...");
1153 bool valid_model =
true;
1238 bool valid_model =
true;
1240 it != this->models_map.end(); ++it) {
1241 std::shared_ptr<fims_popdy::FisheryModelBase<Type>>& model = (*it).second;
1242 std::set<uint32_t>::iterator jt;
1244 for (jt = model->population_ids.begin();
1245 jt != model->population_ids.end(); ++jt) {
1249 std::shared_ptr<fims_popdy::Population<Type>> p = (*pt).second;
1251 if (model->model_type_m ==
"caa") {
1252 typename std::set<uint32_t>::iterator fleet_ids_it;
1253 for (fleet_ids_it = p->fleet_ids.begin();
1254 fleet_ids_it != p->fleet_ids.end(); ++fleet_ids_it) {
1257 if (it != this->
fleets.end()) {
1259 std::shared_ptr<fims_popdy::Fleet<Type>> f = (*it).second;
1261 if (f->fleet_selectivity_id_m ==
static_cast<Type
>(-999)) {
1262 valid_model =
false;
1264 "No selectivity pattern defined for fleet " +
1266 ". FIMS requires selectivity be defined for all fleets "
1267 "when running a catch at age model.");
1272 if (p->recruitment_id ==
static_cast<Type
>(-999)) {
1273 valid_model =
false;
1275 "No recruitment function defined for population " +
1277 ". FIMS requires recruitment functions be defined for all "
1278 "populations when running a catch at age model.");
1281 std::shared_ptr<fims_popdy::RecruitmentBase<Type>> r =
1284 if (r->process_id ==
static_cast<Type
>(-999)) {
1285 valid_model =
false;
1287 "No recruitment process function defined for population " +
1289 ". FIMS requires recruitment process functions be defined "
1291 "recruitments when running a catch at age model.");
1294 if (p->growth_id ==
static_cast<Type
>(-999)) {
1295 valid_model =
false;
1297 "No growth function defined for population " +
1299 ". FIMS requires growth functions be defined for all "
1300 "populations when running a catch at age model.");
1303 if (p->maturity_id ==
static_cast<Type
>(-999)) {
1304 valid_model =
false;
1307 "No maturity function defined for population " +
1309 ". FIMS requires maturity functions be defined for all "
1310 "populations when running a catch at age model.");
1320template <
typename Type>
Definition fims_vector.hpp:27
void emplace_back(Args &&...args)
Constructs an element in-place at the end.
Definition fims_vector.hpp:389
size_type size() const
Returns the number of elements.
Definition fims_vector.hpp:299
Generic capability interface for growth models that can feed the growth-derived age-to-length convers...
Definition growth_model_adapter.hpp:26
Platform macros and the core FIMS logging system.
#define FIMS_WARNING_LOG(MESSAGE)
Definition def.hpp:648
#define FIMS_INFO_LOG(MESSAGE)
Record an info-log entry with metadata.
Definition def.hpp:648
std::string to_string(T v)
Definition def.hpp:735
#define FIMS_ERROR_LOG(MESSAGE)
Definition def.hpp:664
This distributions module includes any .hpp files within the subfolders so that only this file needs ...
Establishes the FIMS Vector class.
Defines the base class for all fishery models within the FIMS framework.
Declare the fleet functor class which is the base class for all fleet functors.
Includes any .hpp files within the subfolders so that only this file needs to included in include sta...
Defines a size provider that reads mean growth outputs and prepares population-level size probabiliti...
Definition of the FIMSObject structure.
std::shared_ptr< AgeToLengthConversionBase< Type > > BuildAgeToLengthConversionFleet(const std::shared_ptr< Population< Type > > &population, const std::shared_ptr< Fleet< Type > > &fleet)
Build the active age-to-length conversion for a fleet from the current population and fleet state.
Definition runtime.hpp:44
Defines the Population class and its fields and methods.
Includes any .hpp files within the subfolders so that only this file needs to included in include sta...
Shared runtime helpers for constructing and validating fleet age-to-length conversions.
Includes any .hpp files within the subfolders so that only this file needs to included in include sta...
Defines helpers for constructing population-level biological size grids.
Base class for all fleets.
Definition fleet.hpp:26
Population class. Contains subpopulations that are divided into generic partitions (e....
Definition population.hpp:27
static fims::Vector< double > BuildObservationEdgesFromLowerEdges(const fims::Vector< double > &lower_edges)
Build one fleet observation-bin edge vector from stored bin lower edges.
Definition size_grid_builder.hpp:112
static SizeGrid BuildDefaultFromFleetEdges(const fims::Vector< fims::Vector< double > > &fleet_edges)
Build the default population biological size grid from resolved fleet observation-bin edges.
Definition size_grid_builder.hpp:155
Population-level biological size grid.
Definition size_grid.hpp:26
bool IsConsistent() const
Return whether the grid dimensions and geometry are internally consistent.
Definition size_grid.hpp:80
fims::Vector< double > edges
Definition size_grid.hpp:28
std::size_t n_bins
Definition size_grid.hpp:27