File size: 6,372 Bytes
0ab0788
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import yaml
from matplotlib import colors as mcolors
from matplotlib.colors import ListedColormap

def menu_config_statisticals():
    STATS = {
        "Moyenne": "mean",
        "Maximum": "max",
        "Moyenne des maxima": "mean-max",
        "Mois comptabilisant le plus de maximas": "month",
        "Jour de pluie": "numday",
    }

    SEASON = {
        "Année hydrologique": "hydro",
        "Hiver": "djf",
        "Printemps": "mam",
        "Été": "jja",
        "Automne": "son",
    }

    SCALE = {
        "Horaire": "mm_h",
        "Journalière": "mm_j"
    }

    return STATS, SEASON, SCALE

def menu_config_gev():
    MODEL_PARAM = {
        "s_gev": {"mu0": "μ₀", "sigma0": "σ₀", "xi": "ξ"},
        "ns_gev_m1": {"mu0": "μ₀", "mu1": "μ₁", "sigma0": "σ₀", "xi": "ξ"},
        "ns_gev_m2": {"mu0": "μ₀", "sigma0": "σ₀", "sigma1": "σ₁", "xi": "ξ"},
        "ns_gev_m3": {"mu0": "μ₀", "mu1": "μ₁", "sigma0": "σ₀", "sigma1": "σ₁", "xi": "ξ"},
        "ns_gev_m1_break_year": {"mu0": "μ₀", "mu1": "μ₁", "sigma0": "σ₀", "xi": "ξ"},
        "ns_gev_m2_break_year": {"mu0": "μ₀", "sigma0": "σ₀", "sigma1": "σ₁", "xi": "ξ"},
        "ns_gev_m3_break_year": {"mu0": "μ₀", "mu1": "μ₁", "sigma0": "σ₀", "sigma1": "σ₁", "xi": "ξ"},
        "best_model": {"mu0": "μ₀", "mu1": "μ₁", "sigma0": "σ₀", "sigma1": "σ₁", "xi": "ξ"}
    }

    # Liste complète des modèles avec leurs équations explicites
    MODEL_NAME = {
        # Stationnaire
        "M₀(μ₀, σ₀) : μ(t) = μ₀ ; σ(t) = σ₀ ; ξ(t) = ξ": "s_gev",

        # Non stationnaires simples
        "M₁(μ, σ₀) : μ(t) = μ₀ + μ₁·t ; σ(t) = σ₀ ; ξ(t) = ξ": "ns_gev_m1",
        "M₂(μ₀, σ) : μ(t) = μ₀ ; σ(t) = σ₀ + σ₁·t ; ξ(t) = ξ": "ns_gev_m2",
        "M₃(μ, σ) : μ(t) = μ₀ + μ₁·t ; σ(t) = σ₀ + σ₁·t ; ξ(t) = ξ": "ns_gev_m3",

        # Non stationnaires avec rupture
        "M₁⋆(μ, σ₀) : μ(t) = μ₀ + μ₁·t₊ ; σ(t) = σ₀ ; ξ(t) = ξ en notant t₊ = t · 𝟙_{t > t₀} avec t₀ = 1985": "ns_gev_m1_break_year",
        "M₂⋆(μ₀, σ) : μ(t) = μ₀ ; σ(t) = σ₀ + σ₁·t₊ ; ξ(t) = ξ en notant t₊ = t · 𝟙_{t > t₀} avec t₀ = 1985": "ns_gev_m2_break_year",
        "M₃⋆(μ, σ) : μ(t) = μ₀ + μ₁·t₊ ; σ(t) = σ₀ + σ₁·t₊ ; ξ(t) = ξ en notant t₊ = t · 𝟙_{t > t₀} avec t₀ = 1985": "ns_gev_m3_break_year",

        "M₃⋆ᵇ(μ, σ) : μ(t) = μ₀ + μ₁·t₊ ; σ(t) = σ₀ + σ₁·t₊ ; ξ(t) = ξ en notant t₊ = t · 𝟙_{t > t₀} avec t₀ = 1985": "ns_gev_m3_break_year_bootstrap",

        # Autres
        "M(minimisant AIC)": "best_model",
        "M(minimisant pval)": "best_model_lrt"
    }

    return MODEL_PARAM, MODEL_NAME

