Files
Ai/docs/location_data_remote_sensing_failure_report.md
2026-05-11 00:36:02 +03:30

18 KiB

گزارش تحلیل خطای location_data برای Remote Sensing Run

این سند بر اساس payload دریافتی از endpoint زیر تهیه شده است:

  • GET /api/location-data/remote-sensing/runs/{task_id}/status/

نمونه run بررسی‌شده:

  • task_id: 02959179-63b2-4388-bb2e-a4d79176eca2
  • run.id: 6
  • بازه زمانی: 2026-04-09 تا 2026-05-09
  • وضعیت API: failed
  • وضعیت Celery: RETRY

1) خلاصه خیلی کوتاه

این run تا مرحله واکشی metricها و ذخیره observationها جلو رفته، اما در مرحله ساخت subdivision داده‌محور شکست خورده است.

خطای نهایی:

  • هیچ observation قابل استفاده‌ای برای خوشه‌بندی باقی نماند.

این خطا در کد دقیقاً زمانی رخ می‌دهد که سیستم بعد از بارگذاری observationها، هیچ ردیفی را برای clustering قابل استفاده تشخیص ندهد.

مسیر کد:

  • location_data/tasks.py
  • location_data/data_driven_subdivision.py

2) جدول مدل‌ها / جدول‌های درگیر

مدل جدول Django نقش
SoilLocation location_data_soillocation اطلاعات location و farm boundary
BlockSubdivision location_data_blocksubdivision تقسیم‌بندی بلوک/مزرعه
RemoteSensingRun location_data_remotesensingrun وضعیت اجرای pipeline سنجش‌ازدور
AnalysisGridCell location_data_analysisgridcell سلول‌های شبکه تحلیلی
AnalysisGridObservation location_data_analysisgridobservation مقادیر metricها برای هر cell
RemoteSensingSubdivisionResult location_data_remotesensingsubdivisionresult نتیجه clustering و subdivision نهایی
RemoteSensingClusterAssignment location_data_remotesensingclusterassignment نسبت هر cell به cluster

3) جدول معنی فیلدهای سطح اول response

فیلد مقدار نمونه توضیح
code 200 پاسخ HTTP موفق از API؛ لزوماً به معنای موفق بودن task نیست
msg success پیام wrapper API
data.status failed وضعیت client-facing run
data.source database payload از داده‌های ذخیره‌شده در DB ساخته شده
data.task_id UUID شناسه Celery task
data.run object snapshot اصلی run
data.task object جزئیات stageها، timestamps و وضعیت Celery

4) جدول معنی فیلدهای run

فیلد مقدار نمونه توضیح
id 6 شناسه رکورد run در DB
block_code "" خالی یعنی کل مزرعه، نه یک بلوک خاص
chunk_size_sqm 900 اندازه هر cell به متر مربع
temporal_start 2026-04-09 شروع بازه تحلیل
temporal_end 2026-05-09 پایان بازه تحلیل
status failure مقدار خام DB
status_label failed نسخه نرمال‌شده برای client
pipeline_status failed تکرار client-facing status
stage observations_persisted آخرین stage ذخیره‌شده در metadata
selected_features ndvi, ndwi, soil_vv_db, dem_m, slope_deg featureهایی که pipeline فکر می‌کند برای clustering لازم‌اند
requested_cluster_count null تعداد cluster صریح از کاربر نیامده و الگوریتم باید تصمیم بگیرد
error_message متن فارسی خطا خطای نهایی ثبت‌شده روی run
started_at timestamp زمان شروع واقعی run
finished_at timestamp زمان ثبت failure روی run
created_at timestamp زمان ایجاد رکورد run
updated_at timestamp آخرین به‌روزرسانی رکورد run

5) جدول معنی فیلدهای run.metadata

فیلد توضیح
scope scope اجرای تحلیل؛ در این نمونه all_blocks
stage stage فعلی/آخر ذخیره‌شده
task_id شناسه Celery task
pipeline.name نام pipeline
pipeline.version نسخه pipeline
farm_uuid شناسه مزرعه
timestamps زمان ورود به هر stage
status_label وضعیت client-facing ذخیره‌شده در metadata
requested_via مبدا درخواست؛ در این نمونه api
stage_details جزئیات هر stage
failure_reason دلیل نهایی ثبت failure
selected_features featureهای مورد استفاده برای clustering
requested_cluster_count cluster count درخواستی، اگر وجود داشته باشد

6) جدول معنی stageها در این run

stage وضعیت مشاهده‌شده معنی
queued completed task در صف قرار گرفته
preparing_analysis_grid completed آماده‌سازی grid تحلیلی
analysis_grid_ready completed grid سلول‌ها آماده بوده
analysis_cells_selected completed 12 سلول برای پردازش انتخاب شده‌اند
fetching_remote_metrics completed metricها از openEO درخواست شده‌اند
remote_metrics_fetched completed jobهای openEO تمام شده‌اند
observations_persisted failed observationها ذخیره شده‌اند ولی pipeline بعد از این مرحله fail شده
failed completed stage شکست نهایی ثبت شده

نکته مهم:

  • در payload فعلی، run.stage هنوز observations_persisted است اما data.status برابر failed است.
  • این یعنی status و stage با هم perfectly sync نیستند.

7) جدول معنی stage_details

7.1) preparing_analysis_grid

فیلد توضیح
block_code بلوک هدف
temporal_extent.start_date شروع بازه
temporal_extent.end_date پایان بازه

7.2) analysis_grid_ready

فیلد توضیح
grid_summary.created آیا grid همین run ساخته شده یا از قبل وجود داشته
grid_summary.block_code کد بلوک
grid_summary.total_count تعداد کل cellها
grid_summary.created_count تعداد cell تازه ایجادشده
grid_summary.chunk_size_sqm اندازه cell
grid_summary.existing_count تعداد cellهای موجود از قبل

7.3) analysis_cells_selected

فیلد توضیح
force_refresh آیا cache نادیده گرفته شده
total_cell_count تعداد کل cellها
existing_cell_count تعداد cellهایی که داده از قبل داشته‌اند
cell_count_to_process تعداد cellهایی که باید پردازش شوند

7.4) fetching_remote_metrics

فیلد توضیح
target_cells لیست cellهای هدف
requested_cell_count تعداد cellهای هدف
metric_progress.total_metrics تعداد metricهایی که pipeline انتظار دارد
metric_progress.completed_metric_count تعداد metricهای کامل‌شده
metric_progress.completed_metrics metricهای کامل‌شده واقعی
metric_progress.failed_metrics metricهای fail شده
metric_progress.states وضعیت هر metric از نگاه progress tracker

7.5) remote_metrics_fetched

فیلد توضیح
failed_metric_count تعداد metric fail شده
service_metadata.backend backend مورد استفاده
service_metadata.job_refs job id هر metric در openEO
service_metadata.backend_url آدرس backend
service_metadata.failed_metrics خطاهای metric-level
service_metadata.collections_used collectionهای مصرف‌شده

7.6) observations_persisted

فیلد توضیح
created_count تعداد observation ساخته‌شده
updated_count تعداد observation به‌روزشده

8) جدول معنی task

فیلد مقدار نمونه توضیح
current_stage observations_persisted stage فعلی/آخرین stage ثبت‌شده
current_stage_details created_count=12, updated_count=0 جزئیات stage جاری
timestamps object timeline کامل stageها
stages list نسخه ترتیبی از stageها
metric_progress object وضعیت پیشرفت metricها
failure_reason متن فارسی خطای ثبت‌شده
celery.state RETRY Celery task هنوز final نشده و در retry است
celery.ready false نتیجه نهایی هنوز آماده نیست
celery.successful false task هنوز success نشده
celery.failed false task هنوز fail نهایی نشده
celery.info متن خطا پیام retry فعلی Celery

9) دلیل دقیق خطا

دلیل مستقیم خطا از خود کد:

  • در location_data/data_driven_subdivision.py اگر بعد از ساخت dataset، هیچ observation قابل استفاده برای clustering باقی نماند، این exception پرتاب می‌شود:
    • هیچ observation قابل استفاده‌ای برای خوشه‌بندی باقی نماند.

