FIMS  v0.11.0
Loading...
Searching...
No Matches
catch_at_age.hpp
Go to the documentation of this file.
1
8#ifndef FIMS_MODELS_CATCH_AT_AGE_HPP
9#define FIMS_MODELS_CATCH_AT_AGE_HPP
10
11#include <algorithm>
12#include <cmath>
13#include <set>
14#include <regex>
15#include <stdexcept>
16
19
20/* Dictionary block for shared parameter snippet documentations.
21 * Referenced in function docs via @snippet{doc} this snippet_id.
22 [param_population]
23 @param population Shared pointer to the population object.
24 [param_population]
25 [param_i_age_year]
26 @param i_age_year Dimension folded index for age and year.
27 [param_i_age_year]
28 [param_year]
29 @param year Year index.
30 [param_year]
31 [param_age]
32 @param age Age index.
33 [param_age]
34 [param_i_agem1_yearm1]
35 @param i_agem1_yearm1 Dimension folded index for age-1 and year-1.
36 [param_i_agem1_yearm1]
37 [param_i_dev]
38 @param i_dev Index to log_recruit_dev of vector length n_years-1.
39 [param_i_dev]
40 [param_other]
41 @param other The other CatchAtAge object to copy from.
42 [param_other]
43 */
44
45namespace fims_popdy {
46
47template <typename Type>
57class CatchAtAge : public FisheryModelBase<Type> {
58 public:
63 std::string name_m;
64
69 typedef typename std::map<std::string, fims::Vector<Type>>::iterator
71
76 typedef typename std::map<uint32_t,
77 std::map<std::string, fims::Vector<Type>>>::iterator
79
83 typedef
84 typename std::map<uint32_t,
85 std::map<std::string, fims::Vector<size_t>>>::iterator
91 typedef typename std::map<uint32_t,
92 std::map<std::string, fims::Vector<Type>>>::iterator
94
99 typedef
100 typename std::map<uint32_t,
101 std::map<std::string, fims::Vector<size_t>>>::iterator
103
108 typedef typename std::map<uint32_t,
109 std::shared_ptr<fims_popdy::Fleet<Type>>>::iterator
115 typedef
116 typename std::map<std::string, fims::Vector<Type>>::iterator dq_iterator;
122 std::map<std::string, fims::Vector<fims::Vector<Type>>> report_vectors;
131
132 public:
133 std::vector<Type> ages;
139 std::stringstream ss;
140 ss << "caa_" << this->GetId() << "_";
141 this->name_m = ss.str();
142 this->model_type_m = "caa";
143 }
144
158
163 virtual ~CatchAtAge() {}
164
169 virtual void Initialize() {
170 for (size_t p = 0; p < this->populations.size(); p++) {
171 if (this->populations[p]->proportion_female.size() == 0) {
172 this->populations[p]->proportion_female.resize(1);
173 this->populations[p]->proportion_female[0] = static_cast<Type>(0.5);
174 }
175
176 this->populations[p]->M.resize(this->populations[p]->n_years *
177 this->populations[p]->n_ages);
178
179 this->populations[p]->f_multiplier.resize(this->populations[p]->n_years);
180
181 this->populations[p]->spawning_biomass_ratio.resize(
182 (this->populations[p]->n_years + 1));
183 }
184
185 for (fleet_iterator fit = this->fleets.begin(); fit != this->fleets.end();
186 ++fit) {
187 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
188
189 if (fleet->log_q.size() == 0) {
190 fleet->log_q.resize(1);
191 fleet->log_q[0] = static_cast<Type>(0.0);
192 }
193 fleet->q.resize(fleet->log_q.size());
194 fleet->Fmort.resize(fleet->n_years);
195 }
196 }
197
202 virtual void Prepare() {
203 for (size_t p = 0; p < this->populations.size(); p++) {
204 std::shared_ptr<fims_popdy::Population<Type>> &population =
205 this->populations[p];
206
207 auto &derived_quantities =
208 this->GetPopulationDerivedQuantities(population->GetId());
209
210 // Reset the derived quantities for the population
211 for (auto &kv : derived_quantities) {
212 this->ResetVector(kv.second);
213 }
214
215 // Transformation Section
216 for (size_t age = 0; age < population->n_ages; age++) {
217 for (size_t year = 0; year < population->n_years; year++) {
218 size_t i_age_year = age * population->n_years + year;
220 fims_math::exp(population->log_M[i_age_year]);
221 }
222 }
223
224 for (size_t year = 0; year < population->n_years; year++) {
225 population->f_multiplier[year] =
226 fims_math::exp(population->log_f_multiplier[year]);
227 }
228 }
229
230 for (fleet_iterator fit = this->fleets.begin(); fit != this->fleets.end();
231 ++fit) {
232 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
233 auto &derived_quantities =
234 this->GetFleetDerivedQuantities(fleet->GetId());
235
236 for (auto &kv : derived_quantities) {
237 this->ResetVector(kv.second);
238 }
239
240 // Transformation Section
241 for (size_t i = 0; i < fleet->log_q.size(); i++) {
242 fleet->q[i] = fims_math::exp(fleet->log_q[i]);
243 }
244
245 for (size_t year = 0; year < fleet->n_years; year++) {
246 fleet->Fmort[year] = fims_math::exp(fleet->log_Fmort[year]);
247 }
248 }
249 }
253 void AddPopulation(uint32_t id) { this->population_ids.insert(id); }
254
258 std::set<uint32_t> &GetPopulationIds() { return this->population_ids; }
259
265 std::vector<std::shared_ptr<fims_popdy::Population<Type>>> &GetPopulations() {
266 return this->populations;
267 }
268
283 size_t i_age_year, size_t age) {
284 std::map<std::string, fims::Vector<Type>> &dq_ =
286
287 dq_["numbers_at_age"][i_age_year] =
288 fims_math::exp(population->log_init_naa[age]);
289 }
290
315 size_t i_age_year, size_t i_agem1_yearm1, size_t age) {
316 // using Z from previous age/year
317
318 std::map<std::string, fims::Vector<Type>> &dq_ =
320
321 dq_["numbers_at_age"][i_age_year] =
322 dq_["numbers_at_age"][i_agem1_yearm1] *
323 (fims_math::exp(-dq_["mortality_Z"][i_agem1_yearm1]));
324
325 // Plus group calculation
326 if (age == (population->n_ages - 1)) {
327 dq_["numbers_at_age"][i_age_year] =
328 dq_["numbers_at_age"][i_age_year] +
329 dq_["numbers_at_age"][i_agem1_yearm1 + 1] *
330 (fims_math::exp(-dq_["mortality_Z"][i_agem1_yearm1 + 1]));
331 }
332 }
333
358 size_t i_age_year, size_t i_agem1_yearm1, size_t age) {
359 std::map<std::string, fims::Vector<Type>> &dq_ =
361
362 // using M from previous age/year
363 dq_["unfished_numbers_at_age"][i_age_year] =
364 dq_["unfished_numbers_at_age"][i_agem1_yearm1] *
365 (fims_math::exp(-population->M[i_agem1_yearm1]));
366
367 // Plus group calculation
368 if (age == (population->n_ages - 1)) {
369 dq_["unfished_numbers_at_age"][i_age_year] =
370 dq_["unfished_numbers_at_age"][i_age_year] +
371 dq_["unfished_numbers_at_age"][i_agem1_yearm1 + 1] *
372 (fims_math::exp(-population->M[i_agem1_yearm1 + 1]));
373 }
374 }
375
402 size_t i_age_year, size_t age) {
403 std::map<std::string, fims::Vector<Type>> &dq_ =
405
406 // In year 0, the previous age is the previous element of the same year
407 size_t i_agem1 = i_age_year - 1;
408 dq_["unfished_numbers_at_age"][i_age_year] =
409 dq_["unfished_numbers_at_age"][i_agem1] *
410 fims_math::exp(-population->M[i_agem1]);
411
412 if (age == (population->n_ages - 1)) {
413 dq_["unfished_numbers_at_age"][i_age_year] =
414 dq_["unfished_numbers_at_age"][i_age_year] /
415 (1.0 - fims_math::exp(-population->M[i_age_year]));
416 }
417 }
418
452 size_t i_age_year, size_t year, size_t age) {
453 std::map<std::string, fims::Vector<Type>> &dq_ =
455
456 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
457 // evaluate is a member function of the selectivity class
458 Type s = population->fleets[fleet_]->selectivity->evaluate(
459 population->ages[age], year);
460
461 dq_["mortality_F"][i_age_year] +=
462 population->fleets[fleet_]->Fmort[year] *
463 population->f_multiplier[year] * s;
464
465 dq_["sum_selectivity"][i_age_year] += s;
466 }
467 dq_["mortality_M"][i_age_year] = population->M[i_age_year];
468
469 dq_["mortality_Z"][i_age_year] =
470 population->M[i_age_year] + dq_["mortality_F"][i_age_year];
471 }
472
489 size_t i_age_year, size_t year, size_t age) {
490 std::map<std::string, fims::Vector<Type>> &dq_ =
492
493 dq_["biomass"][year] += dq_["numbers_at_age"][i_age_year] *
495 }
496
513 size_t i_age_year, size_t year, size_t age) {
514 std::map<std::string, fims::Vector<Type>> &dq_ =
516
517 dq_["unfished_biomass"][year] +=
518 dq_["unfished_numbers_at_age"][i_age_year] *
520 }
521
540 size_t i_age_year, size_t year, size_t age) {
541 std::map<std::string, fims::Vector<Type>> &dq_ =
543
544 dq_["spawning_biomass"][year] +=
545 population->proportion_female.get_force_scalar(age) *
546 dq_["numbers_at_age"][i_age_year] *
547 dq_["proportion_mature_at_age"][i_age_year] *
549 }
550
568 size_t i_age_year, size_t year, size_t age) {
569 std::map<std::string, fims::Vector<Type>> &dq_ =
571
572 dq_["unfished_spawning_biomass"][year] +=
573 population->proportion_female.get_force_scalar(age) *
574 dq_["unfished_numbers_at_age"][i_age_year] *
575 dq_["proportion_mature_at_age"][i_age_year] *
577 }
578
595 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year) {
596 std::map<std::string, fims::Vector<Type>> &dq_ =
598 population->spawning_biomass_ratio[year] =
599 dq_["spawning_biomass"][year] / dq_["unfished_spawning_biomass"][0];
600 }
601
627 std::shared_ptr<fims_popdy::Population<Type>> &population) {
628 std::map<std::string, fims::Vector<Type>> &dq_ =
630
631 std::vector<Type> numbers_spr(population->n_ages, 1.0);
632 Type phi_0 = 0.0;
633 phi_0 += numbers_spr[0] *
634 population->proportion_female.get_force_scalar(0) *
635 dq_["proportion_mature_at_age"][0] *
637 for (size_t a = 1; a < (population->n_ages - 1); a++) {
638 numbers_spr[a] =
639 numbers_spr[a - 1] * fims_math::exp(-population->M[a - 1]);
640 phi_0 += numbers_spr[a] *
641 population->proportion_female.get_force_scalar(a) *
642 dq_["proportion_mature_at_age"][a] *
644 }
645
646 numbers_spr[population->n_ages - 1] =
647 (numbers_spr[population->n_ages - 2] *
648 fims_math::exp(-population->M[population->n_ages - 2])) /
649 (1 - fims_math::exp(-population->M[population->n_ages - 1]));
650 phi_0 +=
651 numbers_spr[population->n_ages - 1] *
652 population->proportion_female.get_force_scalar(population->n_ages - 1) *
653 dq_["proportion_mature_at_age"][population->n_ages - 1] *
655
656 return phi_0;
657 }
658
684 size_t i_age_year, size_t year, size_t i_dev) {
685 std::map<std::string, fims::Vector<Type>> &dq_ =
687
689
690 if (i_dev == population->n_years) {
691 dq_["numbers_at_age"][i_age_year] =
692 population->recruitment->evaluate_mean(
693 dq_["spawning_biomass"][year - 1], phi_0);
694 /*the final year of the time series has no data to inform recruitment
695 devs, so this value is set to the mean recruitment.*/
696 } else {
697 // Why are we using evaluate_mean, how come a virtual function was
698 // changed? AMH: there are now two virtual functions: evaluate_mean and
699 // evaluate_process (see below)
700 population->recruitment->log_expected_recruitment[year - 1] =
701 fims_math::log(population->recruitment->evaluate_mean(
702 dq_["spawning_biomass"][year - 1], phi_0));
703
704 dq_["numbers_at_age"][i_age_year] = fims_math::exp(
705 population->recruitment->process->evaluate_process(year - 1));
706 }
707
708 dq_["expected_recruitment"][year] = dq_["numbers_at_age"][i_age_year];
709 }
710
727 size_t i_age_year, size_t year, size_t age) {
728 std::map<std::string, fims::Vector<Type>> &dq_ =
730
731 // Year n_years is the start-of-year state after the last data year, so it
732 // reuses that year's maturity.
733 dq_["proportion_mature_at_age"][i_age_year] =
734 population->maturity->evaluate(
735 population->ages[age], (std::min)(year, population->n_years - 1));
736 }
737
754 size_t year, size_t age) {
755 std::map<std::string, fims::Vector<Type>> &pdq_ =
757
758 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
759 std::map<std::string, fims::Vector<Type>> &fdq_ =
760 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
761 size_t i_age_year = year * population->n_ages + age;
762
763 pdq_["total_catch_weight"][year] +=
764 fdq_["catch_weight_at_age"][i_age_year];
765
766 fdq_["catch_weight"][year] += fdq_["catch_weight_at_age"][i_age_year];
767
768 pdq_["total_catch_numbers"][year] +=
769 fdq_["catch_numbers_at_age"][i_age_year];
770
771 fdq_["catch_numbers"][year] += fdq_["catch_numbers_at_age"][i_age_year];
772 }
773 }
774
794 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year,
795 size_t age) {
796 int i_age_year = year * population->n_ages + age;
797
798 if (population->growth == nullptr) {
799 throw std::runtime_error(
800 "Population growth pointer was null while resolving landings "
801 "weight-at-age.");
802 }
803
804 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
805 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet =
806 population->fleets[fleet_];
807 std::map<std::string, fims::Vector<Type>> &fdq_ =
808 this->GetFleetDerivedQuantities(fleet->GetId());
809
811
812 fdq_["catch_weight_at_age"][i_age_year] =
813 fdq_["catch_numbers_at_age"][i_age_year] * mean_weight_at_age;
814 }
815 }
816
836 size_t i_age_year, size_t year, size_t age) {
837 std::map<std::string, fims::Vector<Type>> &pdq_ =
839
840 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
841 std::map<std::string, fims::Vector<Type>> &fdq_ =
842 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
843
844 // Baranov Catch Equation
845 fdq_["catch_numbers_at_age"][i_age_year] +=
846 (population->fleets[fleet_]->Fmort[year] *
847 population->f_multiplier[year] *
848 population->fleets[fleet_]->selectivity->evaluate(
849 population->ages[age], year)) /
850 pdq_["mortality_Z"][i_age_year] * pdq_["numbers_at_age"][i_age_year] *
851 (1 - fims_math::exp(-(pdq_["mortality_Z"][i_age_year])));
852 }
853 }
854
873 size_t i_age_year, size_t year, size_t age) {
874 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
875 std::map<std::string, fims::Vector<Type>> &fdq_ =
876 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
877
878 fdq_["index_weight"][year] += fdq_["index_weight_at_age"][i_age_year];
879
880 fdq_["index_numbers"][year] += fdq_["index_numbers_at_age"][i_age_year];
881 }
882 }
883
905 size_t i_age_year, size_t year, size_t age) {
906 std::map<std::string, fims::Vector<Type>> &pdq_ =
908
909 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
910 std::map<std::string, fims::Vector<Type>> &fdq_ =
911 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
912
913 fdq_["index_numbers_at_age"][i_age_year] +=
914 (population->fleets[fleet_]->q.get_force_scalar(year) *
915 population->fleets[fleet_]->selectivity->evaluate(
916 population->ages[age], year)) *
917 pdq_["numbers_at_age"][i_age_year];
918 }
919 }
920
939 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year,
940 size_t age) {
941 int i_age_year = year * population->n_ages + age;
942
943 if (population->growth == nullptr) {
944 throw std::runtime_error(
945 "Population growth pointer was null while resolving index "
946 "weight-at-age.");
947 }
948
949 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
950 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet =
951 population->fleets[fleet_];
952 std::map<std::string, fims::Vector<Type>> &fdq_ =
953 this->GetFleetDerivedQuantities(fleet->GetId());
954
956
957 fdq_["index_weight_at_age"][i_age_year] =
958 fdq_["index_numbers_at_age"][i_age_year] * mean_weight_at_age;
959 }
960 }
961
967 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
968 std::map<std::string, fims::Vector<Type>> &fdq_ =
969 this->GetFleetDerivedQuantities((*fit).second->GetId());
970
971 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
972 for (size_t y = 0; y < fleet->n_years; y++) {
973 Type sum = static_cast<Type>(0.0);
974 Type sum_obs = static_cast<Type>(0.0);
975 // robust_add is a small value to add to expected composition
976 // proportions at age to stabilize likelihood calculations
977 // when the expected proportions are close to zero.
978 // Type robust_add = static_cast<Type>(0.0); // zeroed out before
979 // testing 0.0001; sum robust is used to calculate the total sum of
980 // robust additions to ensure that proportions sum to 1. Type robust_sum
981 // = static_cast<Type>(1.0);
982
983 for (size_t a = 0; a < fleet->n_ages; a++) {
984 size_t i_age_year = y * fleet->n_ages + a;
985 // Here we have a check to determine if the age comp
986 // should be calculated from the retained catch or
987 // the total population. These values are slightly different.
988 // In the future this will have more impact as we implement
989 // timing rather than everything occurring at the start of
990 // the year.
991 if (fleet->fleet_observed_catch_data_id_m == -999) {
992 fdq_["agecomp_expected"][i_age_year] =
993 fdq_["index_numbers_at_age"][i_age_year];
994 } else {
995 fdq_["agecomp_expected"][i_age_year] =
996 fdq_["catch_numbers_at_age"][i_age_year];
997 }
998 sum += fdq_["agecomp_expected"][i_age_year];
999 // robust_sum -= robust_add;
1000
1001 // This sums over the observed age composition data so that
1002 // the expected age composition can be rescaled to match the
1003 // total number observed. The check for na values should not
1004 // be needed as individual years should not have missing data.
1005 // This is need to be re-explored if/when we modify FIMS to
1006 // allow for composition bins that do not match the population
1007 // bins.
1008 if (fleet->fleet_observed_agecomp_data_id_m != -999) {
1009 if (fleet->observed_agecomp_data->at(i_age_year) !=
1010 fleet->observed_agecomp_data->na_value) {
1011 sum_obs += fleet->observed_agecomp_data->at(i_age_year);
1012 }
1013 }
1014 }
1015 for (size_t a = 0; a < fleet->n_ages; a++) {
1016 size_t i_age_year = y * fleet->n_ages + a;
1017 fdq_["agecomp_proportion"][i_age_year] =
1018 fdq_["agecomp_expected"][i_age_year] / sum;
1019 // robust_add + robust_sum * this->agecomp_expected[i_age_year] / sum;
1020
1021 if (fleet->fleet_observed_agecomp_data_id_m != -999) {
1022 fdq_["agecomp_expected"][i_age_year] =
1023 fdq_["agecomp_proportion"][i_age_year] * sum_obs;
1024 }
1025 }
1026 }
1027 }
1028 }
1029
1030 // --- Growth-derived WAA helpers ---
1031 //
1032 // These helpers compute and cache fleet-level and population-level
1033 // weight-at-age values that use growth-derived age-to-length conversion rows
1034 // when available.
1035
1056 const std::shared_ptr<fims_popdy::Fleet<Type>> &fleet,
1058 Type mean_weight = static_cast<Type>(0.0);
1059 for (size_t l = 0; l < fleet->n_lengths; ++l) {
1060 mean_weight +=
1062 growth_observation->EvaluateWeightAtLength(fleet->lengths[l]);
1063 }
1064 return mean_weight;
1065 }
1066
1082 const std::shared_ptr<fims_popdy::Fleet<Type>> &fleet, size_t year,
1084 if (age_to_length_conversion_derived == nullptr ||
1085 !age_to_length_conversion_derived->IsActive()) {
1086 throw std::runtime_error(
1087 "Growth-derived age-to-length conversion was unavailable while "
1088 "building fleet age-to-length probabilities.");
1089 }
1090
1091 if (!age_to_length_conversion_derived->BuildAgeToLengthConversionRow(
1093 std::stringstream ss;
1094 ss << "Failed to build growth-derived age-to-length conversion row for "
1095 "fleet id "
1096 << fleet->GetId() << ", year " << year << ", age " << age << ".";
1097 FIMS_ERROR_LOG(ss.str());
1098 throw std::runtime_error(ss.str());
1099 }
1100 }
1101
1132
1143 for (size_t p = 0; p < this->populations.size(); ++p) {
1145 this->populations[p]);
1146 }
1147 }
1148
1158 for (size_t p = 0; p < this->populations.size(); ++p) {
1159 std::shared_ptr<fims_popdy::Population<Type>> &population =
1160 this->populations[p];
1161
1162 if (population == nullptr || population->growth == nullptr) {
1163 continue;
1164 }
1165
1166 std::shared_ptr<fims_popdy::GrowthDerivedObservationBase<Type>>
1167 growth_observation = std::dynamic_pointer_cast<
1169 population->growth);
1170
1171 if (growth_observation != nullptr) {
1173 }
1174 }
1175 }
1176
1193 const std::shared_ptr<fims_popdy::Fleet<Type>> &fleet, size_t year,
1194 size_t age) {
1195 if (fleet == nullptr) {
1196 throw std::runtime_error(
1197 "Fleet pointer was null while resolving growth-derived fleet mean "
1198 "weight-at-age.");
1199 }
1200
1201 std::shared_ptr<fims_popdy::AgeToLengthConversionDerived<Type>>
1202 age_to_length_conversion_derived_model = std::dynamic_pointer_cast<
1204 fleet->age_to_length_conversion_model);
1205
1210 }
1211
1212 std::stringstream ss;
1213 ss << "Failed to resolve growth-derived fleet mean weight-at-age for fleet "
1214 "id "
1215 << fleet->GetId() << ", year " << year << ", age " << age << ".";
1216 FIMS_ERROR_LOG(ss.str());
1217 throw std::runtime_error(ss.str());
1218 }
1219
1235 const std::shared_ptr<fims_popdy::Population<Type>> &population,
1238 size_t year, size_t age) {
1239 if (population == nullptr || growth_observation == nullptr) {
1240 throw std::runtime_error(
1241 "Population or growth-derived observation pointer was null while "
1242 "resolving biological mean weight-at-age.");
1243 }
1244
1245 const GrowthProducts<Type> *gp =
1246 growth_observation->TryGetPreparedGrowthProducts();
1247
1248 if (gp == nullptr) {
1249 growth_observation->PrepareGrowthProducts();
1250 gp = growth_observation->TryGetPreparedGrowthProducts();
1251 }
1252
1253 if (gp == nullptr) {
1254 throw std::runtime_error(
1255 "Growth products were unavailable while resolving biological mean "
1256 "weight-at-age.");
1257 }
1258
1259 if (gp->n_years == 0 || gp->n_ages == 0) {
1260 throw std::runtime_error(
1261 "Prepared growth products were empty while resolving biological mean "
1262 "weight-at-age.");
1263 }
1264
1265 if (gp->n_sexes != 1) {
1266 throw std::runtime_error(
1267 "Biological mean weight-at-age currently requires one prepared sex.");
1268 }
1269
1270 const size_t y = (std::min)(year, gp->n_years - 1);
1271 const size_t a = (std::min)(age, gp->n_ages - 1);
1272 return gp->MeanWAA(y, a, 0);
1273 }
1274
1291 const std::shared_ptr<fims_popdy::Population<Type>> &population,
1292 size_t year, size_t age) {
1293 if (population == nullptr) {
1294 throw std::runtime_error(
1295 "Population pointer was null while resolving population mean "
1296 "weight-at-age.");
1297 }
1298
1299 if (population->growth == nullptr) {
1300 throw std::runtime_error(
1301 "Population growth pointer was null while resolving population mean "
1302 "weight-at-age.");
1303 }
1304
1305 std::shared_ptr<fims_popdy::GrowthDerivedObservationBase<Type>>
1306 growth_observation = std::dynamic_pointer_cast<
1308
1309 if (growth_observation == nullptr) {
1310 return population->growth->evaluate(year, population->ages[age]);
1311 }
1312
1315 }
1316
1322 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1323 std::map<std::string, fims::Vector<Type>> &fdq_ =
1324 this->GetFleetDerivedQuantities((*fit).second->GetId());
1325
1326 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1327
1328 if (!fleet->requires_age_length_mapping || fleet->n_lengths == 0) {
1329 continue;
1330 }
1331
1332 if (fleet->age_to_length_conversion_model == nullptr ||
1333 !fleet->age_to_length_conversion_model->IsActive()) {
1334 std::stringstream ss;
1335 ss << "Fleet id " << fleet->GetId()
1336 << "no usable age-to-length conversion path";
1337 FIMS_ERROR_LOG(ss.str());
1338 throw std::runtime_error(ss.str());
1339 }
1340
1341 for (size_t y = 0; y < fleet->n_years; y++) {
1342 Type sum = static_cast<Type>(0.0);
1343 Type sum_obs = static_cast<Type>(0.0);
1344 // robust_add is a small value to add to expected composition
1345 // proportions at age to stabilize likelihood calculations
1346 // when the expected proportions are close to zero.
1347 // Type robust_add = static_cast<Type>(0.0); // 0.0001; zeroed out
1348 // before testing sum robust is used to calculate the total sum of
1349 // robust additions to ensure that proportions sum to 1. Type
1350 // robust_sum = static_cast<Type>(1.0);
1351 for (size_t a = 0; a < fleet->n_ages; a++) {
1352 size_t i_age_year = y * fleet->n_ages + a;
1354 if (!fleet->age_to_length_conversion_model
1355 ->BuildAgeToLengthConversionRow(
1357 std::stringstream ss;
1358 ss << "Failed to build age-to-length conversion row for fleet id "
1359 << fleet->GetId() << ", year " << y << ", age " << a << ".";
1360 FIMS_ERROR_LOG(ss.str());
1361 throw std::runtime_error(ss.str());
1362 }
1363
1364 for (size_t l = 0; l < fleet->n_lengths; l++) {
1365 size_t i_length_year = y * fleet->n_lengths + l;
1367 // Use agecomp_proportion rather than agecomp_expected, which is
1368 // rescaled to the observed age-composition sample size and is
1369 // therefore 0 in years without age-composition data. The scale
1370 // cancels when the length composition is normalized below.
1371 fdq_["lengthcomp_expected"][i_length_year] +=
1372 fdq_["agecomp_proportion"][i_age_year] * age_to_length_prob;
1373
1374 fdq_["catch_numbers_at_length"][i_length_year] +=
1375 fdq_["catch_numbers_at_age"][i_age_year] * age_to_length_prob;
1376
1377 fdq_["index_numbers_at_length"][i_length_year] +=
1378 fdq_["index_numbers_at_age"][i_age_year] * age_to_length_prob;
1379 }
1380 }
1381
1382 for (size_t l = 0; l < fleet->n_lengths; l++) {
1383 size_t i_length_year = y * fleet->n_lengths + l;
1384 sum += fdq_["lengthcomp_expected"][i_length_year];
1385 // robust_sum -= robust_add;
1386
1387 if (fleet->fleet_observed_lengthcomp_data_id_m != -999) {
1388 if (fleet->observed_lengthcomp_data->at(i_length_year) !=
1389 fleet->observed_lengthcomp_data->na_value) {
1390 sum_obs += fleet->observed_lengthcomp_data->at(i_length_year);
1391 }
1392 }
1393 }
1394 for (size_t l = 0; l < fleet->n_lengths; l++) {
1395 size_t i_length_year = y * fleet->n_lengths + l;
1396 fdq_["lengthcomp_proportion"][i_length_year] =
1397 fdq_["lengthcomp_expected"][i_length_year] / sum;
1398 // robust_add + robust_sum *
1399 // this->lengthcomp_expected[i_length_year] / sum;
1400 if (fleet->fleet_observed_lengthcomp_data_id_m != -999) {
1401 fdq_["lengthcomp_expected"][i_length_year] =
1402 fdq_["lengthcomp_proportion"][i_length_year] * sum_obs;
1403 }
1404 }
1405 }
1406 }
1407 }
1408
1414 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1415 std::map<std::string, fims::Vector<Type>> &fdq_ =
1416 this->GetFleetDerivedQuantities((*fit).second->GetId());
1417 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1418
1419 for (size_t i = 0; i < fdq_["index_numbers"].size(); i++) {
1420 if (fleet->observed_index_units == "number") {
1421 fdq_["index_expected"][i] = fdq_["index_numbers"][i];
1422 } else {
1423 fdq_["index_expected"][i] = fdq_["index_weight"][i];
1424 }
1425 fdq_["log_index_expected"][i] = log(fdq_["index_expected"][i]);
1426 }
1427 }
1428 }
1429
1435 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1436 std::map<std::string, fims::Vector<Type>> &fdq_ =
1437 this->GetFleetDerivedQuantities((*fit).second->GetId());
1438 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1439
1440 for (size_t i = 0; i < fdq_["catch_weight"].size(); i++) {
1441 if (fleet->observed_catch_units == "number") {
1442 fdq_["catch_expected"][i] = fdq_["catch_numbers"][i];
1443 } else {
1444 fdq_["catch_expected"][i] = fdq_["catch_weight"][i];
1445 }
1446 fdq_["log_catch_expected"][i] = log(fdq_["catch_expected"][i]);
1447 }
1448 }
1449 }
1450
1451 virtual void Evaluate() {
1452 /*
1453 Sets derived vectors to zero
1454 Performs parameters transformations
1455 Sets recruitment deviations to mean 0.
1456 */
1457 Prepare();
1460 /*
1461 start at year=0, age=0;
1462 here year 0 is the estimated initial population structure and age 0 are
1463 recruits loops start at zero with if statements inside to specify unique
1464 code for initial structure and recruitment 0 loops. Could also have started
1465 loops at 1 with initial structure and recruitment setup outside the loops.
1466
1467 year loop is extended to <= n_years because SSB is calculated as the start
1468 of the year value and by extending one extra year we get estimates of the
1469 population structure at the end of the final year. An alternative approach
1470 would be to keep initial numbers at age in it's own vector and each year to
1471 include the population structure at the end of the year. This is likely a
1472 null point given that we are planning to modify to an event/stanza based
1473 structure in later milestones which will eliminate this confusion by
1474 explicitly referencing the exact date (or period of averaging) at which any
1475 calculation or output is being made.
1476 */
1477 for (size_t p = 0; p < this->populations.size(); p++) {
1478 std::shared_ptr<fims_popdy::Population<Type>> &population =
1479 this->populations[p];
1480 std::map<std::string, fims::Vector<Type>> &pdq_ =
1481 this->GetPopulationDerivedQuantities(population->GetId());
1482 // CAAPopulationProxy<Type>& population = this->populations_proxies[p];
1483
1484 for (size_t y = 0; y <= population->n_years; y++) {
1485 for (size_t a = 0; a < population->n_ages; a++) {
1486 /*
1487 index naming defines the dimensional folding structure
1488 i.e. i_age_year is referencing folding over years and ages.
1489 */
1490 size_t i_age_year = y * population->n_ages + a;
1491 /*
1492 Mortality rates are not estimated in the final year which is
1493 used to show expected population structure at the end of the model
1494 period. This is because biomass in year i represents biomass at the
1495 start of the year. Should we add complexity to track more values such
1496 as start, mid, and end biomass in all years where, start biomass=end
1497 biomass of the previous year? Referenced above, this is probably not
1498 worth exploring as later milestone changes will eliminate this
1499 confusion.
1500 */
1501 if (y < population->n_years) {
1502 /*
1503 First thing we need is total mortality aggregated across all fleets
1504 to inform the subsequent catch and change in numbers at age
1505 calculations. This is only calculated for years < n_years as these
1506 are the model estimated years with data. The year loop extends to
1507 y=n_years so that population numbers at age and SSB can be
1508 calculated at the end of the last year of the model
1509 */
1511 }
1513 /* if statements needed because some quantities are only needed
1514 for the first year and/or age, so these steps are included here.
1515 */
1516 if (y == 0) {
1517 // Initial numbers at age is a user input or estimated parameter
1518 // vector.
1520
1521 if (a == 0) {
1522 /*
1523 Expected recruitment in year 0 is numbers at age 0 in year 0.
1524 */
1525 pdq_["expected_recruitment"][y] =
1526 pdq_["numbers_at_age"][i_age_year];
1527 pdq_["unfished_numbers_at_age"][i_age_year] =
1528 fims_math::exp(population->recruitment->log_rzero[0]);
1529 } else {
1531 }
1532
1533 } else {
1534 if (a == 0) {
1535 // Set the nrecruits for age a=0 year y (use pointers instead of
1536 // functional returns)
1538 pdq_["unfished_numbers_at_age"][i_age_year] =
1539 fims_math::exp(population->recruitment->log_rzero[0]);
1540 } else {
1541 size_t i_agem1_yearm1 = (y - 1) * population->n_ages + (a - 1);
1544 a);
1545 }
1546 }
1547
1548 /*
1549 Fished and unfished biomass vectors are summing biomass at
1550 age across ages.
1551 */
1552
1554
1556
1557 /*
1558 Fished and unfished spawning biomass vectors are summing biomass at
1559 age across ages to allow calculation of recruitment in the next
1560 year.
1561 */
1562
1564
1566
1567 /*
1568 Here composition, total catch, and index values are calculated for all
1569 years with reference data. They are not calculated for y=n_years as
1570 there is this is just to get final population structure at the end of
1571 the terminal year.
1572 */
1573 if (y < population->n_years) {
1577
1581 }
1582 }
1583 /* Calculate spawning biomass depletion ratio */
1585 }
1586 }
1591 }
1596 virtual void Report() {
1597 int n_fleets = this->fleets.size();
1598 int n_pops = this->populations.size();
1599#ifdef TMB_MODEL
1600 if (this->do_reporting == true) {
1602 report_vectors.clear();
1603 // std::shared_ptr<UncertaintyReportInfoMap>
1604 // population_uncertainty_report_info_map =
1605 // this->GetPopulationUncertaintyReportInfoMap();
1606
1607 // std::shared_ptr<UncertaintyReportInfoMap>
1608 // fleet_uncertainty_report_info_map =
1609 // this->GetFleetUncertaintyReportInfoMap();
1610
1611 // initialize population vectors
1630
1631 // initialize fleet vectors
1654
1655 // initiate population index for structuring report out objects
1656 int pop_idx = 0;
1657 for (size_t p = 0; p < this->populations.size(); p++) {
1658 std::map<std::string, fims::Vector<Type>> &derived_quantities =
1660 biomass_p(pop_idx) = derived_quantities["biomass"].to_tmb();
1662 derived_quantities["expected_recruitment"].to_tmb();
1663 mortality_F_p(pop_idx) = derived_quantities["mortality_F"].to_tmb();
1664 mortality_M_p(pop_idx) = derived_quantities["mortality_M"].to_tmb();
1665 mortality_Z_p(pop_idx) = derived_quantities["mortality_Z"].to_tmb();
1667 derived_quantities["numbers_at_age"].to_tmb();
1669 derived_quantities["proportion_mature_at_age"].to_tmb();
1671 derived_quantities["spawning_biomass"].to_tmb();
1673 derived_quantities["sum_selectivity"].to_tmb();
1675 derived_quantities["total_catch_numbers"].to_tmb();
1677 derived_quantities["total_catch_weight"].to_tmb();
1679 derived_quantities["unfished_biomass"].to_tmb();
1681 derived_quantities["unfished_numbers_at_age"].to_tmb();
1683 derived_quantities["unfished_spawning_biomass"].to_tmb();
1685 this->populations[pop_idx]->spawning_biomass_ratio.to_tmb();
1686
1688 growth_observation = std::dynamic_pointer_cast<
1690 this->populations[p]->growth)) {
1691 const auto *gp = growth_observation->TryGetPreparedGrowthProducts();
1692 if (gp == nullptr) {
1693 throw std::runtime_error(
1694 "Growth products were not prepared before report generation.");
1695 }
1696
1697 const std::size_t n = gp->Size();
1698 vector<Type> mean_laa(n);
1699 vector<Type> sd_laa(n);
1700 vector<Type> mean_waa(n);
1701 for (std::size_t i = 0; i < n; ++i) {
1702 mean_laa(i) = gp->mean_LAA[i];
1703 sd_laa(i) = gp->sd_LAA[i];
1704 const std::size_t year = i / this->populations[p]->n_ages;
1705 const std::size_t age = i % this->populations[p]->n_ages;
1706 mean_waa(i) =
1707 PopulationMeanWeightAA(this->populations[p], year, age);
1708 }
1712 }
1713
1714 pop_idx += 1;
1715 }
1716
1717 // initiate fleet index for structuring report out objects
1718 int fleet_idx = 0;
1720 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1721 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1722 std::map<std::string, fims::Vector<Type>> &derived_quantities =
1723 this->GetFleetDerivedQuantities(fleet->GetId());
1724
1726 derived_quantities["agecomp_expected"].to_tmb();
1728 derived_quantities["agecomp_proportion"].to_tmb();
1733 if (isDouble<Type>::value) {
1735 age_to_length_conversion_derived_used[0] = static_cast<Type>(0.0);
1736
1737 std::shared_ptr<fims_popdy::AgeToLengthConversionDerived<Type>>
1739 std::dynamic_pointer_cast<
1741 fleet->age_to_length_conversion_model);
1742
1746 age_to_length_conversion_derived_used[0] = static_cast<Type>(1.0);
1747 growth_derived_mean_WAA.resize(fleet->n_years * fleet->n_ages);
1748
1749 for (size_t y = 0; y < fleet->n_years; ++y) {
1750 for (size_t a = 0; a < fleet->n_ages; ++a) {
1751 const size_t i_age_year = y * fleet->n_ages + a;
1752
1753 if (this->report_age_to_length_conversion_derived_tensor) {
1754 if (age_to_length_conversion_derived.size() == 0) {
1756 fleet->n_years * fleet->n_ages * fleet->n_lengths);
1757 }
1758
1763
1767 ->growth_observation_,
1769
1770 for (size_t l = 0; l < fleet->n_lengths; ++l) {
1771 const size_t i_length_age_year =
1772 y * (fleet->n_ages * fleet->n_lengths) +
1773 a * fleet->n_lengths + l;
1776 }
1777 } else {
1780 }
1781 }
1782 }
1783 }
1784 }
1785
1793 fleet->age_to_length_conversion.to_tmb();
1794 }
1796 derived_quantities["index_expected"].to_tmb();
1798 derived_quantities["index_numbers"].to_tmb();
1800 derived_quantities["index_numbers_at_age"].to_tmb();
1802 derived_quantities["index_numbers_at_length"].to_tmb();
1803 index_weight_f(fleet_idx) = derived_quantities["index_weight"].to_tmb();
1805 derived_quantities["index_weight_at_age"].to_tmb();
1807 derived_quantities["catch_expected"].to_tmb();
1809 derived_quantities["catch_numbers"].to_tmb();
1811 derived_quantities["catch_numbers_at_age"].to_tmb();
1813 derived_quantities["catch_numbers_at_length"].to_tmb();
1814 catch_weight_f(fleet_idx) = derived_quantities["catch_weight"].to_tmb();
1816 derived_quantities["catch_weight_at_age"].to_tmb();
1817 // length_comp_expected_f(fleet_idx) =
1818 // derived_quantities["length_comp_expected"];
1819 // length_comp_proportion_f(fleet_idx) =
1820 // derived_quantities["length_comp_proportion"];
1822 derived_quantities["lengthcomp_expected"].to_tmb();
1824 derived_quantities["lengthcomp_proportion"].to_tmb();
1826 derived_quantities["log_index_expected"].to_tmb();
1828 derived_quantities["log_catch_expected"].to_tmb();
1829 fleet_idx += 1;
1830 }
1831
1832 vector<Type> biomass = ADREPORTvector(biomass_p);
1833 vector<Type> expected_recruitment =
1835 vector<Type> mortality_F = ADREPORTvector(mortality_F_p);
1836 vector<Type> mortality_M = ADREPORTvector(mortality_M_p);
1837 vector<Type> mortality_Z = ADREPORTvector(mortality_Z_p);
1838 vector<Type> numbers_at_age = ADREPORTvector(numbers_at_age_p);
1839 vector<Type> proportion_mature_at_age =
1841 vector<Type> spawning_biomass = ADREPORTvector(spawning_biomass_p);
1842 vector<Type> sum_selectivity = ADREPORTvector(sum_selectivity_p);
1843 vector<Type> total_catch_numbers = ADREPORTvector(total_catch_numbers_p);
1844 vector<Type> total_catch_weight = ADREPORTvector(total_catch_weight_p);
1845 vector<Type> unfished_biomass = ADREPORTvector(unfished_biomass_p);
1846 vector<Type> unfished_numbers_at_age =
1848 vector<Type> unfished_spawning_biomass =
1850 vector<Type> spawning_biomass_ratio =
1852
1853 vector<Type> agecomp_expected = ADREPORTvector(agecomp_expected_f);
1854 vector<Type> agecomp_proportion = ADREPORTvector(agecomp_proportion_f);
1855 vector<Type> index_expected = ADREPORTvector(index_expected_f);
1856 vector<Type> index_numbers = ADREPORTvector(index_numbers_f);
1857 vector<Type> index_numbers_at_age =
1859 vector<Type> index_numbers_at_length =
1861 vector<Type> index_weight = ADREPORTvector(index_weight_f);
1862 vector<Type> index_weight_at_age = ADREPORTvector(index_weight_at_age_f);
1863 vector<Type> catch_expected = ADREPORTvector(catch_expected_f);
1864 vector<Type> catch_numbers = ADREPORTvector(catch_numbers_f);
1865 vector<Type> catch_numbers_at_age =
1867 vector<Type> catch_numbers_at_length =
1869 vector<Type> catch_weight = ADREPORTvector(catch_weight_f);
1870 vector<Type> catch_weight_at_age = ADREPORTvector(catch_weight_at_age_f);
1871 // vector<Type> length_comp_expected =
1872 // ADREPORTvector(length_comp_expected_f); vector<Type>
1873 // length_comp_proportion = ADREPORTvector(length_comp_proportion_f);
1874 vector<Type> lengthcomp_expected = ADREPORTvector(lengthcomp_expected_f);
1875 vector<Type> lengthcomp_proportion =
1877 vector<Type> log_index_expected = ADREPORTvector(log_index_expected_f);
1878 vector<Type> log_catch_expected = ADREPORTvector(log_catch_expected_f);
1879 // populations
1880 // report
1881 FIMS_REPORT_F_("biomass", biomass_p, this->of);
1882 FIMS_REPORT_F_("expected_recruitment", expected_recruitment_p, this->of);
1883 FIMS_REPORT_F_("mortality_F", mortality_F_p, this->of);
1884 FIMS_REPORT_F_("mortality_M", mortality_M_p, this->of);
1885 FIMS_REPORT_F_("mortality_Z", mortality_Z_p, this->of);
1886 FIMS_REPORT_F_("numbers_at_age", numbers_at_age_p, this->of);
1887 FIMS_REPORT_F_("proportion_mature_at_age", proportion_mature_at_age_p,
1888 this->of);
1889 FIMS_REPORT_F_("spawning_biomass", spawning_biomass_p, this->of);
1890 FIMS_REPORT_F_("sum_selectivity", sum_selectivity_p, this->of);
1891 FIMS_REPORT_F_("total_catch_numbers", total_catch_numbers_p, this->of);
1892 FIMS_REPORT_F_("total_catch_weight", total_catch_weight_p, this->of);
1893 FIMS_REPORT_F_("unfished_biomass", unfished_biomass_p, this->of);
1894 FIMS_REPORT_F_("unfished_numbers_at_age", unfished_numbers_at_age_p,
1895 this->of);
1896 FIMS_REPORT_F_("unfished_spawning_biomass", unfished_spawning_biomass_p,
1897 this->of);
1898 FIMS_REPORT_F_("spawning_biomass_ratio", spawning_biomass_ratio_p,
1899 this->of);
1900 FIMS_REPORT_F_("growth_mean_LAA", growth_mean_LAA_p, this->of);
1901 FIMS_REPORT_F_("growth_sd_LAA", growth_sd_LAA_p, this->of);
1902 FIMS_REPORT_F_("growth_mean_WAA", growth_mean_WAA_p, this->of);
1903
1904 // adreport
1905 ADREPORT_F(biomass, this->of);
1906 ADREPORT_F(expected_recruitment, this->of);
1907 ADREPORT_F(mortality_F, this->of);
1908 ADREPORT_F(mortality_M, this->of);
1909 ADREPORT_F(mortality_Z, this->of);
1910 ADREPORT_F(numbers_at_age, this->of);
1911 ADREPORT_F(proportion_mature_at_age, this->of);
1912 ADREPORT_F(spawning_biomass, this->of);
1913 ADREPORT_F(sum_selectivity, this->of);
1914 ADREPORT_F(total_catch_numbers, this->of);
1915 ADREPORT_F(total_catch_weight, this->of);
1916 ADREPORT_F(unfished_biomass, this->of);
1917 ADREPORT_F(unfished_numbers_at_age, this->of);
1918 ADREPORT_F(unfished_spawning_biomass, this->of);
1919 ADREPORT_F(spawning_biomass_ratio, this->of);
1920
1921 // fleets
1922 // report
1923 FIMS_REPORT_F_("agecomp_expected", agecomp_expected_f, this->of);
1924 FIMS_REPORT_F_("agecomp_proportion", agecomp_proportion_f, this->of);
1925 FIMS_REPORT_F_("age_to_length_conversion", age_to_length_conversion_f,
1926 this->of);
1927 FIMS_REPORT_F_("age_to_length_conversion_derived",
1928 age_to_length_conversion_derived_f, this->of);
1929 FIMS_REPORT_F_("age_to_length_conversion_derived_used",
1930 age_to_length_conversion_derived_used_f, this->of);
1931 FIMS_REPORT_F_("growth_derived_mean_WAA", growth_derived_mean_WAA_f,
1932 this->of);
1933 FIMS_REPORT_F_("index_expected", index_expected_f, this->of);
1934 FIMS_REPORT_F_("index_numbers", index_numbers_f, this->of);
1935 FIMS_REPORT_F_("index_numbers_at_age", index_numbers_at_age_f, this->of);
1936 FIMS_REPORT_F_("index_numbers_at_length", index_numbers_at_length_f,
1937 this->of);
1938 FIMS_REPORT_F_("index_weight", index_weight_f, this->of);
1939 FIMS_REPORT_F_("index_weight_at_age", index_weight_at_age_f, this->of);
1940 FIMS_REPORT_F_("catch_expected", catch_expected_f, this->of);
1941 FIMS_REPORT_F_("catch_numbers", catch_numbers_f, this->of);
1942 FIMS_REPORT_F_("catch_numbers_at_age", catch_numbers_at_age_f, this->of);
1943 FIMS_REPORT_F_("catch_numbers_at_length", catch_numbers_at_length_f,
1944 this->of);
1945 FIMS_REPORT_F_("catch_weight", catch_weight_f, this->of);
1946 FIMS_REPORT_F_("catch_weight_at_age", catch_weight_at_age_f, this->of);
1947 FIMS_REPORT_F_("lengthcomp_expected", lengthcomp_expected_f, this->of);
1948 FIMS_REPORT_F_("lengthcomp_proportion", lengthcomp_proportion_f,
1949 this->of);
1950 FIMS_REPORT_F_("log_index_expected", log_index_expected_f, this->of);
1951 FIMS_REPORT_F_("log_catch_expected", log_catch_expected_f, this->of);
1952 // adreport
1953 ADREPORT_F(agecomp_expected, this->of);
1954 ADREPORT_F(agecomp_proportion, this->of);
1955 ADREPORT_F(index_expected, this->of);
1956 ADREPORT_F(index_numbers, this->of);
1957 ADREPORT_F(index_numbers_at_age, this->of);
1958 ADREPORT_F(index_numbers_at_length, this->of);
1959 ADREPORT_F(index_weight, this->of);
1960 ADREPORT_F(index_weight_at_age, this->of);
1961 ADREPORT_F(catch_expected, this->of);
1962 ADREPORT_F(catch_numbers, this->of);
1963 ADREPORT_F(catch_numbers_at_age, this->of);
1964 ADREPORT_F(catch_numbers_at_length, this->of);
1965 ADREPORT_F(catch_weight, this->of);
1966 ADREPORT_F(catch_weight_at_age, this->of);
1967 ADREPORT_F(lengthcomp_expected, this->of);
1968 ADREPORT_F(lengthcomp_proportion, this->of);
1969 ADREPORT_F(log_index_expected, this->of);
1970 ADREPORT_F(log_catch_expected, this->of);
1971 std::stringstream var_name;
1972 typename std::map<std::string, fims::Vector<fims::Vector<Type>>>::iterator
1973 rvit;
1974 for (rvit = report_vectors.begin(); rvit != report_vectors.end();
1975 ++rvit) {
1976 auto &x = rvit->second;
1977
1978 int outer_dim = x.size();
1979 int dim = 0;
1980 for (int i = 0; i < outer_dim; i++) {
1981 dim += x[i].size();
1982 }
1983 vector<Type> res(dim);
1984 int idx = 0;
1985 for (int i = 0; i < outer_dim; i++) {
1986 int inner_dim = x[i].size();
1987 for (int j = 0; j < inner_dim; j++) {
1988 res(idx) = x[i][j];
1989 idx += 1;
1990 }
1991 }
1992 this->of->reportvector.push(res, rvit->first.c_str());
1993 }
1994 }
1995#endif
1996 }
1997};
1998
1999} // namespace fims_popdy
2000
2001#endif
Definition fims_vector.hpp:27
void resize(size_t s)
Changes the number of elements stored.
Definition fims_vector.hpp:401
CatchAtAge is a class containing a catch-at-age model, which is just one of many potential fishery mo...
Definition catch_at_age.hpp:57
void CalculateSpawningBiomassRatio(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t year)
Calculate the spawning biomass ratio for a population and year.
Definition catch_at_age.hpp:594
void PreparePopulationGrowthProducts()
Prepares cached population growth products for all populations whose growth objects expose the growth...
Definition catch_at_age.hpp:1157
std::map< std::string, fims::Vector< Type > >::iterator dq_iterator
Iterate through derived quantities.
Definition catch_at_age.hpp:116
void evaluate_catch()
Definition catch_at_age.hpp:1433
std::map< std::string, fims::Vector< Type > >::iterator derived_quantities_iterator
Iterate the derived quantities.
Definition catch_at_age.hpp:70
Type CalculateSBPR0(std::shared_ptr< fims_popdy::Population< Type > > &population)
Calculates equilibrium spawning biomass per recruit.
Definition catch_at_age.hpp:626
virtual void Initialize()
Definition catch_at_age.hpp:169
std::vector< Type > ages
Definition catch_at_age.hpp:133
void CalculateUnfishedNumbersAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t i_agem1_yearm1, size_t age)
Calculates unfished numbers at age at year and age specific indices.
Definition catch_at_age.hpp:356
void EnsureAllFleetAgeToLengthConversion()
Ensure all fleets linked to this model have a usable age-to-length conversion.
Definition catch_at_age.hpp:1142
void CalculateBiomass(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculates biomass for a population.
Definition catch_at_age.hpp:487
void CalculateCatchWeightAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t year, size_t age)
Calculates weight at age of the catch for a given fleet from a population.
Definition catch_at_age.hpp:793
std::map< std::string, fims::Vector< fims::Vector< Type > > > report_vectors
A map of report vectors for the object. used to populate the report_vectors map in for submodule para...
Definition catch_at_age.hpp:122
Type MeanWeightFromAgeToLengthConversionRow(const std::shared_ptr< fims_popdy::GrowthDerivedObservationBase< Type > > &growth_observation, const std::shared_ptr< fims_popdy::Fleet< Type > > &fleet, const fims::Vector< Type > &age_to_length_conversion_row)
Compute expected fleet-specific weight-at-age from a normalized age-to-length conversion row and flee...
Definition catch_at_age.hpp:1053
Type BiologicalMeanWeightFromPreparedGrowthProducts(const std::shared_ptr< fims_popdy::Population< Type > > &population, const std::shared_ptr< fims_popdy::GrowthDerivedObservationBase< Type > > &growth_observation, size_t year, size_t age)
Read biological mean weight-at-age directly from prepared growth products.
Definition catch_at_age.hpp:1234
std::set< uint32_t > & GetPopulationIds()
Get the population ids of the model.
Definition catch_at_age.hpp:258
std::map< uint32_t, std::map< std::string, fims::Vector< size_t > > >::iterator population_derived_quantities_dims_iterator
Used to iterate through population-based derived quantities dimensions.
Definition catch_at_age.hpp:102
std::map< uint32_t, std::shared_ptr< fims_popdy::Fleet< Type > > >::iterator fleet_iterator
Iterate through fleets.
Definition catch_at_age.hpp:110
void CalculateCatch(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t year, size_t age)
Calculates total catch (catch) by fleet and population for a given year by aggregating age-specific c...
Definition catch_at_age.hpp:753
Type GrowthDerivedFleetMeanWeightAA(const std::shared_ptr< fims_popdy::Fleet< Type > > &fleet, size_t year, size_t age)
Compute fleet-specific expected weight-at-age from the growth-derived age-to-length conversion path.
Definition catch_at_age.hpp:1192
void CalculateIndexWeightAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t year, size_t age)
Calculates biomass of fish for the index for a given fleet from a population.
Definition catch_at_age.hpp:938
void evaluate_age_comp()
Definition catch_at_age.hpp:965
void evaluate_length_comp()
Definition catch_at_age.hpp:1320
virtual ~CatchAtAge()
Destroy the Catch At Age object.
Definition catch_at_age.hpp:163
CatchAtAge(const CatchAtAge &other)
Copy constructor for the CatchAtAge class.
Definition catch_at_age.hpp:150
bool report_age_to_length_conversion_derived_tensor
Controls whether reporting materializes the full derived age-to-length tensor for fleets using the gr...
Definition catch_at_age.hpp:130
void CalculateSpawningBiomass(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculates spawning biomass for a population.
Definition catch_at_age.hpp:538
CatchAtAge()
Definition catch_at_age.hpp:138
Type MeanWeightFromAgeToLengthConversionDerived(const std::shared_ptr< fims_popdy::AgeToLengthConversionDerived< Type > > &age_to_length_conversion_derived, const std::shared_ptr< fims_popdy::Fleet< Type > > &fleet, size_t year, size_t age)
Compute fleet-specific mean weight-at-age from one growth-derived age-to-length conversion row.
Definition catch_at_age.hpp:1118
virtual void Evaluate()
Evaluate the model.
Definition catch_at_age.hpp:1451
std::string name_m
The name of the model.
Definition catch_at_age.hpp:63
void CalculateMaturityAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculates maturity at age, in proportion, for a population.
Definition catch_at_age.hpp:725
void CalculateUnfishedSpawningBiomass(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculated unfished spawning biomass for a population.
Definition catch_at_age.hpp:566
void CalculateIndex(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculates the index for a fleet from a population.
Definition catch_at_age.hpp:872
void CalculateUnfishedBiomass(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculates the unfished biomass for a population.
Definition catch_at_age.hpp:511
std::map< uint32_t, std::map< std::string, fims::Vector< Type > > >::iterator fleet_derived_quantities_iterator
Used to iterate through fleet-based derived quantities.
Definition catch_at_age.hpp:78
std::map< uint32_t, std::map< std::string, fims::Vector< Type > > >::iterator population_derived_quantities_iterator
Used to iterate through population-based derived quantities.
Definition catch_at_age.hpp:93
void CalculateNumbersAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t i_agem1_yearm1, size_t age)
Calculates numbers at age for a population.
Definition catch_at_age.hpp:313
void CalculateUnfishedInitialNumbersAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t age)
Calculates unfished numbers at age in the first year.
Definition catch_at_age.hpp:400
void CalculateRecruitment(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t i_dev)
Calculates expected recruitment for a population.
Definition catch_at_age.hpp:682
void CalculateCatchNumbersAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculates numbers of fish for the catch for a given fleet from a population, year and age.
Definition catch_at_age.hpp:834
virtual void Report()
Definition catch_at_age.hpp:1596
void AddPopulation(uint32_t id)
Definition catch_at_age.hpp:253
std::vector< std::shared_ptr< fims_popdy::Population< Type > > > & GetPopulations()
Definition catch_at_age.hpp:265
std::map< uint32_t, std::map< std::string, fims::Vector< size_t > > >::iterator fleet_derived_quantities_dims_iterator
Used to iterate through fleet-based derived quantities dimensions.
Definition catch_at_age.hpp:86
Type PopulationMeanWeightAA(const std::shared_ptr< fims_popdy::Population< Type > > &population, size_t year, size_t age)
Calculates population-level mean weight-at-age.
Definition catch_at_age.hpp:1290
void CalculateMortality(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculates total mortality for a population.
Definition catch_at_age.hpp:450
void CalculateIndexNumbersAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t year, size_t age)
Calculates the numbers for the index for a fleet from a population.
Definition catch_at_age.hpp:903
void BuildAgeToLengthConversionDerivedRowOrThrow(const std::shared_ptr< fims_popdy::AgeToLengthConversionDerived< Type > > &age_to_length_conversion_derived, const std::shared_ptr< fims_popdy::Fleet< Type > > &fleet, size_t year, size_t age, fims::Vector< Type > &age_to_length_conversion_row)
Build one fleet-specific growth-derived age-to-length conversion row or fail clearly.
Definition catch_at_age.hpp:1079
void CalculateInitialNumbersAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t age)
Calculates initial numbers at age for index and age.
Definition catch_at_age.hpp:281
virtual void Prepare()
Definition catch_at_age.hpp:202
void evaluate_index()
Definition catch_at_age.hpp:1412
FisheryModelBase is a base class for fishery models in FIMS.
Definition fishery_model_base.hpp:77
uint32_t GetId()
Get the Id object.
Definition fishery_model_base.hpp:382
std::map< uint32_t, std::shared_ptr< fims_popdy::Fleet< Type > > > fleets
A map of fleets in the fishery model, indexed by fleet id. Unique instances to eliminate duplicate in...
Definition fishery_model_base.hpp:107
std::vector< std::shared_ptr< fims_popdy::Population< Type > > > populations
A vector of populations in the fishery model.
Definition fishery_model_base.hpp:101
std::string model_type_m
A string specifying the model type.
Definition fishery_model_base.hpp:91
DerivedQuantitiesMap & GetFleetDerivedQuantities()
Get the fleet derived quantities.
Definition fishery_model_base.hpp:213
std::set< uint32_t > population_ids
Unique identifier for the fishery model.
Definition fishery_model_base.hpp:96
DerivedQuantitiesMap & GetPopulationDerivedQuantities()
Get the population derived quantities.
Definition fishery_model_base.hpp:222
virtual void ResetVector(fims::Vector< Type > &v, Type value=0.0)
Reset a vector from start to end with a value.
Definition fishery_model_base.hpp:361
Generic capability interface for growth models that can feed the growth-derived age-to-length convers...
Definition growth_model_adapter.hpp:26
virtual void PrepareGrowthProducts()=0
Prepare growth products for the current model state.
#define FIMS_ERROR_LOG(MESSAGE)
Definition def.hpp:664
Defines the base class for all fishery models within the FIMS framework.
#define ADREPORT_F(name, F)
TMB macro that reports variables and uncertainties.
Definition interface.hpp:83
The population dynamics of FIMS.
Definition catch_at_age.hpp:45
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
Shared runtime helpers for constructing and validating fleet age-to-length conversions.
Growth-derived age-to-length conversion implementation that reads prepared population age-to-size pro...
Definition derived.hpp:35
Base class for all fleets.
Definition fleet.hpp:26
virtual const Type evaluate(int year, const double &a)=0
Calculates the growth at the independent variable value.
Growth "products" in a consistent (year, age, sex) space.
Definition growth_products.hpp:26
Population class. Contains subpopulations that are divided into generic partitions (e....
Definition population.hpp:27