FIMS  v0.10.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
409 size_t i_age_year, size_t year, size_t age) {
410 std::map<std::string, fims::Vector<Type>> &dq_ =
412
413 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
414 // evaluate is a member function of the selectivity class
415 Type s = population->fleets[fleet_]->selectivity->evaluate(
416 population->ages[age], year);
417
418 dq_["mortality_F"][i_age_year] +=
419 population->fleets[fleet_]->Fmort[year] *
420 population->f_multiplier[year] * s;
421
422 dq_["sum_selectivity"][i_age_year] += s;
423 }
424 dq_["mortality_M"][i_age_year] = population->M[i_age_year];
425
426 dq_["mortality_Z"][i_age_year] =
427 population->M[i_age_year] + dq_["mortality_F"][i_age_year];
428 }
429
446 size_t i_age_year, size_t year, size_t age) {
447 std::map<std::string, fims::Vector<Type>> &dq_ =
449
450 dq_["biomass"][year] += dq_["numbers_at_age"][i_age_year] *
452 }
453
470 size_t i_age_year, size_t year, size_t age) {
471 std::map<std::string, fims::Vector<Type>> &dq_ =
473
474 dq_["unfished_biomass"][year] +=
475 dq_["unfished_numbers_at_age"][i_age_year] *
477 }
478
497 size_t i_age_year, size_t year, size_t age) {
498 std::map<std::string, fims::Vector<Type>> &dq_ =
500
501 dq_["spawning_biomass"][year] +=
502 population->proportion_female.get_force_scalar(age) *
503 dq_["numbers_at_age"][i_age_year] *
504 dq_["proportion_mature_at_age"][i_age_year] *
506 }
507
525 size_t i_age_year, size_t year, size_t age) {
526 std::map<std::string, fims::Vector<Type>> &dq_ =
528
529 dq_["unfished_spawning_biomass"][year] +=
530 population->proportion_female.get_force_scalar(age) *
531 dq_["unfished_numbers_at_age"][i_age_year] *
532 dq_["proportion_mature_at_age"][i_age_year] *
534 }
535
552 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year) {
553 std::map<std::string, fims::Vector<Type>> &dq_ =
555 population->spawning_biomass_ratio[year] =
556 dq_["spawning_biomass"][year] / dq_["unfished_spawning_biomass"][0];
557 }
558
583 std::shared_ptr<fims_popdy::Population<Type>> &population) {
584 std::map<std::string, fims::Vector<Type>> &dq_ =
586
587 std::vector<Type> numbers_spr(population->n_ages, 1.0);
588 Type phi_0 = 0.0;
589 phi_0 += numbers_spr[0] *
590 population->proportion_female.get_force_scalar(0) *
591 dq_["proportion_mature_at_age"][0] *
593 for (size_t a = 1; a < (population->n_ages - 1); a++) {
594 numbers_spr[a] = numbers_spr[a - 1] * fims_math::exp(-population->M[a]);
595 phi_0 += numbers_spr[a] *
596 population->proportion_female.get_force_scalar(a) *
597 dq_["proportion_mature_at_age"][a] *
599 }
600
601 numbers_spr[population->n_ages - 1] =
602 (numbers_spr[population->n_ages - 2] *
603 fims_math::exp(-population->M[population->n_ages - 2])) /
604 (1 - fims_math::exp(-population->M[population->n_ages - 1]));
605 phi_0 +=
606 numbers_spr[population->n_ages - 1] *
607 population->proportion_female.get_force_scalar(population->n_ages - 1) *
608 dq_["proportion_mature_at_age"][population->n_ages - 1] *
610
611 return phi_0;
612 }
613
639 size_t i_age_year, size_t year, size_t i_dev) {
640 std::map<std::string, fims::Vector<Type>> &dq_ =
642
644
645 if (i_dev == population->n_years) {
646 dq_["numbers_at_age"][i_age_year] =
647 population->recruitment->evaluate_mean(
648 dq_["spawning_biomass"][year - 1], phi_0);
649 /*the final year of the time series has no data to inform recruitment
650 devs, so this value is set to the mean recruitment.*/
651 } else {
652 // Why are we using evaluate_mean, how come a virtual function was
653 // changed? AMH: there are now two virtual functions: evaluate_mean and
654 // evaluate_process (see below)
655 population->recruitment->log_expected_recruitment[year - 1] =
656 fims_math::log(population->recruitment->evaluate_mean(
657 dq_["spawning_biomass"][year - 1], phi_0));
658
659 dq_["numbers_at_age"][i_age_year] = fims_math::exp(
660 population->recruitment->process->evaluate_process(year - 1));
661 }
662
663 dq_["expected_recruitment"][year] = dq_["numbers_at_age"][i_age_year];
664 }
665
681 size_t i_age_year, size_t age) {
682 std::map<std::string, fims::Vector<Type>> &dq_ =
684
685 dq_["proportion_mature_at_age"][i_age_year] =
686 population->maturity->evaluate(population->ages[age]);
687 }
688
705 size_t year, size_t age) {
706 std::map<std::string, fims::Vector<Type>> &pdq_ =
708
709 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
710 std::map<std::string, fims::Vector<Type>> &fdq_ =
711 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
712 size_t i_age_year = year * population->n_ages + age;
713
714 pdq_["total_catch_weight"][year] +=
715 fdq_["catch_weight_at_age"][i_age_year];
716
717 fdq_["catch_weight"][year] += fdq_["catch_weight_at_age"][i_age_year];
718
719 pdq_["total_catch_numbers"][year] +=
720 fdq_["catch_numbers_at_age"][i_age_year];
721
722 fdq_["catch_numbers"][year] += fdq_["catch_numbers_at_age"][i_age_year];
723 }
724 }
725
745 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year,
746 size_t age) {
747 int i_age_year = year * population->n_ages + age;
748
749 if (population->growth == nullptr) {
750 throw std::runtime_error(
751 "Population growth pointer was null while resolving landings "
752 "weight-at-age.");
753 }
754
755 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
756 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet =
757 population->fleets[fleet_];
758 std::map<std::string, fims::Vector<Type>> &fdq_ =
759 this->GetFleetDerivedQuantities(fleet->GetId());
760
762
763 fdq_["catch_weight_at_age"][i_age_year] =
764 fdq_["catch_numbers_at_age"][i_age_year] * mean_weight_at_age;
765 }
766 }
767
787 size_t i_age_year, size_t year, size_t age) {
788 std::map<std::string, fims::Vector<Type>> &pdq_ =
790
791 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
792 std::map<std::string, fims::Vector<Type>> &fdq_ =
793 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
794
795 // Baranov Catch Equation
796 fdq_["catch_numbers_at_age"][i_age_year] +=
797 (population->fleets[fleet_]->Fmort[year] *
798 population->f_multiplier[year] *
799 population->fleets[fleet_]->selectivity->evaluate(
800 population->ages[age], year)) /
801 pdq_["mortality_Z"][i_age_year] * pdq_["numbers_at_age"][i_age_year] *
802 (1 - fims_math::exp(-(pdq_["mortality_Z"][i_age_year])));
803 }
804 }
805
824 size_t i_age_year, size_t year, size_t age) {
825 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
826 std::map<std::string, fims::Vector<Type>> &fdq_ =
827 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
828
829 fdq_["index_weight"][year] += fdq_["index_weight_at_age"][i_age_year];
830
831 fdq_["index_numbers"][year] += fdq_["index_numbers_at_age"][i_age_year];
832 }
833 }
834
856 size_t i_age_year, size_t year, size_t age) {
857 std::map<std::string, fims::Vector<Type>> &pdq_ =
859
860 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
861 std::map<std::string, fims::Vector<Type>> &fdq_ =
862 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
863
864 fdq_["index_numbers_at_age"][i_age_year] +=
865 (population->fleets[fleet_]->q.get_force_scalar(year) *
866 population->fleets[fleet_]->selectivity->evaluate(
867 population->ages[age], year)) *
868 pdq_["numbers_at_age"][i_age_year];
869 }
870 }
871
890 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year,
891 size_t age) {
892 int i_age_year = year * population->n_ages + age;
893
894 if (population->growth == nullptr) {
895 throw std::runtime_error(
896 "Population growth pointer was null while resolving index "
897 "weight-at-age.");
898 }
899
900 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
901 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet =
902 population->fleets[fleet_];
903 std::map<std::string, fims::Vector<Type>> &fdq_ =
904 this->GetFleetDerivedQuantities(fleet->GetId());
905
907
908 fdq_["index_weight_at_age"][i_age_year] =
909 fdq_["index_numbers_at_age"][i_age_year] * mean_weight_at_age;
910 }
911 }
912
918 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
919 std::map<std::string, fims::Vector<Type>> &fdq_ =
920 this->GetFleetDerivedQuantities((*fit).second->GetId());
921
922 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
923 for (size_t y = 0; y < fleet->n_years; y++) {
924 Type sum = static_cast<Type>(0.0);
925 Type sum_obs = static_cast<Type>(0.0);
926 // robust_add is a small value to add to expected composition
927 // proportions at age to stabilize likelihood calculations
928 // when the expected proportions are close to zero.
929 // Type robust_add = static_cast<Type>(0.0); // zeroed out before
930 // testing 0.0001; sum robust is used to calculate the total sum of
931 // robust additions to ensure that proportions sum to 1. Type robust_sum
932 // = static_cast<Type>(1.0);
933
934 for (size_t a = 0; a < fleet->n_ages; a++) {
935 size_t i_age_year = y * fleet->n_ages + a;
936 // Here we have a check to determine if the age comp
937 // should be calculated from the retained catch or
938 // the total population. These values are slightly different.
939 // In the future this will have more impact as we implement
940 // timing rather than everything occurring at the start of
941 // the year.
942 if (fleet->fleet_observed_catch_data_id_m == -999) {
943 fdq_["agecomp_expected"][i_age_year] =
944 fdq_["index_numbers_at_age"][i_age_year];
945 } else {
946 fdq_["agecomp_expected"][i_age_year] =
947 fdq_["catch_numbers_at_age"][i_age_year];
948 }
949 sum += fdq_["agecomp_expected"][i_age_year];
950 // robust_sum -= robust_add;
951
952 // This sums over the observed age composition data so that
953 // the expected age composition can be rescaled to match the
954 // total number observed. The check for na values should not
955 // be needed as individual years should not have missing data.
956 // This is need to be re-explored if/when we modify FIMS to
957 // allow for composition bins that do not match the population
958 // bins.
959 if (fleet->fleet_observed_agecomp_data_id_m != -999) {
960 if (fleet->observed_agecomp_data->at(i_age_year) !=
961 fleet->observed_agecomp_data->na_value) {
962 sum_obs += fleet->observed_agecomp_data->at(i_age_year);
963 }
964 }
965 }
966 for (size_t a = 0; a < fleet->n_ages; a++) {
967 size_t i_age_year = y * fleet->n_ages + a;
968 fdq_["agecomp_proportion"][i_age_year] =
969 fdq_["agecomp_expected"][i_age_year] / sum;
970 // robust_add + robust_sum * this->agecomp_expected[i_age_year] / sum;
971
972 if (fleet->fleet_observed_agecomp_data_id_m != -999) {
973 fdq_["agecomp_expected"][i_age_year] =
974 fdq_["agecomp_proportion"][i_age_year] * sum_obs;
975 }
976 }
977 }
978 }
979 }
980
981 // --- Growth-derived WAA helpers ---
982 //
983 // These helpers compute and cache fleet-level and population-level
984 // weight-at-age values that use growth-derived age-to-length conversion rows
985 // when available.
986
1007 const std::shared_ptr<fims_popdy::Fleet<Type>> &fleet,
1009 Type mean_weight = static_cast<Type>(0.0);
1010 for (size_t l = 0; l < fleet->n_lengths; ++l) {
1011 mean_weight +=
1013 growth_observation->EvaluateWeightAtLength(fleet->lengths[l]);
1014 }
1015 return mean_weight;
1016 }
1017
1033 const std::shared_ptr<fims_popdy::Fleet<Type>> &fleet, size_t year,
1035 if (age_to_length_conversion_derived == nullptr ||
1036 !age_to_length_conversion_derived->IsActive()) {
1037 throw std::runtime_error(
1038 "Growth-derived age-to-length conversion was unavailable while "
1039 "building fleet age-to-length probabilities.");
1040 }
1041
1042 if (!age_to_length_conversion_derived->BuildAgeToLengthConversionRow(
1044 std::stringstream ss;
1045 ss << "Failed to build growth-derived age-to-length conversion row for "
1046 "fleet id "
1047 << fleet->GetId() << ", year " << year << ", age " << age << ".";
1048 FIMS_ERROR_LOG(ss.str());
1049 throw std::runtime_error(ss.str());
1050 }
1051 }
1052
1083
1094 for (size_t p = 0; p < this->populations.size(); ++p) {
1096 this->populations[p]);
1097 }
1098 }
1099
1109 for (size_t p = 0; p < this->populations.size(); ++p) {
1110 std::shared_ptr<fims_popdy::Population<Type>> &population =
1111 this->populations[p];
1112
1113 if (population == nullptr || population->growth == nullptr) {
1114 continue;
1115 }
1116
1117 std::shared_ptr<fims_popdy::GrowthDerivedObservationBase<Type>>
1118 growth_observation = std::dynamic_pointer_cast<
1120 population->growth);
1121
1122 if (growth_observation != nullptr) {
1124 }
1125 }
1126 }
1127
1144 const std::shared_ptr<fims_popdy::Fleet<Type>> &fleet, size_t year,
1145 size_t age) {
1146 if (fleet == nullptr) {
1147 throw std::runtime_error(
1148 "Fleet pointer was null while resolving growth-derived fleet mean "
1149 "weight-at-age.");
1150 }
1151
1152 std::shared_ptr<fims_popdy::AgeToLengthConversionDerived<Type>>
1153 age_to_length_conversion_derived_model = std::dynamic_pointer_cast<
1155 fleet->age_to_length_conversion_model);
1156
1161 }
1162
1163 std::stringstream ss;
1164 ss << "Failed to resolve growth-derived fleet mean weight-at-age for fleet "
1165 "id "
1166 << fleet->GetId() << ", year " << year << ", age " << age << ".";
1167 FIMS_ERROR_LOG(ss.str());
1168 throw std::runtime_error(ss.str());
1169 }
1170
1186 const std::shared_ptr<fims_popdy::Population<Type>> &population,
1189 size_t year, size_t age) {
1190 if (population == nullptr || growth_observation == nullptr) {
1191 throw std::runtime_error(
1192 "Population or growth-derived observation pointer was null while "
1193 "resolving biological mean weight-at-age.");
1194 }
1195
1196 const GrowthProducts<Type> *gp =
1197 growth_observation->TryGetPreparedGrowthProducts();
1198
1199 if (gp == nullptr) {
1200 growth_observation->PrepareGrowthProducts();
1201 gp = growth_observation->TryGetPreparedGrowthProducts();
1202 }
1203
1204 if (gp == nullptr) {
1205 throw std::runtime_error(
1206 "Growth products were unavailable while resolving biological mean "
1207 "weight-at-age.");
1208 }
1209
1210 if (gp->n_years == 0 || gp->n_ages == 0) {
1211 throw std::runtime_error(
1212 "Prepared growth products were empty while resolving biological mean "
1213 "weight-at-age.");
1214 }
1215
1216 if (gp->n_sexes != 1) {
1217 throw std::runtime_error(
1218 "Biological mean weight-at-age currently requires one prepared sex.");
1219 }
1220
1221 const size_t y = (std::min)(year, gp->n_years - 1);
1222 const size_t a = (std::min)(age, gp->n_ages - 1);
1223 return gp->MeanWAA(y, a, 0);
1224 }
1225
1242 const std::shared_ptr<fims_popdy::Population<Type>> &population,
1243 size_t year, size_t age) {
1244 if (population == nullptr) {
1245 throw std::runtime_error(
1246 "Population pointer was null while resolving population mean "
1247 "weight-at-age.");
1248 }
1249
1250 if (population->growth == nullptr) {
1251 throw std::runtime_error(
1252 "Population growth pointer was null while resolving population mean "
1253 "weight-at-age.");
1254 }
1255
1256 std::shared_ptr<fims_popdy::GrowthDerivedObservationBase<Type>>
1257 growth_observation = std::dynamic_pointer_cast<
1259
1260 if (growth_observation == nullptr) {
1261 return population->growth->evaluate(year, population->ages[age]);
1262 }
1263
1266 }
1267
1273 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1274 std::map<std::string, fims::Vector<Type>> &fdq_ =
1275 this->GetFleetDerivedQuantities((*fit).second->GetId());
1276
1277 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1278
1279 if (!fleet->requires_age_length_mapping || fleet->n_lengths == 0) {
1280 continue;
1281 }
1282
1283 if (fleet->age_to_length_conversion_model == nullptr ||
1284 !fleet->age_to_length_conversion_model->IsActive()) {
1285 std::stringstream ss;
1286 ss << "Fleet id " << fleet->GetId()
1287 << "no usable age-to-length conversion path";
1288 FIMS_ERROR_LOG(ss.str());
1289 throw std::runtime_error(ss.str());
1290 }
1291
1292 for (size_t y = 0; y < fleet->n_years; y++) {
1293 Type sum = static_cast<Type>(0.0);
1294 Type sum_obs = static_cast<Type>(0.0);
1295 // robust_add is a small value to add to expected composition
1296 // proportions at age to stabilize likelihood calculations
1297 // when the expected proportions are close to zero.
1298 // Type robust_add = static_cast<Type>(0.0); // 0.0001; zeroed out
1299 // before testing sum robust is used to calculate the total sum of
1300 // robust additions to ensure that proportions sum to 1. Type
1301 // robust_sum = static_cast<Type>(1.0);
1302 for (size_t a = 0; a < fleet->n_ages; a++) {
1303 size_t i_age_year = y * fleet->n_ages + a;
1305 if (!fleet->age_to_length_conversion_model
1306 ->BuildAgeToLengthConversionRow(
1308 std::stringstream ss;
1309 ss << "Failed to build age-to-length conversion row for fleet id "
1310 << fleet->GetId() << ", year " << y << ", age " << a << ".";
1311 FIMS_ERROR_LOG(ss.str());
1312 throw std::runtime_error(ss.str());
1313 }
1314
1315 for (size_t l = 0; l < fleet->n_lengths; l++) {
1316 size_t i_length_year = y * fleet->n_lengths + l;
1318 fdq_["lengthcomp_expected"][i_length_year] +=
1319 fdq_["agecomp_expected"][i_age_year] * age_to_length_prob;
1320
1321 fdq_["catch_numbers_at_length"][i_length_year] +=
1322 fdq_["catch_numbers_at_age"][i_age_year] * age_to_length_prob;
1323
1324 fdq_["index_numbers_at_length"][i_length_year] +=
1325 fdq_["index_numbers_at_age"][i_age_year] * age_to_length_prob;
1326 }
1327 }
1328
1329 for (size_t l = 0; l < fleet->n_lengths; l++) {
1330 size_t i_length_year = y * fleet->n_lengths + l;
1331 sum += fdq_["lengthcomp_expected"][i_length_year];
1332 // robust_sum -= robust_add;
1333
1334 if (fleet->fleet_observed_lengthcomp_data_id_m != -999) {
1335 if (fleet->observed_lengthcomp_data->at(i_length_year) !=
1336 fleet->observed_lengthcomp_data->na_value) {
1337 sum_obs += fleet->observed_lengthcomp_data->at(i_length_year);
1338 }
1339 }
1340 }
1341 for (size_t l = 0; l < fleet->n_lengths; l++) {
1342 size_t i_length_year = y * fleet->n_lengths + l;
1343 fdq_["lengthcomp_proportion"][i_length_year] =
1344 fdq_["lengthcomp_expected"][i_length_year] / sum;
1345 // robust_add + robust_sum *
1346 // this->lengthcomp_expected[i_length_year] / sum;
1347 if (fleet->fleet_observed_lengthcomp_data_id_m != -999) {
1348 fdq_["lengthcomp_expected"][i_length_year] =
1349 fdq_["lengthcomp_proportion"][i_length_year] * sum_obs;
1350 }
1351 }
1352 }
1353 }
1354 }
1355
1361 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1362 std::map<std::string, fims::Vector<Type>> &fdq_ =
1363 this->GetFleetDerivedQuantities((*fit).second->GetId());
1364 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1365
1366 for (size_t i = 0; i < fdq_["index_numbers"].size(); i++) {
1367 if (fleet->observed_index_units == "number") {
1368 fdq_["index_expected"][i] = fdq_["index_numbers"][i];
1369 } else {
1370 fdq_["index_expected"][i] = fdq_["index_weight"][i];
1371 }
1372 fdq_["log_index_expected"][i] = log(fdq_["index_expected"][i]);
1373 }
1374 }
1375 }
1376
1382 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1383 std::map<std::string, fims::Vector<Type>> &fdq_ =
1384 this->GetFleetDerivedQuantities((*fit).second->GetId());
1385 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1386
1387 for (size_t i = 0; i < fdq_["catch_weight"].size(); i++) {
1388 if (fleet->observed_catch_units == "number") {
1389 fdq_["catch_expected"][i] = fdq_["catch_numbers"][i];
1390 } else {
1391 fdq_["catch_expected"][i] = fdq_["catch_weight"][i];
1392 }
1393 fdq_["log_catch_expected"][i] = log(fdq_["catch_expected"][i]);
1394 }
1395 }
1396 }
1397
1398 virtual void Evaluate() {
1399 /*
1400 Sets derived vectors to zero
1401 Performs parameters transformations
1402 Sets recruitment deviations to mean 0.
1403 */
1404 Prepare();
1407 /*
1408 start at year=0, age=0;
1409 here year 0 is the estimated initial population structure and age 0 are
1410 recruits loops start at zero with if statements inside to specify unique
1411 code for initial structure and recruitment 0 loops. Could also have started
1412 loops at 1 with initial structure and recruitment setup outside the loops.
1413
1414 year loop is extended to <= n_years because SSB is calculated as the start
1415 of the year value and by extending one extra year we get estimates of the
1416 population structure at the end of the final year. An alternative approach
1417 would be to keep initial numbers at age in it's own vector and each year to
1418 include the population structure at the end of the year. This is likely a
1419 null point given that we are planning to modify to an event/stanza based
1420 structure in later milestones which will eliminate this confusion by
1421 explicitly referencing the exact date (or period of averaging) at which any
1422 calculation or output is being made.
1423 */
1424 for (size_t p = 0; p < this->populations.size(); p++) {
1425 std::shared_ptr<fims_popdy::Population<Type>> &population =
1426 this->populations[p];
1427 std::map<std::string, fims::Vector<Type>> &pdq_ =
1428 this->GetPopulationDerivedQuantities(population->GetId());
1429 // CAAPopulationProxy<Type>& population = this->populations_proxies[p];
1430
1431 for (size_t y = 0; y <= population->n_years; y++) {
1432 for (size_t a = 0; a < population->n_ages; a++) {
1433 /*
1434 index naming defines the dimensional folding structure
1435 i.e. i_age_year is referencing folding over years and ages.
1436 */
1437 size_t i_age_year = y * population->n_ages + a;
1438 /*
1439 Mortality rates are not estimated in the final year which is
1440 used to show expected population structure at the end of the model
1441 period. This is because biomass in year i represents biomass at the
1442 start of the year. Should we add complexity to track more values such
1443 as start, mid, and end biomass in all years where, start biomass=end
1444 biomass of the previous year? Referenced above, this is probably not
1445 worth exploring as later milestone changes will eliminate this
1446 confusion.
1447 */
1448 if (y < population->n_years) {
1449 /*
1450 First thing we need is total mortality aggregated across all fleets
1451 to inform the subsequent catch and change in numbers at age
1452 calculations. This is only calculated for years < n_years as these
1453 are the model estimated years with data. The year loop extends to
1454 y=n_years so that population numbers at age and SSB can be
1455 calculated at the end of the last year of the model
1456 */
1458 }
1460 /* if statements needed because some quantities are only needed
1461 for the first year and/or age, so these steps are included here.
1462 */
1463 if (y == 0) {
1464 // Initial numbers at age is a user input or estimated parameter
1465 // vector.
1467
1468 if (a == 0) {
1469 /*
1470 Expected recruitment in year 0 is numbers at age 0 in year 0.
1471 */
1472 pdq_["expected_recruitment"][y] =
1473 pdq_["numbers_at_age"][i_age_year];
1474 pdq_["unfished_numbers_at_age"][i_age_year] =
1475 fims_math::exp(population->recruitment->log_rzero[0]);
1476 } else {
1478 }
1479
1480 } else {
1481 if (a == 0) {
1482 // Set the nrecruits for age a=0 year y (use pointers instead of
1483 // functional returns) assuming fecundity = 1 and 50:50 sex ratio
1485 pdq_["unfished_numbers_at_age"][i_age_year] =
1486 fims_math::exp(population->recruitment->log_rzero[0]);
1487 } else {
1488 size_t i_agem1_yearm1 = (y - 1) * population->n_ages + (a - 1);
1491 a);
1492 }
1493 }
1494
1495 /*
1496 Fished and unfished biomass vectors are summing biomass at
1497 age across ages.
1498 */
1499
1501
1503
1504 /*
1505 Fished and unfished spawning biomass vectors are summing biomass at
1506 age across ages to allow calculation of recruitment in the next
1507 year.
1508 */
1509
1511
1513
1514 /*
1515 Here composition, total catch, and index values are calculated for all
1516 years with reference data. They are not calculated for y=n_years as
1517 there is this is just to get final population structure at the end of
1518 the terminal year.
1519 */
1520 if (y < population->n_years) {
1524
1528 }
1529 }
1530 /* Calculate spawning biomass depletion ratio */
1532 }
1533 }
1538 }
1543 virtual void Report() {
1544 int n_fleets = this->fleets.size();
1545 int n_pops = this->populations.size();
1546#ifdef TMB_MODEL
1547 if (this->do_reporting == true) {
1549 report_vectors.clear();
1550 // std::shared_ptr<UncertaintyReportInfoMap>
1551 // population_uncertainty_report_info_map =
1552 // this->GetPopulationUncertaintyReportInfoMap();
1553
1554 // std::shared_ptr<UncertaintyReportInfoMap>
1555 // fleet_uncertainty_report_info_map =
1556 // this->GetFleetUncertaintyReportInfoMap();
1557
1558 // initialize population vectors
1577
1578 // initialize fleet vectors
1601
1602 // initiate population index for structuring report out objects
1603 int pop_idx = 0;
1604 for (size_t p = 0; p < this->populations.size(); p++) {
1605 std::map<std::string, fims::Vector<Type>> &derived_quantities =
1607 biomass_p(pop_idx) = derived_quantities["biomass"].to_tmb();
1609 derived_quantities["expected_recruitment"].to_tmb();
1610 mortality_F_p(pop_idx) = derived_quantities["mortality_F"].to_tmb();
1611 mortality_M_p(pop_idx) = derived_quantities["mortality_M"].to_tmb();
1612 mortality_Z_p(pop_idx) = derived_quantities["mortality_Z"].to_tmb();
1614 derived_quantities["numbers_at_age"].to_tmb();
1616 derived_quantities["proportion_mature_at_age"].to_tmb();
1618 derived_quantities["spawning_biomass"].to_tmb();
1620 derived_quantities["sum_selectivity"].to_tmb();
1622 derived_quantities["total_catch_numbers"].to_tmb();
1624 derived_quantities["total_catch_weight"].to_tmb();
1626 derived_quantities["unfished_biomass"].to_tmb();
1628 derived_quantities["unfished_numbers_at_age"].to_tmb();
1630 derived_quantities["unfished_spawning_biomass"].to_tmb();
1632 this->populations[pop_idx]->spawning_biomass_ratio.to_tmb();
1633
1635 growth_observation = std::dynamic_pointer_cast<
1637 this->populations[p]->growth)) {
1638 const auto *gp = growth_observation->TryGetPreparedGrowthProducts();
1639 if (gp == nullptr) {
1640 throw std::runtime_error(
1641 "Growth products were not prepared before report generation.");
1642 }
1643
1644 const std::size_t n = gp->Size();
1645 vector<Type> mean_laa(n);
1646 vector<Type> sd_laa(n);
1647 vector<Type> mean_waa(n);
1648 for (std::size_t i = 0; i < n; ++i) {
1649 mean_laa(i) = gp->mean_LAA[i];
1650 sd_laa(i) = gp->sd_LAA[i];
1651 const std::size_t year = i / this->populations[p]->n_ages;
1652 const std::size_t age = i % this->populations[p]->n_ages;
1653 mean_waa(i) =
1654 PopulationMeanWeightAA(this->populations[p], year, age);
1655 }
1659 }
1660
1661 pop_idx += 1;
1662 }
1663
1664 // initiate fleet index for structuring report out objects
1665 int fleet_idx = 0;
1667 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1668 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1669 std::map<std::string, fims::Vector<Type>> &derived_quantities =
1670 this->GetFleetDerivedQuantities(fleet->GetId());
1671
1673 derived_quantities["agecomp_expected"].to_tmb();
1675 derived_quantities["agecomp_proportion"].to_tmb();
1680 if (isDouble<Type>::value) {
1682 age_to_length_conversion_derived_used[0] = static_cast<Type>(0.0);
1683
1684 std::shared_ptr<fims_popdy::AgeToLengthConversionDerived<Type>>
1686 std::dynamic_pointer_cast<
1688 fleet->age_to_length_conversion_model);
1689
1693 age_to_length_conversion_derived_used[0] = static_cast<Type>(1.0);
1694 growth_derived_mean_WAA.resize(fleet->n_years * fleet->n_ages);
1695
1696 for (size_t y = 0; y < fleet->n_years; ++y) {
1697 for (size_t a = 0; a < fleet->n_ages; ++a) {
1698 const size_t i_age_year = y * fleet->n_ages + a;
1699
1700 if (this->report_age_to_length_conversion_derived_tensor) {
1701 if (age_to_length_conversion_derived.size() == 0) {
1703 fleet->n_years * fleet->n_ages * fleet->n_lengths);
1704 }
1705
1710
1714 ->growth_observation_,
1716
1717 for (size_t l = 0; l < fleet->n_lengths; ++l) {
1718 const size_t i_length_age_year =
1719 y * (fleet->n_ages * fleet->n_lengths) +
1720 a * fleet->n_lengths + l;
1723 }
1724 } else {
1727 }
1728 }
1729 }
1730 }
1731 }
1732
1740 fleet->age_to_length_conversion.to_tmb();
1741 }
1743 derived_quantities["index_expected"].to_tmb();
1745 derived_quantities["index_numbers"].to_tmb();
1747 derived_quantities["index_numbers_at_age"].to_tmb();
1749 derived_quantities["index_numbers_at_length"].to_tmb();
1750 index_weight_f(fleet_idx) = derived_quantities["index_weight"].to_tmb();
1752 derived_quantities["index_weight_at_age"].to_tmb();
1754 derived_quantities["catch_expected"].to_tmb();
1756 derived_quantities["catch_numbers"].to_tmb();
1758 derived_quantities["catch_numbers_at_age"].to_tmb();
1760 derived_quantities["catch_numbers_at_length"].to_tmb();
1761 catch_weight_f(fleet_idx) = derived_quantities["catch_weight"].to_tmb();
1763 derived_quantities["catch_weight_at_age"].to_tmb();
1764 // length_comp_expected_f(fleet_idx) =
1765 // derived_quantities["length_comp_expected"];
1766 // length_comp_proportion_f(fleet_idx) =
1767 // derived_quantities["length_comp_proportion"];
1769 derived_quantities["lengthcomp_expected"].to_tmb();
1771 derived_quantities["lengthcomp_proportion"].to_tmb();
1773 derived_quantities["log_index_expected"].to_tmb();
1775 derived_quantities["log_catch_expected"].to_tmb();
1776 fleet_idx += 1;
1777 }
1778
1779 vector<Type> biomass = ADREPORTvector(biomass_p);
1780 vector<Type> expected_recruitment =
1782 vector<Type> mortality_F = ADREPORTvector(mortality_F_p);
1783 vector<Type> mortality_M = ADREPORTvector(mortality_M_p);
1784 vector<Type> mortality_Z = ADREPORTvector(mortality_Z_p);
1785 vector<Type> numbers_at_age = ADREPORTvector(numbers_at_age_p);
1786 vector<Type> proportion_mature_at_age =
1788 vector<Type> spawning_biomass = ADREPORTvector(spawning_biomass_p);
1789 vector<Type> sum_selectivity = ADREPORTvector(sum_selectivity_p);
1790 vector<Type> total_catch_numbers = ADREPORTvector(total_catch_numbers_p);
1791 vector<Type> total_catch_weight = ADREPORTvector(total_catch_weight_p);
1792 vector<Type> unfished_biomass = ADREPORTvector(unfished_biomass_p);
1793 vector<Type> unfished_numbers_at_age =
1795 vector<Type> unfished_spawning_biomass =
1797 vector<Type> spawning_biomass_ratio =
1799
1800 vector<Type> agecomp_expected = ADREPORTvector(agecomp_expected_f);
1801 vector<Type> agecomp_proportion = ADREPORTvector(agecomp_proportion_f);
1802 vector<Type> index_expected = ADREPORTvector(index_expected_f);
1803 vector<Type> index_numbers = ADREPORTvector(index_numbers_f);
1804 vector<Type> index_numbers_at_age =
1806 vector<Type> index_numbers_at_length =
1808 vector<Type> index_weight = ADREPORTvector(index_weight_f);
1809 vector<Type> index_weight_at_age = ADREPORTvector(index_weight_at_age_f);
1810 vector<Type> catch_expected = ADREPORTvector(catch_expected_f);
1811 vector<Type> catch_numbers = ADREPORTvector(catch_numbers_f);
1812 vector<Type> catch_numbers_at_age =
1814 vector<Type> catch_numbers_at_length =
1816 vector<Type> catch_weight = ADREPORTvector(catch_weight_f);
1817 vector<Type> catch_weight_at_age = ADREPORTvector(catch_weight_at_age_f);
1818 // vector<Type> length_comp_expected =
1819 // ADREPORTvector(length_comp_expected_f); vector<Type>
1820 // length_comp_proportion = ADREPORTvector(length_comp_proportion_f);
1821 vector<Type> lengthcomp_expected = ADREPORTvector(lengthcomp_expected_f);
1822 vector<Type> lengthcomp_proportion =
1824 vector<Type> log_index_expected = ADREPORTvector(log_index_expected_f);
1825 vector<Type> log_catch_expected = ADREPORTvector(log_catch_expected_f);
1826 // populations
1827 // report
1828 FIMS_REPORT_F_("biomass", biomass_p, this->of);
1829 FIMS_REPORT_F_("expected_recruitment", expected_recruitment_p, this->of);
1830 FIMS_REPORT_F_("mortality_F", mortality_F_p, this->of);
1831 FIMS_REPORT_F_("mortality_M", mortality_M_p, this->of);
1832 FIMS_REPORT_F_("mortality_Z", mortality_Z_p, this->of);
1833 FIMS_REPORT_F_("numbers_at_age", numbers_at_age_p, this->of);
1834 FIMS_REPORT_F_("proportion_mature_at_age", proportion_mature_at_age_p,
1835 this->of);
1836 FIMS_REPORT_F_("spawning_biomass", spawning_biomass_p, this->of);
1837 FIMS_REPORT_F_("sum_selectivity", sum_selectivity_p, this->of);
1838 FIMS_REPORT_F_("total_catch_numbers", total_catch_numbers_p, this->of);
1839 FIMS_REPORT_F_("total_catch_weight", total_catch_weight_p, this->of);
1840 FIMS_REPORT_F_("unfished_biomass", unfished_biomass_p, this->of);
1841 FIMS_REPORT_F_("unfished_numbers_at_age", unfished_numbers_at_age_p,
1842 this->of);
1843 FIMS_REPORT_F_("unfished_spawning_biomass", unfished_spawning_biomass_p,
1844 this->of);
1845 FIMS_REPORT_F_("spawning_biomass_ratio", spawning_biomass_ratio_p,
1846 this->of);
1847 FIMS_REPORT_F_("growth_mean_LAA", growth_mean_LAA_p, this->of);
1848 FIMS_REPORT_F_("growth_sd_LAA", growth_sd_LAA_p, this->of);
1849 FIMS_REPORT_F_("growth_mean_WAA", growth_mean_WAA_p, this->of);
1850
1851 // adreport
1852 ADREPORT_F(biomass, this->of);
1853 ADREPORT_F(expected_recruitment, this->of);
1854 ADREPORT_F(mortality_F, this->of);
1855 ADREPORT_F(mortality_M, this->of);
1856 ADREPORT_F(mortality_Z, this->of);
1857 ADREPORT_F(numbers_at_age, this->of);
1858 ADREPORT_F(proportion_mature_at_age, this->of);
1859 ADREPORT_F(spawning_biomass, this->of);
1860 ADREPORT_F(sum_selectivity, this->of);
1861 ADREPORT_F(total_catch_numbers, this->of);
1862 ADREPORT_F(total_catch_weight, this->of);
1863 ADREPORT_F(unfished_biomass, this->of);
1864 ADREPORT_F(unfished_numbers_at_age, this->of);
1865 ADREPORT_F(unfished_spawning_biomass, this->of);
1866 ADREPORT_F(spawning_biomass_ratio, this->of);
1867
1868 // fleets
1869 // report
1870 FIMS_REPORT_F_("agecomp_expected", agecomp_expected_f, this->of);
1871 FIMS_REPORT_F_("agecomp_proportion", agecomp_proportion_f, this->of);
1872 FIMS_REPORT_F_("age_to_length_conversion", age_to_length_conversion_f,
1873 this->of);
1874 FIMS_REPORT_F_("age_to_length_conversion_derived",
1875 age_to_length_conversion_derived_f, this->of);
1876 FIMS_REPORT_F_("age_to_length_conversion_derived_used",
1877 age_to_length_conversion_derived_used_f, this->of);
1878 FIMS_REPORT_F_("growth_derived_mean_WAA", growth_derived_mean_WAA_f,
1879 this->of);
1880 FIMS_REPORT_F_("index_expected", index_expected_f, this->of);
1881 FIMS_REPORT_F_("index_numbers", index_numbers_f, this->of);
1882 FIMS_REPORT_F_("index_numbers_at_age", index_numbers_at_age_f, this->of);
1883 FIMS_REPORT_F_("index_numbers_at_length", index_numbers_at_length_f,
1884 this->of);
1885 FIMS_REPORT_F_("index_weight", index_weight_f, this->of);
1886 FIMS_REPORT_F_("index_weight_at_age", index_weight_at_age_f, this->of);
1887 FIMS_REPORT_F_("catch_expected", catch_expected_f, this->of);
1888 FIMS_REPORT_F_("catch_numbers", catch_numbers_f, this->of);
1889 FIMS_REPORT_F_("catch_numbers_at_age", catch_numbers_at_age_f, this->of);
1890 FIMS_REPORT_F_("catch_numbers_at_length", catch_numbers_at_length_f,
1891 this->of);
1892 FIMS_REPORT_F_("catch_weight", catch_weight_f, this->of);
1893 FIMS_REPORT_F_("catch_weight_at_age", catch_weight_at_age_f, this->of);
1894 FIMS_REPORT_F_("lengthcomp_expected", lengthcomp_expected_f, this->of);
1895 FIMS_REPORT_F_("lengthcomp_proportion", lengthcomp_proportion_f,
1896 this->of);
1897 FIMS_REPORT_F_("log_index_expected", log_index_expected_f, this->of);
1898 FIMS_REPORT_F_("log_catch_expected", log_catch_expected_f, this->of);
1899 // adreport
1900 ADREPORT_F(agecomp_expected, this->of);
1901 ADREPORT_F(agecomp_proportion, this->of);
1902 ADREPORT_F(index_expected, this->of);
1903 ADREPORT_F(index_numbers, this->of);
1904 ADREPORT_F(index_numbers_at_age, this->of);
1905 ADREPORT_F(index_numbers_at_length, this->of);
1906 ADREPORT_F(index_weight, this->of);
1907 ADREPORT_F(index_weight_at_age, this->of);
1908 ADREPORT_F(catch_expected, this->of);
1909 ADREPORT_F(catch_numbers, this->of);
1910 ADREPORT_F(catch_numbers_at_age, this->of);
1911 ADREPORT_F(catch_numbers_at_length, this->of);
1912 ADREPORT_F(catch_weight, this->of);
1913 ADREPORT_F(catch_weight_at_age, this->of);
1914 ADREPORT_F(lengthcomp_expected, this->of);
1915 ADREPORT_F(lengthcomp_proportion, this->of);
1916 ADREPORT_F(log_index_expected, this->of);
1917 ADREPORT_F(log_catch_expected, this->of);
1918 std::stringstream var_name;
1919 typename std::map<std::string, fims::Vector<fims::Vector<Type>>>::iterator
1920 rvit;
1921 for (rvit = report_vectors.begin(); rvit != report_vectors.end();
1922 ++rvit) {
1923 auto &x = rvit->second;
1924
1925 int outer_dim = x.size();
1926 int dim = 0;
1927 for (int i = 0; i < outer_dim; i++) {
1928 dim += x[i].size();
1929 }
1930 vector<Type> res(dim);
1931 int idx = 0;
1932 for (int i = 0; i < outer_dim; i++) {
1933 int inner_dim = x[i].size();
1934 for (int j = 0; j < inner_dim; j++) {
1935 res(idx) = x[i][j];
1936 idx += 1;
1937 }
1938 }
1939 this->of->reportvector.push(res, rvit->first.c_str());
1940 }
1941 }
1942#endif
1943 }
1944};
1945
1946} // namespace fims_popdy
1947
1948#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:551
void PreparePopulationGrowthProducts()
Prepares cached population growth products for all populations whose growth objects expose the growth...
Definition catch_at_age.hpp:1108
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:1380
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:582
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:1093
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:444
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:744
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:1004
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:1185
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:704
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:1143
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:889
void evaluate_age_comp()
Definition catch_at_age.hpp:916
void evaluate_length_comp()
Definition catch_at_age.hpp:1271
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:495
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:1069
virtual void Evaluate()
Evaluate the model.
Definition catch_at_age.hpp:1398
std::string name_m
The name of the model.
Definition catch_at_age.hpp:63
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:523
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:823
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:468
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
void CalculateMaturityAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t i_age_year, size_t age)
Calculates maturity at age, in proportion, for a population.
Definition catch_at_age.hpp:679
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 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:637
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:785
virtual void Report()
Definition catch_at_age.hpp:1543
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:1241
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:407
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:854
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:1030
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:1359
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:79
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