Skip to content

feat(backend): add formula-based LiDAR weight prediction baseline#46

Open
nicole-gomes wants to merge 2 commits into
mainfrom
EURODEV-84/create-prediction-module
Open

feat(backend): add formula-based LiDAR weight prediction baseline#46
nicole-gomes wants to merge 2 commits into
mainfrom
EURODEV-84/create-prediction-module

Conversation

@nicole-gomes

@nicole-gomes nicole-gomes commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds a new isolated backend/prediction/ package for bovine weight estimation based on LiDAR-derived morphometric measurements. It introduces a deterministic formula-based baseline using heart girth and body length, plus measurement validation, conservative confidence scoring, structured diagnostics, and unit tests. The goal is to support the first real-measurements phase with a production-oriented baseline that does not depend on the legacy 2D /api/v1/scan demo flow, synthetic data, or a trained supervised model.

Motivation

This solves the need for a first-pass weight estimation module for the LiDAR measurements workflow while real ground-truth animal weights are not yet available for model training and calibration. The implementation creates a clear separation between the new LiDAR-based baseline path and the older image-based demo path, and it keeps the architecture extensible for a future trained model once real farm data is collected.

Closes #

Type of change

  • feat — new user-visible feature
  • fix — bug fix
  • perf — performance improvement
  • refactor — code change without behaviour change
  • docs — documentation only
  • test — tests only
  • build / ci — build system or CI changes
  • chore — other maintenance
  • security — security-related change
  • Breaking change (explain below)

Scope of change

  • mobile/ — Expo / React Native
  • backend/ — FastAPI service
  • .github/ — CI, templates, governance
  • root / documentation

How was this tested?

  • Linted (expo lint, ruff)
  • Type-checked (tsc --noEmit, mypy where applicable)
  • Smoke-tested locally
  • Not testable in isolation — explain below

Manual and automated validation performed:

  • Ran python -m unittest tests.test_weight_estimation_agent
  • Ran python -m unittest discover tests
  • Executed the predictor manually with a valid bovine payload and confirmed:
    • positive estimated weight
    • conservative confidence score
    • expected model_version and estimation_method
    • requires_ground_truth_validation = true
    • is_formula_based = true
    • is_trained_model = false

Notes:

  • ruff could not be executed in the current environment because Ruff was not installed locally or in the backend virtual environment.
  • No dedicated static type-checker was configured for this backend package in the current environment.

Screenshots or recordings

N/A — backend-only change.

Checklist

  • My commits follow the Conventional Commits format.
  • I updated the relevant README or documentation.
  • I did not add any secret, key, or production credential.
  • If I added a large binary asset, it is tracked by Git LFS.
  • I tagged the appropriate reviewers from CODEOWNERS.

Notes for the reviewer

Business rules implemented in this PR:

  • The estimator is formula-based only and is not a trained model.
  • model_version is fixed as formula-baseline-v0.1.0.
  • estimation_method is fixed as heart_girth_body_length_formula.
  • The primary calculation uses chest_girth_cm and body_length_cm.
  • The formula converts centimeters to inches, computes weight in pounds, and converts the result to kilograms.
  • withers_height_cm, thoracic_depth_cm, and rump_width_cm are currently used for validation, plausibility, and diagnostics rather than as primary calculation inputs.
  • The response always sets:
    • requires_ground_truth_validation = true
    • is_formula_based = true
    • is_trained_model = false
  • Confidence is intentionally conservative and capped at 0.70.
  • The confidence score is an operational baseline indicator, not a calibrated statistical probability.
  • Missing, zero, and negative measurements are rejected.
  • Measurements outside plausible bovine ranges are rejected.
  • Measurements near plausible range limits generate warnings.
  • Inconsistent morphometric ratios generate warnings and reduce confidence.
  • Non-bovine species labels generate a warning because plausibility checks are tuned for bovines.
  • Very young animals generate a warning because adult morphometric formulas may be less reliable.

Plausible bovine ranges currently applied:

  • body_length_cm: 80 to 260
  • withers_height_cm: 80 to 210
  • thoracic_depth_cm: 35 to 120
  • rump_width_cm: 20 to 100
  • chest_girth_cm: 90 to 320

Consistency checks currently applied:

  • chest_girth_cm / body_length_cm outside 0.85 to 1.70
  • withers_height_cm / thoracic_depth_cm outside 1.25 to 3.20
  • rump_width_cm / chest_girth_cm outside 0.15 to 0.45
  • thoracic_depth_cm >= withers_height_cm

Deferred work / follow-up:

  • Expose this predictor through a dedicated API endpoint.
  • Calibrate confidence and estimation behavior against real farm ground-truth weights.
  • Replace or extend the baseline via model_registry.py when a trained model becomes available.

@nicole-gomes nicole-gomes requested a review from Tcordeir0 as a code owner June 11, 2026 11:47
def predict(
self,
request: WeightEstimationRequest,
) -> WeightEstimationResponse: ...
def predict(
self,
request: WeightEstimationRequest,
) -> WeightEstimationResponse: ...

@Tcordeir0 Tcordeir0 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI verde ✅. Revisei: a fórmula heart-girth está correta e o pacote prediction/ ficou bem isolado e extensível pro modelo treinado futuro. Baseline backend-only, não mexe no app — alinhado. Só vamos manter o peso rotulado como baseline/preliminar e sem plugar no app até termos o modelo treinado (pós coleta de 22/06). Mandou bem, aprovado! 🚀

@Tcordeir0 Tcordeir0 self-assigned this Jun 11, 2026
@Tcordeir0 Tcordeir0 added the ci Continuous integration and GitHub Actions workflows label Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Continuous integration and GitHub Actions workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants