# راهنمای کامل PCSE در این پروژه

این سند توضیح می‌دهد `PCSE` در این پروژه دقیقا چه نقشی دارد، چگونه داده‌ها را مصرف می‌کند، خروجی آن چگونه ساخته می‌شود، و این خروجی چه اثری روی توصیه‌های آبیاری و کودهی دارد. تمرکز اصلی این راهنما روی اتصال بین این فایل‌ها است:

- `crop_simulation/services.py`
- `crop_simulation/recommendation_optimizer.py`
- `crop_simulation/apps.py`
- `irrigation/apps.py`
- `fertilization/apps.py`
- `rag/services/irrigation.py`
- `rag/services/fertilization.py`

---

## 1) PCSE چیست؟

`PCSE` مخفف `Python Crop Simulation Environment` است. این کتابخانه یک چارچوب شبیه‌سازی زراعی است که می‌تواند با مدل‌هایی مثل `WOFOST` رشد گیاه، توسعه فنولوژیک، تولید زیست‌توده، عملکرد، و پاسخ به آب و نیتروژن را شبیه‌سازی کند.

در این پروژه، PCSE نقش این‌ها را بر عهده دارد:

- تبدیل داده‌های مزرعه، هوا، خاک و برنامه مدیریت به یک اجرای شبیه‌سازی
- برآورد خروجی‌های کلیدی مثل:
  - `yield_estimate`
  - `biomass`
  - `max_lai`
- مقایسه سناریوهای مختلف آبیاری و کودهی
- تولید یک مبنای عددی برای recommendation engine

به زبان ساده:

- `RAG` متن توصیه را خوش‌بیان و کاربرپسند می‌کند
- `PCSE` منطق عددی و شبیه‌سازی سناریویی را تامین می‌کند

---

## 2) معماری کلی PCSE در این پروژه

جریان اصلی به این صورت است:

1. داده مزرعه از دیتابیس خوانده می‌شود
2. داده هوا از forecastها به فرمت قابل فهم برای PCSE تبدیل می‌شود
3. داده خاک و وضعیت سایت ساخته می‌شود
4. پروفایل گیاه و `agromanagement` آماده می‌شود
5. اگر recommendation آبیاری یا کودهی وجود داشته باشد، به `TimedEvents` تزریق می‌شود
6. مدل PCSE اجرا می‌شود
7. خروجی‌های روزانه، خلاصه و نهایی جمع می‌شوند
8. از روی آن‌ها شاخص عملکرد و recommendation سناریویی ساخته می‌شود
9. RAG از این خروجی به‌عنوان `context_text` استفاده می‌کند تا متن نهایی توصیه را بسازد

---

## 3) نقطه ورود اصلی PCSE

### `crop_simulation/apps.py`

در `crop_simulation/apps.py` یک optimizer سراسری lazy-loaded تعریف شده:

- `recommendation_optimizer`
- `get_recommendation_optimizer()`

این optimizer از کلاس `SimulationRecommendationOptimizer` در `crop_simulation/recommendation_optimizer.py` ساخته می‌شود.

بنابراین:

- `rag/services/irrigation.py` از `apps.get_app_config("crop_simulation").get_recommendation_optimizer()` استفاده می‌کند
- `rag/services/fertilization.py` هم همین کار را انجام می‌دهد

یعنی هر دو سرویس recommendation در نهایت به موتور شبیه‌سازی crop_simulation وصل هستند.

---

## 4) نقش `irrigation/apps.py`

فایل `irrigation/apps.py` فقط یک AppConfig ساده نیست؛ در عمل تنظیمات پایه optimizer آبیاری را نگه می‌دارد.

### پارامترهای مهم

#### `simulation_model`

مدل پیش‌فرض:

```python
"Wofost81_NWLP_CWB_CNB"
```

این یعنی recommendationهای آبیاری قرار است روی مدلی ساخته شوند که هم water-limited و هم nutrient-aware است.

#### `validity_days`

```python
3
```

توصیه آبیاری کوتاه‌مدت است و بیشتر به forecastهای نزدیک متکی است.

#### `minimum_event_mm`

```python
4.0
```

