From a0be8826f69fc2eea18a0f5c411b005f60e391d8 Mon Sep 17 00:00:00 2001 From: iantaylor-NOAA Date: Thu, 24 Sep 2026 14:36:35 -0700 Subject: [PATCH 1/2] add fatal errors for issues with Lbins - fixes #784 - related to https://github.com/nmfs-ost/ss3-doc/issues/339 --- SS_readdata_330.tpl | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/SS_readdata_330.tpl b/SS_readdata_330.tpl index bcb12c59..75ba236c 100644 --- a/SS_readdata_330.tpl +++ b/SS_readdata_330.tpl @@ -2589,6 +2589,13 @@ Lbin_lo(f, j) = Age_Data[i](7); Lbin_hi(f, j) = Age_Data[i](8); + // Methods 1 and 2 use bin indices, so reject fractional values before they are truncated. + if ((Lbin_method == 1 || Lbin_method == 2) && + (Lbin_lo(f, j) != int(Lbin_lo(f, j)) || Lbin_hi(f, j) != int(Lbin_hi(f, j)))) + { + warnstream << "Lbin_lo and Lbin_hi must be integers when Lbin_method is 1 or 2 in age comp " << header_a(f, j); + write_message(FATAL, 0); + } switch (Lbin_method) // here all 3 methods are converted to poplenbins for use internally { case 1: // values are population length bin numbers @@ -2613,7 +2620,7 @@ } if (s == 0) { - warnstream << "L_bin_lo no match to poplenbins in age comp " << header_a(f, j); + warnstream << "Lbin_lo no match to poplenbins in age comp " << header_a(f, j); write_message(FATAL, 0); } Lbin_lo(f, j) = s; @@ -2626,7 +2633,7 @@ } if (s == 0) { - warnstream << "L_bin_hi no match to poplenbins in age comp " << header_a(f, j); + warnstream << "Lbin_hi no match to poplenbins in age comp " << header_a(f, j); write_message(FATAL, 0); } Lbin_hi(f, j) = s; @@ -2646,7 +2653,7 @@ } if (s == 0) { - warnstream << "L_bin_lo no match to poplenbins in age comp " << header_a(f, j); + warnstream << "Lbin_lo no match to poplenbins in age comp " << header_a(f, j); write_message(FATAL, 0); } Lbin_lo(f, j) = s; @@ -2659,7 +2666,7 @@ } if (s == 0) { - warnstream << "L_bin_hi no match to poplenbins in age comp " << header_a(f, j); + warnstream << "Lbin_hi no match to poplenbins in age comp " << header_a(f, j); write_message(FATAL, 0); } Lbin_hi(f, j) = s; @@ -2667,10 +2674,23 @@ } } + // Lbin_hi is inclusive; reject ranges that share an endpoint with another range's lower bound. + for (int j1 = 1; j1 < j; j1++) + { + if ((Lbin_hi(f, j) > Lbin_lo(f, j) && Lbin_hi(f, j) == Lbin_lo(f, j1)) || + (Lbin_hi(f, j1) > Lbin_lo(f, j1) && Lbin_hi(f, j1) == Lbin_lo(f, j))) + { + warnstream << "overlapping Lbin ranges in age comps for fleet " << f + << ": " << Lbin_lo(f, j) << "-" << Lbin_hi(f, j) + << " and " << Lbin_lo(f, j1) << "-" << Lbin_hi(f, j1); + write_message(FATAL, 0); + } + } + // lbin_lo and lbin_hi are now in terms of poplenbins; their original values are retained in header_a if (Lbin_lo(f, j) > nlength || Lbin_lo(f, j) > Lbin_hi(f, j)) { - warnstream << "L_bin_lo is too high in age comp. Are you using lengths or bin numbers? " << header_a(f, j); + warnstream << "Lbin_lo is too high in age comp. Are you using lengths or bin numbers? " << header_a(f, j); write_message(FATAL, 0); } if (Lbin_lo(f, j) == 1 && Lbin_hi(f, j) == nlength) From 46ceff469cde5e505f299de09f67940eccd32acf Mon Sep 17 00:00:00 2001 From: iantaylor-NOAA Date: Mon, 26 Oct 2026 14:10:37 -0700 Subject: [PATCH 2/2] convert Lbin check to be more focused - copilot prompt: "please suggest a fix to this comment: https://github.com/nmfs-ost/ss3-source-code/pull/785#discussion_r4101280057" - It now compares earlier rows in the same fleet/ALK-time bucket and only treats matching year/month, sex, partition, and age-error type as the same observation context. --- SS_readdata_330.tpl | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/SS_readdata_330.tpl b/SS_readdata_330.tpl index 75ba236c..3b2caac1 100644 --- a/SS_readdata_330.tpl +++ b/SS_readdata_330.tpl @@ -2674,15 +2674,21 @@ } } - // Lbin_hi is inclusive; reject ranges that share an endpoint with another range's lower bound. - for (int j1 = 1; j1 < j; j1++) + // Lbin_hi is inclusive; compare overlapping ranges only within the same observation context. + for (int p1 = 1; p1 < p; p1++) { - if ((Lbin_hi(f, j) > Lbin_lo(f, j) && Lbin_hi(f, j) == Lbin_lo(f, j1)) || - (Lbin_hi(f, j1) > Lbin_lo(f, j1) && Lbin_hi(f, j1) == Lbin_lo(f, j))) + int previous_j = have_data(ALK_time, f, data_type, p1); + if (header_a(f, j, 1) == header_a(f, previous_j, 1) && + header_a(f, j, 2) == header_a(f, previous_j, 2) && + gen_a(f, j) == gen_a(f, previous_j) && + mkt_a(f, j) == mkt_a(f, previous_j) && + ageerr_type_a(f, j) == ageerr_type_a(f, previous_j) && + ((Lbin_hi(f, j) > Lbin_lo(f, j) && Lbin_hi(f, j) == Lbin_lo(f, previous_j)) || + (Lbin_hi(f, previous_j) > Lbin_lo(f, previous_j) && Lbin_hi(f, previous_j) == Lbin_lo(f, j)))) { warnstream << "overlapping Lbin ranges in age comps for fleet " << f << ": " << Lbin_lo(f, j) << "-" << Lbin_hi(f, j) - << " and " << Lbin_lo(f, j1) << "-" << Lbin_hi(f, j1); + << " and " << Lbin_lo(f, previous_j) << "-" << Lbin_hi(f, previous_j); write_message(FATAL, 0); } }