Commit 091aa6eb authored by Francesco Amadori's avatar Francesco Amadori
Browse files

Project Update

parent 7ad6b390
Loading
Loading
Loading
Loading
+390 −0
Original line number Diff line number Diff line
import os

import yaml
from numpy import array
from os import environ
from pandas import read_csv, DataFrame
from pathlib import Path


def create_path_night(pathfolder, target, rad_mode, instrument):
    """
    Create a standardized path for accessing instrument data for a given target and night.

    Parameters
    ----------
    pathfolder : str or Path
        Base path to the data folder.
    target : str
        Name of the target object.
    rad_mode : str
        Radiation mode (e.g., "Transmission", "Emission").
    instrument : str
        Name of the instrument (e.g., "GIANO_B").

    Returns
    -------
    str
        Full path string to the instrument data directory.
    """
    return str(Path(pathfolder, target, "HR_Instruments", rad_mode, instrument))


def get_target_list(path_targets_folder):
    """
    Retrieve a list of target directories from the specified path.

    Parameters
    ----------
    path_targets_folder : str or Path
        Path to the folder containing target directories.

    Returns
    -------
    ndarray
        Array of target names. Returns ["None"] if no targets are found.
    """
    target_list = [d.name for d in Path(path_targets_folder).iterdir() if d.is_dir()]
    target_list = target_list if len(target_list) > 0 else ["None"]
    return array(target_list)


def get_target_info(path_targets_folder, target):
    """
    Load target information from the info.yaml file.

    Parameters
    ----------
    path_targets_folder : str or Path
        Path to the folder containing target directories.
    target : str
        Name of the target. If "None", returns a list of None values.

    Returns
    -------
    tuple
        A tuple containing target parameters in the following order:
        (name, radius_jup, mass_jup, gravity_cm_s2, t_eq_K, stellar_radius_sun,
        stellar_mass_sun, p0_log10_bar, hjd0_days, period_days, v_system_km_s,
        Limit_Phase, kp_km_s, ecc, periastron_argument, stellar_teff_K, ra, dec,
        a_Rs_ratio, projected_obliquity_deg, inclination_deg, v_sini_km_s).
        Returns a list of 22 None values if target is "None".
    """
    if target != "None":
        with open(str(Path(path_targets_folder, target, "info.yaml")), 'r') as f:
            yaml_file = yaml.safe_load(f)  # Use safe_load to avoid executing arbitrary code in the YAML
        return (
            yaml_file["name"],
            yaml_file["radius_jup"],
            yaml_file["mass_jup"],
            yaml_file["gravity_cm_s2"],
            yaml_file["t_eq_K"],
            yaml_file["stellar_radius_sun"],
            yaml_file["stellar_mass_sun"],
            yaml_file["p0_log10_bar"],
            yaml_file["hjd0_days"],
            yaml_file["period_days"],
            yaml_file["v_system_km_s"],
            yaml_file["Limit_Phase"],
            yaml_file["kp_km_s"],
            yaml_file["ecc"],
            yaml_file["periastron_argument"],
            yaml_file["stellar_teff_K"],
            yaml_file["ra"] if "ra" in yaml_file.keys() else "",
            yaml_file["dec"] if "dec" in yaml_file.keys() else "",
            yaml_file.get("a_Rs_ratio", ""),
            yaml_file.get("projected_obliquity_deg", ""),
            yaml_file.get("inclination_deg", ""),
            yaml_file.get("v_sini_km_s", ""),
        )
    else:
        return [None for _ in range(22)]


