"""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, }