lactationcurve

A package for fitting dairy animal lactation curves, evaluating lactation curve characteristics (LCCs) (time to peak, peak yield, cumulative yield, persistency), and computing 305-day milk yield using the ICAR guideline.

Contact: Meike van Leerdam, mbv32@cornell.edu

Authors: Meike van Leerdam,Judith Osei-Tete, Douwe de Kok, Lucia Trapanese

Initial authored: 2025‑08‑12

Updated: 2026‑02‑24


Main Lactation curve models implemented:

MilkBot: Flexible four-parameter model describing rise, peak, and decline. (Both frequentist and Bayesian fitting available)

Wood: Incomplete gamma function; most popular due to its simplicity, its stability in the presence of missing data, and its computational ease.

Wilmink: Linear–exponential hybrid model, with fixed or estimated decay rate.

Ali & Schaeffer: Polynomial-logarithmic model with a linear regression component for more complex curve shapes.

Fischer: Simple exponential decay model.

Additional models available for a.o. symbolic LCC derivations: Brody, Sikka, Nelder, Dhanoa, Emmans, Hayashi, Rook, Dijkstra, Prasad.


Model Formulas

  • Wood : y(t) = a * t^b * exp(-c * t)
  • Wilmink : y(t) = a + b * t + c * exp(k * t) with default k = -0.05
  • Ali & Schaeffer : t_scaled = t / 305, L = ln(305 / t)

    y(t) = a + b*t_scaled + c*t_scaled^2 + d*L + k*L^2

  • Fischer : y(t) = a - b*t - a*exp(-c*t)
  • MilkBot : y(t) = a * (1 - exp((c - t)/b) / 2) * exp(-d*t)

Features

  • Frequentist fitting (numeric optimization & least squares):
    • Wood, Wilmink, Ali & Schaeffer, Fischer, MilkBot
  • Bayesian fitting via MilkBot API:
    • MilkBot
  • Lactation Curve Characteristics — symbolic + numeric:
    • time_to_peak, peak_yield, cumulative_milk_yield, persistency
  • ICAR procedures cumulative milk yield:
    • Test Interval Method
  • Input validation/normalization via validate_and_prepare_inputs
  • Caching of symbolic expressions for performance

API Overview

The package is organized into three main modules:

  1. lactationcurve.fitting
  2. lactationcurve.characteristics
  3. lactationcurve.preprocessing

Output Types Summary Of Most Important Functions

| Function | Output |

|---------|--------|

| fit_lactation_curve | Predicted yields (np.ndarray) |

| get_lc_parameters | Tuple of numerical parameters |

| bayesian_fit_milkbot_single_lactation | Dict of MilkBot parameters |

| lactation_curve_characteristic_function | (expr, params, func) |

| calculate_characteristic | float (LCC value) |

| test_interval_method | DataFrame with 305‑day totals |


Bayesian Fitting (MilkBot API)

  • Set fitting="bayesian" and model="milkbot" in fit_lactation_curve or calculate_characteristic.
  • Provide an API key via .env
  • Choose priors via continent="USA" | "EU" | "CHEN" (CHEN supplies published priors from literature).
  • The helper bayesian_fit_milkbot_single_lactation(...) normalizes differing API responses.
  • The key can be requested by sending an email to Jim Ehrlich jehrlich@MilkBot.com.
  • More information about the API can be found in the API documentation, or in the corresponding paper.

Citing the lactationcurve package

If you use the lactationcurve package in your research, please consider citing it as follows:

van Leerdam, M. B., de Kok, D., Osei-Tete, J. A., & Hostens, M. (2026). Bovi-analytics/lactation_curve_core: v.0.1.0. (v.0.1.0). Zenodo. https://doi.org/10.5281/zenodo.18715145

If you also use the Bayesian fitting functionality that relies on the MilkBot API, please also cite the following paper:

Ehrlich, J.L., 2013. Quantifying inter-group variability in lactation curve shape and magnitude with the MilkBot lactation model. PeerJ 1, e54. https://doi.org/10.7717/peerj.54


License

MIT License