هر نوبت آبیاری نباید از این کمتر شود، چون در عمل آبیاری‌های خیلی کوچک یا بی‌اثرند یا اجرای میدانی ضعیفی دارند.

#### `significant_rain_threshold_mm`

```python
4.0
```

اگر بارش موثر به این آستانه برسد، recommendation می‌تواند محافظه‌کارتر شود یا پنجره اعتبار کوتاه‌تر شود.

#### `stage_targets`

برای هر مرحله رشد یک هدف رطوبت خاک تعریف شده:

- `initial`: 65%
- `vegetative`: 70%
- `flowering`: 75%
- `fruiting`: 68%

این‌ها مستقیما بر `moisture_target_percent` در توصیه نهایی اثر می‌گذارند.

#### `strategy_profiles`

سه استراتژی اصلی برای آبیاری تعریف شده:

- `conservative`
- `balanced`
- `protective`

هر استراتژی این مولفه‌ها را دارد:

- `multiplier`
- `frequency_factor`
- `event_count`

این‌ها تعیین می‌کنند:

- جمع کل آب بیشتر یا کمتر شود
- تعداد نوبت‌ها بیشتر یا کمتر شود
- توزیع آب در طول بازه forecast چگونه باشد

---

## 5) نقش `fertilization/apps.py`

این فایل هم مثل نسخه آبیاری، تنظیمات پایه recommendation optimizer کودهی را نگه می‌دارد.

### پارامترهای مهم

#### `simulation_model`

باز هم مدل:

```python
"Wofost81_NWLP_CWB_CNB"
```

یعنی recommendation کودهی بر مبنای مدلی ساخته می‌شود که نیتروژن را در سطح شبیه‌سازی لحاظ می‌کند.

#### `validity_days`

```python
7
```

پنجره اعتبار کودهی بلندتر از آبیاری است، چون تصمیم تغذیه‌ای معمولاً کندتر و با اثر تجمعی‌تر است.

#### `rain_delay_threshold_mm`

```python
3.0
```

اگر بارش موثر نزدیک باشد، برخی روش‌های مصرف یا زمان مصرف می‌توانند نامناسب شوند.

#### `stage_targets`

برای هر مرحله رشد، هدف تغذیه‌ای جداگانه تعریف شده است:

- `n`
- `p`
- `k`
- `formula`
- `application_method`
- `timing`

مثلا در مرحله `flowering`:

- نیاز پتاس بالاتر می‌شود
- فرمول `15-10-30` پیشنهاد می‌شود
- روش مصرف و timing هم متناسب با حساسیت گیاه تعیین می‌شود

#### `strategy_profiles`

سه استراتژی اصلی:

- `maintenance`
- `balanced`
- `corrective`

هر کدام ضریب مصرف و تمرکز متفاوت دارند. این استراتژی‌ها پایه سناریوسازی برای شبیه‌سازی یا heuristic هستند.

---

## 6) PCSE در `crop_simulation/services.py` چگونه کار می‌کند؟

### 6.1 نرمال‌سازی ورودی‌ها

قبل از اجرای مدل، ورودی‌ها یکنواخت می‌شوند:

- `_normalize_weather_records()`
- `_normalize_agromanagement()`
- `_normalize_site_parameters_for_model()`

### 6.2 ساخت payload مزرعه

تابع `build_simulation_payload_from_farm()` اطلاعات زیر را می‌سازد:

- weather
- soil
- site_parameters
- crop_parameters
- agromanagement

منابع آن:

- `SensorData`
- `WeatherForecast`
- پروفایل گیاه
- داده لایه خاک

### 6.3 ساخت داده خاک و سایت

در این مرحله مقادیر مهمی مثل این‌ها ساخته می‌شوند:

- `SMFCF`
- `SMW`
- `RDMSOL`
- `WAV`
- `NAVAILI`
- `P_STATUS`
- `K_STATUS`
- `SOIL_PH`
- `EC`

تعبیر عملی این مقادیر:

