Indian Ocean Skipjack
model.hpp
1 #pragma once
2 
3 #include "dimensions.hpp"
4 #include "distributions.hpp"
5 using namespace Utilities::Distributions;
6 
7 namespace IOSKJ {
8 
13 class Model {
14 public:
15 
19  Array<double,Region,Age> numbers;
20 
24  Array<double,Region> biomass;
25 
29  Array<double,Region> biomass_spawners;
30 
37  Array<double,Region> biomass_spawners_unfished;
38 
47  Array<double,Quarter> spawning;
48 
52  Array<double,Region,Quarter> biomass_spawning;
53 
58  Array<double,Region,Quarter> biomass_spawning_unfished;
59 
63  Array<double,Region> recruits_unfished;
64 
69 
74  bool recruits_relation_on = true;
75 
79  Array<double,Region> recruits_determ;
80 
84  bool recruits_variation_on = true;
85 
89  double recruits_sd;
90 
95 
100 
104  double recruits_deviation = 0;
105 
109  double recruits_multiplier = 1;
110 
114  Array<double,Region> recruits;
115 
116 
130  double growth_rate_2;
131  double growth_assymptote;
132  double growth_stanza_inflection;
133  double growth_stanza_steepness;
134  double growth_age_0;
135  double growth_cv_0;
136  double growth_cv_old;
137 
141  Array<double,Size> length_size;
142 
146  Array<Normal,Age> length_age;
147 
151  Array<double,Age,Size> age_size;
152 
166  double weight_length_b;
167 
171  Array<double,Size> weight_size;
172  Array<double,Age> weight_age;
173 
187  double maturity_length_steepness;
188 
192  Array<double,Size> maturity_size;
193  Array<double,Age> maturity_age;
194 
209 
215  Array<double,Age> mortality_shape = {
216  1.25, 1.25, 1.25, 1.25,
217  1.25, 1.25, 1.25, 1.25, // Age 1
218  0.80, 0.80, 0.80, 0.80, // Age 2
219  0.45, 0.45, 0.45, 0.45, // Age 3
220  1.50, 1.50, 1.50, 1.50, // Age 4+
221  1.50, 1.50, 1.50, 1.50 // Age 4+
222  };
223 
227  Array<double,Age> mortality;
228 
232  Array<double,Age> survival;
233 
247  Array<double,RegionFrom,Region> movement_region;
248 
253  double movement_length_steepness;
254  Array<double,Size> movement_size;
255  Array<double,Age> movement_age;
256 
269  Array<double,SelectivityKnot> selectivity_lengths = {20,30,40,50,60,70,80};
270 
274  Array<double,Method,SelectivityKnot> selectivity_values;
275 
279  Array<double,Method,Size> selectivity_size;
280  Array<double,Method,Age> selectivity_age;
281 
285  enum {
286  // For determining pristine conditions
287  exploit_none = 0,
288  // For determining MSY related reference points
289  // and F based MPs
290  exploit_rate = 1,
291  // For conditioning with historical catches and
292  // TAC based MPs
293  exploit_catch = 2,
294  // For TAE based MPs
295  exploit_effort = 3,
296  } exploit;
297 
301  Array<double,Region,Method> biomass_vulnerable;
302 
307  Array<double,Region,Method> cpue;
308  Array<GeometricMean,Region,Method> cpue_base;
309 
313  Array<double,Region,Method> catches;
314 
321  Array<double,Region,Method> effort;
322 
326  Array<double,Region,Method> catchability;
327  Array<GeometricMean,Region,Method> catchability_estim;
328 
329 
333  Array<double,Region,Method> exploitation_rate_specified;
334 
339  Array<double,Region,Method> catches_taken;
340 
344  Array<double,Region,Method> exploitation_rate;
345 
349  Array<double,Region,Age> escapement;
350 
358  double msy;
359  double e_msy;
360  double f_msy;
361  double biomass_spawners_msy;
362  int msy_trials;
363 
367  double e_40;
368  double f_40;
369  double biomass_spawners_40;
370 
383  Array<double,Quarter> m_pl_quarter = {0.97,0.87,0.97,1.19};
384 
399  double biomass_status(void) const{
400  return sum(biomass_spawners)/sum(biomass_spawners_unfished);
401  }
402 
404 
417  void movement_uniform(void){
418  movement_region = 1.0/regions.size();
419  movement_length_inflection = 0;
420  movement_length_steepness = 100;
421  }
422 
429  void spawning_uniform(void){
430  spawning = 1.0;
431  }
432 
434 
451  void exploitation_rate_set(double value){
452  // Turn on exploitation defined by `exploitation_rate_specified`
453  exploit = exploit_rate;
454 
455  // Set exploitation rate to be zero for most areas
456  // but to `value` for the three main methods in each
457  // region.
458  exploitation_rate_specified = 0;
459  exploitation_rate_specified(WE,PS) = value;
460  exploitation_rate_specified(MA,PL) = value;
461  exploitation_rate_specified(EA,GN) = value;
462  }
463 
467  double exploitation_rate_get(void) const {
468  double survival = geomean(escapement);
469  return 1 - survival;
470  }
471 
476  void fishing_mortality_set(double value){
477  exploitation_rate_set(1-std::exp(-value));
478  }
479 
484  double fishing_mortality_get(void) const {
485  return -std::log(1-exploitation_rate_get());
486  }
487 
493  void catches_set(double catches_, double error=0.2){
494  // Turn on exploitation defined by `catches`
495  exploit = exploit_catch;
496 
503  Lognormal dist(1,error);
504 
505  catches(WE,PS) = 0.354 * catches_ * dist.random();
506  catches(WE,PL) = 0.018 * catches_ * dist.random();
507  catches(WE,GN) = 0.117 * catches_ * dist.random();
508  catches(WE,OT) = 0.024 * catches_ * dist.random();
509 
510  catches(MA,PS) = 0.000 * catches_ * dist.random();
511  catches(MA,PL) = 0.198 * catches_ * dist.random();
512  catches(MA,GN) = 0.000 * catches_ * dist.random();
513  catches(MA,OT) = 0.005 * catches_ * dist.random();
514 
515  catches(EA,PS) = 0.058 * catches_ * dist.random();
516  catches(EA,PL) = 0.006 * catches_ * dist.random();
517  catches(EA,GN) = 0.141 * catches_ * dist.random();
518  catches(EA,OT) = 0.078 * catches_ * dist.random();
519  }
520 
524  void effort_set(double effort_){
525  // Turn on exploitation defined by `effort`
526  exploit = exploit_effort;
527 
528  // Since effort units are currently nominal
529  // for each region/method relative to the period
530  // 2004-2013, effort is set the same for all region/methods
531  effort = effort_;
532  }
533 
535 
539  void initialise(void){
540  // Initialise length distributions by age
541  double growth_cv_slope = (growth_cv_old - growth_cv_0)/ages.size();
542  for(auto age : ages){
543  // Convert age from quarters (middle of quarter) to years
544  double a = double(age.index()+0.5)/4.0;
545  // Mean length at age
546  double part1 = (1+std::exp(-growth_stanza_steepness*(a-growth_age_0-growth_stanza_inflection)))/
547  (1+std::exp(growth_stanza_inflection*growth_stanza_steepness));
548  double part2 = std::pow(part1,-(growth_rate_2-growth_rate_1)/growth_stanza_steepness);
549  double mean = growth_assymptote * (1-std::exp(-growth_rate_2*(a-growth_age_0))*part2);
550  // Standard deviation of length at age
551  double cv = growth_cv_0 + growth_cv_slope*a;
552  double sd = mean * cv;
553  Normal dist(mean,sd);
554  length_age(age) = dist;
555  // Calculate proportions in each size bin
556  double sum = 0;
557  for(auto size : sizes){
558  double lower = 2*size.index();
559  double upper = lower+2;
560  double prop = dist.cdf(upper)-dist.cdf(lower);
561  age_size(age,size) = prop;
562  sum += prop;
563  }
564  // Normalise to ensure rows sum to 1
565  for(auto size : sizes) age_size(age,size) /= sum;
566  }
567 
568  // Initialise arrays that are dimensioned by size
569  for(auto size : sizes){
570  double length = 2*size.index()+1;
571  length_size(size) = length;
572  weight_size(size) = weight_length_a*std::pow(length,weight_length_b);
573  maturity_size(size) = 1.0/(1.0+std::pow(19,(maturity_length_inflection-length)/maturity_length_steepness));
574  movement_size(size) = 1.0/(1.0+std::pow(19,(movement_length_inflection-length)/movement_length_steepness));
575  }
576 
577  // Initialise selectivity
578  for(auto method : methods){
579  // Iterpolate selectivity-at-size using piecewise spline
580  // Ensure that selectivity is between 0 and 1 since spline
581  // can produce values outside this range even if knots are not
582  double max = 0;
583  for(auto size : sizes){
584  double length = length_size(size);
585  double selectivity = 0;
586  if(length<selectivity_lengths(0)) selectivity = 0;
587  else{
588  for(uint knot=0;knot<selectivity_knots.size()-1;knot++){
589  if(selectivity_lengths(knot)<=length and length<selectivity_lengths(knot+1)){
590  selectivity = selectivity_values(method,knot) + (length-selectivity_lengths(knot)) * (
591  selectivity_values(method,knot+1)-selectivity_values(method,knot))/(
592  selectivity_lengths(knot+1)-selectivity_lengths(knot)
593  );
594  }
595  }
596  }
597  if(selectivity<0) selectivity = 0;
598  else if(selectivity>max) max = selectivity;
599  selectivity_size(method,size) = selectivity;
600  }
601  for(auto size : sizes) selectivity_size(method,size) /= max;
602  }
603 
604  // Initialise arrays that are dimensioned by age but dependent
605  // up arrays dimensioned by size
606  weight_age = 0;
607  maturity_age = 0;
608  selectivity_age = 0;
609  for(auto age : ages){
610  for(auto size : sizes){
611  weight_age(age) += weight_size(size) * age_size(age,size);
612  maturity_age(age) += maturity_size(size) * age_size(age,size);
613  movement_age(age) += movement_size(size) * age_size(age,size);
614  for(auto method : methods) selectivity_age(method,age) += selectivity_size(method,size) * age_size(age,size);
615  }
616  }
617 
618  // Normalise movement and selectivities to maximum
619  double movement_max = -1;
620  Array<double,Method> selectivity_max = -1;
621  for(auto age : ages){
622  if(movement_age(age)>movement_max) movement_max = movement_age(age);
623  for(auto method : methods){
624  if(selectivity_age(method,age)>selectivity_max(method)) selectivity_max(method) = selectivity_age(method,age);
625  }
626  }
627  for(auto age : ages){
628  movement_age(age) /= movement_max;
629  for(auto method : methods) selectivity_age(method,age) /= selectivity_max(method);
630  }
631 
632  // Set up mortality by age schedule
633  for(auto age : ages){
634  mortality(age) = mortality_mean * mortality_shape(age);
635  survival(age) = std::exp(-0.25 * mortality(age));
636  }
637 
638  // Initialise regional movement matrix
639  for(auto region_from : region_froms){
640  // Check that the off diagonal elements sum to between 0 and 1
641  double off_diagonals = 0;
642  for(auto region : regions){
643  if(region_from.index()!=region.index()) off_diagonals += movement_region(region_from,region);
644  }
645  // If they don't then normalise them
646  if(off_diagonals<0){
647  throw std::runtime_error("Woahhh! There is a negative regional movement parameter");
648  }
649  else if(off_diagonals>1){
650  for(auto region : regions){
651  if(region_from.index()!=region.index()) movement_region(region_from,region) = movement_region(region_from,region)/off_diagonals;
652  }
653  off_diagonals = 1;
654  }
655  // Ensure diagonals are complements
656  movement_region(region_from,Level<Region>(region_from)) = 1 - off_diagonals;
657  }
658 
659  // Initialise normal distribution for recr. devs.
660  recruits_distrib = Normal(0,recruits_sd);
661 
662  // During debug mode dump the model here for easy inspection
663  // Done here before equilibrium() in case that fails
664  #if DEBUG
665  write();
666  #endif
667 
668  // Go to pristine
669  pristine_go();
670 
671  // During debug mode dump the model here for easy inspection
672  // Done after equilibrium() and biomass_spawning_unfished has been set
673  #if DEBUG
674  write();
675  #endif
676  }
677 
681  void update(uint time){
682  uint year = IOSKJ::year(time);
683  uint quarter = IOSKJ::quarter(time);
684 
685  // Calculate total biomass, spawners biomass and spawning biomass by region
686  for(auto region : regions){
687  double biomass_ = 0;
688  double biomass_spawners_ = 0;
689  double biomass_spawning_ = 0;
690  for(auto age : ages){
691  double biomass = numbers(region,age) * weight_age(age)/1000;
692  biomass_ += biomass;
693  double spawners = biomass * maturity_age(age);
694  biomass_spawners_ += spawners;
695  biomass_spawning_ += spawners * spawning(quarter);
696  }
697  biomass(region) = biomass_;
698  biomass_spawners(region) = biomass_spawners_;
699  biomass_spawning(region,quarter) = biomass_spawning_;
700  }
701 
702  // Ageing and recruitment
703  for(auto region : regions){
704 
705  // Recruits
706  // Determininistic recruitment given stock size
707  if(recruits_relation_on){
708  // Stock-recruitment relation is active so calculate recruits based on
709  // the spawning biomass in the previous time step
710  double h = recruits_steepness;
711  double r0 = recruits_unfished(region);
712  double s0 = biomass_spawning_unfished(region,quarter);
713  double s = biomass_spawning(region,quarter);
714  recruits_determ(region) = 4*h*r0*s/((5*h-1)*s+s0*(1-h));
715  } else {
716  // Stock-recruitment relation is not active so recruitment is just r0.
717  recruits_determ(region) = recruits_unfished(region);
718  }
719  // Recruitment variation
720  // Important: recruitment deviation is set only once per year
721  // otherwise, if set quarterly, will be less than specified
722  if(recruits_variation_on and quarter==0){
723  recruits_deviation = recruits_autocorr*recruits_deviation +
724  std::sqrt(1-std::pow(recruits_autocorr,2))*recruits_distrib.random();
725  recruits_multiplier = std::exp(recruits_deviation - 0.5*std::pow(recruits_sd,2));
726  }
727  recruits(region) = recruits_determ(region) * recruits_multiplier;
728 
729  // Oldest age class accumulates
730  numbers(region,ages.size()-1) += numbers(region,ages.size()-2);
731 
732  // For most ages just "shuffle" along
733  for(uint age=ages.size()-2;age>0;age--){
734  numbers(region,age) = numbers(region,age-1);
735  }
736 
737  // Recruits from a regeion become age 0 in the region
738  numbers(region,0) = recruits(region);
739  }
740 
741  // Natural mortality
742  for(auto region : regions){
743  for(auto age : ages){
744  numbers(region,age) *= survival(age);
745  }
746  }
747 
748  // Movement
749  for(auto region_from : region_froms){
750  for(auto region_to : regions){
751  for(auto age : ages){
752  double movers =
753  numbers(Level<Region>(region_from),age) *
754  movement_region(region_from,region_to) *
755  movement_age(age);
756  numbers(Level<Region>(region_from),age) -= movers;
757  numbers(region_to,age) += movers;
758  }
759  }
760  }
761 
762  // Fishing mortality
763  if(exploit!=exploit_none){
764  // For each region and method
765  for(auto region : regions){
766  for(auto method : methods){
767  // Calculate vulnerable biomass
768  double biomass_vuln = 0;
769  for(auto age : ages){
770  biomass_vuln += numbers(region,age) *
771  weight_age(age)/1000 *
772  selectivity_age(method,age);
773  }
774  biomass_vulnerable(region,method) = biomass_vuln;
775 
776  // Update CPUE
777  if(quarter==0){
778  if(year==1985) cpue_base(region,method).reset();
779  // User 1985-1989 as the 'base' years. This allows for
780  // retrospective operation of CPUE based management procedure
781  // from 1990 onwards
782  if(year>=1985 and year<=1989){
783  cpue_base(region,method).append(biomass_vuln);
784  } else {
785  cpue(region,method) = biomass_vuln/cpue_base(region,method);
786  }
787  }
788 
789  // Determine exploitation rate
790  double er = 0;
791  if(exploit==exploit_catch){
792  // Calculate exploitation rate from catches and biomass_vulnerable
793  double c = catches(region,method);
794  if(c>0){
795  if(biomass_vuln>0){
796  er = c/biomass_vuln;
797  if(er>1) er = 1;
798  } else er = 1;
799  } else er = 0;
800  // Update estimate of catchability
801  double e = effort(region,method);
802  if(e>0){
803  double q = er/e;
804  if(year==2005) catchability_estim(region,method).reset();
805  if(q>0 and year>=2005 and year<=2014) catchability_estim(region,method).append(q);
806  if(year==2014){
807  catchability(region,method) = catchability_estim(region,method);
808  // Where no catches for a region method make catchability 0
809  if(not std::isfinite(catchability(region,method))){
810  catchability(region,method) = 0;
811  }
812  }
813  }
814  }
815  else if(exploit==exploit_effort){
816  // Calculate exploitation rate from number of
817  // effort units
818  er = catchability(region,method) * effort(region,method);
819  } else {
820  // Use the exploitation rate specified
821  er = exploitation_rate_specified(region,method);
822  }
823  exploitation_rate(region,method) = er;
824  catches_taken(region,method) = er * biomass_vuln;
825  }
826  }
827  // Pre-calculate the escapement for each region and ages
828  for(auto region : regions){
829  for(auto age : ages){
830  double proportion_taken = 0;
831  for(auto method : methods){
832  proportion_taken += exploitation_rate(region,method) * selectivity_age(method,age);
833  }
834  escapement(region,age) = (proportion_taken>1)?0:(1-proportion_taken);
835  }
836  }
837  }
838  else {
839  escapement = 1;
840  }
841  // Apply escapement
842  for(auto region : regions){
843  for(auto age : ages){
844  numbers(region,age) *= escapement(region,age);
845  }
846  }
847  }
848 
853  void equilibrium(void){
854  #if DEBUG
855  std::cout<<"************equilibrium()**************\n";
856  #endif
857  // Turn off recruitment variation (saving current setting
858  // for putting back at the end of this method)
859  bool recruits_variation_on_setting = recruits_variation_on;
860  recruits_variation_on = false;
861  // Seed the population with a small population in each partition
862  numbers = 1;
863  // Iterate until there is a very minor change in biomass
864  uint steps = 0;
865  const uint steps_max = 1000;
866  Array<double,Region> biomass_prev = 1;
867  while(steps<steps_max){
868  // It is necessary to update the model for each quarter so that quarterly differences
869  // in dynamics (e.g. spawning proportion) are incorporated
870  for(uint quarter=0;quarter<4;quarter++) update(quarter);
871 
872  // Break if biomass has gone to very low levels (as happens when this method
873  // is called with high exploitation rates from yield_curve) since the proportional
874  // diffs minimise to a low level
875  if(biomass(sum)<0.01) break;
876 
877  double diffs = 0;
878  for(auto region : regions){
879  diffs += fabs(biomass(region)-biomass_prev(region))/biomass_prev(region);
880  }
881  diffs /= regions.size();
882  if(diffs<0.0001) break;
883  biomass_prev = biomass;
884 
885  #if DEBUG
886  std::cout<<steps<<"\t"<<biomass(WE)<<"\t"<<biomass(MA)<<"\t"<<biomass(EA)<<"\t"<<diffs<<std::endl;
887  #endif
888 
889  // Throw an error if undefined biomass
890  if(not std::isfinite(biomass(WE)+biomass(MA)+biomass(EA))){
891  write();
892  throw std::runtime_error("Biomass is not finite. Check inputs. Model has been written to `model/output`");
893  }
894 
895  steps++;
896  }
897  // Throw an error if there was no convergence
898  if(steps>steps_max) throw std::runtime_error("No convergence in equilibrium() function");
899  // Turn on recruitment deviation again
900  recruits_variation_on = recruits_variation_on_setting;
901  }
902 
903  void pristine_go(void){
904  // Calculate unfished state
905  // Turn off recruitment relationship and exploitation
906  recruits_relation_on = false;
907  exploit = exploit_none;
908  // Set unfished recruitment in all regions to an arbitrarily high number
909  // so it can be calculated in terms of biomass_spawners_unfished
910  recruits_unfished = 1e10;
911  // Go to equilibrium
912  equilibrium();
913  // Scale up unfished recruitment and biomass_spawning_unfished (by region and quarter)
914  // to match biomass_spawners_unfished
915  for(auto region : regions){
916  // Calculate scalar
917  double scalar = biomass_spawners_unfished(region)/biomass_spawners(region);
918  // Apply scalar
919  recruits_unfished(region) *= scalar;
920  for(auto age : ages) numbers(region,age) *= scalar;
921  for(auto quarter : quarters){
922  biomass_spawning_unfished(region,quarter) = biomass_spawning(region,quarter)*scalar;
923  }
924  }
925 
926  // Calculate the
927  // Turn on recruitment relationship etc again
928  recruits_relation_on = true;
929  exploit = exploit_catch;
930  }
931 
935  Frame yield_curve(double step = 0.01){
936  Frame curve({
937  "exprate","f","yield","status","vuln",
938  "catch_we_ps","catch_ma_pl","catch_ea_gn",
939  "vuln_we_ps","vuln_ma_pl","vuln_ea_gn"
940  });
941  for(double exprate=0;exprate<1;exprate+=step){
942  #if DEBUG
943  std::cout<<"************yield_curve "<<exprate<<"**************\n";
944  #endif
945  exploitation_rate_set(std::max(exprate,1e-6));
946  equilibrium();
947  curve.append({
948  exprate,fishing_mortality_get(),sum(catches_taken),biomass_status(),sum(biomass_vulnerable),
949  catches_taken(WE,PS),catches_taken(MA,PL),catches_taken(EA,GN),
950  biomass_vulnerable(WE,PS),biomass_vulnerable(MA,PL),biomass_vulnerable(EA,GN)
951  });
952  }
953  return curve;
954  }
955 
961  Frame yield_per_recruit(void){
962  pristine_go();
963  Frame ypr({"age","number","length","weight"});
964  for(auto age : ages){
965  double number = 0;
966  double length = 0;
967  double weight = 0;
968  for(auto region : regions){
969  double n = numbers(region,age);
970  number += n;
971  // TODO
972  //length += length_age(size) * n;
973  //weight += weights_age(size) * n;
974  }
975  length /= number;
976  weight /= number;
977  ypr.append({double(age.index()),number,length,weight});
978  }
979  return ypr;
980  }
981 
985  void msy_go(void){
986  int count = 0;
987  auto result = boost::math::tools::brent_find_minima([&](double exprate){
988  count++;
989  exploitation_rate_set(exprate);
990  equilibrium();
991  return -sum(catches_taken);
992  },0.01,0.99,8);
993  e_msy = result.first;
994  f_msy = -std::log(1-e_msy);
995  msy = -result.second;
996  msy_trials = count;
997  // Go to equilibrium with maximum so that Bmsy can be determined
998  exploitation_rate_set(e_msy);
999  equilibrium();
1000  biomass_spawners_msy = sum(biomass_spawners);
1001  }
1002 
1006  void msy_find(void){
1007  // Create a copy of this model and take it to MSY
1008  Model calc = *this;
1009  calc.msy_go();
1010  // Copy over values
1011  e_msy = calc.e_msy;
1012  f_msy = calc.f_msy;
1013  msy = calc.msy;
1014  msy_trials = calc.msy_trials;
1015  biomass_spawners_msy = calc.biomass_spawners_msy;
1016  }
1017 
1022  void status_go(const double& status){
1023  int count = 0;
1024  auto result = boost::math::tools::brent_find_minima([&](double exprate){
1025  count++;
1026  exploitation_rate_set(exprate);
1027  equilibrium();
1028  return std::fabs(biomass_status()-status);
1029  },0.01,0.99,8);
1030  e_40 = result.first;
1031  f_40 = -std::log(1-e_40);
1032  // Go to equilibrium with maximum so that Bmsy can be determined
1033  exploitation_rate_set(e_40);
1034  equilibrium();
1035  biomass_spawners_40 = sum(biomass_spawners);
1036  }
1037 
1041  void b40_find(void){
1042  // Create a copy of this model and take it
1043  // to MSY
1044  Model calc = *this;
1045  calc.status_go(0.4);
1046  // Copy over values
1047  e_40 = calc.e_40;
1048  f_40 = calc.f_40;
1049  biomass_spawners_40 = calc.biomass_spawners_40;
1050  }
1051 
1055  void write(void){
1056  numbers.write("model/output/numbers.tsv");
1057  spawning.write("model/output/spawning.tsv");
1058  biomass_spawning_unfished.write("model/output/biomass_spawning_unfished.tsv");
1059 
1060  length_size.write("model/output/length_size.tsv");
1061  length_age.write("model/output/length_age.tsv",{"mean","sd"},[](std::ostream& stream,const Normal& dist){
1062  stream<<dist.mean<<"\t"<<dist.sd;
1063  });
1064  age_size.write("model/output/age_size.tsv");
1065 
1066  weight_size.write("model/output/weight_size.tsv");
1067  weight_age.write("model/output/weight_age.tsv");
1068 
1069  maturity_size.write("model/output/maturity_size.tsv");
1070  maturity_age.write("model/output/maturity_age.tsv");
1071 
1072  mortality.write("model/output/mortality.tsv");
1073  survival.write("model/output/survival.tsv");
1074 
1075  movement_region.write("model/output/movement_region.tsv");
1076  movement_size.write("model/output/movement_size.tsv");
1077  movement_age.write("model/output/movement_age.tsv");
1078 
1079  selectivity_size.write("model/output/selectivity_size.tsv");
1080  selectivity_age.write("model/output/selectivity_age.tsv");
1081 
1082  catchability.write("model/output/catchability.tsv");
1083  }
1084 
1085 };
1086 
1087 }
Definition: data.hpp:6
Array< double, Region > biomass_spawners
Definition: model.hpp:29
void initialise(void)
Definition: model.hpp:539
double mortality_mean
Definition: model.hpp:208
double growth_rate_1
Definition: model.hpp:129
Array< double, Region > biomass
Definition: model.hpp:24
Definition: model.hpp:13
Array< double, Region, Method > exploitation_rate_specified
Definition: model.hpp:333
void movement_uniform(void)
Definition: model.hpp:417
Array< double, RegionFrom, Region > movement_region
Definition: model.hpp:247
void msy_go(void)
Definition: model.hpp:985
Array< double, Region > biomass_spawners_unfished
Definition: model.hpp:37
Array< double, Region, Method > catchability
Definition: model.hpp:326
Array< double, Size > length_size
Definition: model.hpp:141
double biomass_status(void) const
Definition: model.hpp:399
Array< double, Method, SelectivityKnot > selectivity_values
Definition: model.hpp:274
double recruits_sd
Definition: model.hpp:89
void catches_set(double catches_, double error=0.2)
Definition: model.hpp:493
Array< double, Region, Method > catches_taken
Definition: model.hpp:339
Array< double, Age > mortality
Definition: model.hpp:227
void equilibrium(void)
Definition: model.hpp:853
Array< Normal, Age > length_age
Definition: model.hpp:146
Array< double, Method, Size > selectivity_size
Definition: model.hpp:279
Definition: distributions.hpp:4
void fishing_mortality_set(double value)
Definition: model.hpp:476
double weight_length_a
Definition: model.hpp:165
Definition: distributions.hpp:188
Frame yield_per_recruit(void)
Definition: model.hpp:961
Array< double, Region > recruits_unfished
Definition: model.hpp:63
double recruits_autocorr
Definition: model.hpp:99
Array< double, Age > survival
Definition: model.hpp:232
double maturity_length_inflection
Definition: model.hpp:186
double recruits_steepness
Definition: model.hpp:68
void exploitation_rate_set(double value)
Definition: model.hpp:451
Array< double, Size > weight_size
Definition: model.hpp:171
Array< double, Age, Size > age_size
Definition: model.hpp:151
double fishing_mortality_get(void) const
Definition: model.hpp:484
double movement_length_inflection
Definition: model.hpp:252
Frame yield_curve(double step=0.01)
Definition: model.hpp:935
Array< double, Size > maturity_size
Definition: model.hpp:192
double msy
Definition: model.hpp:358
Array< double, Region, Quarter > biomass_spawning_unfished
Definition: model.hpp:58
Array< double, Region, Method > exploitation_rate
Definition: model.hpp:344
void effort_set(double effort_)
Definition: model.hpp:524
void write(void)
Definition: model.hpp:1055
Array< double, Region > recruits_determ
Definition: model.hpp:79
Array< double, Region, Method > effort
Definition: model.hpp:321
double e_40
Definition: model.hpp:367
void spawning_uniform(void)
Definition: model.hpp:429
Array< double, Region, Method > biomass_vulnerable
Definition: model.hpp:301
void msy_find(void)
Definition: model.hpp:1006
void update(uint time)
Definition: model.hpp:681
Array< double, Region, Age > escapement
Definition: model.hpp:349
void b40_find(void)
Definition: model.hpp:1041
Array< double, Region, Method > catches
Definition: model.hpp:313
Normal recruits_distrib
Definition: model.hpp:94
void status_go(const double &status)
Definition: model.hpp:1022
Array< double, Region, Age > numbers
Definition: model.hpp:19
Array< double, Region > recruits
Definition: model.hpp:114
Array< double, Region, Quarter > biomass_spawning
Definition: model.hpp:52
Array< double, Region, Method > cpue
Definition: model.hpp:307
Definition: distributions.hpp:262
Array< double, Quarter > spawning
Definition: model.hpp:47
double exploitation_rate_get(void) const
Definition: model.hpp:467