[Animal] Add set_DMI and set_DMI_per_X intake options for user-defined rations - #3248
matthew7838 wants to merge 52 commits into
Conversation
Implements the DMI control features from the feed intake control design doc (#3113/#3213): new optional intake_option and intake_value ration inputs, target-DMI resolution in RationManager, neutralized DMI adjustment constants when a DMI input option is used, a single formulation attempt when milk reduction is disallowed, cross-validation rules for the new inputs, and a CrossValidator fix so multi-rule blocks fail when any rule fails.
Growing pens have no daily gain before the first growth update, which made set_DMI_per_X resolve a zero intake target and crash nutrient supply calculations on the first formulation. Falls back to the predicted dry matter requirement for that formulation and logs a warning.
1a4270d to
108e976
Compare
108e976 to
992f974
Compare
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1153 |
Replaces the TYPE_CHECKING Pen import with Any and converts the returns that read from the pen to float, so the mypy error count stays level.
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1145 |
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1145 |
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1133 |
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1164 |
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1164 |
|
🚨 Unauthorized changes detected in protected files. Please remove these changes if they are not intended. |
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1164 |
|
🚨 Unauthorized changes detected in protected files. Please remove these changes if they are not intended. |
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1164 |
|
🚨 Unauthorized changes detected in protected files. Please remove these changes if they are not intended. |
|
Current Coverage: 99% Mypy errors on dmi-intake-options-3213 branch: 1164 |
|
🚨 Unauthorized changes detected in protected files. Please remove these changes if they are not intended. |
| "intake_value": { | ||
| "type": "number", | ||
| "description": "Dry matter intake value used for the ration of this animal combination. Units are kg/animal/day for set_DMI, and kg dry matter intake per kg milk yield (lac_cow) or per kg average daily gain (growing) for set_DMI_per_X. Ignored when intake_option is predict_DMI.", | ||
| "minimum": 0, | ||
| "nullable": true, | ||
| "default": null | ||
| }, |
There was a problem hiding this comment.
I think the config here allows intake_value = 0. There should be a safeguard somewhere to make sure this value is positive, possibly in the cross_validation
Adds user control over dry matter intake for user-defined rations, implementing the DMI control features design doc.
Context
Part of #3213 (tracker issue #3113). This is the testing branch for SME review.
What
intake_option(predict_DMI(default) |set_DMI|set_DMI_per_X) andintake_value.set_DMIfixes intake atintake_value(kg/animal/day) for any animal combination, including calves (overriding the hard-coded 3 kg).set_DMI_per_Xsets intake tointake_value× the pen's average milk yield (lac_cow) or average daily gain (growing) at each formulation. If the X value is not positive (e.g. no growth computed yet on day 1), the predicted requirement is used for that formulation and a warning is logged.DMI_CONSTRAINT_FRACTION=0.0,DMI_REQUIREMENT_BOOST=1.0,DMI_RETRY_INCREASE_FACTOR=1.0, so intake deviates from the target only by the user-defined tolerance.milk_reduction_maximumis 0, since retries could only alter the user-designated intake or production.feed_cross_validation.json, wired into all feed-loading tasks):set_DMI_per_Xonly for growing/lac_cow withintake_valuein (0, 100); non-predict options requireintake_value;predict_DMIrequires it to be null.CrossValidatorbug where only the last rule of a multi-rule block determined the block result in non-eager mode.Why
NASEM-predicted DMI is currently the only option, which limits representing real farms where observed DMI is known. See the design doc for details.
How
RationManagerparses the new inputs, resolves the target DMI per animal combination (resolve_target_dmi), and exposes the effective DMI constants;Penseeds formulation with the resolved target and uses it for the user-defined ration fallback;RationConfigcarries the effective constants into the optimizer constraints and bounds. The predict path is unchanged.Test plan
devcheckout on the same machine (Animal/Manure/Feed passing; the CropAndSoil failures reproduce identically ondevand are unrelated).set_DMIevery pen consumes exactly the input value every day; withset_DMI_per_Xthe formulated intake matchesintake_value× pen ADG to 4 decimal places at each formulation.InputManagerruns: 11 valid/violating feed inputs in both eager and non-eager modes behave as intended; existing inputs validate unchanged.dev.Input Changes
intake_optionandintake_valueto entries of therationsblob in the feed input file. Both default to current behavior (predict_DMI), so existing input files run unchanged.input/metadata/cross_validation/feed_cross_validation.jsonand listed it inavailable_simulation_tasks.json,end_to_end_testing_task.json, andsingle_run.json(the protected example task files are left unchanged).Output Changes
RationManager.set_intake_options.dmi_intake_option: new variable recording the selected DMI option (with the intake value in its info map) per animal combination when rations are user-defined. No existing output variables changed.Filter
{ "name": "dmi_intake_options", "filters": [ "RationManager.set_intake_options.dmi_intake_option" ] }