From 0b01455257393e9b785f6fbed07cb60a87321c65 Mon Sep 17 00:00:00 2001 From: Jared Lewis Date: Sat, 29 Aug 2026 08:11:42 +1000 Subject: [PATCH 1/2] fix: fabricate CMIP7 coverage by repeating the final year The CMIP6 source for a fabricated CMIP7 series stops in 2014, so the series was relabelled onto the requested end date. This moved every real year with it, and each file was relabelled on its own, so a dataset split across several chunks ended up with overlapping files that all finished on the same month. Replaces the relabelling with padding. The real timesteps keep their dates and values, and the final year is tiled forward until the series reaches the requested end. Re-mints the fire and cloud radiative effects CMIP7 baselines, whose fabricated files now start in 1850 rather than 1857. --- .../src/climate_ref_core/cmip6_to_cmip7.py | 92 +- .../src/climate_ref_core/esgf/cmip7.py | 22 +- .../tests/unit/test_cmip6_to_cmip7.py | 136 ++- .../diagnostics/climate_drivers_for_fire.py | 6 +- .../cmip7/catalog.yaml | 58 +- .../cmip7/manifest.json | 18 +- .../cmip7/catalog.yaml | 34 +- .../cmip7/manifest.json | 52 +- .../cmip7/regression/series.json | 1082 ++++++++--------- 9 files changed, 772 insertions(+), 728 deletions(-) diff --git a/packages/climate-ref-core/src/climate_ref_core/cmip6_to_cmip7.py b/packages/climate-ref-core/src/climate_ref_core/cmip6_to_cmip7.py index 9b1775f1b..9ddaedb86 100644 --- a/packages/climate-ref-core/src/climate_ref_core/cmip6_to_cmip7.py +++ b/packages/climate-ref-core/src/climate_ref_core/cmip6_to_cmip7.py @@ -22,17 +22,15 @@ from dataclasses import dataclass from datetime import UTC, datetime, timedelta from importlib import resources -from typing import TYPE_CHECKING, Any +from typing import Any import attrs import cftime import numpy as np import pandas as pd +import xarray as xr from loguru import logger -if TYPE_CHECKING: - import xarray as xr - def suppress_bounds_coordinates(ds: xr.Dataset) -> xr.Dataset: """ @@ -496,15 +494,17 @@ def _month_index(t: Any) -> int: _MONTHS_PER_YEAR = 12 -def shift_time_axis_end(ds: xr.Dataset, end_year: int, end_month: int = 12) -> xr.Dataset: +def repeat_final_year_to(ds: xr.Dataset, end_year: int, end_month: int = 12) -> xr.Dataset: """ - Relabel a monthly time axis so the final timestep lands on ``end_year``-``end_month``. + Extend a monthly series to ``end_year``-``end_month`` by repeating its final year. + + The real timesteps keep their real dates and values. Only the tail is fabricated, by + tiling the last twelve months forward until the series reaches the requested end. This + gives CMIP7 ``historical`` coverage for years the CMIP6 source never ran (e.g. 2015-2021) + without moving the years that did. - The whole ``time`` coordinate (and any ``time_bnds``) is shifted by a constant - whole-month offset, so monthly spacing, calendar, and cftime types are preserved - and only the labels move. This is used to fabricate CMIP7 ``historical`` coverage - that reaches years for which no real data exists (e.g. 2002-2021 for the fire - diagnostic), without altering the underlying data values. + A series shorter than a year repeats whatever it has. A series that already reaches the + requested end is returned unchanged. Only monthly data with a ``cftime`` time axis is supported; datasets without a ``time`` coordinate (fixed-frequency, e.g. ``sftlf``) are returned unchanged. @@ -521,7 +521,7 @@ def shift_time_axis_end(ds: xr.Dataset, end_year: int, end_month: int = 12) -> x Returns ------- xr.Dataset - A shallow copy with the relabelled time axis. + A dataset whose time axis runs to the requested end. """ if not 1 <= end_month <= _MONTHS_PER_YEAR: raise ValueError(f"end_month must be in 1..12, got {end_month}") @@ -533,14 +533,13 @@ def shift_time_axis_end(ds: xr.Dataset, end_year: int, end_month: int = 12) -> x last = time_values[-1] if not isinstance(last, cftime.datetime): raise TypeError( - "shift_time_axis_end requires a cftime time axis; " + "repeat_final_year_to requires a cftime time axis; " f"got {type(last).__name__}. Decode with use_cftime=True." ) - # Whole-month offset that moves the final label onto the requested end. - target_index = end_year * 12 + (end_month - 1) - offset_months = target_index - _month_index(last) - if offset_months == 0: + target_index = end_year * _MONTHS_PER_YEAR + (end_month - 1) + missing = target_index - _month_index(last) + if missing <= 0: return ds calendar = last.calendar @@ -554,31 +553,50 @@ def _days_in_month(year: int, month: int) -> int: last_of_month = first_of_next - timedelta(days=1) # type: ignore[operator] return int(last_of_month.day) # type: ignore[attr-defined] - def _shift(t: cftime.datetime) -> cftime.datetime: - total = _month_index(t) + offset_months - year, month = divmod(total, 12) + def _add_months(t: cftime.datetime, months: int) -> cftime.datetime: + year, month = divmod(_month_index(t) + months, _MONTHS_PER_YEAR) month += 1 - # Clamp the day to the target month/calendar: a non-multiple-of-12 offset - # can land a day-31 (or leap Feb-29) label on a shorter month, which cftime - # would reject. Our monthly data is mid-month so this is normally a no-op. + # Clamp the day to the target month/calendar: a day-31 (or leap Feb-29) label + # can land on a shorter month, which cftime would reject. day = min(t.day, _days_in_month(year, month)) return cftime.datetime(year, month, day, t.hour, t.minute, t.second, t.microsecond, calendar=calendar) - ds = ds.copy(deep=False) - shifted = np.array([_shift(t) for t in time_values]) - new_time = ds["time"].copy(data=shifted) + # Tile the final year, so each fabricated month reuses the same month one or more years back. + period = min(_MONTHS_PER_YEAR, len(time_values)) + positions = [len(time_values) - period + (step % period) for step in range(missing)] + offsets = [ + _month_index(last) + 1 + step - _month_index(time_values[position]) + for step, position in enumerate(positions) + ] + + padding = ds.isel(time=positions) + padded_times = np.array( + [_add_months(time_values[position], offset) for position, offset in zip(positions, offsets)] + ) + new_time = padding["time"].copy(data=padded_times) new_time.encoding = dict(ds["time"].encoding) - ds = ds.assign_coords(time=new_time) + padding = padding.assign_coords(time=new_time) - # Shift the matching time bounds, if present, so the axis stays self-consistent. + # Move the matching time bounds with their timesteps, so the axis stays self-consistent. bounds_name = ds["time"].attrs.get("bounds") if bounds_name and bounds_name in ds: bnds_values = ds[bounds_name].values - shifted_bnds = np.array([[_shift(v) for v in row] for row in bnds_values]) - ds[bounds_name] = ds[bounds_name].copy(data=shifted_bnds) + padded_bnds = np.array( + [ + [_add_months(bound, offset) for bound in bnds_values[position]] + for position, offset in zip(positions, offsets) + ] + ) + padding[bounds_name] = padding[bounds_name].copy(data=padded_bnds) - logger.debug(f"Shifted time axis by {offset_months} months so it ends {end_year:04d}-{end_month:02d}") - return ds + extended = xr.concat([ds, padding], dim="time", data_vars="minimal", coords="minimal") + extended["time"].attrs = dict(ds["time"].attrs) + extended["time"].encoding = dict(ds["time"].encoding) + + logger.debug( + f"Repeated the final year for {missing} months so the series ends {end_year:04d}-{end_month:02d}" + ) + return extended def convert_cmip6_dataset( @@ -604,10 +622,10 @@ def convert_cmip6_dataset( inplace If True, modify the dataset in place; otherwise return a copy extend_historical_to - Opt-in ``(end_year, end_month)``. When set, the ``time`` axis is relabelled - via :func:`shift_time_axis_end` so the series ends on that month, fabricating - CMIP7 coverage for years without real data. Defaults to ``None`` (time axis - untouched), so existing conversions are byte-identical. + Opt-in ``(end_year, end_month)``. When set, the series is padded out to that month + via :func:`repeat_final_year_to`, fabricating CMIP7 coverage for years without real + data. Defaults to ``None`` (time axis untouched), so existing conversions are + byte-identical. Returns ------- @@ -619,7 +637,7 @@ def convert_cmip6_dataset( if extend_historical_to is not None: end_year, end_month = extend_historical_to - ds = shift_time_axis_end(ds, end_year=end_year, end_month=end_month) + ds = repeat_final_year_to(ds, end_year=end_year, end_month=end_month) # Determine the primary variable (skip coordinates/bounds) data_vars = [str(v) for v in ds.data_vars if not str(v).endswith("_bnds") and v not in ds.coords] diff --git a/packages/climate-ref-core/src/climate_ref_core/esgf/cmip7.py b/packages/climate-ref-core/src/climate_ref_core/esgf/cmip7.py index f9c25ccb2..a2c01448f 100644 --- a/packages/climate-ref-core/src/climate_ref_core/esgf/cmip7.py +++ b/packages/climate-ref-core/src/climate_ref_core/esgf/cmip7.py @@ -21,7 +21,7 @@ format_cmip7_time_range, get_dreq_entry, get_frequency_from_table, - shift_time_axis_end, + repeat_final_year_to, suppress_bounds_coordinates, ) from climate_ref_core.data import resolve_cache_dir @@ -51,8 +51,8 @@ def _convert_file_to_cmip7( cmip7_facets CMIP7 facets for the output path extend_historical_to - Opt-in ``(end_year, end_month)`` passed to :func:`convert_cmip6_dataset` - to relabel the time axis so historical coverage reaches that month. + Opt-in ``(end_year, end_month)``. The series is padded out to that month by + repeating its final year, so historical coverage reaches it. Defaults to ``None`` (time axis untouched). Returns @@ -85,12 +85,12 @@ def _convert_file_to_cmip7( time_coder = xr.coders.CFDatetimeCoder(use_cftime=True) with xr.open_dataset(cmip6_path, decode_times=time_coder) as ds: - # When fabricating extended historical coverage, relabel the time axis first - # so both the filename time range and the written data reflect the new dates. + # When fabricating extended historical coverage, pad the series first so both the + # filename time range and the written data reflect the added months. source_ds = ds if extend_historical_to is not None: end_year, end_month = extend_historical_to - source_ds = shift_time_axis_end(ds, end_year=end_year, end_month=end_month) + source_ds = repeat_final_year_to(ds, end_year=end_year, end_month=end_month) frequency = str(cmip7_facets.get("frequency", "mon")) time_range = format_cmip7_time_range(source_ds, frequency) @@ -199,11 +199,11 @@ def __init__( time_span Optional time range filter (start, end) in YYYY-MM format extend_historical_to - Opt-in ``(end_year, end_month)``. When set, each converted CMIP7 file has - its time axis relabelled so historical coverage ends on that month, letting - us fabricate CMIP7 data for years without real CMIP6 source data (e.g. the - fire diagnostic's 2002-2021 window). Defaults to ``None`` (time axis - untouched), so other CMIP7 conversions are unchanged. + Opt-in ``(end_year, end_month)``. When set, a converted CMIP7 file that stops + short has its final year repeated until it ends on that month, letting us + fabricate CMIP7 data for years without real CMIP6 source data (e.g. the fire + diagnostic's 2002-2021 window). Files that already reach it are untouched, as + are all conversions when this defaults to ``None``. """ self.slug = slug self.facets = facets diff --git a/packages/climate-ref-core/tests/unit/test_cmip6_to_cmip7.py b/packages/climate-ref-core/tests/unit/test_cmip6_to_cmip7.py index 222d1f238..bddd2a72f 100644 --- a/packages/climate-ref-core/tests/unit/test_cmip6_to_cmip7.py +++ b/packages/climate-ref-core/tests/unit/test_cmip6_to_cmip7.py @@ -25,7 +25,7 @@ get_frequency_from_table, get_realm, parse_variant_label, - shift_time_axis_end, + repeat_final_year_to, suppress_bounds_coordinates, ) @@ -1047,8 +1047,8 @@ def _monthly_cftime(start_year: int, start_month: int, n: int) -> list[cftime.da return out -class TestShiftTimeAxisEnd: - """Test relabelling a monthly time axis so it ends on a target month.""" +class TestRepeatFinalYearTo: + """Test padding a monthly series out to a target month by repeating its final year.""" def _monthly_dataset(self, start_year: int, n: int) -> xr.Dataset: time = _monthly_cftime(start_year, 1, n) @@ -1066,60 +1066,87 @@ def _monthly_dataset(self, start_year: int, n: int) -> xr.Dataset: ds["time"].attrs["bounds"] = "time_bnds" return ds - def test_shifts_end_to_target(self): + def test_extends_end_to_target(self): """The last timestep lands exactly on the requested year/month.""" - ds = self._monthly_dataset(1850, 12 * 20) # 1850-01 .. 1869-12 - shifted = shift_time_axis_end(ds, end_year=2021, end_month=12) + ds = self._monthly_dataset(1950, 12 * 65) # 1950-01 .. 2014-12 + extended = repeat_final_year_to(ds, end_year=2021, end_month=12) - last = shifted["time"].values[-1] - first = shifted["time"].values[0] + last = extended["time"].values[-1] assert (last.year, last.month) == (2021, 12) - # 20 years of monthly data => starts 2002-01 - assert (first.year, first.month) == (2002, 1) - - def test_preserves_length_and_spacing(self): - """Every month is still present, one step apart, after the shift.""" - n = 12 * 5 - ds = self._monthly_dataset(1990, n) - shifted = shift_time_axis_end(ds, end_year=2021, end_month=12) - - times = shifted["time"].values - assert len(times) == n - # Consecutive months differ by exactly one calendar month. + + def test_keeps_the_real_years_where_they_are(self): + """Padding is additive, so the real timesteps keep their dates and values.""" + n = 12 * 65 + ds = self._monthly_dataset(1950, n) + extended = repeat_final_year_to(ds, end_year=2021, end_month=12) + + first = extended["time"].values[0] + assert (first.year, first.month) == (1950, 1) + np.testing.assert_array_equal(extended["tas"].values[:n], ds["tas"].values) + + def test_pads_with_whole_months_in_sequence(self): + """The added months continue the series, one step apart.""" + ds = self._monthly_dataset(1990, 12 * 5) # 1990-01 .. 1994-12 + extended = repeat_final_year_to(ds, end_year=2000, end_month=12) + + times = extended["time"].values + assert len(times) == 12 * 11 for prev, nxt in itertools.pairwise(times): - expected = prev.year * 12 + prev.month # next month index - assert nxt.year * 12 + (nxt.month - 1) == expected + assert nxt.year * 12 + (nxt.month - 1) == prev.year * 12 + prev.month + + def test_repeats_the_final_year_values(self): + """Each fabricated month reuses the same month from the final real year.""" + n = 12 * 3 + ds = self._monthly_dataset(1990, n) # 1990-01 .. 1992-12 + extended = repeat_final_year_to(ds, end_year=1994, end_month=12) + + final_year = ds["tas"].values[-12:] + np.testing.assert_array_equal(extended["tas"].values[n : n + 12], final_year) + np.testing.assert_array_equal(extended["tas"].values[n + 12 :], final_year) + + def test_repeats_a_short_series(self): + """A series shorter than a year repeats whatever it has.""" + ds = self._monthly_dataset(1990, 3) # 1990-01 .. 1990-03 + extended = repeat_final_year_to(ds, end_year=1990, end_month=9) + + assert len(extended["time"]) == 9 + np.testing.assert_array_equal(extended["tas"].values, [0.0, 1.0, 2.0] * 3) def test_preserves_calendar_type(self): - """The shifted axis keeps its cftime calendar.""" + """The padded axis keeps its cftime calendar.""" ds = self._monthly_dataset(2000, 12) original_calendar = ds["time"].values[0].calendar - shifted = shift_time_axis_end(ds, end_year=2021, end_month=12) - last = shifted["time"].values[-1] + extended = repeat_final_year_to(ds, end_year=2021, end_month=12) + last = extended["time"].values[-1] assert isinstance(last, cftime.datetime) assert last.calendar == original_calendar - def test_shifts_time_bounds(self): - """time_bnds are shifted in lock-step with the time coordinate.""" + def test_pads_time_bounds(self): + """time_bnds are extended in lock-step with the time coordinate.""" ds = self._monthly_dataset(1900, 24) - shifted = shift_time_axis_end(ds, end_year=2021, end_month=12) + extended = repeat_final_year_to(ds, end_year=2021, end_month=12) - last_time = shifted["time"].values[-1] - last_bnds = shifted["time_bnds"].values[-1] - # Upper bound matches the final coordinate label. + last_time = extended["time"].values[-1] + last_bnds = extended["time_bnds"].values[-1] assert (last_bnds[1].year, last_bnds[1].month) == (last_time.year, last_time.month) def test_no_op_when_already_at_target(self): - """No shift when the series already ends on the target month.""" + """No padding when the series already ends on the target month.""" ds = self._monthly_dataset(2002, 12 * 20) # ends 2021-12 already - shifted = shift_time_axis_end(ds, end_year=2021, end_month=12) - assert (shifted["time"].values[-1].year, shifted["time"].values[-1].month) == (2021, 12) - assert (shifted["time"].values[0].year, shifted["time"].values[0].month) == (2002, 1) + extended = repeat_final_year_to(ds, end_year=2021, end_month=12) + assert len(extended["time"]) == len(ds["time"]) + assert (extended["time"].values[-1].year, extended["time"].values[-1].month) == (2021, 12) + + def test_no_op_when_past_target(self): + """A series that already runs past the target is left alone.""" + ds = self._monthly_dataset(2002, 12 * 20) # ends 2021-12 + extended = repeat_final_year_to(ds, end_year=2010, end_month=6) + assert len(extended["time"]) == len(ds["time"]) def test_no_time_coordinate_returns_unchanged(self): """Fixed-frequency datasets (no time coord) pass through untouched.""" ds = xr.Dataset({"sftlf": (["lat", "lon"], np.zeros((3, 4)))}) - result = shift_time_axis_end(ds, end_year=2021) + result = repeat_final_year_to(ds, end_year=2021) assert "time" not in result.coords def test_non_cftime_axis_raises(self): @@ -1127,39 +1154,39 @@ def test_non_cftime_axis_raises(self): time = np.array(["1990-01-16", "1990-02-16"], dtype="datetime64[ns]") ds = xr.Dataset({"tas": ("time", [1.0, 2.0])}, coords={"time": time}) with pytest.raises(TypeError, match="cftime"): - shift_time_axis_end(ds, end_year=2021) + repeat_final_year_to(ds, end_year=2021) def test_does_not_mutate_input(self): """The original dataset's time axis is left unchanged.""" ds = self._monthly_dataset(1850, 24) - original_last = ds["time"].values[-1] - shift_time_axis_end(ds, end_year=2021, end_month=12) - assert ds["time"].values[-1] == original_last + original_length = len(ds["time"]) + repeat_final_year_to(ds, end_year=2021, end_month=12) + assert len(ds["time"]) == original_length @pytest.mark.parametrize("end_month", [0, 13, -1]) def test_invalid_end_month_raises(self, end_month): """``end_month`` outside 1..12 fails fast rather than mislabelling.""" ds = self._monthly_dataset(1850, 12) with pytest.raises(ValueError, match=r"end_month must be in 1\.\.12"): - shift_time_axis_end(ds, end_year=2021, end_month=end_month) + repeat_final_year_to(ds, end_year=2021, end_month=end_month) def test_non_december_end_month(self): - """A non-December target shifts month-of-year, keeping spacing.""" + """A non-December target stops on that month, keeping spacing.""" ds = self._monthly_dataset(1990, 12 * 3) # 1990-01 .. 1992-12 - shifted = shift_time_axis_end(ds, end_year=2021, end_month=6) - last = shifted["time"].values[-1] - assert (last.year, last.month) == (2021, 6) - for prev, nxt in itertools.pairwise(shifted["time"].values): + extended = repeat_final_year_to(ds, end_year=1995, end_month=6) + last = extended["time"].values[-1] + assert (last.year, last.month) == (1995, 6) + for prev, nxt in itertools.pairwise(extended["time"].values): assert nxt.year * 12 + (nxt.month - 1) == prev.year * 12 + prev.month def test_clamps_day_to_shorter_target_month(self): - """A day-31 label shifted onto a shorter month is clamped, not rejected.""" - # Single Jan-31 timestep shifted forward one month -> Feb, which has no - # 31st (28 on the NoLeap calendar); the day must clamp instead of raising. + """A day-31 label copied onto a shorter month is clamped, not rejected.""" + # Single Jan-31 timestep repeated into Feb, which has no 31st (28 on the + # NoLeap calendar); the day must clamp instead of raising. time = [cftime.DatetimeNoLeap(2000, 1, 31)] ds = xr.Dataset({"tas": ("time", [1.0])}, coords={"time": time}) - shifted = shift_time_axis_end(ds, end_year=2000, end_month=2) - last = shifted["time"].values[-1] + extended = repeat_final_year_to(ds, end_year=2000, end_month=2) + last = extended["time"].values[-1] assert (last.year, last.month, last.day) == (2000, 2, 28) @@ -1195,11 +1222,12 @@ def test_default_leaves_time_untouched(self): converted = convert_cmip6_dataset(ds) assert list(converted["time"].values) == list(original_time) - def test_extend_relabels_end(self): - """With the opt-in, the converted series ends on the requested month.""" + def test_extend_pads_to_end(self): + """With the opt-in, the converted series is padded out to the requested month.""" ds = self._cmip6_monthly() converted = convert_cmip6_dataset(ds, extend_historical_to=(2021, 12)) last = converted["time"].values[-1] first = converted["time"].values[0] assert (last.year, last.month) == (2021, 12) - assert (first.year, first.month) == (2002, 1) + # Only the tail is fabricated, so the real years keep their dates. + assert (first.year, first.month) == (1850, 1) diff --git a/packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/climate_drivers_for_fire.py b/packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/climate_drivers_for_fire.py index 0debfda17..44e8ada90 100644 --- a/packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/climate_drivers_for_fire.py +++ b/packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/climate_drivers_for_fire.py @@ -180,10 +180,8 @@ class ClimateDriversForFire(ESMValToolDiagnostic): name="cmip7", description="Test with CMIP7 data.", requests=( - # The recipe runs CMIP7 over 2002-2021, but real CanESM5 - # `historical` data ends in 2014. We fetch the trailing 20 years - # of real data and relabel its time axis via extend_historical_to - # so the fabricated CMIP7 series ends 2021-12 and covers 2002-2021. + # The recipe runs CMIP7 over 2002-2021, but real CanESM5 `historical` data + # ends in 2014, so extend_historical_to repeats 2014 out to 2021-12. CMIP7Request( slug="cmip7", facets={ diff --git a/packages/climate-ref-esmvaltool/tests/test-data/climate-drivers-for-fire/cmip7/catalog.yaml b/packages/climate-ref-esmvaltool/tests/test-data/climate-drivers-for-fire/cmip7/catalog.yaml index 85757889b..c224d9913 100644 --- a/packages/climate-ref-esmvaltool/tests/test-data/climate-drivers-for-fire/cmip7/catalog.yaml +++ b/packages/climate-ref-esmvaltool/tests/test-data/climate-drivers-for-fire/cmip7/catalog.yaml @@ -39,7 +39,7 @@ cmip7: start_time: null time_range: null time_units: null - tracking_id: hdl:21.14107/d3ce0008-f617-463a-ba5a-e6ff6c152131 + tracking_id: hdl:21.14107/4e1fbecd-9e5a-4a08-8030-2df83bfdcbe5 units: '%' variable_id: sftlf variant_label: r1i1p1f1 @@ -53,7 +53,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: cVeg_tavg-u-hxy-lnd_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: cVeg_tavg-u-hxy-lnd_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -73,10 +73,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: vegetation_carbon_content - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/727097e3-96c3-4ec6-8e43-92fe37aa7728 + tracking_id: hdl:21.14107/3966d8f6-8fbb-459f-8016-6e7e0334eeff units: kg m-2 variable_id: cVeg variant_label: r1i1p1f1 @@ -90,7 +90,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: hurs_tavg-h2m-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: hurs_tavg-h2m-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -110,10 +110,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: relative_humidity - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/56c6d051-dc98-453b-9a37-0a3616377eda + tracking_id: hdl:21.14107/11b13f7e-48be-491a-be22-e19fc1dda4bd units: '%' variable_id: hurs variant_label: r1i1p1f1 @@ -127,7 +127,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: pr_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: pr_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -147,10 +147,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: precipitation_flux - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/e32ca4bc-e58f-4622-9090-afe8e4718cd2 + tracking_id: hdl:21.14107/3f702c96-44cc-43e8-b81a-75f24d092eae units: kg m-2 s-1 variable_id: pr variant_label: r1i1p1f1 @@ -164,7 +164,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: tas_tavg-h2m-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: tas_tavg-h2m-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -184,10 +184,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: air_temperature - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/247bb279-1fa0-4360-a7cb-3a259882b340 + tracking_id: hdl:21.14107/82835f24-e327-4d10-b31d-82c9ee67adbf units: K variable_id: tas variant_label: r1i1p1f1 @@ -201,7 +201,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: tas_tmaxavg-h2m-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: tas_tmaxavg-h2m-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -221,10 +221,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: air_temperature - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/f1481a4b-340d-4264-949f-5b9fb2dbb0b4 + tracking_id: hdl:21.14107/82fe41ae-fff7-4d41-83c3-557173667e81 units: K variable_id: tas variant_label: r1i1p1f1 @@ -238,7 +238,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: treeFrac_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: treeFrac_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -258,10 +258,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: area_fraction - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/5411c6cb-2296-47b1-b3f2-e0e5b9ede0c7 + tracking_id: hdl:21.14107/e4a7e0df-8b23-464a-be06-dfa2aa01719d units: '%' variable_id: treeFrac variant_label: r1i1p1f1 @@ -275,7 +275,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: vegFrac_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: vegFrac_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -295,10 +295,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: area_fraction - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/b6336aa2-a0df-4612-8d43-8c0f3ffe74e1 + tracking_id: hdl:21.14107/7a21df08-012b-40c3-a4e1-a0a113f1cee7 units: '%' variable_id: vegFrac variant_label: r1i1p1f1 diff --git a/packages/climate-ref-esmvaltool/tests/test-data/climate-drivers-for-fire/cmip7/manifest.json b/packages/climate-ref-esmvaltool/tests/test-data/climate-drivers-for-fire/cmip7/manifest.json index 967295463..5b36b66f7 100644 --- a/packages/climate-ref-esmvaltool/tests/test-data/climate-drivers-for-fire/cmip7/manifest.json +++ b/packages/climate-ref-esmvaltool/tests/test-data/climate-drivers-for-fire/cmip7/manifest.json @@ -16,24 +16,24 @@ "size": 14659 }, "executions/recipe/plots/fire_evaluation/fire_evaluation/burnt_fraction_CanESM5_historical_2002_2021.png": { - "sha256": "046026eab98b28a007e51f3783fba09343849fc30f229d8a9a94932e3598ac7a", - "size": 353675 + "sha256": "14c88e942e24dcdf2d897761f43fd2f964638cadb808089c08adfa6c2c879ed3", + "size": 354302 }, "executions/recipe/plots/fire_evaluation/fire_evaluation/fire_weather_control_CanESM5_historical_2002_2021.png": { - "sha256": "f45f9713db3ad099262664f0431914c8bfbd699e25b1f1f9705b1ca0cad26917", - "size": 359134 + "sha256": "ef6149ae9e86c88bff3cacdcd20d57bf8a5de1ec31f9ec4ac59d93c83b176e72", + "size": 358759 }, "executions/recipe/plots/fire_evaluation/fire_evaluation/fuel_load_continuity_control_CanESM5_historical_2002_2021.png": { - "sha256": "c1eb7e2229b6e8792cbd7d2b8b8bccdf393d1f1cdc464068c0d1e31d60fc4a55", - "size": 367211 + "sha256": "e37c1c67b5fb17a163bfb3321d09caad2d54f19f3d4e2b93772e8263874fcc16", + "size": 367250 }, "executions/recipe/run/fire_evaluation/fire_evaluation/diagnostic_provenance.yml": { "sha256": "a008bdb886d37bbc3c65c957a68c6cb7fa5047e7fe45de2597a18581baab1f07", "size": 4739 }, "executions/recipe/work/fire_evaluation/fire_evaluation/tas_tavg-h2m-hxy-u_Amon_glb_gn_CanESM5_vpd_r1i1p1f1_2002-2021.nc": { - "sha256": "24ae391417df4b63d8ef0c64f213e488db861509f08d443ed89112130fc1c3e5", - "size": 9981838 + "sha256": "a7d692f13015d2172f475b19061b4c2855143f5522596da6363ded3d9a7e190a", + "size": 9981855 }, "output.json": { "sha256": "98cb09d7af578eb33ce0ee02868fc040b114bd5c792ea84b3f76e8494a3039b5", @@ -45,5 +45,5 @@ } }, "schema": 2, - "test_case_version": 2 + "test_case_version": 3 } diff --git a/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/catalog.yaml b/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/catalog.yaml index e0fd41f7c..c8c09c40f 100644 --- a/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/catalog.yaml +++ b/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/catalog.yaml @@ -39,7 +39,7 @@ cmip7: start_time: null time_range: null time_units: null - tracking_id: hdl:21.14107/28755f83-74b9-4422-bead-9225ddb7a57e + tracking_id: hdl:21.14107/ebb116c7-0fab-433c-a2b3-e7d2da903dfc units: m2 variable_id: areacella variant_label: r1i1p1f1 @@ -53,7 +53,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: rlut_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: rlut_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -73,10 +73,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: toa_outgoing_longwave_flux - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/4e548a95-a5ea-4e5f-8774-123c884c6437 + tracking_id: hdl:21.14107/5d8e35e3-eb4d-4407-9ad3-05edb0773756 units: W m-2 variable_id: rlut variant_label: r1i1p1f1 @@ -90,7 +90,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: rlutcs_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: rlutcs_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -110,10 +110,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: toa_outgoing_longwave_flux_assuming_clear_sky - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/33d7f3bb-f08d-479a-b3ea-4493dcc1183d + tracking_id: hdl:21.14107/6313eacb-0ec5-4659-a440-68569d8dadae units: W m-2 variable_id: rlutcs variant_label: r1i1p1f1 @@ -127,7 +127,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: rsut_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: rsut_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -147,10 +147,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: toa_outgoing_shortwave_flux - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/a56b4e19-ac38-451f-a374-ef00e6e52500 + tracking_id: hdl:21.14107/f29f53fb-df74-4943-8f2a-caa7c8f8aed0 units: W m-2 variable_id: rsut variant_label: r1i1p1f1 @@ -164,7 +164,7 @@ cmip7: end_time: '2021-12-16 12:00:00' experiment_id: historical external_variables: areacella - filename: rsutcs_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185701-202112.nc + filename: rsutcs_tavg-u-hxy-u_mon_glb_gn_CanESM5_historical_r1i1p1f1_185001-202112.nc finalised: true frequency: mon grid_label: gn @@ -184,10 +184,10 @@ cmip7: region: glb source_id: CanESM5 standard_name: toa_outgoing_shortwave_flux_assuming_clear_sky - start_time: '1857-01-16 12:00:00' - time_range: 1857-01-16 12:00:00-2021-12-16 12:00:00 + start_time: '1850-01-16 12:00:00' + time_range: 1850-01-16 12:00:00-2021-12-16 12:00:00 time_units: days since 1850-01-01 - tracking_id: hdl:21.14107/25bd661b-2adf-40f2-88ef-5d6893f5da7b + tracking_id: hdl:21.14107/327ef19b-488f-4e55-ac57-7a06d4256b31 units: W m-2 variable_id: rsutcs variant_label: r1i1p1f1 diff --git a/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/manifest.json b/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/manifest.json index 47de5543d..844caaa5b 100644 --- a/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/manifest.json +++ b/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/manifest.json @@ -3,7 +3,7 @@ "committed": { "diagnostic.json": "183d82f3963ad19b5a556b8025e6990c444f292adda1d464e12136d05a5ef3b3", "output.json": "097d07332e39889ab51b9c55a9f03e4d3dc6a442a7f1693aa15d59bba50d7086", - "series.json": "bb5f92524671be619ac30d8aad69c45744e333389d8fc02081944ea445dacbcc" + "series.json": "21a54adcc37ef04630faaccbb02d424867119898b51e148d4cd1cd623921a19c" }, "diagnostic_version": 2, "native": { @@ -16,70 +16,70 @@ "size": 22125 }, "executions/recipe/plots/plot_maps/plot/map_lwcre_CanESM5_atmos.png": { - "sha256": "8fd12bec85f5941118c49478a76f19f6d0615de5c43ae1dc7597ad4b881e4ea1", - "size": 559519 + "sha256": "219995af6b5cdd889b7d6677bbd47dc2c4f37ad99d76c6bcc94ff29a1cd92d10", + "size": 527230 }, "executions/recipe/plots/plot_maps/plot/map_swcre_CanESM5_atmos.png": { - "sha256": "c5a8894e2d90bf041087ad813e35d2eda34dc701c6f612a850feb6e32353dd3f", - "size": 419286 + "sha256": "aab2c0a409042d5aadc177a36689e9a8016c0b844176b5345fbb24a2c6f902d6", + "size": 578771 }, "executions/recipe/plots/plot_profiles/plot/variable_vs_lat_lwcre_ambiguous_dataset_ambiguous_mip.png": { - "sha256": "f2d0d8c56184e5f1671c1eeff1612b349e7c3bf6073e833aaaa5f42932537128", - "size": 162036 + "sha256": "cb8040e05150cbe0f96633b8c28b721153759558c8a98ea220aa5d03834c431a", + "size": 161421 }, "executions/recipe/plots/plot_profiles/plot/variable_vs_lat_swcre_ambiguous_dataset_ambiguous_mip.png": { - "sha256": "628b66e16d91d262d2fc5d4a97734f8a2f058a809df874f86a22c66a9b1a4cb7", - "size": 129570 + "sha256": "df3c3e80453a5cc549b80c68df0e3635ac3b3a1e30abeb98cd9805ee90fd7527", + "size": 173904 }, "executions/recipe/run/plot_maps/plot/diagnostic_provenance.yml": { - "sha256": "32560c73cc12c1825891364a6d703020512cb80c24e297d52e09495d66df4ef9", + "sha256": "bbdf7f91d9eddff5ae64968cb18ab31ed20eea4d05e12720887c000ee159a277", "size": 3682 }, "executions/recipe/run/plot_profiles/plot/diagnostic_provenance.yml": { - "sha256": "97ead21e04b280cb4b733c68f4130e5e63e6fe858beb00cd6b92852d8c92b489", + "sha256": "3111d6177c4dcdee98dd0c8485b9918c14975ba59c475ddf9ed5b217abd524db", "size": 1422 }, "executions/recipe/work/plot_maps/plot/map_lwcre_CanESM5_atmos_bottom.nc": { - "sha256": "50948828bb1dd3fe053325b7860b4170dc81c83a8006b162cfbc539c74fb0a31", + "sha256": "2a7f1e36d1bfab0eb72f5554b6acf8b4f1c19f79a4cc0eab62fc42d31b57232a", "size": 299088 }, "executions/recipe/work/plot_maps/plot/map_lwcre_CanESM5_atmos_top_left.nc": { - "sha256": "7d8d5a3098695ec265def4098e88c144d80d5b221b8f1b26407841d5e301b131", + "sha256": "528e349f329a9943a85abacf7fc977560eb9b12902c42191eee264eae4ff58f9", "size": 296682 }, "executions/recipe/work/plot_maps/plot/map_lwcre_CanESM5_atmos_top_right.nc": { - "sha256": "daeda7c33146d0979fa2523545f03c13ee0a275c04a17eae896e14d7e1d08096", - "size": 293881 + "sha256": "2c4460b73f46dde5d00dd804665728924306a07e9984dffc398374d92cdf6adf", + "size": 293912 }, "executions/recipe/work/plot_maps/plot/map_swcre_CanESM5_atmos_bottom.nc": { - "sha256": "982b3b16bfecbd2e04ee0ead4b59a4f079e7eab0e664f4ce6d1b072bc7e5d62c", + "sha256": "b64b0a69b6329f1bb33fc535c6c9bd50f07ab95120893ac477824df3852acfd2", "size": 299278 }, "executions/recipe/work/plot_maps/plot/map_swcre_CanESM5_atmos_top_left.nc": { - "sha256": "d3366e9e8aedfba8d8cebb6fff5547b4769abe524b7939cd08e95a76c3f46652", + "sha256": "a0d1409207210b6a949664a348c3e2c65fad54e803a1af0bdf4ad261280da88c", "size": 296966 }, "executions/recipe/work/plot_maps/plot/map_swcre_CanESM5_atmos_top_right.nc": { - "sha256": "5c1cabc02f9d451f07b15005730f29205bfebd1a5cca46ade1c584d1e652153c", - "size": 293881 + "sha256": "6e0b8b24754ff89be620ec54534d84c4a7a110dfe001025da2b12e7c66eb885f", + "size": 293912 }, "executions/recipe/work/plot_profiles/plot/variable_vs_lat_lwcre_ambiguous_dataset_ambiguous_mip.nc": { - "sha256": "8cd9444fffdee52dfe0de2eec7454329552ee2557e4e979c6594b285de503e19", - "size": 12976 + "sha256": "70106f8fef5ee8d5e47b3df9dc1cff8ca387613af43efd16453866c5ea434ca1", + "size": 12989 }, "executions/recipe/work/plot_profiles/plot/variable_vs_lat_swcre_ambiguous_dataset_ambiguous_mip.nc": { - "sha256": "9bb4e5162adbbc284b35d32f6fa2382d9ddf9e66982a0020245c938f074977f8", - "size": 12978 + "sha256": "8357638c36e8c4b43144ba439bae6b2fde6fafec1aa25a37e37f0f50aaa1106e", + "size": 12991 }, "output.json": { "sha256": "64e93ece3b9dc2b2bc8127681fd4c8a292cc3df8602f7ef5c9e208da6f5bb558", "size": 5532 }, "series.json": { - "sha256": "28fa10d62a913c9c420cc8112fca5a815c0de7d81bf2355c89a61f3f68cac9a5", - "size": 25525 + "sha256": "00fd1ba06075d828010721baaa0730f81c5ecf4f9fc4faf8d6f6385281bcc75e", + "size": 28125 } }, "schema": 2, - "test_case_version": 1 + "test_case_version": 2 } diff --git a/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/regression/series.json b/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/regression/series.json index e132db97e..23cde678a 100644 --- a/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/regression/series.json +++ b/packages/climate-ref-esmvaltool/tests/test-data/cloud-radiative-effects/cmip7/regression/series.json @@ -202,8 +202,8 @@ "index_name": "lat", "kind": "reference", "values": [ - null, - null, + -1.045989, + -0.5889727, 0.4203378, 1.927015, 3.465251, @@ -587,186 +587,186 @@ "index_name": "lat", "kind": "reference", "values": [ - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null + -2.48495, + -3.011922, + -1.812262, + -2.358131, + -2.247997, + -2.210956, + -2.280323, + -2.603404, + -2.842537, + -2.792567, + -2.791625, + -3.027941, + -5.090857, + -6.759895, + -7.045802, + -7.725838, + -8.862566, + -9.501175, + -11.455, + -12.64522, + -17.76624, + -23.13368, + -28.28044, + -34.07334, + -42.48692, + -50.30328, + -56.32111, + -60.11624, + -62.73796, + -65.22518, + -65.88797, + -67.76736, + -69.31221, + -70.41383, + -71.37982, + -71.74639, + -71.44776, + -71.48259, + -71.51714, + -71.23863, + -71.07479, + -70.66764, + -70.17005, + -69.53057, + -68.71002, + -67.81548, + -66.79104, + -65.57703, + -64.40285, + -63.02597, + -61.73565, + -60.32459, + -58.50654, + -56.54043, + -54.85621, + -53.25089, + -51.21268, + -49.46764, + -47.60698, + -46.17438, + -45.08433, + -43.9425, + -43.10743, + -42.21624, + -41.53518, + -40.76889, + -40.00203, + -39.81641, + -39.70792, + -39.6317, + -39.6504, + -39.79145, + -40.34766, + -40.82922, + -41.56613, + -42.24284, + -43.30133, + -44.32298, + -45.09357, + -45.71731, + -46.52399, + -47.74177, + -47.39764, + -47.77183, + -47.91388, + -47.31296, + -47.35217, + -46.50909, + -46.00924, + -45.20827, + -45.56945, + -48.2179, + -51.964, + -55.62644, + -59.21768, + -61.26494, + -60.74314, + -58.10833, + -54.50056, + -50.53028, + -46.35247, + -42.44291, + -39.03374, + -36.11345, + -34.3248, + -33.14566, + -32.38345, + -32.05309, + -32.49255, + -32.27388, + -32.06071, + -32.55756, + -32.49456, + -33.10534, + -33.80188, + -34.65215, + -36.04041, + -37.55629, + -38.91296, + -39.95918, + -40.29867, + -41.06542, + -42.21053, + -43.83743, + -44.64352, + -46.09937, + -47.39515, + -47.69776, + -48.31335, + -48.96756, + -50.05252, + -51.24553, + -52.07272, + -52.32423, + -52.08033, + -52.02091, + -52.00805, + -52.68217, + -52.53229, + -52.84266, + -53.34156, + -53.03299, + -52.27736, + -51.45988, + -50.9086, + -50.00771, + -48.77616, + -47.74044, + -46.80811, + -44.86913, + -42.27487, + -39.72132, + -37.72079, + -36.29692, + -33.53915, + -32.17155, + -30.52497, + -29.14896, + -27.6422, + -26.79022, + -25.86799, + -25.3077, + -24.28875, + -24.90899, + -24.56762, + -23.25611, + -22.00085, + -20.37689, + -17.77505, + -16.33492, + -15.04555, + -14.59322, + -15.13996, + -15.60001, + -16.2065, + -16.25373, + -16.06816, + -15.85888, + -15.46977, + -14.5417 ] }, { @@ -970,186 +970,186 @@ ], "index_name": "lat", "values": [ - 3.329102, - 3.329102, - 3.329102, - 4.179688, - 4.717773, - 4.717773, - 4.652344, - 4.632812, - 4.632812, - 5.273438, - 5.301758, - 5.550781, - 6.822266, - 6.822266, - 7.549805, - 8.777344, - 8.777344, - 10.60254, - 11.93945, - 11.93945, - 15.33203, - 16.27539, - 16.27539, - 20.91016, - 20.97363, - 21.70605, - 24.68848, - 24.68848, - 25.58887, - 26.90527, - 26.90527, - 28.01172, - 28.70508, - 28.70508, - 29.42188, - 29.57715, - 29.58984, - 30.0166, - 30.0166, - 30.00488, - 29.9668, - 29.9668, - 29.6123, - 29.17676, - 29.17676, - 28.65039, - 28.37598, - 28.37598, - 27.32227, - 27.15723, - 27.01758, - 25.26074, - 25.26074, - 24.66113, - 23.14648, - 23.14648, - 22.27051, - 21.36914, - 21.36914, - 20.24902, - 19.77246, - 19.77246, - 18.49121, - 18.36426, - 18.26562, - 17.53125, - 17.53125, - 17.69727, - 18.03711, - 18.03711, - 18.81641, - 19.48926, - 19.48926, - 21.79395, - 22.58008, - 22.58008, - 26.625, - 26.81934, - 27.74414, - 32.4834, - 32.4834, - 34.10156, - 36.81934, - 36.81934, - 37.03613, - 37.19141, - 37.19141, - 36.14551, - 35.86914, - 35.86914, - 35.50195, - 35.50195, - 36.25879, - 39.12402, - 39.12402, - 40.48828, - 42.3916, - 42.3916, - 40.58398, - 39.50684, - 39.50684, - 32.29297, - 30.88477, - 30.58691, - 24.38184, - 24.38184, - 23.41602, - 20.58496, - 20.58496, - 19.87793, - 19.05762, - 19.05762, - 18.35156, - 18.00684, - 18.00684, + 3.454102, + 3.454102, + 3.454102, + 4.306641, + 4.844727, + 4.844727, + 4.838867, + 4.836914, + 4.836914, + 5.40625, + 5.431641, + 5.6875, + 6.988281, + 6.988281, + 7.701172, + 8.90332, + 8.90332, + 10.60547, + 11.85352, + 11.85352, + 15.00684, + 15.88379, + 15.88379, + 20.3916, + 20.45312, + 21.25, + 24.49414, + 24.49414, + 25.5, + 26.9707, + 26.9707, + 28.11816, + 28.83691, + 28.83691, + 29.57324, + 29.7334, + 29.74609, + 30.16895, + 30.16895, + 30.16504, + 30.15332, + 30.15332, + 29.81348, + 29.39453, + 29.39453, + 28.79688, + 28.48535, + 28.48535, + 27.23633, + 27.04199, + 26.88281, + 24.88184, + 24.88184, + 24.28223, + 22.76758, + 22.76758, + 21.96875, + 21.14551, + 21.14551, + 20.00391, + 19.51758, + 19.51758, + 18.29883, + 18.17676, + 18.08105, + 17.36523, + 17.36523, + 17.5459, + 17.91602, + 17.91602, + 18.76855, + 19.50488, + 19.50488, + 21.98438, + 22.83008, + 22.83008, + 26.79883, + 26.98926, + 27.87012, + 32.37988, + 32.37988, + 34.12207, + 37.04492, + 37.04492, + 37.4209, + 37.68945, + 37.68945, + 36.51172, + 36.20117, + 36.20117, + 36.0127, + 36.0127, + 36.7998, + 39.77734, + 39.77734, + 40.89551, + 42.4541, + 42.4541, + 40.38379, + 39.15039, + 39.15039, + 31.94336, + 30.53613, + 30.23926, + 24.06836, + 24.06836, + 23.125, + 20.36133, + 20.36133, + 19.68945, + 18.91016, + 18.91016, + 18.29102, + 17.98926, + 17.98926, 17.95801, - 17.95117, - 18.08984, - 19.48438, - 19.48438, - 19.91113, - 20.91309, - 20.91309, - 22.02051, - 23.0957, - 23.0957, - 24.13379, - 24.54492, - 24.54492, - 24.91016, - 24.93945, - 24.9707, - 25.17285, - 25.17285, - 24.82812, - 24.16699, - 24.16699, - 24.38086, - 24.55469, - 24.55469, - 24.48926, - 24.46875, - 24.46875, - 24.60156, - 24.60547, - 24.50098, - 24.01758, - 24.01758, - 23.52246, - 22.73242, - 22.73242, - 21.9834, - 21.4707, - 21.4707, - 19.6543, - 19.20801, - 19.18457, - 17.46289, - 17.46289, - 16.97852, - 15.23828, - 15.23828, - 14.54688, - 13.60254, - 13.60254, - 12.63965, - 12.06934, - 12.06934, - 10.5957, - 10.30664, - 10.25098, - 8.992188, - 8.992188, - 8.873047, - 8.473633, - 8.473633, - 8.391602, - 8.262695, - 8.262695, - 8.262695 + 17.9541, + 18.08496, + 19.40039, + 19.40039, + 19.84082, + 20.875, + 20.875, + 22.0625, + 23.21484, + 23.21484, + 24.26074, + 24.6748, + 24.6748, + 24.90527, + 24.92383, + 24.94043, + 25.0498, + 25.0498, + 24.72559, + 24.10449, + 24.10449, + 24.3916, + 24.62598, + 24.62598, + 24.64258, + 24.64746, + 24.64746, + 24.88184, + 24.88867, + 24.78613, + 24.31152, + 24.31152, + 23.78223, + 22.9375, + 22.9375, + 22.1377, + 21.58984, + 21.58984, + 19.8418, + 19.41211, + 19.38672, + 17.49023, + 17.49023, + 16.99023, + 15.19238, + 15.19238, + 14.50879, + 13.57715, + 13.57715, + 12.80762, + 12.35156, + 12.35156, + 11.08984, + 10.84277, + 10.77539, + 9.250977, + 9.250977, + 9.099609, + 8.592773, + 8.592773, + 8.539062, + 8.455078, + 8.455078, + 8.455078 ] }, { @@ -1353,186 +1353,186 @@ ], "index_name": "lat", "values": [ - -3.197266, - -3.197266, - -3.197266, - -3.259766, - -3.298828, - -3.298828, - -3.441406, - -3.484375, - -3.484375, - -4.012695, - -4.036133, - -4.194336, - -5.003906, - -5.003906, - -5.522461, - -6.397461, - -6.397461, - -7.824219, - -8.869141, - -8.869141, - -13.89941, - -15.29883, - -15.29883, - -27.51562, - -27.68164, - -30.53906, - -42.17383, - -42.17383, - -47.58301, - -55.49023, - -55.49023, - -62.04004, - -66.14453, - -66.14453, - -70.21875, - -71.10645, - -71.16406, - -73.1416, - -73.1416, - -73.10645, - -72.99512, - -72.99512, - -72.20605, - -71.23535, - -71.23535, - -69.19043, - -68.12305, - -68.12305, - -65.34375, - -64.91113, - -64.63184, - -61.13281, - -61.13281, - -59.92969, - -56.88867, - -56.88867, - -54.59277, - -52.22852, - -52.22852, - -49.37012, - -48.15332, - -48.15332, - -44.88281, - -44.55762, - -44.26367, - -42.0791, - -42.0791, - -42.18066, - -42.38867, - -42.38867, - -42.65234, - -42.88086, - -42.88086, - -43.28125, - -43.41797, - -43.41797, - -45.22754, - -45.31445, - -45.97266, - -49.34473, - -49.34473, - -51.05566, - -53.92676, - -53.92676, - -55.31738, - -56.31445, - -56.31445, - -54.96191, - -54.60547, - -54.60547, - -51.44238, - -51.44238, - -52.28711, - -55.48633, - -55.48633, - -56.59863, - -58.14746, - -58.14746, - -53.56348, - -50.83203, - -50.83203, - -42.90137, - -41.35352, - -41.15918, - -37.10645, - -37.10645, - -36.4541, - -34.54199, - -34.54199, - -34.19531, - -33.79297, - -33.79297, - -33.7168, - -33.67969, - -33.67969, - -35.59668, - -35.85449, - -36.11914, - -38.77734, - -38.77734, - -39.23047, - -40.2959, - -40.2959, - -41.68262, - -43.02832, - -43.02832, - -44.20703, - -44.67285, - -44.67285, - -45.8877, - -45.98438, - -46.28516, - -48.21289, - -48.21289, - -48.17969, - -48.11621, - -48.11621, - -48.57715, - -48.95215, - -48.95215, - -48.18066, - -47.9375, - -47.9375, - -46.2666, - -46.21777, - -45.5625, - -42.55469, - -42.55469, - -40.76758, - -37.91699, - -37.91699, - -35.68066, - -34.15137, - -34.15137, - -30.44336, - -29.5332, - -29.48633, - -26.01562, - -26.01562, - -25.45117, - -23.41992, - -23.41992, - -22.64453, - -21.58594, - -21.58594, - -19.91309, - -18.92285, - -18.92285, - -15.33203, - -14.62891, - -14.53027, - -12.3291, - -12.3291, - -12.2002, - -11.76465, - -11.76465, - -11.66699, - -11.5127, - -11.5127, - -11.5127 + -3.338867, + -3.338867, + -3.338867, + -3.416016, + -3.464844, + -3.464844, + -3.625977, + -3.673828, + -3.673828, + -4.143555, + -4.164062, + -4.336914, + -5.219727, + -5.219727, + -5.804688, + -6.792969, + -6.792969, + -8.004883, + -8.893555, + -8.893555, + -13.64746, + -14.9707, + -14.9707, + -26.45605, + -26.6123, + -29.54492, + -41.48242, + -41.48242, + -47.23926, + -55.65332, + -55.65332, + -62.51465, + -66.81543, + -66.81543, + -70.66016, + -71.49805, + -71.55469, + -73.50195, + -73.50195, + -73.47266, + -73.37793, + -73.37793, + -72.55957, + -71.55371, + -71.55371, + -69.27148, + -68.08203, + -68.08203, + -65.01953, + -64.54199, + -64.23828, + -60.42285, + -60.42285, + -59.23535, + -56.23242, + -56.23242, + -54.08887, + -51.88184, + -51.88184, + -49.00488, + -47.7793, + -47.7793, + -44.45508, + -44.125, + -43.81348, + -41.50098, + -41.50098, + -41.65234, + -41.96289, + -41.96289, + -42.39746, + -42.77148, + -42.77148, + -43.3623, + -43.56348, + -43.56348, + -45.14453, + -45.21973, + -45.81738, + -48.87598, + -48.87598, + -50.72754, + -53.83691, + -53.83691, + -55.38184, + -56.49023, + -56.49023, + -55.01953, + -54.63086, + -54.63086, + -51.81152, + -51.81152, + -52.63574, + -55.75781, + -55.75781, + -56.64062, + -57.87012, + -57.87012, + -53.00977, + -50.11328, + -50.11328, + -42.25, + -40.71484, + -40.52832, + -36.65137, + -36.65137, + -36.04688, + -34.27539, + -34.27539, + -33.93555, + -33.54297, + -33.54297, + -33.51562, + -33.50195, + -33.50195, + -35.49023, + -35.75781, + -36.04297, + -38.91699, + -38.91699, + -39.38477, + -40.48145, + -40.48145, + -41.8584, + -43.19629, + -43.19629, + -44.24805, + -44.66504, + -44.66504, + -45.83691, + -45.93066, + -46.24023, + -48.23047, + -48.23047, + -48.22852, + -48.22266, + -48.22266, + -48.8457, + -49.35254, + -49.35254, + -48.61719, + -48.38574, + -48.38574, + -46.69238, + -46.64258, + -45.97754, + -42.92773, + -42.92773, + -40.98828, + -37.89551, + -37.89551, + -35.51172, + -33.88184, + -33.88184, + -30.42578, + -29.57715, + -29.53125, + -26.18555, + -26.18555, + -25.67676, + -23.85059, + -23.85059, + -23.06055, + -21.98242, + -21.98242, + -20.9541, + -20.34473, + -20.34473, + -17.34668, + -16.75977, + -16.64648, + -14.125, + -14.125, + -13.91016, + -13.18457, + -13.18457, + -12.70703, + -11.95215, + -11.95215, + -11.95215 ] } ] From c5279da8c6dd1bd925b5b2213fbaf2624b805a22 Mon Sep 17 00:00:00 2001 From: Jared Lewis Date: Sat, 29 Aug 2026 08:12:21 +1000 Subject: [PATCH 2/2] docs(changelog): add the CMIP7 fabrication fragment --- changelog/887.fix.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/887.fix.md diff --git a/changelog/887.fix.md b/changelog/887.fix.md new file mode 100644 index 000000000..64abf0804 --- /dev/null +++ b/changelog/887.fix.md @@ -0,0 +1,5 @@ +Fabricated CMIP7 test data now reaches years without real CMIP6 source data by repeating the final year, +rather than relabelling the whole series onto the requested end date. +The real years keep their real dates, so a diagnostic can ask for a period that the source data genuinely covers. +This also fixes datasets split across several files, where each file was dragged onto the same end date +and the converted files overlapped.