Ajout des sélection par chaines critique dans pda
This commit is contained in:
parent
9ca623aef1
commit
c55d478660
@ -43,7 +43,13 @@ inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
||||
|
||||
|
||||
def interface_plan_d_action(G_temp):
|
||||
st.markdown(f"# {str(_('pages.plan_d_action.title'))}")
|
||||
|
||||
if "sel_prod" not in st.session_state:
|
||||
st.session_state.sel_prod = None
|
||||
if "sel_comp" not in st.session_state:
|
||||
st.session_state.sel_comp = None
|
||||
if "sel_miner" not in st.session_state:
|
||||
st.session_state.sel_miner = None
|
||||
|
||||
if "plan_d_action" not in st.session_state:
|
||||
st.session_state["plan_d_action"] = 0
|
||||
@ -55,6 +61,7 @@ def interface_plan_d_action(G_temp):
|
||||
st.session_state["G_md"] = f"{JOBS}/{st.session_state["uuid"]}.md"
|
||||
|
||||
if st.session_state["plan_d_action"] == 0:
|
||||
st.markdown(f"# {str(_('pages.plan_d_action.title'))}")
|
||||
html_expander(f"{str(_('pages.plan_d_action.help'))}", content="\n".join(_("pages.plan_d_action.help_content")), open_by_default=False, details_class="details_introduction")
|
||||
# Préparation du graphe
|
||||
G_temp, niveaux_temp = preparer_graphe(G_temp)
|
||||
@ -86,8 +93,8 @@ def interface_plan_d_action(G_temp):
|
||||
st.session_state["plan_d_action"] = 1
|
||||
st.rerun() # force la réexécution immédiatement avec état mis à jour
|
||||
|
||||
|
||||
elif st.session_state["plan_d_action"] == 1:
|
||||
st.markdown("")
|
||||
# Traitement lourd une seule fois
|
||||
if not st.session_state["g_md_done"]:
|
||||
write_dot(st.session_state["G_final"], st.session_state["G_dot"])
|
||||
@ -104,6 +111,9 @@ def interface_plan_d_action(G_temp):
|
||||
if (st.button("Réinitialiser", icon=":material/refresh:")):
|
||||
st.session_state["plan_d_action"] = 0
|
||||
st.session_state["g_md_done"] = False
|
||||
st.session_state.sel_prod = None
|
||||
st.session_state.sel_comp = None
|
||||
st.session_state.sel_miner = None
|
||||
for f in JOBS.glob(f"*{st.session_state["uuid"]}*"):
|
||||
if f.is_file():
|
||||
f.unlink()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -155,3 +155,11 @@ INDICATEURS = {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
poids_operation = {
|
||||
'Extraction': 1,
|
||||
'Traitement': 1.5,
|
||||
'Assemblage': 1.5,
|
||||
'Fabrication': 2,
|
||||
'Substitution': 2
|
||||
}
|
||||
|
||||
@ -3,7 +3,8 @@ import matplotlib.pyplot as plt
|
||||
|
||||
from app.plan_d_action.utils.data.config import (
|
||||
PRECONISATIONS,
|
||||
INDICATEURS
|
||||
INDICATEURS,
|
||||
poids_operation
|
||||
)
|
||||
from app.plan_d_action.utils.data.data_processing import parse_chains_md
|
||||
from app.plan_d_action.utils.data.data_utils import (
|
||||
@ -17,17 +18,95 @@ from app.plan_d_action.utils.data.pda_interface import (
|
||||
)
|
||||
from app.plan_d_action.utils.data.data_utils import initialiser_seuils
|
||||
|
||||
def calcul_poids_chaine(poids_A, poids_F, poids_T, poids_E, poids_M):
|
||||
poids_total = (\
|
||||
poids_A * poids_operation["Assemblage"] + \
|
||||
poids_F * poids_operation["Fabrication"] + \
|
||||
poids_T * poids_operation["Traitement"] + \
|
||||
poids_E * poids_operation["Extraction"] + \
|
||||
poids_M * poids_operation["Substitution"] \
|
||||
) / sum(poids_operation.values())
|
||||
|
||||
if poids_total < 3:
|
||||
criticite_chaine = "Modérée"
|
||||
niveau_criticite = {"Facile"}
|
||||
elif poids_total < 6:
|
||||
criticite_chaine = "Élevée"
|
||||
niveau_criticite = {"Facile", "Modérée"}
|
||||
else:
|
||||
criticite_chaine = "Critique"
|
||||
niveau_criticite = {"Facile", "Modérée", "Difficile"}
|
||||
|
||||
return criticite_chaine, niveau_criticite, poids_total
|
||||
|
||||
def analyser_chaines(chaines, produits, composants, mineraux, seuils, top_n=None):
|
||||
resultats = []
|
||||
|
||||
for chaine in chaines:
|
||||
sel_prod = chaine["produit"]
|
||||
sel_comp = chaine["composant"]
|
||||
sel_miner = chaine["minerai"]
|
||||
|
||||
poids_A, *_ = set_vulnerability(produits[sel_prod]["IHH_Assemblage"], produits[sel_prod]["ISG_Assemblage"], "IHH", "ISG", seuils)
|
||||
poids_F, *_ = set_vulnerability(composants[sel_comp]["IHH_Fabrication"], composants[sel_comp]["ISG_Fabrication"], "IHH", "ISG", seuils)
|
||||
poids_T, *_ = set_vulnerability(mineraux[sel_miner]["IHH_Traitement"], mineraux[sel_miner]["ISG_Traitement"], "IHH", "ISG", seuils)
|
||||
poids_E, *_ = set_vulnerability(mineraux[sel_miner]["IHH_Extraction"], mineraux[sel_miner]["ISG_Extraction"], "IHH", "ISG", seuils)
|
||||
poids_M, *_ = set_vulnerability(mineraux[sel_miner]["ICS"], mineraux[sel_miner]["IVC"], "ICS", "IVC", seuils)
|
||||
|
||||
criticite_chaine, niveau_criticite, poids_total = calcul_poids_chaine(
|
||||
poids_A, poids_F, poids_T, poids_E, poids_M
|
||||
)
|
||||
|
||||
resultats.append({
|
||||
"chaine": chaine,
|
||||
"criticite_chaine": criticite_chaine,
|
||||
"niveau_criticite": niveau_criticite,
|
||||
"poids_total": poids_total
|
||||
})
|
||||
|
||||
# Tri décroissant
|
||||
resultats.sort(key=lambda x: x["poids_total"], reverse=True)
|
||||
|
||||
# Si top_n n'est pas spécifié, tout est retourné
|
||||
if top_n is None or top_n >= len(resultats):
|
||||
return resultats
|
||||
|
||||
# Déterminer le seuil de coupure
|
||||
seuil_poids = resultats[top_n - 1]["poids_total"]
|
||||
|
||||
# Inclure tous ceux dont le poids est égal au seuil
|
||||
top_resultats = [r for r in resultats if r["poids_total"] >= seuil_poids]
|
||||
|
||||
return top_resultats
|
||||
|
||||
def tableau_de_bord(chains, produits, composants, mineraux, seuils):
|
||||
col_left, col_right = st.columns([1, 1], gap="small", border=True)
|
||||
col_left, col_right = st.columns([2, 3], gap="small", border=True)
|
||||
with col_left:
|
||||
st.markdown("**<u>Panneau de sélection</u>**", unsafe_allow_html=True)
|
||||
|
||||
produits_disponibles = sorted({c["produit"] for c in chains})
|
||||
sel_prod = st.selectbox("Produit", produits_disponibles)
|
||||
sel_prod = st.selectbox("Produit", produits_disponibles, index=produits_disponibles.index(st.session_state.sel_prod) if st.session_state.sel_prod else 0)
|
||||
|
||||
composants_dispo = sorted({c["composant"] for c in chains if c["produit"] == sel_prod})
|
||||
sel_comp = st.selectbox("Composant", composants_dispo)
|
||||
sel_comp = st.selectbox("Composant", composants_dispo, index=composants_dispo.index(st.session_state.sel_comp) if st.session_state.sel_comp else 0)
|
||||
|
||||
mineraux_dispo = sorted({c["minerai"] for c in chains if c["produit"] == sel_prod and c["composant"] == sel_comp})
|
||||
sel_miner = st.selectbox("Minerai", mineraux_dispo)
|
||||
sel_miner = st.selectbox("Minerai", mineraux_dispo, index=mineraux_dispo.index(st.session_state.sel_miner) if st.session_state.sel_miner else 0)
|
||||
with col_right:
|
||||
top_chains = analyser_chaines(chains, produits, composants, mineraux, seuils, top_n=5)
|
||||
st.markdown("**<u>Top chaînes critiques pour sélection rapide</u>**", unsafe_allow_html=True)
|
||||
for i, entry in enumerate(top_chains):
|
||||
ch = entry["chaine"]
|
||||
poids = entry["poids_total"]
|
||||
criticite = entry["criticite_chaine"]
|
||||
if st.button(f"**{ch['produit']} <-> {ch['composant']} <-> {ch['minerai']}** : {poids:.2f} → {criticite}", key=f"select_{i}"):
|
||||
st.session_state.sel_prod = ch["produit"]
|
||||
st.session_state.sel_comp = ch["composant"]
|
||||
st.session_state.sel_miner = ch["minerai"]
|
||||
st.rerun()
|
||||
|
||||
c1, c2 = st.columns([3, 2], gap="small", border=True, vertical_alignment='center')
|
||||
with c1:
|
||||
st.markdown("**<u>Synthèse des criticités</u>**", unsafe_allow_html=True)
|
||||
poids_A, couleur_A, couleur_A_ihh, couleur_A_isg = set_vulnerability(produits[sel_prod]["IHH_Assemblage"], produits[sel_prod]["ISG_Assemblage"], "IHH", "ISG", seuils)
|
||||
poids_F, couleur_F, couleur_F_ihh, couleur_F_isg = set_vulnerability(composants[sel_comp]["IHH_Fabrication"], composants[sel_comp]["ISG_Fabrication"], "IHH", "ISG", seuils)
|
||||
@ -41,32 +120,8 @@ def tableau_de_bord(chains, produits, composants, mineraux, seuils):
|
||||
st.markdown(f"* **{sel_miner} - Extraction** : {colorer_couleurs(couleur_E)} ({poids_E})")
|
||||
st.markdown(f"* **{sel_miner} - Minerai** : {colorer_couleurs(couleur_M)} ({poids_M})")
|
||||
|
||||
poids_operation = {
|
||||
'Extraction': 1,
|
||||
'Traitement': 1.5,
|
||||
'Assemblage': 1.5,
|
||||
'Fabrication': 2,
|
||||
'Substitution': 2
|
||||
}
|
||||
|
||||
poids_total = (\
|
||||
poids_A * poids_operation["Assemblage"] + \
|
||||
poids_F * poids_operation["Fabrication"] + \
|
||||
poids_T * poids_operation["Traitement"] + \
|
||||
poids_E * poids_operation["Extraction"] + \
|
||||
poids_M * poids_operation["Substitution"] \
|
||||
) / sum(poids_operation.values())
|
||||
|
||||
if poids_total < 3:
|
||||
criticite_chaine = "Modérée"
|
||||
niveau_criticite = {"Facile"}
|
||||
elif poids_total < 6:
|
||||
criticite_chaine = "Élevée"
|
||||
niveau_criticite = {"Facile", "Modérée"}
|
||||
else:
|
||||
criticite_chaine = "Critique"
|
||||
niveau_criticite = {"Facile", "Modérée", "Difficile"}
|
||||
|
||||
criticite_chaine, niveau_criticite, poids_total = calcul_poids_chaine(poids_A, poids_F, poids_T, poids_E, poids_M)
|
||||
with c2:
|
||||
st.error(f"**Criticité globale : {criticite_chaine} ({poids_total})**")
|
||||
|
||||
return (
|
||||
@ -82,11 +137,11 @@ def afficher_criticites(produits, composants, mineraux, sel_prod, sel_comp, sel_
|
||||
col_left, col_right = st.columns([1, 1], gap="small", border=True)
|
||||
|
||||
with col_left:
|
||||
fig1, ax1 = plt.subplots(figsize=(1, 1))
|
||||
ax1.scatter([produits[sel_prod]["ISG_Assemblage"]], [produits[sel_prod]["IHH_Assemblage"]], label="Assemblage".ljust(20), s=5)
|
||||
ax1.scatter([composants[sel_comp]["ISG_Fabrication"]], [composants[sel_comp]["IHH_Fabrication"]], label="Fabrication".ljust(20), s=5)
|
||||
ax1.scatter([mineraux[sel_miner]["ISG_Extraction"]], [mineraux[sel_miner]["IHH_Extraction"]], label="Extraction".ljust(20), s=5)
|
||||
ax1.scatter([mineraux[sel_miner]["ISG_Traitement"]], [mineraux[sel_miner]["IHH_Traitement"]], label="Traitement".ljust(20), s=5)
|
||||
fig1, ax1 = plt.subplots(figsize=(2, 2.4))
|
||||
ax1.scatter([produits[sel_prod]["ISG_Assemblage"]], [produits[sel_prod]["IHH_Assemblage"]], label="Assemblage", s=5)
|
||||
ax1.scatter([composants[sel_comp]["ISG_Fabrication"]], [composants[sel_comp]["IHH_Fabrication"]], label="Fabrication", s=5)
|
||||
ax1.scatter([mineraux[sel_miner]["ISG_Extraction"]], [mineraux[sel_miner]["IHH_Extraction"]], label="Extraction", s=5)
|
||||
ax1.scatter([mineraux[sel_miner]["ISG_Traitement"]], [mineraux[sel_miner]["IHH_Traitement"]], label="Traitement", s=5)
|
||||
|
||||
# Seuils ISG (vertical)
|
||||
ax1.axvline(seuils["ISG"]["vert"]["max"], linestyle='--', color='green', alpha=0.7, linewidth=0.5) # Seuil vert-orange
|
||||
@ -101,13 +156,13 @@ def afficher_criticites(produits, composants, mineraux, sel_prod, sel_comp, sel_
|
||||
ax1.set_xlabel("ISG", fontsize=4)
|
||||
ax1.set_ylabel("IHH", fontsize=4)
|
||||
ax1.tick_params(axis='both', which='major', labelsize=4)
|
||||
ax1.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=4)
|
||||
ax1.legend(bbox_to_anchor=(0.5, -0.25), loc='upper center', fontsize=4)
|
||||
plt.tight_layout()
|
||||
st.pyplot(fig1)
|
||||
|
||||
with col_right:
|
||||
fig2, ax2 = plt.subplots(figsize=(1, 1))
|
||||
ax2.scatter([mineraux[sel_miner]["IVC"]], [mineraux[sel_miner]["ICS"]], color='green', s=5, label=sel_miner.ljust(20))
|
||||
fig2, ax2 = plt.subplots(figsize=(2, 2.1))
|
||||
ax2.scatter([mineraux[sel_miner]["IVC"]], [mineraux[sel_miner]["ICS"]], color='green', s=5, label=sel_miner)
|
||||
|
||||
# Seuils IVC (vertical)
|
||||
ax2.axvline(seuils["IVC"]["vert"]["max"], linestyle='--', color='green', alpha=0.7, linewidth=0.5) # Seuil vert-orange
|
||||
@ -122,7 +177,7 @@ def afficher_criticites(produits, composants, mineraux, sel_prod, sel_comp, sel_
|
||||
ax2.set_xlabel("IVC", fontsize=4)
|
||||
ax2.set_ylabel("ICS", fontsize=4)
|
||||
ax2.tick_params(axis='both', which='major', labelsize=4)
|
||||
ax2.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=4)
|
||||
ax2.legend(bbox_to_anchor=(0.5, -0.25), loc='upper center', fontsize=4)
|
||||
plt.tight_layout()
|
||||
st.pyplot(fig2)
|
||||
|
||||
@ -269,6 +324,7 @@ def afficher_details_operations(produits, composants, mineraux, sel_prod, sel_co
|
||||
afficher_caracteristiques_minerai(sel_miner, mineraux[sel_miner], minerai_general)
|
||||
|
||||
def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"):
|
||||
|
||||
produits, composants, mineraux, chains, descriptions, details_sections = parse_chains_md(filepath)
|
||||
|
||||
if not chains:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user