Biopesticide-AI / bioai /paths.py
flvcko's picture
Biopesticide-AI: AMD Hackathon Unicorn Track submission
914512c
Raw
History Blame Contribute Delete
2.36 kB
"""
Centralized path resolution for bioai.
All runtime paths are derived from the project root, which is the directory
containing the ``bioai/`` package. This makes the codebase portable across
machines (no hardcoded ``/home/z/my-project`` paths).
Resolution order:
1. Walk up from this file (``bioai/paths.py``) until we find a directory
that contains a ``bioai`` subdirectory. That's the project root.
2. If that fails (e.g., we're inside a frozen binary), fall back to the
current working directory.
Override the project root by setting the ``BIOAI_PROJECT_ROOT`` env var
(useful for Docker, where WORKDIR=/app is the project root).
"""
from __future__ import annotations
import os
from pathlib import Path
def _find_project_root() -> Path:
# Allow explicit override
env = os.environ.get("BIOAI_PROJECT_ROOT")
if env:
p = Path(env).expanduser().resolve()
if p.is_dir():
return p
# Walk up from this file until we find a directory containing bioai/
here = Path(__file__).resolve().parent # .../bioai/
for candidate in [here, *here.parents]:
if (candidate / "bioai").is_dir():
return candidate
# Last resort: current working directory
return Path.cwd()
PROJECT_ROOT: Path = _find_project_root()
# Standard subdirectories
DATA_DIR: Path = PROJECT_ROOT / "data"
SYNTHETIC_DIR: Path = DATA_DIR / "synthetic"
EXTERNAL_DIR: Path = DATA_DIR / "external"
PROCESSED_DIR: Path = DATA_DIR / "processed"
CHECKPOINTS_DIR: Path = PROJECT_ROOT / "checkpoints"
CACHE_DIR: Path = PROJECT_ROOT / ".fireworks_cache"
# Standard file paths
DEFAULT_PEST_FASTA: Path = SYNTHETIC_DIR / "pest_transcripts.fasta"
DEFAULT_SAFETY_FASTA: Path = SYNTHETIC_DIR / "safety_transcripts.fasta"
DEFAULT_TRAINING_CSV: Path = PROCESSED_DIR / "training_data.csv"
SIRNA_CHECKPOINT: Path = CHECKPOINTS_DIR / "sirna_best.pt"
VAE_CHECKPOINT: Path = CHECKPOINTS_DIR / "vae_best.pt"
PINN_CHECKPOINT: Path = CHECKPOINTS_DIR / "pinn_best.pt"
def ensure_dirs() -> None:
"""Create the standard subdirectories if they don't exist.
Called at module import so any subsequent path is safe to write to.
"""
for d in (DATA_DIR, SYNTHETIC_DIR, EXTERNAL_DIR, PROCESSED_DIR, CHECKPOINTS_DIR, CACHE_DIR):
d.mkdir(parents=True, exist_ok=True)
# Run once on import
ensure_dirs()