def get_target_nights(path_targets, target, rad_mode, instrument="GIANO_B", simulated=0):
    """
    Retrieve a comma-separated list of observation nights for a given target.

    Parameters
    ----------
    path_targets : str or Path
        Base path to the targets folder.
    target : str
        Name of the target object.
    rad_mode : str
        Radiation mode (e.g., "Transmission", "Emission").
    instrument : str, optional
        Name of the instrument. Default is "GIANO_B".
    simulated : int, optional
        Flag to filter simulated or real data. 0 for real data, 1 for simulated data. Default is 0.

    Returns
    -------
    str
        Comma-separated string of night directory names. Returns empty string if no nights are found.
    """
    path_instrument = create_path_night(path_targets, target, rad_mode, instrument)
    night_result = [d.name for d in Path(path_instrument).iterdir() if d.is_dir()]
    nights = ""
    if night_result:
        for elem in sorted(night_result):
            if (("sim" not in elem and not simulated) or ("sim" in elem and simulated)) and "A" not in elem:
                nights += elem + ","
        nights = nights[:-1]
    return nights


def insert_target_catalog(
        path_target,
        target_id,
        radius,
        mass,
        gravity,
        t_eq,
        stellar_radius,
        stellar_mass,
        p0,
        hjd0,
        period,
        vsys,
        limph,
        kp,
        ks,
        ecc,
        opi=1.57,
        stellar_teff=0,
        rad_mode="Transmission",
        ra=0,
        dec=0,
        a_Rs_ratio=0,
        projected_obliquity=0,
        inclination=0,
        v_sini=0
):
    """
    Create a new target entry in the catalog with its directory structure and info.yaml file.

    This function creates the necessary directory structure for a new target and writes
    its physical and orbital parameters to an info.yaml file.

    Parameters
    ----------
    path_target : str or Path
        Base path where the target directory will be created.
    target_id : str
        Name identifier for the target.
    radius : float
        Planet radius in Jupiter radii.
    mass : float
        Planet mass in Jupiter masses.
    gravity : float
        Surface gravity in cm/s^2.
    t_eq : float
        Equilibrium temperature in Kelvin.
    stellar_radius : float
        Stellar radius in solar radii.
    stellar_mass : float
        Stellar mass in solar masses.
    p0 : float
        Reference pressure in log10(bar).
    hjd0 : float
        Reference time of transit in HJD (days).
    period : float
        Orbital period in days.
    vsys : float
        System velocity in km/s.
    limph : float
        Phase limit for observations.
    kp : float
        Planet's semi-amplitude velocity in km/s.
    ks : float
        Star's semi-amplitude velocity in km/s.
    ecc : float
        Orbital eccentricity.
    opi : float, optional
        Periastron argument in radians. Default is 1.57 (π/2).
    stellar_teff : float, optional
        Stellar effective temperature in Kelvin. Default is 0.
    rad_mode : str, optional
        Radiation mode. Default is "Transmission".
    ra : float, optional
        Right ascension in degrees. Default is 0.
    dec : float, optional
        Declination in degrees. Default is 0.
    a_Rs_ratio : float, optional
        Stellar radiation ratio. Default is 0.
    projected_obliquity : float, optional
        Projected obliquity in degrees. Default is 0.
    inclination : float, optional
        Inclination in degrees. Default is 0.
    v_sini : float, optional
        Stellar velocity in km/s. Default is 0.

    Returns
    -------
    None
        Creates directories and writes info.yaml file.
    """
    yaml_dict = (
        {
            'name': target_id,
            'radius_jup': float(radius),
            'mass_jup': float(mass),
            'gravity_cm_s2': float(gravity),
            't_eq_K': float(t_eq),
            'stellar_radius_sun': float(stellar_radius),
            'stellar_mass_sun': float(stellar_mass),
            'stellar_teff_K': float(stellar_teff),
            'p0_log10_bar': float(p0),
            'hjd0_days': float(hjd0),
            'period_days': float(period),
            'kp_km_s': float(kp),
            'ks_km_s': float(ks),
            'v_system_km_s': float(vsys),
            'Limit_Phase': float(limph),
            'ecc': float(ecc),
            'periastron_argument': float(opi),
            'ra': float(ra),
            'dec': float(dec),
            'a_Rs_ratio': float(a_Rs_ratio),
            'projected_obliquity_deg': float(projected_obliquity),
            'inclination_deg': float(inclination),
            'v_sini_km_s': float(v_sini)

        }
    )
    os.system("mkdir -p " + str(Path(path_target, target_id, "Models")))
    os.system("mkdir -p " + str(Path(path_target, target_id, "Star_Spectrum")))
    os.system("mkdir -p " + str(Path(path_target, target_id, "Retrievals")))
    os.system("mkdir -p " + str(Path(path_target, target_id, "HR_Instruments", rad_mode)))
    with open(str(Path(path_target, target_id, "info.yaml")), 'w') as f:
        yaml.dump(yaml_dict, f, sort_keys=False)


