update chicken weight to have chicken_area data as well
This commit is contained in:
1 parent
a6d4ddac65
commit
6bad900cf0
13 files changed
+132
-21
No files matched your search
@@ -283,6 +283,7 @@ class Command(BaseCommand):
|
||||
weight = AVG_WEIGHT[i]
|
||||
prev_weight = AVG_WEIGHT[i - 1] if i > 0 else DOC_IN_WEIGHT
|
||||
adg = _round(weight - prev_weight, 2) if weight else 0.0
|
||||
area_cm2 = _round(4.8 * (weight ** 0.66), 1) if weight else 0.0
|
||||
cw, _ = ChickenWeight.objects.update_or_create(
|
||||
cycle=cycle,
|
||||
date=day,
|
||||
@@ -293,6 +294,7 @@ class Command(BaseCommand):
|
||||
"chicken_count": SAMPLE_COUNT[i],
|
||||
"uniformity": UNIFORMITY[i],
|
||||
"average_daily_gain": adg,
|
||||
"chicken_area": area_cm2,
|
||||
},
|
||||
)
|
||||
cw_by_date[day] = cw
|
||||
|
||||
@@ -147,16 +147,18 @@ class Command(BaseCommand):
|
||||
|
||||
cw_by_date = {}
|
||||
for row in sheets["chicken_weight"]:
|
||||
avg_wt = float(as_number(row.get("average_weight")))
|
||||
obj, _ = ChickenWeight.objects.update_or_create(
|
||||
cycle=cycle,
|
||||
date=row["date"],
|
||||
defaults={
|
||||
"age": int(as_number(row.get("age"))),
|
||||
"doc_weight": int(as_number(row.get("doc_weight"))),
|
||||
"average_weight": float(as_number(row.get("average_weight"))),
|
||||
"average_weight": avg_wt,
|
||||
"chicken_count": int(as_number(row.get("chicken_count"))),
|
||||
"uniformity": float(as_number(row.get("uniformity"))),
|
||||
"average_daily_gain": float(as_number(row.get("average_daily_gain"))),
|
||||
"chicken_area": round(4.8 * (avg_wt ** 0.66), 1) if avg_wt > 0 else 0.0,
|
||||
},
|
||||
)
|
||||
cw_by_date[row["date"]] = obj
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Generated by Django 5.2.17 on 2026-10-07 08:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('operations', '0020_drop_orphan_structured_data'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='chickenweight',
|
||||
name='chicken_area',
|
||||
field=models.FloatField(default=0.0),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='chickencounting',
|
||||
name='cc_id',
|
||||
field=models.BigAutoField(primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='chickenweight',
|
||||
name='cw_id',
|
||||
field=models.BigAutoField(primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='feedsacks',
|
||||
name='fs_id',
|
||||
field=models.BigAutoField(primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='iotpanel',
|
||||
name='panel_id',
|
||||
field=models.BigAutoField(primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='kpi',
|
||||
name='kpi_id',
|
||||
field=models.BigAutoField(primary_key=True, serialize=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='manualinput',
|
||||
name='manual_id',
|
||||
field=models.BigAutoField(primary_key=True, serialize=False),
|
||||
),
|
||||
]
|
||||
@@ -105,6 +105,7 @@ class ChickenWeight(models.Model):
|
||||
chicken_count = models.IntegerField()
|
||||
uniformity = models.FloatField()
|
||||
average_daily_gain = models.FloatField()
|
||||
chicken_area = models.FloatField(default=0.0)
|
||||
cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="chicken_weights")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
@@ -116,10 +116,24 @@ def aggregate_weight_by_date(
|
||||
weights = [float(f.get("predicted_weight_g") or 0) for f in floors]
|
||||
unifs = [float(f.get("uniformity") or 0) for f in floors]
|
||||
samples = [int(f.get("n_valid_samples") or 0) for f in floors]
|
||||
areas = [
|
||||
float(
|
||||
f.get("area_cm2_median")
|
||||
or f.get("area_cm2")
|
||||
or f.get("predicted_area_cm2")
|
||||
or f.get("bbox_area_cm2")
|
||||
or f.get("area")
|
||||
or 0
|
||||
)
|
||||
for f in floors
|
||||
]
|
||||
valid_areas = [a for a in areas if a > 0]
|
||||
avg_area = sum(valid_areas) / len(valid_areas) if valid_areas else 0.0
|
||||
by_date[day] = {
|
||||
"average_weight": sum(weights) / len(weights),
|
||||
"uniformity": sum(unifs) / len(unifs),
|
||||
"chicken_count": max(samples) if samples else 0,
|
||||
"chicken_area": round(avg_area, 2),
|
||||
}
|
||||
return by_date
|
||||
|
||||
@@ -309,6 +323,7 @@ def sync_chicken_weight_for_cycle(
|
||||
uniformity = 0.0
|
||||
chicken_count = int(cycle.doc_in_count)
|
||||
adg = 0.0
|
||||
chicken_area = 0.0
|
||||
else:
|
||||
metrics = weight_by_date.get(day)
|
||||
if metrics is None:
|
||||
@@ -317,6 +332,7 @@ def sync_chicken_weight_for_cycle(
|
||||
uniformity = float(metrics["uniformity"])
|
||||
chicken_count = int(metrics["chicken_count"])
|
||||
adg = round(average_weight - prev_weight, 2)
|
||||
chicken_area = float(metrics.get("chicken_area", 0.0))
|
||||
|
||||
defaults = {
|
||||
"age": age,
|
||||
@@ -325,6 +341,7 @@ def sync_chicken_weight_for_cycle(
|
||||
"chicken_count": chicken_count,
|
||||
"uniformity": uniformity,
|
||||
"average_daily_gain": adg,
|
||||
"chicken_area": chicken_area,
|
||||
}
|
||||
ChickenWeight.objects.update_or_create(
|
||||
cycle=cycle,
|
||||
|
||||
@@ -175,12 +175,7 @@ erDiagram
|
||||
int chicken_count "NOT NULL (n_weight_samples)"
|
||||
float uniformity "NOT NULL (Flock weight uniformity %)"
|
||||
float average_daily_gain "NOT NULL (ADG in grams/day)"
|
||||
float area_cm2_median "Median body area in cm^2"
|
||||
float minor_axis_cm_median "Median minor axis / width in cm"
|
||||
float major_axis_cm_median "Median major axis / length in cm"
|
||||
float gompertz_baseline_g "Theoretical Gompertz curve baseline"
|
||||
float vision_gain_g "Allometric vision gain residual"
|
||||
float rejection_rate "MAD outlier filter rejection percentage"
|
||||
float chicken_area "NOT NULL DEFAULT 0.0 (Median chicken area in cm^2)"
|
||||
timestamp created_at "NOT NULL"
|
||||
timestamp updated_at "NOT NULL"
|
||||
}
|
||||
@@ -308,8 +303,7 @@ Our edge pipeline aggregates floor camera runs and pushes clean daily rollups di
|
||||
- `chicken_count` $\leftarrow \sum \text{n\_weight\_samples}$ (valid non-outlier tracks).
|
||||
- `uniformity` $\leftarrow \text{flock size uniformity percentage}$.
|
||||
- `average_daily_gain` $\leftarrow \text{daily weight gain in grams/day}$.
|
||||
- `area_cm2_median`, `minor_axis_cm_median`, `major_axis_cm_median` $\leftarrow \text{calibrated physical dimensions}$.
|
||||
- `gompertz_baseline_g`, `vision_gain_g` $\leftarrow \text{audited growth model residual breakdown}$.
|
||||
- `chicken_area` $\leftarrow \text{calibrated median chicken body area in cm²}$.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1290,6 +1290,22 @@
|
||||
"parent": "PF_pHT-a65sNfpEKlwq7-159",
|
||||
"label": "average_daily_gain float NOT NULL"
|
||||
},
|
||||
{
|
||||
"id": "PF_pHT-a65sNfpEKlwq7-cw-area",
|
||||
"type": "node",
|
||||
"parent": "PF_pHT-a65sNfpEKlwq7-66"
|
||||
},
|
||||
{
|
||||
"id": "PF_pHT-a65sNfpEKlwq7-cw-area-col1",
|
||||
"type": "node",
|
||||
"parent": "PF_pHT-a65sNfpEKlwq7-cw-area"
|
||||
},
|
||||
{
|
||||
"id": "PF_pHT-a65sNfpEKlwq7-cw-area-col2",
|
||||
"type": "node",
|
||||
"parent": "PF_pHT-a65sNfpEKlwq7-cw-area",
|
||||
"label": "chicken_area float NOT NULL"
|
||||
},
|
||||
{
|
||||
"id": "PF_pHT-a65sNfpEKlwq7-321",
|
||||
"type": "node",
|
||||
@@ -2537,4 +2553,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 337 KiB |
@@ -147,8 +147,9 @@ CREATE INDEX IF NOT EXISTS idx_cycles_close_requested_by_id ON cycles (close_req
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS flock (
|
||||
flock_id SERIAL PRIMARY KEY,
|
||||
flock_name VARCHAR(30) NOT NULL,
|
||||
kandang_id INTEGER NOT NULL REFERENCES kandang (kandang_id) ON DELETE CASCADE,
|
||||
flock_name VARCHAR(30) NOT NULL,
|
||||
iot_api_url VARCHAR(500) NOT NULL DEFAULT '',
|
||||
kandang_id INTEGER NOT NULL REFERENCES kandang (kandang_id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
@@ -259,8 +260,9 @@ CREATE TABLE IF NOT EXISTS chicken_weight (
|
||||
doc_weight INTEGER NOT NULL,
|
||||
average_weight FLOAT NOT NULL,
|
||||
chicken_count INTEGER NOT NULL,
|
||||
uniformity FLOAT NOT NULL,
|
||||
average_daily_gain FLOAT NOT NULL,
|
||||
uniformity FLOAT NOT NULL,
|
||||
average_daily_gain FLOAT NOT NULL,
|
||||
chicken_area FLOAT NOT NULL DEFAULT 0.0,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
cycle_id INTEGER NOT NULL REFERENCES cycles (cycle_id) ON DELETE CASCADE
|
||||
|
||||
Reference in new issue
Block a user