Current version of the package

  1"""
  2
  3A package for fitting **dairy animal lactation curves**, evaluating
  4**lactation curve characteristics (LCCs)** (time to peak, peak yield,
  5cumulative yield, persistency), and computing **305-day milk yield**
  6using the **ICAR guideline**.
  7
  8> **Contact:** Meike van Leerdam, mbv32@cornell.edu
  9>
 10> **Authors:** Meike van Leerdam,Judith Osei-Tete, Douwe de Kok, Lucia Trapanese
 11
 12> **Initial authored:** 2025‑08‑12
 13
 14> **Updated:** 2026‑02‑24
 15
 16---
 17
 18## Main Lactation curve models implemented:
 19
 20MilkBot: Flexible four-parameter model describing rise, peak,
 21and decline. (Both frequentist and Bayesian fitting available)
 22
 23Wood: Incomplete gamma function; most popular due to its simplicity,
 24its stability in the presence of missing data, and its
 25computational ease.
 26
 27Wilmink: Linear–exponential hybrid model, with fixed or estimated decay rate.
 28
 29Ali & Schaeffer: Polynomial-logarithmic model with a linear
 30regression component for more complex curve shapes.
 31
 32Fischer: Simple exponential decay model.
 33
 34Additional models available for a.o. symbolic LCC derivations:
 35**Brody**, **Sikka**, **Nelder**, **Dhanoa**, **Emmans**,
 36**Hayashi**, **Rook**, **Dijkstra**, **Prasad**.
 37
 38---
 39
 40## Model Formulas
 41
 42* **Wood** : `y(t) = a * t^b * exp(-c * t)`
 43* **Wilmink** : `y(t) = a + b * t + c * exp(k * t)` with default `k = -0.05`
 44* **Ali & Schaeffer** :  `t_scaled = t / 305`, `L = ln(305 / t)`
 45
 46  `y(t) = a + b*t_scaled + c*t_scaled^2 + d*L + k*L^2`
 47* **Fischer** : `y(t) = a - b*t - a*exp(-c*t)`
 48* **MilkBot** : `y(t) = a * (1 - exp((c - t)/b) / 2) * exp(-d*t)`
 49
 50---
 51
 52## Features
 53
 54- **Frequentist fitting** (numeric optimization & least squares):
 55  - Wood, Wilmink, Ali & Schaeffer, Fischer, MilkBot
 56- **Bayesian fitting via MilkBot API**:
 57  - MilkBot
 58- **Lactation Curve Characteristics** — symbolic + numeric:
 59  - time_to_peak, peak_yield, cumulative_milk_yield, persistency
 60- **ICAR procedures cumulative milk yield:**
 61  - Test Interval Method
 62- Input validation/normalization via `validate_and_prepare_inputs`
 63- Caching of symbolic expressions for performance
 64
 65---
 66
 67## API Overview
 68
 69The package is organized into three main modules:
 70
 711. `lactationcurve.fitting`
 722. `lactationcurve.characteristics`
 733. `lactationcurve.preprocessing`
 74
 75---
 76
 77## Output Types Summary Of Most Important Functions
 78
 79| Function | Output |
 80
 81|---------|--------|
 82
 83| `fit_lactation_curve` | Predicted yields (np.ndarray) |
 84
 85| `get_lc_parameters` | Tuple of numerical parameters |
 86
 87| `bayesian_fit_milkbot_single_lactation` | Dict of MilkBot parameters |
 88
 89| `lactation_curve_characteristic_function` | (expr, params, func) |
 90
 91| `calculate_characteristic` | float (LCC value) |
 92
 93| `test_interval_method` | DataFrame with 305‑day totals |
 94
 95---
 96
 97## Bayesian Fitting (MilkBot API)
 98
 99* Set `fitting="bayesian"` and `model="milkbot"` in
100  `fit_lactation_curve` or `calculate_characteristic`.
101* Provide an **API key** via .env
102* Choose priors via `continent="USA" | "EU" | "CHEN"`
103  ([CHEN](https://github.com/Bovi-analytics/Chen-et-al-2023b)
104  supplies published priors from literature).
105* The helper `bayesian_fit_milkbot_single_lactation(...)`
106  normalizes differing API responses.
107* The key can be requested by sending an email to Jim Ehrlich
108  [jehrlich@MilkBot.com](mailto:jehrlich@MilkBot.com).
109* More information about the API can be found in the
110  [API documentation](https://api.milkbot.com/), or in the
111  corresponding
112  [paper](https://peerj.com/articles/54/#MainContent).
113
114---
115
116## Citing the lactationcurve package
117
118If you use the `lactationcurve` package in your research, please consider citing it as follows:
119
120*van Leerdam, M. B., de Kok, D., Osei-Tete, J. A., &
121Hostens, M. (2026). Bovi-analytics/lactation_curve_core:
122v.0.1.0. (v.0.1.0). Zenodo.
123https://doi.org/10.5281/zenodo.18715145*
124
125
126If you also use the Bayesian fitting functionality that relies
127on the MilkBot API, please also cite the following paper:
128
129*Ehrlich, J.L., 2013. Quantifying inter-group variability
130in lactation curve shape and magnitude with the MilkBot
131lactation model. PeerJ 1, e54.
132https://doi.org/10.7717/peerj.54*
133
134---
135
136## License
137
138[MIT License](https://github.com/Bovi-analytics/lactation_curve_core/blob/master/LICENSE)
139
140
141---
142
143## Current version of the package
144
145"""
146
147
148# import submodules to make them available at the package level
149
150from . import characteristics, fitting, preprocessing
151
152__all__ = ["fitting", "characteristics", "preprocessing"]
153# from .characteristics import (
154#     calculate_characteristic,
155#     lactation_curve_characteristic_function,
156#     numeric_cumulative_yield,
157#     numeric_peak_yield,
158#     numeric_time_to_peak,
159#     persistency_fitted_curve,
160#     persistency_milkbot,
161#     persistency_wood,
162#     test_interval_method,
163# )
164# from .fitting import (
165#     ali_schaeffer_model,
166#     bayesian_fit_milkbot_single_lactation,
167#     brody_model,
168#     dhanoa_model,
169#     dijkstra_model,
170#     emmans_model,
171#     fischer_model,
172#     fit_lactation_curve,
173#     get_chen_priors,
174#     get_lc_parameters,
175#     get_lc_parameters_least_squares,
176#     hayashi_model,
177#     milkbot_model,
178#     nelder_model,
179#     prasad_model,
180#     rook_model,
181#     sikka_model,
182#     wilmink_model,
183#     wood_model,
184# )
185# from .preprocessing import (
186#     PreparedInputs,
187#     standardize_lactation_columns,
188#     validate_and_prepare_inputs,
189# )
190
191# __all__ = [
192#     # Preprocessing
193#     "PreparedInputs",
194#     "standardize_lactation_columns",
195#     "validate_and_prepare_inputs",
196#     # Fitting
197#     "ali_schaeffer_model",
198#     "bayesian_fit_milkbot_single_lactation",
199#     "brody_model",
200#     "dhanoa_model",
201#     "dijkstra_model",
202#     "emmans_model",
203#     "fischer_model",
204#     "fit_lactation_curve",
205#     "get_chen_priors",
206#     "get_lc_parameters",
207#     "get_lc_parameters_least_squares",
208#     "hayashi_model",
209#     "milkbot_model",
210#     "nelder_model",
211#     "prasad_model",
212#     "rook_model",
213#     "sikka_model",
214#     "wilmink_model",
215#     "wood_model",
216#     # Characteristics
217#     "calculate_characteristic",
218#     "lactation_curve_characteristic_function",
219#     "numeric_cumulative_yield",
220#     "numeric_peak_yield",
221#     "numeric_time_to_peak",
222#     "persistency_fitted_curve",
223#     "persistency_milkbot",
224#     "persistency_wood",
225#     "test_interval_method",
226# ]
227
228# Expose package version (try metadata, fall back to a sensible dev string)
229try:
230    from importlib.metadata import PackageNotFoundError, version
231except Exception:
232    try:
233        from importlib_metadata import PackageNotFoundError, version  # type: ignore
234    except Exception:
235        version = None
236        PackageNotFoundError = Exception
237
238if version:
239    try:
240        __version__ = version("lactationcurve")
241    except PackageNotFoundError:
242        __version__ = "0+dev"
243else:
244    __version__ = "0+dev"
245
246__all__.append("__version__")
__version__ = '1.1.1'