"""
PMCMCG Corner Plot Generator

This module generates corner plots for MCMC analysis results using different plotting libraries
(corner, pygtc). It processes retrieval data and creates visualization plots with parameter
distributions and confidence intervals.

The script is designed to be called from command line with specific arguments and maintains
the exact sequence of operations for compatibility with the existing pipeline.
"""

import os
import traceback
from pathlib import Path

import corner
# import seaborn as sns
import pygtc
import numpy as np
import pickle
import sys
import matplotlib
matplotlib.rcParams['agg.path.chunksize'] = 10000
if not os.environ.get('SPHINX_BUILD'):
    matplotlib.use("TkAgg")
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import pandas as pd
from scipy.ndimage import gaussian_filter


def db_value_corner_plot(lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix,
                          target_kp, target_ecc, target_opi, target_t_eq):
    """
    Extract database values and median values for corner plot parameters.

    This function checks which parameters are available in the parameter lists
    and extracts corresponding target values and median values for plotting.

    Args:
        lista_par: List of fitted parameters
        lista_par_fix: List of fixed parameters
        best_fit_parameters: Median values for fitted parameters
        error_list: Error values for fitted parameters
        value_fix: Values for fixed parameters
        target_kp: Target K_p value
        target_ecc: Target eccentricity
        target_opi: Target omega value
        target_t_eq: Target equilibrium temperature

    Returns:
        tuple: Contains values_db (list), values_median (list), index (list),
               T0_f (float), et_f (float)
    """
    et_f = 0
    values_db = []
    values_median = []
    index = []
    if "kp" in lista_par:
        values_db.append(target_kp)
        values_median.append(best_fit_parameters[lista_par.index("kp")])
        index.append(lista_par.index("kp"))
    if "rv" in lista_par:
        values_db.append(0)
        values_median.append(best_fit_parameters[lista_par.index("rv")])
        index.append(lista_par.index("rv"))
    if "ecc" in lista_par:
        values_db.append(target_ecc)
        values_median.append(best_fit_parameters[lista_par.index("ecc")])
        index.append(lista_par.index("ecc"))
    if "opi" in lista_par:
        values_db.append(target_opi)
        values_median.append(best_fit_parameters[lista_par.index("opi")])
        index.append(lista_par.index("opi"))
    if "T0" in lista_par:
        T0_f = best_fit_parameters[lista_par.index("T0")]
        values_db.append(target_t_eq)
        values_median.append(best_fit_parameters[lista_par.index("T0")])
        index.append(lista_par.index("T0"))
        et_f = error_list[lista_par.index("T0")]
    elif "T0" in lista_par_fix:
        T0_f = value_fix[lista_par_fix.index("T0")]
    else:
        T0_f = None
    return values_db, values_median, index, T0_f, et_f


def find_param_arr(name, lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix, value=None):
    """
    Find parameter value and error from parameter lists.

    Searches for a parameter in the fitted parameters list first, then in
    the fixed parameters list, and finally uses the provided default value.

    Args:
        name: Parameter name to search for
        lista_par: List of fitted parameters
        lista_par_fix: List of fixed parameters
        best_fit_parameters: Median values for fitted parameters
        error_list: Error values for fitted parameters
        value_fix: Values for fixed parameters
        value: Default value to use if parameter not found

    Returns:
        ValueErrorTP: Object containing parameter value and error
    """
    from GUIBRUSHR.General_Constants.Classes.ValueErrorTP import ValueErrorTP
    error = 0
    if name in lista_par:
        param = best_fit_parameters[lista_par.index(name)]
        error = error_list[lista_par.index(name)]
    elif name in lista_par_fix:
        param = value_fix[lista_par_fix.index(name)]
    else:
        param = value
    return ValueErrorTP(param, error)


