#!/usr/bin/env python
# -*- coding: utf-8 -*-
from logging import debug, info
from pathlib import Path
import numpy as np
import pandas as pd
from .....utils import path
_filetype_list = (
("fluxstoke", ""),
("fluxstokev", ""),
("phystoke", ""),
("phystoke", "_csr"),
)
[docs]
def fetch(
ref_dir,
ref_file,
input_interval,
target_dir,
tracer=None,
**kwargs,
):
"""Locate legacy LMDZ mass-flux files and link them to the working directory.
Builds monthly period-start dates covering ``input_interval`` at
``tracer.file_freq`` (clamped to the requested bounds), links the
``defstoke.nc`` file (or the ``defstoke_file`` override) once, then
for each period links whichever of ``fluxstoke``, ``fluxstokev``,
``phystoke`` and ``phystoke_csr`` monthly files exist in ``ref_dir``.
For the first file type found in each month, computes 3-hourly
sub-period date pairs assuming 8 physics steps per day
(``nday_step = 8``).
Args:
ref_dir: directory holding the LMDZ mass-flux files.
ref_file: unused (kept for interface consistency; this plugin
derives its own file names).
input_interval: 2-element sequence ``(datei, datef)`` giving the
requested date range.
target_dir: directory where matching files are symlinked.
tracer: the meteo datastream Plugin, used for ``tracer.file_freq``
and the optional ``tracer.defstoke_file`` override.
Returns:
tuple: ``(list_files, list_dates)``, dicts keyed by each month's
start date for which at least one mass-flux file was found.
``list_files`` maps each key to the (repeated) file name of the
first matching file type found that month; ``list_dates`` maps
each key to the list of 3-hourly ``[start, start + 3h]`` date
pairs spanning that month.
"""
info(f"Linking meteo files from {ref_dir} to {target_dir}")
datei, datef = input_interval
ref_datei = pd.Timestamp(year=datei.year, month=datei.month, day=1)
list_period_dates = pd.date_range(ref_datei, datef, freq=tracer.file_freq)
list_period_dates = list_period_dates.to_pydatetime()
if list_period_dates[0] < datei:
list_period_dates[0] = datei
if list_period_dates[-1] < datef:
list_period_dates = np.append(list_period_dates, datef)
# Link defstoke file for legacy LMDZ/acc plugin
source = Path(getattr(tracer, "defstoke_file", "defstoke.nc"))
if not source.is_absolute():
source = Path(ref_dir, source)
if source.is_file():
target = Path(target_dir, source.name)
path.link(source, target)
list_dates = {}
list_files = {}
# Link meteo files
for date in list_period_dates:
ref_date = pd.Timestamp(year=date.year, month=date.month, day=1)
for prefix, suffix in _filetype_list:
if prefix == "defstoke":
source = Path(getattr(tracer, "defstoke_file", "defstoke.nc"))
if not source.is_absolute():
source = Path(ref_dir, source)
else:
filename = f"{prefix}.{date:an%Y.m%m}{suffix}.nc"
source = Path(ref_dir, filename)
if not source.is_file():
continue
# Link file
target = Path(target_dir, source.name)
path.link(source, target)
# Get dates in the file
if date not in list_dates:
# TODO: need to get that from 'nday_step' in LMDZ model plugin
nday_step = 8
n_time = nday_step * ref_date.days_in_month
list_dates[date] = [
[d, d + pd.Timedelta(hours=3)]
for d in pd.date_range(ref_date, periods=n_time, freq="3h")
]
list_files[date] = len(list_dates[date]) * [source.name]
for key, val in list_dates.items():
debug(f"{key}:")
for di, df in val:
debug(f" {di} - {df}")
return list_files, list_dates