From c48e891bdbcc8eeb92d9ef488b7b6ea4dcc1b91d Mon Sep 17 00:00:00 2001 From: RickMethot Date: Wed, 8 Feb 2023 16:24:40 -0800 Subject: [PATCH 01/58] first commit for B-H with ab add S-R option 10 for a,b formulation --- SS_benchfore.tpl | 12 ++--- SS_param.tpl | 1 + SS_popdyn.tpl | 33 +++++++++++--- SS_readcontrol_330.tpl | 11 ++++- SS_recruit.tpl | 85 ++++++++++++++++++----------------- SS_write_report.tpl | 8 +++- StockSynthesis.code-workspace | 1 + 7 files changed, 94 insertions(+), 57 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index cc9b6f97..290028fd 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -902,7 +902,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } // SPAWN-RECR: calc equil spawn-recr in YPR; need to make this area-specific - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work(2), SR_parm_work(3), SSB_unf, Recr_unf, SSB_equil); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSB_equil); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bspr = Equ_SpawnRecr_Result(1); Bspr_rec = Equ_SpawnRecr_Result(2); @@ -1017,7 +1017,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F0.1: " << Btgt_Fmult << endl; SPR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work(2), SR_parm_work(3), SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt = Equ_SpawnRecr_Result(1); Btgt_Rec = Equ_SpawnRecr_Result(2); YPR_Btgt_enc = YPR_enc; // total encountered yield per recruit @@ -1111,7 +1111,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SPR_Btgt = SSB_equil / SPR_unfished; // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific SPR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work(2), SR_parm_work(3), SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1331,7 +1331,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SPR_unfished; SPR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work(2), SR_parm_work(3), SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); Recr_msy = Equ_SpawnRecr_Result(2); yld1(1) = YPR_opt * Recr_msy; @@ -1424,7 +1424,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SPR_unfished; SPR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work(2), SR_parm_work(3), SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); Recr_msy = Equ_SpawnRecr_Result(2); Profit = (PricePerF * YPR_val_vec) * Recr_msy - Cost; @@ -1718,7 +1718,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SPR_Btgt2 = SSB_equil / SPR_unfished; // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific SPR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work(2), SR_parm_work(3), SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } diff --git a/SS_param.tpl b/SS_param.tpl index 9ddf9a86..da7d0d5e 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -416,6 +416,7 @@ PARAMETER_SECTION // note that bycatch_F(1,Nfleet,1,nseas) has similar role number alpha; number beta; + number steepness; number GenTime; number Yield; number Adj4010; diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index e6c64a53..1548b7d4 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -337,17 +337,38 @@ FUNCTION void get_initial_conditions() Fishon = 0; virg_fec = fec; Recr.initialize(); // will store recruitment by area + + // SPAWN-RECR: get expected recruitment globally or by area + if (recr_dist_area == 1 || pop == 1) // do global spawn_recruitment calculations + { + equ_Recr = 1.0; + Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation. Returns SPR because R = 1.0 + SPR_virgin = SSB_equil; // spawners per recruit. Needed for Sr_fxn = 10 + + if(SR_fxn == 10) // B-H with a,b + { + alpha = mfexp(SR_parm(3)); + beta = mfexp(SR_parm(4)); + steepness = alpha * SPR_virgin / (4.00 + alpha * SPR_virgin); + Recr_virgin = 1.0 / beta * (alpha - ( 1.0 / SPR_virgin)); + SR_parm(1) = log(Recr_virgin); + SR_parm(2) = steepness; + // warning<< SR_parm(1) << " Ln(R0) " << mfexp(SR_parm(1)) << endl + // << " alpha_beta: "< SSB_virgin_adj) { SSB_BH1 = SSB_virgin_adj; @@ -167,6 +157,14 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab NewRecruits = Recr_virgin_adj * temp * mfexp(RkrTop); break; } + + case 10: // Beverton-Holt with alpha beta + { + alpha = mfexp(SR_parm_work(3)); + beta = mfexp(SR_parm_work(4)); + NewRecruits = (alpha*SSB_curr_adj) / (1.0 + beta * SSB_curr_adj); + break; + } } RETURN_ARRAYS_DECREMENT(); return NewRecruits; @@ -270,7 +268,7 @@ FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_vir //******************************************************************** /* SS_Label_FUNCTION 44 Equil_Spawn_Recr_Fxn */ // SPAWN-RECR: function Equil_Spawn_Recr_Fxn -FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const prevariable& SRparm2, const prevariable& SRparm3, +FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, const prevariable& SSB_virgin, const prevariable& Recr_virgin, const prevariable& SPR_temp) { RETURN_ARRAYS_INCREMENT(); @@ -286,7 +284,7 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const prevariable& SRparm2, const prev dvariable srz_min; dvariable SRZ_surv; - steepness = SRparm2; // common usage but some different + steepness = SRparm(2); // common usage but some different // SS_Label_44.1 calc equilibrium SpawnBio and Recruitment from input SPR_temp, which is spawning biomass per recruit at some given F level switch (SR_fxn) { @@ -296,16 +294,7 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const prevariable& SRparm2, const prev write_message (FATAL, 0); // EXIT! break; } - // SS_Label_44.1.1 Beverton-Holt with flattop beyond Bzero - case 6: //Beverton-Holt - { - alpha = 4.0 * steepness * Recr_virgin / (5. * steepness - 1.); - beta = (SSB_virgin * (1. - steepness)) / (5. * steepness - 1.); - B_equil = alpha * SPR_temp - beta; - B_equil = posfun(B_equil, 0.0001, temp); - R_equil = (4. * steepness * Recr_virgin * B_equil) / (SSB_virgin * (1. - steepness) + (5. * steepness - 1.) * B_equil); - break; - } + // SS_Label_44.1.2 Ricker case 2: // Ricker { @@ -314,17 +303,32 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const prevariable& SRparm2, const prev break; } - // SS_Label_44.1.3 Beverton-Holt + // SS_Label_44.1.1 Beverton-Holt + case 6: //Beverton-Holt with flattop beyond Bzero, but no flattop in equil calcs + { + } + // SS_Label_44.1.3 Beverton-Holt case 3: // same as case 6 { - alpha = 4.0 * steepness * Recr_virgin / (5. * steepness - 1.); - beta = (SSB_virgin * (1. - steepness)) / (5. * steepness - 1.); + dvariable SPR = SSB_virgin / Recr_virgin; + alpha = ((4.0 * steepness) / (1. - steepness)) / SPR ; + beta = (1.0 / Recr_virgin) * (alpha - (1.0 / SPR)); B_equil = alpha * SPR_temp - beta; B_equil = posfun(B_equil, 0.0001, temp); R_equil = (4. * steepness * Recr_virgin * B_equil) / (SSB_virgin * (1. - steepness) + (5. * steepness - 1.) * B_equil); //Beverton-Holt break; } + case 10: // Beverton-Holt with alpha and beta parameterization + { + alpha = mfexp(SRparm(3)); + beta = mfexp(SRparm(4)); + B_equil = alpha * SPR_temp - beta; + B_equil = posfun(B_equil, 0.0001, temp); + R_equil = (alpha * Recr_virgin * B_equil) / (1.0 + beta * Recr_virgin * B_equil); + break; + } + // SS_Label_44.1.4 constant recruitment case 4: // constant; no bias correction { @@ -335,7 +339,7 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const prevariable& SRparm2, const prev // SS_Label_44.1.5 Hockey Stick case 5: // hockey stick { - alpha = SRparm3 * Recr_virgin; // min recruitment level + alpha = SRparm(3) * Recr_virgin; // min recruitment level // temp=SSB_virgin/R0*steepness; // spawners per recruit at inflection beta = (Recr_virgin - alpha) / (steepness * SSB_virgin); // slope of recruitment on spawners below the inflection B_equil = Join_Fxn(0.0 * SSB_virgin / Recr_virgin, SSB_virgin / Recr_virgin, SSB_virgin / Recr_virgin * steepness, SPR_temp, alpha / ((1. / SPR_temp) - beta), SPR_temp * Recr_virgin); @@ -347,9 +351,8 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const prevariable& SRparm2, const prev { SRZ_0 = log(1.0 / (SSB_virgin / Recr_virgin)); srz_min = SRZ_0 * (1.0 - steepness); - B_equil = SSB_virgin * (1. - (log(1. / SPR_temp) - SRZ_0) / pow((srz_min - SRZ_0), (1. / SRparm3))); - B_equil = posfun(B_equil, 0.0001, temp); - SRZ_surv = mfexp((1. - pow((B_equil / SSB_virgin), SRparm3)) * (srz_min - SRZ_0) + SRZ_0); // survival + B_equil = SSB_virgin * (1. - (log(1. / SPR_temp) - SRZ_0) / pow((srz_min - SRZ_0), (1. / SRparm(3)))); + SRZ_surv = mfexp((1. - pow((B_equil / SSB_virgin), SRparm(3))) * (srz_min - SRZ_0) + SRZ_0); // survival R_equil = B_equil * SRZ_surv; break; } @@ -367,14 +370,14 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const prevariable& SRparm2, const prev // REC = (TOP/BOT)**(1.0/POWER)*SPRF0/SPR // Power = exp(logC); // Hupper = 1.0/(5.0 * pow(0.2,Power)); - Shepherd_c = SRparm3; - Shepherd_c2 = pow(0.2, SRparm3); + Shepherd_c = SRparm(3); + Shepherd_c2 = pow(0.2, SRparm(3)); Hupper = 1.0 / (5.0 * Shepherd_c2); - steepness = 0.2 + (SRparm2 - 0.2) / (0.8) * (Hupper - 0.2); + steepness = 0.2 + (SRparm(2) - 0.2) / (0.8) * (Hupper - 0.2); Shep_top = 5.0 * steepness * (1.0 - Shepherd_c2) * (SPR_temp * Recr_virgin) / SSB_virgin - (1.0 - 5.0 * steepness * Shepherd_c2); Shep_bot = 5.0 * steepness - 1.0; Shep_top2 = posfun(Shep_top, 0.001, temp); - R_equil = (SSB_virgin / SPR_temp) * pow((Shep_top2 / Shep_bot), (1.0 / SRparm3)); + R_equil = (SSB_virgin / SPR_temp) * pow((Shep_top2 / Shep_bot), (1.0 / SRparm(3))); B_equil = R_equil * SPR_temp; break; } @@ -382,8 +385,8 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const prevariable& SRparm2, const prev // SS_Label_43.3.8 Ricker-power case 9: // Ricker power 3-parameter SRR. per Punt & Cope 2017 { - steepness = SRparm2; - dvariable RkrPower = SRparm3; + steepness = SRparm(2); + dvariable RkrPower = SRparm(3); temp = SSB_virgin / (SPR_temp * Recr_virgin); dvariable RkrTop = pow(0.8, RkrPower) * log(temp) / log(5.0 * steepness); RkrTop = posfun(RkrTop, 0.000001, CrashPen); diff --git a/SS_write_report.tpl b/SS_write_report.tpl index f51aa464..07528817 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -1783,8 +1783,12 @@ FUNCTION void write_bigoutput() << pick_report_name(19); SS2out << " Function: " << SR_fxn << " RecDev_method: " << do_recdev << " sum_recdev: " << sum_recdev << endl << SR_parm(1) << " Ln(R0) " << mfexp(SR_parm(1)) << endl - << steepness << " steepness" << endl + << steepness << " steepness " << "#_derived_alpha_beta: "< Date: Mon, 13 Feb 2023 17:36:35 -0800 Subject: [PATCH 02/58] revise to use WHAM syntax --- SS_benchfore.tpl | 5 ++++- SS_popdyn.tpl | 5 ++--- SS_recruit.tpl | 43 ++++++++++++++++++++++++++++--------------- SS_write_report.tpl | 23 +++++++++++++++++------ 4 files changed, 51 insertions(+), 25 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 290028fd..512803fe 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -748,6 +748,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Recr_unf = mfexp(SR_parm_work(1)); Do_Equil_Calc(Recr_unf); SSB_unf = SSB_equil; + report5<<" calc SSBunf "< SSB_virgin_adj) { SSB_BH1 = SSB_virgin_adj; @@ -162,7 +163,7 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab { alpha = mfexp(SR_parm_work(3)); beta = mfexp(SR_parm_work(4)); - NewRecruits = (alpha*SSB_curr_adj) / (1.0 + beta * SSB_curr_adj); + NewRecruits = (alpha * SSB_curr_adj) / (beta + SSB_curr_adj); break; } } @@ -310,22 +311,34 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, // SS_Label_44.1.3 Beverton-Holt case 3: // same as case 6 { - dvariable SPR = SSB_virgin / Recr_virgin; - alpha = ((4.0 * steepness) / (1. - steepness)) / SPR ; - beta = (1.0 / Recr_virgin) * (alpha - (1.0 / SPR)); - B_equil = alpha * SPR_temp - beta; + // from WHAM per Tim Miller: + // WHAM based on R = A*S/(1+B*S) + // log_SR_a = log(4 * SR_h/(exp(log_SPR0)*(1 - SR_h))); + // log_SR_b = log((5*SR_h - 1)/((1-SR_h)*SR_R0*exp(log_SPR0))); + // SR_h = 0.2 * exp(0.8*log(exp(log_SR_a) * exp(log_SPR0))); + // SR_R0 = log(exp(log_SR_a + log_SPR0))/(exp(log_SR_b + log_SPR0)); + + // SS3 previously used alternative formulation: R = A*S/(B+S) + // converting SS3 to align with WHAM + alpha = 4.0 * steepness / (SPR_virgin * (1. - steepness)); + beta = (5.0 * steepness - 1.0) / ((1 - steepness) * SSB_virgin); + B_equil = (alpha * SPR_temp - 1.0) / beta; B_equil = posfun(B_equil, 0.0001, temp); - R_equil = (4. * steepness * Recr_virgin * B_equil) / (SSB_virgin * (1. - steepness) + (5. * steepness - 1.) * B_equil); //Beverton-Holt + R_equil = alpha * B_equil / (1.0 + beta * B_equil); +// report5<<" WHAM Beq "< Date: Mon, 13 Feb 2023 17:43:58 -0800 Subject: [PATCH 03/58] Update .gitignore --- .gitignore | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 7036b5eb..7dfad946 100644 --- a/.gitignore +++ b/.gitignore @@ -7,10 +7,9 @@ *.htp *.obj *.log -ss.tpl -ss3.tpl -ss_opt.tpl -ss_trans.tpl +Compile/ss.tpl +Compile/ss_opt.tpl +Compile/ss_trans.tpl ~$*.* Compile/ss.log Compile/ss3.log From d6aa468c7236bf4c27fc9f4b26ca3e9a01198f45 Mon Sep 17 00:00:00 2001 From: RickMethot Date: Fri, 19 May 2023 11:14:13 -0700 Subject: [PATCH 04/58] Srr=10 now matching SRR=3 --- SS_popdyn.tpl | 15 ++++++++------- SS_readcontrol_330.tpl | 2 +- SS_recruit.tpl | 5 ++--- SS_write_report.tpl | 10 ++++------ 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 766486c6..724ee024 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -347,17 +347,18 @@ FUNCTION void get_initial_conditions() if(SR_fxn == 10) // B-H with a,b { + // WHAM based on R = A*S/(1+B*S) + // log_SR_a = log(4 * SR_h/(exp(log_SPR0)*(1 - SR_h))); + // log_SR_b = log((5*SR_h - 1)/((1-SR_h)*SR_R0*exp(log_SPR0))); + // h = a * SPR0 / (4. + a * SPR0) + // R0 = 1/b * (a-1/SPR0) + alpha = mfexp(SR_parm(3)); beta = mfexp(SR_parm(4)); - alpha = 4.0 * steepness / (SPR_virgin * (1. - steepness)); - beta = (5.0 * steepness - 1.0) / ((1 - steepness) * SSB_virgin); + steepness = alpha * SPR_virgin / (4. + alpha * SPR_virgin); + Recr_virgin = 1. / beta * (alpha - (1. / SPR_virgin)); SR_parm(1) = log(Recr_virgin); SR_parm(2) = steepness; - // warning<< SR_parm(1) << " Ln(R0) " << mfexp(SR_parm(1)) << endl - // << " alpha_beta: "< Date: Fri, 19 May 2023 17:06:15 -0700 Subject: [PATCH 05/58] adding reporting for timevary growth --- SS_benchfore.tpl | 8 ++++++++ SS_popdyn.tpl | 8 ++++++++ SS_write_report.tpl | 14 ++++++++------ StockSynthesis.code-workspace | 3 ++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 512803fe..5bd02654 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -3652,6 +3652,14 @@ FUNCTION void Get_Forecast() Smry_Table(y, 11) = SSB_equil; Smry_Table(y, 13) = GenTime; + if( SR_fxn == 10 ) + { + temp = SSB_equil / equ_Recr; // current year's SPB/R with current biology at age + alpha = mfexp(SR_parm_work(3)); + beta = mfexp(SR_parm_work(4)); + SR_parm_byyr(y, 2) = alpha * temp / (4. + alpha * temp); // implied steepness + SR_parm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 + } Fishon = 1; Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation if (STD_Yr_Reverse_Ofish(y) > 0) diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 724ee024..58476d6c 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -1785,6 +1785,14 @@ FUNCTION void get_time_series() Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation with current year's biology Smry_Table(y, 11) = SSB_equil; Smry_Table(y, 13) = GenTime; + if( SR_fxn == 10 ) + { + temp = SSB_equil / Recr_virgin; // current year's SPB/R with current biology at age + alpha = mfexp(SR_parm_work(3)); + beta = mfexp(SR_parm_work(4)); + SR_parm_byyr(y, 2) = alpha * temp / (4. + alpha * temp); // implied steepness + SR_parm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 + } Fishon = 1; Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation with current year's biology and F if (STD_Yr_Reverse_Ofish(y) > 0) diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 0c4dcdaf..0eb617ff 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -1789,7 +1789,7 @@ FUNCTION void write_bigoutput() if (SR_fxn == 10) { SS2out << " Ln_alpha_parameter: " << SR_parm(3) << " alpha " << mfexp(SR_parm(3)) << endl; - SS2out << " Ln_beta_parameter: " << SR_parm(4) << " beta " << mfexp(SR_parm(4)) << endl; + SS2out << " Ln_beta_parameter: " << SR_parm(4) << " beta " << mfexp(SR_parm(4)); } else if (SR_fxn == 3) { @@ -1813,9 +1813,7 @@ FUNCTION void write_bigoutput() { SS2out << " Ricker_Power: " << SR_parm(3); } - - SS2out << endl; - SS2out << sigmaR << " sigmaR" << endl; + SS2out << endl << sigmaR << " sigmaR" << endl; SS2out << init_equ_steepness << " # 0/1 to use steepness in initial equ recruitment calculation" << endl; SS2out << SR_parm(N_SRparm2 - 1) << " init_eq: see below" << endl @@ -1848,7 +1846,7 @@ FUNCTION void write_bigoutput() } SS2out << endl; - SS2out << "Yr SpawnBio exp_recr with_regime bias_adjusted pred_recr dev biasadjuster era mature_bio mature_num raw_dev" << endl; + SS2out << "Yr SpawnBio exp_recr with_regime bias_adjusted pred_recr dev biasadjuster era mature_bio mature_num raw_dev SPR0 h R0" << endl; SS2out << "S/Rcurve " << SSB_virgin << " " << Recr_virgin << endl; y = styr - 2; SS2out << "Virg " << SSB_yr(y) << " " << exp_rec(y) << " - " << 0.0 << " Virg " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " 0.0 " << endl; @@ -1899,7 +1897,11 @@ FUNCTION void write_bigoutput() { SS2out << " _ _ Fixed"; } - SS2out << endl; + temp = Smry_Table(y,11) / Recr_virgin; + alpha = mfexp(SR_parm_byyr(y,3)); + beta = mfexp(SR_parm_byyr(y,4)); + SS2out << " " << temp << " " << alpha * temp / (4. + alpha * temp) << " " << 1. / beta * (alpha - (1. / temp)); + SS2out << SR_parm_byyr(y)(1,4) << endl; } // REPORT_KEYWORD SPAWN_RECR_CURVE diff --git a/StockSynthesis.code-workspace b/StockSynthesis.code-workspace index cdd30489..14159ac5 100644 --- a/StockSynthesis.code-workspace +++ b/StockSynthesis.code-workspace @@ -11,7 +11,8 @@ "*.htp": "c", "ostream": "c", "xlocale": "c", - "iosfwd": "c" + "iosfwd": "c", + "cmath": "c" }, "explorer.excludeGitIgnore": true } From a1722ebb063e58b12c982bb748cb2ab8ba0430f9 Mon Sep 17 00:00:00 2001 From: RickMethot Date: Wed, 31 May 2023 09:40:07 -0700 Subject: [PATCH 06/58] WIP --- SS_benchfore.tpl | 19 ++++++++++++------- SS_recruit.tpl | 5 ++++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 5bd02654..657cc7ee 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -748,18 +748,22 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Recr_unf = mfexp(SR_parm_work(1)); Do_Equil_Calc(Recr_unf); SSB_unf = SSB_equil; - report5<<" calc SSBunf "< Date: Wed, 22 May 2024 16:11:03 -0700 Subject: [PATCH 07/58] working version with a,b --- SS_recruit.tpl | 41 +++++++++++++++++++---------------------- SS_write_report.tpl | 8 ++++---- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/SS_recruit.tpl b/SS_recruit.tpl index c24509c0..5553dd26 100644 --- a/SS_recruit.tpl +++ b/SS_recruit.tpl @@ -49,15 +49,19 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab case 3: // Beverton-Holt { steepness = SR_parm_work(2); -// dvariable SPR = SSB_virgin_adj / Recr_virgin; -// dvariable alpha = (4.0 * steepness) / ( SPR * (1. - steepness)) ; -// dvariable beta = (5.0 * steepness - 1.0 )/((1.0 - steepness ) * Recr_virgin * SPR ); -// beta = (1.0 / Recr_virgin) * (alpha - (1.0 / SPR)); NewRecruits = (4. * steepness * Recr_virgin_adj * SSB_curr_adj) / (SSB_virgin_adj * (1. - steepness) + (5. * steepness - 1.) * SSB_curr_adj); break; } + case 10: // Beverton-Holt with alpha beta per WHAM: R = A*S/(1+B*S) + { + alpha = mfexp(SR_parm_work(3)); + beta = mfexp(SR_parm_work(4)); + NewRecruits = (alpha * SSB_curr_adj) / (1.0 + beta * SSB_curr_adj); + break; + } + // SS_Label_43.3.4 constant expected recruitment case 4: // none { @@ -159,14 +163,6 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab break; } - case 10: // Beverton-Holt with alpha beta - { - // WHAM based on R = A*S/(1+B*S) - alpha = mfexp(SR_parm_work(3)); - beta = mfexp(SR_parm_work(4)); - NewRecruits = (alpha * SSB_curr_adj) / (1.0 + beta * SSB_curr_adj); - break; - } } RETURN_ARRAYS_DECREMENT(); return NewRecruits; @@ -322,18 +318,19 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, SPR_virgin = SSB_virgin / Recr_virgin; alpha = 4.0 * steepness / (SPR_virgin * (1. - steepness)); beta = (5.0 * steepness - 1.0) / ((1 - steepness) * SSB_virgin); - report5<<" alpha "< Date: Tue, 28 May 2024 14:39:34 -0700 Subject: [PATCH 08/58] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7dfad946..a602a79c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ Compile/ss.tpl Compile/ss_opt.tpl Compile/ss_trans.tpl +Compile/ss3.tpl +Compile/Make_SS_warn.bat ~$*.* Compile/ss.log Compile/ss3.log From 4f96850a4e0d2bde613f98c25249601180adef8f Mon Sep 17 00:00:00 2001 From: Rick-Methot-NOAA Date: Wed, 12 Jun 2024 14:50:29 -0700 Subject: [PATCH 09/58] augment spawn_recr report and use to test time-vary SR_parm approach --- SS_benchfore.tpl | 12 ++-- SS_popdyn.tpl | 18 ++++-- SS_readcontrol_330.tpl | 9 +++ SS_recruit.tpl | 13 ++-- SS_write_report.tpl | 139 ++++++++++++++++++++++++++++++++++------- 5 files changed, 156 insertions(+), 35 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 657cc7ee..9f6577d6 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -753,7 +753,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { report5 << "SR_parm for benchmark: " << SR_parm_work << endl << "mean from years: " << Bmark_Yr(9) << " " << Bmark_Yr(10) << endl; - SPR_virgin = SSB_virgin / Recr_virgin; + // SPR_virgin = SSB_virgin / Recr_virgin; // already defined Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR report5 << " Virgin SPR0, SSB, R: " << SPR_virgin << " " << Equ_SpawnRecr_Result << endl; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_unfished); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR @@ -1906,15 +1906,15 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } else if (show_MSY == 2) // do brief output { - SS2out << SPR_actual / 100. << " " << SPR_Fmult << " " << Mgmt_quant(10) << " " << YPR_spr_dead / Vbio1_spr << " " << Bspr_rec << " " + report5 << SPR_actual / 100. << " " << SPR_Fmult << " " << Mgmt_quant(10) << " " << YPR_spr_dead / Vbio1_spr << " " << Bspr_rec << " " << Bspr << " " << YPR_spr_dead * Bspr_rec << " " << YPR_spr_ret * Bspr_rec << " " << Vbio1_spr * Bspr_rec << " # "; - SS2out << SPR_Btgt << " " << Btgt / SSB_unf << " " << Btgt_Fmult << " " << Mgmt_quant(7) << " " << YPR_Btgt_dead / Vbio1_Btgt << " " << Btgt_Rec << " " + report5 << SPR_Btgt << " " << Btgt / SSB_unf << " " << Btgt_Fmult << " " << Mgmt_quant(7) << " " << YPR_Btgt_dead / Vbio1_Btgt << " " << Btgt_Rec << " " << Btgt << " " << YPR_Btgt_dead * Btgt_Rec << " " << YPR_Btgt_ret * Btgt_Rec << " " << Vbio1_Btgt * Btgt_Rec << " # "; - SS2out << MSY_SPR << " " << Bmsy / SSB_unf << " " << MSY_Fmult << " " << Mgmt_quant(14) << " " << MSY / (Vbio1_MSY * Recr_msy) << " " << Recr_msy << " " + report5 << MSY_SPR << " " << Bmsy / SSB_unf << " " << MSY_Fmult << " " << Mgmt_quant(14) << " " << MSY / (Vbio1_MSY * Recr_msy) << " " << Recr_msy << " " << Bmsy << " " << MSY << " " << YPR_msy_dead * Recr_msy << " " << YPR_msy_ret * Recr_msy << " " << Vbio1_MSY * Recr_msy << " # " << endl; } @@ -2580,6 +2580,7 @@ FUNCTION void Get_Forecast() } } // SPAWN-RECR: get recruitment in forecast; needs to be area-specific + // SR_fxn if (SR_parm_timevary(1) == 0) // R0 is not time-varying { R0_use = Recr_virgin; @@ -3218,7 +3219,8 @@ FUNCTION void Get_Forecast() } } // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass - // SPAWN-RECR: calc recruitment in time series; need to make this area-specififc + // SPAWN-RECR: calc recruitment in time series; need to make this area-specific + // SR_fxn if (SR_parm_timevary(1) == 0) // R0 is not time-varying { R0_use = Recr_virgin; diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 58476d6c..265e2c37 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -357,6 +357,7 @@ FUNCTION void get_initial_conditions() beta = mfexp(SR_parm(4)); steepness = alpha * SPR_virgin / (4. + alpha * SPR_virgin); Recr_virgin = 1. / beta * (alpha - (1. / SPR_virgin)); +// warning << " before AB_calcs " << "parm " << SR_parm(1) << " calc " << log(Recr_virgin) << endl; SR_parm(1) = log(Recr_virgin); SR_parm(2) = steepness; } @@ -370,6 +371,8 @@ FUNCTION void get_initial_conditions() SR_parm_virg(i) = SR_parm(i); SR_parm_work(i) = SR_parm(i); } +// if (SR_fxn == 3) warning << "tester_A: " << SR_parm_work(1) << " base: " << SR_parm(1) << endl; +// if (SR_fxn == 10) warning << "tester_A: " << SR_parm_work(4) << " base: " << SR_parm(4) << endl; equ_Recr = Recr_virgin; exp_rec(eq_yr, 1) = Recr_virgin; // expected Recr from s-r parms exp_rec(eq_yr, 2) = Recr_virgin; @@ -476,6 +479,9 @@ FUNCTION void get_initial_conditions() else { SR_parm_work(f) = parm_timevary(SR_parm_timevary(f), eq_yr); +// warning << "tester_B: " << SR_parm_work(f) << " timevary " << " base " << SR_parm(f) < 0 || SR_parm_timevary(4) > 0) ) {SR_update_SPR0 = 1;} // alpha or beta is time-varying + else if ((SR_parm_timevary(1) > 0 || SR_parm_timevary(2) > 0) ) {SR_update_SPR0 = 1;} // R0 or steepness is time-varying } } N_SRparm3 = N_SRparm2; diff --git a/SS_recruit.tpl b/SS_recruit.tpl index 5553dd26..2065b277 100644 --- a/SS_recruit.tpl +++ b/SS_recruit.tpl @@ -22,6 +22,7 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab dvariable SRZ_0; dvariable srz_min; dvariable SRZ_surv; +// warning << y << " Tester_R0 " << Recr_virgin_adj << " SSB0 " << SSB_virgin_adj << " SSB_curr: " << SSB_current << endl; // SS_Label_43.1 add 0.1 to input spawning biomass value to make calculation more rebust SSB_curr_adj = SSB_current + 0.100; // robust @@ -56,8 +57,8 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab case 10: // Beverton-Holt with alpha beta per WHAM: R = A*S/(1+B*S) { - alpha = mfexp(SR_parm_work(3)); - beta = mfexp(SR_parm_work(4)); + dvariable alpha = mfexp(SR_parm_work(3)); + dvariable beta = mfexp(SR_parm_work(4)); NewRecruits = (alpha * SSB_curr_adj) / (1.0 + beta * SSB_curr_adj); break; } @@ -315,10 +316,12 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, // SS3 previously used alternative formulation: R = A*S/(B+S) // converting SS3 to align with WHAM - SPR_virgin = SSB_virgin / Recr_virgin; + // SPR_virgin = SSB_virgin / Recr_virgin; // this is already defined alpha = 4.0 * steepness / (SPR_virgin * (1. - steepness)); beta = (5.0 * steepness - 1.0) / ((1 - steepness) * SSB_virgin); + // " h " << steepness << " derive " << alpha * SPR_virgin / (4. + alpha * SPR_virgin) << " " << endl; + // " R0 " << Recr_virgin << " derive " << 1. / beta * (alpha - 1./SPR_virgin) << endl; // report5 <<" SSB_unf "< 0 && j <= 4 ) // timevary SRparm exists + {SS2out << " #_is_time_vary,_so_SRR_updates_base_SPR_annually";} + if (j == (N_SRparm2 - 1) && SR_parm_timevary(j) > 0) // timevary regime exists + {SS2out << " #_Persistent_deviations_from_SRR_(e.g.regimes)_exist";} + SS2out << endl; + } + + SS2out << "# " < Bmark_Yr(k)) + {SS2out << "#_range_of_years_is_averaged,_so_reduces_standard_error_of_result;_do_this_only_when_timevarying_makes_necessary: " << k << " "<< k+1 << endl;} + } + SS2out << "SPR_unfished_benchmark: " << Mgmt_quant(1) / Mgmt_quant(4) << " #_based_on_averaging_biology_over_benchmark_year_range " << endl; + SS2out << "Bmsy/Bzero: "<< Bmsy / SSB_virgin << " # using styr bio for Bzero" << endl; + SS2out << "Bmsy/Bunf: "<< Bmsy / Mgmt_quant(1) << " # using MSY's averaged bio for Bunf" << endl; + + SS2out << "#" << endl << "RecDev_method: " << do_recdev << endl << "sum_recdev: " << sum_recdev << endl << "recr_logL: " << recr_like << endl; + SS2out << recdev_start << " " << recdev_end << " main_recdev:start_end" << endl + << recdev_adj(1) << " " << recdev_adj(2, 5) << " breakpoints_for_bias_adjustment_ramp " << endl; + + temp = sigmaR * sigmaR; // sigmaR^2 + SS2out << "ERA N RMSE RMSE^2/sigmaR^2 mean_BiasAdj est_rho Durbin-Watson" << endl; + SS2out << "main " << n_rmse(1) << " " << rmse(1) << " " << square(rmse(1)) / temp << " " << rmse(2) << " " << cross / var << " " << Durbin; + if (wrote_bigreport == 0) // first time writing bigreport + { + if (rmse(1) < 0.5 * sigmaR && rmse(2) > (0.01 + 2.0 * square(rmse(1)) / temp)) + { + warnstream << "Main recdev biasadj is >2 times ratio of rmse to sigmaR"; + SS2out << " # " << warnstream.str() ; + write_message (WARN, 0); + } + } + SS2out << endl; + + SS2out << "early " << n_rmse(3) << " " << rmse(3) << " " << square(rmse(3)) / temp << " " << rmse(4); + if (wrote_bigreport == 0) // first time writing bigreport + { + if (rmse(3) < 0.5 * sigmaR && rmse(4) > (0.01 + 2.0 * square(rmse(3)) / temp)) + { + warnstream << "Early recdev biasadj is >2 times ratio of rmse to sigmaR"; + SS2out << " # " << warnstream.str(); + write_message (WARN, 0); + } + } + SS2out << endl << "#" << endl << "Initial_equilibrium: " << init_equ_steepness << " # 0/1_to_use_spawner-recruitment_in_initial_equ_recruitment_calculation" << endl << "#" << endl; + + SS2out << "Yr SpawnBio exp_recr with_regime bias_adjusted pred_recr dev biasadjuster era mature_bio mature_num raw_dev SPR0_curr h_curr R0_curr P1 P2 P3 P4" << endl; SS2out << "S/Rcurve " << SSB_virgin << " " << Recr_virgin << endl; y = styr - 2; SS2out << "Virg " << SSB_yr(y) << " " << exp_rec(y) << " - " << 0.0 << " Virg " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " 0.0 " << endl; @@ -1897,10 +1994,10 @@ FUNCTION void write_bigoutput() { SS2out << " _ _ Fixed"; } - dvariable SPR = Smry_Table(y, 11) / Recr_virgin; - alpha = mfexp(SR_parm_byyr(y,3)); - beta = mfexp(SR_parm_byyr(y,4)); - SS2out << " " << SPR << " " << alpha * SPR / (4. + alpha * SPR) << " " << 1. / beta * (alpha - (1. / SPR)); + dvariable SPR_curr = Smry_Table(y, 11) / Recr_virgin; + SS2out << " " << SPR_curr << " "; + SS2out << alpha * SPR_curr / (4. + alpha * SPR_curr) << " "; // steepness with current SPR + SS2out << 1. / beta * (alpha - (1. / SPR_curr)) << " "; // R0 with current SPR SS2out << SR_parm_byyr(y)(1,4) << endl; } From 707aa32d73b66a2fd61cab99bdfa47287895480d Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Wed, 26 Jun 2024 15:05:50 -0700 Subject: [PATCH 10/58] adding benchmark change --- SS_benchfore.tpl | 4 ++-- SS_write_report.tpl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 9f6577d6..30802ac0 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -1340,7 +1340,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) MSY_SPR = SSB_equil / SPR_unfished; SPR_temp = SSB_equil; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - Bmsy = Equ_SpawnRecr_Result(1); + Bmsy = Equ_SpawnRecr_Result(1); // with MSY set to SPR, not directly estimated Recr_msy = Equ_SpawnRecr_Result(2); yld1(1) = YPR_opt * Recr_msy; YPR_msy_enc = YPR_enc; @@ -1433,7 +1433,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) MSY_SPR = SSB_equil / SPR_unfished; SPR_temp = SSB_equil; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - Bmsy = Equ_SpawnRecr_Result(1); + Bmsy = Equ_SpawnRecr_Result(1); // MSY is directly estimated Recr_msy = Equ_SpawnRecr_Result(2); Profit = (PricePerF * YPR_val_vec) * Recr_msy - Cost; if (Do_MSY == 2) // dead catch without excluded bycatch fleets diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 61ce49f8..0f0d10e9 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -1851,7 +1851,7 @@ FUNCTION void write_bigoutput() SS2out << "# " < Date: Wed, 3 Jul 2024 15:30:57 -0700 Subject: [PATCH 11/58] format changes for spawn_recr report --- SS_readcontrol_330.tpl | 6 +++++- SS_write_report.tpl | 40 ++++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 58f24521..0a66f8e0 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1986,7 +1986,11 @@ SR_update_SPR0 = 0; //#_SR_function: 1=null; 2=Ricker; 3=std_B-H; 4=SCAA; 5=Hockey; 6=B-H_flattop; 7=Survival_3Parm; 10=B-H with a,b "< 0 && j <= 4 ) // timevary SRparm exists {SS2out << " #_is_time_vary,_so_SRR_updates_base_SPR_annually";} if (j == (N_SRparm2 - 1) && SR_parm_timevary(j) > 0) // timevary regime exists - {SS2out << " #_Persistent_deviations_from_SRR_(e.g.regimes)_exist";} + {SS2out << " #_Regime_parameter_used_to_offset_from_SRR";} SS2out << endl; } @@ -1869,8 +1870,8 @@ FUNCTION void write_bigoutput() { SS2out << "Ln(alpha): " << SR_parm(3) << " alpha " << mfexp(SR_parm(3)) << endl; SS2out << "Ln(beta): " << SR_parm(4) << " beta " << mfexp(SR_parm(4)) << endl; - SS2out << "steepness_derived: " << alpha * SPR_virgin / (4. + alpha * SPR_virgin) << endl; // steepness virgin SS2out << "ln(R0)_derived: " << log( 1. / beta * (alpha - (1. / SPR_virgin))) << endl; // virgin R0 + SS2out << "steepness_derived: " << alpha * SPR_virgin / (4. + alpha * SPR_virgin) << endl; // steepness virgin break; } case 8: @@ -1882,19 +1883,12 @@ FUNCTION void write_bigoutput() Shepherd_c2 = pow(0.2, Shepherd_c); Hupper = 1.0 / (5.0 * Shepherd_c2); temp = 0.2 + (SR_parm(2) - 0.2) / (0.8) * (Hupper - 0.2); - SS2out << " Shepherd_c: " << Shepherd_c << " steepness_limit: " << Hupper << " Adjusted_steepness: " << temp << endl; - break; - } - case 9: - { - SS2out << " Ricker_Parm1: " << SR_parm(1) << endl; - SS2out << " Ricker_Parm2: " << SR_parm(2) << endl; - SS2out << " Ricker_Power: " << SR_parm(3) << endl; + SS2out << "Shepherd_c: " << Shepherd_c << endl << "Shepard_steepness_limit: " << Hupper << endl << "Shepard_adjusted_steepness: " << temp << endl; break; } default: { - SS2out << "default output needed " << endl; + SS2out << "other_SRR " << endl; break; } } @@ -1914,8 +1908,8 @@ FUNCTION void write_bigoutput() SS2out << "Bmsy/Bunf: "<< Bmsy / Mgmt_quant(1) << " # using MSY's averaged bio for Bunf" << endl; SS2out << "#" << endl << "RecDev_method: " << do_recdev << endl << "sum_recdev: " << sum_recdev << endl << "recr_logL: " << recr_like << endl; - SS2out << recdev_start << " " << recdev_end << " main_recdev:start_end" << endl - << recdev_adj(1) << " " << recdev_adj(2, 5) << " breakpoints_for_bias_adjustment_ramp " << endl; + SS2out << "main_recdev:start_end: " << recdev_start << " " << recdev_end << endl + << "breakpoints_for_bias_adjustment_ramp: " < Date: Tue, 9 Jul 2024 15:13:53 -0700 Subject: [PATCH 12/58] fixes to ss_warn --- Compile/Make_SS_warn.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Compile/Make_SS_warn.bat b/Compile/Make_SS_warn.bat index f53510ee..af9b1430 100644 --- a/Compile/Make_SS_warn.bat +++ b/Compile/Make_SS_warn.bat @@ -28,6 +28,6 @@ tpl2cpp ss3 g++ -c -std=c++17 -O2 -D_FILE_OFFSET_BITS=64 -DUSE_ADMB_CONTRIBS -D_USE_MATH_DEFINES -I. -I"C:\ADMB-13.2\include" -I"C:\ADMB-13.2\include\contrib" -Wall -Wextra -o ss3.obj ss3.cpp -g++ -static -o ss3.exe ss3.obj "C:\ADMB-13.2\lib\libadmb-contrib-mingw64-g++12.a" +g++ -static -o ss3.exe ss3.obj "C:\ADMB-13.2\lib\libadmb-contrib-mingw64-g++13.a" dir *.exe From d11c35ff570f503e8597dbdc6793437ca9174b05 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Tue, 13 Aug 2024 20:06:06 -0700 Subject: [PATCH 13/58] WIP-more work needed on benchmark calcs --- SS_benchfore.tpl | 30 ++++++++++++++++++++------ SS_param.tpl | 1 + SS_popdyn.tpl | 21 +++++++++--------- SS_recruit.tpl | 52 ++++++++++++++++++++++----------------------- SS_write_report.tpl | 6 +++--- 5 files changed, 63 insertions(+), 47 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 30802ac0..66259197 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -744,6 +744,18 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SR_parm_work(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); } } + + if(SR_fxn == 10) // B-H with alpha, beta + { + alpha = mfexp(SR_parm_work(3)); + beta = mfexp(SR_parm_work(4)); + Fishon = 0; + Recr_unf = 1.0; + Do_Equil_Calc(Recr_unf); + SPR_virgin_adj = SSB_equil / 1.0; + SR_parm_work(2) = alpha * SPR_virgin_adj / (4. + alpha * SPR_virgin_adj); // steepness + SR_parm_work(1) = log(1. / beta * (alpha - (1. / SPR_virgin_adj))); // ln(R0) + } Fishon = 0; Recr_unf = mfexp(SR_parm_work(1)); Do_Equil_Calc(Recr_unf); @@ -751,13 +763,17 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SPR_unfished = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin if (show_MSY == 1) { - report5 << "SR_parm for benchmark: " << SR_parm_work << endl + report5 << "SR_parms for benchmark: " << SR_parm_work << endl << "mean from years: " << Bmark_Yr(9) << " " << Bmark_Yr(10) << endl; // SPR_virgin = SSB_virgin / Recr_virgin; // already defined - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Virgin SPR0, SSB, R: " << SPR_virgin << " " << Equ_SpawnRecr_Result << endl; + report5 << " Virgin SSB, R0: " << SSB_virgin << " " << Recr_virgin << " " << SPR_virgin_adj << endl; + report5 << " unfished SSB, R0: " << SSB_unf << " " << Recr_unf << " " << SPR_unfished << " with current biology " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_virgin_adj); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Virgin SPR0, result_SSB, R: " << SPR_virgin_adj << " " << Equ_SpawnRecr_Result << endl << endl; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_unfished); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Benchmark SPR0, SSB, R: " << SPR_unfished << " " << Equ_SpawnRecr_Result << endl; + report5 << " Benchmark SPR0, result_SSB, R: " << SPR_unfished << " " << Equ_SpawnRecr_Result << endl << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_unfished); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Benchmark SPR0, result_SSB, R: " << SPR_unfished << " " << Equ_SpawnRecr_Result << " with virgin spawn-recr " << endl; } SR_parm_work(N_SRparm2 + 1) = SSB_unf; Mgmt_quant(1) = SSB_unf; @@ -1930,7 +1946,7 @@ FUNCTION void Get_Forecast() dvariable OFL_catch; dvariable Fcast_Crash; dvariable totcatch; - dvariable R0_use; + dvariable R0_use; // annually updated variable if SR_update_SPR0 == 1 dvariable SSB_use; dvar_matrix catage_w(1, gmorph, 0, nages); dvar_vector tempcatch(1, Nfleet); @@ -2581,7 +2597,7 @@ FUNCTION void Get_Forecast() } // SPAWN-RECR: get recruitment in forecast; needs to be area-specific // SR_fxn - if (SR_parm_timevary(1) == 0) // R0 is not time-varying + if (SR_update_SPR0 == 0) // R0 is not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; @@ -3221,7 +3237,7 @@ FUNCTION void Get_Forecast() // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_fxn - if (SR_parm_timevary(1) == 0) // R0 is not time-varying + if (SR_update_SPR0 == 0) // R0 is not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; diff --git a/SS_param.tpl b/SS_param.tpl index da7d0d5e..06c280ea 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -166,6 +166,7 @@ PARAMETER_SECTION number half_sigmaRsq; number sigmaR; number SPR_virgin; + number SPR_virgin_adj; number regime_change; number rho; number dirichlet_Parm; diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 265e2c37..3aa6d549 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -344,7 +344,7 @@ FUNCTION void get_initial_conditions() equ_Recr = 1.0; Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation. Returns SPR because R = 1.0 SPR_virgin = SSB_equil; // spawners per recruit. Needed for Sr_fxn = 10 - + SPR_virgin_adj = SSB_equil; if(SR_fxn == 10) // B-H with a,b { // WHAM based on R = A*S/(1+B*S) @@ -355,8 +355,8 @@ FUNCTION void get_initial_conditions() alpha = mfexp(SR_parm(3)); beta = mfexp(SR_parm(4)); - steepness = alpha * SPR_virgin / (4. + alpha * SPR_virgin); - Recr_virgin = 1. / beta * (alpha - (1. / SPR_virgin)); + steepness = alpha * SPR_virgin_adj / (4. + alpha * SPR_virgin_adj); + Recr_virgin = 1. / beta * (alpha - (1. / SPR_virgin_adj)); // warning << " before AB_calcs " << "parm " << SR_parm(1) << " calc " << log(Recr_virgin) << endl; SR_parm(1) = log(Recr_virgin); SR_parm(2) = steepness; @@ -380,7 +380,7 @@ FUNCTION void get_initial_conditions() exp_rec(eq_yr, 4) = Recr_virgin; Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation SSB_virgin = SSB_equil; - SPR_virgin = SSB_equil / Recr_virgin; // spawners per recruit +// SPR_virgin = SSB_equil / Recr_virgin; // spawners per recruit already calculated if(Do_Benchmark==0) { Mgmt_quant(1)=SSB_virgin; @@ -696,7 +696,7 @@ FUNCTION void get_time_series() dvariable crashtemp1; dvariable interim_tot_catch; dvariable Z_adjuster; - dvariable R0_use; + dvariable R0_use; // annually updated variable if SR_update_SPR0 == 1; gets passed to Spawn_Recr() function dvariable SSB_use; if (Do_Morphcomp > 0) @@ -1024,10 +1024,10 @@ FUNCTION void get_time_series() } } - // SS_Label_Info_24.2.3 #Get the total recruitment produced by this spawning biomass + // SS_Label_Info_24.2.3 #Get the total recruitment produced by this spawning biomass at the beginning of the season // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_Fxn relevant keyword - if (SR_parm_timevary(1) == 0) // R0 is not time-varying + if (SR_update_SPR0 == 0) // SRparm are not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; @@ -1035,12 +1035,12 @@ FUNCTION void get_time_series() else { R0_use = mfexp(SR_parm_work(1)); - warning << y << " set R0use to SRparm_work " << R0_use << " vir: " << Recr_virgin << endl; equ_Recr = R0_use; Fishon = 0; eq_yr = y; bio_yr = y; Do_Equil_Calc(R0_use); // call function to do equilibrium calculation + SSB_use = SSB_equil; if (fishery_on_off == 1) { Fishon = 1; @@ -1049,7 +1049,6 @@ FUNCTION void get_time_series() { Fishon = 0; } - SSB_use = SSB_equil; } Recruits = Spawn_Recr(SSB_use, R0_use, SSB_current); // calls to function Spawn_Recr if (SR_fxn != 7) apply_recdev(Recruits, R0_use); // apply recruitment deviation @@ -1485,7 +1484,7 @@ FUNCTION void get_time_series() SSB_yr(y) = SSB_current; } } - // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass + // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass at some time during the season // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_fxn if (SR_update_SPR0 == 0) // SR parms are not time-varying @@ -1501,6 +1500,7 @@ FUNCTION void get_time_series() eq_yr = y; bio_yr = y; Do_Equil_Calc(R0_use); // call function to do equilibrium calculation + SSB_use = SSB_equil; if (fishery_on_off == 1) { Fishon = 1; @@ -1509,7 +1509,6 @@ FUNCTION void get_time_series() { Fishon = 0; } - SSB_use = SSB_equil; } Recruits = Spawn_Recr(SSB_use, R0_use, SSB_current); // calls to function Spawn_Recr diff --git a/SS_recruit.tpl b/SS_recruit.tpl index 2065b277..179ecd6e 100644 --- a/SS_recruit.tpl +++ b/SS_recruit.tpl @@ -268,7 +268,7 @@ FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_vir /* SS_Label_FUNCTION 44 Equil_Spawn_Recr_Fxn */ // SPAWN-RECR: function Equil_Spawn_Recr_Fxn FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, - const prevariable& SSB_virgin, const prevariable& Recr_virgin, const prevariable& SPR_temp) + const prevariable& SSB_temp, const prevariable& RECR_temp, const prevariable& SPR_temp) { RETURN_ARRAYS_INCREMENT(); dvar_vector Equil_Spawn_Recr_Calc(1, 2); // values to return 1 is B_equil, 2 is R_equil @@ -297,8 +297,8 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, // SS_Label_44.1.2 Ricker case 2: // Ricker { - B_equil = SSB_virgin * (1. + (log(Recr_virgin / SSB_virgin) + log(SPR_temp)) / steepness); - R_equil = Recr_virgin * B_equil / SSB_virgin * mfexp(steepness * (1. - B_equil / SSB_virgin)); + B_equil = SSB_temp * (1. + (log(RECR_temp / SSB_temp) + log(SPR_temp)) / steepness); + R_equil = RECR_temp * B_equil / SSB_temp * mfexp(steepness * (1. - B_equil / SSB_temp)); break; } @@ -316,14 +316,14 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, // SS3 previously used alternative formulation: R = A*S/(B+S) // converting SS3 to align with WHAM - // SPR_virgin = SSB_virgin / Recr_virgin; // this is already defined - alpha = 4.0 * steepness / (SPR_virgin * (1. - steepness)); + // SPR_virgin = SSB_temp / RECR_temp; // this is already defined + alpha = 4.0 * steepness / (SPR_virgin_adj * (1. - steepness)); beta = (5.0 * steepness - 1.0) / ((1 - steepness) * SSB_virgin); // " h " << steepness << " derive " << alpha * SPR_virgin / (4. + alpha * SPR_virgin) << " " << endl; - // " R0 " << Recr_virgin << " derive " << 1. / beta * (alpha - 1./SPR_virgin) << endl; -// report5 <<" SSB_unf "< Date: Thu, 15 Aug 2024 17:02:43 -0700 Subject: [PATCH 14/58] WIP2-need-to-fix-SPR-passing_to_benchmark --- SS_benchfore.tpl | 36 ++++++++++++++++++------------------ SS_popdyn.tpl | 17 ++++++++--------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 66259197..67a06898 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -536,7 +536,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) dvariable last_F1; dvariable Closer; dvariable Vbio1_unfished; - dvariable SPR_unfished; + dvariable SPR_unf; dvariable Vbio_MSY; dvariable Vbio1_MSY; dvariable junk; @@ -751,7 +751,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) beta = mfexp(SR_parm_work(4)); Fishon = 0; Recr_unf = 1.0; - Do_Equil_Calc(Recr_unf); + Do_Equil_Calc(Recr_unf); // SPR_virgin_adj = SSB_equil / 1.0; SR_parm_work(2) = alpha * SPR_virgin_adj / (4. + alpha * SPR_virgin_adj); // steepness SR_parm_work(1) = log(1. / beta * (alpha - (1. / SPR_virgin_adj))); // ln(R0) @@ -759,21 +759,21 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Fishon = 0; Recr_unf = mfexp(SR_parm_work(1)); Do_Equil_Calc(Recr_unf); - SSB_unf = SSB_equil; - SPR_unfished = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin + SSB_unf = SSB_equil; // equilibrium unfished SSB using the benchmark averaged Recr_unf and benchmark averaged biology + SPR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin if (show_MSY == 1) { report5 << "SR_parms for benchmark: " << SR_parm_work << endl << "mean from years: " << Bmark_Yr(9) << " " << Bmark_Yr(10) << endl; // SPR_virgin = SSB_virgin / Recr_virgin; // already defined report5 << " Virgin SSB, R0: " << SSB_virgin << " " << Recr_virgin << " " << SPR_virgin_adj << endl; - report5 << " unfished SSB, R0: " << SSB_unf << " " << Recr_unf << " " << SPR_unfished << " with current biology " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl; + report5 << " unfished SSB, R0: " << SSB_unf << " " << Recr_unf << " " << SPR_unf << " with current biology " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_virgin_adj); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR report5 << " Virgin SPR0, result_SSB, R: " << SPR_virgin_adj << " " << Equ_SpawnRecr_Result << endl << endl; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_unfished); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Benchmark SPR0, result_SSB, R: " << SPR_unfished << " " << Equ_SpawnRecr_Result << endl << endl; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_unfished); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Benchmark SPR0, result_SSB, R: " << SPR_unfished << " " << Equ_SpawnRecr_Result << " with virgin spawn-recr " << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Benchmark SPR0, result_SSB, R: " << SPR_unf << " " << Equ_SpawnRecr_Result << endl << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Benchmark SPR0, result_SSB, R: " << SPR_unf << " " << Equ_SpawnRecr_Result << " with virgin spawn-recr " << endl; } SR_parm_work(N_SRparm2 + 1) = SSB_unf; Mgmt_quant(1) = SSB_unf; @@ -808,7 +808,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SPR_target100 = SPR_target * 100.; Do_Equil_Calc(equ_Recr); - SPR_unfished = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin + SPR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin Vbio1_unfished = smrybio; // gets value from equil_calc if (show_MSY == 1) { @@ -854,7 +854,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Fishon = 1; Do_Equil_Calc(equ_Recr); - yld1(ii) = 100. * SSB_equil / SPR_unfished; // spawning potential ratio + yld1(ii) = 100. * SSB_equil / SPR_unf; // spawning potential ratio } SPR_actual = yld1(1); // spawning potential ratio @@ -1008,7 +1008,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) last_F1 = F1(1); if (show_MSY == 1) { - report5 << j << " " << F1(1) << " " << equ_F_std << " " << SSB_equil / SPR_unfished << " " << YPR_opt << " " << F01_actual << " " << F01_second << " last F1 " << last_F1 << " Closer " << Closer << " delta " << (F01_origin * 0.1 - F01_actual) / (F01_second) << endl; + report5 << j << " " << F1(1) << " " << equ_F_std << " " << SSB_equil / SPR_unf << " " << YPR_opt << " " << F01_actual << " " << F01_second << " last F1 " << last_F1 << " Closer " << Closer << " delta " << (F01_origin * 0.1 - F01_actual) / (F01_second) << endl; } F1(1) += (F01_origin * 0.1 - F01_actual) / (F01_second); F1(1) = (1. - Closer) * F1(1) + Closer * last_F1; @@ -1051,7 +1051,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) YPR_Btgt_revenue = (PricePerF * YPR_val_vec) * Btgt_Rec; // vector*vector*scalar // YPR_Btgt_revenue = Price*YPR_ret*Btgt_Rec; YPR_Btgt_profit = YPR_Btgt_revenue - Cost; - SPR_Btgt = SSB_equil / SPR_unfished; + SPR_Btgt = SSB_equil / SPR_unf; Vbio_Btgt = totbio; Vbio1_Btgt = smrybio; Mgmt_quant(7) = equ_F_std; @@ -1131,7 +1131,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // else Hrate for bycatch fleets already set } Do_Equil_Calc(equ_Recr); // where equ_Recr=1.0, so returned SSB_equil is a SSB/R, - SPR_Btgt = SSB_equil / SPR_unfished; + SPR_Btgt = SSB_equil / SPR_unf; // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific SPR_temp = SSB_equil; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR @@ -1353,7 +1353,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Do_Equil_Calc(equ_Recr); // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific - MSY_SPR = SSB_equil / SPR_unfished; + MSY_SPR = SSB_equil / SPR_unf; SPR_temp = SSB_equil; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); // with MSY set to SPR, not directly estimated @@ -1446,7 +1446,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } Do_Equil_Calc(equ_Recr); // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific - MSY_SPR = SSB_equil / SPR_unfished; + MSY_SPR = SSB_equil / SPR_unf; SPR_temp = SSB_equil; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); // MSY is directly estimated @@ -1739,7 +1739,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // else Hrate for bycatch fleets already set } Do_Equil_Calc(equ_Recr); - SPR_Btgt2 = SSB_equil / SPR_unfished; + SPR_Btgt2 = SSB_equil / SPR_unf; // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific SPR_temp = SSB_equil; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR @@ -1947,7 +1947,7 @@ FUNCTION void Get_Forecast() dvariable Fcast_Crash; dvariable totcatch; dvariable R0_use; // annually updated variable if SR_update_SPR0 == 1 - dvariable SSB_use; + dvariable SSB_use; // selected version of SSB that gets passes to Spawn_Recr dvar_matrix catage_w(1, gmorph, 0, nages); dvar_vector tempcatch(1, Nfleet); imatrix Do_F_tune(t_base, TimeMax_Fcast_std, 1, Nfleet); // flag for doing F from catch diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 3aa6d549..f4600932 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -344,7 +344,7 @@ FUNCTION void get_initial_conditions() equ_Recr = 1.0; Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation. Returns SPR because R = 1.0 SPR_virgin = SSB_equil; // spawners per recruit. Needed for Sr_fxn = 10 - SPR_virgin_adj = SSB_equil; + SPR_virgin_adj = SSB_equil; // also needed for Sr_fxn 10. Will get revised in benchmark to use averaged biology if requested. if(SR_fxn == 10) // B-H with a,b { // WHAM based on R = A*S/(1+B*S) @@ -381,14 +381,14 @@ FUNCTION void get_initial_conditions() Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation SSB_virgin = SSB_equil; // SPR_virgin = SSB_equil / Recr_virgin; // spawners per recruit already calculated - if(Do_Benchmark==0) + if(Do_Benchmark==0) // assign values that would be created in benchmark section { - Mgmt_quant(1)=SSB_virgin; - SSB_unf=SSB_virgin; - Recr_unf=Recr_virgin; - Mgmt_quant(2)=totbio; // from equil calcs - Mgmt_quant(3)=smrybio; // from equil calcs - Mgmt_quant(4)=Recr_virgin; + Mgmt_quant(1) = SSB_virgin; + SSB_unf = SSB_virgin; + Recr_unf = Recr_virgin; + Mgmt_quant(2) = totbio; // from equil calcs + Mgmt_quant(3) = smrybio; // from equil calcs + Mgmt_quant(4) = Recr_virgin; } Smry_Table(styr - 2, 1) = totbio; // from equil calcs Smry_Table(styr - 2, 2) = smrybio; // from equil calcs @@ -1495,7 +1495,6 @@ FUNCTION void get_time_series() else // update SSB_use and R0_use where will update SPR0 inside the Spawn_recr fxn { R0_use = mfexp(SR_parm_work(1)); // check to be sure this works when R0 is derived from B-H with alpha, beta parameters - equ_Recr = R0_use; Fishon = 0; eq_yr = y; bio_yr = y; From 2bd30c2da1fe3cb542ad3dfa6f015e2475ee0d10 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 13 Sep 2024 16:27:52 -0700 Subject: [PATCH 15/58] WIP: add switch in benchmark to use correct SPR0 --- SS_benchfore.tpl | 42 +++++++-------- SS_popdyn.tpl | 5 +- SS_readcontrol_330.tpl | 2 +- SS_recruit.tpl | 116 ++++++++++++++++++++--------------------- 4 files changed, 80 insertions(+), 85 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 67a06898..0ddc922e 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -745,35 +745,30 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } } - if(SR_fxn == 10) // B-H with alpha, beta + if (SR_update_SPR0 == 0) // use virgin biology for the spawner-recruitment R0,h calculations { - alpha = mfexp(SR_parm_work(3)); - beta = mfexp(SR_parm_work(4)); - Fishon = 0; - Recr_unf = 1.0; - Do_Equil_Calc(Recr_unf); // - SPR_virgin_adj = SSB_equil / 1.0; - SR_parm_work(2) = alpha * SPR_virgin_adj / (4. + alpha * SPR_virgin_adj); // steepness - SR_parm_work(1) = log(1. / beta * (alpha - (1. / SPR_virgin_adj))); // ln(R0) + Recr_unf = Recr_virgin; + SSB_unf = SSB_virgin; + SPR_unf = SSB_unf / Recr_unf; + } + else // use benchmark biology in the spawner-recruitment R0,h calculations + { + Fishon = 0; + Recr_unf = mfexp(SR_parm_work(1)); + Do_Equil_Calc(Recr_unf); + SSB_unf = SSB_equil; // equilibrium unfished SSB using the benchmark averaged Recr_unf and benchmark averaged biology + SPR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin } - Fishon = 0; - Recr_unf = mfexp(SR_parm_work(1)); - Do_Equil_Calc(Recr_unf); - SSB_unf = SSB_equil; // equilibrium unfished SSB using the benchmark averaged Recr_unf and benchmark averaged biology - SPR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin if (show_MSY == 1) { report5 << "SR_parms for benchmark: " << SR_parm_work << endl - << "mean from years: " << Bmark_Yr(9) << " " << Bmark_Yr(10) << endl; - // SPR_virgin = SSB_virgin / Recr_virgin; // already defined - report5 << " Virgin SSB, R0: " << SSB_virgin << " " << Recr_virgin << " " << SPR_virgin_adj << endl; - report5 << " unfished SSB, R0: " << SSB_unf << " " << Recr_unf << " " << SPR_unf << " with current biology " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_virgin_adj); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Virgin SPR0, result_SSB, R: " << SPR_virgin_adj << " " << Equ_SpawnRecr_Result << endl << endl; + << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl; + if ( SR_update_SPR0 == 1) report5 << "SPR0 for equilibrium spawner-recruit based on benchmark biology, not virgin biology" << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Virgin SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SPR_virgin << " equil: " << Equ_SpawnRecr_Result << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Benchmark SPR0, result_SSB, R: " << SPR_unf << " " << Equ_SpawnRecr_Result << endl << endl; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Benchmark SPR0, result_SSB, R: " << SPR_unf << " " << Equ_SpawnRecr_Result << " with virgin spawn-recr " << endl; + report5 << " Benchmark SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SPR_unf << " equil: " << Equ_SpawnRecr_Result << endl; } SR_parm_work(N_SRparm2 + 1) = SSB_unf; Mgmt_quant(1) = SSB_unf; @@ -925,7 +920,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc equil spawn-recr in YPR; need to make this area-specific SPR_temp = SSB_equil; // based on most recent call to Do_Equil_Calc Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5< SSB_virgin_adj) + if (SSB_curr_adj > SSB_virgin_use) { - SSB_BH1 = SSB_virgin_adj; + SSB_BH1 = SSB_virgin_use; } else { SSB_BH1 = SSB_curr_adj; } - NewRecruits = (4. * steepness * Recr_virgin_adj * SSB_BH1) / (SSB_virgin_adj * (1. - steepness) + (5. * steepness - 1.) * SSB_BH1); + NewRecruits = (4. * steepness * Recr_virgin_use * SSB_BH1) / (SSB_virgin_use * (1. - steepness) + (5. * steepness - 1.) * SSB_BH1); break; } // SS_Label_43.3.7 survival based case 7: // survival based, so constrained such that recruits cannot exceed fecundity { - // PPR_0=SSB_virgin_adj/Recr_virgin_adj; // pups per recruit at virgin + // PPR_0=SSB_virgin_use/Recr_virgin_use; // pups per recruit at virgin // Surv_0=1./PPR_0; // recruits per pup at virgin - // Pups_0=SSB_virgin_adj; // total population fecundity is the number of pups produced + // Pups_0=SSB_virgin_use; // total population fecundity is the number of pups produced // Sfrac=SR_parm(2); - SRZ_0 = log(1.0 / (SSB_virgin_adj / Recr_virgin_adj)); + SRZ_0 = log(1.0 / (SSB_virgin_use / Recr_virgin_use)); steepness = SR_parm_work(2); srz_min = SRZ_0 * (1.0 - steepness); - SRZ_surv = mfexp((1. - pow((SSB_curr_adj / SSB_virgin_adj), SR_parm_work(3))) * (srz_min - SRZ_0) + SRZ_0); // survival + SRZ_surv = mfexp((1. - pow((SSB_curr_adj / SSB_virgin_use), SR_parm_work(3))) * (srz_min - SRZ_0) + SRZ_0); // survival NewRecruits = SSB_curr_adj * SRZ_surv; exp_rec(y, 1) = NewRecruits; // expected arithmetic mean recruitment // SS_Label_43.3.7.1 Do variation in recruitment by adjusting survival @@ -145,8 +145,8 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab Shepherd_c2 = pow(0.2, SR_parm_work(3)); Hupper = 1.0 / (5.0 * Shepherd_c2); steepness = 0.2 + (SR_parm_work(2) - 0.2) / (0.8) * (Hupper - 0.2); - temp = (SSB_curr_adj) / (SSB_virgin_adj); - NewRecruits = (5. * steepness * Recr_virgin_adj * (1. - Shepherd_c2) * temp) / + temp = (SSB_curr_adj) / (SSB_virgin_use); + NewRecruits = (5. * steepness * Recr_virgin_use * (1. - Shepherd_c2) * temp) / (1.0 - 5.0 * steepness * Shepherd_c2 + (5. * steepness - 1.) * pow(temp, Shepherd_c)); break; } @@ -156,11 +156,11 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab { steepness = SR_parm_work(2); dvariable RkrPower = SR_parm_work(3); - temp = SSB_curr_adj / SSB_virgin_adj; + temp = SSB_curr_adj / SSB_virgin_use; temp2 = posfun(1.0 - temp, 0.0000001, temp3); temp = 1.0 - temp2; // Rick's new line to stabilize recruitment at R0 if B>B0 dvariable RkrTop = log(5.0 * steepness) * pow(temp2, RkrPower) / pow(0.8, RkrPower); - NewRecruits = Recr_virgin_adj * temp * mfexp(RkrTop); + NewRecruits = Recr_virgin_use * temp * mfexp(RkrTop); break; } @@ -169,7 +169,7 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_adj, const prevariab return NewRecruits; } // end spawner_recruitment -FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_virgin_adj) +FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_virgin_use) { RETURN_ARRAYS_INCREMENT(); // SS_Label_43.4 For non-survival based SRR, get recruitment deviations by adjusting recruitment itself @@ -196,7 +196,7 @@ FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_vir { if (do_recdev >= 3) { - NewRecruits = Recr_virgin_adj * mfexp(recdev(y)); // recruitment deviation + NewRecruits = Recr_virgin_use * mfexp(recdev(y)); // recruitment deviation } else if (SR_fxn != 7) { @@ -228,7 +228,7 @@ FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_vir } case 2: // use multiplier of R0 { - exp_rec(y, 2) = Recr_virgin_adj * Fcast_Loop_Control(4); // apply fcast multiplier to the virgin recruitment + exp_rec(y, 2) = Recr_virgin_use * Fcast_Loop_Control(4); // apply fcast multiplier to the virgin recruitment NewRecruits = exp_rec(y, 2); if (SR_fxn != 4) NewRecruits *= mfexp(-biasadj(y) * half_sigmaRsq); // bias adjustment @@ -268,7 +268,7 @@ FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_vir /* SS_Label_FUNCTION 44 Equil_Spawn_Recr_Fxn */ // SPAWN-RECR: function Equil_Spawn_Recr_Fxn FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, - const prevariable& SSB_temp, const prevariable& RECR_temp, const prevariable& SPR_temp) + const prevariable& SSB_virgin_use, const prevariable& Recr_virgin_use, const prevariable& SPR_current) { RETURN_ARRAYS_INCREMENT(); dvar_vector Equil_Spawn_Recr_Calc(1, 2); // values to return 1 is B_equil, 2 is R_equil @@ -284,7 +284,7 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, dvariable SRZ_surv; steepness = SRparm(2); // common usage but some different - // SS_Label_44.1 calc equilibrium SpawnBio and Recruitment from input SPR_temp, which is spawning biomass per recruit at some given F level + // SS_Label_44.1 calc equilibrium SpawnBio and Recruitment from input SPR_current, which is spawning biomass per recruit at some given F level switch (SR_fxn) { case 1: // previous placement for B-H constrained @@ -297,8 +297,8 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, // SS_Label_44.1.2 Ricker case 2: // Ricker { - B_equil = SSB_temp * (1. + (log(RECR_temp / SSB_temp) + log(SPR_temp)) / steepness); - R_equil = RECR_temp * B_equil / SSB_temp * mfexp(steepness * (1. - B_equil / SSB_temp)); + B_equil = SSB_virgin_use * (1. + (log(Recr_virgin_use / SSB_virgin_use) + log(SPR_current)) / steepness); + R_equil = Recr_virgin_use * B_equil / SSB_virgin_use * mfexp(steepness * (1. - B_equil / SSB_virgin_use)); break; } @@ -316,19 +316,19 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, // SS3 previously used alternative formulation: R = A*S/(B+S) // converting SS3 to align with WHAM - // SPR_virgin = SSB_temp / RECR_temp; // this is already defined + // SPR_virgin = SSB_virgin_use / Recr_virgin_use; // this is already defined alpha = 4.0 * steepness / (SPR_virgin_adj * (1. - steepness)); beta = (5.0 * steepness - 1.0) / ((1 - steepness) * SSB_virgin); // " h " << steepness << " derive " << alpha * SPR_virgin / (4. + alpha * SPR_virgin) << " " << endl; - // " R0 " << RECR_temp << " derive " << 1. / beta * (alpha - 1./SPR_virgin) << endl; -// report5 <<" SSB_unf "< Date: Mon, 16 Sep 2024 18:22:06 -0700 Subject: [PATCH 16/58] refactor SPR to SSBpR; clean-up reference to timevary biology --- SS_benchfore.tpl | 73 ++++++++++++++++++++++++--------------------- SS_param.tpl | 6 ++-- SS_popdyn.tpl | 18 ++++++----- SS_recruit.tpl | 54 ++++++++++++++++----------------- SS_write_report.tpl | 14 ++++----- 5 files changed, 85 insertions(+), 80 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 0ddc922e..fa527705 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -536,7 +536,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) dvariable last_F1; dvariable Closer; dvariable Vbio1_unfished; - dvariable SPR_unf; + dvariable SSBpR_unf; dvariable Vbio_MSY; dvariable Vbio1_MSY; dvariable junk; @@ -749,7 +749,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { Recr_unf = Recr_virgin; SSB_unf = SSB_virgin; - SPR_unf = SSB_unf / Recr_unf; + SSBpR_unf = SSB_unf / Recr_unf; } else // use benchmark biology in the spawner-recruitment R0,h calculations { @@ -757,18 +757,21 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Recr_unf = mfexp(SR_parm_work(1)); Do_Equil_Calc(Recr_unf); SSB_unf = SSB_equil; // equilibrium unfished SSB using the benchmark averaged Recr_unf and benchmark averaged biology - SPR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin + SSBpR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin + SSBpR_virgin_adj = SSB_unf / Recr_unf; // update } if (show_MSY == 1) { report5 << "SR_parms for benchmark: " << SR_parm_work << endl << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl; if ( SR_update_SPR0 == 1) report5 << "SPR0 for equilibrium spawner-recruit based on benchmark biology, not virgin biology" << endl; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Virgin SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SPR_virgin << " equil: " << Equ_SpawnRecr_Result << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Virgin SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " equil: " << Equ_SpawnRecr_Result << endl; + + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Benchmark SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_unf << " equil: " << Equ_SpawnRecr_Result << endl; + report5 << "Repro_output_by_age_for_morph_1: " << fec(1) << endl; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Benchmark SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SPR_unf << " equil: " << Equ_SpawnRecr_Result << endl; } SR_parm_work(N_SRparm2 + 1) = SSB_unf; Mgmt_quant(1) = SSB_unf; @@ -803,7 +806,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SPR_target100 = SPR_target * 100.; Do_Equil_Calc(equ_Recr); - SPR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin + SSBpR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin Vbio1_unfished = smrybio; // gets value from equil_calc if (show_MSY == 1) { @@ -849,7 +852,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Fishon = 1; Do_Equil_Calc(equ_Recr); - yld1(ii) = 100. * SSB_equil / SPR_unf; // spawning potential ratio + yld1(ii) = 100. * SSB_equil / SSBpR_unf; // spawning potential ratio } SPR_actual = yld1(1); // spawning potential ratio @@ -918,8 +921,8 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } // SPAWN-RECR: calc equil spawn-recr in YPR; need to make this area-specific - SPR_temp = SSB_equil; // based on most recent call to Do_Equil_Calc - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + SSBpR_temp = SSB_equil; // based on most recent call to Do_Equil_Calc + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bspr = Equ_SpawnRecr_Result(1); Bspr_rec = Equ_SpawnRecr_Result(2); @@ -1002,7 +1005,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) last_F1 = F1(1); if (show_MSY == 1) { - report5 << j << " " << F1(1) << " " << equ_F_std << " " << SSB_equil / SPR_unf << " " << YPR_opt << " " << F01_actual << " " << F01_second << " last F1 " << last_F1 << " Closer " << Closer << " delta " << (F01_origin * 0.1 - F01_actual) / (F01_second) << endl; + report5 << j << " " << F1(1) << " " << equ_F_std << " " << SSB_equil / SSBpR_unf << " " << YPR_opt << " " << F01_actual << " " << F01_second << " last F1 " << last_F1 << " Closer " << Closer << " delta " << (F01_origin * 0.1 - F01_actual) / (F01_second) << endl; } F1(1) += (F01_origin * 0.1 - F01_actual) / (F01_second); F1(1) = (1. - Closer) * F1(1) + Closer * last_F1; @@ -1033,8 +1036,8 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Btgt_Fmult = F1(1); if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F0.1: " << Btgt_Fmult << endl; - SPR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + SSBpR_temp = SSB_equil; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt = Equ_SpawnRecr_Result(1); Btgt_Rec = Equ_SpawnRecr_Result(2); YPR_Btgt_enc = YPR_enc; // total encountered yield per recruit @@ -1045,7 +1048,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) YPR_Btgt_revenue = (PricePerF * YPR_val_vec) * Btgt_Rec; // vector*vector*scalar // YPR_Btgt_revenue = Price*YPR_ret*Btgt_Rec; YPR_Btgt_profit = YPR_Btgt_revenue - Cost; - SPR_Btgt = SSB_equil / SPR_unf; + SPR_Btgt = SSB_equil / SSBpR_unf; Vbio_Btgt = totbio; Vbio1_Btgt = smrybio; Mgmt_quant(7) = equ_F_std; @@ -1060,9 +1063,12 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // ****************************************************** if (show_MSY == 1) { - report5 << "#" << endl - << "Find_target_SSB/Bzero; where Bzero is for Bmark years, not Virgin" << endl - << "Iter Fmult ann_F SPR Catch SSB Recruits SSB/Bzero Tot_catch"; + report5 << "#" << endl; + if (SR_update_SPR0 == 0) // use virgin biology for the spawner-recruitment R0,h calculations + {report5 << "Find_target_SSB/Bzero; where Bzero is Virgin SSB:" << SSB_unf << " where SSBpR_unf = " << SSBpR_unf << endl;} + else + {report5 << "Find_target_SSB/Bzero; where Bzero is for Bmark biology and updated SPR0: " << SSB_unf << " where SSBpR_unf = " << SSBpR_unf << endl;} + report5 << "Iter Fmult ann_F SPR Catch SSB Recruits SSB/Bzero Tot_catch"; for (p = 1; p <= pop; p++) for (gp = 1; gp <= N_GP; gp++) { @@ -1088,8 +1094,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Nloops = 28; } - // Btgttgt=BTGT_target*SSB_virgin; // this is relative to virgin, not to the average biology from benchmark years - Btgttgt = BTGT_target * SSB_unf; // now relative to Bmark + Btgttgt = BTGT_target * SSB_unf; for (j = 0; j <= Nloops; j++) // loop find Btarget { @@ -1124,12 +1129,11 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } // else Hrate for bycatch fleets already set } - Do_Equil_Calc(equ_Recr); // where equ_Recr=1.0, so returned SSB_equil is a SSB/R, - SPR_Btgt = SSB_equil / SPR_unf; + Do_Equil_Calc(equ_Recr); // where equ_Recr=1.0, so returned SSB_equil is in units of SSB/R, + SSBpR_temp = SSB_equil; + SPR_Btgt = SSBpR_temp / SSBpR_unf; // where SSBpR_unf = SSB_unf / Recr_unf so units of SSB/R; so result is SPR_Btgt = (fished SSB/R) / (unfished SSB/R) // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific - SPR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5< Bmark_Yr(k)) {SS2out << "#_range_of_years_is_averaged,_so_reduces_standard_error_of_result;_do_this_only_when_timevarying_makes_necessary: " << k << " "<< k+1 << endl;} } - SS2out << "SPR_unfished_benchmark: " << Mgmt_quant(1) / Mgmt_quant(4) << " #_based_on_averaging_biology_over_benchmark_year_range " << endl; + SS2out << "SSBpR_unfished_benchmark: " << Mgmt_quant(1) / Mgmt_quant(4) << " #_based_on_averaging_biology_over_benchmark_year_range " << endl; SS2out << "Bmsy/Bzero: "<< Bmsy / SSB_virgin << " # using styr bio for Bzero" << endl; SS2out << "Bmsy/Bunf: "<< Bmsy / Mgmt_quant(1) << " # using MSY's averaged bio for Bunf" << endl; @@ -4915,8 +4915,8 @@ FUNCTION void SPR_profile() Do_Equil_Calc(equ_Recr); // SPAWN-RECR: calc equil spawn-recr in the SPR loop - SPR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SPR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + SSBpR_temp = SSB_equil; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt_prof = Equ_SpawnRecr_Result(1); Btgt_prof_rec = Equ_SpawnRecr_Result(2); if (Btgt_prof < 0.001 || Btgt_prof_rec < 0.001) From c04d9b4612223bc42d1ffceec15309293469fbb5 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 20 Sep 2024 09:58:02 -0700 Subject: [PATCH 17/58] create new switch to control updating of SSBpR0 --- SS_benchfore.tpl | 12 +++++----- SS_popdyn.tpl | 8 +++---- SS_readcontrol_330.tpl | 53 +++++++++++++++++++++++++++++++++++++----- SS_write_ssnew.tpl | 6 ++++- 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index fa527705..484d010c 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -745,7 +745,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } } - if (SR_update_SPR0 == 0) // use virgin biology for the spawner-recruitment R0,h calculations + if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations in bmark { Recr_unf = Recr_virgin; SSB_unf = SSB_virgin; @@ -764,7 +764,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { report5 << "SR_parms for benchmark: " << SR_parm_work << endl << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl; - if ( SR_update_SPR0 == 1) report5 << "SPR0 for equilibrium spawner-recruit based on benchmark biology, not virgin biology" << endl; + if ( SR_update_SSBpR0_bmark == 1) report5 << "SPR0 for equilibrium spawner-recruit based on benchmark biology, not virgin biology" << endl; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR report5 << " Virgin SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " equil: " << Equ_SpawnRecr_Result << endl; @@ -1064,7 +1064,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (show_MSY == 1) { report5 << "#" << endl; - if (SR_update_SPR0 == 0) // use virgin biology for the spawner-recruitment R0,h calculations + if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations {report5 << "Find_target_SSB/Bzero; where Bzero is Virgin SSB:" << SSB_unf << " where SSBpR_unf = " << SSBpR_unf << endl;} else {report5 << "Find_target_SSB/Bzero; where Bzero is for Bmark biology and updated SPR0: " << SSB_unf << " where SSBpR_unf = " << SSBpR_unf << endl;} @@ -1945,7 +1945,7 @@ FUNCTION void Get_Forecast() dvariable OFL_catch; dvariable Fcast_Crash; dvariable totcatch; - dvariable R0_use; // annually updated variable if SR_update_SPR0 == 1 + dvariable R0_use; // annually updated value if SR_update_SSBpR0_timeseries == 1 dvariable SSB_use; // selected version of SSB that gets passes to Spawn_Recr dvar_matrix catage_w(1, gmorph, 0, nages); dvar_vector tempcatch(1, Nfleet); @@ -2596,7 +2596,7 @@ FUNCTION void Get_Forecast() } // SPAWN-RECR: get recruitment in forecast; needs to be area-specific // SR_fxn - if (SR_update_SPR0 == 0) // R0 is not time-varying + if (SR_update_SSBpR0_timeseries == 0) // R0 is not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; @@ -3236,7 +3236,7 @@ FUNCTION void Get_Forecast() // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_fxn - if (SR_update_SPR0 == 0) // R0 is not time-varying + if (SR_update_SSBpR0_timeseries == 0) // R0 is not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index c42f907e..79b1d59f 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -697,7 +697,7 @@ FUNCTION void get_time_series() dvariable crashtemp1; dvariable interim_tot_catch; dvariable Z_adjuster; - dvariable R0_use; // annually updated variable if SR_update_SPR0 == 1; gets passed to Spawn_Recr() function + dvariable R0_use; // annually updated variable if SR_update_SSBpR0_timeseries == 1; gets passed to Spawn_Recr() function dvariable SSB_use; if (Do_Morphcomp > 0) @@ -1028,7 +1028,7 @@ FUNCTION void get_time_series() // SS_Label_Info_24.2.3 #Get the total recruitment produced by this spawning biomass at the beginning of the season // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_Fxn relevant keyword - if (SR_update_SPR0 == 0) // SRparm are not time-varying + if (SR_update_SSBpR0_timeseries == 0) // SRparm are not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; @@ -1489,12 +1489,12 @@ FUNCTION void get_time_series() // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass at some time during the season // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_fxn - if (SR_update_SPR0 == 0) // SR parms are not time-varying + if (SR_update_SSBpR0_timeseries == 0) // SR parms are not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; } - else // update SSB_use and R0_use where will update SPR0 inside the Spawn_recr fxn + else // update SSB_use and R0_use where will update SSBpR0 inside the Spawn_recr fxn { R0_use = mfexp(SR_parm_work(1)); // check to be sure this works when R0 is derived from B-H with alpha, beta parameters Fishon = 0; diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index c4cd8a2a..bec821cd 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1950,8 +1950,21 @@ !!echoinput< 0 || SR_parm_timevary(4) > 0) ) {SR_update_SPR0 = 1;} // alpha or beta is time-varying - else if ((SR_parm_timevary(1) > 0 || SR_parm_timevary(2) > 0) ) {SR_update_SPR0 = 1;} // R0 or steepness is time-varying + if (SR_fxn == 10 && (SR_parm_timevary(3) > 0 || SR_parm_timevary(4) > 0) ) {SR_update_parm = 1;} // alpha or beta is time-varying + else if ((SR_parm_timevary(1) > 0 || SR_parm_timevary(2) > 0) ) {SR_update_parm = 1;} // R0 or steepness is time-varying } } N_SRparm3 = N_SRparm2; @@ -2149,6 +2162,34 @@ echoinput << " SR timevary_parm_cnt start and end " << timevary_parm_start_SR << " " << timevary_parm_cnt_SR << endl; echoinput << "link to timevary parms: " << SR_parm_timevary << endl; } + +// SR_update_SSBpR0_rd values +// 1 best: update SSBpR0 for benchmark and for time series only if SRparm R0 or h (not regime) is set to have time-varying property +// 2 incorrect, relic: always update SSBpR0 for benchmark's use of spawner-recruitment (old, incorrect SS3 approach), but only for the time series if there is a timevary SR parm +// 3 option: do not update SSBpR0 (do keep start year SPR0), even if R0 or h is set to have time-varying property + + switch (SR_update_SSBpR0_rd) + { + case 0: + if(timevary_MG_firstyr < YrMax) // timevary biology exists and SR_update not set + { + warnstream << "user must select 1, 2, or 3 for updating SPR0 flag (formerly labelled future feature in SR input) because there is time-varying biology"; + write_message (FATAL, 0); // EXIT! + } + break; + case 1: + SR_update_SSBpR0_bmark = 1 * SR_update_parm; // but conditional on SRparm_timevary, so update value there + SR_update_SSBpR0_timeseries = 1 * SR_update_parm; + break; + case 2: + SR_update_SSBpR0_bmark = 1; + SR_update_SSBpR0_timeseries = 0; + break; + case 3: + SR_update_SSBpR0_bmark = 0; + SR_update_SSBpR0_timeseries = 0; + break; + } echoinput << "SR_Npar and N_SRparm2 and N_SRparm3: " << N_SRparm(SR_fxn) << " " << N_SRparm2 << " " << N_SRparm3 << endl; // clang-format off END_CALCS diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 04c450d2..590c76df 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -2136,7 +2136,11 @@ FUNCTION void write_nucontrol() report4 << "#" << endl; report4 << SR_fxn << " #_Spawner-Recruitment; Options: 1=NA; 2=Ricker; 3=std_B-H; 4=SCAA; 5=Hockey; 6=B-H_flattop; 7=survival_3Parm; 8=Shepherd_3Parm; 9=RickerPower_3parm" << endl; report4 << init_equ_steepness << " # 0/1 to use steepness in initial equ recruitment calculation" << endl; - report4 << sigmaR_dendep << " # future feature: 0/1 to make realized sigmaR a function of SR curvature" << endl; + report4 << SR_update_SSBpR0_rd << "# SR_update_SSBpR0" << endl << + "# 0 - OK, but only if no timevary biology or SR parm" << endl << + "# 1 - best: update SSBpR0 for benchmark and for time series only if SRparm R0 or h (not regime) is set to have time-varying property" << endl << + "# 2 - incorrect (old, incorrect SS3 approach): always update SSBpR0 for benchmark's use of spawner-recruitment, but only for the time series if there is a timevary SR parm" << endl << + "# 3 - option: do not update SSBpR0 (do keep start year SSBpR0), even if R0 or h is set to have time-varying property" << endl << "#" << endl; report4 << "#_ LO HI INIT PRIOR PR_SD PR_type PHASE env-var use_dev dev_mnyr dev_mxyr dev_PH Block Blk_Fxn # parm_name" << endl; report4.unsetf(std::ios_base::fixed); report4.unsetf(std::ios_base::floatfield); From 1d2e75a6f91ad0cf4a8b87c62bea341fc51f8a77 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 4 Oct 2024 14:58:13 -0700 Subject: [PATCH 18/58] too many changes --- SS_benchfore.tpl | 82 +++++++++++++++++++++++------------------- SS_global.tpl | 4 +-- SS_param.tpl | 9 +++-- SS_popdyn.tpl | 36 +++++++++---------- SS_proced.tpl | 6 ++-- SS_readcontrol_330.tpl | 21 +++++------ SS_readdata_330.tpl | 4 +-- SS_write.tpl | 2 +- SS_write_report.tpl | 44 +++++++---------------- SS_write_ssnew.tpl | 6 ++-- 10 files changed, 103 insertions(+), 111 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 484d010c..58e85267 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -4,6 +4,15 @@ // SS_Label_file # * get_forecast() // calculates forecast quantities, includes all popdy characteristics of the time series, writes forecast-report.sso // SS_Label_file # +// Terminology +// SSB refers to spawning stock biomass, calculated from reproductive output at age (fec()) and numbers-at-age at spawn_month in spawn_seas +// SSBpR refers to SSB per recruit calculated with equilibrium age composition in equil_calc +// SPR refers to spawner potential ratio which is the ratio of SSBpR at some level of F to SSBpR with F = 0 + +// SSBpR_virgin calculated and reported, but never used +// SSBpR_virgin_adj used only in the alpha-beta spawner-recruitment. _adj means could be updated if SR_update_SSBpR0_timeseries == 1. Also used to get alpha in equil_spawn_recr B-H +// but note that also uses SSB_virgin_use. So need to align _use with _adj + FUNCTION void setup_Benchmark() // and forecast { // SS_Label_Info_7.5 #Get averages from selected years to use in forecasts @@ -113,12 +122,7 @@ FUNCTION void setup_Benchmark() // and forecast } } t = styr + (endyr + 1 - styr) * nseas + spawn_seas - 1; - fec = Wt_Age_t(t, -2); - // for (g=1;g<=gmorph;g++) - // if(use_morph(g)>0 && sx(g)==1) - // { - // fec(g)=save_sel_num(t,0,g); - // } +// fec = Wt_Age_t(t, -2); this will always be overwritten, so deleting if (Fcast_Loop_Control(3) == 3) // using mean recr_dist from range of years { @@ -569,7 +573,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) eq_yr = y; t_base = y + (y - styr) * nseas - 1; bio_t_base = styr + (bio_yr - styr) * nseas - 1; - // set the Hrate for bycatch fleets so not scaled with other fleets // bycatch_F(f,s) is created here for use in forecast for (f = 1; f <= Nfleet; f++) @@ -643,6 +646,8 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Make_AgeLength_Key(s, subseas); // SPAWN-RECR: call make_fecundity for benchmarks + // this means that any calculation of SSB in benchmark will use the updated fec + // but SSBpR0 will only use that updated fec if SR_update_SSBpR0_bmark == 1 if (s == spawn_seas) { { @@ -744,7 +749,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SR_parm_work(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); } } - if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations in bmark { Recr_unf = Recr_virgin; @@ -763,14 +767,17 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (show_MSY == 1) { report5 << "SR_parms for benchmark: " << SR_parm_work << endl - << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl; - if ( SR_update_SSBpR0_bmark == 1) report5 << "SPR0 for equilibrium spawner-recruit based on benchmark biology, not virgin biology" << endl; + << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << " flag for updating SSBpR0 = " << SR_update_SSBpR0_bmark << endl; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR report5 << " Virgin SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " equil: " << Equ_SpawnRecr_Result << endl; - - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Benchmark SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_unf << " equil: " << Equ_SpawnRecr_Result << endl; - report5 << "Repro_output_by_age_for_morph_1: " << fec(1) << endl; + if ( SR_update_SSBpR0_bmark == 1) + { + report5 << "SPR0 for equilibrium spawner-recruit based on benchmark biology, not virgin biology" << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Benchmark SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_unf << " equil: " << Equ_SpawnRecr_Result << endl; + } + report5 << 0 << " y: " << y << " Repro_output_by_age_for_morph_1 bench " << fec(1) << endl; +// report5 << "Repro_output_by_age_for_morph_1: " << fec(1) << endl; } SR_parm_work(N_SRparm2 + 1) = SSB_unf; @@ -1849,7 +1856,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << "ann_F " << Mgmt_quant(10) << endl; report5 << "Exploit(Catch_dead/B_smry) " << YPR_spr_dead / Vbio1_spr << endl; report5 << "Recruits " << Bspr_rec << endl; - report5 << "SPBio " << Bspr << " " << Bspr / Bspr_rec << endl; + report5 << "SSBio " << Bspr << " " << Bspr / Bspr_rec << endl; report5 << "Catch_encountered " << YPR_spr_enc * Bspr_rec << " " << YPR_spr_enc << endl; report5 << "Catch_dead " << YPR_spr_dead * Bspr_rec << " " << YPR_spr_dead << endl; report5 << "Catch_retain " << YPR_spr_ret * Bspr_rec << " " << YPR_spr_ret << endl; @@ -1869,7 +1876,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << "ann_F " << Mgmt_quant(7) << endl; report5 << "Exploit(Catch_dead/B_smry) " << YPR_Btgt_dead / Vbio1_Btgt << endl; report5 << "Recruits@F0.1 " << Btgt_Rec << endl; - report5 << "SPBio " << Btgt << " " << Btgt / Btgt_Rec << endl; + report5 << "SSBio " << Btgt << " " << Btgt / Btgt_Rec << endl; report5 << "Catch_encountered " << YPR_Btgt_enc * Btgt_Rec << " " << YPR_Btgt_enc << endl; report5 << "Catch_dead " << YPR_Btgt_dead * Btgt_Rec << " " << YPR_Btgt_dead << endl; report5 << "Catch_retain " << YPR_Btgt_ret * Btgt_Rec << " " << YPR_Btgt_ret << endl; @@ -1889,7 +1896,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << "ann_F " << Mgmt_quant(7) << endl; report5 << "Exploit(Catch_dead/B_smry) " << YPR_Btgt_dead / Vbio1_Btgt << endl; report5 << "Recruits " << Btgt_Rec << endl; - report5 << "SPBio " << Btgt << " " << Btgt / Btgt_Rec << endl; + report5 << "SSBio " << Btgt << " " << Btgt / Btgt_Rec << endl; report5 << "Catch_encountered " << YPR_Btgt_enc * Btgt_Rec << " " << YPR_Btgt_enc << endl; report5 << "Catch_dead " << YPR_Btgt_dead * Btgt_Rec << " " << YPR_Btgt_dead << endl; report5 << "Catch_retain " << YPR_Btgt_ret * Btgt_Rec << " " << YPR_Btgt_ret << endl; @@ -1906,9 +1913,9 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << "ann_F " << Mgmt_quant(14) << endl; report5 << "Exploit(Catch/Bsmry) " << MSY / (Vbio1_MSY * Recr_msy) << endl; report5 << "Recruits@MSY " << Recr_msy << endl; - report5 << "SPBmsy " << Bmsy << " " << Bmsy / Recr_msy << endl; - report5 << "SPBmsy/SPB_virgin " << Bmsy / SSB_virgin << endl; - report5 << "SPBmsy/SPB_unfished " << Bmsy / SSB_unf << endl; + report5 << "SSBmsy " << Bmsy << " " << Bmsy / Recr_msy << endl; + report5 << "SSBmsy/SSB_virgin " << Bmsy / SSB_virgin << endl; + report5 << "SSBmsy/SSB_unfished " << Bmsy / SSB_unf << endl; report5 << "MSY_for_optimize " << MSY << " " << MSY / Recr_msy << endl; report5 << "MSY_encountered " << YPR_msy_enc * Recr_msy << " " << YPR_msy_enc << endl; report5 << "MSY_dead " << YPR_msy_dead * Recr_msy << " " << YPR_msy_dead << endl; @@ -1934,6 +1941,8 @@ FUNCTION void Get_Benchmarks(const int show_MSY) << " " << Vbio1_MSY * Recr_msy << " # " << endl; } write_bodywt = write_bodywt_save; + report5 << 0 << " y: " << y << " Repro_output_by_age_for_morph_1 end_bench: " << fec(1) << endl; +// report5 << "Repro_output_by_age_for_morph_1_after_benchmark: " << fec(1) << endl; } // end benchmarks FUNCTION void Get_Forecast() @@ -1945,8 +1954,6 @@ FUNCTION void Get_Forecast() dvariable OFL_catch; dvariable Fcast_Crash; dvariable totcatch; - dvariable R0_use; // annually updated value if SR_update_SSBpR0_timeseries == 1 - dvariable SSB_use; // selected version of SSB that gets passes to Spawn_Recr dvar_matrix catage_w(1, gmorph, 0, nages); dvar_vector tempcatch(1, Nfleet); imatrix Do_F_tune(t_base, TimeMax_Fcast_std, 1, Nfleet); // flag for doing F from catch @@ -2220,6 +2227,8 @@ FUNCTION void Get_Forecast() for (int Fcast_Loop1 = 1; Fcast_Loop1 <= jloop; Fcast_Loop1++) // for different forecast conditions { + report5 << Fcast_Loop1 << " y: " << 0 << " Repro_output_by_age_for_morph_1 top_forecast: " << fec(1) << endl; + switch (Fcast_Loop1) // select which ABC_loops to use { case 1: // do OFL only @@ -2290,7 +2299,7 @@ FUNCTION void Get_Forecast() get_growth3(y, t, s, subseas); // in case needed for Lorenzen M Make_AgeLength_Key(s, subseas); // which also updates Wt_Age_beg, etc. } - if (s == spawn_seas) +// if (s == spawn_seas) // { if (WTage_rd == 1) { @@ -2301,12 +2310,12 @@ FUNCTION void Get_Forecast() } else { - get_mat_fec(); + get_mat_fec(); // does spawnseas and stores in wt_Age_t(t, -2) } } } } - + report5 << Fcast_Loop1 << " y: " << y << " updated_Repro_output_by_age_for_morph_1 endyr: " << fec(1) << endl; for (y = endyr + 1; y <= YrMax; y++) { t_base = styr + (y - styr) * nseas - 1; @@ -2496,6 +2505,7 @@ FUNCTION void Get_Forecast() Wt_Age_mid(s, g) = ALK(ALK_idx, g) * wt_len(s, GP(g)); // use for fisheries with no size selectivity } } + report5 << Fcast_Loop1 << " y: " << y << " updated_Repro_output_by_age_for_morph_1 annual: " << fec(1) << endl; Wt_Age_t(t, 0) = Wt_Age_beg(s); for (g = 1; g <= gmorph; g++) if (use_morph(g) > 0) @@ -2578,19 +2588,19 @@ FUNCTION void Get_Forecast() if (Hermaphro_Option != 0) // get male biomass { - MaleSPB(y).initialize(); + MaleSSB(y).initialize(); for (p = 1; p <= pop; p++) { for (g = 1; g <= gmorph; g++) if (sx(g) == 2 && use_morph(g) > 0) // male; all assumed to be mature { natage(t, p, g, 0) = 0.0; // these fish do not yet exist - MaleSPB(y, p, GP4(g)) += Wt_Age_t(t, 0, g) * natage(t, p, g); // accumulates SSB by area and by growthpattern + MaleSSB(y, p, GP4(g)) += Wt_Age_t(t, 0, g) * natage(t, p, g); // accumulates SSB by area and by growthpattern } } - if (Hermaphro_maleSPB > 0.0) // add MaleSPB to female SSB + if (Hermaphro_maleSSB > 0.0) // add MaleSSB to female SSB { - SSB_current += Hermaphro_maleSPB * sum(MaleSPB(y)); + SSB_current += Hermaphro_maleSSB * sum(MaleSSB(y)); SSB_yr(y) = SSB_current; } } @@ -2619,7 +2629,6 @@ FUNCTION void Get_Forecast() } SSB_use = SSB_equil; } - Recruits = Spawn_Recr(SSB_use, R0_use, SSB_current); // calls to function Spawn_Recr if (SR_fxn != 7) apply_recdev(Recruits, R0_use); // apply recruitment deviation if (Fcast_Loop1 < Fcast_Loop_Control(2)) // use expected recruitment this should include environ effect - CHECK THIS @@ -3218,18 +3227,18 @@ FUNCTION void Get_Forecast() if (Hermaphro_Option != 0) // get male biomass { - MaleSPB(y).initialize(); + MaleSSB(y).initialize(); for (p = 1; p <= pop; p++) { for (g = 1; g <= gmorph; g++) if (sx(g) == 2 && use_morph(g) > 0) // male; all assumed to be mature { - MaleSPB(y, p, GP4(g)) += Wt_Age_t(t, 0, g) * elem_prod(natage(t, p, g), mfexp(-Z_rate(t, p, g) * spawn_time_seas)); // accumulates SSB by area and by growthpattern + MaleSSB(y, p, GP4(g)) += Wt_Age_t(t, 0, g) * elem_prod(natage(t, p, g), mfexp(-Z_rate(t, p, g) * spawn_time_seas)); // accumulates SSB by area and by growthpattern } } - if (Hermaphro_maleSPB > 0.0) // add MaleSPB to female SSB + if (Hermaphro_maleSSB > 0.0) // add MaleSSB to female SSB { - SSB_current += Hermaphro_maleSPB * sum(MaleSPB(y)); + SSB_current += Hermaphro_maleSSB * sum(MaleSSB(y)); SSB_yr(y) = SSB_current; } } @@ -3668,7 +3677,7 @@ FUNCTION void Get_Forecast() Smry_Table(y, 4) = Mgmt_quant(Fcast_catch_start + y - endyr); eq_yr = y; equ_Recr = Recr_unf; - bio_yr = endyr; + bio_yr = y; Fishon = 0; Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation @@ -3676,7 +3685,7 @@ FUNCTION void Get_Forecast() Smry_Table(y, 13) = GenTime; if( SR_fxn == 10 ) { - temp = SSB_equil / equ_Recr; // current year's SPB/R with current biology at age + temp = SSB_equil / equ_Recr; // current year's SSB/R with current biology at age alpha = mfexp(SR_parm_work(3)); beta = mfexp(SR_parm_work(4)); SR_parm_byyr(y, 2) = alpha * temp / (4. + alpha * temp); // implied steepness @@ -3684,6 +3693,7 @@ FUNCTION void Get_Forecast() } Fishon = 1; Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation +// warning < 0) SPR_std(STD_Yr_Reverse_Ofish(y)) = SSB_equil / Smry_Table(y, 11); Smry_Table(y, 9) = totbio; diff --git a/SS_global.tpl b/SS_global.tpl index 4fa5dcfb..c18dc5af 100644 --- a/SS_global.tpl +++ b/SS_global.tpl @@ -1270,10 +1270,10 @@ REPORT_SECTION if (Do_TG > 0) report << " TG-fleetcomp " << TG_like1 << endl << " TG-negbin " << TG_like2 << endl; - report << " -log(L): " << obj_fun << " Spbio: " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)) << endl; + report << " -log(L): " << obj_fun << " SSBio: " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)) << endl; report << endl - << "Year Spbio Recruitment" << endl; + << "Year SSBio Recruitment" << endl; report << "Virg " << SSB_yr(styr - 2) << " " << exp_rec(styr - 2, 4) << endl; report << "Init " << SSB_yr(styr - 1) << " " << exp_rec(styr - 1, 4) << endl; for (y = styr; y <= endyr; y++) diff --git a/SS_param.tpl b/SS_param.tpl index 43a4206c..110bce12 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -159,7 +159,7 @@ PARAMETER_SECTION 3darray recr_dist_endyr(1,N_GP*gender,1,N_settle_timings,1,pop); !!// SS_Label_Info_5.1.2 #Create SR_parm vector, recruitment vectors init_bounded_number_vector SR_parm(1,N_SRparm3,SR_parm_LO,SR_parm_HI,SR_parm_PH) - matrix SR_parm_byyr(styr-3,YrMax,1,N_SRparm2+1) // R0, steepness, parm3, sigmar, rec_dev_offset, R1, rho, SPB Time_vary implementation of spawner-recruitment + matrix SR_parm_byyr(styr-3,YrMax,1,N_SRparm2+1) // R0, steepness, parm3, sigmar, rec_dev_offset, R1, rho, SSB Time_vary implementation of spawner-recruitment vector SR_parm_virg(1,N_SRparm2+1) vector SR_parm_work(1,N_SRparm2+1) number two_sigmaRsq; @@ -241,9 +241,12 @@ PARAMETER_SECTION number Recr_virgin number SSB_vir_LH - number SSB_unf + number SSB_unf // SSB unfished, based on benchmark biology number Recr_unf + number SSB_use + number R0_use; // annually updated value if SR_update_SSBpR0_timeseries == 1 + number SSB_deplete // SSB that will be used as denominator for depletion calculations and as basis for control rule inflection number SSB_current; // Spawning biomass number SSB_equil; @@ -322,7 +325,7 @@ PARAMETER_SECTION !!k=0; !!if(Hermaphro_Option!=0) k=1; - 3darray MaleSPB(styr-3,YrMax*k,1,pop,1,N_GP) //Male Spawning biomass + 3darray MaleSSB(styr-3,YrMax*k,1,pop,1,N_GP) //Male Spawning biomass matrix SSB_equil_pop_gp(1,pop,1,N_GP); matrix MaleSSB_equil_pop_gp(1,pop,1,N_GP); diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 79b1d59f..6b51ce91 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -383,7 +383,7 @@ FUNCTION void get_initial_conditions() // SSBpR_virgin = SSB_equil / Recr_virgin; // spawners per recruit already calculated if(Do_Benchmark==0) // assign values that would be created in benchmark section { - Mgmt_quant(1) = SSB_virgin; + Mgmt_quant(1) = SSB_virgin; // can be overwritten in benchmark by updated SSB_unf SSB_unf = SSB_virgin; Recr_unf = Recr_virgin; Mgmt_quant(2) = totbio; // from equil calcs @@ -395,7 +395,7 @@ FUNCTION void get_initial_conditions() Smry_Table(styr - 2, 3) = smrynum; // from equil calcs SSB_pop_gp(eq_yr) = SSB_equil_pop_gp; // dimensions of pop x N_GP if (Hermaphro_Option != 0) - MaleSPB(eq_yr) = MaleSSB_equil_pop_gp; + MaleSSB(eq_yr) = MaleSSB_equil_pop_gp; SSB_yr(eq_yr) = SSB_equil; SR_parm_byyr(eq_yr, N_SRparm2 + 1) = SSB_equil; SR_parm_virg(N_SRparm2 + 1) = SSB_equil; @@ -527,7 +527,7 @@ FUNCTION void get_initial_conditions() // SS_Label_Info_23.5.1.2 #Adjustments include spawner-recruitment function // do initial equilibrium with R1 based on offset from spawner-recruitment curve, using same approach as the benchmark calculations // first get SPR for this init_F - // SPAWN-RECR: calc initial equilibrium pop, SPB, Recruitment + // SPAWN-RECR: calc initial equilibrium pop, SSB, Recruitment // equ_Recr=Recr_virgin; equ_Recr = R1_exp * regime_change; @@ -554,7 +554,7 @@ FUNCTION void get_initial_conditions() SSB_pop_gp(eq_yr) = SSB_equil_pop_gp; // dimensions of pop x N_GP if (Hermaphro_Option != 0) - MaleSPB(eq_yr) = MaleSSB_equil_pop_gp; + MaleSSB(eq_yr) = MaleSSB_equil_pop_gp; SSB_yr(eq_yr) = SSB_equil; SR_parm_byyr(eq_yr, N_SRparm2 + 1) = SSB_equil; SR_parm_work(N_SRparm2 + 1) = SSB_equil; @@ -697,14 +697,12 @@ FUNCTION void get_time_series() dvariable crashtemp1; dvariable interim_tot_catch; dvariable Z_adjuster; - dvariable R0_use; // annually updated variable if SR_update_SSBpR0_timeseries == 1; gets passed to Spawn_Recr() function - dvariable SSB_use; if (Do_Morphcomp > 0) Morphcomp_exp.initialize(); // SS_Label_Info_24.0 #Retrieve spawning biomass and recruitment from the initial equilibrium - // SPAWN-RECR: begin of time series, retrieve last spbio and recruitment + // SPAWN-RECR: begin of time series, retrieve last SSBio and recruitment SSB_current = SSB_yr(styr); // need these initial assignments in case recruitment distribution occurs before spawnbio&recruits if (recdev_doit(styr - 1) > 0) { @@ -983,7 +981,7 @@ FUNCTION void get_time_series() } } // SS_Label_Info_24.2.2 #Compute spawning biomass if this is spawning season so recruits could occur later this season - // SPAWN-RECR: calc SPB in time series if spawning is at beginning of the season + // SPAWN-RECR: calc SSB in time series if spawning is at beginning of the season if (s == spawn_seas && spawn_time_seas < 0.0001) // compute spawning biomass if spawning at beginning of season so recruits could occur later this season { SSB_pop_gp(y).initialize(); @@ -1009,18 +1007,18 @@ FUNCTION void get_time_series() if (Hermaphro_Option != 0) // get male biomass { - MaleSPB(y).initialize(); + MaleSSB(y).initialize(); for (p = 1; p <= pop; p++) { for (g = 1; g <= gmorph; g++) if (sx(g) == 2 && use_morph(g) > 0) // male; all assumed to be mature { - MaleSPB(y, p, GP4(g)) += Wt_Age_t(t, 0, g) * natage(t, p, g); // accumulates SSB by area and by growthpattern + MaleSSB(y, p, GP4(g)) += Wt_Age_t(t, 0, g) * natage(t, p, g); // accumulates SSB by area and by growthpattern } } - if (Hermaphro_maleSPB > 0.0) // add MaleSPB to female SSB + if (Hermaphro_maleSSB > 0.0) // add MaleSSB to female SSB { - SSB_current += Hermaphro_maleSPB * sum(MaleSPB(y)); + SSB_current += Hermaphro_maleSSB * sum(MaleSSB(y)); SSB_yr(y) = SSB_current; } } @@ -1471,18 +1469,18 @@ FUNCTION void get_time_series() SSB_yr(y) = SSB_current; if (Hermaphro_Option != 0) // get male biomass { - MaleSPB(y).initialize(); + MaleSSB(y).initialize(); for (p = 1; p <= pop; p++) { for (g = 1; g <= gmorph; g++) if (sx(g) == 2 && use_morph(g) > 0) // male; all assumed to be mature { - MaleSPB(y, p, GP4(g)) += Wt_Age_t(t, 0, g) * elem_prod(natage(t, p, g), mfexp(-Z_rate(t, p, g) * spawn_time_seas)); // accumulates SSB by area and by growthpattern + MaleSSB(y, p, GP4(g)) += Wt_Age_t(t, 0, g) * elem_prod(natage(t, p, g), mfexp(-Z_rate(t, p, g) * spawn_time_seas)); // accumulates SSB by area and by growthpattern } } - if (Hermaphro_maleSPB > 0.0) // add MaleSPB to female SSB + if (Hermaphro_maleSSB > 0.0) // add MaleSSB to female SSB { - SSB_current += Hermaphro_maleSPB * sum(MaleSPB(y)); + SSB_current += Hermaphro_maleSSB * sum(MaleSSB(y)); SSB_yr(y) = SSB_current; } } @@ -1798,7 +1796,7 @@ FUNCTION void get_time_series() Smry_Table(y, 13) = GenTime; if( SR_fxn == 10 ) { - temp = SSB_equil / Recr_virgin; // current year's SPB/R with current biology at age + temp = SSB_equil / Recr_virgin; // current year's SSB/R with current biology at age alpha = mfexp(SR_parm_work(3)); beta = mfexp(SR_parm_work(4)); SR_parm_byyr(y, 2) = alpha * temp / (4. + alpha * temp); // implied steepness @@ -2284,9 +2282,9 @@ FUNCTION void Do_Equil_Calc(const prevariable& equ_Recr) SSB_equil = sum(SSB_equil_pop_gp); GenTime /= SSB_equil; smryage /= smrynum; - if (Hermaphro_maleSPB > 0.0) // add MaleSPB to female SSB + if (Hermaphro_maleSSB > 0.0) // add MaleSSB to female SSB { - SSB_equil += Hermaphro_maleSPB * sum(MaleSSB_equil_pop_gp); + SSB_equil += Hermaphro_maleSSB * sum(MaleSSB_equil_pop_gp); } } // end equil calcs diff --git a/SS_proced.tpl b/SS_proced.tpl index 534adf53..3e545ba7 100644 --- a/SS_proced.tpl +++ b/SS_proced.tpl @@ -206,15 +206,15 @@ PROCEDURE_SECTION temp = sqrt((temp + 0.0000001) / (double(recdev_end - recdev_start + 1))); if (mcmc_counter == 0 && mceval_counter == 0) { - cout << current_phase() << " " << niter << " -log(L): " << obj_fun << " Spbio: " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)); + cout << current_phase() << " " << niter << " -log(L): " << obj_fun << " SSBio: " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)); } else if (mcmc_counter > 0) { - cout << " MCMC: " << mcmc_counter << " -log(L): " << obj_fun << " Spbio: " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)); + cout << " MCMC: " << mcmc_counter << " -log(L): " << obj_fun << " SSBio: " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)); } else if (mceval_counter > 0) { - cout << " MCeval: " << mceval_counter << " -log(L): " << obj_fun << " Spbio: " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)); + cout << " MCeval: " << mceval_counter << " -log(L): " << obj_fun << " SSBio: " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)); } if (F_Method > 1 && sum(catch_like) > 0.01) { diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index bec821cd..a2e2057c 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1155,11 +1155,11 @@ int Hermaphro_seas; int Hermaphro_firstage; number Hermaphro_seas_rd; - number Hermaphro_maleSPB; + number Hermaphro_maleSSB; LOCAL_CALCS // clang-format on Hermaphro_seas = 0; - Hermaphro_maleSPB = 0.0; + Hermaphro_maleSSB = 0.0; Hermaphro_firstage = 0; MGparm_Hermaphro = 0; @@ -1182,8 +1182,8 @@ // so 2.3 will do switch in season 2 beginning with age 3. echoinput << Hermaphro_seas << " Hermaphro_season (-1 means all seasons)" << endl; echoinput << Hermaphro_firstage << " Hermaphro_firstage (from decimal part of seas input; note that firstage can only be a single digit, so 9 is max" << endl; - *(ad_comm::global_datafile) >> Hermaphro_maleSPB; // read as a fraction (0.0 to 1.0) of the male SSB added into the total SSB - echoinput << Hermaphro_maleSPB << " Hermaphro_maleSPB " << endl; + *(ad_comm::global_datafile) >> Hermaphro_maleSSB; // read as a fraction (0.0 to 1.0) of the male SSB added into the total SSB + echoinput << Hermaphro_maleSSB << " Hermaphro_maleSSB " << endl; } // clang-format off END_CALCS @@ -2190,6 +2190,7 @@ SR_update_SSBpR0_timeseries = 0; break; } + echoinput << "SRupdate " << SR_update_parm << " use " << SR_update_SSBpR0_bmark << " rd " << SR_update_SSBpR0_rd<< endl; echoinput << "SR_Npar and N_SRparm2 and N_SRparm3: " << N_SRparm(SR_fxn) << " " << N_SRparm2 << " " << N_SRparm3 << endl; // clang-format off END_CALCS @@ -5827,7 +5828,7 @@ Extra_Std_N += YrMax - (styr - 2) + 1; if (More_Std_Input(12) == 2) Extra_Std_N += YrMax - (styr - 2) + 1; // for recruitment } - // add 3 values for ln(Spbio) + // add 3 values for ln(SSBio) // (years are automatically generated as startyr, mid-point, and endyr) Do_se_LnSSB = Extra_Std_N + 1; Extra_Std_N += 3; @@ -6881,23 +6882,23 @@ } } - // output ln(SPB) std for selected years - echoinput << " do ln(SPB) std labels for 3 years" << endl; + // output ln(SSB) std for selected years + echoinput << " do ln(SSB) std labels for 3 years" << endl; CoVar_Count++; j++; active_parm(CoVar_Count) = j; sprintf(onenum, "%d", styr); - ParmLabel += "ln(SPB)_" + onenum + CRLF(1); + ParmLabel += "ln(SSB)_" + onenum + CRLF(1); CoVar_Count++; j++; active_parm(CoVar_Count) = j; sprintf(onenum, "%d", int((endyr + styr) / 2)); - ParmLabel += "ln(SPB)_" + onenum + CRLF(1); + ParmLabel += "ln(SSB)_" + onenum + CRLF(1); CoVar_Count++; j++; active_parm(CoVar_Count) = j; sprintf(onenum, "%d", endyr); - ParmLabel += "ln(SPB)_" + onenum + CRLF(1); + ParmLabel += "ln(SSB)_" + onenum + CRLF(1); if (Do_se_smrybio > 0) { diff --git a/SS_readdata_330.tpl b/SS_readdata_330.tpl index d212bcde..56277cb9 100644 --- a/SS_readdata_330.tpl +++ b/SS_readdata_330.tpl @@ -5035,10 +5035,10 @@ if (STD_Yr_Reverse(y) > 0) { j++; - STD_Yr_Reverse(y) = j; // use for SPB and recruitment + STD_Yr_Reverse(y) = j; // use for SSB and recruitment if (y >= styr) { - // depletion must start in year AFTER first catch. It could vary earlier if recdevs happened enough earlier to change spbio, but this is not included + // depletion must start in year AFTER first catch. It could vary earlier if recdevs happened enough earlier to change SSBio, but this is not included if ((depletion_basis > 0 && y > first_catch_yr) || y == endyr) { N_STD_Yr_Dep++; diff --git a/SS_write.tpl b/SS_write.tpl index 96d516b3..a3664db4 100644 --- a/SS_write.tpl +++ b/SS_write.tpl @@ -1011,7 +1011,7 @@ FUNCTION void write_rebuilder_output() rebuild_dat << exp_rec(y, 4) << " "; } rebuild_dat << " #recruits; first value is R0 (virgin)" << endl; - rebuild_dat << SSB_yr(styr - 2) << " " << SSB_yr(styr, k) << " #spbio; first value is SSB_virgin (virgin)" << endl; + rebuild_dat << SSB_yr(styr - 2) << " " << SSB_yr(styr, k) << " #SSBio; first value is SSB_virgin (virgin)" << endl; rebuild_dat << 1 << " "; for (y = styr; y <= k; y++) rebuild_dat << 0 << " "; diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 0fe3f0c0..571e2e4c 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -1516,8 +1516,8 @@ FUNCTION void write_bigoutput() if (s == spawn_seas) { temp = sum(SSB_pop_gp(y, p)); - if (Hermaphro_maleSPB > 0) - temp += Hermaphro_maleSPB * sum(MaleSPB(y, p)); + if (Hermaphro_maleSSB > 0) + temp += Hermaphro_maleSSB * sum(MaleSSB(y, p)); SS2out << temp; } else @@ -1529,7 +1529,7 @@ FUNCTION void write_bigoutput() { SS2out << SSB_pop_gp(y, p); if (Hermaphro_Option != 0) - SS2out << MaleSPB(y, p); + SS2out << MaleSSB(y, p); } else { @@ -1710,7 +1710,7 @@ FUNCTION void write_bigoutput() if (k < 4) k = 4; // quantities to store summary statistics - dvector rmse(1, k); // used in the SpBio, Index, Lencomp and Agecomp reports + dvector rmse(1, k); // used in the SSBio, Index, Lencomp and Agecomp reports dvector Hrmse(1, k); dvector Rrmse(1, k); dvector n_rmse(1, k); @@ -4738,33 +4738,11 @@ FUNCTION void SPR_profile() for (s = 1; s <= nseas; s++) { t = styr - 3 * nseas + s - 1; - - if (MG_active(2) > 0 || MG_active(3) > 0 || save_for_report > 0 || WTage_rd > 0) - { - subseas = 1; - ALK_idx = (s - 1) * N_subseas + subseas; // for midseason - Make_AgeLength_Key(s, subseas); // for begin season - subseas = mid_subseas; - ALK_idx = (s - 1) * N_subseas + subseas; // for midseason - Make_AgeLength_Key(s, subseas); // for midseason - if (s == spawn_seas) - { - subseas = spawn_subseas; - if (spawn_subseas != 1 && spawn_subseas != mid_subseas) - { - //don't call get_growth3(subseas) because using an average ave_size - Make_AgeLength_Key(s, subseas); // spawn subseas - } - get_mat_fec(); - } - } - - for (g = 1; g <= gmorph; g++) - if (use_morph(g) > 0) - { - ALK_idx = (s - 1) * N_subseas + mid_subseas; // for midseason - Make_FishSelex(); - } + Wt_Age_beg(s) = Wt_Age_t(t, 0); // used for smrybio + Wt_Age_mid(s) = Wt_Age_t(t, -1); + if (s == spawn_seas) + fec = Wt_Age_t(t, -2); + report5 << 0 << " y: " << y << " updated_Repro_output spr/ypr: " << fec(1) << endl; } SS2out << "SPRloop Iter Bycatch Fmult F_std SPR YPR_dead YPR_dead*Recr YPR_ret*Recr Revenue Cost Profit SSB Recruits SSB/Bzero Tot_Catch "; @@ -5016,7 +4994,7 @@ FUNCTION void Global_MSY() // GLOBAL_MSY with knife-edge age selection, then slot-age selection SS2out << endl << pick_report_name(55) << endl; - y = styr - 3; // stores the averaged + y = styr - 3; // stores the averaged biology and selectivity, etc. from benchmark yz = y; bio_yr = y; eq_yr = y; @@ -5095,7 +5073,9 @@ FUNCTION void Global_MSY() SS2out << "Actual "; show_MSY = 2; // invokes just brief output in benchmark did_MSY = 0; + report5 << 0 << " y: " << y << " updated_Repro_output global_1: " << fec(1) << endl; Get_Benchmarks(show_MSY); + report5 << 0 << " y: " << y << " updated_Repro_output global_2: " << fec(1) << endl; did_MSY = 0; } } diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 590c76df..7c037fe3 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1548,7 +1548,7 @@ FUNCTION void write_nucontrol() NuStart << final_conv << " # final convergence criteria (e.g. 1.0e-04) " << endl; NuStart << retro_yr - endyr << " # retrospective year relative to end year (e.g. -4)" << endl; NuStart << Smry_Age << " # min age for calc of summary biomass" << endl; - NuStart << depletion_basis_rd << " # Depletion basis: denom is: 0=skip; 1=X*SPBvirgin; 2=X*SPBmsy; 3=X*SPB_styr; 4=X*SPB_endyr; 5=X*dyn_Bzero; values>=11 invoke N multiyr with 10s & 100s digit; append .1 to invoke log(ratio); e.g. 122.1 produces log(12 year trailing average of B/Bmsy)" << endl; + NuStart << depletion_basis_rd << " # Depletion basis: denom is: 0=skip; 1=X*SSBvirgin; 2=X*SSBmsy; 3=X*SSB_styr; 4=X*SSB_endyr; 5=X*dyn_Bzero; values>=11 invoke N multiyr with 10s & 100s digit; append .1 to invoke log(ratio); e.g. 122.1 produces log(12 yr trailing average of B/Bmsy)" << endl; NuStart << depletion_level << " # Fraction (X) for Depletion denominator (e.g. 0.4)" << endl; NuStart << SPR_reporting << " # SPR_report_basis: 0=skip; 1=(1-SPR)/(1-SPR_tgt); 2=(1-SPR)/(1-SPR_MSY); 3=(1-SPR)/(1-SPR_Btarget); 4=rawSPR" << endl; NuStart << F_reporting << " # F_std_reporting_units: 0=skip; 1=exploitation(Bio); 2=exploitation(Num); 3=sum(Apical_F's); 4=mean F for range of ages (numbers weighted); 5=unweighted mean F for range of ages" << endl; @@ -1941,7 +1941,7 @@ FUNCTION void write_nucontrol() if (Hermaphro_Option != 0) { report4 << Hermaphro_seas_rd << " # Hermaphro_season.first_age (seas=-1 means all seasons; first_age must be 0 to 9)" << endl - << Hermaphro_maleSPB << " # fraction_of_maleSSB_added_to_total_SSB " << endl; + << Hermaphro_maleSSB << " # fraction_of_maleSSB_added_to_total_SSB " << endl; } report4 << MGparm_def << " #_parameter_offset_approach for M, G, CV_G: 1- direct, no offset**; 2- male=fem_parm*exp(male_parm); 3: male=female*exp(parm) then old=young*exp(parm)" << endl; @@ -2136,7 +2136,7 @@ FUNCTION void write_nucontrol() report4 << "#" << endl; report4 << SR_fxn << " #_Spawner-Recruitment; Options: 1=NA; 2=Ricker; 3=std_B-H; 4=SCAA; 5=Hockey; 6=B-H_flattop; 7=survival_3Parm; 8=Shepherd_3Parm; 9=RickerPower_3parm" << endl; report4 << init_equ_steepness << " # 0/1 to use steepness in initial equ recruitment calculation" << endl; - report4 << SR_update_SSBpR0_rd << "# SR_update_SSBpR0" << endl << + report4 << SR_update_SSBpR0_rd << " # SR_update_SSBpR0" << endl << "# 0 - OK, but only if no timevary biology or SR parm" << endl << "# 1 - best: update SSBpR0 for benchmark and for time series only if SRparm R0 or h (not regime) is set to have time-varying property" << endl << "# 2 - incorrect (old, incorrect SS3 approach): always update SSBpR0 for benchmark's use of spawner-recruitment, but only for the time series if there is a timevary SR parm" << endl << From 72bac37779aefe74611ae32bc0f22785c0adc14d Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 4 Oct 2024 16:23:39 -0700 Subject: [PATCH 19/58] add HCR_anchor in forecast.ss --- SS_benchfore.tpl | 37 ++++++++++++++++++++----------------- SS_param.tpl | 1 + SS_readdata_330.tpl | 4 ++-- SS_write_report.tpl | 6 +++--- SS_write_ssnew.tpl | 3 ++- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 58e85267..f7a3a3b1 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -776,8 +776,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR report5 << " Benchmark SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_unf << " equil: " << Equ_SpawnRecr_Result << endl; } - report5 << 0 << " y: " << y << " Repro_output_by_age_for_morph_1 bench " << fec(1) << endl; -// report5 << "Repro_output_by_age_for_morph_1: " << fec(1) << endl; } SR_parm_work(N_SRparm2 + 1) = SSB_unf; @@ -2211,6 +2209,11 @@ FUNCTION void Get_Forecast() break; } } + if (Fcast_Loop_Control(5) <= 1) + {HCR_anchor = SSB_unf;} + else if (Fcast_Loop_Control(5) ==2) + {HCR_anchor = SSB_virgin;} + report5 << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl; report5 << "#" << endl; } @@ -2227,7 +2230,7 @@ FUNCTION void Get_Forecast() for (int Fcast_Loop1 = 1; Fcast_Loop1 <= jloop; Fcast_Loop1++) // for different forecast conditions { - report5 << Fcast_Loop1 << " y: " << 0 << " Repro_output_by_age_for_morph_1 top_forecast: " << fec(1) << endl; +// report5 << Fcast_Loop1 << " y: " << 0 << " Repro_output_by_age_for_morph_1 top_forecast: " << fec(1) << endl; switch (Fcast_Loop1) // select which ABC_loops to use { @@ -2315,7 +2318,7 @@ FUNCTION void Get_Forecast() } } } - report5 << Fcast_Loop1 << " y: " << y << " updated_Repro_output_by_age_for_morph_1 endyr: " << fec(1) << endl; +// report5 << Fcast_Loop1 << " y: " << y << " updated_Repro_output_by_age_for_morph_1 endyr: " << fec(1) << endl; for (y = endyr + 1; y <= YrMax; y++) { t_base = styr + (y - styr) * nseas - 1; @@ -2505,7 +2508,7 @@ FUNCTION void Get_Forecast() Wt_Age_mid(s, g) = ALK(ALK_idx, g) * wt_len(s, GP(g)); // use for fisheries with no size selectivity } } - report5 << Fcast_Loop1 << " y: " << y << " updated_Repro_output_by_age_for_morph_1 annual: " << fec(1) << endl; +// report5 << Fcast_Loop1 << " y: " << y << " updated_Repro_output_by_age_for_morph_1 annual: " << fec(1) << endl; Wt_Age_t(t, 0) = Wt_Age_beg(s); for (g = 1; g <= gmorph; g++) if (use_morph(g) > 0) @@ -2663,9 +2666,9 @@ FUNCTION void Get_Forecast() } else if (ABC_Loop == 2 && s == 1) // Calc the buffer in season 1, will use last year's spawnbio if multiseas and spawnseas !=1 { - temp = SSB_unf; - join1 = 1. / (1. + mfexp(10. * (SSB_current - H4010_bot * temp))); - join2 = 1. / (1. + mfexp(10. * (SSB_current - H4010_top * temp))); + + join1 = 1. / (1. + mfexp(10. * (SSB_current - H4010_bot * HCR_anchor))); + join2 = 1. / (1. + mfexp(10. * (SSB_current - H4010_top * HCR_anchor))); switch (HarvestPolicy) { @@ -2678,8 +2681,8 @@ FUNCTION void Get_Forecast() // ramp scales catch as f(B) and buffer (H4010_scale) applied to F { ABC_buffer(y) = H4010_scale_vec(y) * - ((0.0001 * SSB_current / (H4010_bot * temp)) * (join1) // low - + (0.0001 + (1.0 - 0.0001) * (H4010_top * temp / SSB_current) * (SSB_current - H4010_bot * temp) / (H4010_top * temp - H4010_bot * temp)) * (1.0 - join1) // curve + ((0.0001 * SSB_current / (H4010_bot * HCR_anchor)) * (join1) // low + + (0.0001 + (1.0 - 0.0001) * (H4010_top * HCR_anchor / SSB_current) * (SSB_current - H4010_bot * HCR_anchor) / (H4010_top * HCR_anchor - H4010_bot * HCR_anchor)) * (1.0 - join1) // curve ) * (join2) // scale combo + @@ -2690,8 +2693,8 @@ FUNCTION void Get_Forecast() // ramp scales F as f(B) and buffer (H4010_scale) applied to F { ABC_buffer(y) = H4010_scale_vec(y) * - ((0.0001 * SSB_current / (H4010_bot * temp)) * (join1) // low - + (0.0001 + (1.0 - 0.0001) * (SSB_current - H4010_bot * temp) / (H4010_top * temp - H4010_bot * temp)) * (1.0 - join1) // curve + ((0.0001 * SSB_current / (H4010_bot * HCR_anchor)) * (join1) // low + + (0.0001 + (1.0 - 0.0001) * (SSB_current - H4010_bot * HCR_anchor) / (H4010_top * HCR_anchor - H4010_bot * HCR_anchor)) * (1.0 - join1) // curve ) * (join2) // scale combo + @@ -2702,8 +2705,8 @@ FUNCTION void Get_Forecast() // ramp scales catch as f(B) and buffer (H4010_scale) applied to catch { ABC_buffer(y) = 1.0 * - ((0.0001 * SSB_current / (H4010_bot * temp)) * (join1) // low - + (0.0001 + (1.0 - 0.0001) * (H4010_top * temp / SSB_current) * (SSB_current - H4010_bot * temp) / (H4010_top * temp - H4010_bot * temp)) * (1.0 - join1) // curve + ((0.0001 * SSB_current / (H4010_bot * HCR_anchor)) * (join1) // low + + (0.0001 + (1.0 - 0.0001) * (H4010_top * HCR_anchor / SSB_current) * (SSB_current - H4010_bot * HCR_anchor) / (H4010_top * HCR_anchor - H4010_bot * HCR_anchor)) * (1.0 - join1) // curve ) * (join2) // scale combo + @@ -2714,8 +2717,8 @@ FUNCTION void Get_Forecast() // ramp scales F as f(B) and buffer (H4010_scale) applied to catch { ABC_buffer(y) = 1.0 * - ((0.0001 * SSB_current / (H4010_bot * temp)) * (join1) // low - + (0.0001 + (1.0 - 0.0001) * (SSB_current - H4010_bot * temp) / (H4010_top * temp - H4010_bot * temp)) * (1.0 - join1) // curve + ((0.0001 * SSB_current / (H4010_bot * HCR_anchor)) * (join1) // low + + (0.0001 + (1.0 - 0.0001) * (SSB_current - H4010_bot * HCR_anchor) / (H4010_top * HCR_anchor - H4010_bot * HCR_anchor)) * (1.0 - join1) // curve ) * (join2) // scale combo + @@ -3520,7 +3523,7 @@ FUNCTION void Get_Forecast() f = fish_fleet_area(0, ff); if (fleet_type(f) == 1) { - if (ABC_Loop == 2 && HarvestPolicy >= 3) + if (ABC_Loop == 2 && HarvestPolicy >= 3) // alternative ABC_buffer approach { catch_fleet(t, f) *= H4010_scale_vec(y); } diff --git a/SS_param.tpl b/SS_param.tpl index 110bce12..b077172f 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -235,6 +235,7 @@ PARAMETER_SECTION init_bounded_vector Fcast_recruitments(recdev_end+1,s,recdev_LO,recdev_HI,Fcast_recr_PH2) init_bounded_vector Fcast_impl_error(endyr+1,j,-1,1,k) vector ABC_buffer(endyr+1,YrMax); + number HCR_anchor // basis (denominator) bor inflection in control rule // SPAWN-RECR: define some spawning biomass and recruitment entities number SSB_virgin diff --git a/SS_readdata_330.tpl b/SS_readdata_330.tpl index 56277cb9..96658403 100644 --- a/SS_readdata_330.tpl +++ b/SS_readdata_330.tpl @@ -4345,8 +4345,8 @@ "even when the base is set to the mean of earlier recruitments" << endl; } - echoinput << Fcast_Loop_Control(5) << " #echo: loop control 5 not used" << endl; - + echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=unfished_benchmark_SSB(old_approach), 2=virgin_SSB " << endl; + echoinput << "#next enter year in which Fcast loop 3 caps and allocations begin to be applied" << endl; *(ad_comm::global_datafile) >> Fcast_Cap_FirstYear; echoinput << Fcast_Cap_FirstYear << " # echoed value" << endl; diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 571e2e4c..72b5d79d 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -4742,7 +4742,7 @@ FUNCTION void SPR_profile() Wt_Age_mid(s) = Wt_Age_t(t, -1); if (s == spawn_seas) fec = Wt_Age_t(t, -2); - report5 << 0 << " y: " << y << " updated_Repro_output spr/ypr: " << fec(1) << endl; +// report5 << 0 << " y: " << y << " updated_Repro_output spr/ypr: " << fec(1) << endl; } SS2out << "SPRloop Iter Bycatch Fmult F_std SPR YPR_dead YPR_dead*Recr YPR_ret*Recr Revenue Cost Profit SSB Recruits SSB/Bzero Tot_Catch "; @@ -5073,9 +5073,9 @@ FUNCTION void Global_MSY() SS2out << "Actual "; show_MSY = 2; // invokes just brief output in benchmark did_MSY = 0; - report5 << 0 << " y: " << y << " updated_Repro_output global_1: " << fec(1) << endl; +// report5 << 0 << " y: " << y << " updated_Repro_output global_1: " << fec(1) << endl; Get_Benchmarks(show_MSY); - report5 << 0 << " y: " << y << " updated_Repro_output global_2: " << fec(1) << endl; +// report5 << 0 << " y: " << y << " updated_Repro_output global_2: " << fec(1) << endl; did_MSY = 0; } } diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 7c037fe3..44188a2c 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1642,6 +1642,7 @@ FUNCTION void write_nucontrol() NuFore << HarvestPolicy << " # Control rule method (0: none; 1: ramp does catch=f(SSB), buffer on F; 2: ramp does F=f(SSB), buffer on F; 3: ramp does catch=f(SSB), buffer on catch; 4: ramp does F=f(SSB), buffer on catch) " << endl; NuFore << "# values for top, bottom and buffer exist, but not used when Policy=0" << endl; NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of Bzero, e.g. 0.40); must be > control rule cutoff, or set to -1 to use Bmsy/SSB_unf " << endl; + NuFore << "# Also see HCR_anchor below" << endl; NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of Bzero, e.g. 0.10) " << endl; NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar] with filling from year to YrMax " << endl; if (H4010_scale_rd < 0) @@ -1665,7 +1666,7 @@ FUNCTION void write_nucontrol() { NuFore << Fcast_Loop_Control(4) << " # multiplier on base recruitment " << endl; } - NuFore << Fcast_Loop_Control(5) << " # not used" << endl << "#" << endl; + NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 1 uses unfished benchmark SSB (old hardwired approach), 2 = virgin SSB" << endl << "#" << endl; NuFore << Fcast_Cap_FirstYear << " # FirstYear for caps and allocations (should be after years with fixed inputs) " << endl; From 1712c7c5254d7a4c9c7332ff39d868d23827d2a4 Mon Sep 17 00:00:00 2001 From: Ian Taylor Date: Fri, 18 Oct 2024 09:43:01 -0700 Subject: [PATCH 20/58] revert change in capitalization of Recr_Virgin --- SS_readcontrol_330.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index a2e2057c..6df633b6 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -6527,7 +6527,7 @@ active_parm(CoVar_Count) = j; if (y == styr - 2) { - ParmLabel += "Recr_virgin"; + ParmLabel += "Recr_Virgin"; } else if (y == styr - 1) { From 7ffbff5c9a034a44bc0ec500c9cb5e3fb7bcebe7 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Thu, 17 Oct 2024 16:07:03 -0700 Subject: [PATCH 21/58] latest update --- SS_benchfore.tpl | 25 +++++++++++++------------ SS_param.tpl | 2 +- SS_write_ssnew.tpl | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index f7a3a3b1..ce9ded30 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -767,7 +767,8 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (show_MSY == 1) { report5 << "SR_parms for benchmark: " << SR_parm_work << endl - << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << " flag for updating SSBpR0 = " << SR_update_SSBpR0_bmark << endl; + << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << + "input.SR_update_SSBpR0_rd: " << SR_update_SSBpR0_rd << "flag for updating SSBpR0_Bmark: " << SR_update_SSBpR0_bmark << endl; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR report5 << " Virgin SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " equil: " << Equ_SpawnRecr_Result << endl; if ( SR_update_SSBpR0_bmark == 1) @@ -2176,10 +2177,16 @@ FUNCTION void Get_Forecast() { H4010_top = H4010_top_rd; } + if (Fcast_Loop_Control(5) <= 1) + {HCR_anchor = SSB_unf;} + else if (Fcast_Loop_Control(5) ==2) + {HCR_anchor = SSB_virgin;} report5 << "#" << endl; report5 << "N_forecast_yrs: " << N_Fcast_Yrs << endl; - report5 << "OY_Control_Rule " - << " Inflection: " << H4010_top << " Intercept: " << H4010_bot << " Scale: " << H4010_scale_vec(endyr + 1) << "; "; + report5 << "OY_Control_Rule: Inflection: " << H4010_top << " Intercept: " << H4010_bot << " Scale: " << H4010_scale_vec(endyr + 1) << endl + << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl; + report5 << "#" << endl; + switch (HarvestPolicy) { case 0: // none @@ -2209,13 +2216,7 @@ FUNCTION void Get_Forecast() break; } } - if (Fcast_Loop_Control(5) <= 1) - {HCR_anchor = SSB_unf;} - else if (Fcast_Loop_Control(5) ==2) - {HCR_anchor = SSB_virgin;} - report5 << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl; - report5 << "#" << endl; - } + } int jloop; if (fishery_on_off == 1 || Do_Dyn_Bzero > 0) @@ -2264,7 +2265,7 @@ FUNCTION void Get_Forecast() if (HarvestPolicy == 0) report5 << "pop year ABC_Loop season No_buffer bio-all bio-Smry SpawnBio Depletion recruit-0 "; if (HarvestPolicy <= 2) - report5 << "pop year ABC_Loop season Ramp&Buffer bio-all bio-Smry SpawnBio Depletion recruit-0 "; + report5 << "pop year ABC_Loop season Ramp&Buffer Buffer2 bio-all bio-Smry SpawnBio Depletion recruit-0 "; if (HarvestPolicy >= 3) report5 << "pop year ABC_Loop season Ramp bio-all bio-Smry SpawnBio Depletion recruit-0 "; for (int ff = 1; ff <= N_catchfleets(0); ff++) @@ -3138,7 +3139,7 @@ FUNCTION void Get_Forecast() } if (show_MSY == 1) { - report5 << p << " " << y << " " << ABC_Loop << " " << s << " " << ABC_buffer(y) << " " << totbio << " " << smrybio << " "; + report5 << p << " " << y << " " << ABC_Loop << " " << s << " " << ABC_buffer(y) << " " << H4010_scale_vec(y) << " " << totbio << " " << smrybio << " "; if (s == spawn_seas) { report5 << SSB_current << " "; diff --git a/SS_param.tpl b/SS_param.tpl index b077172f..b6f9341b 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -235,7 +235,7 @@ PARAMETER_SECTION init_bounded_vector Fcast_recruitments(recdev_end+1,s,recdev_LO,recdev_HI,Fcast_recr_PH2) init_bounded_vector Fcast_impl_error(endyr+1,j,-1,1,k) vector ABC_buffer(endyr+1,YrMax); - number HCR_anchor // basis (denominator) bor inflection in control rule + number HCR_anchor // basis (denominator) for inflection in control rule. Select virgin SSB or benchmark SSB // SPAWN-RECR: define some spawning biomass and recruitment entities number SSB_virgin diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 44188a2c..30a11a62 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1642,9 +1642,9 @@ FUNCTION void write_nucontrol() NuFore << HarvestPolicy << " # Control rule method (0: none; 1: ramp does catch=f(SSB), buffer on F; 2: ramp does F=f(SSB), buffer on F; 3: ramp does catch=f(SSB), buffer on catch; 4: ramp does F=f(SSB), buffer on catch) " << endl; NuFore << "# values for top, bottom and buffer exist, but not used when Policy=0" << endl; NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of Bzero, e.g. 0.40); must be > control rule cutoff, or set to -1 to use Bmsy/SSB_unf " << endl; - NuFore << "# Also see HCR_anchor below" << endl; NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of Bzero, e.g. 0.10) " << endl; NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar] with filling from year to YrMax " << endl; + NuFore << "# Also see HCR_anchor below" << endl; if (H4010_scale_rd < 0) { j = H4010_scale_vec_rd.size() - 1; From 7f14cd6f0a1a7d6ef89a7c600598893ca35339c7 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Thu, 23 Jan 2025 14:33:17 -0800 Subject: [PATCH 22/58] add 3 lines to mgmt_quant --- SS_benchfore.tpl | 52 ++++++++++++++++++++++++------------------ SS_popdyn.tpl | 2 +- SS_readcontrol_330.tpl | 20 +++++++++++++++- SS_recruit.tpl | 2 +- SS_write_report.tpl | 18 +++++++++++---- 5 files changed, 64 insertions(+), 30 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index ce9ded30..234b2c08 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -9,9 +9,9 @@ // SSBpR refers to SSB per recruit calculated with equilibrium age composition in equil_calc // SPR refers to spawner potential ratio which is the ratio of SSBpR at some level of F to SSBpR with F = 0 -// SSBpR_virgin calculated and reported, but never used -// SSBpR_virgin_adj used only in the alpha-beta spawner-recruitment. _adj means could be updated if SR_update_SSBpR0_timeseries == 1. Also used to get alpha in equil_spawn_recr B-H -// but note that also uses SSB_virgin_use. So need to align _use with _adj +// SSBpR_virgin is calculated in popdyn using the start year biology +// SSBpR_virgin_adj used in equil_spawn_recr. _adj means could be updated if SR_update_SSBpR0_timeseries == 1. +// Also used to get alpha in equil_spawn_recr B-H FUNCTION void setup_Benchmark() // and forecast { @@ -754,12 +754,13 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Recr_unf = Recr_virgin; SSB_unf = SSB_virgin; SSBpR_unf = SSB_unf / Recr_unf; + SSBpR_virgin_adj = SSB_unf / Recr_unf; // so same as SSBpR_virgin, but is the version that will be used in equil_spawn_recr() } else // use benchmark biology in the spawner-recruitment R0,h calculations { Fishon = 0; Recr_unf = mfexp(SR_parm_work(1)); - Do_Equil_Calc(Recr_unf); + Do_Equil_Calc(Recr_unf); // this calcs SSB using benchmark biology SSB_unf = SSB_equil; // equilibrium unfished SSB using the benchmark averaged Recr_unf and benchmark averaged biology SSBpR_unf = SSB_unf / Recr_unf; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin SSBpR_virgin_adj = SSB_unf / Recr_unf; // update @@ -767,17 +768,21 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (show_MSY == 1) { report5 << "SR_parms for benchmark: " << SR_parm_work << endl - << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << - "input.SR_update_SSBpR0_rd: " << SR_update_SSBpR0_rd << "flag for updating SSBpR0_Bmark: " << SR_update_SSBpR0_bmark << endl; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Virgin SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " equil: " << Equ_SpawnRecr_Result << endl; + << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << endl << + "input_SR_update_SSBpR0_rd: " << SR_update_SSBpR0_rd << "; flag for updating SSBpR0_Bmark: " << SR_update_SSBpR0_bmark << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Virgin SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " " << SSB_virgin/Recr_virgin << " equil: " << Equ_SpawnRecr_Result << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Benchmark SSB, R0, virgin_SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_virgin << " equil: " << Equ_SpawnRecr_Result << endl; if ( SR_update_SSBpR0_bmark == 1) { report5 << "SPR0 for equilibrium spawner-recruit based on benchmark biology, not virgin biology" << endl; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_unf); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << " Benchmark SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_unf << " equil: " << Equ_SpawnRecr_Result << endl; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_virgin_adj); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << " Benchmark SSB, R0, bench_SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_virgin_adj << " equil: " << Equ_SpawnRecr_Result << endl; } - + Mgmt_quant(19) = Recr_unf; + Mgmt_quant(20) = SSB_unf; + Mgmt_quant(21) = SSB_unf; // placeholder to be replaced by SSB_HCR_infl } SR_parm_work(N_SRparm2 + 1) = SSB_unf; Mgmt_quant(1) = SSB_unf; @@ -928,7 +933,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc equil spawn-recr in YPR; need to make this area-specific SSBpR_temp = SSB_equil; // based on most recent call to Do_Equil_Calc - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bspr = Equ_SpawnRecr_Result(1); Bspr_rec = Equ_SpawnRecr_Result(2); @@ -1043,7 +1048,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F0.1: " << Btgt_Fmult << endl; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt = Equ_SpawnRecr_Result(1); Btgt_Rec = Equ_SpawnRecr_Result(2); YPR_Btgt_enc = YPR_enc; // total encountered yield per recruit @@ -1139,7 +1144,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSBpR_temp = SSB_equil; SPR_Btgt = SSBpR_temp / SSBpR_unf; // where SSBpR_unf = SSB_unf / Recr_unf so units of SSB/R; so result is SPR_Btgt = (fished SSB/R) / (unfished SSB/R) // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1360,7 +1365,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SSBpR_unf; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); // with MSY set to SPR, not directly estimated Recr_msy = Equ_SpawnRecr_Result(2); yld1(1) = YPR_opt * Recr_msy; @@ -1387,12 +1392,13 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << endl; } - Mgmt_quant(15) = yld1(1); Mgmt_quant(12) = Bmsy; Mgmt_quant(13) = MSY_SPR; Mgmt_quant(14) = equ_F_std; + Mgmt_quant(15) = yld1(1); Mgmt_quant(16) = YPR_ret * Recr_msy; Mgmt_quant(17) = Bmsy / SSB_unf; + Mgmt_quant(18) = Recr_msy; Vbio1_MSY = smrybio; Vbio_MSY = totbio; } @@ -1453,7 +1459,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SSBpR_unf; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); // MSY is directly estimated Recr_msy = Equ_SpawnRecr_Result(2); Profit = (PricePerF * YPR_val_vec) * Recr_msy - Cost; @@ -1525,12 +1531,14 @@ FUNCTION void Get_Benchmarks(const int show_MSY) YPR_msy_profit = YPR_msy_revenue - Cost; MSY = yld1(1); MSY_Fmult = Fmult; - Mgmt_quant(15) = yld1(1); Mgmt_quant(12) = Bmsy; Mgmt_quant(13) = MSY_SPR; Mgmt_quant(14) = equ_F_std; + Mgmt_quant(15) = yld1(1); Mgmt_quant(16) = YPR_ret * Recr_msy; Mgmt_quant(17) = Bmsy / SSB_unf; + Mgmt_quant(18) = Recr_msy; + Vbio1_MSY = smrybio; Vbio_MSY = totbio; @@ -1747,7 +1755,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SPR_Btgt2 = SSB_equil / SSBpR_unf; // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1816,9 +1824,9 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Btgt_Fmult2 = Fmult; if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F_Blimit " << Btgt_Fmult2 << " " << Btgt2 / Blim_report << endl; - Mgmt_quant(18) = Btgt2; - Mgmt_quant(19) = equ_F_std; - Mgmt_quant(20) = sum(equ_catch_fleet(2)) * Equ_SpawnRecr_Result(2); + Mgmt_quant(22) = Btgt2; + Mgmt_quant(23) = equ_F_std; + Mgmt_quant(24) = sum(equ_catch_fleet(2)) * Equ_SpawnRecr_Result(2); } // end finding F for Blimit if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 6b51ce91..efedf516 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -536,7 +536,7 @@ FUNCTION void get_initial_conditions() SSBpR_temp = SSB_equil / equ_Recr; // spawners per recruit at initial F // get equilibrium SSB and recruitment from SSBpR_temp, Recr_virgin and virgin steepness // this is the initial year, so no time-vary effects available, so uses _virgin quantities for spawner-recruitment - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR R1_exp = Equ_SpawnRecr_Result(2); // set the expected recruitment equal to this equilibrium exp_rec(eq_yr, 1) = R1_exp; diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 6df633b6..42e07f53 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -5871,7 +5871,7 @@ // clang-format on if (Do_Benchmark > 0) { - N_STD_Mgmt_Quant = 17; + N_STD_Mgmt_Quant = 21; if (Do_Benchmark == 3) N_STD_Mgmt_Quant += 3; // for Blimit } else @@ -6678,6 +6678,24 @@ CoVar_Count++; j++; active_parm(CoVar_Count) = j; +// add quantities needed when time-vary life history is used; but report here for all cases; elements 18-21 of mgmt_quant + ParmLabel += "Recr_MSY_bmarkbio" + CRLF(1); + CoVar_Count++; + j++; + active_parm(CoVar_Count) = j; + ParmLabel += "Recr_unfished_bmarkbio" + CRLF(1); + CoVar_Count++; + j++; + active_parm(CoVar_Count) = j; + ParmLabel += "SSB_unfished_bmarkbio" + CRLF(1); + CoVar_Count++; + j++; + active_parm(CoVar_Count) = j; + ParmLabel += "SSB_HCR_infl" + CRLF(1); + CoVar_Count++; + j++; + active_parm(CoVar_Count) = j; + if (Do_Benchmark == 3) { ParmLabel += "SSB_Blim" + CRLF(1); diff --git a/SS_recruit.tpl b/SS_recruit.tpl index 645dbcf3..88815fa9 100644 --- a/SS_recruit.tpl +++ b/SS_recruit.tpl @@ -268,7 +268,7 @@ FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_vir /* SS_Label_FUNCTION 44 Equil_Spawn_Recr_Fxn */ // SPAWN-RECR: function Equil_Spawn_Recr_Fxn FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, - const prevariable& SSB_virgin_use, const prevariable& Recr_virgin_use, const prevariable& SSBpR_current) + const prevariable& SSB_virgin_use, const prevariable& Recr_virgin_use, const prevariable& SSBpR_virgin_adj, const prevariable& SSBpR_current) { RETURN_ARRAYS_INCREMENT(); dvar_vector Equil_Spawn_Recr_Calc(1, 2); // values to return 1 is B_equil, 2 is R_equil diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 72b5d79d..558aad3f 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -4742,10 +4742,10 @@ FUNCTION void SPR_profile() Wt_Age_mid(s) = Wt_Age_t(t, -1); if (s == spawn_seas) fec = Wt_Age_t(t, -2); -// report5 << 0 << " y: " << y << " updated_Repro_output spr/ypr: " << fec(1) << endl; + report5 << " repro_output for spr/ypr: " << fec(1) << endl; } - SS2out << "SPRloop Iter Bycatch Fmult F_std SPR YPR_dead YPR_dead*Recr YPR_ret*Recr Revenue Cost Profit SSB Recruits SSB/Bzero Tot_Catch "; + SS2out << "SPRloop Iter Bycatch Fmult F_std SSBpR YpR_dead YpR_dead*Recr YpR_ret*Recr Revenue Cost Profit SSB Recruits SSB/Bzero Tot_Catch "; for (f = 1; f <= Nfleet; f++) { if (fleet_type(f) <= 2) @@ -4789,20 +4789,28 @@ FUNCTION void SPR_profile() k = 1; } for (int with_BYC = 0; with_BYC <= k; with_BYC++) - for (int SPRloop1 = 0; SPRloop1 <= SPRloop1_end; SPRloop1++) + for (int SPRloop1 = -1; SPRloop1 <= SPRloop1_end; SPRloop1++) { Fmultchanger1 = value(pow(0.0001 / Fcrash, 0.025)); Fmultchanger2 = value(Fcrash / 39.); SPRloops = 40; switch (SPRloop1) { + case -1: + { + SPRloops = 1; + Fmult2 = 0.0; + break; + } case 0: { + SPRloops = 40; Fmult2 = maxpossF; break; } case 1: { + SPRloops = 40; Fmult2 = Fcrash; break; } @@ -4894,7 +4902,7 @@ FUNCTION void SPR_profile() Do_Equil_Calc(equ_Recr); // SPAWN-RECR: calc equil spawn-recr in the SPR loop SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt_prof = Equ_SpawnRecr_Result(1); Btgt_prof_rec = Equ_SpawnRecr_Result(2); if (Btgt_prof < 0.001 || Btgt_prof_rec < 0.001) @@ -4954,7 +4962,7 @@ FUNCTION void SPR_profile() { SS2out << " " << SSB_equil_pop_gp(p, gp) * Btgt_prof_rec; } - SS2out << endl; + SS2out << " R " << equ_Recr << " SSB " << SSB_equil << endl; if (SPRloop1 == 0) { Fmult2 -= Fmultchanger0; From cec04047f0fa418422ab18519ab28c818f53ecba Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Thu, 20 Feb 2025 08:49:35 -0800 Subject: [PATCH 23/58] add 4 lines to mgmt_quant to display more benchmark quantities --- SS_benchfore.tpl | 36 ++++++++++++++++++++---------------- SS_popdyn.tpl | 2 +- SS_readcontrol_330.tpl | 6 +++++- SS_write_ssnew.tpl | 2 +- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 234b2c08..a63857c6 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -783,6 +783,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Mgmt_quant(19) = Recr_unf; Mgmt_quant(20) = SSB_unf; Mgmt_quant(21) = SSB_unf; // placeholder to be replaced by SSB_HCR_infl + Mgmt_quant(22) = SSB_virgin; } SR_parm_work(N_SRparm2 + 1) = SSB_unf; Mgmt_quant(1) = SSB_unf; @@ -1824,9 +1825,9 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Btgt_Fmult2 = Fmult; if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F_Blimit " << Btgt_Fmult2 << " " << Btgt2 / Blim_report << endl; - Mgmt_quant(22) = Btgt2; - Mgmt_quant(23) = equ_F_std; - Mgmt_quant(24) = sum(equ_catch_fleet(2)) * Equ_SpawnRecr_Result(2); + Mgmt_quant(N_STD_Mgmt_Quant - 2) = Btgt2; + Mgmt_quant(N_STD_Mgmt_Quant - 1) = equ_F_std; + Mgmt_quant(N_STD_Mgmt_Quant) = sum(equ_catch_fleet(2)) * Equ_SpawnRecr_Result(2); } // end finding F for Blimit if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) @@ -2172,23 +2173,26 @@ FUNCTION void Get_Forecast() } } - if (H4010_top_rd < 0.0) - { - H4010_top = Bmsy / SSB_unf; - if (H4010_bot > 0.25) - { - warnstream << "control rule cutoff is large (" << H4010_bot << "); so may not be < calculated Bmsy/SSB_unf (" << H4010_top << ")"; - write_message (WARN, 0); - } - } - else - { - H4010_top = H4010_top_rd; - } if (Fcast_Loop_Control(5) <= 1) {HCR_anchor = SSB_unf;} else if (Fcast_Loop_Control(5) ==2) {HCR_anchor = SSB_virgin;} + + if (H4010_top_rd < 0.0) + { + H4010_top = Bmsy / HCR_anchor; // convert to fraction + if (H4010_bot > 0.25) + { + warnstream << "control rule cutoff is large (" << H4010_bot << "); so may not be < calculated Bmsy/SSB_unf (" << H4010_top << ")"; + write_message (WARN, 0); + } + } + else + { + H4010_top = H4010_top_rd; + } + + Mgmt_quant(21) = H4010_top * HCR_anchor; report5 << "#" << endl; report5 << "N_forecast_yrs: " << N_Fcast_Yrs << endl; report5 << "OY_Control_Rule: Inflection: " << H4010_top << " Intercept: " << H4010_bot << " Scale: " << H4010_scale_vec(endyr + 1) << endl diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index efedf516..adc7e1d9 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -383,8 +383,8 @@ FUNCTION void get_initial_conditions() // SSBpR_virgin = SSB_equil / Recr_virgin; // spawners per recruit already calculated if(Do_Benchmark==0) // assign values that would be created in benchmark section { - Mgmt_quant(1) = SSB_virgin; // can be overwritten in benchmark by updated SSB_unf SSB_unf = SSB_virgin; + Mgmt_quant(1) = SSB_unf; // can be overwritten in benchmark by updated SSB_unf Recr_unf = Recr_virgin; Mgmt_quant(2) = totbio; // from equil calcs Mgmt_quant(3) = smrybio; // from equil calcs diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 42e07f53..a4a8bbb5 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -5871,7 +5871,7 @@ // clang-format on if (Do_Benchmark > 0) { - N_STD_Mgmt_Quant = 21; + N_STD_Mgmt_Quant = 22; if (Do_Benchmark == 3) N_STD_Mgmt_Quant += 3; // for Blimit } else @@ -6695,6 +6695,10 @@ CoVar_Count++; j++; active_parm(CoVar_Count) = j; + ParmLabel += "SSB_virgin_again" + CRLF(1); + CoVar_Count++; + j++; + active_parm(CoVar_Count) = j; if (Do_Benchmark == 3) { diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 30a11a62..0d4ad371 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1641,7 +1641,7 @@ FUNCTION void write_nucontrol() NuFore << HarvestPolicy << " # Control rule method (0: none; 1: ramp does catch=f(SSB), buffer on F; 2: ramp does F=f(SSB), buffer on F; 3: ramp does catch=f(SSB), buffer on catch; 4: ramp does F=f(SSB), buffer on catch) " << endl; NuFore << "# values for top, bottom and buffer exist, but not used when Policy=0" << endl; - NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of Bzero, e.g. 0.40); must be > control rule cutoff, or set to -1 to use Bmsy/SSB_unf " << endl; + NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of Bzero, e.g. 0.40); must be > control rule cutoff, or set to -1 to use Bmsy as the inflection " << endl; NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of Bzero, e.g. 0.10) " << endl; NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar] with filling from year to YrMax " << endl; NuFore << "# Also see HCR_anchor below" << endl; From f232d531f82da34f5ac89638ab2fc5ae575461c1 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 21 Feb 2025 16:40:31 -0800 Subject: [PATCH 24/58] assure align of SRR curve and SPR/YPR profile --- SS_benchfore.tpl | 45 ++++++++++++++++++++++----------------------- SS_param.tpl | 2 +- SS_popdyn.tpl | 12 ++++++------ SS_recruit.tpl | 4 ++-- SS_write_report.tpl | 12 +++++++----- 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index a63857c6..4f86b30a 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -10,7 +10,7 @@ // SPR refers to spawner potential ratio which is the ratio of SSBpR at some level of F to SSBpR with F = 0 // SSBpR_virgin is calculated in popdyn using the start year biology -// SSBpR_virgin_adj used in equil_spawn_recr. _adj means could be updated if SR_update_SSBpR0_timeseries == 1. +// SSBpR_virgin_4SRR is passed to equil_spawn_recr. _adj means could be updated if SR_update_SSBpR0_timeseries == 1. // Also used to get alpha in equil_spawn_recr B-H FUNCTION void setup_Benchmark() // and forecast @@ -749,12 +749,19 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SR_parm_work(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); } } + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin_4SRR, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + report5 << endl << " virgin - SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " " << SSBpR_virgin << " equil: " << Equ_SpawnRecr_Result << endl< 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F0.1: " << Btgt_Fmult << endl; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_4SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt = Equ_SpawnRecr_Result(1); Btgt_Rec = Equ_SpawnRecr_Result(2); YPR_Btgt_enc = YPR_enc; // total encountered yield per recruit @@ -1145,7 +1144,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSBpR_temp = SSB_equil; SPR_Btgt = SSBpR_temp / SSBpR_unf; // where SSBpR_unf = SSB_unf / Recr_unf so units of SSB/R; so result is SPR_Btgt = (fished SSB/R) / (unfished SSB/R) // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_adj, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_4SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1185,7 +1184,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << " " << SSB_equil_pop_gp(p, gp) * Equ_SpawnRecr_Result(2); } report5 << endl; -// " SSB_unf " << SSB_unf << " recr " < Date: Tue, 25 Feb 2025 15:54:07 -0800 Subject: [PATCH 25/58] adjust SPR in profile to match old approach --- SS_write_report.tpl | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 605facfe..51a21d98 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -4746,6 +4746,29 @@ FUNCTION void SPR_profile() SS2out << " repro_output for spr/ypr: " << fec(1) << endl;} } + if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations in bmark + { + Recr_unf = Recr_virgin; + SSB_unf = SSB_virgin; + Fishon = 0; + Recr_unf = Recr_virgin; + Do_Equil_Calc(Recr_unf); // this calcs SSB using benchmark biology + temp1 = SSB_equil; // equilibrium unfished SSB using the benchmark averaged Recr_unf and benchmark averaged biology + temp2 = temp1 / Recr_unf; + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin_4SRR, temp2); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + SS2out << " virgSRR_&_bmarkbio - SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " " << SSBpR_virgin_4SRR << " equil: " << Equ_SpawnRecr_Result << endl< Date: Tue, 11 Mar 2025 10:35:36 -0700 Subject: [PATCH 26/58] WIP --- SS_benchfore.tpl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 4f86b30a..6ac46694 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -754,12 +754,11 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations in bmark { Recr_unf = Recr_virgin; - SSB_unf = SSB_virgin; Fishon = 0; - Recr_unf = Recr_virgin; - Do_Equil_Calc(Recr_unf); // this calcs SSB using benchmark biology - temp1 = SSB_equil; // equilibrium unfished SSB using the benchmark averaged Recr_unf and benchmark averaged biology - temp2 = temp1 / Recr_unf; +// Recr_unf = Recr_virgin; + Do_Equil_Calc(Recr_virgin); // this calcs SSB + SSB_unf = SSB_equil; // equilibrium unfished SSB using the benchmark averaged Recr_unf and benchmark averaged biology + temp2 = SSB_unf / Recr_virgin; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin_4SRR, temp2); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR report5 << " virgSRR_&_bmarkbio - SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " " << SSBpR_virgin_4SRR << " equil: " << Equ_SpawnRecr_Result << endl< Date: Thu, 13 Mar 2025 15:25:07 -0700 Subject: [PATCH 27/58] still a WIP --- SS_benchfore.tpl | 129 +++++++++++++++++++++++------------------ SS_param.tpl | 4 +- SS_popdyn.tpl | 23 ++++---- SS_readcontrol_330.tpl | 5 ++ SS_recruit.tpl | 4 +- SS_write_report.tpl | 22 +++---- 6 files changed, 103 insertions(+), 84 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 6ac46694..9e33d32c 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -10,8 +10,7 @@ // SPR refers to spawner potential ratio which is the ratio of SSBpR at some level of F to SSBpR with F = 0 // SSBpR_virgin is calculated in popdyn using the start year biology -// SSBpR_virgin_4SRR is passed to equil_spawn_recr. _adj means could be updated if SR_update_SSBpR0_timeseries == 1. -// Also used to get alpha in equil_spawn_recr B-H +// SSBpR_virgin_4_SRR used to get alpha in equil_spawn_recr B-H FUNCTION void setup_Benchmark() // and forecast { @@ -749,48 +748,58 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SR_parm_work(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); } } - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin_4SRR, SSBpR_virgin); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - report5 << endl << " virgin - SSB, R0, SPR0: " << SSB_virgin << " " << Recr_virgin << " " << SSBpR_virgin << " " << SSBpR_virgin << " equil: " << Equ_SpawnRecr_Result << endl< 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F0.1: " << Btgt_Fmult << endl; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_4SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt = Equ_SpawnRecr_Result(1); Btgt_Rec = Equ_SpawnRecr_Result(2); YPR_Btgt_enc = YPR_enc; // total encountered yield per recruit @@ -1074,20 +1083,26 @@ FUNCTION void Get_Benchmarks(const int show_MSY) else // find F giving Btarget SS_Label_720 { // ****************************************************** + + if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations + {Btgttgt = BTGT_target * SSB_virgin;} + else + {Btgttgt = BTGT_target * SSB_unf;} if (show_MSY == 1) { - report5 << "#" << endl; - if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations - {report5 << "Find_target_SSB/Bzero; where Bzero is Virgin SSB:" << SSB_unf << " where SSBpR_unf = " << SSBpR_unf << endl;} - else - {report5 << "Find_target_SSB/Bzero; where Bzero is for Bmark biology and updated SPR0: " << SSB_unf << " where SSBpR_unf = " << SSBpR_unf << endl;} - report5 << "Iter Fmult ann_F SPR Catch SSB Recruits SSB/Bzero Tot_catch"; - for (p = 1; p <= pop; p++) - for (gp = 1; gp <= N_GP; gp++) - { - report5 << " SSB_Area:" << p << "_GP:" << gp; - } - report5 << endl; + report5 << "#" << endl; + if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations + {report5 << "Find_target_SSB/Bzero; where Bzero is Virgin SSB:" << SSB_virgin << " where SSBpR_unf = " << SSBpR_virgin << endl;} + else + {report5 << "Find_target_SSB/Bzero; where Bzero is for Bmark biology and updated SPR0: " << SSB_unf << " where SSBpR_unf = " << SSBpR_virgin_4_SRR << endl;} + report5 << "Iter Fmult ann_F SPR Catch SSB Recruits SSB/Bzero Tot_catch"; + + for (p = 1; p <= pop; p++) + for (gp = 1; gp <= N_GP; gp++) + { + report5 << " SSB_Area:" << p << "_GP:" << gp; + } + report5 << endl; } F1(1) = log(1.0e-3); @@ -1107,8 +1122,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Nloops = 28; } - Btgttgt = BTGT_target * SSB_unf; - for (j = 0; j <= Nloops; j++) // loop find Btarget { if (fabs(Fchange) <= Closer2) @@ -1146,7 +1159,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSBpR_temp = SSB_equil; SPR_Btgt = SSBpR_temp / SSBpR_unf; // where SSBpR_unf = SSB_unf / Recr_unf so units of SSB/R; so result is SPR_Btgt = (fished SSB/R) / (unfished SSB/R) // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_unf, Recr_unf, SSBpR_virgin_4SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1186,7 +1199,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << " " << SSB_equil_pop_gp(p, gp) * Equ_SpawnRecr_Result(2); } report5 << endl; -// " SSB_unf " << SSB_unf << " recr " < 0) SPR_std(STD_Yr_Reverse_Ofish(y)) = SSB_equil / Smry_Table(y, 11); diff --git a/SS_param.tpl b/SS_param.tpl index 4af7af91..d174efc7 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -166,7 +166,9 @@ PARAMETER_SECTION number half_sigmaRsq; number sigmaR; number SSBpR_virgin; - number SSBpR_virgin_4SRR; + number SSB0_4_SRR; + number R0_4_SRR; + number SSBpR_virgin_4_SRR; // value of SSB/R used in SRR number regime_change; number rho; number dirichlet_Parm; diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index fd3f7347..752cc348 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -342,9 +342,8 @@ FUNCTION void get_initial_conditions() if (recr_dist_area == 1 || pop == 1) // do global spawn_recruitment calculations { equ_Recr = 1.0; - Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation. Returns SPR because R = 1.0 + Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation. Returns SPR because R = 1.0 SSBpR_virgin = SSB_equil; // spawners per recruit. Needed for Sr_fxn = 10 - SSBpR_virgin_4SRR = SSB_equil; // also needed for Sr_fxn 10. Will get revised in benchmark to use averaged biology if requested. if(SR_fxn == 10) // B-H with a,b { // WHAM based on R = A*S/(1+B*S) @@ -355,8 +354,8 @@ FUNCTION void get_initial_conditions() alpha = mfexp(SR_parm(3)); beta = mfexp(SR_parm(4)); - steepness = alpha * SSBpR_virgin_4SRR / (4. + alpha * SSBpR_virgin_4SRR); - Recr_virgin = 1. / beta * (alpha - (1. / SSBpR_virgin_4SRR)); + steepness = alpha * SSBpR_virgin / (4. + alpha * SSBpR_virgin); + Recr_virgin = 1. / beta * (alpha - (1. / SSBpR_virgin)); // warning << " before AB_calcs " << "parm " << SR_parm(1) << " calc " << log(Recr_virgin) << endl; SR_parm(1) = log(Recr_virgin); SR_parm(2) = steepness; @@ -378,9 +377,8 @@ FUNCTION void get_initial_conditions() exp_rec(eq_yr, 2) = Recr_virgin; exp_rec(eq_yr, 3) = Recr_virgin; exp_rec(eq_yr, 4) = Recr_virgin; - Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation + Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation SSB_virgin = SSB_equil; -// SSBpR_virgin = SSB_equil / Recr_virgin; // spawners per recruit already calculated if(Do_Benchmark==0) // assign values that would be created in benchmark section { SSB_unf = SSB_virgin; @@ -536,7 +534,7 @@ FUNCTION void get_initial_conditions() SSBpR_temp = SSB_equil / equ_Recr; // spawners per recruit at initial F // get equilibrium SSB and recruitment from SSBpR_temp, Recr_virgin and virgin steepness // this is the initial year, so no time-vary effects available, so uses _virgin quantities for spawner-recruitment - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_virgin_4SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR R1_exp = Equ_SpawnRecr_Result(2); // set the expected recruitment equal to this equilibrium exp_rec(eq_yr, 1) = R1_exp; @@ -1038,9 +1036,8 @@ FUNCTION void get_time_series() Fishon = 0; eq_yr = y; bio_yr = y; - Do_Equil_Calc(R0_use); // call function to do equilibrium calculation with current year's biology and adjusted R0 + Do_Equil_Calc(R0_use); // call function to do per recruit calculation with current year's biology and adjusted R0 SSB_use = SSB_equil; - SSBpR_virgin_4SRR = SSB_use / R0_use; // update if (fishery_on_off == 1) { Fishon = 1; @@ -1498,9 +1495,8 @@ FUNCTION void get_time_series() Fishon = 0; eq_yr = y; bio_yr = y; - Do_Equil_Calc(R0_use); // call function to do equilibrium calculation + Do_Equil_Calc(R0_use); // call function to do per recruit calculation SSB_use = SSB_equil; - SSBpR_virgin_4SRR = SSB_use / R0_use; // update if (fishery_on_off == 1) { Fishon = 1; @@ -1791,7 +1787,7 @@ FUNCTION void get_time_series() equ_Recr = Recr_virgin; bio_yr = y; Fishon = 0; - Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation with current year's biology + Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation with current year's biology Smry_Table(y, 11) = SSB_equil; Smry_Table(y, 13) = GenTime; if( SR_fxn == 10 ) @@ -1803,7 +1799,7 @@ FUNCTION void get_time_series() SR_parm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 } Fishon = 1; - Do_Equil_Calc(equ_Recr); // call function to do equilibrium calculation with current year's biology and F + Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation with current year's biology and F if (STD_Yr_Reverse_Ofish(y) > 0) { SPR_std(STD_Yr_Reverse_Ofish(y)) = SSB_equil / Smry_Table(y, 11); @@ -1834,6 +1830,7 @@ FUNCTION void get_time_series() //******************************************************************** /* SS_Label_FUNCTION 30 Do_Equil_Calc */ + // This function does per recruit calculations, so produces an age composition that is in equilibrium with M+F FUNCTION void Do_Equil_Calc(const prevariable& equ_Recr) { int t_base; diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index a4a8bbb5..8b1aea35 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1957,9 +1957,11 @@ // 3 option: do not update SSBpR0 (do keep start year SPR0), even if R0 or h is set to have time-varying property int SR_update_SSBpR0_bmark int SR_update_SSBpR0_timeseries + int bench_update_equil LOCAL_CALCS SR_update_SSBpR0_bmark = 0; SR_update_SSBpR0_timeseries = 0; + bench_update_equil = 0; echoinput< Date: Fri, 14 Mar 2025 11:42:52 -0700 Subject: [PATCH 28/58] add backward compat flag to starter --- SS_readstarter.tpl | 16 ++++++++++++++++ SS_write_ssnew.tpl | 1 + 2 files changed, 17 insertions(+) diff --git a/SS_readstarter.tpl b/SS_readstarter.tpl index c9b7724e..7406f6b8 100644 --- a/SS_readstarter.tpl +++ b/SS_readstarter.tpl @@ -705,6 +705,7 @@ int ender; int irand_seed; int irand_seed_rd; + int TV_bio_compat; // flag in 3.30.24 for impact of timevary biology on benchmark SRR calculations int F_std_multi; // for multi-year averaging of F_std int F_std_log; // for log(ratio) of F_std int F_std_basis; @@ -806,6 +807,21 @@ echoinput << "random number seed: " << irand_seed << endl; tempin = 0; } + + echoinput << "now read flag for dealing with impact of time-varying biology on benchmark SRR calculations" << endl; + *(ad_comm::global_datafile) >> tempin; + if (tempin == 3.30) // old format file that does not provide input + { + ender = 1; + TV_bio_compat = 0; + } + else // new input beginning 3.30.24 + { + TV_bio_compat = int(tempin); + echoinput << "Compatibility flag for legacy (0) vs improved (1) impact of timevary biology on benchmark SRR calcs: " << TV_bio_compat << endl; + tempin = 0; + } + if (ender == 0) { *(ad_comm::global_datafile) >> tempin; diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 0d4ad371..5e79c37a 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1564,6 +1564,7 @@ FUNCTION void write_nucontrol() NuStart << double(mcmc_output_detail) + MCMC_bump << " # MCMC output detail: integer part (0=default; 1=adds obj func components; 2= +write_report_for_each_mceval); and decimal part (added to SR_LN(R0) on first call to mcmc)" << endl; NuStart << ALK_tolerance << " # ALK tolerance ***disabled in code" << endl; NuStart << irand_seed_rd << " # random number seed for bootstrap data (-1 to use long(time) as seed): # " << irand_seed << endl; + NuStart << TV_bio_compat << " # Compatibility flag for legacy (0) vs improved (1) impact of timevary biology on benchmark SRR calcs >=3.30.24" << endl; NuStart << "3.30 # check value for end of file and for version control" << endl; NuStart.close(); From 5bcfa050b63fc76d398230b9ed1bec1d69447b34 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Thu, 20 Mar 2025 15:56:14 -0700 Subject: [PATCH 29/58] WIP - new approach not showing difference --- SS_benchfore.tpl | 146 ++++++++++++++++++++++++++++------------- SS_param.tpl | 2 +- SS_popdyn.tpl | 14 ++-- SS_readcontrol_330.tpl | 55 +--------------- SS_readstarter.tpl | 8 +-- SS_write_report.tpl | 7 +- SS_write_ssnew.tpl | 8 +-- 7 files changed, 124 insertions(+), 116 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 9e33d32c..81a2a327 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -646,7 +646,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: call make_fecundity for benchmarks // this means that any calculation of SSB in benchmark will use the updated fec - // but SSBpR0 will only use that updated fec if SR_update_SSBpR0_bmark == 1 if (s == spawn_seas) { { @@ -749,54 +748,107 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } } - Recr_unf = mfexp(SR_parm_work(1)); + /* + Early thoughts: + 1 # SR_update_SSBpR0 + # 1 - best: update SSBpR0 for benchmark and for time series only if SRparm R0 or h (not regime) is set to have time-varying property + # 2 - incorrect (old, incorrect SS3 approach): always update SSBpR0 for benchmark's use of spawner-recruitment, but only for the time series if there is a timevary SR parm + + Flags: + timevary_MG_firstyr == YrMax // means that no biology is time-varying + timevary_parm_start_SR > 0 // means that R0 or h (i.e. any except regime, sigmaR, autocorr) is time-varying, so SSBpR0 gets updated for time series and for bench + timevary_bio_4SRR is new user selected flag: 0 for legacy, vs 1 for improved use of timevary biology in SRR calcs + + Legacy approach: + SSBpR0 set at start year using start year biology + SSBpR0 updated during time series if there is time-varying R0, but does not call equil_spawn_recr_calc + SSBpR with benchmark biology used in benchmark calculations + SSBpR0 for benchmark always uses bench biology, which is incorrect + SSB_bench (aka SSB_unf) does not call equil_spawn_recr_calc, it is just R * SSBpR, so is incomplete accounting for effect of timevary bio + Btgttgt is a fraction of SSB_bench (no options) + Btgttgt2 can be fraction of SSB_MSY or fraction of SSB_virgin, but not SSB_bench + HCR inflection is a fraction of SSB_bench (no options) + depletion basis is user-selected as SSB_virgin or SSB_msy + SSB_msy uses equil_spawn_recr_calc in its creation, but SSB_bench does not. So they are inconsistent + none of the above is an issue if there is no timevarying biology + ------- + Improved approach + SSBpR0 set at start year using start year biology + SSBpR0 updated during time series if there is time-varying R0; PLUS NEW: equil_spawn_recr_calc called to get new equilibrium R0, SSB0 + SSBpR0 for benchmark stays at virgin unless timevary_bio_4SRR == 0, or if timevary_parm_start_SR > 0 + Btgttgt can now use either frac*SSB_bench or frac*SSB_virgin + Btgttgt2 can be fraction of SSB_MSY, of SSB_virgin, or of SSB_bench + HCR inflection adds option to use SSB_virgin or SSB_bench + depletion adds option to use SSB_bench + */ + Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used Fishon = 0; - Do_Equil_Calc(Recr_unf); // this calcs SSB as SSB_equil using benchmark biology - dvariable SPR_bench = SSB_equil / Recr_unf; // SSBpR using bench biology - - // SR_update_SSBpR0_rd values -// 1 best: update SSBpR0 for benchmark and for time series only if SRparm R0 or h (not regime) is set to have time-varying property -// 2 incorrect, relic: always update SSBpR0 for benchmark's use of spawner-recruitment (old, incorrect SS3 approach), but only for the time series if there is a timevary SR parm -// 3 option: do not update SSBpR0 (do keep start year SPR0), even if R0 or h is set to have time-varying property -// if(bench_update_equil == 0) // legacy approach that omits recalc of equilibrium R,SSB - { - SSB_unf = SSB_equil; - SSB0_4_SRR = SSB_equil; - R0_4_SRR = Recr_unf; - report5 << " only SPR: " << SSB_equil << " Recr: " << Recr_unf << " SPR: " << SSB0_4_SRR / R0_4_SRR << " bench SPR: " << SPR_bench << endl; - } -// else if (SR_update_SSBpR0_bmark == 0) // retain virgin SSBpR0 for SRR + Do_Equil_Calc(Recr_unf); // this returns SSB_equil using benchmark biology + dvariable SSBpR_bench = SSB_equil / Recr_unf; + + if( timevary_MG_firstyr == YrMax && WTage_rd == 0) // no time-varying biology { - // this is the correct approach. It uses the same SRR as the time series and calculates an new equilibrium point using benchmark SPR - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SPR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - R0_4_SRR = Equ_SpawnRecr_Result(2); - SSB0_4_SRR = Equ_SpawnRecr_Result(1); - Do_Equil_Calc(R0_4_SRR); // this calcs SSB as SSB_equil using benchmark biology - report5 << " use virgin SPR in SRR - SSB: " << SSB_virgin << " Recr: " << Recr_virgin << " SPR: " << SSB_virgin / Recr_virgin << " bench SPR: " << SPR_bench << " new equil: " << Equ_SpawnRecr_Result << " per_R_calc: " << SSB_equil << endl; + SSB0_4_SRR = SSB_virgin; + R0_4_SRR = Recr_virgin; + SSB_unf = SSB_equil; // should this also depend on timevary_parm_start_SR > 0??? } -// else // use benchmark biology (aka _unf) for SSBpR0 calcs [incorrect approach, unless there are time-varying R0 or h parameters] + else // there is some timevary biology, with any WTage_rd == 1 qualifying as timevarying without actually chacking for different values in diff years { - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_equil, Recr_unf, SPR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - R0_4_SRR = Equ_SpawnRecr_Result(2); - SSB0_4_SRR = Equ_SpawnRecr_Result(1); - Do_Equil_Calc(R0_4_SRR); // this calcs SSB as SSB_equil using benchmark biology - report5 << " use bench SPR in SRR - SSB: " << SSB_equil << " Recr: " << Recr_unf << " SPR: " << SSB0_4_SRR / R0_4_SRR << " bench SPR: " << SPR_bench << " new equil: " << Equ_SpawnRecr_Result << " per_R_calc: " << SSB_equil << endl; + if( timevary_bio_4SRR == 0) // legacy approach; this switch is read from starter.ss + { + warnstream << "There is timevary biology and the legacy approach to benchmark calculations is being used; user should be aware"; + write_message (WARN, 0); + if(timevary_parm_start_SR == 0) // no timevary SRR parms + { + SSB_unf = SSB_equil; + R0_4_SRR = Recr_unf; + SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR + // Equil_Spawn_Recr_Fxn will be called in more complete approach to use SSBpR_bench to move along the SRR + } + else // there are timevary SRR parms. Legacy code is same + { + SSB_unf = SSB_equil; + R0_4_SRR = Recr_unf; + SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR + SSBpR_bench = SSB0_4_SRR / R0_4_SRR; + } + report5 << " legacy: Recr: " << R0_4_SRR << " SSB: " << SSB0_4_SRR << " bench SPR: " << SSBpR_bench << endl; + } + + else // more complete approach to time vary biology will be used (introduced in 3.30.24) + { + if(timevary_parm_start_SR == 0) // no timevary SRR parms, so use SSB_virgin, Recr_virgin which will create virgin SSBpR0 + { + SSB0_4_SRR = SSB_virgin; + R0_4_SRR = Recr_virgin; + // get new equilibrium point using original SRR and SSBpR_bench + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + SSB_unf = Equ_SpawnRecr_Result(1); + Recr_unf = Equ_SpawnRecr_Result(2); + report5 << " use virgin SSBpR0 in SRR - SSB: " << SSB_virgin << " Recr: " << Recr_virgin << " SPR: " << SSB_virgin / Recr_virgin << " bench SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; + } + else // use benchmark quantities for SRR + { + // Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + } + Do_Equil_Calc(R0_4_SRR); // this calcs SSBpR and returns it as SSB_equil using benchmark biology + SSB_unf = SSB_equil; + report5 << " CHECK! - SSB_unf and updated equilibrium SSB0_4_SRR: " << SSB_unf << " " << SSB0_4_SRR << endl; + } } if (show_MSY == 1) { SR_parm_work(N_SRparm2 + 1) = SSB0_4_SRR; - Mgmt_quant(1) = SSB_equil; + Mgmt_quant(1) = SSB_unf; Mgmt_quant(2) = totbio; // this is calculated in Do_Equil_Calc Mgmt_quant(3) = smrybio; Mgmt_quant(4) = Recr_unf; report5 << "SR_parms for benchmark: " << SR_parm_work << endl - << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << endl << - "input_SR_update_SSBpR0_rd: " << SR_update_SSBpR0_rd << "; flag for updating SSBpR0_Bmark: " << SR_update_SSBpR0_bmark << endl; - SSB_equil = Equ_SpawnRecr_Result(1); - Mgmt_quant(19) = Equ_SpawnRecr_Result(2); // recruitment - Mgmt_quant(20) = SSB_equil; - Mgmt_quant(21) = SSB_equil; // placeholder to be replaced by SSB_HCR_infl + << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << endl; + Mgmt_quant(19) = R0_4_SRR; // recruitment + Mgmt_quant(20) = SSB_unf; + Mgmt_quant(21) = SSB_unf; // placeholder to be replaced by SSB_HCR_infl Mgmt_quant(22) = SSB_virgin; } @@ -1084,14 +1136,14 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { // ****************************************************** - if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations - {Btgttgt = BTGT_target * SSB_virgin;} + if (timevary_bio_4SRR == 0) + {Btgttgt = BTGT_target * SSB_unf;} // current SS3 approach else {Btgttgt = BTGT_target * SSB_unf;} if (show_MSY == 1) { report5 << "#" << endl; - if (SR_update_SSBpR0_bmark == 0) // use virgin biology for the spawner-recruitment R0,h calculations + if (timevary_bio_4SRR == 0) // use virgin biology for the spawner-recruitment R0,h calculations {report5 << "Find_target_SSB/Bzero; where Bzero is Virgin SSB:" << SSB_virgin << " where SSBpR_unf = " << SSBpR_virgin << endl;} else {report5 << "Find_target_SSB/Bzero; where Bzero is for Bmark biology and updated SPR0: " << SSB_unf << " where SSBpR_unf = " << SSBpR_virgin_4_SRR << endl;} @@ -1852,8 +1904,9 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { report5 << "#" << endl << "Management_report" << endl; - report5 << "Steepness_Recr_SSB_virgin(R0) " << SR_parm(2) << " " << Recr_virgin << " " << SSB_virgin << endl; - report5 << "Steepness_Recr_SSB_benchmark " << SR_parm_work(2) << " " << Recr_unf << " " << SSB_unf << endl; + report5 << "Virgin: Steepness_Recr_SSB " << SR_parm(2) << " " << Recr_virgin << " " << SSB_virgin << endl; + report5 << "Bench: Steepness_Recr_SSB " << SR_parm_work(2) << " " << R0_4_SRR << " " << SSB0_4_SRR << endl; + report5 << "unf : Steepness_Recr_SSB " << SR_parm_work(2) << " " << Recr_unf << " " << SSB_unf << endl; report5 << "#" << endl << "Summary_age: " << Smry_Age << endl; report5 << "#_Bmark_years: beg_bio, end_bio, beg_selex, end_selex, beg_relF, end_relF, beg_recr_dist, end_recr_dist, beg_SRparm, end_SRparm" << endl @@ -2636,7 +2689,7 @@ FUNCTION void Get_Forecast() } // SPAWN-RECR: get recruitment in forecast; needs to be area-specific // SR_fxn - if (SR_update_SSBpR0_timeseries == 0) // R0 is not time-varying + if (timevary_parm_start_SR == 0) // R0 is not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; @@ -2649,7 +2702,8 @@ FUNCTION void Get_Forecast() eq_yr = y; bio_yr = y; Do_Equil_Calc(R0_use); // call function to do per recruit calculation - if (fishery_on_off == 1) + // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R + if (fishery_on_off == 1) { Fishon = 1; } @@ -2660,6 +2714,7 @@ FUNCTION void Get_Forecast() SSB_use = SSB_equil; } Recruits = Spawn_Recr(SSB_use, R0_use, SSB_current); // calls to function Spawn_Recr + warning << y << " SSB0: " << SSB_use << " R0: " << R0_use << " SSB_curr: " << SSB_current << " R: " << Recruits << endl; if (SR_fxn != 7) apply_recdev(Recruits, R0_use); // apply recruitment deviation if (Fcast_Loop1 < Fcast_Loop_Control(2)) // use expected recruitment this should include environ effect - CHECK THIS { @@ -3275,7 +3330,7 @@ FUNCTION void Get_Forecast() // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_fxn - if (SR_update_SSBpR0_timeseries == 0) // R0 is not time-varying + if (timevary_parm_start_SR == 0) // R0 is not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; @@ -3288,7 +3343,8 @@ FUNCTION void Get_Forecast() eq_yr = y; bio_yr = y; Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation - if (fishery_on_off == 1) + // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R + if (fishery_on_off == 1) { Fishon = 1; } diff --git a/SS_param.tpl b/SS_param.tpl index d174efc7..e8d532c5 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -247,7 +247,7 @@ PARAMETER_SECTION number SSB_unf // SSB unfished, based on benchmark biology number Recr_unf number SSB_use - number R0_use; // annually updated value if SR_update_SSBpR0_timeseries == 1 + number R0_use number SSB_deplete // SSB that will be used as denominator for depletion calculations and as basis for control rule inflection number SSB_current; // Spawning biomass diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 752cc348..e58d4627 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -382,10 +382,10 @@ FUNCTION void get_initial_conditions() if(Do_Benchmark==0) // assign values that would be created in benchmark section { SSB_unf = SSB_virgin; - Mgmt_quant(1) = SSB_unf; // can be overwritten in benchmark by updated SSB_unf - Recr_unf = Recr_virgin; - Mgmt_quant(2) = totbio; // from equil calcs - Mgmt_quant(3) = smrybio; // from equil calcs + Mgmt_quant(1) = SSB_unf; // will be overwritten in benchmark + Recr_unf = Recr_virgin; // will be overwritten in benchmark + Mgmt_quant(2) = totbio; // from Do_Equil_Calc + Mgmt_quant(3) = smrybio; // from Do_Equil_Calc Mgmt_quant(4) = Recr_virgin; } Smry_Table(styr - 2, 1) = totbio; // from equil calcs @@ -1024,7 +1024,7 @@ FUNCTION void get_time_series() // SS_Label_Info_24.2.3 #Get the total recruitment produced by this spawning biomass at the beginning of the season // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_Fxn relevant keyword - if (SR_update_SSBpR0_timeseries == 0) // SRparm are not time-varying + if (timevary_parm_start_SR == 0) // SRparm are not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; @@ -1038,6 +1038,7 @@ FUNCTION void get_time_series() bio_yr = y; Do_Equil_Calc(R0_use); // call function to do per recruit calculation with current year's biology and adjusted R0 SSB_use = SSB_equil; + // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R if (fishery_on_off == 1) { Fishon = 1; @@ -1484,7 +1485,7 @@ FUNCTION void get_time_series() // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass at some time during the season // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_fxn - if (SR_update_SSBpR0_timeseries == 0) // SR parms are not time-varying + if (timevary_parm_start_SR == 0) // SR parms are not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; @@ -1497,6 +1498,7 @@ FUNCTION void get_time_series() bio_yr = y; Do_Equil_Calc(R0_use); // call function to do per recruit calculation SSB_use = SSB_equil; + // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R if (fishery_on_off == 1) { Fishon = 1; diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 8b1aea35..f49d1c2c 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1950,20 +1950,7 @@ !!echoinput< 0 || SR_parm_timevary(4) > 0) ) {SR_update_parm = 1;} // alpha or beta is time-varying - else if ((SR_parm_timevary(1) > 0 || SR_parm_timevary(2) > 0) ) {SR_update_parm = 1;} // R0 or steepness is time-varying } } + N_SRparm3 = N_SRparm2; if (timevary_parm_start_SR > 0) { @@ -2164,38 +2147,6 @@ echoinput << " SR timevary_parm_cnt start and end " << timevary_parm_start_SR << " " << timevary_parm_cnt_SR << endl; echoinput << "link to timevary parms: " << SR_parm_timevary << endl; } - -// SR_update_SSBpR0_rd values -// 1 best: update SSBpR0 for benchmark and for time series only if SRparm R0 or h (not regime) is set to have time-varying property -// 2 incorrect, relic: always update SSBpR0 for benchmark's use of spawner-recruitment (old, incorrect SS3 approach), but only for the time series if there is a timevary SR parm -// 3 option: do not update SSBpR0 (do keep start year SPR0), even if R0 or h is set to have time-varying property - - switch (SR_update_SSBpR0_rd) - { - case 0: - if(timevary_MG_firstyr < YrMax) // timevary biology exists and SR_update not set - { - warnstream << "user must select 1, 2, or 3 for updating SPR0 flag (formerly labelled future feature in SR input) because there is time-varying biology"; - write_message (FATAL, 0); // EXIT! - } - break; - case 1: - SR_update_SSBpR0_bmark = 1 * SR_update_parm; // but conditional on SRparm_timevary, so update value there - SR_update_SSBpR0_timeseries = 1 * SR_update_parm; - bench_update_equil = 1; - break; - case 2: - SR_update_SSBpR0_bmark = 1; - SR_update_SSBpR0_timeseries = 0; - bench_update_equil = 0; - break; - case 3: - SR_update_SSBpR0_bmark = 0; - SR_update_SSBpR0_timeseries = 0; - bench_update_equil = 1; - break; - } - echoinput << "SRupdate " << SR_update_parm << " use " << SR_update_SSBpR0_bmark << " rd " << SR_update_SSBpR0_rd<< endl; echoinput << "SR_Npar and N_SRparm2 and N_SRparm3: " << N_SRparm(SR_fxn) << " " << N_SRparm2 << " " << N_SRparm3 << endl; // clang-format off END_CALCS diff --git a/SS_readstarter.tpl b/SS_readstarter.tpl index 7406f6b8..eb978211 100644 --- a/SS_readstarter.tpl +++ b/SS_readstarter.tpl @@ -705,7 +705,7 @@ int ender; int irand_seed; int irand_seed_rd; - int TV_bio_compat; // flag in 3.30.24 for impact of timevary biology on benchmark SRR calculations + int timevary_bio_4SRR; // flag in 3.30.24 for impact of timevary biology on benchmark SRR calculations int F_std_multi; // for multi-year averaging of F_std int F_std_log; // for log(ratio) of F_std int F_std_basis; @@ -813,12 +813,12 @@ if (tempin == 3.30) // old format file that does not provide input { ender = 1; - TV_bio_compat = 0; + timevary_bio_4SRR = 0; } else // new input beginning 3.30.24 { - TV_bio_compat = int(tempin); - echoinput << "Compatibility flag for legacy (0) vs improved (1) impact of timevary biology on benchmark SRR calcs: " << TV_bio_compat << endl; + timevary_bio_4SRR = int(tempin); + echoinput << "Compatibility flag for legacy (0) vs improved (1) impact of timevary biology on benchmark SRR calcs: " << timevary_bio_4SRR << endl; tempin = 0; } diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 2eae335a..a30f85ca 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -4747,7 +4747,8 @@ FUNCTION void SPR_profile() SS2out << " stored - SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_virgin << " " << SSBpR_virgin_4_SRR<=3.30.24" << endl; + NuStart << timevary_bio_4SRR << " # Compatibility flag for legacy (0) vs improved (1) impact of timevary biology on benchmark SRR calcs >=3.30.24" << endl; NuStart << "3.30 # check value for end of file and for version control" << endl; NuStart.close(); @@ -2138,11 +2138,7 @@ FUNCTION void write_nucontrol() report4 << "#" << endl; report4 << SR_fxn << " #_Spawner-Recruitment; Options: 1=NA; 2=Ricker; 3=std_B-H; 4=SCAA; 5=Hockey; 6=B-H_flattop; 7=survival_3Parm; 8=Shepherd_3Parm; 9=RickerPower_3parm" << endl; report4 << init_equ_steepness << " # 0/1 to use steepness in initial equ recruitment calculation" << endl; - report4 << SR_update_SSBpR0_rd << " # SR_update_SSBpR0" << endl << - "# 0 - OK, but only if no timevary biology or SR parm" << endl << - "# 1 - best: update SSBpR0 for benchmark and for time series only if SRparm R0 or h (not regime) is set to have time-varying property" << endl << - "# 2 - incorrect (old, incorrect SS3 approach): always update SSBpR0 for benchmark's use of spawner-recruitment, but only for the time series if there is a timevary SR parm" << endl << - "# 3 - option: do not update SSBpR0 (do keep start year SSBpR0), even if R0 or h is set to have time-varying property" << endl << "#" << endl; + report4 << " 0 # not_used" << endl; report4 << "#_ LO HI INIT PRIOR PR_SD PR_type PHASE env-var use_dev dev_mnyr dev_mxyr dev_PH Block Blk_Fxn # parm_name" << endl; report4.unsetf(std::ios_base::fixed); report4.unsetf(std::ios_base::floatfield); From 013a176bbe246c43cef0d12d1bfa1a641bea11cb Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 21 Mar 2025 16:03:00 -0700 Subject: [PATCH 30/58] by jove, I think he did it --- SS_benchfore.tpl | 17 ++++++++--------- SS_objfunc.tpl | 11 +++++++++++ SS_readcontrol_330.tpl | 8 ++++---- SS_write_report.tpl | 25 ------------------------- 4 files changed, 23 insertions(+), 38 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 81a2a327..3a61921d 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -801,8 +801,9 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if(timevary_parm_start_SR == 0) // no timevary SRR parms { SSB_unf = SSB_equil; - R0_4_SRR = Recr_unf; + R0_4_SRR = Recr_unf; // same as Recr_virgin because no timevary SRparms SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR + SSBpR_bench = SSB0_4_SRR / R0_4_SRR; // Equil_Spawn_Recr_Fxn will be called in more complete approach to use SSBpR_bench to move along the SRR } else // there are timevary SRR parms. Legacy code is same @@ -831,7 +832,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { // Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR } - Do_Equil_Calc(R0_4_SRR); // this calcs SSBpR and returns it as SSB_equil using benchmark biology + Do_Equil_Calc(Recr_unf); // this calcs SSBpR and returns it as SSB_equil using benchmark biology and the updated equil Recr SSB_unf = SSB_equil; report5 << " CHECK! - SSB_unf and updated equilibrium SSB0_4_SRR: " << SSB_unf << " " << SSB0_4_SRR << endl; } @@ -846,9 +847,9 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Mgmt_quant(4) = Recr_unf; report5 << "SR_parms for benchmark: " << SR_parm_work << endl << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << endl; - Mgmt_quant(19) = R0_4_SRR; // recruitment - Mgmt_quant(20) = SSB_unf; - Mgmt_quant(21) = SSB_unf; // placeholder to be replaced by SSB_HCR_infl + Mgmt_quant(19) = SSB_unf; // placeholder for depletion denominator + Mgmt_quant(20) = SSB_unf; // placeholder to be replaced by SSB_HCR_infl + Mgmt_quant(21) = SSB_unf; Mgmt_quant(22) = SSB_virgin; } @@ -2259,7 +2260,7 @@ FUNCTION void Get_Forecast() H4010_top = H4010_top_rd; } - Mgmt_quant(21) = H4010_top * HCR_anchor; + Mgmt_quant(20) = HCR_anchor; report5 << "#" << endl; report5 << "N_forecast_yrs: " << N_Fcast_Yrs << endl; report5 << "OY_Control_Rule: Inflection: " << H4010_top << " Intercept: " << H4010_bot << " Scale: " << H4010_scale_vec(endyr + 1) << endl @@ -2714,7 +2715,6 @@ FUNCTION void Get_Forecast() SSB_use = SSB_equil; } Recruits = Spawn_Recr(SSB_use, R0_use, SSB_current); // calls to function Spawn_Recr - warning << y << " SSB0: " << SSB_use << " R0: " << R0_use << " SSB_curr: " << SSB_current << " R: " << Recruits << endl; if (SR_fxn != 7) apply_recdev(Recruits, R0_use); // apply recruitment deviation if (Fcast_Loop1 < Fcast_Loop_Control(2)) // use expected recruitment this should include environ effect - CHECK THIS { @@ -3779,9 +3779,8 @@ FUNCTION void Get_Forecast() } Fishon = 1; Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation -// warning < 0) - SPR_std(STD_Yr_Reverse_Ofish(y)) = SSB_equil / Smry_Table(y, 11); + {SPR_std(STD_Yr_Reverse_Ofish(y)) = SSB_equil / Smry_Table(y, 11);} Smry_Table(y, 9) = totbio; Smry_Table(y, 10) = smrybio; Smry_Table(y, 12) = SSB_equil; diff --git a/SS_objfunc.tpl b/SS_objfunc.tpl index 82b91498..474153ee 100644 --- a/SS_objfunc.tpl +++ b/SS_objfunc.tpl @@ -1187,21 +1187,25 @@ FUNCTION void Process_STDquant() case 1: { depletion /= (depletion_level * SSB_virgin); + Mgmt_quant(19) = SSB_virgin; break; } case 2: { depletion /= (depletion_level * Bmsy); + Mgmt_quant(19) = Bmsy; break; } case 3: { depletion /= (depletion_level * SSB_yr(styr)); + Mgmt_quant(19) = SSB_yr(styr); break; } case 4: { depletion /= (depletion_level * SSB_yr(endyr)); + Mgmt_quant(19) = SSB_yr(endyr); break; } case 5: // dynamic Bzero @@ -1213,6 +1217,13 @@ FUNCTION void Process_STDquant() depletion(STD_Yr_Reverse_Dep(y)) /= ( depletion_level * Extra_Std(Do_Dyn_Bzero + y - (styr - 2))); // warning< Date: Wed, 26 Mar 2025 16:25:56 -0700 Subject: [PATCH 31/58] align depletion_basis and Btarget and HCR anchor --- SS_benchfore.tpl | 60 +++++++++++++++++++++++++++--------------- SS_param.tpl | 1 - SS_popdyn.tpl | 4 +-- SS_readcontrol_330.tpl | 5 ++++ SS_readdata_330.tpl | 20 +++++++++++--- SS_readstarter.tpl | 2 +- SS_recruit.tpl | 2 +- SS_write_report.tpl | 14 +++++----- SS_write_ssnew.tpl | 9 ++++--- 9 files changed, 76 insertions(+), 41 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 3a61921d..a851db30 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -10,7 +10,7 @@ // SPR refers to spawner potential ratio which is the ratio of SSBpR at some level of F to SSBpR with F = 0 // SSBpR_virgin is calculated in popdyn using the start year biology -// SSBpR_virgin_4_SRR used to get alpha in equil_spawn_recr B-H +// SSBpR_virgin used to get alpha in equil_spawn_recr B-H FUNCTION void setup_Benchmark() // and forecast { @@ -776,7 +776,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSBpR0 set at start year using start year biology SSBpR0 updated during time series if there is time-varying R0; PLUS NEW: equil_spawn_recr_calc called to get new equilibrium R0, SSB0 SSBpR0 for benchmark stays at virgin unless timevary_bio_4SRR == 0, or if timevary_parm_start_SR > 0 - Btgttgt can now use either frac*SSB_bench or frac*SSB_virgin + Btgttgt can now use either frac*SSB_bench or frac*SSB_virgin by using the existing flag for depletion basis Btgttgt2 can be fraction of SSB_MSY, of SSB_virgin, or of SSB_bench HCR inflection adds option to use SSB_virgin or SSB_bench depletion adds option to use SSB_bench @@ -792,7 +792,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) R0_4_SRR = Recr_virgin; SSB_unf = SSB_equil; // should this also depend on timevary_parm_start_SR > 0??? } - else // there is some timevary biology, with any WTage_rd == 1 qualifying as timevarying without actually chacking for different values in diff years + else // there is some timevary biology (with any WTage_rd == 1 qualifying as timevarying without actually chacking for different values in diff years) { if( timevary_bio_4SRR == 0) // legacy approach; this switch is read from starter.ss { @@ -806,8 +806,11 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSBpR_bench = SSB0_4_SRR / R0_4_SRR; // Equil_Spawn_Recr_Fxn will be called in more complete approach to use SSBpR_bench to move along the SRR } - else // there are timevary SRR parms. Legacy code is same + else // there are timevary SRR parms, so use benchmark biology to create a whole new SRR { + Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used + // steepness and other SR parms will also come from SR_parm_work + Do_Equil_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSB_unf = SSB_equil; R0_4_SRR = Recr_unf; SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR @@ -818,7 +821,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) else // more complete approach to time vary biology will be used (introduced in 3.30.24) { - if(timevary_parm_start_SR == 0) // no timevary SRR parms, so use SSB_virgin, Recr_virgin which will create virgin SSBpR0 + if(timevary_parm_start_SR == 0) // no timevary SRR parms, so SRR will use SSB_virgin, Recr_virgin to internally create virgin SSBpR0 { SSB0_4_SRR = SSB_virgin; R0_4_SRR = Recr_virgin; @@ -826,15 +829,25 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR SSB_unf = Equ_SpawnRecr_Result(1); Recr_unf = Equ_SpawnRecr_Result(2); - report5 << " use virgin SSBpR0 in SRR - SSB: " << SSB_virgin << " Recr: " << Recr_virgin << " SPR: " << SSB_virgin / Recr_virgin << " bench SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; + if (show_MSY == 1) report5 << " use virgin SSBpR0 in SRR - SSB: " << SSB_virgin << " Recr: " << Recr_virgin << " SPR: " << SSB_virgin / Recr_virgin << " bench SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; } - else // use benchmark quantities for SRR + else // use benchmark quantities for SRR, so everything can change { - // Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + // get new equilibrium point for the benchmark SRR + Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used + Fishon = 0; + Do_Equil_Calc(Recr_unf); // this returns SSB_equil using benchmark biology + SSBpR_bench = SSB_equil / Recr_unf; + SSB0_4_SRR = SSB_equil; + SSB_unf = SSB_equil; + R0_4_SRR = Recr_unf; + // verify + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + if (show_MSY == 1) report5 << " use bench SSBpR0 in SRR - SSB: " << SSB_unf << " Recr: " << Recr_unf << " SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; } Do_Equil_Calc(Recr_unf); // this calcs SSBpR and returns it as SSB_equil using benchmark biology and the updated equil Recr SSB_unf = SSB_equil; - report5 << " CHECK! - SSB_unf and updated equilibrium SSB0_4_SRR: " << SSB_unf << " " << SSB0_4_SRR << endl; + if (show_MSY == 1) report5 << " CHECK! - SSB_unf based on updated SRR (if any): " << SSB_unf << endl; } } @@ -1137,17 +1150,18 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { // ****************************************************** - if (timevary_bio_4SRR == 0) - {Btgttgt = BTGT_target * SSB_unf;} // current SS3 approach + if (depletion_basis == 1) + {Btgttgt = BTGT_target * SSB_virgin;} else - {Btgttgt = BTGT_target * SSB_unf;} - if (show_MSY == 1) + {Btgttgt = BTGT_target * SSB_unf;} // current SS3 approach uses benchmark biology + + if (show_MSY == 1) { report5 << "#" << endl; - if (timevary_bio_4SRR == 0) // use virgin biology for the spawner-recruitment R0,h calculations - {report5 << "Find_target_SSB/Bzero; where Bzero is Virgin SSB:" << SSB_virgin << " where SSBpR_unf = " << SSBpR_virgin << endl;} + if (depletion_basis == 1) + {report5 << "Find_target_SSB as fraction: " << BTGT_target << " of Virgin SSB:" << SSB_virgin << endl;} else - {report5 << "Find_target_SSB/Bzero; where Bzero is for Bmark biology and updated SPR0: " << SSB_unf << " where SSBpR_unf = " << SSBpR_virgin_4_SRR << endl;} + {report5 << "Find_target_SSB as fraction: " << BTGT_target << " of SSB_unf: "<< SSB_unf << endl;} report5 << "Iter Fmult ann_F SPR Catch SSB Recruits SSB/Bzero Tot_catch"; for (p = 1; p <= pop; p++) @@ -1252,7 +1266,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << " " << SSB_equil_pop_gp(p, gp) * Equ_SpawnRecr_Result(2); } report5 << endl; -// " SSB_unf " << SSB_unf << " recr " < 0.25) { warnstream << "control rule cutoff is large (" << H4010_bot << "); so may not be < calculated Bmsy/SSB_unf (" << H4010_top << ")"; diff --git a/SS_param.tpl b/SS_param.tpl index e8d532c5..3f850ebf 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -168,7 +168,6 @@ PARAMETER_SECTION number SSBpR_virgin; number SSB0_4_SRR; number R0_4_SRR; - number SSBpR_virgin_4_SRR; // value of SSB/R used in SRR number regime_change; number rho; number dirichlet_Parm; diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index e58d4627..d27225db 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -356,11 +356,11 @@ FUNCTION void get_initial_conditions() beta = mfexp(SR_parm(4)); steepness = alpha * SSBpR_virgin / (4. + alpha * SSBpR_virgin); Recr_virgin = 1. / beta * (alpha - (1. / SSBpR_virgin)); -// warning << " before AB_calcs " << "parm " << SR_parm(1) << " calc " << log(Recr_virgin) << endl; SR_parm(1) = log(Recr_virgin); SR_parm(2) = steepness; } - else { + else + { Recr_virgin = mfexp(SR_parm(1)); } diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index ced24029..26936674 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -6955,6 +6955,11 @@ depletion_basis_label += " " + onenum + "%*Dyn_Bzero"; break; } + case 6: + { + depletion_basis_label += " " + onenum + "%*Bmark_Biomass"; + break; + } } if (depletion_log == 1) depletion_basis_label += ";log"; if (depletion_multi > 1) diff --git a/SS_readdata_330.tpl b/SS_readdata_330.tpl index 96658403..901d92d6 100644 --- a/SS_readdata_330.tpl +++ b/SS_readdata_330.tpl @@ -4345,7 +4345,19 @@ "even when the base is set to the mean of earlier recruitments" << endl; } - echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=unfished_benchmark_SSB(old_approach), 2=virgin_SSB " << endl; + if (Fcast_Loop_Control(5) == 0) // default before 3.30.24 + { + echoinput << "basis for HCR anchor was not set; setting to 2 to match default before 3.30.24" << endl; + warnstream << "basis for HCR anchor was not set; setting to 2 to match default before 3.30.24"; + write_message(ADJUST, 0); + Fcast_Loop_Control(5) = 2; + } + echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=virgin_SSB; 2=unfished_benchmark_SSB(old_approach)" << endl; + if (depletion_basis == 1 && Fcast_Loop_Control(5) == 2) + { + warnstream << "depletion_basis is using virgin but HCR anchor is using SSB_unf from benchmark. Are you sure?"; + write_message(WARN, 0); + } echoinput << "#next enter year in which Fcast loop 3 caps and allocations begin to be applied" << endl; *(ad_comm::global_datafile) >> Fcast_Cap_FirstYear; @@ -4814,16 +4826,16 @@ warnstream << "Set F_std_basis=0 because no benchmark or forecast"; write_message(WARN, 0); } - if (depletion_basis == 2) + if (depletion_basis == 2 || depletion_basis == 6 ) { depletion_basis = 1; - warnstream << "Change depletion basis to 1 because benchmarks are off"; + warnstream << "Change depletion basis to 1 because benchmarks were not requested"; write_message(WARN, 0); } if (SPR_reporting >= 1 && SPR_reporting <= 3) { SPR_reporting = 4; - warnstream << "Change SPR_reporting to 4 because benchmarks are off"; + warnstream << "Change SPR_reporting to 4 because benchmarks were not requested"; write_message(WARN, 0); } } diff --git a/SS_readstarter.tpl b/SS_readstarter.tpl index eb978211..e2ab712f 100644 --- a/SS_readstarter.tpl +++ b/SS_readstarter.tpl @@ -643,7 +643,7 @@ int depletion_basis; int depletion_multi; int depletion_log; - init_number depletion_basis_rd; // 0=skip; 1=B0; 2=Bmsy; 3=B_styr; 4=B_endyr; 5=dynamic_Bzero; values >=11 invoke multiyr with 10's digit; append .1 to invoke log(ratio) with hundreds digit + init_number depletion_basis_rd; // 0=skip; 1=B0; 2=Bmsy; 3=B_styr; 4=B_endyr; 5=dynamic_Bzero; 6=Bmark_SSB_unf; values >=11 invoke multiyr with 10's digit; append .1 to invoke log(ratio) with hundreds digit LOCAL_CALCS // clang-format on echoinput << depletion_basis_rd << " depletion_basis as read; this is also known as Bratio and is a std quantity; has multi-yr and log(ratio) options" << endl; diff --git a/SS_recruit.tpl b/SS_recruit.tpl index cd938550..2fb0b3c4 100644 --- a/SS_recruit.tpl +++ b/SS_recruit.tpl @@ -284,7 +284,7 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, dvariable SRZ_surv; dvariable SSBpR_virgin_use; - SSBpR_virgin_use = SSB_virgin_use / Recr_virgin_use; // local instance of SSBpR_virgin_4_SRR + SSBpR_virgin_use = SSB_virgin_use / Recr_virgin_use; steepness = SRparm(2); // common usage but some different // SS_Label_44.1 calc equilibrium SpawnBio and Recruitment from input SSBpR_current, which is spawning biomass per recruit at some given F level switch (SR_fxn) diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 212f5ed1..7a9688e5 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -1845,8 +1845,8 @@ FUNCTION void write_bigoutput() SS2out << j << " " << ParmLabel(firstSRparm + j) << " " << SR_parm(j) << " " << SR_parm_PH(j); if (SR_parm_timevary(j) > 0 && j <= 4 ) // timevary SRparm exists {SS2out << " #_is_time_vary,_so_SRR_updates_base_SPR_annually";} - if (j == (N_SRparm2 - 1) && SR_parm_timevary(j) > 0) // timevary regime exists - {SS2out << " #_Regime_parameter_used_to_offset_from_SRR";} + if (j == (N_SRparm2 - 1) && SR_parm_timevary(j) > 0) // timevary regime exists + {SS2out << " #_Regime_parameter_used_to_offset_from_SRR";} SS2out << endl; } @@ -1858,7 +1858,7 @@ FUNCTION void write_bigoutput() { case 3: // Beverton-Holt with steepness { - alpha = 4.0 * steepness / (SSBpR_virgin_4_SRR * (1. - steepness)); + alpha = 4.0 * steepness / (SSBpR_virgin * (1. - steepness)); beta = (5.0 * steepness - 1.0) / ((1. - steepness) * SSB_virgin); SS2out << "Ln(R0): " << SR_parm(1) << endl << "R0: " << mfexp(SR_parm(1)) << endl; SS2out << "steepness: " << steepness << endl; @@ -1870,8 +1870,8 @@ FUNCTION void write_bigoutput() { SS2out << "Ln(alpha): " << SR_parm(3) << " alpha " << mfexp(SR_parm(3)) << endl; SS2out << "Ln(beta): " << SR_parm(4) << " beta " << mfexp(SR_parm(4)) << endl; - SS2out << "ln(R0)_derived: " << log( 1. / beta * (alpha - (1. / SSBpR_virgin_4_SRR))) << endl; // virgin R0 - SS2out << "steepness_derived: " << alpha * SSBpR_virgin_4_SRR / (4. + alpha * SSBpR_virgin_4_SRR) << endl; // steepness virgin + SS2out << "ln(R0)_derived: " << log( 1. / beta * (alpha - (1. / SSBpR_virgin))) << endl; // virgin R0 + SS2out << "steepness_derived: " << alpha * SSBpR_virgin / (4. + alpha * SSBpR_virgin) << endl; // steepness virgin break; } case 8: @@ -4744,7 +4744,7 @@ FUNCTION void SPR_profile() fec = Wt_Age_t(t, -2); SS2out << " repro_output for spr/ypr: " << fec(1) << endl;} } - SS2out << " stored - SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_virgin << " " << SSBpR_virgin_4_SRR<=11 invoke N multiyr with 10s & 100s digit; append .1 to invoke log(ratio); e.g. 122.1 produces log(12 yr trailing average of B/Bmsy)" << endl; + NuStart << depletion_basis_rd << " # Depletion basis: denom is: 0=skip; 1=X*SSBvirgin; 2=X*SSBmsy; 3=X*SSB_styr; 4=X*SSB_endyr; 5=X*dyn_Bzero; 6=X*Bmark_SSB_unf; values>=11 invoke N multiyr with 10s & 100s digit; append .1 to invoke log(ratio); e.g. 122.1 produces log(12 yr trailing average of B/Bmsy)" << endl; + NuStart << "# If value = 1, then Btarget in benchmark will be a fraction of SSB_virgin, else will be a fraction of SSB_benchmark" << endl; NuStart << depletion_level << " # Fraction (X) for Depletion denominator (e.g. 0.4)" << endl; NuStart << SPR_reporting << " # SPR_report_basis: 0=skip; 1=(1-SPR)/(1-SPR_tgt); 2=(1-SPR)/(1-SPR_MSY); 3=(1-SPR)/(1-SPR_Btarget); 4=rawSPR" << endl; NuStart << F_reporting << " # F_std_reporting_units: 0=skip; 1=exploitation(Bio); 2=exploitation(Num); 3=sum(Apical_F's); 4=mean F for range of ages (numbers weighted); 5=unweighted mean F for range of ages" << endl; @@ -1592,7 +1593,7 @@ FUNCTION void write_nucontrol() } NuFore << SPR_target << " # SPR target (e.g. 0.40)" << endl; - NuFore << BTGT_target << " # Biomass target (e.g. 0.40)" << endl; + NuFore << BTGT_target << " # Biomass target (e.g. 0.40) as fraction of SSB_virgin if depletion basis = 1, else as fraction of SSB_unfished in benchmark" << endl; if (Do_Benchmark == 3) NuFore << Blim_frac << " # COND: Do_Benchmark==3; Blimit as fraction of Bmsy (neg value to use as frac of Bzero) (e.g. 0.50)" << endl; NuFore << "#_Bmark_years: beg_bio, end_bio, beg_selex, end_selex, beg_relF, end_relF, beg_recr_dist, end_recr_dist, beg_SRparm, end_SRparm (enter actual year, or values of 0 or -integer to be rel. endyr)" << endl @@ -1645,7 +1646,7 @@ FUNCTION void write_nucontrol() NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of Bzero, e.g. 0.40); must be > control rule cutoff, or set to -1 to use Bmsy as the inflection " << endl; NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of Bzero, e.g. 0.10) " << endl; NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar] with filling from year to YrMax " << endl; - NuFore << "# Also see HCR_anchor below" << endl; + NuFore << "# Also see HCR_anchor below to use virgin vs benchmark SSB as basis" << endl; if (H4010_scale_rd < 0) { j = H4010_scale_vec_rd.size() - 1; @@ -1667,7 +1668,7 @@ FUNCTION void write_nucontrol() { NuFore << Fcast_Loop_Control(4) << " # multiplier on base recruitment " << endl; } - NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 1 uses unfished benchmark SSB (old hardwired approach), 2 = virgin SSB" << endl << "#" << endl; + NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 2 uses unfished benchmark SSB (old hardwired approach); 1 = virgin SSB" << endl << "#" << endl; NuFore << Fcast_Cap_FirstYear << " # FirstYear for caps and allocations (should be after years with fixed inputs) " << endl; From 1b251cded4675baf6c42f6f7c72967e2a00083c6 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Thu, 27 Mar 2025 11:42:31 -0700 Subject: [PATCH 32/58] rename Do_Equil_Calc; remove erroneous application of regime in initial_equil --- SS_benchfore.tpl | 34 +++++++++++++++++----------------- SS_popdyn.tpl | 30 +++++++++++++++--------------- SS_write_report.tpl | 6 +++--- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index a851db30..933beacd 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -783,7 +783,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) */ Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used Fishon = 0; - Do_Equil_Calc(Recr_unf); // this returns SSB_equil using benchmark biology + SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology dvariable SSBpR_bench = SSB_equil / Recr_unf; if( timevary_MG_firstyr == YrMax && WTage_rd == 0) // no time-varying biology @@ -810,7 +810,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used // steepness and other SR parms will also come from SR_parm_work - Do_Equil_Calc(Recr_unf); // this returns SSB_equil using benchmark biology + SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSB_unf = SSB_equil; R0_4_SRR = Recr_unf; SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR @@ -836,7 +836,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // get new equilibrium point for the benchmark SRR Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used Fishon = 0; - Do_Equil_Calc(Recr_unf); // this returns SSB_equil using benchmark biology + SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSBpR_bench = SSB_equil / Recr_unf; SSB0_4_SRR = SSB_equil; SSB_unf = SSB_equil; @@ -845,7 +845,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR if (show_MSY == 1) report5 << " use bench SSBpR0 in SRR - SSB: " << SSB_unf << " Recr: " << Recr_unf << " SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; } - Do_Equil_Calc(Recr_unf); // this calcs SSBpR and returns it as SSB_equil using benchmark biology and the updated equil Recr + SSBpR_Calc(Recr_unf); // this calcs SSBpR and returns it as SSB_equil using benchmark biology and the updated equil Recr SSB_unf = SSB_equil; if (show_MSY == 1) report5 << " CHECK! - SSB_unf based on updated SRR (if any): " << SSB_unf << endl; } @@ -893,7 +893,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) dvariable SPR_target100; SPR_target100 = SPR_target * 100.; - Do_Equil_Calc(equ_Recr); // where equ_Recr has been set to 1.0 + SSBpR_Calc(equ_Recr); // where equ_Recr has been set to 1.0 SSBpR_unf = SSB_equil / equ_Recr; // this corresponds to the biology for benchmark average years, not the virgin SSB_virgin Vbio1_unfished = smrybio; // gets value from equil_calc if (show_MSY == 1) @@ -939,7 +939,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } Fishon = 1; - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); yld1(ii) = 100. * SSB_equil / SSBpR_unf; // spawning potential ratio } SPR_actual = yld1(1); // spawning potential ratio @@ -1051,7 +1051,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } // else Hrate for bycatch fleets already set } - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); F01_origin = YPR_opt / Fmult; BTGT_target = 0.1; // now relative to Bmark @@ -1083,7 +1083,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } } // else Hrate for bycatch fleets set above } - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); yld1(ii) = YPR_opt; } @@ -1222,7 +1222,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } // else Hrate for bycatch fleets already set } - Do_Equil_Calc(equ_Recr); // where equ_Recr=1.0, so returned SSB_equil is in units of SSB/R, + SSBpR_Calc(equ_Recr); // where equ_Recr=1.0, so returned SSB_equil is in units of SSB/R, SSBpR_temp = SSB_equil; SPR_Btgt = SSBpR_temp / SSBpR_unf; // where SSBpR_unf = SSB_unf / Recr_unf so units of SSB/R; so result is SPR_Btgt = (fished SSB/R) / (unfished SSB/R) // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific @@ -1442,7 +1442,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // else Hrate for bycatch fleets already set } - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SSBpR_unf; SSBpR_temp = SSB_equil; @@ -1536,7 +1536,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } } // else Hrate for bycatch fleets set above } - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SSBpR_unf; SSBpR_temp = SSB_equil; @@ -1687,7 +1687,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } Fishon = 0; - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); report5 << "Equil_N_at_age_M_only_Recr_MSY" << endl << "Seas Area GP Sex subM" << age_vector << endl; for (s = 1; s <= nseas; s++) @@ -1837,7 +1837,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } // else Hrate for bycatch fleets already set } - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); SPR_Btgt2 = SSB_equil / SSBpR_unf; // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific SSBpR_temp = SSB_equil; @@ -2720,7 +2720,7 @@ FUNCTION void Get_Forecast() Fishon = 0; eq_yr = y; bio_yr = y; - Do_Equil_Calc(R0_use); // call function to do per recruit calculation + SSBpR_Calc(R0_use); // call function to do per recruit calculation // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R if (fishery_on_off == 1) { @@ -3360,7 +3360,7 @@ FUNCTION void Get_Forecast() Fishon = 0; eq_yr = y; bio_yr = y; - Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation + SSBpR_Calc(equ_Recr); // call function to do per recruit calculation // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R if (fishery_on_off == 1) { @@ -3783,7 +3783,7 @@ FUNCTION void Get_Forecast() equ_Recr = Recr_unf; bio_yr = y; Fishon = 0; - Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation + SSBpR_Calc(equ_Recr); // call function to do per recruit calculation Smry_Table(y, 11) = SSB_equil; Smry_Table(y, 13) = GenTime; @@ -3796,7 +3796,7 @@ FUNCTION void Get_Forecast() SR_parm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 } Fishon = 1; - Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation + SSBpR_Calc(equ_Recr); // call function to do per recruit calculation if (STD_Yr_Reverse_Ofish(y) > 0) {SPR_std(STD_Yr_Reverse_Ofish(y)) = SSB_equil / Smry_Table(y, 11);} Smry_Table(y, 9) = totbio; diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index d27225db..de8fc784 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -1,8 +1,8 @@ // SS_Label_file #12. **SS_popdyn.tpl** // SS_Label_file # * setup_recdevs() -// SS_Label_file # * get_initial_conditions() // does virgin and initial year by calling Do_Equil_Calc() with F=0, then F=init_F +// SS_Label_file # * get_initial_conditions() // does virgin and initial year by calling SSBpR_Calc() with F=0, then F=init_F // SS_Label_file # * get_time_series() // loops the years, calling biology, selectivity and spawn-recr functions as needed -// SS_Label_file # * Do_Equil_Calc() // does per-recruit calculations and returns SSB/R and Y/R +// SS_Label_file # * SSBpR_Calc() // does per-recruit calculations and returns SSB/R and Y/R // SS_Label_file # FUNCTION void setup_recdevs() @@ -342,7 +342,7 @@ FUNCTION void get_initial_conditions() if (recr_dist_area == 1 || pop == 1) // do global spawn_recruitment calculations { equ_Recr = 1.0; - Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation. Returns SPR because R = 1.0 + SSBpR_Calc(equ_Recr); // call function to do per recruit calculation. Returns SPR because R = 1.0 SSBpR_virgin = SSB_equil; // spawners per recruit. Needed for Sr_fxn = 10 if(SR_fxn == 10) // B-H with a,b { @@ -377,7 +377,7 @@ FUNCTION void get_initial_conditions() exp_rec(eq_yr, 2) = Recr_virgin; exp_rec(eq_yr, 3) = Recr_virgin; exp_rec(eq_yr, 4) = Recr_virgin; - Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation + SSBpR_Calc(equ_Recr); // call function to do per recruit calculation SSB_virgin = SSB_equil; if(Do_Benchmark==0) // assign values that would be created in benchmark section { @@ -516,8 +516,8 @@ FUNCTION void get_initial_conditions() exp_rec(eq_yr, 2) = R1; exp_rec(eq_yr, 3) = R1; exp_rec(eq_yr, 4) = R1; - equ_Recr = R1; // equ_Recr is used inside of Do_Equil_Calc - Do_Equil_Calc(equ_Recr); + equ_Recr = R1; // equ_Recr is used inside of SSBpR_Calc + SSBpR_Calc(equ_Recr); CrashPen += Equ_penalty; } else @@ -527,9 +527,9 @@ FUNCTION void get_initial_conditions() // first get SPR for this init_F // SPAWN-RECR: calc initial equilibrium pop, SSB, Recruitment // equ_Recr=Recr_virgin; - equ_Recr = R1_exp * regime_change; - - Do_Equil_Calc(equ_Recr); +// equ_Recr = R1_exp * regime_change; // NOTE: seems wrong to apply regime here + equ_Recr = R1_exp; + SSBpR_Calc(equ_Recr); CrashPen += Equ_penalty; SSBpR_temp = SSB_equil / equ_Recr; // spawners per recruit at initial F // get equilibrium SSB and recruitment from SSBpR_temp, Recr_virgin and virgin steepness @@ -543,7 +543,7 @@ FUNCTION void get_initial_conditions() exp_rec(eq_yr, 3) = equ_Recr; exp_rec(eq_yr, 4) = equ_Recr; R1 = equ_Recr; - Do_Equil_Calc(equ_Recr); // calculated SSB_equil + SSBpR_Calc(equ_Recr); // calculated SSB_equil CrashPen += Equ_penalty; } Smry_Table(styr - 1, 1) = totbio; // from equil calcs @@ -1036,7 +1036,7 @@ FUNCTION void get_time_series() Fishon = 0; eq_yr = y; bio_yr = y; - Do_Equil_Calc(R0_use); // call function to do per recruit calculation with current year's biology and adjusted R0 + SSBpR_Calc(R0_use); // call function to do per recruit calculation with current year's biology and adjusted R0 SSB_use = SSB_equil; // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R if (fishery_on_off == 1) @@ -1496,7 +1496,7 @@ FUNCTION void get_time_series() Fishon = 0; eq_yr = y; bio_yr = y; - Do_Equil_Calc(R0_use); // call function to do per recruit calculation + SSBpR_Calc(R0_use); // call function to do per recruit calculation SSB_use = SSB_equil; // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R if (fishery_on_off == 1) @@ -1789,7 +1789,7 @@ FUNCTION void get_time_series() equ_Recr = Recr_virgin; bio_yr = y; Fishon = 0; - Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation with current year's biology + SSBpR_Calc(equ_Recr); // call function to do per recruit calculation with current year's biology Smry_Table(y, 11) = SSB_equil; Smry_Table(y, 13) = GenTime; if( SR_fxn == 10 ) @@ -1801,7 +1801,7 @@ FUNCTION void get_time_series() SR_parm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 } Fishon = 1; - Do_Equil_Calc(equ_Recr); // call function to do per recruit calculation with current year's biology and F + SSBpR_Calc(equ_Recr); // call function to do per recruit calculation with current year's biology and F if (STD_Yr_Reverse_Ofish(y) > 0) { SPR_std(STD_Yr_Reverse_Ofish(y)) = SSB_equil / Smry_Table(y, 11); @@ -1833,7 +1833,7 @@ FUNCTION void get_time_series() //******************************************************************** /* SS_Label_FUNCTION 30 Do_Equil_Calc */ // This function does per recruit calculations, so produces an age composition that is in equilibrium with M+F -FUNCTION void Do_Equil_Calc(const prevariable& equ_Recr) +FUNCTION void SSBpR_Calc(const prevariable& equ_Recr) { int t_base; int t; diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 7a9688e5..655a4ca2 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -1,6 +1,6 @@ // SS_Label_file #19. **SS_write_report.tpl** // SS_Label_file # * write_bigoutput() // produces *report.sso* and *compreport.sso* -// SS_Label_file # * SPR_profile() // calls Do_Equil_Calc() and Equil_Spawn_Recr_Fxn() over a range of F to get SPR, YPR, and SSB and catch curves +// SS_Label_file # * SPR_profile() // calls SSBpR_Calc() and Equil_Spawn_Recr_Fxn() over a range of F to get SPR, YPR, and SSB and catch curves // SS_Label_file # * global_MSY() // similar to SPR_profile but first changes all selectivities to knife edge and profiles on age-at-entry // SS_Label_file # @@ -4782,7 +4782,7 @@ FUNCTION void SPR_profile() SPRloop1_end = 7; } int SPRloops; - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); if (N_bycatch == 0) { k = 0; @@ -4902,7 +4902,7 @@ FUNCTION void SPR_profile() } Fishon = 1; - Do_Equil_Calc(equ_Recr); + SSBpR_Calc(equ_Recr); // SPAWN-RECR: calc equil spawn-recr in the SPR loop SSBpR_temp = SSB_equil; Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR From 0ad975fe1f73cdf83ed03b1f42686f51e7e26bc6 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 28 Mar 2025 16:20:07 -0700 Subject: [PATCH 33/58] revise SRparm timevary to track R0 h --- SS_popdyn.tpl | 15 +++++++++++---- SS_readcontrol_330.tpl | 15 +++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index de8fc784..c4e55ffc 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -1024,21 +1024,27 @@ FUNCTION void get_time_series() // SS_Label_Info_24.2.3 #Get the total recruitment produced by this spawning biomass at the beginning of the season // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_Fxn relevant keyword - if (timevary_parm_start_SR == 0) // SRparm are not time-varying + if (timevary_parm_start_SR == 0 || timevary_SRparm (y) == 0) // SRparm are not time-varying (but regime still could be) { R0_use = Recr_virgin; SSB_use = SSB_virgin; + warning << y << " virgin "< 0) { R0_use = mfexp(SR_parm_work(1)); // check to be sure this works when R0 is derived from B-H with alpha, beta parameters Fishon = 0; diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 26936674..eaed1c0f 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -2068,9 +2068,11 @@ } // flag for recruitment autocorrelation echoinput << " Do recruitment_autocorr: " << SR_autocorr << endl; + + // note that the regime parameter seems to bypass use of timevary_SRparm, but timevary_SRparm is used for R0, h beginning 3.30.24 timevary_used = 0; - for (j = 1; j <= N_SRparm(SR_fxn) + 2; j++) - if (j != N_SRparm(SR_fxn) + 1) // because sigmaR and autocorr cannot be time-varying + for (j = 1; j <= N_SRparm2 - 1; j++) // so omits autocorr + if (j != N_SRparm2 - 2) // because sigmaR cannot be time-varying { if (SR_parm_1(j, 13) == 0 && SR_parm_1(j, 8) == 0 && SR_parm_1(j, 9) == 0) { @@ -2097,7 +2099,7 @@ timevary_setup(2) = j; // index of base parm within that type of parameter timevary_setup(13) = firstSRparm + j; // index of base parm relative to ParCount which is continuous across all types of parameters timevary_setup(3) = timevary_parm_cnt + 1; // first parameter within total list of all timevary parms - timevary_pass = 1; // placeholder; not used for SR parms + timevary_pass = 0; // placeholder; not used for SR parms // set up env link info echoinput << " check for env " << SR_parm_1(j, 8) << endl; k = int(abs(SR_parm_1(j, 8)) / 100); // find the env link code @@ -2132,9 +2134,10 @@ create_timevary(SR_parm_1(j), timevary_setup, timevary_pass, autogen_timevary(timevary_setup(1)), f, block_design_null, env_data_pass, N_parm_dev, finish_starter); } timevary_def.push_back(timevary_setup(1, 14)); - for (y = styr - 3; y <= YrMax + 1; y++) { - timevary_SRparm(y) = timevary_pass(y); - } // year vector for this category og MGparm + for (y = styr - 3; y <= YrMax + 1; y++) + { + if (timevary_pass(y) > 0 && j != N_SRparm2 - 1) timevary_SRparm(y , YrMax) = timevary_pass(y); // set timevary flag, except for regime parameter + } } } From d1343125650b9d0a313307692c0f6b3414154750 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Mon, 31 Mar 2025 15:39:44 -0700 Subject: [PATCH 34/58] refactor variable names and continue testing --- SS_benchfore.tpl | 88 ++++++++++++++-------------- SS_objfunc.tpl | 18 +++--- SS_param.tpl | 14 ++--- SS_popdyn.tpl | 84 +++++++++++++-------------- SS_prelim.tpl | 12 ++-- SS_proced.tpl | 12 ++-- SS_readcontrol_330.tpl | 126 ++++++++++++++++++++--------------------- SS_recruit.tpl | 40 ++++++------- SS_timevaryparm.tpl | 10 ++-- SS_write.tpl | 16 +++--- SS_write_report.tpl | 38 ++++++------- SS_write_ssnew.tpl | 8 +-- 12 files changed, 233 insertions(+), 233 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 933beacd..d2f202c8 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -415,7 +415,7 @@ FUNCTION void setup_Benchmark() // and forecast } // recr_dist_unf is accumulated while doing the time_series // then its mean is calculated in Get_Benchmarks and assigned to recr_dist - // the SR_parm_bench is calculated from Bmark_yrs 9-10 in benchmark code using values stored in SR_parm_byyr + // the SRparm_bench is calculated from Bmark_yrs 9-10 in benchmark code using values stored in SRparm_byyr } // calc average selectivity to use in equil; store in styr-3 @@ -733,18 +733,18 @@ FUNCTION void Get_Benchmarks(const int show_MSY) for (j = 1; j <= N_SRparm2; j++) { - if (SR_parm_timevary(j) == 0) + if (SRparm_timevary(j) == 0) { - SR_parm_work(j) = SR_parm(j); + SRparm_work(j) = SRparm(j); } else { temp = 0.; for (int y = Bmark_Yr(9); y <= Bmark_Yr(10); y++) { - temp += SR_parm_byyr(y, j); + temp += SRparm_byyr(y, j); } - SR_parm_work(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); + SRparm_work(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); } } @@ -756,7 +756,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Flags: timevary_MG_firstyr == YrMax // means that no biology is time-varying - timevary_parm_start_SR > 0 // means that R0 or h (i.e. any except regime, sigmaR, autocorr) is time-varying, so SSBpR0 gets updated for time series and for bench + timevary_parm_SR_first > 0 // means that R0 or h (i.e. any except regime, sigmaR, autocorr) is time-varying, so SSBpR0 gets updated for time series and for bench timevary_bio_4SRR is new user selected flag: 0 for legacy, vs 1 for improved use of timevary biology in SRR calcs Legacy approach: @@ -775,22 +775,24 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Improved approach SSBpR0 set at start year using start year biology SSBpR0 updated during time series if there is time-varying R0; PLUS NEW: equil_spawn_recr_calc called to get new equilibrium R0, SSB0 - SSBpR0 for benchmark stays at virgin unless timevary_bio_4SRR == 0, or if timevary_parm_start_SR > 0 + SSBpR0 for benchmark stays at virgin unless timevary_bio_4SRR == 0, or if timevary_parm_SR_first > 0 Btgttgt can now use either frac*SSB_bench or frac*SSB_virgin by using the existing flag for depletion basis Btgttgt2 can be fraction of SSB_MSY, of SSB_virgin, or of SSB_bench HCR inflection adds option to use SSB_virgin or SSB_bench depletion adds option to use SSB_bench */ - Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used + Recr_unf = mfexp(SRparm_work(1)); // R0 to be used Fishon = 0; SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology dvariable SSBpR_bench = SSB_equil / Recr_unf; + report5 << "virgin: " << Recr_virgin << " " << SSB_virgin << endl; + report5 << "bench: " << Recr_unf << " " << SSB_equil << endl; if( timevary_MG_firstyr == YrMax && WTage_rd == 0) // no time-varying biology { SSB0_4_SRR = SSB_virgin; R0_4_SRR = Recr_virgin; - SSB_unf = SSB_equil; // should this also depend on timevary_parm_start_SR > 0??? + SSB_unf = SSB_equil; // should this also depend on timevary_parm_SR_first > 0??? } else // there is some timevary biology (with any WTage_rd == 1 qualifying as timevarying without actually chacking for different values in diff years) { @@ -798,18 +800,17 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { warnstream << "There is timevary biology and the legacy approach to benchmark calculations is being used; user should be aware"; write_message (WARN, 0); - if(timevary_parm_start_SR == 0) // no timevary SRR parms + if(timevary_parm_SR_first == 0) // no timevary SRR parms { SSB_unf = SSB_equil; R0_4_SRR = Recr_unf; // same as Recr_virgin because no timevary SRparms SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR SSBpR_bench = SSB0_4_SRR / R0_4_SRR; - // Equil_Spawn_Recr_Fxn will be called in more complete approach to use SSBpR_bench to move along the SRR } - else // there are timevary SRR parms, so use benchmark biology to create a whole new SRR + else // there are timevary SRR parms { - Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used - // steepness and other SR parms will also come from SR_parm_work + Recr_unf = mfexp(SRparm_work(1)); // R0 to be used + // steepness and other SR parms will also come from SRparm_work SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSB_unf = SSB_equil; R0_4_SRR = Recr_unf; @@ -821,20 +822,20 @@ FUNCTION void Get_Benchmarks(const int show_MSY) else // more complete approach to time vary biology will be used (introduced in 3.30.24) { - if(timevary_parm_start_SR == 0) // no timevary SRR parms, so SRR will use SSB_virgin, Recr_virgin to internally create virgin SSBpR0 + if(timevary_parm_SR_first == 0) // no timevary SRR parms, so SRR will use SSB_virgin, Recr_virgin to internally create virgin SSBpR0 { SSB0_4_SRR = SSB_virgin; R0_4_SRR = Recr_virgin; // get new equilibrium point using original SRR and SSBpR_bench - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB_virgin, Recr_virgin, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR SSB_unf = Equ_SpawnRecr_Result(1); Recr_unf = Equ_SpawnRecr_Result(2); if (show_MSY == 1) report5 << " use virgin SSBpR0 in SRR - SSB: " << SSB_virgin << " Recr: " << Recr_virgin << " SPR: " << SSB_virgin / Recr_virgin << " bench SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; } - else // use benchmark quantities for SRR, so everything can change + else // use updated SRparms and benchmark biology { // get new equilibrium point for the benchmark SRR - Recr_unf = mfexp(SR_parm_work(1)); // R0 to be used + Recr_unf = mfexp(SRparm_work(1)); // R0 to be used Fishon = 0; SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSBpR_bench = SSB_equil / Recr_unf; @@ -842,23 +843,22 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSB_unf = SSB_equil; R0_4_SRR = Recr_unf; // verify - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR if (show_MSY == 1) report5 << " use bench SSBpR0 in SRR - SSB: " << SSB_unf << " Recr: " << Recr_unf << " SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; } SSBpR_Calc(Recr_unf); // this calcs SSBpR and returns it as SSB_equil using benchmark biology and the updated equil Recr SSB_unf = SSB_equil; - if (show_MSY == 1) report5 << " CHECK! - SSB_unf based on updated SRR (if any): " << SSB_unf << endl; } } if (show_MSY == 1) { - SR_parm_work(N_SRparm2 + 1) = SSB0_4_SRR; + SRparm_work(N_SRparm2 + 1) = SSB0_4_SRR; Mgmt_quant(1) = SSB_unf; Mgmt_quant(2) = totbio; // this is calculated in Do_Equil_Calc Mgmt_quant(3) = smrybio; Mgmt_quant(4) = Recr_unf; - report5 << "SR_parms for benchmark: " << SR_parm_work << endl + report5 << "SRparms for benchmark: " << SRparm_work << endl << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << endl; Mgmt_quant(19) = SSB_unf; // placeholder for depletion denominator Mgmt_quant(20) = SSB_unf; // placeholder to be replaced by SSB_HCR_infl @@ -1010,7 +1010,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc equil spawn-recr in YPR; need to make this area-specific SSBpR_temp = SSB_equil; // based on most recent call to Do_Equil_Calc - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bspr = Equ_SpawnRecr_Result(1); Bspr_rec = Equ_SpawnRecr_Result(2); @@ -1125,7 +1125,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F0.1: " << Btgt_Fmult << endl; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt = Equ_SpawnRecr_Result(1); Btgt_Rec = Equ_SpawnRecr_Result(2); YPR_Btgt_enc = YPR_enc; // total encountered yield per recruit @@ -1226,7 +1226,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSBpR_temp = SSB_equil; SPR_Btgt = SSBpR_temp / SSBpR_unf; // where SSBpR_unf = SSB_unf / Recr_unf so units of SSB/R; so result is SPR_Btgt = (fished SSB/R) / (unfished SSB/R) // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1402,7 +1402,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } if (F_Method == 1) { - Fmax = (Btgt_Fmult + SPR_Fmult) * 0.5 * SR_parm_work(2) / 0.05; + Fmax = (Btgt_Fmult + SPR_Fmult) * 0.5 * SRparm_work(2) / 0.05; } // previously /0.18 F1(1) = -log(Fmax / Btgt_Fmult - 1.); F2(1) = -log(Fmax / Btgt_Fmult - 1.); @@ -1446,7 +1446,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SSBpR_unf; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); // with MSY set to SPR, not directly estimated Recr_msy = Equ_SpawnRecr_Result(2); yld1(1) = YPR_opt * Recr_msy; @@ -1540,7 +1540,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SSBpR_unf; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); // MSY is directly estimated Recr_msy = Equ_SpawnRecr_Result(2); Profit = (PricePerF * YPR_val_vec) * Recr_msy - Cost; @@ -1841,7 +1841,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SPR_Btgt2 = SSB_equil / SSBpR_unf; // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1923,9 +1923,9 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { report5 << "#" << endl << "Management_report" << endl; - report5 << "Virgin: Steepness_Recr_SSB " << SR_parm(2) << " " << Recr_virgin << " " << SSB_virgin << endl; - report5 << "Bench: Steepness_Recr_SSB " << SR_parm_work(2) << " " << R0_4_SRR << " " << SSB0_4_SRR << endl; - report5 << "unf : Steepness_Recr_SSB " << SR_parm_work(2) << " " << Recr_unf << " " << SSB_unf << endl; + report5 << "Virgin: Steepness_Recr_SSB " << SRparm(2) << " " << Recr_virgin << " " << SSB_virgin << endl; + report5 << "Bench: Steepness_Recr_SSB " << SRparm_work(2) << " " << R0_4_SRR << " " << SSB0_4_SRR << endl; + report5 << "unf : Steepness_Recr_SSB " << SRparm_work(2) << " " << Recr_unf << " " << SSB_unf << endl; report5 << "#" << endl << "Summary_age: " << Smry_Age << endl; report5 << "#_Bmark_years: beg_bio, end_bio, beg_selex, end_selex, beg_relF, end_relF, beg_recr_dist, end_recr_dist, beg_SRparm, end_SRparm" << endl @@ -2423,15 +2423,15 @@ FUNCTION void Get_Forecast() t_base = styr + (y - styr) * nseas - 1; for (f = 1; f <= N_SRparm2; f++) { - if (SR_parm_timevary(f) == 0) + if (SRparm_timevary(f) == 0) { - // no change to SR_parm_work + // no change to SRparm_work } else { - SR_parm_work(f) = parm_timevary(SR_parm_timevary(f), y); + SRparm_work(f) = parm_timevary(SRparm_timevary(f), y); } - SR_parm_byyr(y, f) = SR_parm_work(f); + SRparm_byyr(y, f) = SRparm_work(f); } env_data(y, -1) = log(SSB_current / SSB_yr(styr - 1)); // store most recent value for density-dependent effects, NOTE - off by a year if recalc'ed at beginning of season 1 env_data(y, -2) = recdev(y); // store for density-dependent effects @@ -2708,14 +2708,14 @@ FUNCTION void Get_Forecast() } // SPAWN-RECR: get recruitment in forecast; needs to be area-specific // SR_fxn - if (timevary_parm_start_SR == 0) // R0 is not time-varying + if (timevary_parm_SR_first == 0) // R0 is not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; } else { - R0_use = mfexp(SR_parm_work(1)); + R0_use = mfexp(SRparm_work(1)); equ_Recr = R0_use; Fishon = 0; eq_yr = y; @@ -3348,14 +3348,14 @@ FUNCTION void Get_Forecast() // SS_Label_Info_24.3.4.1 #Get recruitment from this spawning biomass // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_fxn - if (timevary_parm_start_SR == 0) // R0 is not time-varying + if (timevary_parm_SR_first == 0) // R0 is not time-varying { R0_use = Recr_virgin; SSB_use = SSB_virgin; } else { - R0_use = mfexp(SR_parm_work(1)); + R0_use = mfexp(SRparm_work(1)); equ_Recr = R0_use; Fishon = 0; eq_yr = y; @@ -3790,10 +3790,10 @@ FUNCTION void Get_Forecast() if( SR_fxn == 10 ) { temp = SSB_equil / equ_Recr; // current year's SSB/R with current biology at age - alpha = mfexp(SR_parm_work(3)); - beta = mfexp(SR_parm_work(4)); - SR_parm_byyr(y, 2) = alpha * temp / (4. + alpha * temp); // implied steepness - SR_parm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 + alpha = mfexp(SRparm_work(3)); + beta = mfexp(SRparm_work(4)); + SRparm_byyr(y, 2) = alpha * temp / (4. + alpha * temp); // implied steepness + SRparm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 } Fishon = 1; SSBpR_Calc(equ_Recr); // call function to do per recruit calculation diff --git a/SS_objfunc.tpl b/SS_objfunc.tpl index 474153ee..c4655bac 100644 --- a/SS_objfunc.tpl +++ b/SS_objfunc.tpl @@ -745,8 +745,8 @@ FUNCTION void evaluate_the_objective_function() //The recruitment prior is assumed to be a lognormal pdf with expected // value equal to the deterministic stock-recruitment curve // SS_Label_260 // R1 deviation is weighted by ave_age because R1 represents a time series of recruitments - // SR_parm(N_SRparm+1) is sigmaR - // SR_parm(N_SRparm+4) is rho, the autocorrelation coefficient + // SRparm(N_SRparm+1) is sigmaR + // SRparm(N_SRparm+4) is rho, the autocorrelation coefficient // POP code from Ianelli // if (rho>0) // for (i=styr_rec+1;i<=endyr;i++) @@ -767,7 +767,7 @@ FUNCTION void evaluate_the_objective_function() } else { - rho = SR_parm(N_SRparm2); + rho = SRparm(N_SRparm2); recr_like += square(recdev(recdev_first)) / two_sigmaRsq; for (y = recdev_first + 1; y <= recdev_end; y++) { @@ -778,7 +778,7 @@ FUNCTION void evaluate_the_objective_function() } else { - rho = SR_parm(N_SRparm2); + rho = SRparm(N_SRparm2); dvariable dev; dvariable dev_last; if (recdev_first >= styr) @@ -884,10 +884,10 @@ FUNCTION void evaluate_the_objective_function() } for (i = 1; i <= N_SRparm3; i++) - if (SR_parm_PRtype(i) > 0 && (active(SR_parm(i)) || Do_all_priors > 0)) + if (SRparm_PRtype(i) > 0 && (active(SRparm(i)) || Do_all_priors > 0)) { - SR_parm_Like(i) = Get_Prior(SR_parm_PRtype(i), SR_parm_LO(i), SR_parm_HI(i), SR_parm_PR(i), SR_parm_CV(i), SR_parm(i)); - parm_like += SR_parm_Like(i); + SRparm_Like(i) = Get_Prior(SRparm_PRtype(i), SRparm_LO(i), SRparm_HI(i), SRparm_PR(i), SRparm_CV(i), SRparm(i)); + parm_like += SRparm_Like(i); } // SS_Label_Info_25.14 #logL for recdev_cycle if (recdev_cycle > 0) @@ -1847,8 +1847,8 @@ FUNCTION void get_posteriors() } for (i = 1; i <= N_SRparm3; i++) { - if (active(SR_parm(i))) - posts << SR_parm(i) << " "; + if (active(SRparm(i))) + posts << SRparm(i) << " "; } if (recdev_cycle > 0) diff --git a/SS_param.tpl b/SS_param.tpl index 3f850ebf..ed0dc25f 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -157,11 +157,11 @@ PARAMETER_SECTION 4darray recr_dist(styr-3,YrMax,1,N_GP*gender,1,N_settle_timings,1,pop); 3darray recr_dist_unf(1,N_GP*gender,1,N_settle_timings,1,pop); 3darray recr_dist_endyr(1,N_GP*gender,1,N_settle_timings,1,pop); -!!// SS_Label_Info_5.1.2 #Create SR_parm vector, recruitment vectors - init_bounded_number_vector SR_parm(1,N_SRparm3,SR_parm_LO,SR_parm_HI,SR_parm_PH) - matrix SR_parm_byyr(styr-3,YrMax,1,N_SRparm2+1) // R0, steepness, parm3, sigmar, rec_dev_offset, R1, rho, SSB Time_vary implementation of spawner-recruitment - vector SR_parm_virg(1,N_SRparm2+1) - vector SR_parm_work(1,N_SRparm2+1) +!!// SS_Label_Info_5.1.2 #Create SRparm vector, recruitment vectors + init_bounded_number_vector SRparm(1,N_SRparm3,SRparm_LO,SRparm_HI,SRparm_PH) + matrix SRparm_byyr(styr-3,YrMax,1,N_SRparm2+1) // R0, steepness, parm3, sigmar, rec_dev_offset, R1, rho, SSB Time_vary implementation of spawner-recruitment + vector SRparm_virg(1,N_SRparm2+1) + vector SRparm_work(1,N_SRparm2+1) number two_sigmaRsq; number half_sigmaRsq; number sigmaR; @@ -174,7 +174,7 @@ PARAMETER_SECTION LOCAL_CALCS // clang-format on Ave_Size.initialize(); - // if(SR_parm(N_SRparm2)!=0.0 || SR_parm_PH(N_SRparm2)>0) {SR_autocorr=1;} else {SR_autocorr=0;} // flag for recruitment autocorrelation + // if(SRparm(N_SRparm2)!=0.0 || SRparm_PH(N_SRparm2)>0) {SR_autocorr=1;} else {SR_autocorr=0;} // flag for recruitment autocorrelation if (do_recdev == 1) { k = recdev_start; @@ -632,7 +632,7 @@ PARAMETER_SECTION vector init_F_Like(1,N_init_F) vector Q_parm_Like(1,Q_Npar2) vector selparm_Like(1,N_selparm2) - vector SR_parm_Like(1,N_SRparm3) + vector SRparm_Like(1,N_SRparm3) vector recdev_cycle_Like(1,recdev_cycle) !! k=Do_TG*(3*N_TG+2*Nfleet1); vector TG_parm_Like(1,k); diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index c4e55ffc..35a426ef 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -8,7 +8,7 @@ FUNCTION void setup_recdevs() { // SS_Label_Info_7.1 #Set up recruitment bias_adjustment vector - sigmaR = SR_parm(N_SRparm(SR_fxn) + 1); + sigmaR = SRparm(N_SRparm(SR_fxn) + 1); two_sigmaRsq = 2.0 * sigmaR * sigmaR; half_sigmaRsq = 0.5 * sigmaR * sigmaR; @@ -352,26 +352,26 @@ FUNCTION void get_initial_conditions() // h = a * SPR0 / (4. + a * SPR0) // R0 = 1/b * (a-1/SPR0) - alpha = mfexp(SR_parm(3)); - beta = mfexp(SR_parm(4)); + alpha = mfexp(SRparm(3)); + beta = mfexp(SRparm(4)); steepness = alpha * SSBpR_virgin / (4. + alpha * SSBpR_virgin); Recr_virgin = 1. / beta * (alpha - (1. / SSBpR_virgin)); - SR_parm(1) = log(Recr_virgin); - SR_parm(2) = steepness; + SRparm(1) = log(Recr_virgin); + SRparm(2) = steepness; } else { - Recr_virgin = mfexp(SR_parm(1)); + Recr_virgin = mfexp(SRparm(1)); } for (int i = 1; i <= N_SRparm2; i++) { - SR_parm_byyr(eq_yr, i) = SR_parm(i); - SR_parm_virg(i) = SR_parm(i); - SR_parm_work(i) = SR_parm(i); + SRparm_byyr(eq_yr, i) = SRparm(i); + SRparm_virg(i) = SRparm(i); + SRparm_work(i) = SRparm(i); } -// if (SR_fxn == 3) warning << "tester_A: " << SR_parm_work(1) << " base: " << SR_parm(1) << endl; -// if (SR_fxn == 10) warning << "tester_A: " << SR_parm_work(4) << " base: " << SR_parm(4) << endl; +// if (SR_fxn == 3) warning << "tester_A: " << SRparm_work(1) << " base: " << SRparm(1) << endl; +// if (SR_fxn == 10) warning << "tester_A: " << SRparm_work(4) << " base: " << SRparm(4) << endl; equ_Recr = Recr_virgin; exp_rec(eq_yr, 1) = Recr_virgin; // expected Recr from s-r parms exp_rec(eq_yr, 2) = Recr_virgin; @@ -395,9 +395,9 @@ FUNCTION void get_initial_conditions() if (Hermaphro_Option != 0) MaleSSB(eq_yr) = MaleSSB_equil_pop_gp; SSB_yr(eq_yr) = SSB_equil; - SR_parm_byyr(eq_yr, N_SRparm2 + 1) = SSB_equil; - SR_parm_virg(N_SRparm2 + 1) = SSB_equil; - SR_parm_work(N_SRparm2 + 1) = SSB_equil; + SRparm_byyr(eq_yr, N_SRparm2 + 1) = SSB_equil; + SRparm_virg(N_SRparm2 + 1) = SSB_equil; + SRparm_work(N_SRparm2 + 1) = SSB_equil; t = styr - 2 * nseas - 1; for (s = 1; s <= nseas; s++) for (p = 1; p <= pop; p++) @@ -470,18 +470,18 @@ FUNCTION void get_initial_conditions() for (f = 1; f <= N_SRparm2; f++) { - if (SR_parm_timevary(f) == 0) + if (SRparm_timevary(f) == 0) { - // no change to SR_parm_work + // no change to SRparm_work } else { - SR_parm_work(f) = parm_timevary(SR_parm_timevary(f), eq_yr); -// warning << "tester_B: " << SR_parm_work(f) << " timevary " << " base " << SR_parm(f) < 0) // timevary regime exists + if (SRparm_timevary(N_SRparm2 - 1) > 0) // timevary regime exists { - regime_change = mfexp(SR_parm_work(N_SRparm2 - 1)); + regime_change = mfexp(SRparm_work(N_SRparm2 - 1)); } if (init_equ_steepness == 0) // Adjustments do not include spawner-recruitment steepness @@ -534,7 +534,7 @@ FUNCTION void get_initial_conditions() SSBpR_temp = SSB_equil / equ_Recr; // spawners per recruit at initial F // get equilibrium SSB and recruitment from SSBpR_temp, Recr_virgin and virgin steepness // this is the initial year, so no time-vary effects available, so uses _virgin quantities for spawner-recruitment - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB_virgin, Recr_virgin, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB_virgin, Recr_virgin, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR R1_exp = Equ_SpawnRecr_Result(2); // set the expected recruitment equal to this equilibrium exp_rec(eq_yr, 1) = R1_exp; @@ -554,8 +554,8 @@ FUNCTION void get_initial_conditions() if (Hermaphro_Option != 0) MaleSSB(eq_yr) = MaleSSB_equil_pop_gp; SSB_yr(eq_yr) = SSB_equil; - SR_parm_byyr(eq_yr, N_SRparm2 + 1) = SSB_equil; - SR_parm_work(N_SRparm2 + 1) = SSB_equil; + SRparm_byyr(eq_yr, N_SRparm2 + 1) = SSB_equil; + SRparm_work(N_SRparm2 + 1) = SSB_equil; SSB_yr(styr) = SSB_equil; env_data(styr - 1, -1) = 0.0; env_data(styr - 1, -2) = 0.0; @@ -721,16 +721,16 @@ FUNCTION void get_time_series() for (f = 1; f <= N_SRparm2; f++) { - if (SR_parm_timevary(f) == 0) + if (SRparm_timevary(f) == 0) { - // no change to SR_parm_work + // no change to SRparm_work } else { - SR_parm_work(f) = parm_timevary(SR_parm_timevary(f), y); -// warning << "tester_C: " << SR_parm_work(f) << " timevary_year " << endl; + SRparm_work(f) = parm_timevary(SRparm_timevary(f), y); +// warning << "tester_C: " << SRparm_work(f) << " timevary_year " << endl; } - SR_parm_byyr(y, f) = SR_parm_work(f); + SRparm_byyr(y, f) = SRparm_work(f); } // SS_Label_Info_24.1.1 #store begin of year quantities for use in density-dependent processes @@ -1024,16 +1024,16 @@ FUNCTION void get_time_series() // SS_Label_Info_24.2.3 #Get the total recruitment produced by this spawning biomass at the beginning of the season // SPAWN-RECR: calc recruitment in time series; need to make this area-specific // SR_Fxn relevant keyword - if (timevary_parm_start_SR == 0 || timevary_SRparm (y) == 0) // SRparm are not time-varying (but regime still could be) + if (timevary_parm_SR_first == 0 || timevary_SRparm(y) == 0) // SRparm are not time-varying (but regime still could be) { R0_use = Recr_virgin; SSB_use = SSB_virgin; - warning << y << " virgin "< 0) { - R0_use = mfexp(SR_parm_work(1)); // check to be sure this works when R0 is derived from B-H with alpha, beta parameters + R0_use = mfexp(SRparm_work(1)); // check to be sure this works when R0 is derived from B-H with alpha, beta parameters Fishon = 0; eq_yr = y; bio_yr = y; @@ -1802,10 +1802,10 @@ FUNCTION void get_time_series() if( SR_fxn == 10 ) { temp = SSB_equil / Recr_virgin; // current year's SSB/R with current biology at age - alpha = mfexp(SR_parm_work(3)); - beta = mfexp(SR_parm_work(4)); - SR_parm_byyr(y, 2) = alpha * temp / (4. + alpha * temp); // implied steepness - SR_parm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 + alpha = mfexp(SRparm_work(3)); + beta = mfexp(SRparm_work(4)); + SRparm_byyr(y, 2) = alpha * temp / (4. + alpha * temp); // implied steepness + SRparm_byyr(y, 1) = log( 1. / beta * (alpha - (1. / temp))); // implied ln_R0 } Fishon = 1; SSBpR_Calc(equ_Recr); // call function to do per recruit calculation with current year's biology and F diff --git a/SS_prelim.tpl b/SS_prelim.tpl index b23dff21..b58f1a05 100644 --- a/SS_prelim.tpl +++ b/SS_prelim.tpl @@ -689,9 +689,9 @@ for (i = 1; i <= N_SRparm3; i++) { - SR_parm(i) = SR_parm_RD(i); + SRparm(i) = SRparm_RD(i); } - echoinput << " SRR_parms read from ctl " << SR_parm << endl; + echoinput << " SRR_parms read from ctl " << SRparm << endl; if (recdev_cycle > 0) { @@ -863,13 +863,13 @@ MGparm_use = value(MGparm); echoinput << endl - << " now check SR_parm bounds and priors and do jitter if requested " << endl; + << " now check SRparm bounds and priors and do jitter if requested " << endl; for (i = 1; i <= N_SRparm3; i++) { - SR_parm(i) = Check_Parm(i, SR_parm_PH(i), SR_parm_LO(i), SR_parm_HI(i), SR_parm_PRtype(i), SR_parm_PR(i), SR_parm_CV(i), jitter, SR_parm(i)); + SRparm(i) = Check_Parm(i, SRparm_PH(i), SRparm_LO(i), SRparm_HI(i), SRparm_PRtype(i), SRparm_PR(i), SRparm_CV(i), jitter, SRparm(i)); } - echoinput << " SRR_parms after check " << SR_parm << endl; - SR_parm_use = value(SR_parm); + echoinput << " SRR_parms after check " << SRparm << endl; + SRparm_use = value(SRparm); recdev_use.initialize(); if (recdev_cycle > 0) diff --git a/SS_proced.tpl b/SS_proced.tpl index 3e545ba7..8d4896aa 100644 --- a/SS_proced.tpl +++ b/SS_proced.tpl @@ -24,8 +24,8 @@ PROCEDURE_SECTION { if (mcmc_counter == 0) { - SR_parm(1) += MCMC_bump; - cout << mcmc_counter << " adjusted SR_parm in first mcmc call " << SR_parm(1) << " by " << MCMC_bump << endl; + SRparm(1) += MCMC_bump; + cout << mcmc_counter << " adjusted SRparm in first mcmc call " << SRparm(1) << " by " << MCMC_bump << endl; } mcmc_counter++; @@ -255,11 +255,11 @@ PROCEDURE_SECTION ParmTrace << " " << MGparm(j); } } - for (j = 1; j <= SR_parm_PH.indexmax(); j++) + for (j = 1; j <= SRparm_PH.indexmax(); j++) { - if (SR_parm_PH(j) >= 0) + if (SRparm_PH(j) >= 0) { - ParmTrace << " " << SR_parm(j); + ParmTrace << " " << SRparm(j); } } if (recdev_cycle > 0) @@ -384,7 +384,7 @@ PROCEDURE_SECTION ParmTrace << current_phase() << " " << niter << " " << obj_fun << " " << obj_fun - last_objfun << " " << value(SSB_yr(styr)) << " " << value(SSB_yr(endyr)) << " " << biasadj(styr) << " " << max(biasadj) << " " << biasadj(endyr); ParmTrace << " " << MGparm << " "; - ParmTrace << SR_parm << " "; + ParmTrace << SRparm << " "; if (recdev_cycle > 0) ParmTrace << recdev_cycle_parm; if (recdev_do_early > 0) diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index eaed1c0f..7a28a785 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1959,8 +1959,8 @@ int N_SRparm2 int N_SRparm3 // with timevary links included !!N_SRparm2=N_SRparm(SR_fxn)+3; - init_matrix SR_parm_1(1,N_SRparm2,1,14) -!!echoinput<<" SR parms "< 0) varparm_estimated(2) = 1; // sigmaR is estimated so need sd_offset=1 + if (SRparm_1(N_SRparm2 - 2, 7) > 0) varparm_estimated(2) = 1; // sigmaR is estimated so need sd_offset=1 - if (SR_parm_1(N_SRparm2, 3) != 0.0 || SR_parm_1(N_SRparm2, 7) > 0) + if (SRparm_1(N_SRparm2, 3) != 0.0 || SRparm_1(N_SRparm2, 7) > 0) { SR_autocorr = 1; } @@ -2074,19 +2074,19 @@ for (j = 1; j <= N_SRparm2 - 1; j++) // so omits autocorr if (j != N_SRparm2 - 2) // because sigmaR cannot be time-varying { - if (SR_parm_1(j, 13) == 0 && SR_parm_1(j, 8) == 0 && SR_parm_1(j, 9) == 0) + if (SRparm_1(j, 13) == 0 && SRparm_1(j, 8) == 0 && SRparm_1(j, 9) == 0) { // no time-vary parameter effects } else // set up a timevary parameter definition { + timevary_used = 1; ivector timevary_setup(1, 14); // temporary vector for timevary specs timevary_setup.initialize(); - if (timevary_parm_start_SR == 0) timevary_parm_start_SR = timevary_parm_cnt + 1; + if (timevary_parm_SR_first == 0) timevary_parm_SR_first = timevary_parm_cnt + 1; // cumulative index for first timevary SRparm echoinput << " timevary for SR parm: " << j << endl; - timevary_used = 1; timevary_cnt++; // count parameters with time-vary effect - SR_parm_timevary(j) = timevary_cnt; // base SR parameter will use this timevary specification + SRparm_timevary(j) = timevary_cnt; // base SR parameter will use this timevary specification timevary_setup(1) = 2; // indicates a SR parm if (autogen_timevary(2) == 0) { @@ -2101,37 +2101,37 @@ timevary_setup(3) = timevary_parm_cnt + 1; // first parameter within total list of all timevary parms timevary_pass = 0; // placeholder; not used for SR parms // set up env link info - echoinput << " check for env " << SR_parm_1(j, 8) << endl; - k = int(abs(SR_parm_1(j, 8)) / 100); // find the env link code + echoinput << " check for env " << SRparm_1(j, 8) << endl; + k = int(abs(SRparm_1(j, 8)) / 100); // find the env link code timevary_setup(6) = k; // link code for env - if (SR_parm_1(j, 8) > 0) // env variable used + if (SRparm_1(j, 8) > 0) // env variable used { - timevary_setup(7) = int(abs(SR_parm_1(j, 8))) - k * 100; + timevary_setup(7) = int(abs(SRparm_1(j, 8))) - k * 100; k = timevary_setup(7); // for(y=styr-1;y<=YrMax;y++) env_data_pass(y)=env_data_RD(y,k); env_data_pass(1) = env_data_minyr(k); env_data_pass(2) = env_data_maxyr(k); } - else if (abs(SR_parm_1(j, 8) > 0)) // density-dependence + else if (abs(SRparm_1(j, 8) > 0)) // density-dependence { - timevary_setup(7) = -int(abs(SR_parm_1(j, 8)) - k * 100); + timevary_setup(7) = -int(abs(SRparm_1(j, 8)) - k * 100); do_densitydependent = 1; k = 0; env_data_pass.initialize(); } - if (SR_parm_1(j, 13) > 0) // doing blocks + if (SRparm_1(j, 13) > 0) // doing blocks { - if (SR_parm_1(j, 13) > N_Block_Designs) + if (SRparm_1(j, 13) > N_Block_Designs) { warnstream << "SR block request exceeds N_block patterns"; write_message (FATAL, 0); // EXIT! } - create_timevary(SR_parm_1(j), timevary_setup, timevary_pass, autogen_timevary(timevary_setup(1)), f, Block_Design(SR_parm_1(j, 13)), env_data_pass, N_parm_dev, finish_starter); + create_timevary(SRparm_1(j), timevary_setup, timevary_pass, autogen_timevary(timevary_setup(1)), f, Block_Design(SRparm_1(j, 13)), env_data_pass, N_parm_dev, finish_starter); } else { - create_timevary(SR_parm_1(j), timevary_setup, timevary_pass, autogen_timevary(timevary_setup(1)), f, block_design_null, env_data_pass, N_parm_dev, finish_starter); + create_timevary(SRparm_1(j), timevary_setup, timevary_pass, autogen_timevary(timevary_setup(1)), f, block_design_null, env_data_pass, N_parm_dev, finish_starter); } timevary_def.push_back(timevary_setup(1, 14)); for (y = styr - 3; y <= YrMax + 1; y++) @@ -2142,55 +2142,55 @@ } N_SRparm3 = N_SRparm2; - if (timevary_parm_start_SR > 0) + if (timevary_parm_SR_first > 0) { - timevary_parm_cnt_SR = timevary_parm_cnt; + timevary_parm_SR_last = timevary_parm_cnt; if (timevary_used == 1) autogen_timevary(2) = 1; // indicate that some parameter is time-varying - N_SRparm3 += (timevary_parm_cnt_SR - timevary_parm_start_SR + 1); - echoinput << " SR timevary_parm_cnt start and end " << timevary_parm_start_SR << " " << timevary_parm_cnt_SR << endl; - echoinput << "link to timevary parms: " << SR_parm_timevary << endl; + N_SRparm3 += (timevary_parm_SR_last - timevary_parm_SR_first + 1); + echoinput << " SR timevary_parm_cnt start and end " << timevary_parm_SR_first << " " << timevary_parm_SR_last << endl; + echoinput << "link to timevary parms: " << SRparm_timevary << endl; } echoinput << "SR_Npar and N_SRparm2 and N_SRparm3: " << N_SRparm(SR_fxn) << " " << N_SRparm2 << " " << N_SRparm3 << endl; // clang-format off END_CALCS - vector SR_parm_LO(1,N_SRparm3) - vector SR_parm_HI(1,N_SRparm3) - vector SR_parm_RD(1,N_SRparm3) - vector SR_parm_PR(1,N_SRparm3) - ivector SR_parm_PRtype(1,N_SRparm3) - vector SR_parm_CV(1,N_SRparm3) - ivector SR_parm_PH(1,N_SRparm3) + vector SRparm_LO(1,N_SRparm3) + vector SRparm_HI(1,N_SRparm3) + vector SRparm_RD(1,N_SRparm3) + vector SRparm_PR(1,N_SRparm3) + ivector SRparm_PRtype(1,N_SRparm3) + vector SRparm_CV(1,N_SRparm3) + ivector SRparm_PH(1,N_SRparm3) LOCAL_CALCS // clang-format on for (i = 1; i <= N_SRparm2; i++) { - SR_parm_LO(i) = SR_parm_1(i, 1); - SR_parm_HI(i) = SR_parm_1(i, 2); - SR_parm_RD(i) = SR_parm_1(i, 3); - SR_parm_PR(i) = SR_parm_1(i, 4); - SR_parm_CV(i) = SR_parm_1(i, 5); - SR_parm_PRtype(i) = SR_parm_1(i, 6); - SR_parm_PH(i) = SR_parm_1(i, 7); + SRparm_LO(i) = SRparm_1(i, 1); + SRparm_HI(i) = SRparm_1(i, 2); + SRparm_RD(i) = SRparm_1(i, 3); + SRparm_PR(i) = SRparm_1(i, 4); + SRparm_CV(i) = SRparm_1(i, 5); + SRparm_PRtype(i) = SRparm_1(i, 6); + SRparm_PH(i) = SRparm_1(i, 7); } - if (timevary_parm_start_SR > 0) + if (timevary_parm_SR_first > 0) { j = N_SRparm2; - for (f = timevary_parm_start_SR; f <= timevary_parm_cnt_SR; f++) + for (f = timevary_parm_SR_first; f <= timevary_parm_SR_last; f++) { j++; echoinput << f << " " << j << " " << timevary_parm_rd[f] << endl; - SR_parm_LO(j) = timevary_parm_rd[f](1); - SR_parm_HI(j) = timevary_parm_rd[f](2); - SR_parm_RD(j) = timevary_parm_rd[f](3); - SR_parm_PR(j) = timevary_parm_rd[f](4); - SR_parm_PRtype(j) = timevary_parm_rd[f](6); - SR_parm_CV(j) = timevary_parm_rd[f](5); - SR_parm_PH(j) = timevary_parm_rd[f](7); + SRparm_LO(j) = timevary_parm_rd[f](1); + SRparm_HI(j) = timevary_parm_rd[f](2); + SRparm_RD(j) = timevary_parm_rd[f](3); + SRparm_PR(j) = timevary_parm_rd[f](4); + SRparm_PRtype(j) = timevary_parm_rd[f](6); + SRparm_CV(j) = timevary_parm_rd[f](5); + SRparm_PH(j) = timevary_parm_rd[f](7); } } - echoinput << "SR_parm_RD: " << SR_parm_RD << endl; + echoinput << "SRparm_RD: " << SRparm_RD << endl; // clang-format off END_CALCS @@ -5902,19 +5902,19 @@ } } - for (j = 1; j <= SR_parm_PH.indexmax(); j++) + for (j = 1; j <= SRparm_PH.indexmax(); j++) { ParCount++; - if (SR_parm_PH(j) == -9999) { - SR_parm_1(j, 3) = prof_var(prof_var_cnt); - SR_parm_RD(j, 3) = SR_parm_1(j, 3); + if (SRparm_PH(j) == -9999) { + SRparm_1(j, 3) = prof_var(prof_var_cnt); + SRparm_RD(j, 3) = SRparm_1(j, 3); prof_var_cnt += 1; } - if (depletion_fleet > 0 && depletion_type < 2 && SR_parm_PH(j) > 0) SR_parm_PH(j)++; // add 1 to phase if using depletion fleet - if (depletion_fleet > 0 && depletion_type < 2 && j == 1) SR_parm_PH(1) = 1; // R0 active in phase 1, unless type==2 - if (SR_parm_PH(j) > Turn_off_phase2) SR_parm_PH(j) = -1; - if (SR_parm_PH(j) > max_phase) max_phase = SR_parm_PH(j); - if (SR_parm_PH(j) >= 0) + if (depletion_fleet > 0 && depletion_type < 2 && SRparm_PH(j) > 0) SRparm_PH(j)++; // add 1 to phase if using depletion fleet + if (depletion_fleet > 0 && depletion_type < 2 && j == 1) SRparm_PH(1) = 1; // R0 active in phase 1, unless type==2 + if (SRparm_PH(j) > Turn_off_phase2) SRparm_PH(j) = -1; + if (SRparm_PH(j) > max_phase) max_phase = SRparm_PH(j); + if (SRparm_PH(j) >= 0) { active_count++; active_parm(active_count) = ParCount; @@ -7082,7 +7082,7 @@ // containers for parameter values after jitter vector MGparm_use(1,N_MGparm2) - vector SR_parm_use(1,N_SRparm3); + vector SRparm_use(1,N_SRparm3); vector recdev_cycle_use(1,recdev_cycle); vector recdev_use(recdev_first,YrMax); vector recdev_RD(recdev_first,YrMax); diff --git a/SS_recruit.tpl b/SS_recruit.tpl index 2fb0b3c4..93263b20 100644 --- a/SS_recruit.tpl +++ b/SS_recruit.tpl @@ -27,7 +27,7 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariab // SS_Label_43.1 add 0.1 to input spawning biomass value to make calculation more rebust SSB_curr_adj = SSB_current + 0.100; // robust - regime_change = SR_parm_work(N_SRparm2 - 1); // this is a persistent deviation off the S/R curve + regime_change = SRparm_work(N_SRparm2 - 1); // this is a persistent deviation off the S/R curve // SS_Label_43.3 calculate expected recruitment from the input spawning biomass and the SR curve // functions below use Recr_virgin_use,SSB_virgin_use which could have been adjusted adjusted above from R0,SSB_virgin @@ -42,14 +42,14 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariab // SS_Label_43.3.2 Ricker case 2: // ricker { - steepness = SR_parm_work(2); + steepness = SRparm_work(2); NewRecruits = Recr_virgin_use * SSB_curr_adj / SSB_virgin_use * mfexp(steepness * (1. - SSB_curr_adj / SSB_virgin_use)); break; } // SS_Label_43.3.3 Beverton-Holt case 3: // Beverton-Holt { - steepness = SR_parm_work(2); + steepness = SRparm_work(2); NewRecruits = (4. * steepness * Recr_virgin_use * SSB_curr_adj) / (SSB_virgin_use * (1. - steepness) + (5. * steepness - 1.) * SSB_curr_adj); break; @@ -57,8 +57,8 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariab case 10: // Beverton-Holt with alpha beta per WHAM: R = A*S/(1+B*S) { - dvariable alpha = mfexp(SR_parm_work(3)); - dvariable beta = mfexp(SR_parm_work(4)); + dvariable alpha = mfexp(SRparm_work(3)); + dvariable beta = mfexp(SRparm_work(4)); NewRecruits = (alpha * SSB_curr_adj) / (1.0 + beta * SSB_curr_adj); break; } @@ -73,8 +73,8 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariab case 5: // hockey stick where "steepness" is now the fraction of B0 below which recruitment declines linearly // the 3rd parameter allows for a minimum recruitment level { - steepness = SR_parm_work(2); - temp = SR_parm_work(3) * Recr_virgin_use + SSB_curr_adj / (steepness * SSB_virgin_use) * (Recr_virgin_use - SR_parm_work(3) * Recr_virgin_use); // linear decrease below steepness*SSB_virgin_use + steepness = SRparm_work(2); + temp = SRparm_work(3) * Recr_virgin_use + SSB_curr_adj / (steepness * SSB_virgin_use) * (Recr_virgin_use - SRparm_work(3) * Recr_virgin_use); // linear decrease below steepness*SSB_virgin_use NewRecruits = Join_Fxn(0.0 * SSB_virgin_use, SSB_virgin_use, steepness * SSB_virgin_use, SSB_curr_adj, temp, Recr_virgin_use); break; } @@ -82,7 +82,7 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariab // SS_Label_43.3.6 Beverton-Holt, with constraint to have constant R about Bzero case 6: //Beverton-Holt constrained { - steepness = SR_parm_work(2); + steepness = SRparm_work(2); // dvariable SPR = SSB_virgin_use / Recr_virgin; // alpha = ((4.0 * steepness) / (1. - steepness)) / SPR ; // beta = (1.0 / Recr_virgin) * (alpha - (1.0 / SPR)); @@ -104,15 +104,15 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariab // PPR_0=SSB_virgin_use/Recr_virgin_use; // pups per recruit at virgin // Surv_0=1./PPR_0; // recruits per pup at virgin // Pups_0=SSB_virgin_use; // total population fecundity is the number of pups produced - // Sfrac=SR_parm(2); + // Sfrac=SRparm(2); SRZ_0 = log(1.0 / (SSB_virgin_use / Recr_virgin_use)); - steepness = SR_parm_work(2); + steepness = SRparm_work(2); srz_min = SRZ_0 * (1.0 - steepness); - SRZ_surv = mfexp((1. - pow((SSB_curr_adj / SSB_virgin_use), SR_parm_work(3))) * (srz_min - SRZ_0) + SRZ_0); // survival + SRZ_surv = mfexp((1. - pow((SSB_curr_adj / SSB_virgin_use), SRparm_work(3))) * (srz_min - SRZ_0) + SRZ_0); // survival NewRecruits = SSB_curr_adj * SRZ_surv; exp_rec(y, 1) = NewRecruits; // expected arithmetic mean recruitment // SS_Label_43.3.7.1 Do variation in recruitment by adjusting survival - // if(SR_env_target==1) SRZ_surv*=mfexp(SR_parm(N_SRparm2-2)* env_data(y,SR_env_link)); // environ effect on survival + // if(SR_env_target==1) SRZ_surv*=mfexp(SRparm(N_SRparm2-2)* env_data(y,SR_env_link)); // environ effect on survival if (recdev_cycle > 0) { gg = y - (styr + (int((y - styr) / recdev_cycle)) * recdev_cycle) + 1; @@ -141,10 +141,10 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariab // SS_Label_43.3.8 Shepherd case 8: // Shepherd 3-parameter SRR. per Punt & Cope 2017 { - Shepherd_c = SR_parm_work(3); - Shepherd_c2 = pow(0.2, SR_parm_work(3)); + Shepherd_c = SRparm_work(3); + Shepherd_c2 = pow(0.2, SRparm_work(3)); Hupper = 1.0 / (5.0 * Shepherd_c2); - steepness = 0.2 + (SR_parm_work(2) - 0.2) / (0.8) * (Hupper - 0.2); + steepness = 0.2 + (SRparm_work(2) - 0.2) / (0.8) * (Hupper - 0.2); temp = (SSB_curr_adj) / (SSB_virgin_use); NewRecruits = (5. * steepness * Recr_virgin_use * (1. - Shepherd_c2) * temp) / (1.0 - 5.0 * steepness * Shepherd_c2 + (5. * steepness - 1.) * pow(temp, Shepherd_c)); @@ -154,8 +154,8 @@ FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariab // SS_Label_43.3.8 Ricker-power case 9: // Ricker power 3-parameter SRR. per Punt & Cope 2017 { - steepness = SR_parm_work(2); - dvariable RkrPower = SR_parm_work(3); + steepness = SRparm_work(2); + dvariable RkrPower = SRparm_work(3); temp = SSB_curr_adj / SSB_virgin_use; temp2 = posfun(1.0 - temp, 0.0000001, temp3); temp = 1.0 - temp2; // Rick's new line to stabilize recruitment at R0 if B>B0 @@ -177,7 +177,7 @@ FUNCTION void apply_recdev(prevariable& NewRecruits, const prevariable& Recr_vir // exp_rec(y,2) is with regime shift or other env effect; // exp_rec(y,3) is with bias adjustment // exp_rec(y,4) is with dev - regime_change = SR_parm_work(N_SRparm2 - 1); // this is a persistent deviation off the S/R curve + regime_change = SRparm_work(N_SRparm2 - 1); // this is a persistent deviation off the S/R curve if (recdev_cycle > 0) { @@ -446,8 +446,8 @@ FUNCTION dvar_vector Equil_Spawn_Recr_Fxn(const dvar_vector& SRparm, // Recs = (SPRF0/SPR) * (1.0 - pow(Top,1.0/Power)); // Recs = posfun(Recs,0.0001,Penal); // if (Recs < 0) Rec2 = 0; else Rec2 = Recs; - steepness = 0.2 + (10.0 - 0.2)/(1+exp(-SR_parm_work(2))); - dvariable RkrPower=exp(SR_parm_work(3)); + steepness = 0.2 + (10.0 - 0.2)/(1+exp(-SRparm_work(2))); + dvariable RkrPower=exp(SRparm_work(3)); temp=SSB_virgin/(SSBpR_current*Recr_virgin_use); dvariable RkrTop = pow(0.8,RkrPower)*log(temp)/log(5.0*steepness); RkrTop = posfun(RkrTop,0.000001,CrashPen); diff --git a/SS_timevaryparm.tpl b/SS_timevaryparm.tpl index 3c721455..b4f6b1d1 100644 --- a/SS_timevaryparm.tpl +++ b/SS_timevaryparm.tpl @@ -52,15 +52,15 @@ FUNCTION void make_timevaryparm() } case 2: // SR { - baseparm = SR_parm(timevary_setup(2)); // index of base parm - baseparm_min(tvary) = SR_parm_LO(timevary_setup(2)); - baseparm_max(tvary) = SR_parm_HI(timevary_setup(2)); + baseparm = SRparm(timevary_setup(2)); // index of base parm + baseparm_min(tvary) = SRparm_LO(timevary_setup(2)); + baseparm_max(tvary) = SRparm_HI(timevary_setup(2)); if (do_once == 1) - echoinput << "base SR_parm " << baseparm << endl; + echoinput << "base SRparm " << baseparm << endl; for (j = timevary_setup(3); j < timevary_def[tvary + 1](3); j++) { timevary_parm_cnt_all++; - timevary_parm(timevary_parm_cnt_all) = SR_parm(N_SRparm(SR_fxn) + 3 + j - timevary_parm_start_SR + 1); + timevary_parm(timevary_parm_cnt_all) = SRparm(N_SRparm(SR_fxn) + 3 + j - timevary_parm_SR_first + 1); if (do_once == 1) echoinput << j << " timevary_parm: " << timevary_parm(timevary_parm_cnt_all) << endl; } diff --git a/SS_write.tpl b/SS_write.tpl index a3664db4..1ec1a4b6 100644 --- a/SS_write.tpl +++ b/SS_write.tpl @@ -125,7 +125,7 @@ FUNCTION void write_summaryoutput() for (j = 1; j <= N_parm_dev; j++) report2 << parm_dev(j) << " "; } - report2 << SR_parm << " "; + report2 << SRparm << " "; if (recdev_cycle > 0) report2 << recdev_cycle_parm << " "; if (recdev_do_early > 0) @@ -180,14 +180,14 @@ FUNCTION void write_summaryoutput() } } - report2 << runnumber << " SR_parm "; + report2 << runnumber << " SRparm "; for (i = 1; i <= N_SRparm3 + recdev_cycle; i++) { NP++; report2 << " " << ParmLabel(NP); } report2 << endl - << runnumber << " SR_parm " << SR_parm << " "; + << runnumber << " SRparm " << SRparm << " "; if (recdev_cycle > 0) report2 << recdev_cycle_parm; report2 << endl; @@ -453,8 +453,8 @@ FUNCTION void write_SS_summary() for (j = 1; j <= N_SRparm3; j++) { NP++; - SS_smry << ParmLabel(NP) << " " << SR_parm(j) << " "; - if (active(SR_parm(j))) + SS_smry << ParmLabel(NP) << " " << SRparm(j) << " "; + if (active(SRparm(j))) { active_count++; SS_smry << CoVar(active_count, 1) << " Act "; @@ -463,7 +463,7 @@ FUNCTION void write_SS_summary() { SS_smry << 0.0 << " Fix "; } - SS_smry << (SR_parm(j) - SR_parm_LO(j)) / (SR_parm_HI(j) - SR_parm_LO(j) + 1.0e-6) << endl; + SS_smry << (SRparm(j) - SRparm_LO(j)) / (SRparm_HI(j) - SRparm_LO(j) + 1.0e-6) << endl; } if (recdev_cycle > 0) @@ -989,7 +989,7 @@ FUNCTION void write_rebuilder_output() rebuilder << SSB_yr(styr - 2) << " " << SSB_yr(styr, k) << " #SpawnBio" << endl; //i. steepness; SigmaR; rho - rebuilder << SR_parm(2) << " " << sigmaR << " " << SR_parm(N_SRparm2) << " # spawn-recr steepness, sigmaR, autocorr" << endl; + rebuilder << SRparm(2) << " " << sigmaR << " " << SRparm(N_SRparm2) << " # spawn-recr steepness, sigmaR, autocorr" << endl; if (mceval_counter == 0) { @@ -1042,7 +1042,7 @@ FUNCTION void write_rebuilder_output() rebuild_dat << "# Which probability to product detailed results for (1=0.5; 2=0.6; etc.)" << endl << 3 << endl; rebuild_dat << "# Steepness sigma-R Auto-correlation" << endl - << SR_parm(2) << " " << sigmaR << " " << 0 << endl; + << SRparm(2) << " " << sigmaR << " " << 0 << endl; rebuild_dat << "# Target SPR rate (FMSY Proxy); manually change to SPR_MSY if not using SPR_target" << endl << SPR_target << endl; rebuild_dat << "# Discount rate (for cumulative catch)" << endl diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 655a4ca2..b5eba96f 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -647,12 +647,12 @@ FUNCTION void write_bigoutput() { NP++; Activ = 0; - if (active(SR_parm(j))) + if (active(SRparm(j))) { active_count++; Activ = 1; } - Report_Parm(NP, active_count, Activ, SR_parm(j), SR_parm_LO(j), SR_parm_HI(j), SR_parm_RD(j), SR_parm_use(j), SR_parm_PR(j), SR_parm_CV(j), SR_parm_PRtype(j), SR_parm_PH(j), SR_parm_Like(j)); + Report_Parm(NP, active_count, Activ, SRparm(j), SRparm_LO(j), SRparm_HI(j), SRparm_RD(j), SRparm_use(j), SRparm_PR(j), SRparm_CV(j), SRparm_PRtype(j), SRparm_PH(j), SRparm_Like(j)); } if (recdev_cycle > 0) @@ -1778,12 +1778,12 @@ FUNCTION void write_bigoutput() Durbin /= (var + 1.0e-09); var /= (n_rmse(1) + 1.0e-09); - dvariable steepness = SR_parm(2); + dvariable steepness = SRparm(2); SS2out << endl << pick_report_name(19); SS2out << " Function: " << SR_fxn << " RecDev_method: " << do_recdev << " sum_recdev: " << sum_recdev << endl - << SR_parm(1) << " Ln(R0) " << mfexp(SR_parm(1)) << endl + << SRparm(1) << " Ln(R0) " << mfexp(SRparm(1)) << endl << steepness << " steepness" << endl << Bmsy / SSB_virgin << " Bmsy/Bzero "; if (SR_fxn == 8) @@ -1791,22 +1791,22 @@ FUNCTION void write_bigoutput() dvariable Shepherd_c; dvariable Shepherd_c2; dvariable Hupper; - Shepherd_c = SR_parm(3); + Shepherd_c = SRparm(3); Shepherd_c2 = pow(0.2, Shepherd_c); Hupper = 1.0 / (5.0 * Shepherd_c2); - temp = 0.2 + (SR_parm(2) - 0.2) / (0.8) * (Hupper - 0.2); + temp = 0.2 + (SRparm(2) - 0.2) / (0.8) * (Hupper - 0.2); SS2out << " Shepherd_c: " << Shepherd_c << " steepness_limit: " << Hupper << " Adjusted_steepness: " << temp; } else if (SR_fxn == 9) { - SS2out << " Ricker_Power: " << SR_parm(3); + SS2out << " Ricker_Power: " << SRparm(3); } SS2out << endl; SS2out << sigmaR << " sigmaR" << endl; SS2out << init_equ_steepness << " # 0/1 to use steepness in initial equ recruitment calculation" << endl; - SS2out << SR_parm(N_SRparm2 - 1) << " init_eq: see below" << endl + SS2out << SRparm(N_SRparm2 - 1) << " init_eq: see below" << endl << recdev_start << " " << recdev_end << " main_recdev:start_end" << endl << recdev_adj(1) << " " << recdev_adj(2, 5) << " breakpoints_for_bias_adjustment_ramp " << endl; @@ -1842,10 +1842,10 @@ FUNCTION void write_bigoutput() SS2out << "#" << endl << "parm parm_label value phase" << endl; for (int j = 1; j <=N_SRparm2; j++) { - SS2out << j << " " << ParmLabel(firstSRparm + j) << " " << SR_parm(j) << " " << SR_parm_PH(j); - if (SR_parm_timevary(j) > 0 && j <= 4 ) // timevary SRparm exists + SS2out << j << " " << ParmLabel(firstSRparm + j) << " " << SRparm(j) << " " << SRparm_PH(j); + if (SRparm_timevary(j) > 0 && j <= 4 ) // timevary SRparm exists {SS2out << " #_is_time_vary,_so_SRR_updates_base_SPR_annually";} - if (j == (N_SRparm2 - 1) && SR_parm_timevary(j) > 0) // timevary regime exists + if (j == (N_SRparm2 - 1) && SRparm_timevary(j) > 0) // timevary regime exists {SS2out << " #_Regime_parameter_used_to_offset_from_SRR";} SS2out << endl; } @@ -1860,7 +1860,7 @@ FUNCTION void write_bigoutput() { alpha = 4.0 * steepness / (SSBpR_virgin * (1. - steepness)); beta = (5.0 * steepness - 1.0) / ((1. - steepness) * SSB_virgin); - SS2out << "Ln(R0): " << SR_parm(1) << endl << "R0: " << mfexp(SR_parm(1)) << endl; + SS2out << "Ln(R0): " << SRparm(1) << endl << "R0: " << mfexp(SRparm(1)) << endl; SS2out << "steepness: " << steepness << endl; SS2out << "Ln(alpha)_derived: " << log(alpha) << " alpha " << alpha << endl; SS2out << "Ln(beta)_derived: " << log(beta) << " beta " << beta; @@ -1868,8 +1868,8 @@ FUNCTION void write_bigoutput() } case 10: // Beverton-Holt with alpha, beta { - SS2out << "Ln(alpha): " << SR_parm(3) << " alpha " << mfexp(SR_parm(3)) << endl; - SS2out << "Ln(beta): " << SR_parm(4) << " beta " << mfexp(SR_parm(4)) << endl; + SS2out << "Ln(alpha): " << SRparm(3) << " alpha " << mfexp(SRparm(3)) << endl; + SS2out << "Ln(beta): " << SRparm(4) << " beta " << mfexp(SRparm(4)) << endl; SS2out << "ln(R0)_derived: " << log( 1. / beta * (alpha - (1. / SSBpR_virgin))) << endl; // virgin R0 SS2out << "steepness_derived: " << alpha * SSBpR_virgin / (4. + alpha * SSBpR_virgin) << endl; // steepness virgin break; @@ -1879,10 +1879,10 @@ FUNCTION void write_bigoutput() dvariable Shepherd_c; dvariable Shepherd_c2; dvariable Hupper; - Shepherd_c = SR_parm(3); + Shepherd_c = SRparm(3); Shepherd_c2 = pow(0.2, Shepherd_c); Hupper = 1.0 / (5.0 * Shepherd_c2); - temp = 0.2 + (SR_parm(2) - 0.2) / (0.8) * (Hupper - 0.2); + temp = 0.2 + (SRparm(2) - 0.2) / (0.8) * (Hupper - 0.2); SS2out << "Shepherd_c: " << Shepherd_c << endl << "Shepard_steepness_limit: " << Hupper << endl << "Shepard_adjusted_steepness: " << temp << endl; break; } @@ -2006,7 +2006,7 @@ FUNCTION void write_bigoutput() } else {SS2out << " - - ";} - SS2out << SR_parm_byyr(y)(1,N_SRparm2) << endl; + SS2out << SRparm_byyr(y)(1,N_SRparm2) << endl; } // REPORT_KEYWORD SPAWN_RECR_CURVE @@ -2017,7 +2017,7 @@ FUNCTION void write_bigoutput() << pick_report_name(20) << endl; SS2out << "SSB/SSB_virgin SSB Recruitment" << endl; y = styr; - SR_parm_work = SR_parm_byyr(styr); + SRparm_work = SRparm_byyr(styr); for (f = 1; f <= 120; f++) { SSB_current = double(f) / 100. * SSB_virgin; @@ -4905,7 +4905,7 @@ FUNCTION void SPR_profile() SSBpR_Calc(equ_Recr); // SPAWN-RECR: calc equil spawn-recr in the SPR loop SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SR_parm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt_prof = Equ_SpawnRecr_Result(1); Btgt_prof_rec = Equ_SpawnRecr_Result(2); if (Btgt_prof < 0.001 || Btgt_prof_rec < 0.001) diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 1a134ca6..0dd77741 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -2146,11 +2146,11 @@ FUNCTION void write_nucontrol() for (f = 1; f <= N_SRparm2; f++) { NP++; - SR_parm_1(f, 3) = value(SR_parm(f)); + SRparm_1(f, 3) = value(SRparm(f)); for (j = 1; j <= 6; j++) - report4 << setw(14) << SR_parm_1(f, j); + report4 << setw(14) << SRparm_1(f, j); for (j = 7; j <= 14; j++) - report4 << setw(11) << SR_parm_1(f, j); + report4 << setw(11) << SRparm_1(f, j); report4 << " # " << ParmLabel(NP) << endl; } report4.unsetf(std::ios_base::fixed); @@ -2158,7 +2158,7 @@ FUNCTION void write_nucontrol() if (N_SRparm3 > N_SRparm2) { report4 << "# timevary SR parameters" << endl; - for (f = timevary_parm_start_SR; f <= timevary_parm_cnt_SR; f++) + for (f = timevary_parm_SR_first; f <= timevary_parm_SR_last; f++) { NP++; timevary_parm_rd[f](3) = value(timevary_parm(f)); From a101320bf26511b74ccbe9ea82d3673178821c54 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Thu, 3 Apr 2025 15:46:19 -0700 Subject: [PATCH 35/58] timevary_SRparm_controls_working --- SS_benchfore.tpl | 103 ++++++++++++++++++++++++++--------------- SS_param.tpl | 1 + SS_popdyn.tpl | 59 +++++++++++++++-------- SS_readcontrol_330.tpl | 12 ++++- 4 files changed, 117 insertions(+), 58 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index d2f202c8..957081c0 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -747,6 +747,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SRparm_work(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); } } + SRparm_bench = SRparm_work; /* Early thoughts: @@ -2706,33 +2707,47 @@ FUNCTION void Get_Forecast() SSB_yr(y) = SSB_current; } } - // SPAWN-RECR: get recruitment in forecast; needs to be area-specific - // SR_fxn - if (timevary_parm_SR_first == 0) // R0 is not time-varying - { - R0_use = Recr_virgin; - SSB_use = SSB_virgin; - } - else - { - R0_use = mfexp(SRparm_work(1)); - equ_Recr = R0_use; - Fishon = 0; - eq_yr = y; - bio_yr = y; - SSBpR_Calc(R0_use); // call function to do per recruit calculation - // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R + // SPAWN-RECR: get recruitment in at beginning of a season in forecast; + if (timevary_SRparm(y) == 0) // SRparm use virgin values (but regime still could be) + { + R0_use = Recr_virgin; + SSB_use = SSB_virgin; + warning << y << " virgin_SRR; SSB_use: "< 0) diff --git a/SS_param.tpl b/SS_param.tpl index ed0dc25f..2409c944 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -162,6 +162,7 @@ PARAMETER_SECTION matrix SRparm_byyr(styr-3,YrMax,1,N_SRparm2+1) // R0, steepness, parm3, sigmar, rec_dev_offset, R1, rho, SSB Time_vary implementation of spawner-recruitment vector SRparm_virg(1,N_SRparm2+1) vector SRparm_work(1,N_SRparm2+1) + vector SRparm_bench(1,N_SRparm2+1) number two_sigmaRsq; number half_sigmaRsq; number sigmaR; diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 35a426ef..25f67d93 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -1022,29 +1022,32 @@ FUNCTION void get_time_series() } // SS_Label_Info_24.2.3 #Get the total recruitment produced by this spawning biomass at the beginning of the season - // SPAWN-RECR: calc recruitment in time series; need to make this area-specific - // SR_Fxn relevant keyword - if (timevary_parm_SR_first == 0 || timevary_SRparm(y) == 0) // SRparm are not time-varying (but regime still could be) + // SPAWN-RECR: calc recruitment in time series + if (timevary_SRparm(y) == 0) // SRparm use virgin values (but regime still could be) { R0_use = Recr_virgin; SSB_use = SSB_virgin; - warning << y << " virgin "< 0) + else if (timevary_SRparm(y) == 1) // update R0_use and SSB_use in this year + // values will carry forward into subsequent years { - R0_use = mfexp(SRparm_work(1)); // check to be sure this works when R0 is derived from B-H with alpha, beta parameters + R0_use = mfexp(SRparm_work(1)); + // timevary steepness is in SRparm_work(2) and will be applied inside of Equil_Spawn_Recr_Fxn() and Spawn_Recr() + equ_Recr = R0_use; Fishon = 0; eq_yr = y; bio_yr = y; - SSBpR_Calc(R0_use); // call function to do per recruit calculation + SSBpR_Calc(R0_use); // call function to do per recruit calculation with current year's biology and adjusted R0 SSB_use = SSB_equil; - // should call equil_spawn_recr_fxn here to get updated equilibrium with the new SSB/R + warning << y << " update_SRR; SSB_use: "< 0 && j != N_SRparm2 - 1) timevary_SRparm(y , YrMax) = timevary_pass(y); // set timevary flag, except for regime parameter + if (timevary_pass(y) > 0 && j != N_SRparm2 - 1) + { + timevary_SRparm(y) = timevary_pass(y); // set timevary flag, except for regime parameter + SRflag = 1; // first change point + } + else if(SRflag == 1) + { + timevary_SRparm(y) = 2; // flag to carry forward current SRR info + } } } } From bf0931bc87faa4597bf39a86e56cf891149c30b8 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 4 Apr 2025 15:36:51 -0700 Subject: [PATCH 36/58] start cleanup reporting to Spawn_Recr table --- SS_benchfore.tpl | 62 +++++++++++------------ SS_popdyn.tpl | 16 +----- SS_prelim.tpl | 9 ++-- SS_readcontrol_330.tpl | 17 ++++--- SS_recruit.tpl | 2 +- SS_timevaryparm.tpl | 2 +- SS_write_report.tpl | 110 ++++++++++++++++++++++++++++++++--------- SS_write_ssnew.tpl | 2 +- 8 files changed, 132 insertions(+), 88 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 957081c0..84b7c961 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -735,7 +735,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { if (SRparm_timevary(j) == 0) { - SRparm_work(j) = SRparm(j); + SRparm_bench(j) = SRparm(j); } else { @@ -744,7 +744,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { temp += SRparm_byyr(y, j); } - SRparm_work(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); + SRparm_bench(j) = temp / (Bmark_Yr(10) - Bmark_Yr(9) + 1.); } } SRparm_bench = SRparm_work; @@ -757,7 +757,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Flags: timevary_MG_firstyr == YrMax // means that no biology is time-varying - timevary_parm_SR_first > 0 // means that R0 or h (i.e. any except regime, sigmaR, autocorr) is time-varying, so SSBpR0 gets updated for time series and for bench + timevary_SRparm_first > 0 // means that R0 or h (i.e. any except regime, sigmaR, autocorr) is time-varying, so SSBpR0 gets updated for time series and for bench timevary_bio_4SRR is new user selected flag: 0 for legacy, vs 1 for improved use of timevary biology in SRR calcs Legacy approach: @@ -776,13 +776,13 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Improved approach SSBpR0 set at start year using start year biology SSBpR0 updated during time series if there is time-varying R0; PLUS NEW: equil_spawn_recr_calc called to get new equilibrium R0, SSB0 - SSBpR0 for benchmark stays at virgin unless timevary_bio_4SRR == 0, or if timevary_parm_SR_first > 0 + SSBpR0 for benchmark stays at virgin unless timevary_bio_4SRR == 0, or if timevary_SRparm_first > 0 Btgttgt can now use either frac*SSB_bench or frac*SSB_virgin by using the existing flag for depletion basis Btgttgt2 can be fraction of SSB_MSY, of SSB_virgin, or of SSB_bench HCR inflection adds option to use SSB_virgin or SSB_bench depletion adds option to use SSB_bench */ - Recr_unf = mfexp(SRparm_work(1)); // R0 to be used + Recr_unf = mfexp(SRparm_bench(1)); // R0 to be used Fishon = 0; SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology dvariable SSBpR_bench = SSB_equil / Recr_unf; @@ -793,7 +793,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { SSB0_4_SRR = SSB_virgin; R0_4_SRR = Recr_virgin; - SSB_unf = SSB_equil; // should this also depend on timevary_parm_SR_first > 0??? + SSB_unf = SSB_equil; // should this also depend on timevary_SRparm_first > 0??? } else // there is some timevary biology (with any WTage_rd == 1 qualifying as timevarying without actually chacking for different values in diff years) { @@ -801,7 +801,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { warnstream << "There is timevary biology and the legacy approach to benchmark calculations is being used; user should be aware"; write_message (WARN, 0); - if(timevary_parm_SR_first == 0) // no timevary SRR parms + if(timevary_SRparm_first == 0) // no timevary SRR parms { SSB_unf = SSB_equil; R0_4_SRR = Recr_unf; // same as Recr_virgin because no timevary SRparms @@ -810,25 +810,25 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } else // there are timevary SRR parms { - Recr_unf = mfexp(SRparm_work(1)); // R0 to be used - // steepness and other SR parms will also come from SRparm_work + Recr_unf = mfexp(SRparm_bench(1)); // R0 to be used + // steepness and other SR parms will also come from SRparm_bench SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSB_unf = SSB_equil; R0_4_SRR = Recr_unf; SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR SSBpR_bench = SSB0_4_SRR / R0_4_SRR; } - report5 << " legacy: Recr: " << R0_4_SRR << " SSB: " << SSB0_4_SRR << " bench SPR: " << SSBpR_bench << endl; + if (show_MSY == 1) report5 << " legacy: Recr: " << R0_4_SRR << " SSB: " << SSB0_4_SRR << " bench SPR: " << SSBpR_bench << endl; } else // more complete approach to time vary biology will be used (introduced in 3.30.24) { - if(timevary_parm_SR_first == 0) // no timevary SRR parms, so SRR will use SSB_virgin, Recr_virgin to internally create virgin SSBpR0 + if(timevary_SRparm_first == 0) // no timevary SRR parms, so SRR will use SSB_virgin, Recr_virgin to internally create virgin SSBpR0 { SSB0_4_SRR = SSB_virgin; R0_4_SRR = Recr_virgin; // get new equilibrium point using original SRR and SSBpR_bench - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB_virgin, Recr_virgin, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB_virgin, Recr_virgin, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR SSB_unf = Equ_SpawnRecr_Result(1); Recr_unf = Equ_SpawnRecr_Result(2); if (show_MSY == 1) report5 << " use virgin SSBpR0 in SRR - SSB: " << SSB_virgin << " Recr: " << Recr_virgin << " SPR: " << SSB_virgin / Recr_virgin << " bench SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; @@ -836,7 +836,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) else // use updated SRparms and benchmark biology { // get new equilibrium point for the benchmark SRR - Recr_unf = mfexp(SRparm_work(1)); // R0 to be used + Recr_unf = mfexp(SRparm_bench(1)); // R0 to be used Fishon = 0; SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSBpR_bench = SSB_equil / Recr_unf; @@ -844,7 +844,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSB_unf = SSB_equil; R0_4_SRR = Recr_unf; // verify - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR if (show_MSY == 1) report5 << " use bench SSBpR0 in SRR - SSB: " << SSB_unf << " Recr: " << Recr_unf << " SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; } SSBpR_Calc(Recr_unf); // this calcs SSBpR and returns it as SSB_equil using benchmark biology and the updated equil Recr @@ -854,12 +854,12 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (show_MSY == 1) { - SRparm_work(N_SRparm2 + 1) = SSB0_4_SRR; + SRparm_bench(N_SRparm2 + 1) = SSB0_4_SRR; Mgmt_quant(1) = SSB_unf; Mgmt_quant(2) = totbio; // this is calculated in Do_Equil_Calc Mgmt_quant(3) = smrybio; Mgmt_quant(4) = Recr_unf; - report5 << "SRparms for benchmark: " << SRparm_work << endl + report5 << "SRparms for benchmark: " << SRparm_bench << endl << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << endl; Mgmt_quant(19) = SSB_unf; // placeholder for depletion denominator Mgmt_quant(20) = SSB_unf; // placeholder to be replaced by SSB_HCR_infl @@ -1011,7 +1011,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc equil spawn-recr in YPR; need to make this area-specific SSBpR_temp = SSB_equil; // based on most recent call to Do_Equil_Calc - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bspr = Equ_SpawnRecr_Result(1); Bspr_rec = Equ_SpawnRecr_Result(2); @@ -1126,7 +1126,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (rundetail > 0 && mceval_counter == 0 && show_MSY == 1) echoinput << "Calculated F0.1: " << Btgt_Fmult << endl; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt = Equ_SpawnRecr_Result(1); Btgt_Rec = Equ_SpawnRecr_Result(2); YPR_Btgt_enc = YPR_enc; // total encountered yield per recruit @@ -1227,7 +1227,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSBpR_temp = SSB_equil; SPR_Btgt = SSBpR_temp / SSBpR_unf; // where SSBpR_unf = SSB_unf / Recr_unf so units of SSB/R; so result is SPR_Btgt = (fished SSB/R) / (unfished SSB/R) // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1403,7 +1403,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } if (F_Method == 1) { - Fmax = (Btgt_Fmult + SPR_Fmult) * 0.5 * SRparm_work(2) / 0.05; + Fmax = (Btgt_Fmult + SPR_Fmult) * 0.5 * SRparm_bench(2) / 0.05; } // previously /0.18 F1(1) = -log(Fmax / Btgt_Fmult - 1.); F2(1) = -log(Fmax / Btgt_Fmult - 1.); @@ -1447,7 +1447,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SSBpR_unf; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); // with MSY set to SPR, not directly estimated Recr_msy = Equ_SpawnRecr_Result(2); yld1(1) = YPR_opt * Recr_msy; @@ -1541,7 +1541,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) // SPAWN-RECR: calc spawn-recr for MSY calcs; need to make area-specific MSY_SPR = SSB_equil / SSBpR_unf; SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Bmsy = Equ_SpawnRecr_Result(1); // MSY is directly estimated Recr_msy = Equ_SpawnRecr_Result(2); Profit = (PricePerF * YPR_val_vec) * Recr_msy - Cost; @@ -1842,7 +1842,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SPR_Btgt2 = SSB_equil / SSBpR_unf; // SPAWN-RECR: calc equil spawn-recr for Btarget calcs; need to make area-specific SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR yld1(ii) = Equ_SpawnRecr_Result(1); } @@ -1925,8 +1925,8 @@ FUNCTION void Get_Benchmarks(const int show_MSY) report5 << "#" << endl << "Management_report" << endl; report5 << "Virgin: Steepness_Recr_SSB " << SRparm(2) << " " << Recr_virgin << " " << SSB_virgin << endl; - report5 << "Bench: Steepness_Recr_SSB " << SRparm_work(2) << " " << R0_4_SRR << " " << SSB0_4_SRR << endl; - report5 << "unf : Steepness_Recr_SSB " << SRparm_work(2) << " " << Recr_unf << " " << SSB_unf << endl; + report5 << "Bench: Steepness_Recr_SSB " << SRparm_bench(2) << " " << R0_4_SRR << " " << SSB0_4_SRR << endl; + report5 << "unf : Steepness_Recr_SSB " << SRparm_bench(2) << " " << Recr_unf << " " << SSB_unf << endl; report5 << "#" << endl << "Summary_age: " << Smry_Age << endl; report5 << "#_Bmark_years: beg_bio, end_bio, beg_selex, end_selex, beg_relF, end_relF, beg_recr_dist, end_recr_dist, beg_SRparm, end_SRparm" << endl @@ -2746,7 +2746,7 @@ FUNCTION void Get_Forecast() { warning << y << " carry_SRR; SSB_use: "< 0) - recdev_early.initialize(); - if (Do_Forecast > 0 && do_recdev != 0) - Fcast_recruitments.initialize(); - if (Do_Impl_Error > 0) - Fcast_impl_error.initialize(); + if (recdev_do_early > 0) recdev_early.initialize(); + if (Do_Forecast > 0 && do_recdev != 0) Fcast_recruitments.initialize(); + if (Do_Impl_Error > 0) Fcast_impl_error.initialize(); if (do_recdev == 1) { diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index fb2d948a..19c5c5be 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -52,6 +52,7 @@ init_int WTage_rd // 0 means do not read wtatage.ss; 1 means read and use wtatage.ss and also read and use growth parameters // future option 2 will suppress reading and use of growth !!echoinput< 0) timevary_MG_firstyr = styr; init_int N_GP // number of growth patterns (morphs) !!echoinput< 0) + if (timevary_SRparm_first > 0) { timevary_parm_SR_last = timevary_parm_cnt; if (timevary_used == 1) autogen_timevary(2) = 1; // indicate that some parameter is time-varying - N_SRparm3 += (timevary_parm_SR_last - timevary_parm_SR_first + 1); - echoinput << " SR timevary_parm_cnt start and end " << timevary_parm_SR_first << " " << timevary_parm_SR_last << endl; + N_SRparm3 += (timevary_parm_SR_last - timevary_SRparm_first + 1); + echoinput << " SR timevary_parm_cnt start and end " << timevary_SRparm_first << " " << timevary_parm_SR_last << endl; echoinput << "link to timevary parms: " << SRparm_timevary << endl; } echoinput << "SR_Npar and N_SRparm2 and N_SRparm3: " << N_SRparm(SR_fxn) << " " << N_SRparm2 << " " << N_SRparm3 << endl; @@ -2184,10 +2185,10 @@ SRparm_PRtype(i) = SRparm_1(i, 6); SRparm_PH(i) = SRparm_1(i, 7); } - if (timevary_parm_SR_first > 0) + if (timevary_SRparm_first > 0) { j = N_SRparm2; - for (f = timevary_parm_SR_first; f <= timevary_parm_SR_last; f++) + for (f = timevary_SRparm_first; f <= timevary_parm_SR_last; f++) { j++; echoinput << f << " " << j << " " << timevary_parm_rd[f] << endl; diff --git a/SS_recruit.tpl b/SS_recruit.tpl index 93263b20..eaf4c980 100644 --- a/SS_recruit.tpl +++ b/SS_recruit.tpl @@ -6,7 +6,7 @@ //******************************************************************** /* SS_Label_FUNCTION 43 Spawner-recruitment function */ // SPAWN-RECR: function: to calc R from S -FUNCTION dvariable Spawn_Recr(const prevariable& SSB_virgin_use, const prevariable& Recr_virgin_use, const prevariable& SSB_current) +FUNCTION dvariable Spawn_Recr(const dvar_vector& SRparm_work, const prevariable& SSB_virgin_use, const prevariable& Recr_virgin_use, const prevariable& SSB_current) { RETURN_ARRAYS_INCREMENT(); dvariable NewRecruits; diff --git a/SS_timevaryparm.tpl b/SS_timevaryparm.tpl index b4f6b1d1..86259979 100644 --- a/SS_timevaryparm.tpl +++ b/SS_timevaryparm.tpl @@ -60,7 +60,7 @@ FUNCTION void make_timevaryparm() for (j = timevary_setup(3); j < timevary_def[tvary + 1](3); j++) { timevary_parm_cnt_all++; - timevary_parm(timevary_parm_cnt_all) = SRparm(N_SRparm(SR_fxn) + 3 + j - timevary_parm_SR_first + 1); + timevary_parm(timevary_parm_cnt_all) = SRparm(N_SRparm(SR_fxn) + 3 + j - timevary_SRparm_first + 1); if (do_once == 1) echoinput << j << " timevary_parm: " << timevary_parm(timevary_parm_cnt_all) << endl; } diff --git a/SS_write_report.tpl b/SS_write_report.tpl index b5eba96f..8b5d9e2b 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -1779,7 +1779,6 @@ FUNCTION void write_bigoutput() var /= (n_rmse(1) + 1.0e-09); dvariable steepness = SRparm(2); - SS2out << endl << pick_report_name(19); SS2out << " Function: " << SR_fxn << " RecDev_method: " << do_recdev << " sum_recdev: " << sum_recdev << endl @@ -1836,23 +1835,99 @@ FUNCTION void write_bigoutput() } SS2out << endl; + SS2out << "Yr SpawnBio exp_recr with_regime bias_adjusted pred_recr dev biasadjuster era mature_bio mature_num raw_dev" << endl; + SS2out << "S/Rcurve " << SSB_virgin << " " << Recr_virgin << endl; + y = styr - 2; + SS2out << "Virg " << SSB_yr(y) << " " << exp_rec(y) << " - " << 0.0 << " Virg " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " 0.0 " << endl; + y = styr - 1; + SS2out << "Init " << SSB_yr(y) << " " << exp_rec(y) << " - " << 0.0 << " Init " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " " << 0.0 << endl; + + if (recdev_first < styr) + { + for (y = recdev_first; y <= styr - 1; y++) + { + SS2out << y << " " << SSB_yr(styr - 1) << " " << exp_rec(styr - 1, 1) << " " << exp_rec(styr - 1, 2) << " " << exp_rec(styr - 1, 3) * mfexp(-biasadj(y) * half_sigmaRsq) << " " << exp_rec(styr - 1, 3) * mfexp(recdev(y) - biasadj(y) * half_sigmaRsq) << " " + << recdev(y) << " " << biasadj(y) << " Init_age " << SSB_B_yr(styr - 1) << " " << SSB_N_yr(styr - 1) << " " << recdev(y) << endl; // newdev approach uses devs for initial agecomp directly + } + } + for (y = styr; y <= YrMax; y++) + { + SS2out << y << " " << SSB_yr(y) << " " << exp_rec(y) << " "; + if (recdev_do_early > 0 && y >= recdev_early_start && y <= recdev_early_end) + { + SS2out << log(exp_rec(y, 4) / exp_rec(y, 3)) << " " << biasadj(y) << " Early " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " " << recdev(y); + } + else if (y >= recdev_start && y <= recdev_end) + { + SS2out << log(exp_rec(y, 4) / exp_rec(y, 3)) << " " << biasadj(y) << " Main " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " " << recdev(y); + } + else if (Do_Forecast > 0 && y > recdev_end) + { + SS2out << log(exp_rec(y, 4) / exp_rec(y, 3)) << " " << biasadj(y); + if (y <= endyr) + { + SS2out << " Late "; + } + else + { + SS2out << " Fore "; + } + SS2out << SSB_B_yr(y) << " " << SSB_N_yr(y) << " "; + if (do_recdev > 0) + { + SS2out << Fcast_recruitments(y); + } + else + { + SS2out << " 0.0"; + } + } + else + { + SS2out << " _ _ Fixed"; + } + SS2out << endl; + } + SS2out << endl << "#New_Expanded_Spawn_Recr_report" << endl << pick_report_name(19) << endl; - SS2out << "SR_Function: " << SR_fxn << endl; - SS2out << "N_SRparms: " << N_SRparm2 << endl; - SS2out << "#" << endl << "parm parm_label value phase" << endl; + SS2out << SR_fxn << " # SR_Function" << endl; + SS2out << N_SRparm2 << " # N_SRparms" << endl; + + SS2out << "# " < 0 && j <= 4 ) // timevary SRparm exists - {SS2out << " #_is_time_vary,_so_SRR_updates_base_SPR_annually";} + {SS2out << " #_TV";} if (j == (N_SRparm2 - 1) && SRparm_timevary(j) > 0) // timevary regime exists - {SS2out << " #_Regime_parameter_used_to_offset_from_SRR";} + {SS2out << " #_Regime_used_to_offset_from_SRR";} SS2out << endl; } - SS2out << "# " < Bmark_Yr(k)) + {SS2out << "#_range_of_years_is_averaged,_so_reduces_standard_error_of_result;_do_this_only_when_timevarying_makes_necessary: " << k << " "<< k+1 << endl;} + } + SS2out << "SSBpR0_(virgin): " << SSBpR_virgin << " #_uses_biology_from_start_year: " << styr < Bmark_Yr(k)) - {SS2out << "#_range_of_years_is_averaged,_so_reduces_standard_error_of_result;_do_this_only_when_timevarying_makes_necessary: " << k << " "<< k+1 << endl;} - } - SS2out << "SSBpR_unfished_benchmark: " << Mgmt_quant(1) / Mgmt_quant(4) << " #_based_on_averaging_biology_over_benchmark_year_range " << endl; SS2out << "Bmsy/Bzero: "<< Bmsy / SSB_virgin << " # using styr bio for Bzero" << endl; SS2out << "Bmsy/Bunf: "<< Bmsy / Mgmt_quant(1) << " # using MSY's averaged bio for Bunf" << endl; @@ -2021,7 +2085,7 @@ FUNCTION void write_bigoutput() for (f = 1; f <= 120; f++) { SSB_current = double(f) / 100. * SSB_virgin; - temp = Spawn_Recr(SSB_virgin, Recr_virgin, SSB_current); + temp = Spawn_Recr(SRparm_work, SSB_virgin, Recr_virgin, SSB_current); SS2out << SSB_current / SSB_virgin << " " << SSB_current << " " << temp << endl; } } @@ -4905,7 +4969,7 @@ FUNCTION void SPR_profile() SSBpR_Calc(equ_Recr); // SPAWN-RECR: calc equil spawn-recr in the SPR loop SSBpR_temp = SSB_equil; - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_work, SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench , SSB0_4_SRR, R0_4_SRR, SSBpR_temp); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR Btgt_prof = Equ_SpawnRecr_Result(1); Btgt_prof_rec = Equ_SpawnRecr_Result(2); if (Btgt_prof < 0.001 || Btgt_prof_rec < 0.001) diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 0dd77741..147cf597 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -2158,7 +2158,7 @@ FUNCTION void write_nucontrol() if (N_SRparm3 > N_SRparm2) { report4 << "# timevary SR parameters" << endl; - for (f = timevary_parm_SR_first; f <= timevary_parm_SR_last; f++) + for (f = timevary_SRparm_first; f <= timevary_parm_SR_last; f++) { NP++; timevary_parm_rd[f](3) = value(timevary_parm(f)); From aa4eab0ca02a58744bf37f43b12ca59b67e00e19 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 25 Apr 2025 11:54:40 -0700 Subject: [PATCH 37/58] add SPR_reporting option 5 updates the descriptions of SPR_reporting and adds option to report raw SPR --- SS_objfunc.tpl | 8 ++++++-- SS_readcontrol_330.tpl | 7 ++++++- SS_readdata_330.tpl | 4 ++-- SS_readstarter.tpl | 2 +- SS_write_ssnew.tpl | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/SS_objfunc.tpl b/SS_objfunc.tpl index c4655bac..7d6315e3 100644 --- a/SS_objfunc.tpl +++ b/SS_objfunc.tpl @@ -1150,7 +1150,7 @@ FUNCTION void Process_STDquant() switch (SPR_reporting) { - case 0: // keep as raw value + case 0: // no scaling. this option skips SPR_reporting { break; } @@ -1170,11 +1170,15 @@ FUNCTION void Process_STDquant() SPR_std = (1. - SPR_std) / (1. - SPR_Btgt); break; } - case 4: + case 4: // 1-%SPR { SPR_std = 1. - SPR_std; break; } + case 5: // raw %SPR + { + break; + } } switch (depletion_basis) diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 19c5c5be..ba7f2694 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -6984,7 +6984,12 @@ switch (SPR_reporting) { - case 0: // keep as raw value + case 0: // skip SPR reporting + { + SPR_report_label += " raw_SPR"; + break; + } + case 5: // keep as raw %SPR value { SPR_report_label += " raw_SPR"; break; diff --git a/SS_readdata_330.tpl b/SS_readdata_330.tpl index 901d92d6..ad64c3b7 100644 --- a/SS_readdata_330.tpl +++ b/SS_readdata_330.tpl @@ -4834,8 +4834,8 @@ } if (SPR_reporting >= 1 && SPR_reporting <= 3) { - SPR_reporting = 4; - warnstream << "Change SPR_reporting to 4 because benchmarks were not requested"; + SPR_reporting = 5; + warnstream << "Change SPR_reporting to 5 (raw %SPR) because benchmarks were not requested"; write_message(WARN, 0); } } diff --git a/SS_readstarter.tpl b/SS_readstarter.tpl index e2ab712f..8143e984 100644 --- a/SS_readstarter.tpl +++ b/SS_readstarter.tpl @@ -669,7 +669,7 @@ init_number depletion_level; !!echoinput << depletion_level << " depletion_level" << endl; - init_int SPR_reporting; // 0=skip; 1=SPR; 2=SPR_MSY; 3=SPR_Btarget; 4=(1-SPR) + init_int SPR_reporting; // 0=skip; 1=SPR; 2=SPR_MSY; 3=SPR_Btarget; 4=(1-SPR); 5=SPR !!echoinput << SPR_reporting << " SPR_reporting" << endl; init_int F_reporting; // 0=skip; 1=exploit(Bio); 2=exploit(Num); 3=sum(frates); 4=true F for range of ages; 5=unweighted avg F for range of ages LOCAL_CALCS diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 147cf597..e1741e0f 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1551,7 +1551,7 @@ FUNCTION void write_nucontrol() NuStart << depletion_basis_rd << " # Depletion basis: denom is: 0=skip; 1=X*SSBvirgin; 2=X*SSBmsy; 3=X*SSB_styr; 4=X*SSB_endyr; 5=X*dyn_Bzero; 6=X*Bmark_SSB_unf; values>=11 invoke N multiyr with 10s & 100s digit; append .1 to invoke log(ratio); e.g. 122.1 produces log(12 yr trailing average of B/Bmsy)" << endl; NuStart << "# If value = 1, then Btarget in benchmark will be a fraction of SSB_virgin, else will be a fraction of SSB_benchmark" << endl; NuStart << depletion_level << " # Fraction (X) for Depletion denominator (e.g. 0.4)" << endl; - NuStart << SPR_reporting << " # SPR_report_basis: 0=skip; 1=(1-SPR)/(1-SPR_tgt); 2=(1-SPR)/(1-SPR_MSY); 3=(1-SPR)/(1-SPR_Btarget); 4=rawSPR" << endl; + NuStart << SPR_reporting << " # SPR_report_basis: 0=skip; 1=(1-SPR)/(1-SPR_tgt); 2=(1-SPR)/(1-SPR_MSY); 3=(1-SPR)/(1-SPR_Btarget); 4=1-SPR; 5=SPR" << endl; NuStart << F_reporting << " # F_std_reporting_units: 0=skip; 1=exploitation(Bio); 2=exploitation(Num); 3=sum(Apical_F's); 4=mean F for range of ages (numbers weighted); 5=unweighted mean F for range of ages" << endl; if (F_reporting == 4 || F_reporting == 5) { From 2beff82ceb38825c51dd875a888219ee37f53ec7 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Fri, 16 May 2025 16:05:51 -0700 Subject: [PATCH 38/58] clean up ss_new and spawn_recr output --- SS_benchfore.tpl | 4 +-- SS_write_report.tpl | 38 ++++++---------------- SS_write_ssnew.tpl | 77 +++++++++++++++++++++++---------------------- 3 files changed, 50 insertions(+), 69 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 84b7c961..9737e283 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -1801,8 +1801,8 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } else { - Btgttgt2 = -Blim_frac * SSB_virgin; - Blim_report = value(SSB_virgin); + Btgttgt2 = -Blim_frac * SSB_unf; + Blim_report = value(SSB_unf); } for (j = 0; j <= Nloops; j++) // loop find Btarget diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 8b5d9e2b..faf51371 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -1891,8 +1891,6 @@ FUNCTION void write_bigoutput() SS2out << endl << "#New_Expanded_Spawn_Recr_report" << endl << pick_report_name(19) << endl; SS2out << SR_fxn << " # SR_Function" << endl; - SS2out << N_SRparm2 << " # N_SRparms" << endl; - SS2out << "# " < Bmark_Yr(k)) @@ -1938,7 +1937,7 @@ FUNCTION void write_bigoutput() SS2out << "Ln(R0): " << SRparm(1) << endl << "R0: " << mfexp(SRparm(1)) << endl; SS2out << "steepness: " << steepness << endl; SS2out << "Ln(alpha)_derived: " << log(alpha) << " alpha " << alpha << endl; - SS2out << "Ln(beta)_derived: " << log(beta) << " beta " << beta; + SS2out << "Ln(beta)_derived: " << log(beta) << " beta " << beta << endl; break; } case 10: // Beverton-Holt with alpha, beta @@ -2000,22 +1999,12 @@ FUNCTION void write_bigoutput() } } SS2out << endl << "#" << endl << "Initial_equilibrium: " << init_equ_steepness << " # 0/1_to_use_spawner-recruitment_in_initial_equ_recruitment_calculation" << endl << "#" << endl; - if (SR_fxn == 10) SS2out << "#_Note:_h_curr_and_R0_curr_are_for_info_only;_calculated_from_alpha_beta_and_current_SPR0" << endl; - SS2out << "#_columns_with_P_will_show_time_vary_SR_parameters" << endl << "#" << endl; - SS2out << "Yr SpawnBio exp_recr with_regime bias_adjusted pred_recr dev biasadjuster era mature_bio mature_num raw_dev SPR0_curr "; - if(SR_fxn == 10) - {SS2out << "h_curr R0_curr ";} - else - {SS2out << "NA1 NA2 ";} -; - for (j = 1; j <= N_SRparm2; j++) - {SS2out << "P" << j << " ";} - SS2out << endl; - SS2out << "S/Rcurve " << SSB_virgin << " " << Recr_virgin << endl; + SS2out << "Yr SpawnBio exp_recr with_regime bias_adjusted pred_recr dev biasadjuster era mature_bio mature_num raw_dev SPR0_curr " << endl; + y = styr - 2; - SS2out << "Virg " << SSB_yr(y) << " " << exp_rec(y) << " - " << 0.0 << " Virg " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " 0.0 " << endl; + SS2out << "Virg " << SSB_yr(y) << " " << exp_rec(y) << " - " << 0.0 << " Virg " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " 0.0 " << " " << SSBpR_virgin << endl; y = styr - 1; - SS2out << "Init " << SSB_yr(y) << " " << exp_rec(y) << " - " << 0.0 << " Init " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " " << 0.0 << endl; + SS2out << "Init " << SSB_yr(y) << " " << exp_rec(y) << " - " << 0.0 << " Init " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " " << 0.0 << " " << SSBpR_virgin << endl; if (recdev_first < styr) { @@ -2059,18 +2048,9 @@ FUNCTION void write_bigoutput() } else { - SS2out << " _ _ Fixed"; - } - dvariable SPR_curr = Smry_Table(y, 11) / Recr_virgin; - SS2out << " " << SPR_curr << " "; - if (SR_fxn == 10) - { - SS2out << alpha * SPR_curr / (4. + alpha * SPR_curr) << " "; // steepness with current SPR - SS2out << 1. / beta * (alpha - (1. / SPR_curr)) << " "; // R0 with current SPR + SS2out << " _ _ Fixed " << SSB_B_yr(y) << " " << SSB_N_yr(y) << " _ "; } - else - {SS2out << " - - ";} - SS2out << SRparm_byyr(y)(1,N_SRparm2) << endl; + SS2out << " " << Smry_Table(y, 11) / Recr_virgin << endl; } // REPORT_KEYWORD SPAWN_RECR_CURVE diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index e1741e0f..9b6948f0 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1509,11 +1509,11 @@ FUNCTION void write_nucontrol() << version_info2 << endl; if (N_SC > 0) NuStart << Starter_Comments << endl; - NuStart << datfilename << endl - << ctlfilename << endl; - NuStart << readparfile << " # 0=use init values in control file; 1=use ss.par" << endl; - NuStart << rundetail << " # run display detail (0 = minimal; 1=one line per iter; 2=each logL)" << endl; - NuStart << reportdetail << " # detailed output (0=minimal for data-limited, 1=high (w/ wtatage.ss_new), 2=brief, 3=custom) " << endl; + NuStart << datfilename << " #_datfile" << endl + << ctlfilename << " #_ctlfile" << endl; + NuStart << readparfile << " #_init_values_src: 0 (use init values in control file); 1 (use ss3.par)" << endl; + NuStart << rundetail << " #_screen_display: 0 (minimal); 1 (one line per iter); 2 (each logL)" << endl; + NuStart << reportdetail << " #_report_table_selection: 0 (minimal; no wtatage.ss_new); 1 (all tables); 2 (brief), 3 (custom, read list) " << endl; if (reportdetail == 3) { NuStart << "# custom report options: -100 to start with minimal; -101 to start with all; -number to remove, +number to add, -999 to end" << endl; @@ -1524,35 +1524,36 @@ FUNCTION void write_nucontrol() } else { - NuStart << "#COND: custom report options: -100 to start with minimal; -101 to start with all; -number to remove, +number to add, -999 to end" << endl; + NuStart << "# COND: custom report options: -100 to start with minimal; -101 to start with all; -number to remove, +number to add, -999 to end" << endl; } - NuStart << docheckup << " # write 1st iteration details to echoinput.sso file (0,1) " << endl; - NuStart << Do_ParmTrace << " # write parm values to ParmTrace.sso (0=no,1=good,active; 2=good,all; 3=every_iter,all_parms; 4=every,active)" << endl; - NuStart << Do_CumReport << " # write to cumreport.sso (0=no,1=like×eries; 2=add survey fits)" << endl; - NuStart << Do_all_priors << " # Include prior_like for non-estimated parameters (0,1) " << endl; - NuStart << SoftBound << " # Use Soft Boundaries to aid convergence (0,1) (recommended)" << endl; + NuStart << docheckup << " #_checkup: write more 1st iteration age-specific details to echoinput.sso file (0,1) " << endl; + NuStart << Do_ParmTrace << " #_parmtrace: write parm values to ParmTrace.sso: 0 (no); 1 (good_iter,active_parms); 2 (good,all); 3 (every,all); 4 (every,active)" << endl; + NuStart << Do_CumReport << " #_cumreport: write to cumreport.sso: 0 (no); 1 (like×eries); 2 (add survey fits)" << endl; + NuStart << Do_all_priors << " #_prior_like: include prior_like for non-estimated parameters (0,1) " << endl; + NuStart << SoftBound << " #_soft_bounds: Use Soft Boundaries to aid convergence (0,1) (recommended)" << endl; NuStart << "#" << endl - << N_nudata_read << " # Number of datafiles to produce: 0 turns off all *.ss_new; 1st is data_echo.ss_new, 2nd is data_expval.ss, 3rd and higher are data_boot_**N.ss," << endl; - NuStart << Turn_off_phase_rd << " # Turn off estimation for parameters entering after this phase" << endl; + << N_nudata_read << " #_N_bootstraps: Number of datafiles to produce: 0 turns off all *.ss_new; 1st is data_echo.ss_new, 2nd is data_expval.ss, 3rd and higher are data_boot_**N.ss," << endl; + NuStart << Turn_off_phase_rd << " #_last_estimation_phase: turn off estimation for parameters entering after this phase" << endl; NuStart << "#" << endl - << burn_intvl << " # MCeval burn interval" << endl; - NuStart << thin_intvl << " # MCeval thin interval" << endl; - NuStart << jitter << " # jitter initial parm value by this fraction" << endl; - NuStart << STD_Yr_min_rd << " # min year for sdreport outputs (-1 for styr); #_" << STD_Yr_min << endl; - NuStart << STD_Yr_max_rd << " # max year for sdreport outputs (-1 for endyr+1; -2 for endyr+Nforecastyrs); #_" << STD_Yr_max << endl; - NuStart << N_STD_Yr_RD << " # N individual STD years " << endl; + << burn_intvl << " #_MCMCburn" << endl; + NuStart << thin_intvl << " #_MCMCthin" << endl; + NuStart << jitter << " # jitter_fraction: jitter within parameter bounds" << endl; + + NuStart << STD_Yr_min_rd << " #_minyr_sdreport: min year for sdreport outputs (-1 for styr); #_" << STD_Yr_min << endl; + NuStart << STD_Yr_max_rd << " #_maxyr_sdreport: max year for sdreport outputs (-1 for endyr+1; -2 for endyr+Nforecastyrs); #_" << STD_Yr_max << endl; + NuStart << N_STD_Yr_RD << " #_N_STD_yrs: N individual STD years " << endl; NuStart << "#COND: vector of year values if N>0" << endl << STD_Yr_RD << endl; - NuStart << final_conv << " # final convergence criteria (e.g. 1.0e-04) " << endl; - NuStart << retro_yr - endyr << " # retrospective year relative to end year (e.g. -4)" << endl; - NuStart << Smry_Age << " # min age for calc of summary biomass" << endl; - NuStart << depletion_basis_rd << " # Depletion basis: denom is: 0=skip; 1=X*SSBvirgin; 2=X*SSBmsy; 3=X*SSB_styr; 4=X*SSB_endyr; 5=X*dyn_Bzero; 6=X*Bmark_SSB_unf; values>=11 invoke N multiyr with 10s & 100s digit; append .1 to invoke log(ratio); e.g. 122.1 produces log(12 yr trailing average of B/Bmsy)" << endl; + NuStart << final_conv << " #_converge_criterion: (e.g. 1.0e-04) " << endl; + NuStart << retro_yr - endyr << " #_retro_yr: retrospective year relative to end year (e.g. -4)" << endl; + NuStart << Smry_Age << " #_min_age_summary_bio" << endl; + NuStart << depletion_basis_rd << " #_depl_basis: Depletion denom is: 0=skip; 1=X*SSB_virgin; 2=X*SSB_msy; 3=X*SSB_styr; 4=X*SSB_endyr; 5=X*dyn_Bzero; 6=X*SSB_unf_bmark; values>=11 invoke N multiyr with 10s & 100s digit; append .1 to invoke log(ratio); e.g. 122.1 produces log(12 yr trailing average of B/Bmsy)" << endl; NuStart << "# If value = 1, then Btarget in benchmark will be a fraction of SSB_virgin, else will be a fraction of SSB_benchmark" << endl; - NuStart << depletion_level << " # Fraction (X) for Depletion denominator (e.g. 0.4)" << endl; - NuStart << SPR_reporting << " # SPR_report_basis: 0=skip; 1=(1-SPR)/(1-SPR_tgt); 2=(1-SPR)/(1-SPR_MSY); 3=(1-SPR)/(1-SPR_Btarget); 4=1-SPR; 5=SPR" << endl; - NuStart << F_reporting << " # F_std_reporting_units: 0=skip; 1=exploitation(Bio); 2=exploitation(Num); 3=sum(Apical_F's); 4=mean F for range of ages (numbers weighted); 5=unweighted mean F for range of ages" << endl; + NuStart << depletion_level << " #_depl_denom_frac: fraction (X) for Depletion denominator (e.g. 0.4)" << endl; + NuStart << SPR_reporting << " #_SPR_basis: 0 (skip); 1 (1-SPR)/(1-SPR_tgt); 2 (1-SPR)/(1-SPR_MSY); 3 (1-SPR)/(1-SPR_Btarget); 4 (1-SPR); 5 (SPR)" << endl; + NuStart << F_reporting << " # F_std_units: 0 (skip); 1 (exploitation(Bio)); 2 (exploitation(Num)); 3 (sum(Apical_F's)); 4 (mean F for range of ages (numbers weighted)); 5 (unweighted mean F for range of ages)" << endl; if (F_reporting == 4 || F_reporting == 5) { NuStart << F_reporting_ages << " # min and max age over which mean F will be calculated, with F=Z-M" << endl; @@ -1561,12 +1562,12 @@ FUNCTION void write_nucontrol() { NuStart << "#COND 10 15 #_min and max age over which mean F will be calculated with F_reporting=4 or 5" << endl; } - NuStart << F_std_basis_rd << " # F_std_scaling: 0=no scaling; 1=F/Fspr; 2=F/Fmsy; 3=F/Fbtgt; where F means annual F_std, Fmsy means F_std@msy; values >=11 invoke N multiyr using 10s and 100s digit; append .1 to invoke log(ratio)" << endl; - NuStart << double(mcmc_output_detail) + MCMC_bump << " # MCMC output detail: integer part (0=default; 1=adds obj func components; 2= +write_report_for_each_mceval); and decimal part (added to SR_LN(R0) on first call to mcmc)" << endl; - NuStart << ALK_tolerance << " # ALK tolerance ***disabled in code" << endl; - NuStart << irand_seed_rd << " # random number seed for bootstrap data (-1 to use long(time) as seed): # " << irand_seed << endl; - NuStart << timevary_bio_4SRR << " # Compatibility flag for legacy (0) vs improved (1) impact of timevary biology on benchmark SRR calcs >=3.30.24" << endl; - NuStart << "3.30 # check value for end of file and for version control" << endl; + NuStart << F_std_basis_rd << " # F_std_basis: 0=no scaling; 1 (F/Fspr); 2 (F/Fmsy); 3 (F/Fbtgt); where F means annual F_std, Fmsy means F_std@msy; values >=11 invoke N multiyr using 10s and 100s digit; append .1 to invoke log(ratio)" << endl; + NuStart << double(mcmc_output_detail) + MCMC_bump << " #_MCMC_output_detail: integer part (0=default; 1=adds obj func components; 2= +write_report_for_each_mceval); and decimal part (added to SR_LN(R0) on first call to mcmc)" << endl; + NuStart << ALK_tolerance << " #_deprecated: ALK tolerance ***disabled in code" << endl; + NuStart << irand_seed_rd << " #_seed: random number seed for bootstrap data (-1 to use long(time) as seed): # " << irand_seed << endl; + NuStart << timevary_bio_4SRR << " #_Compatibility: flag for legacy (0) vs improved (1) impact of timevary biology on benchmark SRR calcs >=3.30.24" << endl; + NuStart << "3.30 #_final: check value for end of file and for version control" << endl; NuStart.close(); echoinput << "Write forecast.ss_new file " << endl; @@ -1576,7 +1577,7 @@ FUNCTION void write_nucontrol() if (N_FC > 0) NuFore << Forecast_Comments << endl; NuFore << "# for all year entries except rebuilder; enter either: actual year, -999 for styr, 0 for endyr, neg number for rel. endyr" << endl; - NuFore << Do_Benchmark << " # Benchmarks: 0=skip; 1=calc F_spr,F_btgt,F_msy; 2=calc F_spr,F0.1,F_msy; 3=add F_Blimit; " << endl; + NuFore << Do_Benchmark << " # Benchmarks: 0=skip; 1=calc F_spr,F_Btgt,F_msy; 2=calc F_spr,F0.1,F_msy; 3=add F_Blimit; " << endl; NuFore << Do_MSY << " # Do_MSY: 1= set to F(SPR); 2=calc F(MSY); 3=set to F(Btgt) or F0.1; 4=set to F(endyr); 5=calc F(MEY) with MSY_unit options" << endl; NuFore << "# if Do_MSY=5, enter MSY_Units; then list fleet_ID, cost/F, price/mt, include_in_Fmey_scaling; # -fleet_ID to fill; -9999 to terminate" << endl; if (Do_MSY == 5) @@ -1594,13 +1595,13 @@ FUNCTION void write_nucontrol() NuFore << SPR_target << " # SPR target (e.g. 0.40)" << endl; NuFore << BTGT_target << " # Biomass target (e.g. 0.40) as fraction of SSB_virgin if depletion basis = 1, else as fraction of SSB_unfished in benchmark" << endl; - if (Do_Benchmark == 3) - NuFore << Blim_frac << " # COND: Do_Benchmark==3; Blimit as fraction of Bmsy (neg value to use as frac of Bzero) (e.g. 0.50)" << endl; - NuFore << "#_Bmark_years: beg_bio, end_bio, beg_selex, end_selex, beg_relF, end_relF, beg_recr_dist, end_recr_dist, beg_SRparm, end_SRparm (enter actual year, or values of 0 or -integer to be rel. endyr)" << endl + if (Do_Benchmark != 3) NuFore << "#"; + NuFore << Blim_frac << " # COND: Do_Benchmark==3; Blimit as fraction of Bmsy (neg value to use as frac of SSB_virgin or SSB_unfished) (e.g. 0.50)"; + NuFore << "#" << endl << "# Bmark_years: beg_bio, end_bio, beg_selex, end_selex, beg_relF, end_relF, beg_recr_dist, end_recr_dist, beg_SRparm, end_SRparm (enter actual year, or values of 0 or -integer to be rel. endyr)" << endl << Bmark_Yr_rd << endl << "# " << Bmark_Yr << endl; NuFore << "# value <0 convert to endyr-value; except -999 converts to start_yr; must be >=start_yr and <=endyr" << endl; - NuFore << Bmark_RelF_Basis << " #Bmark_relF_Basis: 1 = use year range; 2 = set relF same as forecast below" << endl; + NuFore << Bmark_RelF_Basis << " # Bmark_relF_Basis: 1 = use year range; 2 = set relF same as forecast below" << endl; NuFore << "#" << endl << Do_Forecast_rd << " # Forecast: -1=none; 0=simple_1yr; 1=F(SPR); 2=F(MSY) 3=F(Btgt) or F0.1; 4=Ave F (uses first-last relF yrs); 5=input annual F scalar" << endl; NuFore << "# where none and simple require no input after this line; simple sets forecast F same as end year F" << endl; @@ -1621,7 +1622,7 @@ FUNCTION void write_nucontrol() } // else { // new list based format for Fcast years - NuFore << anystring << endl << anystring << "-12345 # code to invoke new format for expanded fcast year controls" << endl + NuFore << anystring << endl << anystring << " -12345 # code to invoke new format for expanded fcast year controls" << endl << "# biology and selectivity vectors are updated annually in the forecast according to timevary parameters, so check end year of blocks and dev vectors" << endl << "# input in this section directs creation of means over historical years to override any time_vary changes" << endl << "# Factors implemented so far: 1=M, 4=recr_dist, 5=migration, 10=selectivity, 11=rel_F, 12=recruitment" << endl From 0a5451d3b163e1a9a3398b689af4b6fd2b76132b Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Thu, 22 May 2025 12:14:09 -0700 Subject: [PATCH 39/58] Change approach for invoking Bmsy as the HCR_inflection --- SS_benchfore.tpl | 27 +++++++++++++++++---------- SS_popdyn.tpl | 12 ++++++------ SS_readcontrol_330.tpl | 2 +- SS_readdata_330.tpl | 11 ++++++++--- SS_write_ssnew.tpl | 12 ++++++------ 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 9737e283..e156cb78 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -2264,8 +2264,10 @@ FUNCTION void Get_Forecast() {HCR_anchor = SSB_virgin;} else if (Fcast_Loop_Control(5) == 2) {HCR_anchor = SSB_unf;} + else if (Fcast_Loop_Control(5) == 3) + {HCR_anchor = Bmsy;} // so H4010_top_rd should be 1.0; - if (H4010_top_rd < 0.0) + if (H4010_top_rd < 0.0) // legacy approach. This has already been converted to new approach in readdata { H4010_top = Bmsy / HCR_anchor; // convert to fraction of anchor if (H4010_bot > 0.25) @@ -2278,13 +2280,20 @@ FUNCTION void Get_Forecast() { H4010_top = H4010_top_rd; } + if (Fcast_Loop_Control(5) == 3 && H4010_top_rd != 1.0) + { + warnstream << "HCR_anchor is BMSY; so H4010_top normally is 1.0; are you sure you want: " << H4010_top; + write_message (WARN, 0); + } - Mgmt_quant(20) = HCR_anchor; + Mgmt_quant(20) = H4010_top * HCR_anchor; report5 << "#" << endl; report5 << "N_forecast_yrs: " << N_Fcast_Yrs << endl; report5 << "OY_Control_Rule: Inflection: " << H4010_top << " Intercept: " << H4010_bot << " Scale: " << H4010_scale_vec(endyr + 1) << endl - << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl; - report5 << "#" << endl; + << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl + << "intercept(SSB): " << H4010_bot * HCR_anchor << endl + << "Inflection(SSB): " << H4010_top * HCR_anchor << endl + << "#" << endl; switch (HarvestPolicy) { @@ -2712,7 +2721,6 @@ FUNCTION void Get_Forecast() { R0_use = Recr_virgin; SSB_use = SSB_virgin; - warning << y << " virgin_SRR; SSB_use: "<> H4010_top_rd; // use -1 to set H4010_top to Bmsy/SSB_unf - echoinput << H4010_top_rd << " # echoed control rule inflection (-1 to set to Bmsy/SSB_unf)" << endl; + *(ad_comm::global_datafile) >> H4010_top_rd; // as fraction of HCR_anchor; use -1 as legacy approach to set H4010_top to Bmsy/SSB_unf + echoinput << H4010_top_rd << " # echoed control rule inflection" << endl; *(ad_comm::global_datafile) >> H4010_bot; echoinput << H4010_bot << " # echoed control rule cutoff " << endl; *(ad_comm::global_datafile) >> H4010_scale_rd; @@ -4352,7 +4352,12 @@ write_message(ADJUST, 0); Fcast_Loop_Control(5) = 2; } - echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=virgin_SSB; 2=unfished_benchmark_SSB(old_approach)" << endl; + if (H4010_top_rd < 0) // convert old legacy approach to new approach for using Bmsy + { + Fcast_Loop_Control(5) = 3; + H4010_top_rd = 1.0; + } + echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=virgin_SSB; 2=unfished_benchmark_SSB(old_approach); 3=Bmsy" << endl; if (depletion_basis == 1 && Fcast_Loop_Control(5) == 2) { warnstream << "depletion_basis is using virgin but HCR anchor is using SSB_unf from benchmark. Are you sure?"; diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 9b6948f0..98b0b162 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1643,11 +1643,11 @@ FUNCTION void write_nucontrol() } NuFore << HarvestPolicy << " # Control rule method (0: none; 1: ramp does catch=f(SSB), buffer on F; 2: ramp does F=f(SSB), buffer on F; 3: ramp does catch=f(SSB), buffer on catch; 4: ramp does F=f(SSB), buffer on catch) " << endl; - NuFore << "# values for top, bottom and buffer exist, but not used when Policy=0" << endl; - NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of Bzero, e.g. 0.40); must be > control rule cutoff, or set to -1 to use Bmsy as the inflection " << endl; - NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of Bzero, e.g. 0.10) " << endl; - NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar] with filling from year to YrMax " << endl; - NuFore << "# Also see HCR_anchor below to use virgin vs benchmark SSB as basis" << endl; + NuFore << "# values for top, bottom and buffer required, but not used when Policy=0" << endl; + NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of HCR_anchor, see below); must be > control rule cutoff" << endl; + NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of HCR_anchor, e.g. 0.10) " << endl; + NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar]. -year fills from year to YrMax " << endl; + NuFore << "# Also see HCR_anchor below to use virgin vs benchmark SSB or Bmsy as basis for inflection and cutoff" << endl; if (H4010_scale_rd < 0) { j = H4010_scale_vec_rd.size() - 1; @@ -1669,7 +1669,7 @@ FUNCTION void write_nucontrol() { NuFore << Fcast_Loop_Control(4) << " # multiplier on base recruitment " << endl; } - NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 2 uses unfished benchmark SSB (old hardwired approach); 1 = virgin SSB" << endl << "#" << endl; + NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 2 uses unfished benchmark SSB (old hardwired approach); 1 = virgin SSB; 3 = BMSY" << endl << "#" << endl; NuFore << Fcast_Cap_FirstYear << " # FirstYear for caps and allocations (should be after years with fixed inputs) " << endl; From 9d8330074c6de5aa043c48386c2f351a4d5ecfde Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Tue, 3 Jun 2025 10:28:31 -0700 Subject: [PATCH 40/58] git stash pop --- SS_benchfore.tpl | 27 ++++++++++----------------- SS_popdyn.tpl | 12 ++++++------ SS_readcontrol_330.tpl | 2 +- SS_readdata_330.tpl | 11 +++-------- SS_write_ssnew.tpl | 12 ++++++------ 5 files changed, 26 insertions(+), 38 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index e156cb78..9737e283 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -2264,10 +2264,8 @@ FUNCTION void Get_Forecast() {HCR_anchor = SSB_virgin;} else if (Fcast_Loop_Control(5) == 2) {HCR_anchor = SSB_unf;} - else if (Fcast_Loop_Control(5) == 3) - {HCR_anchor = Bmsy;} // so H4010_top_rd should be 1.0; - if (H4010_top_rd < 0.0) // legacy approach. This has already been converted to new approach in readdata + if (H4010_top_rd < 0.0) { H4010_top = Bmsy / HCR_anchor; // convert to fraction of anchor if (H4010_bot > 0.25) @@ -2280,20 +2278,13 @@ FUNCTION void Get_Forecast() { H4010_top = H4010_top_rd; } - if (Fcast_Loop_Control(5) == 3 && H4010_top_rd != 1.0) - { - warnstream << "HCR_anchor is BMSY; so H4010_top normally is 1.0; are you sure you want: " << H4010_top; - write_message (WARN, 0); - } - Mgmt_quant(20) = H4010_top * HCR_anchor; + Mgmt_quant(20) = HCR_anchor; report5 << "#" << endl; report5 << "N_forecast_yrs: " << N_Fcast_Yrs << endl; report5 << "OY_Control_Rule: Inflection: " << H4010_top << " Intercept: " << H4010_bot << " Scale: " << H4010_scale_vec(endyr + 1) << endl - << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl - << "intercept(SSB): " << H4010_bot * HCR_anchor << endl - << "Inflection(SSB): " << H4010_top * HCR_anchor << endl - << "#" << endl; + << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl; + report5 << "#" << endl; switch (HarvestPolicy) { @@ -2721,6 +2712,7 @@ FUNCTION void Get_Forecast() { R0_use = Recr_virgin; SSB_use = SSB_virgin; + warning << y << " virgin_SRR; SSB_use: "<> H4010_top_rd; // as fraction of HCR_anchor; use -1 as legacy approach to set H4010_top to Bmsy/SSB_unf - echoinput << H4010_top_rd << " # echoed control rule inflection" << endl; + *(ad_comm::global_datafile) >> H4010_top_rd; // use -1 to set H4010_top to Bmsy/SSB_unf + echoinput << H4010_top_rd << " # echoed control rule inflection (-1 to set to Bmsy/SSB_unf)" << endl; *(ad_comm::global_datafile) >> H4010_bot; echoinput << H4010_bot << " # echoed control rule cutoff " << endl; *(ad_comm::global_datafile) >> H4010_scale_rd; @@ -4352,12 +4352,7 @@ write_message(ADJUST, 0); Fcast_Loop_Control(5) = 2; } - if (H4010_top_rd < 0) // convert old legacy approach to new approach for using Bmsy - { - Fcast_Loop_Control(5) = 3; - H4010_top_rd = 1.0; - } - echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=virgin_SSB; 2=unfished_benchmark_SSB(old_approach); 3=Bmsy" << endl; + echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=virgin_SSB; 2=unfished_benchmark_SSB(old_approach)" << endl; if (depletion_basis == 1 && Fcast_Loop_Control(5) == 2) { warnstream << "depletion_basis is using virgin but HCR anchor is using SSB_unf from benchmark. Are you sure?"; diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 98b0b162..9b6948f0 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1643,11 +1643,11 @@ FUNCTION void write_nucontrol() } NuFore << HarvestPolicy << " # Control rule method (0: none; 1: ramp does catch=f(SSB), buffer on F; 2: ramp does F=f(SSB), buffer on F; 3: ramp does catch=f(SSB), buffer on catch; 4: ramp does F=f(SSB), buffer on catch) " << endl; - NuFore << "# values for top, bottom and buffer required, but not used when Policy=0" << endl; - NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of HCR_anchor, see below); must be > control rule cutoff" << endl; - NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of HCR_anchor, e.g. 0.10) " << endl; - NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar]. -year fills from year to YrMax " << endl; - NuFore << "# Also see HCR_anchor below to use virgin vs benchmark SSB or Bmsy as basis for inflection and cutoff" << endl; + NuFore << "# values for top, bottom and buffer exist, but not used when Policy=0" << endl; + NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of Bzero, e.g. 0.40); must be > control rule cutoff, or set to -1 to use Bmsy as the inflection " << endl; + NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of Bzero, e.g. 0.10) " << endl; + NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar] with filling from year to YrMax " << endl; + NuFore << "# Also see HCR_anchor below to use virgin vs benchmark SSB as basis" << endl; if (H4010_scale_rd < 0) { j = H4010_scale_vec_rd.size() - 1; @@ -1669,7 +1669,7 @@ FUNCTION void write_nucontrol() { NuFore << Fcast_Loop_Control(4) << " # multiplier on base recruitment " << endl; } - NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 2 uses unfished benchmark SSB (old hardwired approach); 1 = virgin SSB; 3 = BMSY" << endl << "#" << endl; + NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 2 uses unfished benchmark SSB (old hardwired approach); 1 = virgin SSB" << endl << "#" << endl; NuFore << Fcast_Cap_FirstYear << " # FirstYear for caps and allocations (should be after years with fixed inputs) " << endl; From eaba2636e3d5827888804e27be02001b1fea411e Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Tue, 3 Jun 2025 11:46:29 -0700 Subject: [PATCH 41/58] redo code for Bmsy as HCR inflection --- SS_benchfore.tpl | 26 +++++++++++++++++--------- SS_popdyn.tpl | 12 ++++++------ SS_readcontrol_330.tpl | 2 +- SS_readdata_330.tpl | 11 ++++++++--- SS_write_ssnew.tpl | 12 ++++++------ 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 9737e283..4a0f762a 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -2264,8 +2264,10 @@ FUNCTION void Get_Forecast() {HCR_anchor = SSB_virgin;} else if (Fcast_Loop_Control(5) == 2) {HCR_anchor = SSB_unf;} + else if (Fcast_Loop_Control(5) == 3) + {HCR_anchor = Bmsy;} // so H4010_top_rd should be 1.0; - if (H4010_top_rd < 0.0) + if (H4010_top_rd < 0.0) // legacy approach. This has already been converted to new approach in readdata { H4010_top = Bmsy / HCR_anchor; // convert to fraction of anchor if (H4010_bot > 0.25) @@ -2278,13 +2280,20 @@ FUNCTION void Get_Forecast() { H4010_top = H4010_top_rd; } + if (Fcast_Loop_Control(5) == 3 && H4010_top_rd != 1.0) + { + warnstream << "HCR_anchor is BMSY; so H4010_top normally is 1.0; are you sure you want: " << H4010_top; + write_message (WARN, 0); + } - Mgmt_quant(20) = HCR_anchor; + Mgmt_quant(20) = H4010_top * HCR_anchor; report5 << "#" << endl; report5 << "N_forecast_yrs: " << N_Fcast_Yrs << endl; report5 << "OY_Control_Rule: Inflection: " << H4010_top << " Intercept: " << H4010_bot << " Scale: " << H4010_scale_vec(endyr + 1) << endl - << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl; - report5 << "#" << endl; + << "Control_rule_anchor_approach: " << Fcast_Loop_Control(5) << " HCR_anchor: " << HCR_anchor << endl + << "intercept(SSB): " << H4010_bot * HCR_anchor << endl + << "Inflection(SSB): " << H4010_top * HCR_anchor << endl + << "#" << endl; switch (HarvestPolicy) { @@ -2725,7 +2734,7 @@ FUNCTION void Get_Forecast() bio_yr = y; SSBpR_Calc(R0_use); // call function to do per recruit calculation with current year's biology and adjusted R0 SSB_use = SSB_equil; - warning << y << " update_SRR; SSB_use: "<> H4010_top_rd; // use -1 to set H4010_top to Bmsy/SSB_unf - echoinput << H4010_top_rd << " # echoed control rule inflection (-1 to set to Bmsy/SSB_unf)" << endl; + *(ad_comm::global_datafile) >> H4010_top_rd; // as fraction of HCR_anchor; use -1 as legacy approach to set H4010_top to Bmsy/SSB_unf + echoinput << H4010_top_rd << " # echoed control rule inflection" << endl; *(ad_comm::global_datafile) >> H4010_bot; echoinput << H4010_bot << " # echoed control rule cutoff " << endl; *(ad_comm::global_datafile) >> H4010_scale_rd; @@ -4352,7 +4352,12 @@ write_message(ADJUST, 0); Fcast_Loop_Control(5) = 2; } - echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=virgin_SSB; 2=unfished_benchmark_SSB(old_approach)" << endl; + if (H4010_top_rd < 0) // convert old legacy approach to new approach for using Bmsy + { + Fcast_Loop_Control(5) = 3; + H4010_top_rd = 1.0; + } + echoinput << Fcast_Loop_Control(5) << " #control rule anchor: 1=virgin_SSB; 2=unfished_benchmark_SSB(old_approach); 3=Bmsy" << endl; if (depletion_basis == 1 && Fcast_Loop_Control(5) == 2) { warnstream << "depletion_basis is using virgin but HCR anchor is using SSB_unf from benchmark. Are you sure?"; diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 9b6948f0..98b0b162 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1643,11 +1643,11 @@ FUNCTION void write_nucontrol() } NuFore << HarvestPolicy << " # Control rule method (0: none; 1: ramp does catch=f(SSB), buffer on F; 2: ramp does F=f(SSB), buffer on F; 3: ramp does catch=f(SSB), buffer on catch; 4: ramp does F=f(SSB), buffer on catch) " << endl; - NuFore << "# values for top, bottom and buffer exist, but not used when Policy=0" << endl; - NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of Bzero, e.g. 0.40); must be > control rule cutoff, or set to -1 to use Bmsy as the inflection " << endl; - NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of Bzero, e.g. 0.10) " << endl; - NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar] with filling from year to YrMax " << endl; - NuFore << "# Also see HCR_anchor below to use virgin vs benchmark SSB as basis" << endl; + NuFore << "# values for top, bottom and buffer required, but not used when Policy=0" << endl; + NuFore << H4010_top_rd << " # Control rule inflection for constant F (as frac of HCR_anchor, see below); must be > control rule cutoff" << endl; + NuFore << H4010_bot << " # Control rule cutoff for no F (as frac of HCR_anchor, e.g. 0.10) " << endl; + NuFore << H4010_scale_rd << " # Buffer: enter Control rule target as fraction of Flimit (e.g. 0.75), negative value invokes list of [year, scalar]. -year fills from year to YrMax " << endl; + NuFore << "# Also see HCR_anchor below to use virgin vs benchmark SSB or Bmsy as basis for inflection and cutoff" << endl; if (H4010_scale_rd < 0) { j = H4010_scale_vec_rd.size() - 1; @@ -1669,7 +1669,7 @@ FUNCTION void write_nucontrol() { NuFore << Fcast_Loop_Control(4) << " # multiplier on base recruitment " << endl; } - NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 2 uses unfished benchmark SSB (old hardwired approach); 1 = virgin SSB" << endl << "#" << endl; + NuFore << Fcast_Loop_Control(5) << " # HCR_anchor: 0 or 2 uses unfished benchmark SSB (old hardwired approach); 1 = virgin SSB; 3 = BMSY" << endl << "#" << endl; NuFore << Fcast_Cap_FirstYear << " # FirstYear for caps and allocations (should be after years with fixed inputs) " << endl; From 37db2c929955e84d1920cc3eb81cd37dee75df8f Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Tue, 3 Jun 2025 15:16:19 -0700 Subject: [PATCH 42/58] add bench SR_curve; cleanup spawn_recr report --- SS_benchfore.tpl | 6 ++-- SS_param.tpl | 1 + SS_readcontrol_330.tpl | 3 ++ SS_write_report.tpl | 71 ++++++++++++++++++++++-------------------- SS_write_ssnew.tpl | 2 +- 5 files changed, 46 insertions(+), 37 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 4a0f762a..fa585379 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -785,7 +785,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Recr_unf = mfexp(SRparm_bench(1)); // R0 to be used Fishon = 0; SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology - dvariable SSBpR_bench = SSB_equil / Recr_unf; + SSBpR_bench = SSB_equil / Recr_unf; report5 << "virgin: " << Recr_virgin << " " << SSB_virgin << endl; report5 << "bench: " << Recr_unf << " " << SSB_equil << endl; @@ -855,10 +855,10 @@ FUNCTION void Get_Benchmarks(const int show_MSY) if (show_MSY == 1) { SRparm_bench(N_SRparm2 + 1) = SSB0_4_SRR; - Mgmt_quant(1) = SSB_unf; + Mgmt_quant(1) = SSB0_4_SRR; Mgmt_quant(2) = totbio; // this is calculated in Do_Equil_Calc Mgmt_quant(3) = smrybio; - Mgmt_quant(4) = Recr_unf; + Mgmt_quant(4) = R0_4_SRR; report5 << "SRparms for benchmark: " << SRparm_bench << endl << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << endl; Mgmt_quant(19) = SSB_unf; // placeholder for depletion denominator diff --git a/SS_param.tpl b/SS_param.tpl index 2409c944..d8ff05f9 100644 --- a/SS_param.tpl +++ b/SS_param.tpl @@ -167,6 +167,7 @@ PARAMETER_SECTION number half_sigmaRsq; number sigmaR; number SSBpR_virgin; + number SSBpR_bench; number SSB0_4_SRR; number R0_4_SRR; number regime_change; diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 30ce918f..bc8999fa 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1971,6 +1971,7 @@ int timevary_SRparm_first; // == 0 means that no relevant parms are timevarying int firstSRparm; + int timevary_SRparm_first_yr; // year int timevary_parm_SR_last; ivector timevary_SRparm(styr-3,YrMax+1); ivector SRparm_timevary(1,N_SRparm2); @@ -1981,6 +1982,7 @@ firstSRparm = ParCount; timevary_parm_SR_last = 0; timevary_SRparm_first = 0; + timevary_SRparm_first_yr = 0; timevary_SRparm.initialize(); SRparm_timevary.initialize(); SR_env_link = 0; @@ -2142,6 +2144,7 @@ if (timevary_pass(y) > 0 && j != N_SRparm2 - 1) { timevary_SRparm(y) = timevary_pass(y); // set timevary flag, except for regime parameter + timevary_SRparm_first_yr = y; SRflag = 1; // first change point } else if(SRflag == 1) diff --git a/SS_write_report.tpl b/SS_write_report.tpl index faf51371..29e259b7 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -77,7 +77,9 @@ FUNCTION void write_bigoutput() SS2out << "Data_File: " << datfilename << endl; SS2out << "Control_File: " << ctlfilename << endl; if (readparfile >= 1) - SS2out << "Start_parm_values_from_SS.PAR" << endl; + {SS2out << "Start_parm_values_from_SS.PAR" << endl;} + else + {SS2out << "Start_parm_values_from_control_file" << endl;} SS2out << endl << "Convergence_Level: " << objective_function_value::pobjfun->gmax << " is_final_gradient" << endl; temp = get_ln_det_value(); @@ -1889,44 +1891,36 @@ FUNCTION void write_bigoutput() SS2out << endl; } - SS2out << endl << "#New_Expanded_Spawn_Recr_report" << endl << pick_report_name(19) << endl; + SS2out << endl << "#Expanded_Spawn_Recr_report" << endl << pick_report_name(19) << endl; SS2out << SR_fxn << " # SR_Function" << endl; - SS2out << "# " < 0 && j <= 4 ) // timevary SRparm exists - {SS2out << " #_TV";} - if (j == (N_SRparm2 - 1) && SRparm_timevary(j) > 0) // timevary regime exists - {SS2out << " #_Regime_used_to_offset_from_SRR";} - SS2out << endl; + {SS2out << " " << timevary_SRparm_first_yr;} else {SS2out << " -";} + SS2out << endl; } - - if( timevary_SRparm_first == 0) - { SS2out << "0 #_No_timevary_SRparms,_other_than_regime " << endl; } + SS2out << "#" << endl; + if (SRparm_timevary(N_SRparm2 - 1) > 0) // timevary regime exists + {SS2out << " #_Regime_used_to_offset_from_SRR";} + SS2out << timevary_bio_4SRR << " # timevary_bio_4SRR #_Compatibility_flag_for_legacy_(0)_vs_improved_(1)_impact_of_timevary_biology_on_benchmark_SRR_calcs" << endl; + if( timevary_MG_firstyr == YrMax) + { SS2out << " #_No_timevary_MGparm" << endl; } else - { - for (y = styr; y <= YrMax; y++) if (timevary_SRparm(y) == 1) SS2out << y; - SS2out << " # timevary_SRparm_begin_year" << endl; - } + { SS2out << timevary_MG_firstyr << " #_first year_timevary_MGparm_(or_any_year_EWAA) " << endl; } - SS2out << "#" << endl << "Quantities for MSY and other benchmark calculations " << endl << "Benchmark_years: 1_beg_bio 2_end_bio 3_beg_selex 4_end_selex 5_beg_relF 6_end_relF 7_beg_recr_dist 8_end_recr_dist 9_beg_SRparm 10_end_SRparm" << endl; - SS2out << "Benchmark_years: " << Bmark_Yr << endl; + SS2out << "#" << endl << "Quantities for MSY and other benchmark calculations " << endl + << "Benchmark_index: 1 2 3 4 5 6 7 8 9 10" << endl + << "Benchmark_label: beg_bio end_bio beg_selex end_selex beg_relF end_relF beg_recr_dist end_recr_dist beg_SRparm end_SRparm" << endl + << "Benchmark_years: " << Bmark_Yr << endl; for ( int k = 1; k <=9; k+=2) { if (Bmark_Yr(k+1) > Bmark_Yr(k)) - {SS2out << "#_range_of_years_is_averaged,_so_reduces_standard_error_of_result;_do_this_only_when_timevarying_makes_necessary: " << k << " "<< k+1 << endl;} + {SS2out << "#_NOTE:_using_range_of_years_can_reduce_standard_error_of_result;_do_this_only_when_timevarying_makes_necessary: " << k << " " << Bmark_Yr(k) << " " << Bmark_Yr(k+1) << endl;} } - SS2out << "SSBpR0_(virgin): " << SSBpR_virgin << " #_uses_biology_from_start_year: " << styr < Date: Thu, 5 Jun 2025 17:14:25 -0700 Subject: [PATCH 43/58] easy fix for spiny dogfish using SRR 7 --- SS_benchfore.tpl | 2 +- SS_write_report.tpl | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index fa585379..8a6db2c6 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -2721,7 +2721,7 @@ FUNCTION void Get_Forecast() { R0_use = Recr_virgin; SSB_use = SSB_virgin; - warning << y << " virgin_SRR; SSB_use: "< Date: Wed, 11 Jun 2025 10:09:22 -0700 Subject: [PATCH 44/58] repair legacy HCR_anchor; cleanup warnings --- SS_benchfore.tpl | 6 ++---- SS_readcontrol_330.tpl | 10 ++++++++++ SS_readdata_330.tpl | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 8a6db2c6..b58f1629 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -787,8 +787,8 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSBpR_bench = SSB_equil / Recr_unf; - report5 << "virgin: " << Recr_virgin << " " << SSB_virgin << endl; - report5 << "bench: " << Recr_unf << " " << SSB_equil << endl; +// report5 << "virgin: " << Recr_virgin << " " << SSB_virgin << endl; +// report5 << "bench: " << Recr_unf << " " << SSB_equil << endl; if( timevary_MG_firstyr == YrMax && WTage_rd == 0) // no time-varying biology { SSB0_4_SRR = SSB_virgin; @@ -799,8 +799,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) { if( timevary_bio_4SRR == 0) // legacy approach; this switch is read from starter.ss { - warnstream << "There is timevary biology and the legacy approach to benchmark calculations is being used; user should be aware"; - write_message (WARN, 0); if(timevary_SRparm_first == 0) // no timevary SRR parms { SSB_unf = SSB_equil; diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index bc8999fa..375d34ce 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1817,12 +1817,22 @@ if(timevary_MG_firstyr == YrMax) timevary_MG_firstyr = y; // save for reporting in MSY and spawn_recruit output } } + // timevary growth or maturity and Maunder M refers to that maturity if ((timevary_MG(y, 2) > 0 || timevary_MG(y, 3) > 0) && natM_type == 5 && natM_5_opt < 3) timevary_MG(y, 1) = 1; echoinput << y << " timevary_MG: " << timevary_MG(y) << endl; } + if( timevary_MG_firstyr == YrMax && WTage_rd == 0) // no time-varying biology + { + if( timevary_bio_4SRR == 0) // legacy approach; this switch is read from starter.ss + { + warnstream << "There is timevary biology and the legacy approach to benchmark calculations is being used; user should be aware"; + write_message(WARN, 0); + } + } + for (y = endyr + 1; y <= YrMax; y++) { for (f = 1; f <= 7; f++) diff --git a/SS_readdata_330.tpl b/SS_readdata_330.tpl index 33d383e0..0ba0045d 100644 --- a/SS_readdata_330.tpl +++ b/SS_readdata_330.tpl @@ -4345,7 +4345,7 @@ "even when the base is set to the mean of earlier recruitments" << endl; } - if (Fcast_Loop_Control(5) == 0) // default before 3.30.24 + if (Fcast_Loop_Control(5) <= 0) // default before 3.30.24 { echoinput << "basis for HCR anchor was not set; setting to 2 to match default before 3.30.24" << endl; warnstream << "basis for HCR anchor was not set; setting to 2 to match default before 3.30.24"; From c5381f41c5698d3922eac37f75c085d35d35c357 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Wed, 11 Jun 2025 10:28:23 -0700 Subject: [PATCH 45/58] restore global_msy to report.sso --- SS_benchfore.tpl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index b58f1629..eadc9e65 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -2021,20 +2021,19 @@ FUNCTION void Get_Benchmarks(const int show_MSY) } else if (show_MSY == 2) // do brief output { - report5 << SPR_actual / 100. << " " << SPR_Fmult << " " << Mgmt_quant(10) << " " << YPR_spr_dead / Vbio1_spr << " " << Bspr_rec << " " + SS2out << SPR_actual / 100. << " " << SPR_Fmult << " " << Mgmt_quant(10) << " " << YPR_spr_dead / Vbio1_spr << " " << Bspr_rec << " " << Bspr << " " << YPR_spr_dead * Bspr_rec << " " << YPR_spr_ret * Bspr_rec << " " << Vbio1_spr * Bspr_rec << " # "; - report5 << SPR_Btgt << " " << Btgt / SSB_unf << " " << Btgt_Fmult << " " << Mgmt_quant(7) << " " << YPR_Btgt_dead / Vbio1_Btgt << " " << Btgt_Rec << " " + SS2out << SPR_Btgt << " " << Btgt / SSB_unf << " " << Btgt_Fmult << " " << Mgmt_quant(7) << " " << YPR_Btgt_dead / Vbio1_Btgt << " " << Btgt_Rec << " " << Btgt << " " << YPR_Btgt_dead * Btgt_Rec << " " << YPR_Btgt_ret * Btgt_Rec << " " << Vbio1_Btgt * Btgt_Rec << " # "; - report5 << MSY_SPR << " " << Bmsy / SSB_unf << " " << MSY_Fmult << " " << Mgmt_quant(14) << " " << MSY / (Vbio1_MSY * Recr_msy) << " " << Recr_msy << " " + SS2out << MSY_SPR << " " << Bmsy / SSB_unf << " " << MSY_Fmult << " " << Mgmt_quant(14) << " " << MSY / (Vbio1_MSY * Recr_msy) << " " << Recr_msy << " " << Bmsy << " " << MSY << " " << YPR_msy_dead * Recr_msy << " " << YPR_msy_ret * Recr_msy << " " << Vbio1_MSY * Recr_msy << " # " << endl; } write_bodywt = write_bodywt_save; - report5 << 0 << " y: " << y << " Repro_output_by_age_for_morph_1 end_bench: " << fec(1) << endl; // report5 << "Repro_output_by_age_for_morph_1_after_benchmark: " << fec(1) << endl; } // end benchmarks From 03df832e9863e51a3d34bb949585a4ed275b5263 Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Wed, 11 Jun 2025 21:05:10 +0000 Subject: [PATCH 46/58] fix par file line in starter to match new text --- .github/workflows/run-ss3-no-est.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-ss3-no-est.yml b/.github/workflows/run-ss3-no-est.yml index c77bf619..d2f438d2 100644 --- a/.github/workflows/run-ss3-no-est.yml +++ b/.github/workflows/run-ss3-no-est.yml @@ -116,7 +116,7 @@ jobs: file.rename(file.path(dir, "forecast.ss_new"), file.path(dir,"forecast.ss")) # rename control and data files to standardized names (from the starter files) start <- readLines(file.path(dir, "starter.ss")) - first_val_line <- grep("0=use init values in control file", start, fixed = TRUE) + first_val_line <- grep("read from .par file", start, fixed = TRUE) datname <- start[first_val_line-2] ctlname <- start[first_val_line-1] print(datname) From 28c2df84ad6799170dafc7f4294bec1fca9dea55 Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Wed, 11 Jun 2025 21:25:10 +0000 Subject: [PATCH 47/58] fix forecast file removal line --- .github/workflows/run-ss3-no-est.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-ss3-no-est.yml b/.github/workflows/run-ss3-no-est.yml index d2f438d2..399fb650 100644 --- a/.github/workflows/run-ss3-no-est.yml +++ b/.github/workflows/run-ss3-no-est.yml @@ -111,7 +111,7 @@ jobs: on.exit(system(paste0("cd ", wd))) # delete old starter files, rename forecast.ss_new and starter.ss_new files file.remove(file.path(dir, "starter.ss")) - file.remove(file.path("forecast.ss")) + file.remove(file.path(dir, "forecast.ss")) file.rename(file.path(dir, "starter.ss_new"), file.path(dir,"starter.ss")) file.rename(file.path(dir, "forecast.ss_new"), file.path(dir,"forecast.ss")) # rename control and data files to standardized names (from the starter files) From 8ab82444720246da3f34bda98a842af75724d964 Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Thu, 12 Jun 2025 13:19:51 +0000 Subject: [PATCH 48/58] try different fix to starter file lines --- .github/workflows/run-ss3-no-est.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run-ss3-no-est.yml b/.github/workflows/run-ss3-no-est.yml index 399fb650..ccd0e537 100644 --- a/.github/workflows/run-ss3-no-est.yml +++ b/.github/workflows/run-ss3-no-est.yml @@ -116,9 +116,10 @@ jobs: file.rename(file.path(dir, "forecast.ss_new"), file.path(dir,"forecast.ss")) # rename control and data files to standardized names (from the starter files) start <- readLines(file.path(dir, "starter.ss")) - first_val_line <- grep("read from .par file", start, fixed = TRUE) - datname <- start[first_val_line-2] - ctlname <- start[first_val_line-1] + datname <- start[grep("#_datfile", start, fixed = TRUE)] + datname <- gsub(" #_datfile", "", datname) + ctlname <- start[grep("#_ctlfile", start, fixed = TRUE)] + ctlname <- gsub(" #_ctlfile", "", ctlname) print(datname) print(ctlname) file.remove(file.path(dir, datname)) From c744d30a4adaa2bea1858f261b5c95d2e072eb42 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Mon, 16 Jun 2025 13:44:26 -0700 Subject: [PATCH 49/58] fix logic for reading of timevary_bio_4SRR --- SS_readcontrol_330.tpl | 10 ++++++++-- SS_readstarter.tpl | 8 ++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 375d34ce..81004344 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -1824,12 +1824,18 @@ echoinput << y << " timevary_MG: " << timevary_MG(y) << endl; } - if( timevary_MG_firstyr == YrMax && WTage_rd == 0) // no time-varying biology + if( timevary_MG_firstyr < YrMax || WTage_rd == 1) // time-varying biology { if( timevary_bio_4SRR == 0) // legacy approach; this switch is read from starter.ss { - warnstream << "There is timevary biology and the legacy approach to benchmark calculations is being used; user should be aware"; + warnstream << "There is timevary biology and the legacy approach to benchmark calculations is being used; user should be aware of possible impacts to benchmark results"; write_message(WARN, 0); + if( timevary_bio_4SRR_rd == -1) // older starter file did not contain necessary flag + { + warnstream << "There is timevary biology, so the flag for timevary_bio_4SRR must be set to 0 (old default) or 1 (new improved) in starter.ss"; +// make this a WARN while testing, then change to FATAL for operational code + write_message(WARN, 0); + } } } diff --git a/SS_readstarter.tpl b/SS_readstarter.tpl index 8143e984..348b4a70 100644 --- a/SS_readstarter.tpl +++ b/SS_readstarter.tpl @@ -706,6 +706,7 @@ int irand_seed; int irand_seed_rd; int timevary_bio_4SRR; // flag in 3.30.24 for impact of timevary biology on benchmark SRR calculations + int timevary_bio_4SRR_rd; // flag in 3.30.24 for impact of timevary biology on benchmark SRR calculations int F_std_multi; // for multi-year averaging of F_std int F_std_log; // for log(ratio) of F_std int F_std_basis; @@ -809,15 +810,18 @@ } echoinput << "now read flag for dealing with impact of time-varying biology on benchmark SRR calculations" << endl; + timevary_bio_4SRR = 0; + timevary_bio_4SRR_rd = -1; *(ad_comm::global_datafile) >> tempin; - if (tempin == 3.30) // old format file that does not provide input + if (tempin == 3.30) // starter file does not contain the new line for timevary_bio_4SRR, so assign default { ender = 1; timevary_bio_4SRR = 0; } - else // new input beginning 3.30.24 + else // new input line beginning 3.30.24 { timevary_bio_4SRR = int(tempin); + timevary_bio_4SRR_rd = 0; // indicates that line was read echoinput << "Compatibility flag for legacy (0) vs improved (1) impact of timevary biology on benchmark SRR calcs: " << timevary_bio_4SRR << endl; tempin = 0; } From cf6b0c580d6c11e1c9adb9b54aeb05ce90b72dc3 Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Thu, 26 Jun 2025 09:44:20 -0400 Subject: [PATCH 50/58] Update run-ss3-no-est.yml with updated t-v models test models branch --- .github/workflows/run-ss3-no-est.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run-ss3-no-est.yml b/.github/workflows/run-ss3-no-est.yml index ccd0e537..066b05b4 100644 --- a/.github/workflows/run-ss3-no-est.yml +++ b/.github/workflows/run-ss3-no-est.yml @@ -38,6 +38,7 @@ jobs: uses: actions/checkout@v4 with: repository: 'nmfs-ost/ss3-test-models' + ref: t-v-models-update path: test-models-repo - name: Update Ubuntu packages From abeda199d3986d278219677815b402f2dea3497e Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Thu, 26 Jun 2025 15:38:40 -0400 Subject: [PATCH 51/58] Update run-ss3-with-est.yml --- .github/workflows/run-ss3-with-est.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/run-ss3-with-est.yml b/.github/workflows/run-ss3-with-est.yml index cee49885..89ac2dba 100644 --- a/.github/workflows/run-ss3-with-est.yml +++ b/.github/workflows/run-ss3-with-est.yml @@ -1,5 +1,4 @@ # Build SS3 and run test models with estimation and hessian -# Only runs manual run or if run-ss3-no-est.yml runs successfully name: run-ss3-with-est on: workflow_dispatch: @@ -8,16 +7,16 @@ on: # - '**.tpl' # branches: # - main - workflow_run: - workflows: ["run-ss3-no-est"] - types: - - completed - # pull_request: - # types: ['opened', 'edited', 'reopened', 'synchronize', 'ready_for_review'] - # paths: - # - '**.tpl' - # branches: - # - main + # workflow_run: + # workflows: ["run-ss3-no-est"] + # types: + # - completed + pull_request: + types: ['opened', 'edited', 'reopened', 'synchronize', 'ready_for_review'] + paths: + - '**.tpl' + branches: + - main # Run fast running SS3 test models with estimation jobs: @@ -36,6 +35,7 @@ jobs: uses: actions/checkout@v4 with: repository: 'nmfs-ost/ss3-test-models' + ref: t-v-models-update path: test-models-repo - name: Update Ubuntu packages From 92319350c33de60f2277f7e143b69d73c161a872 Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Thu, 26 Jun 2025 15:40:43 -0400 Subject: [PATCH 52/58] Update run-ss3-with-est.yml with simple PR trigger --- .github/workflows/run-ss3-with-est.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/run-ss3-with-est.yml b/.github/workflows/run-ss3-with-est.yml index 89ac2dba..25d7f1c8 100644 --- a/.github/workflows/run-ss3-with-est.yml +++ b/.github/workflows/run-ss3-with-est.yml @@ -12,7 +12,6 @@ on: # types: # - completed pull_request: - types: ['opened', 'edited', 'reopened', 'synchronize', 'ready_for_review'] paths: - '**.tpl' branches: From 7d972b3c983e71ded7ccdd9af2cc8687aeab4a76 Mon Sep 17 00:00:00 2001 From: iantaylor-NOAA Date: Thu, 26 Jun 2025 14:38:05 -0700 Subject: [PATCH 53/58] minor changes to capitalization - useful element of defunct PR discussed in: https://github.com/nmfs-ost/ss3-source-code/pull/683#pullrequestreview-2963734396 --- SS_write_report.tpl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 8e4e6a45..7b6979cc 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -4792,9 +4792,8 @@ FUNCTION void SPR_profile() if (s == spawn_seas) { fec = Wt_Age_t(t, -2); - SS2out << " repro_output for spr/ypr: " << fec(1) << endl;} + SS2out << " repro_output for SPR/YPR: " << fec(1) << endl;} } - SS2out << " stored - SSB, R0, SPR0: " << SSB_unf << " " << Recr_unf << " " << SSBpR_virgin << " " << SSBpR_virgin< Date: Thu, 26 Jun 2025 15:59:37 -0700 Subject: [PATCH 54/58] temporarily changing the r4ss install in test to use branch --- .github/workflows/test-r4ss-with-ss3.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-r4ss-with-ss3.yml b/.github/workflows/test-r4ss-with-ss3.yml index e1d9e618..fcf49d09 100644 --- a/.github/workflows/test-r4ss-with-ss3.yml +++ b/.github/workflows/test-r4ss-with-ss3.yml @@ -52,7 +52,7 @@ jobs: run: Rscript -e 'install.packages(c("remotes","parallely", "furrr", "future"))' - name: Install r4ss - run: Rscript -e 'remotes::install_github("r4ss/r4ss")' + run: Rscript -e 'remotes::install_github("r4ss/r4ss@expanded_SR")' # - name: Get admb and put in path, linux # run: | From ec03c54d9a6a5cced7c5018fc67e40457ea9a48e Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Mon, 30 Jun 2025 11:04:13 -0400 Subject: [PATCH 55/58] Update run-ss3-with-est.yml --- .github/workflows/run-ss3-with-est.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-ss3-with-est.yml b/.github/workflows/run-ss3-with-est.yml index 25d7f1c8..462ac398 100644 --- a/.github/workflows/run-ss3-with-est.yml +++ b/.github/workflows/run-ss3-with-est.yml @@ -20,7 +20,7 @@ on: # Run fast running SS3 test models with estimation jobs: run-ss3-with-est: - if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.draft == 'false' && github.event.workflow_run.conclusion == 'success') }} + # if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.draft == 'false'}} runs-on: ubuntu-latest env: R_REMOTES_NO_ERRORS_FROM_WARNINGS: true From 37650520d55c1476fe54f3fbcfb9c3980e3b7c5c Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Mon, 30 Jun 2025 14:22:27 -0700 Subject: [PATCH 56/58] revise mgmt_quant labels; fix wt_age_mid for global --- SS_popdyn.tpl | 2 ++ SS_readcontrol_330.tpl | 8 ++++---- SS_write_report.tpl | 3 +-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/SS_popdyn.tpl b/SS_popdyn.tpl index 2acdfb82..90e8cf2e 100644 --- a/SS_popdyn.tpl +++ b/SS_popdyn.tpl @@ -269,6 +269,7 @@ FUNCTION void get_initial_conditions() } Wt_Age_t(t, 0) = Wt_Age_beg(s); + Wt_Age_t(t, -1) = Wt_Age_mid(s); for (g = 1; g <= gmorph; g++) if (use_morph(g) > 0) @@ -925,6 +926,7 @@ FUNCTION void get_time_series() } Wt_Age_t(t, 0) = Wt_Age_beg(s); + Wt_Age_t(t, -1) = Wt_Age_mid(s); if (y > styr) // because styr is done as part of initial conditions { diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 81004344..306b37b0 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -6668,19 +6668,19 @@ j++; active_parm(CoVar_Count) = j; // add quantities needed when time-vary life history is used; but report here for all cases; elements 18-21 of mgmt_quant - ParmLabel += "18.Recr_MSY_bmarkbio" + CRLF(1); + ParmLabel += "Recr_MSY_bmarkbio" + CRLF(1); CoVar_Count++; j++; active_parm(CoVar_Count) = j; - ParmLabel += "19.Depletion_denom" + CRLF(1); + ParmLabel += "Depletion_denom" + CRLF(1); CoVar_Count++; j++; active_parm(CoVar_Count) = j; - ParmLabel += "20.HCR_inflect" + CRLF(1); + ParmLabel += "HCR_inflect" + CRLF(1); CoVar_Count++; j++; active_parm(CoVar_Count) = j; - ParmLabel += "ignore" + CRLF(1); + ParmLabel += "SSB_unfished_again" + CRLF(1); CoVar_Count++; j++; active_parm(CoVar_Count) = j; diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 7b6979cc..0817971b 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -4788,13 +4788,12 @@ FUNCTION void SPR_profile() { t = styr - 3 * nseas + s - 1; Wt_Age_beg(s) = Wt_Age_t(t, 0); // used for smrybio - Wt_Age_mid(s) = Wt_Age_t(t, -1); + Wt_Age_mid(s) = Wt_Age_t(t, -1); // used in global MSY if (s == spawn_seas) { fec = Wt_Age_t(t, -2); SS2out << " repro_output for SPR/YPR: " << fec(1) << endl;} } - // do not recalculate here so force using values from benchmark SS2out << "unfished values for SRR: SSB " << SSB0_4_SRR << " R " << R0_4_SRR << " SSBpR " << " SSBpR: " << SSB0_4_SRR / R0_4_SRR << endl; SS2out << "SPRloop Iter Bycatch Fmult F_std SSBpR YpR_dead YpR_dead*Recr YpR_ret*Recr Revenue Cost Profit SSB Recruits SSB/Bzero Tot_Catch "; From fe43c461f77a955cac7d738d14e1f314918daff9 Mon Sep 17 00:00:00 2001 From: Richard Methot Date: Thu, 3 Jul 2025 14:14:45 -0700 Subject: [PATCH 57/58] rework logic in bench; revise the extra mgmt_quant --- SS_benchfore.tpl | 107 ++++++++++++++++++----------------------- SS_readcontrol_330.tpl | 4 +- SS_write_report.tpl | 4 +- 3 files changed, 52 insertions(+), 63 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index eadc9e65..87683d9d 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -750,11 +750,6 @@ FUNCTION void Get_Benchmarks(const int show_MSY) SRparm_bench = SRparm_work; /* - Early thoughts: - 1 # SR_update_SSBpR0 - # 1 - best: update SSBpR0 for benchmark and for time series only if SRparm R0 or h (not regime) is set to have time-varying property - # 2 - incorrect (old, incorrect SS3 approach): always update SSBpR0 for benchmark's use of spawner-recruitment, but only for the time series if there is a timevary SR parm - Flags: timevary_MG_firstyr == YrMax // means that no biology is time-varying timevary_SRparm_first > 0 // means that R0 or h (i.e. any except regime, sigmaR, autocorr) is time-varying, so SSBpR0 gets updated for time series and for bench @@ -762,6 +757,7 @@ FUNCTION void Get_Benchmarks(const int show_MSY) Legacy approach: SSBpR0 set at start year using start year biology + SSBpR0 is not itself saved; instead R0_4_SRR and SSB0_4_SRR are saved and passed to the spawn_recruit functions SSBpR0 updated during time series if there is time-varying R0, but does not call equil_spawn_recr_calc SSBpR with benchmark biology used in benchmark calculations SSBpR0 for benchmark always uses bench biology, which is incorrect @@ -782,87 +778,80 @@ FUNCTION void Get_Benchmarks(const int show_MSY) HCR inflection adds option to use SSB_virgin or SSB_bench depletion adds option to use SSB_bench */ - Recr_unf = mfexp(SRparm_bench(1)); // R0 to be used + Recr_unf = Recr_virgin; // default + SSB0_4_SRR = SSB_virgin; // default + R0_4_SRR = Recr_virgin; Fishon = 0; SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology + // provides basis for values needed below + SSB_unf = SSB_equil; SSBpR_bench = SSB_equil / Recr_unf; -// report5 << "virgin: " << Recr_virgin << " " << SSB_virgin << endl; -// report5 << "bench: " << Recr_unf << " " << SSB_equil << endl; - if( timevary_MG_firstyr == YrMax && WTage_rd == 0) // no time-varying biology - { - SSB0_4_SRR = SSB_virgin; - R0_4_SRR = Recr_virgin; - SSB_unf = SSB_equil; // should this also depend on timevary_SRparm_first > 0??? - } - else // there is some timevary biology (with any WTage_rd == 1 qualifying as timevarying without actually chacking for different values in diff years) + if(timevary_SRparm_first == 0) // no timevary SRR parms { - if( timevary_bio_4SRR == 0) // legacy approach; this switch is read from starter.ss + if( timevary_MG_firstyr == YrMax && WTage_rd == 0) // no time-varying biology { - if(timevary_SRparm_first == 0) // no timevary SRR parms - { - SSB_unf = SSB_equil; - R0_4_SRR = Recr_unf; // same as Recr_virgin because no timevary SRparms - SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR - SSBpR_bench = SSB0_4_SRR / R0_4_SRR; - } - else // there are timevary SRR parms + R0_4_SRR = Recr_virgin; + SSB0_4_SRR = SSB_virgin; + SSB_unf = SSB_virgin; + } + else // there is time-varying biology + { + R0_4_SRR = Recr_virgin; // same as Recr_virgin because no timevary SRparms + if( timevary_bio_4SRR == 0) // legacy approach; this switch is read from starter.ss { - Recr_unf = mfexp(SRparm_bench(1)); // R0 to be used - // steepness and other SR parms will also come from SRparm_bench - SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology SSB_unf = SSB_equil; - R0_4_SRR = Recr_unf; - SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR - SSBpR_bench = SSB0_4_SRR / R0_4_SRR; + SSB0_4_SRR = SSB_equil; // this is inaccurate legacy, as it moves equil off the SRR, rather than along the SRR } - if (show_MSY == 1) report5 << " legacy: Recr: " << R0_4_SRR << " SSB: " << SSB0_4_SRR << " bench SPR: " << SSBpR_bench << endl; - } - - else // more complete approach to time vary biology will be used (introduced in 3.30.24) - { - if(timevary_SRparm_first == 0) // no timevary SRR parms, so SRR will use SSB_virgin, Recr_virgin to internally create virgin SSBpR0 + else { - SSB0_4_SRR = SSB_virgin; - R0_4_SRR = Recr_virgin; // get new equilibrium point using original SRR and SSBpR_bench Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB_virgin, Recr_virgin, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR SSB_unf = Equ_SpawnRecr_Result(1); Recr_unf = Equ_SpawnRecr_Result(2); if (show_MSY == 1) report5 << " use virgin SSBpR0 in SRR - SSB: " << SSB_virgin << " Recr: " << Recr_virgin << " SPR: " << SSB_virgin / Recr_virgin << " bench SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; } - else // use updated SRparms and benchmark biology - { - // get new equilibrium point for the benchmark SRR - Recr_unf = mfexp(SRparm_bench(1)); // R0 to be used - Fishon = 0; - SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology - SSBpR_bench = SSB_equil / Recr_unf; - SSB0_4_SRR = SSB_equil; - SSB_unf = SSB_equil; - R0_4_SRR = Recr_unf; - // verify - Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR - if (show_MSY == 1) report5 << " use bench SSBpR0 in SRR - SSB: " << SSB_unf << " Recr: " << Recr_unf << " SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; - } - SSBpR_Calc(Recr_unf); // this calcs SSBpR and returns it as SSB_equil using benchmark biology and the updated equil Recr - SSB_unf = SSB_equil; + SSBpR_bench = SSB_unf / Recr_unf; + } + } + else // there are timevary SRR parms; use same code regardless of timevary biology. Legacy approach does not include new equilibrium + { + Recr_unf = mfexp(SRparm_bench(1)); // R0 to be used + // note that steepness will get updated when SRparm_bench is used in Equ_SpawnRecr_Result + SSBpR_Calc(Recr_unf); // this returns SSB_equil using benchmark biology + SSB_unf = SSB_equil; + SSBpR_bench = SSB_equil / Recr_unf; + if( timevary_bio_4SRR == 0) // legacy approach; this switch is read from starter.ss + { + R0_4_SRR = Recr_unf; + SSB0_4_SRR = SSB_equil; // this is legacy, but incorrect, as it moves equil off the SRR, rather than along the SRR + } + else // use improved approach with updated SRparms and benchmark biology + { + // get new equilibrium point for the benchmark SRR + Equ_SpawnRecr_Result = Equil_Spawn_Recr_Fxn(SRparm_bench, SSB_equil, Recr_unf, SSBpR_bench); // returns 2 element vector containing equilibrium biomass and recruitment at this SPR + SSB_unf = Equ_SpawnRecr_Result(1); + SSB0_4_SRR = Equ_SpawnRecr_Result(1); + Recr_unf = Equ_SpawnRecr_Result(2); + R0_4_SRR = Equ_SpawnRecr_Result(2); + + if (show_MSY == 1) report5 << " use bench SSBpR0 in SRR - SSB: " << SSB_unf << " Recr: " << Recr_unf << " SPR: " << SSBpR_bench << " new equil: " << Equ_SpawnRecr_Result << endl; } } if (show_MSY == 1) { - SRparm_bench(N_SRparm2 + 1) = SSB0_4_SRR; - Mgmt_quant(1) = SSB0_4_SRR; + SRparm_bench(N_SRparm2 + 1) = SSB_unf; + Mgmt_quant(1) = SSB_unf; Mgmt_quant(2) = totbio; // this is calculated in Do_Equil_Calc Mgmt_quant(3) = smrybio; - Mgmt_quant(4) = R0_4_SRR; + Mgmt_quant(4) = Recr_unf; report5 << "SRparms for benchmark: " << SRparm_bench << endl << "Benchmark biology averaged over years: " << Bmark_Yr(1) << " " << Bmark_Yr(2) << endl << endl; Mgmt_quant(19) = SSB_unf; // placeholder for depletion denominator Mgmt_quant(20) = SSB_unf; // placeholder to be replaced by SSB_HCR_infl - Mgmt_quant(21) = SSB_unf; - Mgmt_quant(22) = SSB_virgin; + Mgmt_quant(21) = R0_4_SRR; + Mgmt_quant(22) = SSB0_4_SRR; } // find Fspr SS_Label_710 diff --git a/SS_readcontrol_330.tpl b/SS_readcontrol_330.tpl index 306b37b0..88992625 100644 --- a/SS_readcontrol_330.tpl +++ b/SS_readcontrol_330.tpl @@ -6680,11 +6680,11 @@ CoVar_Count++; j++; active_parm(CoVar_Count) = j; - ParmLabel += "SSB_unfished_again" + CRLF(1); + ParmLabel += "R0_for_SRR_bench" + CRLF(1); CoVar_Count++; j++; active_parm(CoVar_Count) = j; - ParmLabel += "SSB_virgin_again" + CRLF(1); + ParmLabel += "SSB_for_SRR_bench" + CRLF(1); CoVar_Count++; j++; active_parm(CoVar_Count) = j; diff --git a/SS_write_report.tpl b/SS_write_report.tpl index 0817971b..5f6fa39b 100644 --- a/SS_write_report.tpl +++ b/SS_write_report.tpl @@ -4963,9 +4963,9 @@ FUNCTION void SPR_profile() if (SPRloop1 == 0) Fcrash = Fmult2; } - SS2out << SPRloop1 << " " << SPRloop << " " << with_BYC << " " << Fmult2 << " " << equ_F_std << " " << SSB_equil / (SSB_unf / Recr_unf) << " " << YPR_dead << " " + SS2out << SPRloop1 << " " << SPRloop << " " << with_BYC << " " << Fmult2 << " " << equ_F_std << " " << SSB_equil / (SSB0_4_SRR / R0_4_SRR) << " " << YPR_dead << " " << YPR_dead * Btgt_prof_rec << " " << YPR_ret * Btgt_prof_rec << " " << (PricePerF * YPR_val_vec) * Btgt_prof_rec - << " " << Cost << " " << (PricePerF * YPR_val_vec) * Btgt_prof_rec - Cost << " " << Btgt_prof << " " << Btgt_prof_rec << " " << Btgt_prof / SSB_unf + << " " << Cost << " " << (PricePerF * YPR_val_vec) * Btgt_prof_rec - Cost << " " << Btgt_prof << " " << Btgt_prof_rec << " " << Btgt_prof / SSB0_4_SRR << " " << value(sum(equ_catch_fleet(2)) * Btgt_prof_rec); for (f = 1; f <= Nfleet; f++) if (fleet_type(f) <= 2) From 53a6c3e80cc6a02644da19405fd4d627ebade0db Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Tue, 8 Jul 2025 10:33:10 -0400 Subject: [PATCH 58/58] return to using main test branch repo for ghas --- .github/workflows/run-ss3-no-est.yml | 1 - .github/workflows/run-ss3-with-est.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/run-ss3-no-est.yml b/.github/workflows/run-ss3-no-est.yml index 066b05b4..ccd0e537 100644 --- a/.github/workflows/run-ss3-no-est.yml +++ b/.github/workflows/run-ss3-no-est.yml @@ -38,7 +38,6 @@ jobs: uses: actions/checkout@v4 with: repository: 'nmfs-ost/ss3-test-models' - ref: t-v-models-update path: test-models-repo - name: Update Ubuntu packages diff --git a/.github/workflows/run-ss3-with-est.yml b/.github/workflows/run-ss3-with-est.yml index 462ac398..2225df50 100644 --- a/.github/workflows/run-ss3-with-est.yml +++ b/.github/workflows/run-ss3-with-est.yml @@ -34,7 +34,6 @@ jobs: uses: actions/checkout@v4 with: repository: 'nmfs-ost/ss3-test-models' - ref: t-v-models-update path: test-models-repo - name: Update Ubuntu packages