def plot_corner(arr1, lista_parametri, style_corner="black",
                figsize=None, title_fmt=".2f", smooth=1.0,
                show_titles=True, truth_values=None,
                levels=30, quantiles=None,
                bins=50):
    """
    Create a publication-ready corner plot.

    Parameters
    ----------
    arr1 : array-like
        MCMC samples with shape (nsamples, ndim)
    lista_parametri : list
        Parameter labels (supports LaTeX)
    style_corner : str
        Style options:
        - Contour styles (lines + datapoints): "black", "orange", "blue", "purple", "green", "brown"
        - Filled styles (filled contours, no datapoints): "blue_cmap", "orange_cmap"
        - Colormap style (density gradient): "gnuplot2"
    figsize : tuple, optional
        Figure size. If None, auto-calculated based on ndim
    title_fmt : str
        Format string for title values
    smooth : float
        Smoothing factor for contours
    show_titles : bool
        Show parameter values in titles
    truth_values : list, optional
        True values to overplot
    levels : int
        Number of contour levels for colormap styles (default 30)
    quantiles : list
        Quantiles to show (default [0.16, 0.5, 0.84])
    bins : int
        Number of bins for 2D histograms

    Returns
    -------
    figure : matplotlib.figure.Figure
    """

    if quantiles is None:
        quantiles = [0.16, 0.5, 0.84]
    ndim = arr1.shape[1]
    if figsize is None:
        figsize = (2.5 * ndim, 2.5 * ndim)

    contour_styles = ["black", "orange", "blue", "purple", "green", "brown"]
    filled_styles = ["blue_cmap", "orange_cmap"]
    colormap_styles = ["gnuplot2"]

    # =========================================================================
    # COLORMAP STYLE (gnuplot2) - density gradient with white at lowest
    # =========================================================================
    if style_corner in colormap_styles:

        corner_kwargs = {
            "labels": lista_parametri,
            "quantiles": quantiles,
            "show_titles": show_titles,
            "title_fmt": title_fmt,
            "title_kwargs": {"fontsize": 11},
            "label_kwargs": {"fontsize": 12},
            "labelpad": 0.4,
            "use_math_text": True,
            "plot_contours": False,
            "plot_datapoints": False,
            "plot_density": False,
            "fill_contours": False,
            "no_fill_contours": True,
            "hist_kwargs": {"color": "black", "linewidth": 1.2, "histtype": "step"},
        }

        with plt.rc_context({
            "font.family": "serif",
            "font.size": 10,
            "axes.linewidth": 0.8,
        }):
            figure_output = corner.corner(arr1, **corner_kwargs)
            figure_output.set_size_inches(figsize)

        axes = np.array(figure_output.axes).reshape(ndim, ndim)

        # Create custom colormap with white at lowest values
        base_cmap = plt.colormaps[style_corner]
        cmap_colors = base_cmap(np.linspace(0, 1, 256))
        cmap_colors[0] = [1, 1, 1, 1]  # White for lowest values
        custom_cmap = mcolors.ListedColormap(cmap_colors)

        for i in range(ndim):
            for j in range(i):
                ax = axes[i, j]

                x_data = arr1[:, j]
                y_data = arr1[:, i]

                x_min, x_max = ax.get_xlim()
                y_min, y_max = ax.get_ylim()

                H, xedges, yedges = np.histogram2d(
                    x_data, y_data,
                    bins=bins,
                    range=[[x_min, x_max], [y_min, y_max]]
                )

                if smooth > 0:
                    H = gaussian_filter(H, sigma=smooth)

                H = H / H.max()

                X, Y = np.meshgrid(
                    (xedges[:-1] + xedges[1:]) / 2,
                    (yedges[:-1] + yedges[1:]) / 2
                )

                ax.contourf(X, Y, H.T, levels=levels, cmap=custom_cmap)
                ax.set_xlim(x_min, x_max)
                ax.set_ylim(y_min, y_max)

        if truth_values is not None:
            corner.overplot_lines(figure_output, truth_values, color="red",
                                  linestyle="--", linewidth=1.5)
            corner.overplot_points(figure_output, [truth_values],
                                   marker="s", color="red", ms=6)

    # =========================================================================
    # FILLED STYLES (blue_cmap, orange_cmap) - filled sigma contours, no datapoints
    # =========================================================================
    elif style_corner in filled_styles:

        base_color = style_corner.replace("_cmap", "")

        corner_kwargs = {
            "labels": lista_parametri,
            "quantiles": quantiles,
            "show_titles": show_titles,
            "title_fmt": title_fmt,
            "title_kwargs": {"fontsize": 11},
            "label_kwargs": {"fontsize": 12},
            "labelpad": 0.15,
            "use_math_text": True,
            "smooth": max(smooth, 1.0),
            "levels": (1 - np.exp(-0.5 * np.array([1, 1.5, 2]) ** 2)),
            "fill_contours": True,
            "plot_contours": True,
            "plot_datapoints": False,
            "plot_density": False,
            "color": base_color,
            "hist_kwargs": {
                "color": base_color,
                "linewidth": 1.5,
                "histtype": "stepfilled",
                "alpha": 0.4,
            },
        }

        with plt.rc_context({
            "font.family": "serif",
            "font.size": 10,
            "axes.linewidth": 0.8,
        }):
            figure_output = corner.corner(arr1, **corner_kwargs)
            figure_output.set_size_inches(figsize)

        if truth_values is not None:
            corner.overplot_lines(figure_output, truth_values, color="red",
                                  linestyle="--", linewidth=1.5)
            corner.overplot_points(figure_output, [truth_values],
                                   marker="s", color="red", ms=6)

    # =========================================================================
    # CONTOUR STYLES (black, orange, blue, purple, green, brown) - lines + datapoints
    # =========================================================================
    elif style_corner in contour_styles:

        corner_kwargs = {
            "labels": lista_parametri,
            "quantiles": quantiles,
            "show_titles": show_titles,
            "title_fmt": title_fmt,
            "title_kwargs": {"fontsize": 11},
            "label_kwargs": {"fontsize": 12},
            "labelpad": 0.15,
            "use_math_text": True,
            "smooth": max(smooth, 1.0),
            "levels": (1 - np.exp(-0.5 * np.array([1, 1.5, 2]) ** 2)),
            "fill_contours": False,
            "plot_contours": True,
            "plot_datapoints": True,
            "plot_density": False,
            "color": style_corner,
            "hist_kwargs": {"color": style_corner, "linewidth": 1.5, "histtype": "step"},
            "data_kwargs": {"alpha": 0.15, "ms": 1.0, "color": style_corner},
        }

        with plt.rc_context({
            "font.family": "serif",
            "font.size": 10,
            "axes.linewidth": 0.8,
        }):
            figure_output = corner.corner(arr1, **corner_kwargs)
            figure_output.set_size_inches(figsize)

        if truth_values is not None:
            corner.overplot_lines(figure_output, truth_values, color="red",
                                  linestyle="--", linewidth=1.5)
            corner.overplot_points(figure_output, [truth_values],
                                   marker="s", color="red", ms=6)

    else:
        available = contour_styles + filled_styles + colormap_styles
        raise ValueError(f"Unknown style: {style_corner}. "
                         f"Available styles: {available}")

    figure_output.subplots_adjust(
        left=0.10, bottom=0.10, right=0.95, top=0.95,
        wspace=0.05, hspace=0.05
    )

    return figure_output

