Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions configs/TCO95_CORE2_EP.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# OCP-Tool Configuration — Paleo Example (Early Pliocene)
# OpenIFS Coupling Preparation Tool with paleo reconstruction modifications

# Atmosphere grid settings
atmosphere:
resolution_list: [95]
truncation_type: "cubic-octahedral"
experiment_name: "aack" # 4-digit ECMWF experiment code

# Ocean grid settings
ocean:
grid_name: "CORE2"
has_ice_cavities: false
mesh_file: "/work/ab0246/a270092/input/fesom2/CORE2/mesh.nc"

# Basin modifications for runoff
runoff:
manual_basin_removal:
- "caspian-sea"
- "black-sea"

# Paths (relative to auto-detected root_dir, or absolute)
paths:
input:
fesom_mesh: "input/fesom_mesh/"
gaussian_grids_full: "input/gaussian_grids_full/"
gaussian_grids_octahedral_reduced: "input/gaussian_grids_octahedral_reduced/"
gaussian_grids_linear_reduced: "input/gaussian_grids_linear_reduced/"
openifs_default: "input/openifs_input_default/"
runoff_default: "input/runoff_map_default/"
lpj_guess: "input/lpj-guess/"

# Paleo reconstruction settings
paleo:
enabled: true
experiment_id: "EP" # Used in filenames: EP_icemask_v1.0.nc, etc.

# Directory containing paleo reconstruction NetCDF files
reconstruction_dir: "/work/ab0246/a270179/runtime/input/pliomip3/EP/"

# Directory containing modern reference files
modern_reference_dir: "/work/ab0246/a270179/runtime/input/pliomip3/EP/"

# Path to the ICMSH spectral topography reference file
icmsh_input_file: "/work/ab0246/a270179/runtime/input/pliomip3/EP/ICMSHaackINIT_CORE2_new3"

# Path to compiled calnoro binary (set to null to skip SSO computation)
calnoro_binary: null # e.g. "/path/to/calnoro/a.out"

# Reconstruction file name templates ({exp_id} is replaced by experiment_id)
# These are the defaults — override only if your files differ:
# ice_mask_file: "{exp_id}_icemask_v1.0.nc"
# topography_file: "{exp_id}_topo_v1.0.nc"
# lsm_file: "{exp_id}_LSM_v1.0.nc"
# lake_file: "{exp_id}_lake_v1.0.nc"
# soil_file: "{exp_id}_soil_v1.0.nc"
# biome_file: "{exp_id}_mbiome_v1.0.nc"
# modern_topo_file: "Modern_std_topo_v1.0.nc"
# modern_lake_file: "Modern_std_soil_lake_v1.0.nc"