این یعنی pipeline به این نقطه رسیده:

  1. cellها ساخته شده‌اند
  2. metricها از openEO درخواست شده‌اند
  3. observationها در DB ذخیره شده‌اند
  4. اما در زمان ساخت dataset برای clustering، ردیف قابل مصرفی پیدا نشده است

معنی عملی این خطا

یعنی برای همه observationهای این run، سیستم نتوانسته feature vector قابل استفاده بسازد.

در کد فعلی، observation وقتی از clustering حذف می‌شود که:

  • همه featureهای انتخاب‌شده برای آن observation برابر None باشند

پس این خطا معمولاً یعنی:

  • یا تمام metricهای لازم برای همه cellها null شده‌اند
  • یا feature set انتخابی با داده‌هایی که واقعاً ذخیره شده‌اند mismatch دارد
  • یا persistence / selection طوری انجام شده که clustering به داده قابل استفاده دسترسی پیدا نکرده است

10) محتمل‌ترین علت‌ها برای همین run

علت 1: featureهای حذف‌شده هنوز در pipeline زنده هستند

در payload می‌بینیم:

  • selected_features هنوز شامل dem_m و slope_deg است
  • اما در location_data/openeo_service.py این metricها از محاسبه حذف شده‌اند

نتیجه:

  • API و metadata هنوز فکر می‌کنند این دو feature بخشی از clustering هستند
  • ولی openEO دیگر آن‌ها را تولید نمی‌کند
  • بنابراین در observationها این فیلدها عملاً None می‌مانند

نکته مهم:

  • فقط None بودن dem_m و slope_deg به‌تنهایی برای تولید این خطا کافی نیست
  • اما این mismatch یکی از مهم‌ترین نشانه‌های ناسازگاری pipeline است

علت 2: metricهای اصلی احتمالاً برای همه cellها مقدار قابل استفاده نداشته‌اند

چون این خطا فقط وقتی رخ می‌دهد که هیچ observation usable باقی نماند، محتمل است که برای همه 12 cell:

  • ndvi
  • ndwi
  • soil_vv_db

هم عملاً None شده باشند یا آن‌طور که clustering انتظار دارد قابل مصرف نبوده باشند.

این حالت ممکن است از اینجا آمده باشد:

  • داده خام provider برای این محدوده/بازه تهی یا نامعتبر بوده
  • masking یا aggregation مقدار usable تولید نکرده
  • یا در persistence، featureهای محاسبه‌شده به‌درستی به ستون‌های clustering نرسیده‌اند

علت 3: progress tracker با metricهای واقعی sync نیست

در payload:

  • completed_metrics شامل soil_vv است
  • ولی states شامل soil_vv_db به حالت pending است

یعنی tracker با metric واقعی اجراشده sync نیست:

  • metric واقعی remote: soil_vv
  • metric مشتق‌شده محلی: soil_vv_db

این باعث می‌شود progress ظاهراً ناقص دیده شود، حتی وقتی داده remote کامل شده است.

علت 4: وضعیت DB و Celery با هم متناقض‌اند

در payload:

  • data.status = failed
  • ولی task.celery.state = RETRY

یعنی:

  • از نظر DB، run شکست خورده ثبت شده
  • از نظر Celery، task هنوز در حال retry است و failure نهایی نشده

این برای client گیج‌کننده است، چون معلوم نیست باید run را تمام‌شده و fail شده بداند یا منتظر retry بماند.


11) مشکلات فعلی location_data که از کد مشخص هستند

مشکل 1: DEFAULT_CLUSTER_FEATURES هنوز metricهای حذف‌شده را نگه داشته

فایل:

  • location_data/data_driven_subdivision.py

وضعیت فعلی:

  • dem_m
  • slope_deg

هنوز داخل DEFAULT_CLUSTER_FEATURES هستند.

اثر:

  • selected_features اشتباه در run metadata
  • progress tracker اشتباه
  • clustering contract قدیمی باقی می‌ماند

مشکل 2: serializer و summary هنوز dem_m و slope_deg را به API برمی‌گردانند

فایل‌ها:

  • location_data/serializers.py
  • location_data/views.py