# noinspection PyUnresolvedReferences
################################################
def main():
    """
    Generate corner plot from MCMC retrieval results.

    Command line usage:
        python plot_pmcmcg.py <folder_retrieval> <ext> <target> <path_default>

    Args:
        folder_retrieval: Path to retrieval results folder
        ext: File extension for output
        target: Target name
        path_default: Default path for GUIBRUSHR modules
    """
    # Setup paths from command line arguments
    path_default = sys.argv[4]
    sys.path.append(path_default)
    os.chdir(path_default)

    from GUIBRUSHR.General_Constants.FunctionsAndConstants.general_functions import get_csv_value
    from GUIBRUSHR.General_Constants.Classes.ValueErrorTP import ValueErrorTP

    try:
        folder_retrieval = sys.argv[1]
        ext = sys.argv[2]
        # target = sys.argv[3]
        # in the future this part must be changed eliminating the test part
        #
        df_general_info = pd.read_csv(str(Path(folder_retrieval, "df_general_info.csv")))
        target_radius = float(
            get_csv_value(df_general_info, "target_radius")
        )
        target_mass = float(
            get_csv_value(df_general_info, "target_mass")
        )
        # target_gravity = float(
        #     get_csv_value(df_general_info, "target_gravity")
        # )
        target_t_eq = float(
            get_csv_value(df_general_info, "target_t_eq")
        )
        # target_stellar_radius = float(
        #     get_csv_value(df_general_info, "target_stellar_radius")
        # )
        # target_stellar_mass = float(
        #     get_csv_value(df_general_info, "target_stellar_mass")
        # )
        # target_p0 = float(get_csv_value(df_general_info, "target_p0"))
        # target_hjd0 = float(
        #     get_csv_value(df_general_info, "target_hjd0")
        # )
        # target_period = float(
        #     get_csv_value(df_general_info, "target_period")
        # )
        # target_vsys = float(
        #     get_csv_value(df_general_info, "target_vsys")
        # )
        # target_limph = float(
        #     get_csv_value(df_general_info, "target_limph")
        # )
        target_kp = float(get_csv_value(df_general_info, "target_kp"))

        chemistry = get_csv_value(df_general_info, "chemistry")

        target_ecc = get_csv_value(df_general_info, "target_ecc")
        if target_ecc is not None:
            target_ecc = float(target_ecc)

        target_opi = get_csv_value(df_general_info, "target_opi")
        if target_opi is not None:
            target_opi = float(target_opi)
            if target_opi < 0:
                target_opi += 2 * np.pi
        ################################################
        with open(str(Path(folder_retrieval, "output_data" + ext + ".pkl")), "rb") as fo:
            output_data = pickle.load(fo)
        arr1 = output_data["arr1"]
        lista_par = output_data["lista_par"]
        # Skip third and fourth parameters (commented out in original)
        lista_parametri = output_data["lista_parametri"]
        # Skip sixth and seventh parameters (commented out in original)
        best_fit_parameters = output_data["best_fit_parameters"]
        filename = output_data["filename"]
        value_fix = output_data["value_fix"]
        lista_par_fix = output_data["lista_par_fix"]
        error_list = output_data["error_list"]
        # Skip thirteenth parameter (commented out in original)
        kind_corner = output_data["kind_corner"]
        style_corner = output_data["style_corner"]
        mode_LH = output_data["mode_LH"]
        #
        ndim = len(lista_parametri)
        values_db, values_median, index, T0, et = db_value_corner_plot(
            lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix,
            target_kp, target_ecc, target_opi, target_t_eq
        )
        T0 = ValueErrorTP(T0, et)
        ################################################
        # EXTRACT MOLECULE DISTRIBUTION
        array_molecules = None
        names_molecules = None
        names_molecules_corner = None
        if chemistry == "Free Chemistry":
            idx_first_molec = next((i for i, s in enumerate(lista_parametri) if 'vmr' in s.lower()), None)
            if idx_first_molec is not None:
                array_molecules = arr1[:, idx_first_molec:]
                names_molecules = lista_par[idx_first_molec:]
                names_molecules_corner = lista_parametri[idx_first_molec:]
        if kind_corner == "corner":
            truth_values = np.median(arr1, axis=0)
            figure_output = plot_corner(arr1, lista_parametri, style_corner=style_corner, truth_values=truth_values)
            axes = np.array(figure_output.axes).reshape((ndim, ndim))

            # Stile delle linee
            db_line_style = {"color": "dodgerblue", "linestyle": "-", "linewidth": 1.5, "alpha": 0.8}
            median_line_style = {"color": "red", "linestyle": "--", "linewidth": 1.5, "alpha": 0.8}
            map_line_style = {"color": "purple", "linestyle": "--", "linewidth": 1.5, "alpha": 0.8}

            # Linee blu (values_db)
            c = -1
            for xi in range(ndim):
                if xi in index:
                    c += 1
                    for yi in range(ndim - index[c]):
                        ax = axes[yi + index[c], xi]
                        ax.axvline(values_db[c], **db_line_style)

            c = -1
            for yi in range(ndim):
                if yi in index:
                    c += 1
                    for xi in range(yi):
                        if xi != yi:
                            ax = axes[yi, xi]
                            ax.axhline(values_db[c], **db_line_style)

            # Red lines (medians) - only if mode_LH != "Medians"
            if mode_LH != "Median":
                for i in range(ndim):
                    ax = axes[i, i]
                    ax.axvline(best_fit_parameters[i], **map_line_style)

                for yi in range(ndim):
                    for xi in range(yi):
                        ax = axes[yi, xi]
                        ax.axvline(best_fit_parameters[xi], **map_line_style)
                        ax.axhline(best_fit_parameters[yi], **map_line_style)

            # =========================================================================
            # Legend at the top right of the figure
            # =========================================================================
            fig_width, fig_height = figure_output.get_size_inches()
            fig_size = min(fig_width, fig_height)

            # Adaptive font size: scales with the figure, but with limits
            # Base: 1.2 points per inch, with min=7 and max=12
            legend_fontsize = np.clip(fig_size * 1.2, 7, 12)

            # Length of lines in the legend (scales with the figure)
            legend_handlelength = np.clip(fig_size * 0.25, 1.5, 3.0)

            # Padding and spacing (scales with the figure)
            legend_borderpad = np.clip(fig_size * 0.08, 0.3, 0.8)
            legend_handletextpad = np.clip(fig_size * 0.08, 0.3, 0.8)
            legend_labelspacing = np.clip(fig_size * 0.06, 0.2, 0.5)

            # Linewidth for the lines in the legend
            legend_linewidth = np.clip(fig_size * 0.15, 1.0, 2.0)

            # Create dummy lines for the legend
            legend_elements = [
                Line2D([0], [0], **db_line_style, label="Database values"),
                Line2D([0], [0], **median_line_style, label="Median values")
            ]

            # Add the red line to the legend only if mode_LH != "Medians"
            if mode_LH != "Median":
                legend_elements.append(
                    Line2D([0], [0], **map_line_style, label="Likelihood driven values"),
                )

            # Position the legend
            legend = figure_output.legend(
                handles=legend_elements,
                loc="upper right",
                bbox_to_anchor=(0.98, 0.98),
                frameon=True,
                framealpha=0.9,
                edgecolor="gray",
                fontsize=legend_fontsize,
                fancybox=True,
                borderpad=legend_borderpad,
                handlelength=legend_handlelength,
                handletextpad=legend_handletextpad,
                labelspacing=legend_labelspacing,
            )

            # =========================================================================
            # Verify that the legend does not exceed 2/5 of the figure
            # =========================================================================
            figure_output.canvas.draw()  # Necessary to calculate the legend dimensions

            # Get the dimensions of the legend in inches
            bbox = legend.get_window_extent()
            bbox_inches = bbox.transformed(figure_output.dpi_scale_trans.inverted())
            legend_width = bbox_inches.width
            legend_height = bbox_inches.height

            # Limits: 2/5 of the figure
            max_width = fig_width * 0.4
            max_height = fig_height * 0.4

            # If the legend is too large, reduce it
            if legend_width > max_width or legend_height > max_height:
                scale_factor = min(max_width / legend_width, max_height / legend_height)
                new_fontsize = legend_fontsize * scale_factor * 0.95  # 0.95 for safety margin
                new_fontsize = max(new_fontsize, 6)  # Absolute minimum

                # Remove the old legend and recreate it
                legend.remove()

                legend_elements = [
                    Line2D([0], [0], color="black", linestyle="--",
                           linewidth=legend_linewidth * scale_factor,
                           label="16th, 50th, 84th percentiles"),
                    Line2D([0], [0], color=db_line_style["color"], linestyle=db_line_style["linestyle"],
                           linewidth=legend_linewidth * scale_factor, alpha=db_line_style["alpha"],
                           label="Database values"),
                ]

                if mode_LH != "Median":
                    legend_elements.append(
                        Line2D([0], [0], color=median_line_style["color"],
                               linestyle=median_line_style["linestyle"],
                               linewidth=legend_linewidth * scale_factor,
                               alpha=median_line_style["alpha"],
                               label="Median values")
                    )

                figure_output.legend(
                    handles=legend_elements,
                    loc="upper right",
                    bbox_to_anchor=(0.98, 0.98),
                    frameon=True,
                    framealpha=0.9,
                    edgecolor="gray",
                    fontsize=new_fontsize,
                    fancybox=True,
                    borderpad=legend_borderpad * scale_factor,
                    handlelength=legend_handlelength * scale_factor,
                    handletextpad=legend_handletextpad * scale_factor,
                    labelspacing=legend_labelspacing * scale_factor,
                )
        else:  # pygtc
            # Create the triangle plot using pygtc.
            # The 'truths' parameter will draw vertical/horizontal lines at the median values.
            truth_labels = [(lista_parametri[i] + " = \n" + str(round(best_fit_parameters[i], 5)) + r" $\pm$ " + str(round(error_list[i], 5))) for i in range(ndim)]
            try:
                figure_output = pygtc.plotGTC(
                    arr1,
                    paramNames=lista_parametri,
                    truths=best_fit_parameters,  # draws red lines at the median values
                    truthColors="red",
                    truthLineStyles="-",
                    legendMarker="All",
                    smoothingKernel=0,
                    colorsOrder=["purples"],
                    figureSize=ndim*2,
                    customLabelFont={'family':'DejaVu Sans', 'size':9},
                    customTickFont={'family':'DejaVu Sans', 'size':6},
                    customLegendFont={'family':'DejaVu Sans', 'size':9},
                    nContourLevels=3
                )
            except Exception as e:
                print("3 Countour not possible: " + str(e))
                figure_output = pygtc.plotGTC(
                    arr1,
                    paramNames=lista_parametri,
                    truths=best_fit_parameters,  # draws red lines at the median values
                    truthColors="red",
                    truthLineStyles="-",
                    legendMarker="All",
                    smoothingKernel=0,
                    colorsOrder=["purples"],
                    figureSize=ndim * 2,
                    customLabelFont={'family': 'DejaVu Sans', 'size': 9},
                    customTickFont={'family': 'DejaVu Sans', 'size': 6},
                    customLegendFont={'family': 'DejaVu Sans', 'size': 9},
                )
            axes = figure_output.axes
            # Loop through each parameter to set the title on the corresponding diagonal axis
            from_here = len(axes) - ndim
            i = 0
            for counter, ax in enumerate(axes):
                if counter >= from_here:
                    ax.set_title(truth_labels[i], fontsize=8)
                    i += 1
        #
        os.system("mkdir -p " + str(Path(folder_retrieval, "pmcmcg")))
        filepdf = str(Path(folder_retrieval, "pmcmcg", "plot" + filename + ext + ".pdf"))
        filepng = str(Path(folder_retrieval, "pmcmcg", "plot" + filename + ext + ".png"))
        filepng_temp = str(Path(folder_retrieval, filename + ext + "pmcmcg.png"))
        plt.tight_layout()
        plt.savefig(fname=filepdf, bbox_inches="tight", pad_inches=0.1)
        plt.savefig(fname=filepng, bbox_inches="tight", pad_inches=0.1)
        plt.savefig(fname=filepng_temp, bbox_inches="tight", pad_inches=0.1)

        # Save plot data to pkl for later reconstruction
        corner_pkl_data = {
            "arr1": arr1,
            "lista_par": lista_par,
            "lista_parametri": lista_parametri,
            "best_fit_parameters": best_fit_parameters,
            "filename": filename,
            "value_fix": value_fix,
            "lista_par_fix": lista_par_fix,
            "error_list": error_list,
            "kind_corner": kind_corner,
            "style_corner": style_corner,
            "mode_LH": mode_LH,
            "values_db": values_db,
            "index": index,
            "target_kp": target_kp,
            "target_ecc": target_ecc,
            "target_opi": target_opi,
            "target_t_eq": target_t_eq,
            "target_radius": target_radius,
            "target_mass": target_mass,
            "chemistry": chemistry,
            "array_molecules": array_molecules,
            "names_molecules": names_molecules,
            "names_molecules_corner": names_molecules_corner,
        }
        with open(str(Path(folder_retrieval, "pmcmcg", "plot" + filename + ext + ".pkl")), "wb") as _f:
            pickle.dump(corner_pkl_data, _f)
        with open(str(Path(folder_retrieval, filename + ext + "pmcmcg.pkl")), "wb") as _f:
            pickle.dump(corner_pkl_data, _f)

        # plt.savefig(fname=filepdf, bbox_inches='tight', pad_inches=0.1)
        figure_output.gca().annotate(
            filepdf,
            xy=(1.6, 1.0),
            xycoords="figure fraction",
            ha="right",
            va="top",
            color="black",
            fontsize=15,
        )
        figure_output.gca().annotate(
            filepng,
            xy=(1.6, 1.0),
            xycoords="figure fraction",
            ha="right",
            va="top",
            color="black",
            fontsize=15,
        )
        figure_output.gca().annotate(
            filepng_temp,
            xy=(1.6, 1.0),
            xycoords="figure fraction",
            ha="right",
            va="top",
            color="black",
            fontsize=15,
        )
        figure_output.clear()
        plt.close(figure_output)
        #
        H2 = find_param_arr("H2", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        He = find_param_arr("He", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        ################################################
        kappa_IR = find_param_arr("kappa_IR", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        gamma_g = find_param_arr("gamma_g", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        T_int = find_param_arr("T_int", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        rp = find_param_arr("rp", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix, target_radius)
        #
        T_low = find_param_arr("T_low", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        T_high = find_param_arr("T_high", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        P_low = find_param_arr("P_low", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        P_high = find_param_arr("P_high", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        # k0 = find_param_arr("k0", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        # #
        # gamma = find_param_arr("gamma", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        p1 = find_param_arr("p1", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        p2 = find_param_arr("p2", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        p3 = find_param_arr("p3", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        alpha1 = find_param_arr("alpha1", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        alpha2 = find_param_arr("alpha2", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        T0_node = find_param_arr("T0_node", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        T1_node = find_param_arr("T1_node", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        T2_node = find_param_arr("T2_node", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        T3_node = find_param_arr("T3_node", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        P1_node = find_param_arr("P1_node", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)
        #
        P2_node = find_param_arr("P2_node", lista_par, lista_par_fix, best_fit_parameters, error_list, value_fix)

        temperature_pressure_dictionary = {
            "T0": T0,
            "kappa_IR": kappa_IR,
            "gamma_g": gamma_g,
            "T_int": T_int,
            "rp": rp,
            "target_mass": target_mass,
            "T_low": T_low,
            "T_high": T_high,
            "P_low": P_low,
            "P_high": P_high,
            "p1": p1,
            "p2": p2,
            "p3": p3,
            "alpha1": alpha1,
            "alpha2": alpha2,
            "T0_node": T0_node,
            "T1_node": T1_node,
            "T2_node": T2_node,
            "T3_node": T3_node,
            "P1_node": P1_node,
            "P2_node": P2_node
        }
        c_o_ratio_met = {
            "array_molecules": array_molecules,
            "names_molecules": names_molecules,
            "names_molecules_corner": names_molecules_corner,
            "H2": H2.value,
            "He": He.value,
        }
        with open(str(Path(folder_retrieval, "temperature_pression.pkl")), "wb") as fo:
            pickle.dump(temperature_pressure_dictionary, fo)
        with open(str(Path(folder_retrieval, "c_o_ratio_met.pkl")), "wb") as fo:
            pickle.dump(c_o_ratio_met, fo)
    except Exception as e:
        print("Generic error: " + str(e))
        print(traceback.format_exc())


if __name__ == '__main__':
    main()