def update_target_catalog(
    path_target,
    target_id,
    radius,
    mass,
    gravity,
    t_eq,
    stellar_radius,
    stellar_mass,
    p0,
    hjd0,
    period,
    vsys,
    limph,
    kp,
    ecc,
    opi=1.57,
    stellar_teff=0,
    ra=0,
    dec=0,
    a_Rs_ratio=0,
    projected_obliquity=0,
    inclination=0,
    v_sini=0
):
    """
    Update an existing target's info.yaml file with new parameters.

    This function updates the physical and orbital parameters of an existing target
    by overwriting its info.yaml file. Unlike insert_target_catalog, this function
    does not create the directory structure.

    Parameters
    ----------
    path_target : str or Path
        Base path where the target directory exists.
    target_id : str
        Name identifier for the target.
    radius : float
        Planet radius in Jupiter radii.
    mass : float
        Planet mass in Jupiter masses.
    gravity : float
        Surface gravity in cm/s^2.
    t_eq : float
        Equilibrium temperature in Kelvin.
    stellar_radius : float
        Stellar radius in solar radii.
    stellar_mass : float
        Stellar mass in solar masses.
    p0 : float
        Reference pressure in log10(bar).
    hjd0 : float
        Reference time of transit in HJD (days).
    period : float
        Orbital period in days.
    vsys : float
        System velocity in km/s.
    limph : float
        Phase limit for observations.
    kp : float
        Planet's semi-amplitude velocity in km/s.
    ecc : float
        Orbital eccentricity.
    opi : float, optional
        Periastron argument in radians. Default is 1.57 (π/2).
    stellar_teff : float, optional
        Stellar effective temperature in Kelvin. Default is 0.
    ra : float, optional
        Right ascension in degrees. Default is 0.
    dec : float, optional
        Declination in degrees. Default is 0.

    Returns
    -------
    None
        Updates the info.yaml file for the target.
    """
    yaml_dict = (
        {
            'name': target_id,
            'radius_jup': float(radius),
            'mass_jup': float(mass),
            'gravity_cm_s2': float(gravity),
            't_eq_K': float(t_eq),
            'stellar_radius_sun': float(stellar_radius),
            'stellar_mass_sun': float(stellar_mass),
            'stellar_teff_K': float(stellar_teff),
            'p0_log10_bar': float(p0),
            'hjd0_days': float(hjd0),
            'period_days': float(period),
            'kp_km_s': float(kp),
            'v_system_km_s': float(vsys),
            'Limit_Phase': float(limph),
            'ecc': float(ecc),
            'periastron_argument': float(opi),
            'ra': float(ra),
            'dec': float(dec),
            'a_Rs_ratio': float(a_Rs_ratio),
            'projected_obliquity_deg': float(projected_obliquity),
            'inclination_deg': float(inclination),
            'v_sini_km_s': float(v_sini)
        }
    )
    with open(str(Path(path_target, target_id, "info.yaml")), 'w') as f:
        yaml.dump(yaml_dict, f, sort_keys=False)


class DataInterface:
    """
    Interface class for managing data access and user environment.

    This class provides a simple interface to retrieve system-level information
    such as the current username from environment variables.

    Attributes
    ----------
    username : str
        The current system username obtained from the USER environment variable.
    """

    def __init__(self):
        """
        Initialize the DataInterface with the current system username.
        """
        self.username = environ.get("USER")
        
+122 −0
Original line number Diff line number Diff line
import socket
import tkinter as tk
from pathlib import Path
import os

from screeninfo import get_monitors
import tkinter.messagebox as messagebox

