Source code for GUIBRUSHR.core.config.paths

"""
Path configuration module for GUIBRUSHR.

Provides a focused ``PathConfig`` class that resolves all filesystem paths
needed by the application: the project root, the petitRADTRANS data
directory, the list of user-defined paths (from ``configuration.csv``), and
the directory that contains the YAML configuration files.
"""

import os
import warnings
from pathlib import Path
from typing import List, Optional

from pandas import read_csv


def _load_configuration(
    path_default: Path,
    config_csv: Optional[str] = None,
) -> tuple[Path, List[str]]:
    """Load configuration paths from a CSV file.

    Parameters
    ----------
    path_default : Path
        Project root directory.
    config_csv : str, optional
        Absolute path to the configuration CSV file.  When *None* (default)
        the standard location inside the package is used:
        ``<path_default>/GUIBRUSHR/Files/Configuration_Path/configuration.csv``.

    Returns
    -------
    tuple[Path, List[str]]
        A 2-tuple of:

        - **path_petitradtrans** – :class:`~pathlib.Path` to the
          petitRADTRANS opacity data directory (first entry in the CSV).
        - **paths** – list of all path strings read from the CSV ``Path``
          column.

    Raises
    ------
    RuntimeError
        If the CSV file cannot be read or is malformed.
    """
    if os.environ.get('SPHINX_BUILD'):
        return Path('/dummy/prt/path'), ['/dummy/path1', '/dummy/path2']

    if config_csv is None:
        config_csv = str(
            Path(path_default, "GUIBRUSHR", "Files",
                 "Configuration_Path", "configuration.csv")
        )

    try:
        df = read_csv(config_csv)
        paths = df["Path"]
        if not Path(str(paths[0])).exists():
            warnings.warn(
                f"PRT path does not exist: {paths[0]}. "
                "Please check the configuration.",
                RuntimeWarning,
            )
            exit()
        if not Path(str(paths[1])).exists():
            warnings.warn(
                f"Target path does not exist: {paths[1]}. "
                "Please check the configuration.",
                RuntimeWarning,
            )
            exit()
        return Path(str(df["Path"][0])), df["Path"].tolist()
    except Exception as e:
        raise RuntimeError(f"Failed to load configuration paths: {str(e)}")


[docs] class PathConfig: """Filesystem path configuration for GUIBRUSHR. Resolves and exposes all path-related configuration used throughout the application. By default the project root is determined relative to this source file (four directory levels up), matching the layout used by :class:`~GUIBRUSHR.General_Constants.FunctionsAndConstants.Constant_Variables.ConstantVariables`. Parameters ---------- config_csv : str, optional Override the path to ``configuration.csv``. Useful for testing or when running the application from a non-standard location. Attributes ---------- path_default : Path Absolute path to the project root directory. path_petitradtrans : Path Absolute path to the petitRADTRANS opacity data directory. paths : List[str] All path strings read from the ``Path`` column of ``configuration.csv``. configuration_yaml_path : str Absolute path (as a string) to the directory containing the YAML configuration files. """
[docs] def __init__(self, config_csv: Optional[str] = None) -> None: # Project root: 4 levels up from this file # paths.py -> config -> core -> GUIBRUSHR -> project root self.path_default: Path = ( Path(__file__).parent.parent.parent.parent.resolve() ) self.path_petitradtrans, self.paths = _load_configuration( self.path_default, config_csv ) self.configuration_yaml_path: str = str( Path(self.path_default, "GUIBRUSHR", "Files", "Configuration_Yaml") )