اثر:

  • response API هنوز metricهای حذف‌شده را نمایش می‌دهد
  • summary میانگین dem_m_mean و slope_deg_mean می‌سازد
  • مصرف‌کننده API فکر می‌کند این metricها هنوز پشتیبانی می‌شوند

مشکل 3: _upsert_grid_observations هنوز فیلدهای حذف‌شده را persist می‌کند

فایل:

  • location_data/tasks.py

اثر:

  • ستون‌های dem_m و slope_deg همچنان نوشته می‌شوند، اما عملاً با None
  • metadata هنوز slope_supported را ذخیره می‌کند، در حالی که openEO service دیگر این مفهوم را برنمی‌گرداند

مشکل 4: progress metricها با metricهای واقعی اجراشده mismatch دارد

فایل:

  • location_data/tasks.py

نمونه mismatch:

  • remote metric واقعی: soil_vv
  • feature مورد انتظار برای clustering: soil_vv_db

اثر:

  • completed_metrics و states با هم ناسازگار می‌شوند
  • soil_vv_db در response به شکل pending دیده می‌شود، با اینکه از soil_vv مشتق می‌شود

مشکل 5: stage و status همیشه هماهنگ نیستند

در payload فعلی:

  • run.status_label = failed
  • run.stage = observations_persisted

اثر:

  • client نمی‌فهمد خطا دقیقاً در کدام stage رخ داده
  • task.current_stage هم گمراه‌کننده می‌شود

مشکل 6: DB failure و Celery retry همزمان به client داده می‌شود

اثر:

  • API برای یک run همزمان پیام failed و RETRY می‌دهد
  • از نگاه UX، کاربر نمی‌داند باید retry خودکار را صبر کند یا خطا را final بداند

12) جمع‌بندی عملی برای همین خطا

بر اساس payload و کد، نتیجه عملی این است:

  1. openEO jobها برای ndvi, ndwi, soil_vv اجرا شده‌اند
  2. 12 observation در DB ساخته شده‌اند
  3. pipeline وارد مرحله clustering شده
  4. clustering هیچ observation usable پیدا نکرده
  5. run در DB به حالت failed رفته
  6. اما Celery هنوز task را در حالت RETRY نگه داشته

13) پیشنهادهای اصلاح

اصلاح ضروری

  1. dem_m و slope_deg را از این نقاط هم حذف کنید:

    • location_data/data_driven_subdivision.py
    • location_data/serializers.py
    • location_data/views.py
    • location_data/tasks.py
  2. DEFAULT_CLUSTER_FEATURES را با metricهای واقعی sync کنید:

    • ndvi
    • ndwi
    • soil_vv_db
  3. progress tracker را طوری اصلاح کنید که:

    • completion soil_vv به completion soil_vv_db هم map شود
    • metricهای حذف‌شده اصلاً در state دیده نشوند
  4. منطق status endpoint را طوری تنظیم کنید که:

    • اگر Celery در RETRY است، status client نهایی failed نباشد
    • یا حداقل یک فیلد صریح مثل final_status=false برگردد
  5. قبل از clustering، یک diagnostic بهتر ذخیره شود:

    • تعداد observationهای usable
    • تعداد observationهای all-null
    • تعداد null برای هر feature

اصلاح پیشنهادی برای debug بهتر

در stage_details این موارد اضافه شود:

  • usable_observation_count
  • all_features_missing_cell_codes
  • feature_null_counts
  • selected_features_effective

14) نتیجه نهایی

این run به احتمال زیاد به خاطر ناسازگاری بین featureهای مورد انتظار pipeline و featureهای واقعاً تولید/ذخیره‌شده شکست خورده است، و علاوه بر آن چند inconsistency مهم در location_data وجود دارد:

  • metricهای حذف‌شده هنوز در feature contract حضور دارند
  • progress report با metricهای واقعی sync نیست
  • DB status و Celery status با هم تناقض دارند
  • stage نهایی برای failure به شکل واضح و قابل اتکا به client نمایش داده نمی‌شود

اگر بخواهید، مرحله بعدی می‌تواند این باشد که همین موارد را در کد هم اصلاح کنیم، نه فقط مستندسازی.