- `WAV`: آب در دسترس اولیه
- `NAVAILI`: نیتروژن اولیه در دسترس
- `P_STATUS` و `K_STATUS`: شاخص‌های وضعیت فسفر و پتاسیم
- `SOIL_PH` و `EC`: شرایط شیمیایی که روی کارایی تغذیه و رشد اثر دارند

### 6.4 لود کردن bindingهای PCSE

تابع `_load_pcse_bindings()` این اجزا را از package `pcse` می‌گیرد:

- `ParameterProvider`
- `WeatherDataProvider`
- `WeatherDataContainer`
- `pcse.models`

اگر package نصب نباشد، اجرای سناریوی واقعی PCSE ممکن نیست.

### 6.5 اجرای مدل

کلاس `PcseSimulationManager` قلب اجرای شبیه‌سازی است.

متد `run_simulation()` این کارها را انجام می‌دهد:

1. ساخت `PreparedSimulationInput`
2. normalize کردن weather / soil / crop / site / agromanagement
3. اجرای `_run_with_pcse()`
4. در مدل‌های `Wofost81_NWLP` اعمال adjustment برای `P` و `K`

### 6.6 خروجی‌های اصلی مدل

بعد از اجرا، این سه نوع خروجی جمع می‌شوند:

- `daily_output`
- `summary_output`
- `terminal_output`

و در نهایت metrics اصلی ساخته می‌شود:

- `yield_estimate`
- `biomass`
- `max_lai`

---

## 7) eventهای recommendation چگونه وارد شبیه‌سازی می‌شوند؟

این مهم‌ترین بخش اتصال PCSE به recommendationها است.

### `_parse_recommendation_events()`

این تابع recommendation خام را به event قابل الحاق تبدیل می‌کند.

برای آبیاری:

- `event_signal = "irrigate"`
- کلید مقدار می‌تواند `amount` یا `irrigation_amount` باشد

برای کودهی:

- `event_signal = "apply_n"`
- کلید مقدار می‌تواند `N_amount` یا `amount` باشد

### `_merge_management_recommendations()`

این تابع recommendationها را داخل `TimedEvents` همان campaign اصلی قرار می‌دهد.

پس وقتی شما یک recommendation جدید می‌دهید، در عمل:

- یک برنامه مدیریت جدید ساخته نمی‌شود
- همان `agromanagement` پایه مزرعه گرفته می‌شود
- eventهای جدید به آن تزریق می‌شوند

این طراحی مهم است چون:

- تقویم اصلی کشت حفظ می‌شود
- فقط تصمیم‌های مدیریتی جدید روی سناریو سوار می‌شوند

---

## 8) recommendation optimizer دقیقا چه می‌کند؟

فایل `crop_simulation/recommendation_optimizer.py` لایه تصمیم‌گیری سناریویی است.

کلاس اصلی:

- `SimulationRecommendationOptimizer`

این کلاس دو مسیر دارد:

- مسیر مبتنی بر PCSE
- مسیر heuristic fallback

اگر داده کافی و پروفایل simulation گیاه موجود باشد، اول تلاش می‌کند از PCSE استفاده کند. اگر نشد، به heuristic برمی‌گردد.

---

## 9) تاثیر PCSE روی توصیه آبیاری

### 9.1 ورودی‌های optimizer آبیاری

متد:

- `optimize_irrigation()`

ورودی‌ها:

- `sensor`
- `plant`
- `forecasts`
- `daily_water_needs`
- `growth_stage`
- `irrigation_method`

### 9.2 وقتی مسیر PCSE فعال می‌شود

اگر برای گیاه `simulation profile` معتبر وجود داشته باشد، متد `_optimize_irrigation_with_pcse()` اجرا می‌شود.

در این مسیر:

1. تنظیمات از `irrigation/apps.py` خوانده می‌شود
2. soil/site از سنسور و عمق خاک ساخته می‌شود
3. forecastها به weather record تبدیل می‌شوند
4. از روی `strategy_profiles` چند سناریوی آبیاری ساخته می‌شود
5. برای هر سناریو، eventهای `irrigate` به `agromanagement` تزریق می‌شود
6. هر سناریو با `run_single_simulation()` اجرا می‌شود
7. از روی `yield_estimate` هر سناریو، `score` ساخته می‌شود
8. بهترین سناریو انتخاب می‌شود

