@@ -0,0 +1,84 @@
|
||||
"""WESP-политики расчёта на базе GfE 2001 (отличия от zootech Excel — осознанные)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
||||
FeedGroup = Literal["rough", "succulent", "concentrate", "other", "unknown"]
|
||||
|
||||
# --- GfE 2001 константы (формулы не меняем) ---
|
||||
NEL_Q_COEFF = 0.004
|
||||
NEL_Q_REF_PCT = 57.0
|
||||
NEL_BASE = 0.6
|
||||
|
||||
GE_CP = 0.0239
|
||||
GE_FAT = 0.0398
|
||||
GE_FIBER = 0.0201
|
||||
GE_NFE = 0.0175
|
||||
|
||||
ME_FAT = 0.0312
|
||||
ME_FIBER = 0.0136
|
||||
ME_OR_RESIDUE = 0.0147
|
||||
ME_CP = 0.00234
|
||||
|
||||
USP_FAT_THRESHOLD_G_PER_KG_DM = 70.0 # 7% СЖ/кг СВ
|
||||
|
||||
# DCAB (Na+K)-(Cl+S), мэкв при минералах в г/кг СВ
|
||||
DCAB_NA = 43.5
|
||||
DCAB_K = 25.6
|
||||
DCAB_CL = 28.2
|
||||
DCAB_S = 62.4
|
||||
|
||||
# Дефолты переваримости при пустых коэфф. (Excel legacy, кроме ОВ)
|
||||
DEFAULT_CP_DIGEST_PCT = 86.0
|
||||
DEFAULT_FAT_DIGEST_PCT = 75.0
|
||||
DEFAULT_FIBER_DIGEST_PCT = 86.0
|
||||
DEFAULT_NFE_DIGEST_PCT = 94.0
|
||||
DEFAULT_INSOLUBLE_PROTEIN_PCT = 15.0
|
||||
DEFAULT_PROTEIN_FRACTION_PCT = 18.9
|
||||
|
||||
# WESP: дефолт ВРХ орг. вещ. при пустом поле — по классу корма
|
||||
DEFAULT_OMD_ROUGH_PCT = 65.0
|
||||
DEFAULT_OMD_SUCCULENT_PCT = 72.0
|
||||
DEFAULT_OMD_CONCENTRATE_PCT = 91.0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DeriveContext:
|
||||
feed_group: FeedGroup = "unknown"
|
||||
is_main_feed: bool = False
|
||||
|
||||
@classmethod
|
||||
def from_cells(cls, *, main_feed_g: float = 0.0, feed_group: FeedGroup = "unknown") -> DeriveContext:
|
||||
return cls(
|
||||
feed_group=feed_group,
|
||||
is_main_feed=main_feed_g > 0,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def infer_from_cells(cls, cells: dict[str, float], feed_group: FeedGroup = "unknown") -> DeriveContext:
|
||||
main_feed = cells.get("E", 0.0)
|
||||
return cls.from_cells(main_feed_g=main_feed, feed_group=feed_group)
|
||||
|
||||
|
||||
def default_om_digestibility_pct(ctx: DeriveContext | None) -> float:
|
||||
"""Дефолт переваримости ОВ (%) при отсутствии ВРХ Орг Вещ."""
|
||||
if ctx is None:
|
||||
return DEFAULT_OMD_CONCENTRATE_PCT
|
||||
if ctx.is_main_feed or ctx.feed_group == "rough":
|
||||
return DEFAULT_OMD_ROUGH_PCT
|
||||
if ctx.feed_group == "succulent":
|
||||
return DEFAULT_OMD_SUCCULENT_PCT
|
||||
return DEFAULT_OMD_CONCENTRATE_PCT
|
||||
|
||||
|
||||
def default_digestibility_coefficients() -> dict[str, float]:
|
||||
return {
|
||||
"cp": DEFAULT_CP_DIGEST_PCT,
|
||||
"fat": DEFAULT_FAT_DIGEST_PCT,
|
||||
"fiber": DEFAULT_FIBER_DIGEST_PCT,
|
||||
"nfe": DEFAULT_NFE_DIGEST_PCT,
|
||||
"insoluble_protein": DEFAULT_INSOLUBLE_PROTEIN_PCT,
|
||||
"protein_fraction": DEFAULT_PROTEIN_FRACTION_PCT,
|
||||
}
|
||||
Reference in New Issue
Block a user