Skip to content

[Animal][Ration] Refactor Pen.formulate_optimized_ration()#3043

Merged
matthew7838 merged 52 commits into
devfrom
refactor-pen
Jun 17, 2026
Merged

[Animal][Ration] Refactor Pen.formulate_optimized_ration()#3043
matthew7838 merged 52 commits into
devfrom
refactor-pen

Conversation

@matthew7838

@matthew7838 matthew7838 commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Refactor Pen.formulate_optimized_ration() to remove the # noqa: C901 complexity suppression. Reduces complexity from 13 to 2 by extracting four focused helpers, hoists magic values into named class constants, and tightens a few adjacent rough edges in _attempt_formulation.

Context

Issue(s) closed by this pull request: closes #2846

What

  • Removed # noqa: C901 from formulate_optimized_ration.
  • Extracted four new private helpers:
    • _run_formulation_attempts — the entire while-loop driving repeated optimization attempts.
    • _maybe_increased_dmi_for_retry — returns a bumped DMI value (or None) when a user-defined-ration retry is warranted.
    • _handle_lactation_failure_in_loop — dispatches between the user-defined vs. auto lactation-failure handlers and returns whether the loop should stop.
    • _finalize_ration_outcome — handles the post-loop apply / log / error chain.
  • Added two class-level constants:
    • _DMI_INCREASE_CONSTRAINTS — frozenset of the constraint names that signal a DMI retry could help (was built inline every loop iteration).
    • _DMI_RETRY_INCREASE_FACTOR = 1.1 — replaces the bare magic number.
  • Renamed the confusing pair initial_dry_matter_requirement / initial_dry_matter_requirement_fixed → current_dmi_requirement / original_dmi_requirement. The new names tell you which one is the loop-mutable copy and which is the snapshot.
  • Dropped the defensive getattr(self, "ration", None) in favor of direct self.ration — the attribute is always set by init, so the fallback was dead code that obscured intent and broadened the type.
  • Cleaned up _attempt_formulation:
    • Replaced two 4-line if/else blocks (user_defined_ration_dictionary, tolerance) with one-liner ternaries.
    • Replaced list(self.animals_in_pen.values())[0] with next(iter(...)) (no throwaway list).
    • Extracted the NASEM averaging block into a new _pen_nasem_averages() helper.
    • Added the missing temperature parameter to the docstring.

Why

