From 3bb3c061e10ceb0455f2338e087dc9f97cb66dda Mon Sep 17 00:00:00 2001 From: Rick Methot Date: Wed, 26 Nov 2025 15:24:31 -0800 Subject: [PATCH 1/6] move calc of HCR_anchor --- SS_benchfore.tpl | 56 +++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/SS_benchfore.tpl b/SS_benchfore.tpl index 45f031c0..a66eded9 100644 --- a/SS_benchfore.tpl +++ b/SS_benchfore.tpl @@ -2124,6 +2124,35 @@ FUNCTION void Get_Forecast() { Fcast_Fmult = 0.0; } + + if (Fcast_Loop_Control(5) == 1) + {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 + { + H4010_top = Bmsy / HCR_anchor; // convert to fraction of anchor + 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) == 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; + if (show_MSY == 1) // write more headers { report5 << "Annual_Forecast_Fmult: " << Fcast_Fmult << endl; @@ -2248,33 +2277,6 @@ FUNCTION void Get_Forecast() } } - if (Fcast_Loop_Control(5) == 1) - {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 - { - H4010_top = Bmsy / HCR_anchor; // convert to fraction of anchor - 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) == 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; 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 From e2a5d17df17a986d0f4c85016c18262ac24883f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 17:19:21 -0500 Subject: [PATCH 2/6] Bump actions/upload-artifact from 5 to 6 (#745) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test-simple-with-ss3-artifacts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-simple-with-ss3-artifacts.yml b/.github/workflows/test-simple-with-ss3-artifacts.yml index b4393e82..862800f2 100644 --- a/.github/workflows/test-simple-with-ss3-artifacts.yml +++ b/.github/workflows/test-simple-with-ss3-artifacts.yml @@ -107,7 +107,7 @@ jobs: fi - name: Archive Simple model output - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: simple-model-output-${{ matrix.os }} path: ss3-test-models/models/Simple/ From c6f8aa60f96b96ae4089ff4d2a309c15558f8092 Mon Sep 17 00:00:00 2001 From: Elizabeth Perl Date: Mon, 22 Dec 2025 11:44:27 -0500 Subject: [PATCH 3/6] Clarify Linf_decay description in SS_write_ssnew.tpl (#746) --- SS_write_ssnew.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SS_write_ssnew.tpl b/SS_write_ssnew.tpl index 82b51af4..b90ab9aa 100644 --- a/SS_write_ssnew.tpl +++ b/SS_write_ssnew.tpl @@ -1908,7 +1908,7 @@ FUNCTION void write_nucontrol() { report4 << AFIX << " #_Age(post-settlement) for L1 (aka Amin); first growth parameter is size at this age; linear growth below this" << endl << AFIX2 << " #_Age(post-settlement) for L2 (aka Amax); 999 to treat as Linf" << endl - << Linf_decay << " #_exponential decay for growth above maxage (value should approx initial Z; -999 replicates 3.24; -998 to not allow growth above maxage)" << endl; + << Linf_decay << " #_exponential decay of numbers for calc of size in plus group in the initial year (value should approx initial Z; -999 replicates 3.24; -998 to not calc growth above maxage)" << endl; report4 << "0 #_placeholder for future growth feature" << endl; if (Grow_type >= 3 && Grow_type <= 5) { From 5ebff202be6178fe788c65d281f4186501f8feb2 Mon Sep 17 00:00:00 2001 From: Rick-Methot-NOAA Date: Fri, 30 Jan 2026 14:15:32 -0800 Subject: [PATCH 4/6] first commit for narrow sizebin problem --- SS_expval.tpl | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/SS_expval.tpl b/SS_expval.tpl index df6fb5eb..f6d499ac 100644 --- a/SS_expval.tpl +++ b/SS_expval.tpl @@ -776,6 +776,7 @@ FUNCTION void Get_expected_values(const int y, const int t); { if (SzFreq_scale(SzFreqMethod) <= 2) // bin demarcations are in weight units (1=kg, 2=lbs), so uses wt_len to compare to bins { + warning<<"process_szfreq"<=topbin, so incr ibin "< 1) { botbin = SzFreq_bins2(SzFreqMethod, ibin); + warning<<" incr botbin to "<= topbin) + { + // this should have the fish in z size range distributed across all bins >= size(z) until get to overlap + warning<<" size > current bin, increment bin index "< Date: Mon, 2 Feb 2026 19:21:51 -0800 Subject: [PATCH 5/6] initial commit of rebin fxn --- SS_miscfxn.tpl | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/SS_miscfxn.tpl b/SS_miscfxn.tpl index 76964cb3..8886036c 100644 --- a/SS_miscfxn.tpl +++ b/SS_miscfxn.tpl @@ -120,3 +120,41 @@ FUNCTION dvariable Comp_logL_Dirichlet(const double& Nsamp, const dvariable& dir logL = sum(gammln(Nsamp * obs_comp + dirichlet_Parm * exp_comp)) - sum(gammln(dirichlet_Parm * exp_comp)); return (logL); } + +FUNCTION dvector rebin(const dvector& src_edges, const dvector& src_counts, const dvector& dest_edges) + { + /* + This implementation takes two vectors representing the boundaries (edges) of the source + and destination bins, and one vector for the source counts. + + Rebins frequency data from one set of boundaries to another. + @param src_edges Boundaries of the original bins (size N+1). + @param src_counts Frequency/counts in original bins (size N). + @param dest_edges Boundaries of the new bins (size M+1). + @return Vector of rebinned frequency data (size M). + */ + + dvector dest_counts(dest_edges.size() - 1, 0.0); + for (int i = 0; i < dest_counts.size(); ++i) { + double d_low = dest_edges[i]; + double d_high = dest_edges[i + 1]; + + for (int j = 0; j < src_counts.size(); ++j) { + double s_low = src_edges[j]; + double s_high = src_edges[j + 1]; + + // Calculate the overlap between [d_low, d_high] and [s_low, s_high] + double overlap_low = max(d_low, s_low); + double overlap_high = min(d_high, s_high); + + if (overlap_low < overlap_high) { + double overlap_width = overlap_high - overlap_low; + double src_bin_width = s_high - s_low; + + // Distribute source count proportionally to the overlap area + dest_counts[i] += src_counts[j] * (overlap_width / src_bin_width); + } + } + } + return (dest_counts); + } \ No newline at end of file From 7f10ed4845446ee9d983ba13e986232ca6d47df6 Mon Sep 17 00:00:00 2001 From: Rick-Methot-NOAA Date: Wed, 4 Feb 2026 14:39:00 -0800 Subject: [PATCH 6/6] WIP --- SS_expval.tpl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/SS_expval.tpl b/SS_expval.tpl index f6d499ac..ef9184e7 100644 --- a/SS_expval.tpl +++ b/SS_expval.tpl @@ -704,7 +704,7 @@ FUNCTION void Get_expected_values(const int y, const int t); { case (1): // units are biomass, so accumulate body weight into the bins; Assume that bin demarcations are also in biomass { - if (SzFreq_Omit_Small(SzFreqMethod) == 1) + if (SzFreq_Omit_Small(SzFreqMethod) == 1) { while (wt_len_low(s, 1, z1 + 1) < SzFreq_bins(SzFreqMethod, 1) && z1 < z2) { @@ -853,6 +853,23 @@ FUNCTION void Get_expected_values(const int y, const int t); else // bin demarcations are in length unit (3=cm, 4=inch) so uses population len_bins to compare to data bins { + /* wt_len_low(s, 1, z1 + 1) < SzFreq_bins(SzFreqMethod, 1) && z1 < z2) + FUNCTION dvector rebin(const dvector& src_edges, const dvector& src_counts, const dvector& dest_edges) + 3darray wt_len_low(1,nseas,1,N_GP,1,nlength2) // wt at lower edge of size bin + */ + dvector freq_in(1, z2-z1); // fill the input + freq_in = 1.; + echoinput << " z1: " << z1 << " z2: " << z2 << endl; + echoinput << " freq_in: " << freq_in << endl; + dvector bins_in(1, z2-z1); + bins_in = len_bins2(z1, z2); // input bins shifted + echoinput << " bins_in: " << bins_in << endl; +// dvector bins_out(1, z2-z1) = SzFreq_bins(SzFreqMethod + dvector freq_out(1, SzFreq_Nbins(SzFreqMethod)); + + freq_out = rebin(bins_in, freq_in, SzFreq_bins(SzFreqMethod)); + echoinput << " freq_out: " << freq_out << endl; + if (SzFreq_Omit_Small(SzFreqMethod) == 1) { while (len_bins2(z1 + 1) < SzFreq_bins(SzFreqMethod, 1))