### 9.3 PCSE دقیقا چه چیزی را تغییر می‌دهد؟

PCSE باعث می‌شود recommendation آبیاری فقط بر پایه ET یا بارش نباشد. بلکه تاثیر برنامه آبیاری روی شاخص عملکرد گیاه هم دیده شود.

یعنی سیستم فقط نمی‌گوید:

- امروز 8 میلی‌متر آب بده

بلکه عملاً سناریوها را مقایسه می‌کند:

- اگر آب کمتر بدهیم، عملکرد چقدر افت می‌کند؟
- اگر آب را در نوبت‌های بیشتری پخش کنیم، نتیجه بهتر می‌شود؟
- اگر آبیاری حمایتی بدهیم، نسبت آب به عملکرد چطور تغییر می‌کند؟

### 9.4 خروجی نهایی آبیاری

خروجی recommendation آبیاری شامل این فیلدهاست:

- `total_irrigation_mm`
- `amount_per_event_mm`
- `events`
- `event_dates`
- `timing`
- `moisture_target_percent`
- `validity_period`
- `reasoning`

### 9.5 اثر مستقیم `irrigation/apps.py`

مقادیر این فایل مستقیم روی recommendation اثر دارند:

- `stage_targets` هدف رطوبت خاک را تعیین می‌کند
- `strategy_profiles` candidate scenarioها را تعریف می‌کند
- `validity_days` متن و پنجره اعتبار را تعیین می‌کند
- `minimum_event_mm` جلوی recommendationهای غیرعملی را می‌گیرد
- `significant_rain_threshold_mm` روی logic بارش موثر اثر دارد

### 9.6 اگر PCSE در دسترس نباشد

مسیر `_optimize_irrigation_with_heuristic()` استفاده می‌شود.

در این مسیر امتیازدهی بر اساس این‌هاست:

- نیاز آبی forecast
- بارش موثر
- رطوبت فعلی خاک
- دمای بالا
- باد
- بازده روش آبیاری

اما در این حالت شبیه‌سازی واقعی عملکرد انجام نمی‌شود. پس recommendation سبک‌تر و تخمینی‌تر است.

---

## 10) تاثیر PCSE روی توصیه کودهی

### 10.1 ورودی‌های optimizer کودهی

متد:

- `optimize_fertilization()`

ورودی‌ها:

- `sensor`
- `plant`
- `forecasts`
- `growth_stage`

### 10.2 مسیر PCSE برای کودهی

اگر simulation profile و forecast موجود باشد، `_optimize_fertilization_with_pcse()` اجرا می‌شود.

در این مسیر:

1. تنظیمات از `fertilization/apps.py` خوانده می‌شود
2. stage target مرحله رشد تعیین می‌شود
3. برای هر strategy profile یک دوز نیتروژن متفاوت ساخته می‌شود
4. event `apply_n` روی `TimedEvents` قرار می‌گیرد
5. هر سناریوی کودهی با PCSE اجرا می‌شود
6. `yield_estimate` سناریوها مقایسه می‌شود
7. بهترین استراتژی انتخاب می‌شود

### 10.3 PCSE دقیقا چه کمکی می‌کند؟

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

یعنی سیستم فقط نمی‌گوید:

- چون نیتروژن پایین است، فلان مقدار کود بده

بلکه مقایسه می‌کند:

- اگر سناریوی نگهدارنده اجرا شود، عملکرد چقدر می‌شود؟
- اگر سناریوی اصلاحی اجرا شود، gain عملکردی چقدر است؟
- آیا افزایش دوز واقعاً ارزش دارد یا خیر؟

### 10.4 اثر `fertilization/apps.py`

مقادیر این فایل مستقیما بر recommendation اثر دارند:

- `stage_targets` دوز هدف N/P/K را تعیین می‌کند
- `formula` نوع کود پیشنهادی را تعیین می‌کند
- `application_method` روش مصرف را تعیین می‌کند
- `timing` زمان مناسب مصرف را تعیین می‌کند
- `strategy_profiles` سناریوهای رقابتی را می‌سازد
- `rain_delay_threshold_mm` روی ریسک زمان‌بندی مصرف اثر دارد
- `validity_days` پنجره اعتبار را تعیین می‌کند

