FIMS  v0.9.3
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 <set>
12#include <regex>
13
15
16/* Dictionary block for shared parameter snippet documentations.
17 * Referenced in function docs via @snippet{doc} this snippet_id.
18 [param_population]
19 @param population Shared pointer to the population object.
20 [param_population]
21 [param_i_age_year]
22 @param i_age_year Dimension folded index for age and year.
23 [param_i_age_year]
24 [param_year]
25 @param year Year index.
26 [param_year]
27 [param_age]
28 @param age Age index.
29 [param_age]
30 [param_i_agem1_yearm1]
31 @param i_agem1_yearm1 Dimension folded index for age-1 and year-1.
32 [param_i_agem1_yearm1]
33 [param_i_dev]
34 @param i_dev Index to log_recruit_dev of vector length n_years-1.
35 [param_i_dev]
36 [param_other]
37 @param other The other CatchAtAge object to copy from.
38 [param_other]
39 */
40
41namespace fims_popdy {
42
43template <typename Type>
53class CatchAtAge : public FisheryModelBase<Type> {
54 public:
59 std::string name_m;
60
65 typedef typename std::map<std::string, fims::Vector<Type>>::iterator
67
72 typedef typename std::map<uint32_t,
73 std::map<std::string, fims::Vector<Type>>>::iterator
75
79 typedef
80 typename std::map<uint32_t,
81 std::map<std::string, fims::Vector<size_t>>>::iterator
87 typedef typename std::map<uint32_t,
88 std::map<std::string, fims::Vector<Type>>>::iterator
90
95 typedef
96 typename std::map<uint32_t,
97 std::map<std::string, fims::Vector<size_t>>>::iterator
99
104 typedef typename std::map<uint32_t,
105 std::shared_ptr<fims_popdy::Fleet<Type>>>::iterator
111 typedef
112 typename std::map<std::string, fims::Vector<Type>>::iterator dq_iterator;
118 std::map<std::string, fims::Vector<fims::Vector<Type>>> report_vectors;
119
120 public:
121 std::vector<Type> ages;
127 std::stringstream ss;
128 ss << "caa_" << this->GetId() << "_";
129 this->name_m = ss.str();
130 this->model_type_m = "caa";
131 }
132
142
147 virtual ~CatchAtAge() {}
148
153 virtual void Initialize() {
154 for (size_t p = 0; p < this->populations.size(); p++) {
155 if (this->populations[p]->proportion_female.size() == 0) {
156 this->populations[p]->proportion_female.resize(1);
157 this->populations[p]->proportion_female[0] = static_cast<Type>(0.5);
158 }
159
160 this->populations[p]->M.resize(this->populations[p]->n_years *
161 this->populations[p]->n_ages);
162
163 this->populations[p]->f_multiplier.resize(this->populations[p]->n_years);
164
165 this->populations[p]->spawning_biomass_ratio.resize(
166 (this->populations[p]->n_years + 1));
167 }
168
169 for (fleet_iterator fit = this->fleets.begin(); fit != this->fleets.end();
170 ++fit) {
171 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
172
173 if (fleet->log_q.size() == 0) {
174 fleet->log_q.resize(1);
175 fleet->log_q[0] = static_cast<Type>(0.0);
176 }
177 fleet->q.resize(fleet->log_q.size());
178 fleet->Fmort.resize(fleet->n_years);
179 }
180 }
181
186 virtual void Prepare() {
187 for (size_t p = 0; p < this->populations.size(); p++) {
188 std::shared_ptr<fims_popdy::Population<Type>> &population =
189 this->populations[p];
190
191 auto &derived_quantities =
192 this->GetPopulationDerivedQuantities(population->GetId());
193
194 // Reset the derived quantities for the population
195 for (auto &kv : derived_quantities) {
196 this->ResetVector(kv.second);
197 }
198
199 // Transformation Section
200 for (size_t age = 0; age < population->n_ages; age++) {
201 for (size_t year = 0; year < population->n_years; year++) {
202 size_t i_age_year = age * population->n_years + year;
204 fims_math::exp(population->log_M[i_age_year]);
205 }
206 }
207
208 for (size_t year = 0; year < population->n_years; year++) {
209 population->f_multiplier[year] =
210 fims_math::exp(population->log_f_multiplier[year]);
211 }
212 }
213
214 for (fleet_iterator fit = this->fleets.begin(); fit != this->fleets.end();
215 ++fit) {
216 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
217 auto &derived_quantities =
218 this->GetFleetDerivedQuantities(fleet->GetId());
219
220 for (auto &kv : derived_quantities) {
221 this->ResetVector(kv.second);
222 }
223
224 // Transformation Section
225 for (size_t i = 0; i < fleet->log_q.size(); i++) {
226 fleet->q[i] = fims_math::exp(fleet->log_q[i]);
227 }
228
229 for (size_t year = 0; year < fleet->n_years; year++) {
230 fleet->Fmort[year] = fims_math::exp(fleet->log_Fmort[year]);
231 }
232 }
233 }
237 void AddPopulation(uint32_t id) { this->population_ids.insert(id); }
238
242 std::set<uint32_t> &GetPopulationIds() { return this->population_ids; }
243
249 std::vector<std::shared_ptr<fims_popdy::Population<Type>>> &GetPopulations() {
250 return this->populations;
251 }
252
267 size_t i_age_year, size_t age) {
268 std::map<std::string, fims::Vector<Type>> &dq_ =
270
271 dq_["numbers_at_age"][i_age_year] =
272 fims_math::exp(population->log_init_naa[age]);
273 }
274
299 size_t i_age_year, size_t i_agem1_yearm1, size_t age) {
300 // using Z from previous age/year
301
302 std::map<std::string, fims::Vector<Type>> &dq_ =
304
305 dq_["numbers_at_age"][i_age_year] =
306 dq_["numbers_at_age"][i_agem1_yearm1] *
307 (fims_math::exp(-dq_["mortality_Z"][i_agem1_yearm1]));
308
309 // Plus group calculation
310 if (age == (population->n_ages - 1)) {
311 dq_["numbers_at_age"][i_age_year] =
312 dq_["numbers_at_age"][i_age_year] +
313 dq_["numbers_at_age"][i_agem1_yearm1 + 1] *
314 (fims_math::exp(-dq_["mortality_Z"][i_agem1_yearm1 + 1]));
315 }
316 }
317
342 size_t i_age_year, size_t i_agem1_yearm1, size_t age) {
343 std::map<std::string, fims::Vector<Type>> &dq_ =
345
346 // using M from previous age/year
347 dq_["unfished_numbers_at_age"][i_age_year] =
348 dq_["unfished_numbers_at_age"][i_agem1_yearm1] *
349 (fims_math::exp(-population->M[i_agem1_yearm1]));
350
351 // Plus group calculation
352 if (age == (population->n_ages - 1)) {
353 dq_["unfished_numbers_at_age"][i_age_year] =
354 dq_["unfished_numbers_at_age"][i_age_year] +
355 dq_["unfished_numbers_at_age"][i_agem1_yearm1 + 1] *
356 (fims_math::exp(-population->M[i_agem1_yearm1 + 1]));
357 }
358 }
359
393 size_t i_age_year, size_t year, size_t age) {
394 std::map<std::string, fims::Vector<Type>> &dq_ =
396
397 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
398 // evaluate is a member function of the selectivity class
399 Type s = population->fleets[fleet_]->selectivity->evaluate(
400 population->ages[age], year);
401
402 dq_["mortality_F"][i_age_year] +=
403 population->fleets[fleet_]->Fmort[year] *
404 population->f_multiplier[year] * s;
405
406 dq_["sum_selectivity"][i_age_year] += s;
407 }
408 dq_["mortality_M"][i_age_year] = population->M[i_age_year];
409
410 dq_["mortality_Z"][i_age_year] =
411 population->M[i_age_year] + dq_["mortality_F"][i_age_year];
412 }
413
430 size_t i_age_year, size_t year, size_t age) {
431 std::map<std::string, fims::Vector<Type>> &dq_ =
433
434 dq_["biomass"][year] +=
435 dq_["numbers_at_age"][i_age_year] *
436 population->growth->evaluate(year, population->ages[age]);
437 }
438
455 size_t i_age_year, size_t year, size_t age) {
456 std::map<std::string, fims::Vector<Type>> &dq_ =
458
459 dq_["unfished_biomass"][year] +=
460 dq_["unfished_numbers_at_age"][i_age_year] *
461 population->growth->evaluate(year, population->ages[age]);
462 }
463
482 size_t i_age_year, size_t year, size_t age) {
483 std::map<std::string, fims::Vector<Type>> &dq_ =
485
486 dq_["spawning_biomass"][year] +=
487 population->proportion_female.get_force_scalar(age) *
488 dq_["numbers_at_age"][i_age_year] *
489 dq_["proportion_mature_at_age"][i_age_year] *
490 population->growth->evaluate(year, population->ages[age]);
491 }
492
510 size_t i_age_year, size_t year, size_t age) {
511 std::map<std::string, fims::Vector<Type>> &dq_ =
513
514 dq_["unfished_spawning_biomass"][year] +=
515 population->proportion_female.get_force_scalar(age) *
516 dq_["unfished_numbers_at_age"][i_age_year] *
517 dq_["proportion_mature_at_age"][i_age_year] *
518 population->growth->evaluate(year, population->ages[age]);
519 }
520
537 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year) {
538 std::map<std::string, fims::Vector<Type>> &dq_ =
540 population->spawning_biomass_ratio[year] =
541 dq_["spawning_biomass"][year] / dq_["unfished_spawning_biomass"][0];
542 }
543
568 std::shared_ptr<fims_popdy::Population<Type>> &population) {
569 std::map<std::string, fims::Vector<Type>> &dq_ =
571
572 std::vector<Type> numbers_spr(population->n_ages, 1.0);
573 Type phi_0 = 0.0;
574 phi_0 += numbers_spr[0] *
575 population->proportion_female.get_force_scalar(0) *
576 dq_["proportion_mature_at_age"][0] *
577 population->growth->evaluate(0, population->ages[0]);
578 for (size_t a = 1; a < (population->n_ages - 1); a++) {
579 numbers_spr[a] = numbers_spr[a - 1] * fims_math::exp(-population->M[a]);
580 phi_0 += numbers_spr[a] *
581 population->proportion_female.get_force_scalar(a) *
582 dq_["proportion_mature_at_age"][a] *
583 population->growth->evaluate(0, population->ages[a]);
584 }
585
586 numbers_spr[population->n_ages - 1] =
587 (numbers_spr[population->n_ages - 2] *
588 fims_math::exp(-population->M[population->n_ages - 2])) /
589 (1 - fims_math::exp(-population->M[population->n_ages - 1]));
590 phi_0 +=
591 numbers_spr[population->n_ages - 1] *
592 population->proportion_female.get_force_scalar(population->n_ages - 1) *
593 dq_["proportion_mature_at_age"][population->n_ages - 1] *
594 population->growth->evaluate(0,
595 population->ages[population->n_ages - 1]);
596
597 return phi_0;
598 }
599
625 size_t i_age_year, size_t year, size_t i_dev) {
626 std::map<std::string, fims::Vector<Type>> &dq_ =
628
630
631 if (i_dev == population->n_years) {
632 dq_["numbers_at_age"][i_age_year] =
633 population->recruitment->evaluate_mean(
634 dq_["spawning_biomass"][year - 1], phi_0);
635 /*the final year of the time series has no data to inform recruitment
636 devs, so this value is set to the mean recruitment.*/
637 } else {
638 // Why are we using evaluate_mean, how come a virtual function was
639 // changed? AMH: there are now two virtual functions: evaluate_mean and
640 // evaluate_process (see below)
641 population->recruitment->log_expected_recruitment[year - 1] =
642 fims_math::log(population->recruitment->evaluate_mean(
643 dq_["spawning_biomass"][year - 1], phi_0));
644
645 dq_["numbers_at_age"][i_age_year] = fims_math::exp(
646 population->recruitment->process->evaluate_process(year - 1));
647 }
648
649 dq_["expected_recruitment"][year] = dq_["numbers_at_age"][i_age_year];
650 }
651
667 size_t i_age_year, size_t age) {
668 std::map<std::string, fims::Vector<Type>> &dq_ =
670
671 dq_["proportion_mature_at_age"][i_age_year] =
672 population->maturity->evaluate(population->ages[age]);
673 }
674
691 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year,
692 size_t age) {
693 std::map<std::string, fims::Vector<Type>> &pdq_ =
695
696 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
697 std::map<std::string, fims::Vector<Type>> &fdq_ =
698 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
699 size_t i_age_year = year * population->n_ages + age;
700
701 pdq_["total_landings_weight"][year] +=
702 fdq_["landings_weight_at_age"][i_age_year];
703
704 fdq_["landings_weight"][year] +=
705 fdq_["landings_weight_at_age"][i_age_year];
706
707 pdq_["total_landings_numbers"][year] +=
708 fdq_["landings_numbers_at_age"][i_age_year];
709
710 fdq_["landings_numbers"][year] +=
711 fdq_["landings_numbers_at_age"][i_age_year];
712 }
713 }
714
731 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year,
732 size_t age) {
733 int i_age_year = year * population->n_ages + age;
734 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
735 std::map<std::string, fims::Vector<Type>> &fdq_ =
736 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
737
738 fdq_["landings_weight_at_age"][i_age_year] =
739 fdq_["landings_numbers_at_age"][i_age_year] *
740 population->growth->evaluate(year, population->ages[age]);
741 }
742 }
743
763 size_t i_age_year, size_t year, size_t age) {
764 std::map<std::string, fims::Vector<Type>> &pdq_ =
766
767 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
768 std::map<std::string, fims::Vector<Type>> &fdq_ =
769 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
770
771 // Baranov Catch Equation
772 fdq_["landings_numbers_at_age"][i_age_year] +=
773 (population->fleets[fleet_]->Fmort[year] *
774 population->f_multiplier[year] *
775 population->fleets[fleet_]->selectivity->evaluate(
776 population->ages[age], year)) /
777 pdq_["mortality_Z"][i_age_year] * pdq_["numbers_at_age"][i_age_year] *
778 (1 - fims_math::exp(-(pdq_["mortality_Z"][i_age_year])));
779 }
780 }
781
800 size_t i_age_year, size_t year, size_t age) {
801 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
802 std::map<std::string, fims::Vector<Type>> &fdq_ =
803 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
804
805 fdq_["index_weight"][year] += fdq_["index_weight_at_age"][i_age_year];
806
807 fdq_["index_numbers"][year] += fdq_["index_numbers_at_age"][i_age_year];
808 }
809 }
810
832 size_t i_age_year, size_t year, size_t age) {
833 std::map<std::string, fims::Vector<Type>> &pdq_ =
835
836 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
837 std::map<std::string, fims::Vector<Type>> &fdq_ =
838 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
839
840 fdq_["index_numbers_at_age"][i_age_year] +=
841 (population->fleets[fleet_]->q.get_force_scalar(year) *
842 population->fleets[fleet_]->selectivity->evaluate(
843 population->ages[age], year)) *
844 pdq_["numbers_at_age"][i_age_year];
845 }
846 }
847
863 std::shared_ptr<fims_popdy::Population<Type>> &population, size_t year,
864 size_t age) {
865 int i_age_year = year * population->n_ages + age;
866 for (size_t fleet_ = 0; fleet_ < population->n_fleets; fleet_++) {
867 std::map<std::string, fims::Vector<Type>> &fdq_ =
868 this->GetFleetDerivedQuantities(population->fleets[fleet_]->GetId());
869
870 fdq_["index_weight_at_age"][i_age_year] =
871 fdq_["index_numbers_at_age"][i_age_year] *
872 population->growth->evaluate(year, population->ages[age]);
873 }
874 }
875
881 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
882 std::map<std::string, fims::Vector<Type>> &fdq_ =
883 this->GetFleetDerivedQuantities((*fit).second->GetId());
884
885 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
886 for (size_t y = 0; y < fleet->n_years; y++) {
887 Type sum = static_cast<Type>(0.0);
888 Type sum_obs = static_cast<Type>(0.0);
889 // robust_add is a small value to add to expected composition
890 // proportions at age to stabilize likelihood calculations
891 // when the expected proportions are close to zero.
892 // Type robust_add = static_cast<Type>(0.0); // zeroed out before
893 // testing 0.0001; sum robust is used to calculate the total sum of
894 // robust additions to ensure that proportions sum to 1. Type robust_sum
895 // = static_cast<Type>(1.0);
896
897 for (size_t a = 0; a < fleet->n_ages; a++) {
898 size_t i_age_year = y * fleet->n_ages + a;
899 // Here we have a check to determine if the age comp
900 // should be calculated from the retained landings or
901 // the total population. These values are slightly different.
902 // In the future this will have more impact as we implement
903 // timing rather than everything occurring at the start of
904 // the year.
905 if (fleet->fleet_observed_landings_data_id_m == -999) {
906 fdq_["agecomp_expected"][i_age_year] =
907 fdq_["index_numbers_at_age"][i_age_year];
908 } else {
909 fdq_["agecomp_expected"][i_age_year] =
910 fdq_["landings_numbers_at_age"][i_age_year];
911 }
912 sum += fdq_["agecomp_expected"][i_age_year];
913 // robust_sum -= robust_add;
914
915 // This sums over the observed age composition data so that
916 // the expected age composition can be rescaled to match the
917 // total number observed. The check for na values should not
918 // be needed as individual years should not have missing data.
919 // This is need to be re-explored if/when we modify FIMS to
920 // allow for composition bins that do not match the population
921 // bins.
922 if (fleet->fleet_observed_agecomp_data_id_m != -999) {
923 if (fleet->observed_agecomp_data->at(i_age_year) !=
924 fleet->observed_agecomp_data->na_value) {
925 sum_obs += fleet->observed_agecomp_data->at(i_age_year);
926 }
927 }
928 }
929 for (size_t a = 0; a < fleet->n_ages; a++) {
930 size_t i_age_year = y * fleet->n_ages + a;
931 fdq_["agecomp_proportion"][i_age_year] =
932 fdq_["agecomp_expected"][i_age_year] / sum;
933 // robust_add + robust_sum * this->agecomp_expected[i_age_year] / sum;
934
935 if (fleet->fleet_observed_agecomp_data_id_m != -999) {
936 fdq_["agecomp_expected"][i_age_year] =
937 fdq_["agecomp_proportion"][i_age_year] * sum_obs;
938 }
939 }
940 }
941 }
942 }
943
949 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
950 std::map<std::string, fims::Vector<Type>> &fdq_ =
951 this->GetFleetDerivedQuantities((*fit).second->GetId());
952
953 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
954
955 if (fleet->n_lengths > 0) {
956 for (size_t y = 0; y < fleet->n_years; y++) {
957 Type sum = static_cast<Type>(0.0);
958 Type sum_obs = static_cast<Type>(0.0);
959 // robust_add is a small value to add to expected composition
960 // proportions at age to stabilize likelihood calculations
961 // when the expected proportions are close to zero.
962 // Type robust_add = static_cast<Type>(0.0); // 0.0001; zeroed out
963 // before testing sum robust is used to calculate the total sum of
964 // robust additions to ensure that proportions sum to 1. Type
965 // robust_sum = static_cast<Type>(1.0);
966 for (size_t l = 0; l < fleet->n_lengths; l++) {
967 size_t i_length_year = y * fleet->n_lengths + l;
968 for (size_t a = 0; a < fleet->n_ages; a++) {
969 size_t i_age_year = y * fleet->n_ages + a;
970 size_t i_length_age = a * fleet->n_lengths + l;
971 fdq_["lengthcomp_expected"][i_length_year] +=
972 fdq_["agecomp_expected"][i_age_year] *
973 fleet->age_to_length_conversion[i_length_age];
974
975 fdq_["landings_numbers_at_length"][i_length_year] +=
976 fdq_["landings_numbers_at_age"][i_age_year] *
977 fleet->age_to_length_conversion[i_length_age];
978
979 fdq_["index_numbers_at_length"][i_length_year] +=
980 fdq_["index_numbers_at_age"][i_age_year] *
981 fleet->age_to_length_conversion[i_length_age];
982 }
983
984 sum += fdq_["lengthcomp_expected"][i_length_year];
985 // robust_sum -= robust_add;
986
987 if (fleet->fleet_observed_lengthcomp_data_id_m != -999) {
988 if (fleet->observed_lengthcomp_data->at(i_length_year) !=
989 fleet->observed_lengthcomp_data->na_value) {
990 sum_obs += fleet->observed_lengthcomp_data->at(i_length_year);
991 }
992 }
993 }
994 for (size_t l = 0; l < fleet->n_lengths; l++) {
995 size_t i_length_year = y * fleet->n_lengths + l;
996 fdq_["lengthcomp_proportion"][i_length_year] =
997 fdq_["lengthcomp_expected"][i_length_year] / sum;
998 // robust_add + robust_sum *
999 // this->lengthcomp_expected[i_length_year] / sum;
1000 if (fleet->fleet_observed_lengthcomp_data_id_m != -999) {
1001 fdq_["lengthcomp_expected"][i_length_year] =
1002 fdq_["lengthcomp_proportion"][i_length_year] * sum_obs;
1003 }
1004 }
1005 }
1006 }
1007 }
1008 }
1009
1015 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1016 std::map<std::string, fims::Vector<Type>> &fdq_ =
1017 this->GetFleetDerivedQuantities((*fit).second->GetId());
1018 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1019
1020 for (size_t i = 0; i < fdq_["index_numbers"].size(); i++) {
1021 if (fleet->observed_index_units == "number") {
1022 fdq_["index_expected"][i] = fdq_["index_numbers"][i];
1023 } else {
1024 fdq_["index_expected"][i] = fdq_["index_weight"][i];
1025 }
1026 fdq_["log_index_expected"][i] = log(fdq_["index_expected"][i]);
1027 }
1028 }
1029 }
1030
1036 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1037 std::map<std::string, fims::Vector<Type>> &fdq_ =
1038 this->GetFleetDerivedQuantities((*fit).second->GetId());
1039 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1040
1041 for (size_t i = 0; i < fdq_["landings_weight"].size(); i++) {
1042 if (fleet->observed_landings_units == "number") {
1043 fdq_["landings_expected"][i] = fdq_["landings_numbers"][i];
1044 } else {
1045 fdq_["landings_expected"][i] = fdq_["landings_weight"][i];
1046 }
1047 fdq_["log_landings_expected"][i] = log(fdq_["landings_expected"][i]);
1048 }
1049 }
1050 }
1051
1052 virtual void Evaluate() {
1053 /*
1054 Sets derived vectors to zero
1055 Performs parameters transformations
1056 Sets recruitment deviations to mean 0.
1057 */
1058 Prepare();
1059 /*
1060 start at year=0, age=0;
1061 here year 0 is the estimated initial population structure and age 0 are
1062 recruits loops start at zero with if statements inside to specify unique
1063 code for initial structure and recruitment 0 loops. Could also have started
1064 loops at 1 with initial structure and recruitment setup outside the loops.
1065
1066 year loop is extended to <= n_years because SSB is calculated as the start
1067 of the year value and by extending one extra year we get estimates of the
1068 population structure at the end of the final year. An alternative approach
1069 would be to keep initial numbers at age in it's own vector and each year to
1070 include the population structure at the end of the year. This is likely a
1071 null point given that we are planning to modify to an event/stanza based
1072 structure in later milestones which will eliminate this confusion by
1073 explicitly referencing the exact date (or period of averaging) at which any
1074 calculation or output is being made.
1075 */
1076 for (size_t p = 0; p < this->populations.size(); p++) {
1077 std::shared_ptr<fims_popdy::Population<Type>> &population =
1078 this->populations[p];
1079 std::map<std::string, fims::Vector<Type>> &pdq_ =
1080 this->GetPopulationDerivedQuantities(population->GetId());
1081 // CAAPopulationProxy<Type>& population = this->populations_proxies[p];
1082
1083 for (size_t y = 0; y <= population->n_years; y++) {
1084 for (size_t a = 0; a < population->n_ages; a++) {
1085 /*
1086 index naming defines the dimensional folding structure
1087 i.e. i_age_year is referencing folding over years and ages.
1088 */
1089 size_t i_age_year = y * population->n_ages + a;
1090 /*
1091 Mortality rates are not estimated in the final year which is
1092 used to show expected population structure at the end of the model
1093 period. This is because biomass in year i represents biomass at the
1094 start of the year. Should we add complexity to track more values such
1095 as start, mid, and end biomass in all years where, start biomass=end
1096 biomass of the previous year? Referenced above, this is probably not
1097 worth exploring as later milestone changes will eliminate this
1098 confusion.
1099 */
1100 if (y < population->n_years) {
1101 /*
1102 First thing we need is total mortality aggregated across all fleets
1103 to inform the subsequent catch and change in numbers at age
1104 calculations. This is only calculated for years < n_years as these
1105 are the model estimated years with data. The year loop extends to
1106 y=n_years so that population numbers at age and SSB can be
1107 calculated at the end of the last year of the model
1108 */
1110 }
1112 /* if statements needed because some quantities are only needed
1113 for the first year and/or age, so these steps are included here.
1114 */
1115 if (y == 0) {
1116 // Initial numbers at age is a user input or estimated parameter
1117 // vector.
1119
1120 if (a == 0) {
1121 /*
1122 Expected recruitment in year 0 is numbers at age 0 in year 0.
1123 */
1124 pdq_["expected_recruitment"][y] =
1125 pdq_["numbers_at_age"][i_age_year];
1126 pdq_["unfished_numbers_at_age"][i_age_year] =
1127 fims_math::exp(population->recruitment->log_rzero[0]);
1128 } else {
1130 }
1131
1132 } else {
1133 if (a == 0) {
1134 // Set the nrecruits for age a=0 year y (use pointers instead of
1135 // functional returns) assuming fecundity = 1 and 50:50 sex ratio
1137 pdq_["unfished_numbers_at_age"][i_age_year] =
1138 fims_math::exp(population->recruitment->log_rzero[0]);
1139 } else {
1140 size_t i_agem1_yearm1 = (y - 1) * population->n_ages + (a - 1);
1143 a);
1144 }
1145 }
1146
1147 /*
1148 Fished and unfished biomass vectors are summing biomass at
1149 age across ages.
1150 */
1151
1153
1155
1156 /*
1157 Fished and unfished spawning biomass vectors are summing biomass at
1158 age across ages to allow calculation of recruitment in the next
1159 year.
1160 */
1161
1163
1165
1166 /*
1167 Here composition, total catch, and index values are calculated for all
1168 years with reference data. They are not calculated for y=n_years as
1169 there is this is just to get final population structure at the end of
1170 the terminal year.
1171 */
1172 if (y < population->n_years) {
1176
1180 }
1181 }
1182 /* Calculate spawning biomass depletion ratio */
1184 }
1185 }
1190 }
1195 virtual void Report() {
1196 int n_fleets = this->fleets.size();
1197 int n_pops = this->populations.size();
1198#ifdef TMB_MODEL
1199 if (this->do_reporting == true) {
1200 report_vectors.clear();
1201 // initialize population vectors
1217
1218 // initialize fleet vectors
1238
1239 // initiate population index for structuring report out objects
1240 int pop_idx = 0;
1241 for (size_t p = 0; p < this->populations.size(); p++) {
1242 std::map<std::string, fims::Vector<Type>> &derived_quantities =
1244 biomass_p(pop_idx) = derived_quantities["biomass"].to_tmb();
1246 derived_quantities["expected_recruitment"].to_tmb();
1247 mortality_F_p(pop_idx) = derived_quantities["mortality_F"].to_tmb();
1248 mortality_M_p(pop_idx) = derived_quantities["mortality_M"].to_tmb();
1249 mortality_Z_p(pop_idx) = derived_quantities["mortality_Z"].to_tmb();
1251 derived_quantities["numbers_at_age"].to_tmb();
1253 derived_quantities["proportion_mature_at_age"].to_tmb();
1255 derived_quantities["spawning_biomass"].to_tmb();
1257 derived_quantities["sum_selectivity"].to_tmb();
1259 derived_quantities["total_landings_numbers"].to_tmb();
1261 derived_quantities["total_landings_weight"].to_tmb();
1263 derived_quantities["unfished_biomass"].to_tmb();
1265 derived_quantities["unfished_numbers_at_age"].to_tmb();
1267 derived_quantities["unfished_spawning_biomass"].to_tmb();
1269 this->populations[pop_idx]->spawning_biomass_ratio.to_tmb();
1270
1271 pop_idx += 1;
1272 }
1273
1274 // initiate fleet index for structuring report out objects
1275 int fleet_idx = 0;
1277 for (fit = this->fleets.begin(); fit != this->fleets.end(); ++fit) {
1278 std::shared_ptr<fims_popdy::Fleet<Type>> &fleet = (*fit).second;
1279 std::map<std::string, fims::Vector<Type>> &derived_quantities =
1280 this->GetFleetDerivedQuantities(fleet->GetId());
1281
1283 derived_quantities["agecomp_expected"].to_tmb();
1285 derived_quantities["agecomp_proportion"].to_tmb();
1286 catch_index_f(fleet_idx) = derived_quantities["catch_index"].to_tmb();
1288 derived_quantities["index_expected"].to_tmb();
1290 derived_quantities["index_numbers"].to_tmb();
1292 derived_quantities["index_numbers_at_age"].to_tmb();
1294 derived_quantities["index_numbers_at_length"].to_tmb();
1295 index_weight_f(fleet_idx) = derived_quantities["index_weight"].to_tmb();
1297 derived_quantities["index_weight_at_age"].to_tmb();
1299 derived_quantities["landings_expected"].to_tmb();
1301 derived_quantities["landings_numbers"].to_tmb();
1303 derived_quantities["landings_numbers_at_age"].to_tmb();
1305 derived_quantities["landings_numbers_at_length"].to_tmb();
1307 derived_quantities["landings_weight"].to_tmb();
1309 derived_quantities["landings_weight_at_age"].to_tmb();
1310 // length_comp_expected_f(fleet_idx) =
1311 // derived_quantities["length_comp_expected"];
1312 // length_comp_proportion_f(fleet_idx) =
1313 // derived_quantities["length_comp_proportion"];
1315 derived_quantities["lengthcomp_expected"].to_tmb();
1317 derived_quantities["lengthcomp_proportion"].to_tmb();
1319 derived_quantities["log_index_expected"].to_tmb();
1321 derived_quantities["log_landings_expected"].to_tmb();
1322 fleet_idx += 1;
1323 }
1324
1325 vector<Type> biomass = ADREPORTvector(biomass_p);
1326 vector<Type> expected_recruitment =
1332 vector<Type> proportion_mature_at_age =
1336 vector<Type> total_landings_numbers =
1338 vector<Type> total_landings_weight =
1341 vector<Type> unfished_numbers_at_age =
1343 vector<Type> unfished_spawning_biomass =
1345 vector<Type> spawning_biomass_ratio =
1347
1348 vector<Type> agecomp_expected = ADREPORTvector(agecomp_expected_f);
1349 vector<Type> agecomp_proportion = ADREPORTvector(agecomp_proportion_f);
1353 vector<Type> index_numbers_at_age =
1355 vector<Type> index_numbers_at_length =
1361 vector<Type> landings_numbers_at_age =
1363 vector<Type> landings_numbers_at_length =
1366 vector<Type> landings_weight_at_age =
1368 // vector<Type> length_comp_expected =
1369 // ADREPORTvector(length_comp_expected_f); vector<Type>
1370 // length_comp_proportion = ADREPORTvector(length_comp_proportion_f);
1371 vector<Type> lengthcomp_expected = ADREPORTvector(lengthcomp_expected_f);
1372 vector<Type> lengthcomp_proportion =
1374 vector<Type> log_index_expected = ADREPORTvector(log_index_expected_f);
1375 vector<Type> log_landings_expected =
1377 // populations
1378 // report
1379 FIMS_REPORT_F_("biomass", biomass_p, this->of);
1380 FIMS_REPORT_F_("expected_recruitment", expected_recruitment_p, this->of);
1381 FIMS_REPORT_F_("mortality_F", mortality_F_p, this->of);
1382 FIMS_REPORT_F_("mortality_M", mortality_M_p, this->of);
1383 FIMS_REPORT_F_("mortality_Z", mortality_Z_p, this->of);
1384 FIMS_REPORT_F_("numbers_at_age", numbers_at_age_p, this->of);
1385 FIMS_REPORT_F_("proportion_mature_at_age", proportion_mature_at_age_p,
1386 this->of);
1387 FIMS_REPORT_F_("spawning_biomass", spawning_biomass_p, this->of);
1388 FIMS_REPORT_F_("sum_selectivity", sum_selectivity_p, this->of);
1389 FIMS_REPORT_F_("total_landings_numbers", total_landings_numbers_p,
1390 this->of);
1391 FIMS_REPORT_F_("total_landings_weight", total_landings_weight_p,
1392 this->of);
1393 FIMS_REPORT_F_("unfished_biomass", unfished_biomass_p, this->of);
1394 FIMS_REPORT_F_("unfished_numbers_at_age", unfished_numbers_at_age_p,
1395 this->of);
1396 FIMS_REPORT_F_("unfished_spawning_biomass", unfished_spawning_biomass_p,
1397 this->of);
1398 FIMS_REPORT_F_("spawning_biomass_ratio", spawning_biomass_ratio_p,
1399 this->of);
1400
1401 // adreport
1402 ADREPORT_F(biomass, this->of);
1403 ADREPORT_F(expected_recruitment, this->of);
1404 ADREPORT_F(mortality_F, this->of);
1405 ADREPORT_F(mortality_M, this->of);
1406 ADREPORT_F(mortality_Z, this->of);
1407 ADREPORT_F(numbers_at_age, this->of);
1408 ADREPORT_F(proportion_mature_at_age, this->of);
1409 ADREPORT_F(spawning_biomass, this->of);
1410 ADREPORT_F(sum_selectivity, this->of);
1411 ADREPORT_F(total_landings_numbers, this->of);
1412 ADREPORT_F(total_landings_weight, this->of);
1413 ADREPORT_F(unfished_biomass, this->of);
1414 ADREPORT_F(unfished_numbers_at_age, this->of);
1415 ADREPORT_F(unfished_spawning_biomass, this->of);
1416 ADREPORT_F(spawning_biomass_ratio, this->of);
1417
1418 // fleets
1419 // report
1420 FIMS_REPORT_F_("agecomp_expected", agecomp_expected_f, this->of);
1421 FIMS_REPORT_F_("agecomp_proportion", agecomp_proportion_f, this->of);
1422 FIMS_REPORT_F_("catch_index", catch_index_f, this->of);
1423 FIMS_REPORT_F_("index_expected", index_expected_f, this->of);
1424 FIMS_REPORT_F_("index_numbers", index_numbers_f, this->of);
1425 FIMS_REPORT_F_("index_numbers_at_age", index_numbers_at_age_f, this->of);
1426 FIMS_REPORT_F_("index_numbers_at_length", index_numbers_at_length_f,
1427 this->of);
1428 FIMS_REPORT_F_("index_weight", index_weight_f, this->of);
1429 FIMS_REPORT_F_("index_weight_at_age", index_weight_at_age_f, this->of);
1430 FIMS_REPORT_F_("landings_expected", landings_expected_f, this->of);
1431 FIMS_REPORT_F_("landings_numbers", landings_numbers_f, this->of);
1432 FIMS_REPORT_F_("landings_numbers_at_age", landings_numbers_at_age_f,
1433 this->of);
1434 FIMS_REPORT_F_("landings_numbers_at_length", landings_numbers_at_length_f,
1435 this->of);
1436 FIMS_REPORT_F_("landings_weight", landings_weight_f, this->of);
1437 FIMS_REPORT_F_("landings_weight_at_age", landings_weight_at_age_f,
1438 this->of);
1439 FIMS_REPORT_F_("lengthcomp_expected", lengthcomp_expected_f, this->of);
1440 FIMS_REPORT_F_("lengthcomp_proportion", lengthcomp_proportion_f,
1441 this->of);
1442 FIMS_REPORT_F_("log_index_expected", log_index_expected_f, this->of);
1443 FIMS_REPORT_F_("log_landings_expected", log_landings_expected_f,
1444 this->of);
1445 // adreport
1446 ADREPORT_F(agecomp_expected, this->of);
1447 ADREPORT_F(agecomp_proportion, this->of);
1448 ADREPORT_F(catch_index, this->of);
1449 ADREPORT_F(index_expected, this->of);
1450 ADREPORT_F(index_numbers, this->of);
1451 ADREPORT_F(index_numbers_at_age, this->of);
1452 ADREPORT_F(index_numbers_at_length, this->of);
1453 ADREPORT_F(index_weight, this->of);
1454 ADREPORT_F(index_weight_at_age, this->of);
1455 ADREPORT_F(landings_expected, this->of);
1456 ADREPORT_F(landings_numbers, this->of);
1457 ADREPORT_F(landings_numbers_at_age, this->of);
1458 ADREPORT_F(landings_numbers_at_length, this->of);
1459 ADREPORT_F(landings_weight, this->of);
1460 ADREPORT_F(landings_weight_at_age, this->of);
1461 ADREPORT_F(lengthcomp_expected, this->of);
1462 ADREPORT_F(lengthcomp_proportion, this->of);
1463 ADREPORT_F(log_index_expected, this->of);
1464 ADREPORT_F(log_landings_expected, this->of);
1465 std::stringstream var_name;
1466 typename std::map<std::string, fims::Vector<fims::Vector<Type>>>::iterator
1467 rvit;
1468 for (rvit = report_vectors.begin(); rvit != report_vectors.end();
1469 ++rvit) {
1470 auto &x = rvit->second;
1471
1472 int outer_dim = x.size();
1473 int dim = 0;
1474 for (int i = 0; i < outer_dim; i++) {
1475 dim += x[i].size();
1476 }
1477 vector<Type> res(dim);
1478 int idx = 0;
1479 for (int i = 0; i < outer_dim; i++) {
1480 int inner_dim = x[i].size();
1481 for (int j = 0; j < inner_dim; j++) {
1482 res(idx) = x[i][j];
1483 idx += 1;
1484 }
1485 }
1486 this->of->reportvector.push(res, rvit->first.c_str());
1487 }
1488 }
1489#endif
1490 }
1491};
1492
1493} // namespace fims_popdy
1494
1495#endif
CatchAtAge is a class containing a catch-at-age model, which is just one of many potential fishery mo...
Definition catch_at_age.hpp:53
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:536
std::map< std::string, fims::Vector< Type > >::iterator dq_iterator
Iterate through derived quantities.
Definition catch_at_age.hpp:112
std::map< std::string, fims::Vector< Type > >::iterator derived_quantities_iterator
Iterate the derived quantities.
Definition catch_at_age.hpp:66
Type CalculateSBPR0(std::shared_ptr< fims_popdy::Population< Type > > &population)
Calculates equilibrium spawning biomass per recruit.
Definition catch_at_age.hpp:567
virtual void Initialize()
Definition catch_at_age.hpp:153
std::vector< Type > ages
Definition catch_at_age.hpp:121
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:340
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:428
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:118
std::set< uint32_t > & GetPopulationIds()
Get the population ids of the model.
Definition catch_at_age.hpp:242
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:98
std::map< uint32_t, std::shared_ptr< fims_popdy::Fleet< Type > > >::iterator fleet_iterator
Iterate through fleets.
Definition catch_at_age.hpp:106
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:862
void evaluate_age_comp()
Definition catch_at_age.hpp:879
void evaluate_length_comp()
Definition catch_at_age.hpp:947
virtual ~CatchAtAge()
Destroy the Catch At Age object.
Definition catch_at_age.hpp:147
CatchAtAge(const CatchAtAge &other)
Copy constructor for the CatchAtAge class.
Definition catch_at_age.hpp:138
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:480
CatchAtAge()
Definition catch_at_age.hpp:126
virtual void Evaluate()
Evaluate the model.
Definition catch_at_age.hpp:1052
std::string name_m
The name of the model.
Definition catch_at_age.hpp:59
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:508
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:799
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:453
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:74
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:665
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:89
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:297
void CalculateLandingsNumbersAA(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 landings for a given fleet from a population, year and age.
Definition catch_at_age.hpp:761
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:623
void evaluate_landings()
Definition catch_at_age.hpp:1034
virtual void Report()
Definition catch_at_age.hpp:1195
void AddPopulation(uint32_t id)
Definition catch_at_age.hpp:237
void CalculateLandingsWeightAA(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t year, size_t age)
Calculates weight at age of the landings for a given fleet from a population.
Definition catch_at_age.hpp:730
std::vector< std::shared_ptr< fims_popdy::Population< Type > > > & GetPopulations()
Definition catch_at_age.hpp:249
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:82
void CalculateLandings(std::shared_ptr< fims_popdy::Population< Type > > &population, size_t year, size_t age)
Calculates total catch (landings) by fleet and population for a given year by aggregating age-specifi...
Definition catch_at_age.hpp:690
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:391
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:830
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:265
virtual void Prepare()
Definition catch_at_age.hpp:186
void evaluate_index()
Definition catch_at_age.hpp:1013
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
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:41
void clear_internal()
Clears the internal objects.
Definition rcpp_interface.hpp:235
Population class. Contains subpopulations that are divided into generic partitions (e....
Definition population.hpp:25