formulate_optimized_ration had a McCabe complexity of 13 (suppressed with # noqa: C901), making it hard to read, hard to test in isolation, and hard to extend.

How

Reduced complexity.

Test plan

  • Run with updated unit tests.
  • e2e testing assuring no output change.

Input Changes

Output Changes

  • N/A

Filter

@github-actions

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1155
Mypy errors on dev branch: 1155
No difference in error counts

@github-actions

Copy link
Copy Markdown
Contributor

🚨 Please update the changelog. This PR cannot be merged until changelog.md is updated.

@github-actions

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1155
Mypy errors on dev branch: 1155
No difference in error counts

@github-actions

Copy link
Copy Markdown
Contributor

🚨 Please update the changelog. This PR cannot be merged until changelog.md is updated.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1145
Mypy errors on dev branch: 1145
No difference in error counts

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

🚨 Please update the changelog. This PR cannot be merged until changelog.md is updated.

matthew7838 and others added 4 commits June 3, 2026 17:27
Resolved two docstring conflicts in RUFAS/biophysical/animal/pen.py:
- remove_animals_by_ids: kept origin's Notes block (O(n) cost explanation)
- update_animal_combination: kept HEAD's full-sentence description

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1145
Mypy errors on dev branch: 1145
No difference in error counts

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

🚨 Please update the changelog. This PR cannot be merged until changelog.md is updated.

@matthew7838 matthew7838 marked this pull request as ready for review June 3, 2026 09:18
@matthew7838 matthew7838 requested a review from JoeWaddell June 3, 2026 09:19
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1145
Mypy errors on dev branch: 1145
No difference in error counts

@tomhuhh tomhuhh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Human review passed too, with one caveat.

The outputs remained identical for 3 of the 4 example diets tested. See the summary plot below.

Image

NE diet failed because 176 is missing from the top-level available feeds list. Please fix this before merging.

@github-actions

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1144
Mypy errors on dev branch: 1144
No difference in error counts

@github-actions

Copy link
Copy Markdown
Contributor

🚨 Please update the changelog. This PR cannot be merged until changelog.md is updated.

@matthew7838

Copy link
Copy Markdown
Collaborator Author

Human review passed too, with one caveat.

The outputs remained identical for 3 of the 4 example diets tested. See the summary plot below.

Image NE diet failed because 176 is missing from the top-level available feeds list. Please fix this before merging.

@tomhuhh , can you elaborate a little bit more on this? I'm a little bit confused about exactly where to add the top-level available feeds(which input file?). Also, I'm assuming it's missing/failing for both dev and this branch from looking at the graph, is that right? Or is it something I removed on this PR?

@JoeWaddell JoeWaddell left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Tested on a few rations and it performs just as it does on dev. Good job tidying this up.

Comment thread RUFAS/biophysical/animal/pen.py Outdated
Comment on lines +113 to +127
# Constraint failures that indicate a lactating-cow ration retry should bump the dry matter intake.
_DMI_INCREASE_CONSTRAINTS: frozenset[str] = frozenset(
{
"NE_total_constraint",
"NE_maintenance_and_activity_constraint",
"NE_lactation_constraint",
"NE_growth_constraint",
"calcium_constraint",
"phosphorus_constraint",
"protein_constraint_lower",
"DMI_constraint_lower",
}
)
# Multiplier applied to the dry matter intake when a lactating-cow ration retry is warranted.
_DMI_RETRY_INCREASE_FACTOR: float = 1.1

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also wonder if the _DMI_RETRY_INCREASE_FACTOR should be defined in animal_module_constants.py

@JoeWaddell

Copy link
Copy Markdown
Collaborator

Human review passed too, with one caveat.
The outputs remained identical for 3 of the 4 example diets tested. See the summary plot below.
Image
NE diet failed because 176 is missing from the top-level available feeds list. Please fix this before merging.

@tomhuhh , can you elaborate a little bit more on this? I'm a little bit confused about exactly where to add the top-level available feeds(which input file?). Also, I'm assuming it's missing/failing for both dev and this branch from looking at the graph, is that right? Or is it something I removed on this PR?

It's also failing on dev! Needs the pricing/buffer info. Tested the example Northeast feed file and found it as well.

@github-actions

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1144
Mypy errors on dev branch: 1144
No difference in error counts

@github-actions

Copy link
Copy Markdown
Contributor

🚨 Please update the changelog. This PR cannot be merged until changelog.md is updated.

@matthew7838 matthew7838 self-assigned this Jun 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1144
Mypy errors on dev branch: 1144
No difference in error counts

@github-actions

Copy link
Copy Markdown
Contributor

🚨 Please update the changelog. This PR cannot be merged until changelog.md is updated.
🚨 Unauthorized changes detected in protected files. Please remove these changes if they are not intended.

@github-actions

Copy link
Copy Markdown
Contributor

Current Coverage: 99%

Mypy errors on refactor-pen branch: 1144
Mypy errors on dev branch: 1144
No difference in error counts

@github-actions

Copy link
Copy Markdown
Contributor

🚨 Unauthorized changes detected in protected files. Please remove these changes if they are not intended.

@matthew7838 matthew7838 merged commit 67665e6 into dev Jun 17, 2026
1 check passed
@matthew7838 matthew7838 deleted the refactor-pen branch June 17, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Animal][Ration] Refactor Pen.formulate_optimized_ration()

4 participants