def reverse_param_label(param_label: str, model_name: str, model_param_map: dict) -> str:
    """
    Convertit un label unicode (e.g. 'μ₀') en nom de paramètre interne (e.g. 'mu0'),
    en utilisant le mapping inverse de model_param_map.
    """
    if model_name not in model_param_map:
        raise ValueError(f"Modèle {model_name} non trouvé dans le mapping.")
    
    reverse_map = {v: k for k, v in model_param_map[model_name].items()}
    
    if param_label not in reverse_map:
        raise ValueError(f"Label {param_label} non trouvé pour le modèle {model_name}.")
    
    return reverse_map[param_label]



def load_config(config_path: str) -> dict:
    with open(config_path, "r") as f:
        return yaml.safe_load(f)


def echelle_config(type_: bool, echelle: str = None, n_colors: int = 256):
    if type_: # Continu

        if echelle == "diverging_zero_white": # Choix personnalisé
            # Dégradé négatif (bleu) → 0 (blanc) → positif (jaune à rouge)
            custom_colorscale = [
                (0.0, "#08306B"),   # bleu foncé
                (0.1, "#2171B5"),
                (0.2, "#6BAED6"),
                (0.3, "#C6DBEF"),
                (0.49, "#ffffff"),  # blanc à 0
                (0.5, "#ffffff"),
                (0.6, "#ffffb2"),   # jaune clair
                (0.7, "#fecc5c"),
                (0.8, "#fd8d3c"),
                (0.9, "#f03b20"),
                (1.0, "#bd0026"),   # rouge foncé
            ]

            cmap = mcolors.LinearSegmentedColormap.from_list("diverging_zero_white", custom_colorscale)

            if n_colors is not None:
                # Retourne une version discrète avec n couleurs
                return ListedColormap([cmap(i / (n_colors - 1)) for i in range(n_colors)])
            else:
                return cmap
            
        custom_colorscale = [
            (0.0, "#FFFFE5"),  # blanc
            (0.1, "#DDEED6"),
            (0.2, "#BCDDC8"),
            (0.3, "#9BCCBA"),
            (0.4, "#7ABBAC"),
            (0.5, "#59AA9E"),
            (0.6, "#389990"),
            (0.7, "#29837A"),
            (0.8, "#1C6D63"),
            (0.9, "#0F564B"),
            (1.0, "#003C30"),
        ]

        cmap = mcolors.LinearSegmentedColormap.from_list("custom", custom_colorscale)

        if n_colors is not None:
            # Retourne une version discrète avec n couleurs
            return ListedColormap([cmap(i / (n_colors - 1)) for i in range(n_colors)])
        else:
            return cmap
       
    else: # Discret
      
        couleurs_par_mois = [
            "#ffffff",  # Janvier 
            "blue",     # Février 
            "green",    # Mars 
            "red",      # Avril 
            "orange",   # Mai 
            "#00CED1",  # Juin 
            "yellow",   # Juillet 
            "#f781bf",  # Août 
            "purple",   # Septembre 
            "#654321",  # Octobre 
            "darkblue", # Novembre
            "black",    # Décembre 
        ]

        return ListedColormap(couleurs_par_mois)


def get_readable_season(season_code: str) -> str:
    """
    Retourne le nom humainement lisible d'une saison à partir de son code ("hydro", "djf", etc.).
    Résultat en minuscules.
    """
    _, SEASON, _ = menu_config_statisticals()
    reverse_season = {v: k.lower() for k, v in SEASON.items()}
    if season_code not in reverse_season:
        raise ValueError(f"Code saison inconnu : {season_code}")
    return reverse_season[season_code]