### 10.5 heuristic fallback در کودهی

اگر PCSE اجرا نشود، `_optimize_fertilization_with_heuristic()` استفاده می‌شود.

این مسیر بر این مبنا تصمیم می‌گیرد:

- نیتروژن فعلی
- فسفر فعلی
- پتاسیم فعلی
- pH خاک
- مرحله رشد
- بارش پیش‌رو

خروجی آن هنوز ساختاریافته و مفید است، اما مثل مسیر PCSE مقایسه عملکرد شبیه‌سازی‌شده ندارد.

---

## 11) نقش P و K در حالی که event کودهی فقط `apply_n` است

در نسخه فعلی شبیه‌سازی، event مستقیم کودهی که وارد `TimedEvents` می‌شود بیشتر روی `N_amount` تمرکز دارد.

اما پروژه برای `P` و `K` هم یک adjustment تکمیلی دارد:

- `_estimate_pk_stress_factor()`
- `_apply_pk_adjustment()`

این بخش بعد از اجرای PCSE روی خروجی اعمال می‌شود.

منطق آن:

- اگر فسفر پایین باشد، `p_factor` کاهش می‌یابد
- اگر پتاسیم پایین باشد، `k_factor` کاهش می‌یابد
- اگر `pH` یا `EC` نامناسب باشد، penalty اعمال می‌شود
- سپس این factor روی:
  - `yield_estimate`
  - `biomass`
  - `max_lai`
  اعمال می‌شود

پس حتی اگر event سناریویی مستقیم بیشتر نیتروژنی باشد، وضعیت `P`, `K`, `pH`, `EC` باز هم روی recommendation نهایی اثر می‌گذارد.

---

## 12) RAG چطور از خروجی PCSE استفاده می‌کند؟

### در `rag/services/irrigation.py`

این سرویس:

1. forecastها و داده مزرعه را می‌گیرد
2. نیاز آبی روزانه را از FAO-56 محاسبه می‌کند
3. optimizer شبیه‌سازی را صدا می‌زند
4. اگر `optimized_result` موجود باشد، `context_text` آن را به prompt اضافه می‌کند
5. LLM پاسخ را تولید می‌کند
6. پاسخ با fallback ساختاریافته merge می‌شود

نکته مهم:

- LLM مرجع عددی اصلی نیست
- `optimized_result` مرجع اصلی اعداد است

این موضوع حتی در prompt پیش‌فرض هم صریح آمده است.

### در `rag/services/fertilization.py`

منطق مشابه است:

1. sensor و forecast خوانده می‌شود
2. optimizer کودهی اجرا می‌شود
3. `context_text` به system prompt اضافه می‌شود
4. LLM متن recommendation را می‌سازد
5. خروجی با fallback عددی merge می‌شود

در نتیجه:

- PCSE و optimizer عددها را می‌سازند
- RAG متن را کاربرپسند و اجرایی می‌کند

---

## 13) تفاوت بین simulation engine و recommendation layer

### لایه simulation

در `crop_simulation/services.py`:

- سناریو اجرا می‌شود
- eventها merge می‌شوند
- خروجی‌های عملکردی تولید می‌شوند

### لایه recommendation

در `crop_simulation/recommendation_optimizer.py`:

- چند سناریو candidate ساخته می‌شود
- همه با simulation یا heuristic ارزیابی می‌شوند
- بهترین گزینه انتخاب می‌شود
- `context_text` برای RAG تولید می‌شود

### لایه presentation

در `rag/services/irrigation.py` و `rag/services/fertilization.py`:

- متن نهایی
- هشدارها
- list itemها
- توضیح توسعه‌پذیر

ساخته می‌شود.

---

## 14) سناریوی واقعی آبیاری در این پروژه

یک نمونه ساده:

1. forecast هفت روز آینده دریافت می‌شود
2. نیاز آبی روزانه محاسبه می‌شود
3. optimizer سه سناریوی آبیاری می‌سازد:
   - محافظه‌کارانه
   - متعادل
   - حمایتی