from DataReductionGIANOB.Frame_Gofio import Frame_Gofio


os.environ["OMP_NUM_THREADS"] = "1"
os.environ["OPENBLAS_NUM_THREADS"] = "1"
os.environ["MKL_NUM_THREADS"] = "1"  # export MKL_NUM_THREADS=6
os.environ["VECLIB_MAXIMUM_THREADS"] = "1"  # export VECLIB_MAXIMUM_THREADS=4
os.environ["NUMEXPR_NUM_THREADS"] = "1"  # export NUMEXPR_NUM_THREADS=6


class DataReduction:
    """
    Main application class for GIANO-B Data Reduction GUI.

    This class manages the main application window and initializes the GUI
    components for data reduction of GIANO-B spectroscopic observations.

    Attributes
    ----------
    global_start : int
        Flag indicating if the application has fully started (0=not started, 1=started).
    width : int
        Window width in pixels (95% of monitor width).
    height : int
        Window height in pixels (90% of monitor height).
    displace_x : int
        Horizontal displacement of window from screen edge.
    displace_y : int
        Vertical displacement of window from screen edge.
    path_default : Path
        Default path to the application directory.
    dialog : object or None
        Reference to any active dialog window.
    window : tk.Tk
        Main tkinter window object.
    frame_gofio : Frame_Gofio
        Main frame containing the data reduction interface.
    """

    def __init__(self, path_default):
        """
        Initialize the DataReduction application window.

        Parameters
        ----------
        path_default : Path
            Path to the application's default directory containing resources.
        """
        self.global_start = 0
        # Window
        m = get_monitors()
        self.width = int(m[0].width * 0.95)
        self.height = int(m[0].height * 0.9)
        self.displace_x = int(m[0].width * 0.04)
        self.displace_y = int(m[0].height * 0.04)
        self.path_default = path_default
        self.dialog = None
        self.window = tk.Tk()
        # Configure the grid to expand with the window
        self.window.grid_rowconfigure(0, weight=1)
        self.window.grid_columnconfigure(0, weight=1)
        photo = tk.PhotoImage(file=str(Path.joinpath(path_default, "DataReductionGIANOB", "Files", "logo.png")))
        self.window.iconphoto(True, photo)
        self.window.client(socket.gethostname())
        self.window.geometry(str(self.width) + "x" + str(self.height) + "+" + str(self.displace_x) + "+" + str(self.displace_y))
        self.window.title(
            "GIANO-B Data Reduction"
        )
        self.window.resizable(True, True)
        # self.window.option_add('*Dialog.msg.width', 50)
        # Input frame
        self.frame_gofio = Frame_Gofio(self.window, self, path_default, int(0.95*self.width), int(0.95*self.height))
        #
        self.window.rowconfigure(0, weight=1)
        self.window.columnconfigure(0, weight=1)
        self.global_start = 1

    def on_closing(self):
        """
        Handle the window close event with user confirmation.

        Displays a confirmation dialog before closing the application window.
        Only prompts if the application has fully started (global_start == 1).

        Returns
        -------
        None
            Destroys the window if user confirms, otherwise does nothing.
        """
        if self.global_start:
            if messagebox.askokcancel("Quit", "Do you want to quit?"):
                self.window.destroy()


def main():
    """
    Entry point for the GIANO-B Data Reduction application.

    Initializes the DataReduction GUI, sets up the window close protocol,
    and starts the tkinter main event loop.

    Returns
    -------
    None
        Runs until the GUI window is closed.
    """
    path_default = Path(__file__).parent.parent.resolve()
    GUI_obj = DataReduction(path_default)
    GUI_obj.window.protocol("WM_DELETE_WINDOW", GUI_obj.on_closing)
    GUI_obj.window.mainloop()


if __name__ == '__main__':
    main()
+800 KiB

File added.

No diff preview for this file type.

+5.11 MiB

File added.

Preview size limit exceeded, changes collapsed.

+1.46 MiB

File added.

No diff preview for this file type.

Loading