Skip to content

Option to get date from filename (works with diag files) #18

@mefrediani

Description

@mefrediani

My diag files didn't have xtime and there was no way to get the plot date from attributes.

import re

Replace the if block in line 436 with:
logger.debug(f"Plotting time step {i}") times.append( resolve_timestring(uxds, config_d["dataset"]["files"], i) )

And add these functions:

def parse_time_from_filename(filepath: str) -> str:
    """
    Parse a timestamp from filename patterns like:
      diag.2025-06-06_21.00.00.nc
    and return a string in YYYY-MM-DD_HH:MM:SS format.
    """
    basename = os.path.basename(filepath)
    match = re.search(r"(\d{4}-\d{2}-\d{2})_(\d{2}\.\d{2}\.\d{2})", basename)
    if not match:
        raise ValueError(
            f"Could not parse timestamp from filename '{basename}'. "
            "Expected pattern like 'diag.YYYY-MM-DD_HH.MM.SS.nc'."
        )

    date_part, time_part = match.groups()
    timestring = f"{date_part}_{time_part.replace('.', ':')}"
    try:
        datetime.strptime(timestring, "%Y-%m-%d_%H:%M:%S")
    except ValueError as e:
        raise ValueError(
            f"Parsed timestamp '{timestring}' from '{basename}' is invalid."
        ) from e
    return timestring
def resolve_timestring(
    uxds: ux.UxDataset,
    datafiles: list[str],
    time_index: int,
) -> str:
    """
    Resolve plot timestamp from xtime when present, otherwise from input filename.
    time_index == -1 is used for variables without a Time dimension.
    """
    if "xtime" in uxds:
        idx = 0 if time_index == -1 else time_index
        return "".join(uxds["xtime"].isel(Time=idx).values.astype(str))

    if not datafiles:
        raise ValueError("No input files available to derive timestamp")

    if time_index == -1:
        filepath = datafiles[0]
    else:
        n_time = uxds.sizes.get("Time", 0)
        if n_time != len(datafiles):
            raise ValueError(
                "'xtime' is missing and timestamp mapping is ambiguous: "
                f"dataset Time dimension has {n_time} steps, but only "
                f"{len(datafiles)} input file(s). Use one file per timestep "
                "or provide xtime in input data."
            )
        if time_index >= len(datafiles):
            raise ValueError(
                f"Time index {time_index} is out of range for {len(datafiles)} input files"
            )
        filepath = datafiles[time_index]

    timestring = parse_time_from_filename(filepath)
    logger.warning(
        f"'xtime' variable not found in input data; using timestamp parsed from "
        f"filename '{os.path.basename(filepath)}' -> {timestring}"
    )
    return timestring

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions