From 773064f05c54ebe6971ddcf7be4336d5b8d23c3e Mon Sep 17 00:00:00 2001 From: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com> Date: Thu, 2 Jul 2026 20:21:27 +0000 Subject: [PATCH] Fix off-by-one in 1-indexed loops (frag_picker, job & metric accounting) Split from #707. Enumeration/accounting loops that use 'for ( i = 1; i < container.size(); ++i )' with i as a direct 1-indexed accessor, silently skipping the last element. Changed < to <=. - frag_picker/GrabAllCollector.hh (clear) - frag_picker/VallProvider.cc (find_chunk) - frag_picker/quota/QuotaCollector.cc x5 (per-position pool enumeration) - frag_picker/scores/AtomBasedConstraintsScore.cc x2 (constrainable_atoms map fill, per-row state init) - jd3/JobGenealogist.cc (newick_tree) - pose_metric_calculators/DecomposeAndReweightEnergiesCalculator.cc - pose_metric_calculators/SurfaceCalculator.cc (per-residue summary string) - canonical_sampling/mc_convergence_checks/HierarchicalLevel.cc (address match count) - unfolded_state_energy_calculator/UnfoldedStateEnergyCalculatorMover.cc (protein-residue count) Note: the unfolded_state_energy_calc regression test output changes with this batch (the trailing residue is now counted); the change is intentional and warrants scientific sign-off before merge. --- .../mc_convergence_checks/HierarchicalLevel.cc | 2 +- source/src/protocols/frag_picker/GrabAllCollector.hh | 2 +- source/src/protocols/frag_picker/VallProvider.cc | 2 +- .../src/protocols/frag_picker/quota/QuotaCollector.cc | 10 +++++----- .../frag_picker/scores/AtomBasedConstraintsScore.cc | 4 ++-- source/src/protocols/jd3/JobGenealogist.cc | 2 +- .../DecomposeAndReweightEnergiesCalculator.cc | 2 +- .../pose_metric_calculators/SurfaceCalculator.cc | 2 +- .../UnfoldedStateEnergyCalculatorMover.cc | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source/src/protocols/canonical_sampling/mc_convergence_checks/HierarchicalLevel.cc b/source/src/protocols/canonical_sampling/mc_convergence_checks/HierarchicalLevel.cc index ce7da4ccb58..08427391561 100644 --- a/source/src/protocols/canonical_sampling/mc_convergence_checks/HierarchicalLevel.cc +++ b/source/src/protocols/canonical_sampling/mc_convergence_checks/HierarchicalLevel.cc @@ -307,7 +307,7 @@ HierarchicalLevel::num_matching_levels( utility::vector1< core::Size > & address utility::vector1< core::Size > & address2 ){ runtime_assert( address1.size() == address2.size() ); core::Size num_matching_levels = 0; - for ( core::Size ii = 1; ii < address1.size(); ii++ ) { + for ( core::Size ii = 1; ii <= address1.size(); ii++ ) { if ( address1[ ii ] == address2[ ii ] ) { num_matching_levels++; } diff --git a/source/src/protocols/frag_picker/GrabAllCollector.hh b/source/src/protocols/frag_picker/GrabAllCollector.hh index 67209136fa0..7a75c17ad1c 100644 --- a/source/src/protocols/frag_picker/GrabAllCollector.hh +++ b/source/src/protocols/frag_picker/GrabAllCollector.hh @@ -66,7 +66,7 @@ public: inline void clear() override { - for ( core::Size i=1; iget_chain_id() != chain_id ) { continue; } - for ( core::Size j = 1; j < c->size(); ++j ) { + for ( core::Size j = 1; j <= c->size(); ++j ) { if ( c->at(j)->resi() == residue_id ) { return c; } diff --git a/source/src/protocols/frag_picker/quota/QuotaCollector.cc b/source/src/protocols/frag_picker/quota/QuotaCollector.cc index bf0ecc8cc19..c2fdcfc3947 100644 --- a/source/src/protocols/frag_picker/quota/QuotaCollector.cc +++ b/source/src/protocols/frag_picker/quota/QuotaCollector.cc @@ -51,9 +51,9 @@ bool QuotaCollector::add(std::pairget_pool_name() << "(" << std::setw(3) << storage_[i][j]->total_size() << ") "; } where << std::endl; @@ -64,7 +64,7 @@ void QuotaCollector::list_pools(std::ostream & where) const { void QuotaCollector::clear() { for ( core::Size i=1; i<=storage_.size(); ++i ) { - for ( core::Size j=1; jclear(); } } @@ -73,7 +73,7 @@ void QuotaCollector::clear() { core::Size QuotaCollector::count_candidates(core::Size pos) const { core::Size cnt = 0; - for ( core::Size j=1; jcount_candidates(); } @@ -83,7 +83,7 @@ core::Size QuotaCollector::count_candidates(core::Size pos) const { core::Size QuotaCollector::count_candidates() const { core::Size cnt = 0; for ( core::Size i=1; i<=storage_.size(); ++i ) { - for ( core::Size j=1; jcount_candidates(); } } diff --git a/source/src/protocols/frag_picker/scores/AtomBasedConstraintsScore.cc b/source/src/protocols/frag_picker/scores/AtomBasedConstraintsScore.cc index 80b7d3f0a7d..71417799240 100644 --- a/source/src/protocols/frag_picker/scores/AtomBasedConstraintsScore.cc +++ b/source/src/protocols/frag_picker/scores/AtomBasedConstraintsScore.cc @@ -46,7 +46,7 @@ AtomBasedConstraintsScore::AtomBasedConstraintsScore(core::Size priority, CachingScoringMethod(priority, lowest_acceptable_value, use_lowest, score_name) { query_size_ = query_size; - for ( core::Size i = 1; i < constrainable_atoms.size(); ++i ) { + for ( core::Size i = 1; i <= constrainable_atoms.size(); ++i ) { constrainable_atoms_.insert(std::pair( constrainable_atoms[i], i)); } @@ -97,7 +97,7 @@ void AtomBasedConstraintsScore::do_caching(VallChunkOP chunk) { utility::vector1 flag_row(constrainable_atoms_.size()); utility::vector1 > row( constrainable_atoms_.size()); - for ( core::Size j = 1; j < constrainable_atoms_.size(); ++j ) { + for ( core::Size j = 1; j <= constrainable_atoms_.size(); ++j ) { flag_row[j] = false; row[j] = empty_one; } diff --git a/source/src/protocols/jd3/JobGenealogist.cc b/source/src/protocols/jd3/JobGenealogist.cc index 1cfef3d7066..1f8fe97ed4a 100644 --- a/source/src/protocols/jd3/JobGenealogist.cc +++ b/source/src/protocols/jd3/JobGenealogist.cc @@ -437,7 +437,7 @@ JobGenealogist::newick_tree() const { utility::vector1< std::list< JGResultNodeCAP > > parentless_results_for_input_source; parentless_results_for_input_source.resize( num_input_sources_ ); - for ( unsigned int i = 1; i < job_nodes_for_dag_node_.size(); ++i ) { + for ( unsigned int i = 1; i <= job_nodes_for_dag_node_.size(); ++i ) { for ( auto const & job_node_cop : job_nodes_for_dag_node_[ i ] ) { debug_assert( job_node_cop != nullptr ); if ( job_node_cop->parents().empty() ) { diff --git a/source/src/protocols/pose_metric_calculators/DecomposeAndReweightEnergiesCalculator.cc b/source/src/protocols/pose_metric_calculators/DecomposeAndReweightEnergiesCalculator.cc index 75a576c40a9..df8518cb5b1 100644 --- a/source/src/protocols/pose_metric_calculators/DecomposeAndReweightEnergiesCalculator.cc +++ b/source/src/protocols/pose_metric_calculators/DecomposeAndReweightEnergiesCalculator.cc @@ -418,7 +418,7 @@ DecomposeAndReweightEnergiesCalculator::nonzero_weight_score_types() const utility::vector1 score_types; for ( int i = 1; i < core::scoring::n_score_types; ++i ) { - for ( core::Size j = 1; j < weight_map_vector.size(); ++j ) { + for ( core::Size j = 1; j <= weight_map_vector.size(); ++j ) { if ( weight_map_vector[j][core::scoring::ScoreType(i)] ) { score_types.push_back(core::scoring::ScoreType(i)); break; diff --git a/source/src/protocols/pose_metric_calculators/SurfaceCalculator.cc b/source/src/protocols/pose_metric_calculators/SurfaceCalculator.cc index f10a87297b7..405f6384afd 100644 --- a/source/src/protocols/pose_metric_calculators/SurfaceCalculator.cc +++ b/source/src/protocols/pose_metric_calculators/SurfaceCalculator.cc @@ -82,7 +82,7 @@ SurfaceCalculator::print( std::string const & key ) const { } else if ( key == "residue_surface" ) { std::ostringstream ss; ss << "["; - for ( core::Size ii=1; ii < residue_surface_energy_.size(); ++ii ) { + for ( core::Size ii=1; ii <= residue_surface_energy_.size(); ++ii ) { ss << ii << ":"; if ( residue_surface_energy_[ ii ] != 0.00 ) { ss << ObjexxFCL::format::F(8,4, residue_surface_energy_[ ii ]); diff --git a/source/src/protocols/unfolded_state_energy_calculator/UnfoldedStateEnergyCalculatorMover.cc b/source/src/protocols/unfolded_state_energy_calculator/UnfoldedStateEnergyCalculatorMover.cc index 377af5629f8..a8781df8b8f 100644 --- a/source/src/protocols/unfolded_state_energy_calculator/UnfoldedStateEnergyCalculatorMover.cc +++ b/source/src/protocols/unfolded_state_energy_calculator/UnfoldedStateEnergyCalculatorMover.cc @@ -116,7 +116,7 @@ UnfoldedStateEnergyCalculatorMover::create_random_fragments( Pose & pose, vector { // get number of protein residues core::Size num_protein_res( 0 ); - for ( core::Size i = 1; i < pose.size(); ++i ) { + for ( core::Size i = 1; i <= pose.size(); ++i ) { if ( pose.residue( i ).type().is_protein() ) { num_protein_res++; }