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