4. هر سناریو به `TimedEvents` تزریق می‌شود
5. PCSE برای هر سناریو اجرا می‌شود
6. عملکرد نسبی هر سناریو اندازه‌گیری می‌شود
7. بهترین سناریو انتخاب می‌شود
8. RAG همان سناریو را به زبان قابل فهم برای کاربر توضیح می‌دهد

---

## 15) سناریوی واقعی کودهی در این پروژه

یک نمونه ساده:

1. مرحله رشد تشخیص داده می‌شود
2. target غذایی همان مرحله از `fertilization/apps.py` خوانده می‌شود
3. چند سناریوی دوز و شدت مصرف ساخته می‌شود
4. برای هر سناریو event `apply_n` ساخته می‌شود
5. PCSE سناریوها را اجرا می‌کند
6. خروجی عملکرد مقایسه می‌شود
7. بهترین برنامه انتخاب می‌شود
8. RAG آن را به صورت JSON ساختاریافته به کاربر برمی‌گرداند

---

## 16) مزیت‌های استفاده از PCSE در توصیه آبیاری و کودهی

- recommendationها فقط rule-based نیستند
- تصمیم‌ها بر پایه مقایسه سناریو هستند
- امکان اتصال داده واقعی مزرعه به مدل رشد وجود دارد
- مرحله رشد، هوا، خاک و مدیریت همزمان دیده می‌شوند
- recommendation خروجی قابل توضیح‌تری برای LLM تولید می‌کند

---

## 17) محدودیت‌های فعلی پیاده‌سازی

این پروژه عملی و مفید است، اما چند محدودیت مهم دارد:

- کیفیت recommendation وابسته به کیفیت `simulation profile` گیاه است
- اگر پروفایل simulation وجود نداشته باشد، سیستم به heuristic fallback می‌رود
- event کودهی در شبیه‌سازی فعلی بیشتر نیتروژن‌محور است
- `P` و `K` به شکل adjustment پس از اجرا اعمال می‌شوند، نه لزوما event-driven کامل
- forecastهای هوا کوتاه‌مدت‌اند؛ پس recommendationها مخصوص تصمیم‌گیری عملیاتی نزدیک هستند
- score برخی سناریوها از `yield_estimate / 100` ساخته می‌شود و هنوز می‌تواند با calibration دقیق‌تر بهبود یابد

---

## 18) جمع‌بندی عملی

اگر بخواهیم نقش PCSE را در یک جمله خلاصه کنیم:

> PCSE در این پروژه موتور سنجش اثر تصمیم‌های آبیاری و کودهی روی عملکرد احتمالی گیاه است.

و اگر بخواهیم نقش `irrigation/apps.py` و `fertilization/apps.py` را هم در یک جمله بگوییم:

> این دو فایل policy و defaultهای تصمیم‌گیری را تعریف می‌کنند، و optimizer با استفاده از همان policyها سناریو می‌سازد و با PCSE ارزیابی می‌کند.

بنابراین خروجی نهایی recommendation حاصل ترکیب سه لایه است:

1. داده واقعی مزرعه و forecast
2. شبیه‌سازی سناریویی با PCSE
3. تولید پاسخ ساختاریافته و قابل فهم با RAG

---

## 19) فایل‌هایی که اگر بخواهید این سیستم را توسعه دهید باید اول ببینید

- `crop_simulation/services.py`
- `crop_simulation/recommendation_optimizer.py`
- `crop_simulation/apps.py`
- `irrigation/apps.py`
- `fertilization/apps.py`
- `rag/services/irrigation.py`
- `rag/services/fertilization.py`

اگر بخواهید behavior سیستم را تغییر دهید:

- برای تغییر policy آبیاری: `irrigation/apps.py`
- برای تغییر policy کودهی: `fertilization/apps.py`
- برای تغییر منطق ارزیابی سناریو: `crop_simulation/recommendation_optimizer.py`
- برای تغییر اجرای واقعی مدل: `crop_simulation/services.py`
- برای تغییر متن و ساختار پاسخ: `rag/services/irrigation.py` و `rag/services/fertilization.py`