# Processing options
options:
verbose: true
parallel_workers: 4
use_dask: true
2 changes: 2 additions & 0 deletions environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ dependencies:
- pandas
- pyyaml
- python-eccodes
- python-cdo
- scipy
- git
- pip
- jupyterlab
Expand Down
5 changes: 4 additions & 1 deletion ocp_tool/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
- plotting: Visualization
- co2_interpolation: 3D CO2 interpolation
- field_interpolation: 2D field interpolation
- paleo_input: Paleo land surface modifications (ice, lakes, soils, vegetation)
- paleo_topo: Paleo topography modification (anomaly method)
- paleo_subgrid_oro: Subgrid-scale orography via calnoro
"""

__version__ = "2.0.0"
__version__ = "2.1.0"
70 changes: 69 additions & 1 deletion ocp_tool/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from dataclasses import dataclass, field
from pathlib import Path
from typing import List, Optional, Union
from typing import Dict, List, Optional, Union
import yaml


Expand Down Expand Up @@ -54,6 +54,38 @@ class OutputPaths:
plots: Path


@dataclass
class PaleoConfig:
"""Paleo reconstruction configuration."""
enabled: bool
experiment_id: str # e.g. "EP", "LP" — used in filenames
reconstruction_dir: Path # directory containing reconstruction NetCDF files
modern_reference_dir: Path # directory containing modern reference files
icmsh_input_file: Path # path to ICMSHaackINIT_CORE2 (spectral topo)
calnoro_binary: Optional[Path] # path to compiled calnoro binary
# Reconstruction file names (relative to reconstruction_dir)
ice_mask_file: str = "{exp_id}_icemask_v1.0.nc"
topography_file: str = "{exp_id}_topo_v1.0.nc"
lsm_file: str = "{exp_id}_LSM_v1.0.nc"
lake_file: str = "{exp_id}_lake_v1.0.nc"
soil_file: str = "{exp_id}_soil_v1.0.nc"
biome_file: str = "{exp_id}_mbiome_v1.0.nc"
# Modern reference file names (relative to modern_reference_dir)
modern_topo_file: str = "Modern_std_topo_v1.0.nc"
modern_lake_file: str = "Modern_std_soil_lake_v1.0.nc"

def get_reconstruction_file(self, file_attr: str) -> Path:
"""Get full path to a reconstruction file, substituting experiment_id."""
template = getattr(self, file_attr)
filename = template.format(exp_id=self.experiment_id)
return self.reconstruction_dir / filename

def get_modern_file(self, file_attr: str) -> Path:
"""Get full path to a modern reference file."""
filename = getattr(self, file_attr)
return self.modern_reference_dir / filename


@dataclass
class ProcessingOptions:
"""Processing options."""
Expand All @@ -72,6 +104,7 @@ class OCPConfig:
output_paths: OutputPaths
options: ProcessingOptions
root_dir: Path
paleo: Optional[PaleoConfig] = None

@property
def co2_grib_file(self) -> Path:
Expand All @@ -96,6 +129,17 @@ def get_icmgg_output_file(self) -> Path:
def get_icmgg_iniua_file(self) -> Path:
"""Get path to output ICMGG INIUA file."""
return self.output_paths.openifs_modified / f'ICMGG{self.atmosphere.experiment_name}INIUA'

def get_icmsh_input_file(self) -> Path:
"""Get path to input ICMSH file (spectral topography)."""
if self.paleo and self.paleo.icmsh_input_file:
return self.paleo.icmsh_input_file
return self.input_paths.openifs_default / f'ICMSH{self.atmosphere.experiment_name}INIT'

def get_icmsh_output_file(self) -> Path:
"""Get path to output ICMSH file."""
suffix = f'_{self.paleo.experiment_id}' if self.paleo else f'_{self.ocean.grid_name}'
return self.output_paths.openifs_modified / f'ICMSH{self.atmosphere.experiment_name}INIT{suffix}'


def load_config(config_path: Union[str, Path]) -> OCPConfig:
Expand Down Expand Up @@ -186,6 +230,30 @@ def resolve_path(path_str: str) -> Path:
use_dask=raw['options']['use_dask'],
),
root_dir=root_dir,
paleo=_load_paleo_config(raw, resolve_path) if 'paleo' in raw else None,
)


def _load_paleo_config(raw: dict, resolve_path) -> Optional[PaleoConfig]:
"""Parse paleo section from raw YAML config."""
paleo_raw = raw.get('paleo', {})
if not paleo_raw.get('enabled', False):
return None
return PaleoConfig(
enabled=True,
experiment_id=paleo_raw['experiment_id'],
reconstruction_dir=resolve_path(paleo_raw['reconstruction_dir']),
modern_reference_dir=resolve_path(paleo_raw['modern_reference_dir']),
icmsh_input_file=resolve_path(paleo_raw['icmsh_input_file']),
calnoro_binary=resolve_path(paleo_raw['calnoro_binary']) if paleo_raw.get('calnoro_binary') else None,
ice_mask_file=paleo_raw.get('ice_mask_file', '{exp_id}_icemask_v1.0.nc'),
topography_file=paleo_raw.get('topography_file', '{exp_id}_topo_v1.0.nc'),
lsm_file=paleo_raw.get('lsm_file', '{exp_id}_LSM_v1.0.nc'),
lake_file=paleo_raw.get('lake_file', '{exp_id}_lake_v1.0.nc'),
soil_file=paleo_raw.get('soil_file', '{exp_id}_soil_v1.0.nc'),
biome_file=paleo_raw.get('biome_file', '{exp_id}_mbiome_v1.0.nc'),
modern_topo_file=paleo_raw.get('modern_topo_file', 'Modern_std_topo_v1.0.nc'),
modern_lake_file=paleo_raw.get('modern_lake_file', 'Modern_std_soil_lake_v1.0.nc'),
)


Expand Down
Loading
Loading