Spaces:
Runtime error
Runtime error
Rim BACCOUR
commited on
add prompt to compare both scenarii with and without ombrage
Browse files- prompts/summary_prompt.py +28 -2
- summary_test.py +52 -3
- utils/soil_utils.py +39 -0
- utils/summary.py +42 -3
prompts/summary_prompt.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
-
""" This file contains prompts for
|
2 |
|
3 |
-
|
4 |
Tu es un expert en météorologie et en analyse climatique.
|
5 |
Ta mission est de fournir une synthèse détaillée de l’évolution des conditions météorologiques d’une région donnée.
|
6 |
Tu exploites trois indicateurs clés : la température, les précipitations et l’irradiance solaire.
|
@@ -19,7 +19,33 @@ metrological_data_summary_prompt = """
|
|
19 |
- L’évolution passée et future des températures.
|
20 |
- L'évolution de la tendances des précipitations.
|
21 |
- Les variations de l’irradiance solaire.
|
|
|
22 |
avec des pourcentage de variation du futur par rapport aux années passées et en spécifiant les dates
|
23 |
Présente ta réponse sous un format structuré avec un résumé des tendances observées et des perspectives climatiques selon le scénario choisi."
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
"""
|
|
|
1 |
+
""" This file contains prompts for different LLM uses """
|
2 |
|
3 |
+
meterological_data_summary_prompt = """
|
4 |
Tu es un expert en météorologie et en analyse climatique.
|
5 |
Ta mission est de fournir une synthèse détaillée de l’évolution des conditions météorologiques d’une région donnée.
|
6 |
Tu exploites trois indicateurs clés : la température, les précipitations et l’irradiance solaire.
|
|
|
19 |
- L’évolution passée et future des températures.
|
20 |
- L'évolution de la tendances des précipitations.
|
21 |
- Les variations de l’irradiance solaire.
|
22 |
+
|
23 |
avec des pourcentage de variation du futur par rapport aux années passées et en spécifiant les dates
|
24 |
Présente ta réponse sous un format structuré avec un résumé des tendances observées et des perspectives climatiques selon le scénario choisi."
|
25 |
|
26 |
+
"""
|
27 |
+
|
28 |
+
|
29 |
+
agricultural_yield_comparison_prompt = """
|
30 |
+
Tu es un expert agronome et spécialiste en agrivoltaïsme chez Ombrea (entreprise spécialisée en agrivoltaisme).
|
31 |
+
Ta mission est d’analyser et de comparer deux scénarios agricoles :
|
32 |
+
Un avec ombrage statique apporté par les panneaux photovoltaïques sur la culture et un sans ombrage.
|
33 |
+
Tu dois conseiller un agriculteur sur la meilleure solution pour optimiser son rendement agricole.
|
34 |
+
Il faut se concentrer sur la vision long terme qui prend en compte les aléas climatiques.
|
35 |
+
Tu dois baser ton analyse sur les données suivantes :
|
36 |
+
* Caractéristiques du sol : [pH, texture, teneur en matière organique, capacité de rétention d’eau, etc.]
|
37 |
+
* Type de culture : [Nom de la culture et ses besoins spécifiques en lumière, température et eau]
|
38 |
+
* Besoins hydriques : [Quantité d’eau requise et sensibilité au stress hydrique]
|
39 |
+
* Projections climatiques : [Température moyenne, précipitations, risques de sécheresse, vagues de chaleur, etc.]
|
40 |
+
|
41 |
+
Ton analyse devra inclure :
|
42 |
+
- Comparaison des rendements agricoles : Différences de productivité avec et sans ombrage agrivoltaïque.
|
43 |
+
- Impact sur la consommation d’eau : Évaluation des économies d’eau potentielles grâce à la régulation thermique et l’ombrage.
|
44 |
+
- Effet sur la qualité des cultures : Influence des conditions microclimatiques créées par l’agrivoltaïsme.
|
45 |
+
- Bilan économique : Gains estimés en production et en coûts d’irrigation.
|
46 |
+
|
47 |
+
Formule une réponse détaillée et pédagogique pour l’agriculteur, en expliquant pourquoi l’un des scénarios est plus avantageux.
|
48 |
+
Par exp: Grâce à l’ombrage : Le rendement agricole serait de +X%, Les besoins en eau seraient donc [réduit] de X%.
|
49 |
+
Tu devras vulgariser les concepts techniques pour une meilleure compréhension, en te basant sur des données input et des retours d’expérience.
|
50 |
+
L'utilisateur te founira le nom de la culture, les caractéristiques du sol dans la région en question et les données des rendements avec et sans ombrage.
|
51 |
"""
|
summary_test.py
CHANGED
@@ -2,7 +2,7 @@ import pandas as pd
|
|
2 |
import pandas as pd
|
3 |
import numpy as np
|
4 |
|
5 |
-
from utils.summary import
|
6 |
# Générer des dates sur 5 ans (historique) + 5 ans (prévision)
|
7 |
dates_past = pd.date_range(start="2023-01-01", periods=36, freq='ME') # 3 ans d'historique
|
8 |
dates_future = pd.date_range(start="2023-01-01", periods=60, freq='ME') # 5 ans de prévisions
|
@@ -61,6 +61,55 @@ print(rain_df.head(3))
|
|
61 |
print("\nIrradiance (extrait) :")
|
62 |
print(irradiation_df.head(3))
|
63 |
|
|
|
|
|
|
|
64 |
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import pandas as pd
|
3 |
import numpy as np
|
4 |
|
5 |
+
from utils.summary import get_meterological_summary, get_agricultural_yield_comparison
|
6 |
# Générer des dates sur 5 ans (historique) + 5 ans (prévision)
|
7 |
dates_past = pd.date_range(start="2023-01-01", periods=36, freq='ME') # 3 ans d'historique
|
8 |
dates_future = pd.date_range(start="2023-01-01", periods=60, freq='ME') # 5 ans de prévisions
|
|
|
61 |
print("\nIrradiance (extrait) :")
|
62 |
print(irradiation_df.head(3))
|
63 |
|
64 |
+
if __name__ == "__main__":
|
65 |
+
# summary = get_meterological_summary(scenario, temperature_df, rain_df, irradiation_df)
|
66 |
+
# print(summary)
|
67 |
|
68 |
+
# Example usage
|
69 |
+
import pandas as pd
|
70 |
+
import numpy as np
|
71 |
+
|
72 |
+
from utils.soil_utils import find_nearest_point
|
73 |
+
city = "Bourgogne Franche Comté"
|
74 |
+
closest_soil_features = find_nearest_point(city)
|
75 |
+
print(closest_soil_features)
|
76 |
+
|
77 |
+
# Définir la période de 4 ans dans le passé + 15 ans dans le futur (19 ans)
|
78 |
+
start_date = "2010-01"
|
79 |
+
end_date = "2029-12"
|
80 |
+
|
81 |
+
# Générer une série de dates mensuelles
|
82 |
+
dates = pd.date_range(start=start_date, end=end_date, freq='M')
|
83 |
+
|
84 |
+
# Générer des données fictives de rendement (en tonnes par hectare)
|
85 |
+
np.random.seed(42) # Pour reproductibilité
|
86 |
+
|
87 |
+
# Tendance générale du rendement sans ombrage (augmentation progressive)
|
88 |
+
trend = np.linspace(2.5, 3.2, len(dates)) # Augmente légèrement sur les années
|
89 |
+
|
90 |
+
# Ajout de variations saisonnières et aléatoires
|
91 |
+
seasonality = 0.3 * np.sin(np.linspace(0, 12 * np.pi, len(dates))) # Effet saisonnier
|
92 |
+
random_variation = np.random.normal(0, 0.1, len(dates)) # Bruit aléatoire
|
93 |
+
|
94 |
+
# Calcul du rendement sans ombrage
|
95 |
+
yield_no_shade = trend + seasonality + random_variation
|
96 |
+
|
97 |
+
# Appliquer un effet d'ombrage (réduction de 10-20% du rendement)
|
98 |
+
shade_factor = np.random.uniform(0.1, 0.2, len(dates)) # Entre 10% et 20% de réduction
|
99 |
+
yield_with_shade = yield_no_shade * (1 - shade_factor)
|
100 |
+
|
101 |
+
# Créer le DataFrame
|
102 |
+
df = pd.DataFrame({
|
103 |
+
"date": dates,
|
104 |
+
"yield_no_shade": yield_no_shade,
|
105 |
+
"yield_with_shade": yield_with_shade
|
106 |
+
})
|
107 |
+
water_deficit_data = pd.DataFrame()
|
108 |
+
climate_data = pd.DataFrame()
|
109 |
+
|
110 |
+
print(get_agricultural_yield_comparison(culture="orge",
|
111 |
+
region="bourgogne franche comté",
|
112 |
+
water_df=water_deficit_data,
|
113 |
+
climate_df=climate_data,
|
114 |
+
soil_df=closest_soil_features,
|
115 |
+
agri_yield_df=df))
|
utils/soil_utils.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import geopandas as gpd
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
from geopy.geocoders import Nominatim
|
5 |
+
from shapely.geometry import Point
|
6 |
+
|
7 |
+
load_dotenv()
|
8 |
+
|
9 |
+
file_rmqs ='data/soil_data/raw_data/rmqs.geojson'
|
10 |
+
df = gpd.read_file(file_rmqs)
|
11 |
+
|
12 |
+
def get_city_coordinates(city_name):
|
13 |
+
"""Get latitude and longitude of a city using Nominatim."""
|
14 |
+
geolocator = Nominatim(user_agent="geo_finder")
|
15 |
+
location = geolocator.geocode(city_name)
|
16 |
+
if location:
|
17 |
+
return (location.longitude, location.latitude)
|
18 |
+
return None
|
19 |
+
|
20 |
+
def find_nearest_point(city_name):
|
21 |
+
"""Find the closest GPS point in the dataset to the given city."""
|
22 |
+
city_coords = get_city_coordinates(city_name)
|
23 |
+
print("city coords", city_coords)
|
24 |
+
if not city_coords:
|
25 |
+
return "City not found"
|
26 |
+
|
27 |
+
# Iterate through GeoJSON features
|
28 |
+
df["distance"] = df["geometry"].distance(Point(city_coords[0], city_coords[1]))
|
29 |
+
closest_point = df.loc[df["distance"].idxmin()]
|
30 |
+
|
31 |
+
|
32 |
+
return closest_point # Returns the closest feature
|
33 |
+
|
34 |
+
|
35 |
+
if __name__ == "__main__":
|
36 |
+
# Example usage
|
37 |
+
city = "Paris"
|
38 |
+
closest_feature = find_nearest_point(city)
|
39 |
+
print(closest_feature)
|
utils/summary.py
CHANGED
@@ -5,12 +5,15 @@ from dotenv import load_dotenv
|
|
5 |
from langchain_core.output_parsers import StrOutputParser
|
6 |
from langchain.prompts import ChatPromptTemplate
|
7 |
from langchain.chat_models import ChatOpenAI
|
8 |
-
from prompts.summary_prompt import
|
|
|
|
|
|
|
9 |
|
10 |
load_dotenv()
|
11 |
|
12 |
|
13 |
-
def
|
14 |
|
15 |
today = datetime.today().strftime("%Y/%m/%d")
|
16 |
|
@@ -29,7 +32,7 @@ def get_summary(scenario: str, temperature_df: pd.DataFrame, rain_df: pd.DataFra
|
|
29 |
output_parser = StrOutputParser()
|
30 |
prompt = ChatPromptTemplate.from_messages(
|
31 |
[
|
32 |
-
("system",
|
33 |
("human", "Je veux un résumé de ces prévisions métérologique: les données de temperature {temp_data}, les données de précipitation {rain_data}, les données de radiance solaire {irradiance_data}")
|
34 |
]
|
35 |
)
|
@@ -43,4 +46,40 @@ def get_summary(scenario: str, temperature_df: pd.DataFrame, rain_df: pd.DataFra
|
|
43 |
"irradiance_data": irradiance_data
|
44 |
})
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
return output_parser.parse(response)
|
|
|
5 |
from langchain_core.output_parsers import StrOutputParser
|
6 |
from langchain.prompts import ChatPromptTemplate
|
7 |
from langchain.chat_models import ChatOpenAI
|
8 |
+
from prompts.summary_prompt import (
|
9 |
+
meterological_data_summary_prompt,
|
10 |
+
agricultural_yield_comparison_prompt
|
11 |
+
)
|
12 |
|
13 |
load_dotenv()
|
14 |
|
15 |
|
16 |
+
def get_meterological_summary(scenario: str, temperature_df: pd.DataFrame, rain_df: pd.DataFrame, irradiance_df: pd.DataFrame) -> str:
|
17 |
|
18 |
today = datetime.today().strftime("%Y/%m/%d")
|
19 |
|
|
|
32 |
output_parser = StrOutputParser()
|
33 |
prompt = ChatPromptTemplate.from_messages(
|
34 |
[
|
35 |
+
("system", meterological_data_summary_prompt),
|
36 |
("human", "Je veux un résumé de ces prévisions métérologique: les données de temperature {temp_data}, les données de précipitation {rain_data}, les données de radiance solaire {irradiance_data}")
|
37 |
]
|
38 |
)
|
|
|
46 |
"irradiance_data": irradiance_data
|
47 |
})
|
48 |
|
49 |
+
return output_parser.parse(response)
|
50 |
+
|
51 |
+
|
52 |
+
def get_agricultural_yield_comparison(culture: str, region:str, agri_yield_df: pd.DataFrame, soil_df: pd.DataFrame, climate_df: pd.DataFrame, water_df: pd.DataFrame):
|
53 |
+
|
54 |
+
agricultural_yield = agri_yield_df.head(len(agri_yield_df)).to_string(index=False)
|
55 |
+
soil_data = soil_df.head(len(soil_df)).to_string(index=False)
|
56 |
+
water_data = water_df.head(len(water_df)).to_string(index=False)
|
57 |
+
climate_data = climate_df.head(len(climate_df)).to_string(index=False)
|
58 |
+
|
59 |
+
llm = ChatOpenAI(
|
60 |
+
model="gpt-4o",
|
61 |
+
temperature=0,
|
62 |
+
max_tokens=None,
|
63 |
+
timeout=None,
|
64 |
+
max_retries=2,
|
65 |
+
api_key=os.environ.get("OPENAI_API_KEY")
|
66 |
+
)
|
67 |
+
output_parser = StrOutputParser()
|
68 |
+
prompt = ChatPromptTemplate.from_messages(
|
69 |
+
[
|
70 |
+
("system", agricultural_yield_comparison_prompt),
|
71 |
+
("human", "Je suis agriculteur et je cultive de la {culture} à {region}. Voilà les caractéristiques du sol dans ma région {soil_data} et voilà l'historique et projections du rendement ma culture avec et sans ombrage {agricultural_yield}. J'ai aussi les donnés historiques et prévisions du stress hydrique {water_data} et des données climatiques {climate_data}. " )
|
72 |
+
]
|
73 |
+
)
|
74 |
+
chain = prompt | llm | output_parser
|
75 |
+
|
76 |
+
response = chain.invoke({
|
77 |
+
"culture": culture,
|
78 |
+
"region": region,
|
79 |
+
"soil_data": soil_data,
|
80 |
+
"water_data": water_data,
|
81 |
+
"climate_data": climate_data,
|
82 |
+
"agricultural_yield": agricultural_yield
|
83 |
+
})
|
84 |
+
|
85 |
return output_parser.parse(response)
|