From 2f5ba4888c021a7f45c3d1dd4571966667200582 Mon Sep 17 00:00:00 2001 From: Charles Turner <52199577+charles-turner-1@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:26:02 +0800 Subject: [PATCH 1/8] 292 flaky tests (#293) Fixes issues with MOM6 testing, and time parsing of same. * Revert "Add MOM6 support (om4 025jra ryf) (#258)" This reverts commit 8d18b19d96e3269278f30f7cd470d61f73d1a778. Testing to see whether this restores test stability * Revert "Revert "Add MOM6 support (om4 025jra ryf) (#258)"" This reverts commit 23b3b5f8e6f759ff87c558e127648f211d78e81a - ie. it restores the mom6 stuff. * Add xarray complete * Pin dependencies back in time for 3.11 * Fail fast false * Pin a bunch of deps * Added toxfile * tox.ini w/ comments on failures * Revert "Pin dependencies back in time for 3.11" This reverts commit 6fa66768d7a0fbeaa5b88224e9b50d4c870358b0. * These changes are ugly & horrible but mostly seem to resolve the issues with cftime. THey cause some assets to fail because they alter the parser, but I think this is a window into a solution. * Lots of catches for overflow errors: keeping for posterity * Restore 'test_builders.py' to same state as main * Fix mom6 tests - should now all be failing * Ready to replace time info guesses for MOM6 with a subclass * Fixed broken MOM6 builder * re-enable fast fail * Reverted CI environments to main * Removed '_access' from a bunch of function names - now we have GFDL models in the builders, this is misleading * Revert load_dataset => open_dataset * Updating test to fix coverage * Restored to working state * Tests for GenericTimeParser & AccessTimeParser * Improve test coverage * Improve test coverage for GfdlTimeParser * Improve test coverage for GfdlTimeParser * Improve test coverage for GfdlTimeParser * Marc's comments --- src/access_nri_intake/source/builders.py | 35 +-- src/access_nri_intake/source/utils.py | 308 ++++++++++++++++++++++- tests/test_builders.py | 98 ++++---- tests/test_source_utils.py | 281 ++++++++++++++++++++- tox.ini | 48 ++++ 5 files changed, 702 insertions(+), 68 deletions(-) create mode 100644 tox.ini diff --git a/src/access_nri_intake/source/builders.py b/src/access_nri_intake/source/builders.py index 05fc7d10..7003d22e 100644 --- a/src/access_nri_intake/source/builders.py +++ b/src/access_nri_intake/source/builders.py @@ -15,9 +15,10 @@ from . import ESM_JSONSCHEMA, PATH_COLUMN, VARIABLE_COLUMN from .utils import ( EmptyFileError, - _AccessNCFileInfo, + GenericTimeParser, + GfdlTimeParser, + _NCFileInfo, _VarInfo, - get_timeinfo, ) # Frequency translations @@ -56,8 +57,9 @@ class BaseBuilder(Builder): This builds on the ecgtools.Builder class. """ - # Base class carries an empty set + # Base class carries an empty set, and a GenericParser PATTERNS: list = [] + TIME_PARSER = GenericTimeParser def __init__( self, @@ -222,7 +224,7 @@ def parser(file): raise NotImplementedError @classmethod - def parse_access_filename( + def parse_filename( cls, filename: str, patterns: list[str] | None = None, @@ -285,11 +287,9 @@ def parse_access_filename( return file_id, timestamp, frequency @classmethod - def parse_access_ncfile( - cls, file: str, time_dim: str = "time" - ) -> _AccessNCFileInfo: + def parse_ncfile(cls, file: str, time_dim: str = "time") -> _NCFileInfo: """ - Get Intake-ESM datastore entry info from an ACCESS netcdf file + Get Intake-ESM datastore entry info from a netcdf file Parameters ---------- @@ -300,7 +300,7 @@ def parse_access_ncfile( Returns ------- - output_nc_info: _AccessNCFileInfo + output_nc_info: _NCFileInfo A dataclass containing the information parsed from the file Raises @@ -310,7 +310,7 @@ def parse_access_ncfile( file_path = Path(file) - file_id, filename_timestamp, filename_frequency = cls.parse_access_filename( + file_id, filename_timestamp, filename_frequency = cls.parse_filename( file_path.stem ) @@ -327,14 +327,14 @@ def parse_access_ncfile( attrs = ds[var].attrs dvars.append_attrs(var, attrs) # type: ignore - start_date, end_date, frequency = get_timeinfo( + start_date, end_date, frequency = cls.TIME_PARSER( ds, filename_frequency, time_dim - ) + )() if not dvars.variable_list: raise EmptyFileError("This file contains no variables") - output_ncfile = _AccessNCFileInfo( + output_ncfile = _NCFileInfo( filename=file_path.name, path=file, file_id=file_id, @@ -399,7 +399,7 @@ def parser(cls, file) -> dict: if realm == "ice": realm = "seaIce" - nc_info = cls.parse_access_ncfile(file) + nc_info = cls.parse_ncfile(file) ncinfo_dict = nc_info.to_dict() ncinfo_dict["realm"] = realm @@ -457,7 +457,7 @@ def __init__(self, path): @classmethod def parser(cls, file) -> dict: try: - output_nc_info = cls.parse_access_ncfile(file) + output_nc_info = cls.parse_ncfile(file) ncinfo_dict = output_nc_info.to_dict() if "mom6" in ncinfo_dict["filename"]: @@ -487,6 +487,7 @@ class Mom6Builder(BaseBuilder): rf"[^\.]*({PATTERNS_HELPERS['ymd-ns']})\.{PATTERNS_HELPERS['mom6_components']}.*{PATTERNS_HELPERS['mom6_added_timestamp']}.*$", # Daily snapshot naming rf"[^\.]*({PATTERNS_HELPERS['ymd-ns']})\.{PATTERNS_HELPERS['mom6_components']}.*$", # Basic naming ] + TIME_PARSER = GfdlTimeParser def __init__(self, path): """ @@ -529,7 +530,7 @@ def __init__(self, path): @classmethod def parser(cls, file): try: - output_nc_info = cls.parse_access_ncfile(file) + output_nc_info = cls.parse_ncfile(file) ncinfo_dict = output_nc_info.to_dict() if "ocean" in ncinfo_dict["filename"]: @@ -605,7 +606,7 @@ def parser(cls, file): realm_mapping = {"atm": "atmos", "ocn": "ocean", "ice": "seaIce"} - nc_info = cls.parse_access_ncfile(file) + nc_info = cls.parse_ncfile(file) ncinfo_dict = nc_info.to_dict() # Remove exp_id from file id so that members can be part of the same dataset diff --git a/src/access_nri_intake/source/utils.py b/src/access_nri_intake/source/utils.py index cc0b6905..fe494acf 100644 --- a/src/access_nri_intake/source/utils.py +++ b/src/access_nri_intake/source/utils.py @@ -19,7 +19,7 @@ class EmptyFileError(Exception): @dataclass -class _AccessNCFileInfo: +class _NCFileInfo: """ Holds information about a NetCDF file that is used to create an intake-esm catalog entry. @@ -250,3 +250,309 @@ def _todate(t): frequency = frequency[1] return start_date, end_date, frequency + + +class GenericTimeParser: + """ + Generic time parser + """ + + def __init__(self, ds: xr.Dataset, filename_frequency: str | None, time_dim: str): + """ + Parameters + ---------- + ds: :py:class:`xarray.Dataset` + The dataset to parse the time info from + filename_frequency: str + Frequency as determined from the filename + time_dim: str + The name of the time dimension + """ + self.ds = ds + self.filename_frequency = filename_frequency + self.time_dim = time_dim + + @staticmethod + def _add_month_start(time, n: int): + """Add months to cftime datetime and truncate to start""" + year = time.year + ((time.month + n - 1) // 12) + month = (time.month + n - 1) % 12 + 1 + return time.replace( + year=year, month=month, day=1, hour=0, minute=0, second=0, microsecond=0 + ) + + @staticmethod + def _add_year_start(time, n: int): + """Add years to cftime datetime and truncate to start""" + return time.replace( + year=time.year + n, + month=1, + day=1, + hour=0, + minute=0, + second=0, + microsecond=0, + ) + + @staticmethod + def _guess_start_end_dates(ts, te, frequency): + """Guess the start and end bounded times for a given frequency""" + warnings.warn( + "Time coordinate does not include bounds information. Guessing " + "start and end times." + ) + num, unit = frequency + if unit == "yr": + step_back = -int(num / 2) + step_fwd = num + step_back + ts = GenericTimeParser._add_year_start(ts, step_back) + te = GenericTimeParser._add_year_start(te, step_fwd) + elif unit == "mon": + step_back = -int(num / 2) + step_fwd = num + step_back + ts = GenericTimeParser._add_month_start(ts, step_back) + te = GenericTimeParser._add_month_start(te, step_fwd) + elif unit == "day": + dt = timedelta(days=num) / 2 + ts = ts - dt + te = te + dt + elif unit == "hr": + dt = timedelta(hours=num) / 2 + ts = ts - dt + te = te + dt + else: + warnings.warn("Cannot infer start and end times for subhourly frequencies.") + return ts, te + + def _get_timeinfo(self) -> tuple[str, str, str]: + """ + Get start date, end date and frequency of a xarray dataset. Stolen and adapted from the + cosima cookbook, see + https://github.com/COSIMA/cosima-cookbook/blob/master/cosima_cookbook/database.py#L565 + + Parameters + ---------- + ds: :py:class:`xarray.Dataset` + The dataset to parse the time info from + filename_frequency: str + Frequency as determined from the filename + time_dim: str + The name of the time dimension + + Returns + ------- + start_date: str + The start date of the dataset + end_date: str + The end date of the dataset + frequency: str + The frequency of the dataset + + Raises + ------ + EmptyFileError + If the dataset has a valid unlimited dimension, but no data + """ + + ds = self.ds + filename_frequency = self.filename_frequency + time_dim = self.time_dim + + def _todate(t): + return cftime.num2date(t, time_var.units, calendar=time_var.calendar) + + time_format = "%Y-%m-%d, %H:%M:%S" + ts = None + te = None + frequency: str | tuple[int | None, str] = FREQUENCY_STATIC + has_time = time_dim in ds + + if has_time: + time_var = ds[time_dim] + + if len(time_var) == 0: + raise EmptyFileError( + "This file has a valid unlimited dimension, but no data" + ) + + has_bounds = hasattr(time_var, "bounds") and time_var.bounds in ds.variables + if has_bounds: + bounds_var = ds.variables[time_var.bounds] + ts = _todate(bounds_var[0, 0]) + te = _todate(bounds_var[-1, 1]) + else: + ts = _todate(time_var[0]) + te = _todate(time_var[-1]) + + if len(time_var) > 1 or has_bounds: + if has_bounds: + t1 = _todate(bounds_var[0, 1]) + else: + t1 = _todate(time_var[1]) + + dt = t1 - ts + # TODO: This is not a very good way to get the frequency + if dt.days >= 365: + years = round(dt.days / 365) + frequency = (years, "yr") + elif dt.days >= 28: + months = round(dt.days / 30) + frequency = (months, "mon") + elif dt.days >= 1: + frequency = (dt.days, "day") + elif dt.seconds >= 3600: + hours = round(dt.seconds / 3600) + frequency = (hours, "hr") + else: + frequency = (None, "subhr") + + if filename_frequency: + if filename_frequency != frequency: + msg = ( + f"The frequency '{filename_frequency}' determined from filename does not " + f"match the frequency '{frequency}' determined from the file contents." + ) + if frequency == FREQUENCY_STATIC: + frequency = filename_frequency + warnings.warn(f"{msg} Using '{frequency}'.") + + if has_time & (frequency != FREQUENCY_STATIC): + if not has_bounds: + ts, te = GenericTimeParser._guess_start_end_dates(ts, te, frequency) + + if ts is None: + start_date = "none" + else: + start_date = ts.strftime(time_format) + + if te is None: + end_date = "none" + else: + end_date = te.strftime(time_format) + + if frequency[0]: + frequency = f"{str(frequency[0])}{frequency[1]}" + else: + frequency = frequency[1] + + return start_date, end_date, frequency + + def __call__(self) -> tuple[str, str, str]: + return self._get_timeinfo() + + +class AccessTimeParser(GenericTimeParser): + pass + + +class GfdlTimeParser(GenericTimeParser): + def __init__(self, ds: xr.Dataset, filename_frequency: str | None, time_dim: str): + self.ds = ds + self.filename_frequency = filename_frequency + self.time_dim = time_dim + + def _get_timeinfo(self) -> tuple[str, str, str]: + """ + Get start date, end date and frequency of a xarray dataset. Stolen and adapted from the + cosima cookbook, see + https://github.com/COSIMA/cosima-cookbook/blob/master/cosima_cookbook/database.py#L565 + + Parameters + ---------- + ds: :py:class:`xarray.Dataset` + The dataset to parse the time info from + filename_frequency: str + Frequency as determined from the filename + time_dim: str + The name of the time dimension + + Returns + ------- + start_date: str + The start date of the dataset + end_date: str + The end date of the dataset + frequency: str + The frequency of the dataset + + Raises + ------ + EmptyFileError + If the dataset has a valid unlimited dimension, but no data + """ + + ds = self.ds + filename_frequency = self.filename_frequency + time_dim = self.time_dim + + def _todate(t): + return cftime.num2date(t, time_var.units, calendar=time_var.calendar) + + time_format = "%Y-%m-%d, %H:%M:%S" + ts = None + te = None + frequency: str | tuple[int | None, str] = FREQUENCY_STATIC + has_time = time_dim in ds + + if has_time: + time_var = ds[time_dim] + + if len(time_var) == 0: + raise EmptyFileError( + "This file has a valid unlimited dimension, but no data" + ) + + ts = _todate(time_var[0]) + te = _todate(time_var[-1]) + + if len(time_var) > 1: + t1 = _todate(time_var[1]) + + dt = t1 - ts + # TODO: This is not a very good way to get the frequency + if dt.days >= 365: + years = round(dt.days / 365) + frequency = (years, "yr") + elif dt.days >= 28: + months = round(dt.days / 30) + frequency = (months, "mon") + elif dt.days >= 1: + frequency = (dt.days, "day") + elif dt.seconds >= 3600: + hours = round(dt.seconds / 3600) + frequency = (hours, "hr") + else: + frequency = (None, "subhr") + + if filename_frequency: + if filename_frequency != frequency: + msg = ( + f"The frequency '{filename_frequency}' determined from filename does not " + f"match the frequency '{frequency}' determined from the file contents." + ) + if frequency == FREQUENCY_STATIC: + frequency = filename_frequency + warnings.warn(f"{msg} Using '{frequency}'.") + + if has_time & (frequency != FREQUENCY_STATIC): + ts, te = GenericTimeParser._guess_start_end_dates(ts, te, frequency) + + if ts is None: + start_date = "none" + else: + start_date = ts.strftime(time_format) + + if te is None: + end_date = "none" + else: + end_date = te.strftime(time_format) + + if frequency[0]: + frequency = f"{str(frequency[0])}{frequency[1]}" + else: + frequency = frequency[1] + + return start_date, end_date, frequency + + def __call__(self) -> tuple[str, str, str]: + return self._get_timeinfo() diff --git a/tests/test_builders.py b/tests/test_builders.py index 0ed3c5d4..ea820e63 100644 --- a/tests/test_builders.py +++ b/tests/test_builders.py @@ -13,7 +13,7 @@ from intake_esm.utils import OPTIONS from access_nri_intake.source import CORE_COLUMNS, builders -from access_nri_intake.source.utils import _AccessNCFileInfo +from access_nri_intake.source.utils import _NCFileInfo @pytest.mark.parametrize( @@ -224,7 +224,7 @@ def test_builder_parser(test_data, filename, builder, realm, member, file_id): assert info["file_id"] == file_id -@mock.patch("access_nri_intake.source.utils._AccessNCFileInfo.to_dict") +@mock.patch("access_nri_intake.source.utils._NCFileInfo.to_dict") @pytest.mark.parametrize( "filename", [ @@ -759,8 +759,8 @@ def test_builder_columns_with_iterables(test_data): ), ], ) -def test_parse_access_filename(builder, filename, expected): - assert builder.parse_access_filename(filename) == expected +def test_parse_filename(builder, filename, expected): + assert builder.parse_filename(filename) == expected @pytest.mark.parametrize( @@ -776,7 +776,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm2Builder, "access-om2/output000/ocean/ocean_grid.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="ocean_grid.nc", file_id="ocean_grid", @@ -799,7 +799,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm2Builder, "access-om2/output000/ocean/ocean.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="ocean.nc", file_id="ocean", @@ -849,7 +849,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm2Builder, "access-om2/output000/ocean/ocean_month.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="ocean_month.nc", file_id="ocean_month", @@ -888,7 +888,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm2Builder, "access-om2/output000/ocean/ocean_month_inst_nobounds.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="ocean_month_inst_nobounds.nc", file_id="ocean_month_inst_nobounds", @@ -921,7 +921,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm2Builder, "access-om2/output000/ice/OUTPUT/iceh.1900-01.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="iceh.1900-01.nc", file_id="iceh_XXXX_XX", @@ -953,7 +953,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessCm2Builder, "access-cm2/by578/history/atm/netCDF/by578a.pd201501_dai.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="by578a.pd201501_dai.nc", file_id="by578a_pdXXXXXX_dai", @@ -971,7 +971,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessCm2Builder, "access-cm2/by578/history/ice/iceh_d.2015-01.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="iceh_d.2015-01.nc", file_id="iceh_d_XXXX_XX", @@ -1003,7 +1003,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessCm2Builder, "access-cm2/by578/history/ocn/ocean_daily.nc-20150630", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="ocean_daily.nc-20150630", file_id="ocean_daily", @@ -1035,7 +1035,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessCm2Builder, "access-cm2/by578/history/ocn/ocean_scalar.nc-20150630", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="ocean_scalar.nc-20150630", file_id="ocean_scalar", @@ -1077,7 +1077,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessEsm15Builder, "access-esm1-5/history/atm/netCDF/HI-C-05-r1.pa-185001_mon.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="HI-C-05-r1.pa-185001_mon.nc", file_id="HI_C_05_r1_pa_XXXXXX_mon", @@ -1095,7 +1095,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessEsm15Builder, "access-esm1-5/history/ice/iceh.1850-01.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="iceh.1850-01.nc", file_id="iceh_XXXX_XX", @@ -1127,7 +1127,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessEsm15Builder, "access-esm1-5/history/ocn/ocean_bgc_ann.nc-18501231", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="ocean_bgc_ann.nc-18501231", file_id="ocean_bgc_ann", @@ -1166,7 +1166,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessEsm15Builder, "access-esm1-5/history/ocn/ocean_bgc.nc-18501231", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="ocean_bgc.nc-18501231", file_id="ocean_bgc", @@ -1208,7 +1208,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm3Builder, "access-om3/output000/GMOM_JRA_WD.mom6.h.native_1900_01.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="GMOM_JRA_WD.mom6.h.native_1900_01.nc", file_id="GMOM_JRA_WD_mom6_h_native_XXXX_XX", @@ -1281,7 +1281,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm3Builder, "access-om3/output000/GMOM_JRA_WD.mom6.h.sfc_1900_01_02.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="GMOM_JRA_WD.mom6.h.sfc_1900_01_02.nc", file_id="GMOM_JRA_WD_mom6_h_sfc_XXXX_XX_XX", @@ -1349,7 +1349,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm3Builder, "access-om3/output000/GMOM_JRA_WD.mom6.h.static.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="GMOM_JRA_WD.mom6.h.static.nc", file_id="GMOM_JRA_WD_mom6_h_static", @@ -1377,7 +1377,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm3Builder, "access-om3/output000/GMOM_JRA_WD.mom6.h.z_1900_01.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="GMOM_JRA_WD.mom6.h.z_1900_01.nc", file_id="GMOM_JRA_WD_mom6_h_z_XXXX_XX", @@ -1450,7 +1450,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm3Builder, "access-om3/output000/GMOM_JRA_WD.cice.h.1900-01-01.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="GMOM_JRA_WD.cice.h.1900-01-01.nc", file_id="GMOM_JRA_WD_cice_h_XXXX_XX_XX", @@ -1482,7 +1482,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.AccessOm3Builder, "access-om3/output000/GMOM_JRA_WD.ww3.hi.1900-01-02-00000.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="GMOM_JRA_WD.ww3.hi.1900-01-02-00000.nc", file_id="GMOM_JRA_WD_ww3_hi_XXXX_XX_XX_XXXXX", @@ -1500,14 +1500,14 @@ def test_parse_access_filename(builder, filename, expected): ( builders.Mom6Builder, "mom6/output000/19000101.ice_daily.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="19000101.ice_daily.nc", file_id="XXXXXXXX_ice_daily", filename_timestamp="19000101", - frequency="subhr", + frequency="1day", start_date="1900-01-01, 00:00:00", - end_date="1900-01-01, 00:00:00", + end_date="1901-01-01, 00:00:00", variable=[ "xT", "xTe", @@ -1583,14 +1583,14 @@ def test_parse_access_filename(builder, filename, expected): ( builders.Mom6Builder, "mom6/output000/19000101.ocean_annual_z.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="19000101.ocean_annual_z.nc", file_id="XXXXXXXX_ocean_annual_z", filename_timestamp="19000101", - frequency="subhr", + frequency="1yr", start_date="1900-01-01, 00:00:00", - end_date="1900-01-01, 00:00:00", + end_date="1901-01-01, 00:00:00", variable=[ "xh", "yh", @@ -1746,14 +1746,14 @@ def test_parse_access_filename(builder, filename, expected): ( builders.Mom6Builder, "mom6/output000/19000101.ocean_month_rho2.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="19000101.ocean_month_rho2.nc", file_id="XXXXXXXX_ocean_month_rho2", filename_timestamp="19000101", - frequency="subhr", + frequency="1mon", start_date="1900-01-01, 00:00:00", - end_date="1900-01-01, 00:00:00", + end_date="1901-01-01, 00:00:00", variable=[ "xh", "yh", @@ -1839,14 +1839,14 @@ def test_parse_access_filename(builder, filename, expected): ( builders.Mom6Builder, "mom6/output000/19000101.ocean_scalar_annual.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="19000101.ocean_scalar_annual.nc", file_id="XXXXXXXX_ocean_scalar_annual", filename_timestamp="19000101", - frequency="subhr", + frequency="1yr", start_date="1900-01-01, 00:00:00", - end_date="1900-01-01, 00:00:00", + end_date="1901-01-01, 00:00:00", variable=[ "scalar_axis", "time", @@ -1922,7 +1922,7 @@ def test_parse_access_filename(builder, filename, expected): ( builders.Mom6Builder, "mom6/output000/19000101.ocean_static.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="19000101.ocean_static.nc", file_id="XXXXXXXX_ocean_static", @@ -2100,14 +2100,14 @@ def test_parse_access_filename(builder, filename, expected): ( builders.Mom6Builder, "mom6/output053/20051101.ocean_daily_2005_360.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="20051101.ocean_daily_2005_360.nc", file_id="XXXXXXXX_ocean_daily_XXXX_XXX", filename_timestamp="20051101", - frequency="subhr", - start_date="1991-01-01, 00:00:00", - end_date="1991-01-01, 00:00:00", + frequency="1day", + start_date="2005-12-26, 00:00:00", + end_date="2005-12-27, 00:00:00", variable=[ "xh", "yh", @@ -2233,14 +2233,14 @@ def test_parse_access_filename(builder, filename, expected): ( builders.Mom6Builder, "mom6/output053/20051101.ocean_daily_rho2_2005_360.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="20051101.ocean_daily_rho2_2005_360.nc", file_id="XXXXXXXX_ocean_daily_rho2_XXXX_XXX", filename_timestamp="20051101", - frequency="subhr", - start_date="1991-01-01, 00:00:00", - end_date="1991-01-01, 00:00:00", + frequency="1day", + start_date="2005-12-26, 00:00:00", + end_date="2005-12-27, 00:00:00", variable=[ "xh", "yh", @@ -2331,14 +2331,14 @@ def test_parse_access_filename(builder, filename, expected): ( builders.Mom6Builder, "mom6/output053/20051101.ocean_daily_z_2005_360.nc", - _AccessNCFileInfo( + _NCFileInfo( path=None, # type: ignore filename="20051101.ocean_daily_z_2005_360.nc", file_id="XXXXXXXX_ocean_daily_z_XXXX_XXX", filename_timestamp="20051101", - frequency="subhr", - start_date="1991-01-01, 00:00:00", - end_date="1991-01-01, 00:00:00", + frequency="1day", + start_date="2005-12-26, 00:00:00", + end_date="2005-12-27, 00:00:00", variable=[ "xh", "yh", @@ -2456,7 +2456,7 @@ def test_parse_access_ncfile(test_data, builder, filename, expected, compare_fil # Set the path to the test data directory expected.path = file - assert builder.parse_access_ncfile(file) == expected + assert builder.parse_ncfile(file) == expected if not compare_files: return None diff --git a/tests/test_source_utils.py b/tests/test_source_utils.py index 419a9f44..f7628f49 100644 --- a/tests/test_source_utils.py +++ b/tests/test_source_utils.py @@ -4,7 +4,13 @@ import pytest import xarray as xr -from access_nri_intake.source.utils import get_timeinfo +from access_nri_intake.source.utils import ( + AccessTimeParser, + EmptyFileError, + GenericTimeParser, + GfdlTimeParser, + get_timeinfo, +) @pytest.mark.parametrize( @@ -142,3 +148,276 @@ def test_get_timeinfo(times, bounds, ffreq, expected): ) assert get_timeinfo(ds, filename_frequency=ffreq, time_dim="time") == expected + + +@pytest.mark.parametrize( + "times, bounds, ffreq, expected", + [ + ( + [365 / 2], + False, + (1, "yr"), + ("1900-01-01, 00:00:00", "1901-01-01, 00:00:00", "1yr"), + ), + ( + [31 / 2], + False, + (1, "mon"), + ("1900-01-01, 00:00:00", "1900-02-01, 00:00:00", "1mon"), + ), + ( + [1.5 / 24], + False, + (3, "hr"), + ("1900-01-01, 00:00:00", "1900-01-01, 03:00:00", "3hr"), + ), + ( + [0.0, 9 / 60 / 24], + True, + None, + ("1900-01-01, 00:00:00", "1900-01-01, 00:09:00", "subhr"), + ), + ( + [0.0, 3 / 24], + True, + None, + ("1900-01-01, 00:00:00", "1900-01-01, 03:00:00", "3hr"), + ), + ( + [0.0, 6 / 24], + True, + None, + ("1900-01-01, 00:00:00", "1900-01-01, 06:00:00", "6hr"), + ), + ( + [0.0, 1.0], + True, + None, + ("1900-01-01, 00:00:00", "1900-01-02, 00:00:00", "1day"), + ), + ( + [0.0, 31.0], + True, + None, + ("1900-01-01, 00:00:00", "1900-02-01, 00:00:00", "1mon"), + ), + ( + [0.0, 90.0], + True, + None, + ("1900-01-01, 00:00:00", "1900-04-01, 00:00:00", "3mon"), + ), + ( + [0.0, 365.0], + True, + None, + ("1900-01-01, 00:00:00", "1901-01-01, 00:00:00", "1yr"), + ), + ( + [0.0, 730.0], + True, + None, + ("1900-01-01, 00:00:00", "1902-01-01, 00:00:00", "2yr"), + ), + ( + [1.5 / 24, 4.5 / 24], + False, + None, + ("1900-01-01, 00:00:00", "1900-01-01, 06:00:00", "3hr"), + ), + ( + [3 / 24, 9 / 24], + False, + None, + ("1900-01-01, 00:00:00", "1900-01-01, 12:00:00", "6hr"), + ), + ( + [0.5, 1.5], + False, + None, + ("1900-01-01, 00:00:00", "1900-01-03, 00:00:00", "1day"), + ), + ( + [31 / 2, 45], + False, + None, + ("1900-01-01, 00:00:00", "1900-03-01, 00:00:00", "1mon"), + ), + ( + [45, 135.5], + False, + None, + ("1900-01-01, 00:00:00", "1900-07-01, 00:00:00", "3mon"), + ), + ( + [365 / 2, 365 + 365 / 2], + False, + None, + ("1900-01-01, 00:00:00", "1902-01-01, 00:00:00", "1yr"), + ), + ( + [365, 3 * 365], + False, + None, + ("1900-01-01, 00:00:00", "1904-01-01, 00:00:00", "2yr"), + ), + ], +) +@pytest.mark.parametrize( + "parser", + [AccessTimeParser, GenericTimeParser], +) +def test_generic_time_parser(times, bounds, ffreq, expected, parser): + if bounds: + time = (times[0] + times[1]) / 2 + ds = xr.Dataset( + data_vars={ + "dummy": ("time", [0]), + "time_bounds": (("time", "nv"), [(times[0], times[1])]), + }, + coords={"time": [time]}, + ) + ds["time"].attrs = dict(bounds="time_bounds") + else: + ds = xr.Dataset( + data_vars={"dummy": ("time", [0] * len(times))}, + coords={"time": times}, + ) + + ds["time"].attrs |= dict( + units="days since 1900-01-01 00:00:00", calendar="GREGORIAN" + ) + + assert parser(ds, filename_frequency=ffreq, time_dim="time")() == expected + + +@pytest.mark.parametrize( + "parser", + [AccessTimeParser, GenericTimeParser], +) +def test_generic_time_parser_warnings(parser): + times = [1.5 / 24 / 60] + ffreq = (3, "s") + + ds = xr.Dataset( + data_vars={"dummy": ("time", [0] * len(times))}, + coords={"time": times}, + ) + + ds["time"].attrs |= dict( + units="days since 1900-01-01 00:00:00", calendar="GREGORIAN" + ) + + with pytest.warns( + match="Cannot infer start and end times for subhourly frequencies." + ): + parser(ds, filename_frequency=ffreq, time_dim="time")._guess_start_end_dates( + 0, 1, (1, "s") + ) + + +@pytest.mark.parametrize( + "parser", + [AccessTimeParser, GenericTimeParser, GfdlTimeParser], +) +def test_generic_empty_file_error(parser): + times = [] + ffreq = (3, "hr") + + ds = xr.Dataset( + data_vars={"dummy": ("time", [])}, + coords={"time": times}, + ) + + ds["time"].attrs |= dict( + units="days since 1900-01-01 00:00:00", calendar="GREGORIAN" + ) + + with pytest.raises(EmptyFileError): + parser(ds, filename_frequency=ffreq, time_dim="time")() + + +@pytest.mark.parametrize( + "times, ffreq, expected", + [ + ( + [365 / 2], + (1, "yr"), + ("1900-01-01, 00:00:00", "1901-01-01, 00:00:00", "1yr"), + ), + ( + [31 / 2], + (1, "mon"), + ("1900-01-01, 00:00:00", "1900-02-01, 00:00:00", "1mon"), + ), + ( + [1.5 / 24], + (3, "hr"), + ("1900-01-01, 00:00:00", "1900-01-01, 03:00:00", "3hr"), + ), + ( + [1.5 / 24, 4.5 / 24], + None, + ("1900-01-01, 00:00:00", "1900-01-01, 06:00:00", "3hr"), + ), + ( + [3 / 24, 9 / 24], + None, + ("1900-01-01, 00:00:00", "1900-01-01, 12:00:00", "6hr"), + ), + ( + [0.5, 1.5], + None, + ("1900-01-01, 00:00:00", "1900-01-03, 00:00:00", "1day"), + ), + ( + [31 / 2, 45], + None, + ("1900-01-01, 00:00:00", "1900-03-01, 00:00:00", "1mon"), + ), + ( + [45, 135.5], + None, + ("1900-01-01, 00:00:00", "1900-07-01, 00:00:00", "3mon"), + ), + ( + [365 / 2, 365 + 365 / 2], + None, + ("1900-01-01, 00:00:00", "1902-01-01, 00:00:00", "1yr"), + ), + ( + [365, 3 * 365], + None, + ("1900-01-01, 00:00:00", "1904-01-01, 00:00:00", "2yr"), + ), + ( + [365 / 86400 / 720, 365 / 86400 / 360], # 1/2 second, 1 second + None, + ("1900-01-01, 00:00:00", "1900-01-01, 00:00:01", "subhr"), + ), + ], +) +def test_gfdl_time_parser(times, ffreq, expected): + ds = xr.Dataset( + data_vars={"dummy": ("time", [0] * len(times))}, + coords={"time": times}, + ) + + ds["time"].attrs |= dict( + units="days since 1900-01-01 00:00:00", calendar="GREGORIAN" + ) + + assert GfdlTimeParser(ds, filename_frequency=ffreq, time_dim="time")() == expected + + +def test_gfdl_parser_notime(): + ds = xr.Dataset( + data_vars={"dummy": ("latitude", [0])}, + coords={"latitude": [0]}, + ) + + assert GfdlTimeParser(ds, filename_frequency=None, time_dim="time")() == ( + "none", + "none", + "fx", + ) diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..18a7bbf4 --- /dev/null +++ b/tox.ini @@ -0,0 +1,48 @@ +[tox] +envlist = + py{310,311,312,313} + +[testenv] +setenv = + PYTHONPATH = {toxinidir} + +deps = + pytest + +commands = + pip install pytest-random-order + pip install . + pytest --random-order tests + +basepython = + py310: python3.10 + py311: python3.11 + py312: python3.12 + py313: python3.13 + +[testenv:py310] +conda_env = ci/environment-3.10.yml + +[testenv:py311] +conda_env = ci/environment-3.11.yml + +[testenv:py312] +conda_env = ci/environment-3.12.yml + +[testenv:py313] +conda_env = ci/environment-3.13.yml + + +; 310: All Passed + +; 311: 1 failed +; [FAILED tests/test_builders.py::test_builder_build[basedirs4-Mom6Builder-kwargs4-27-27-15] - AssertionError: assert 26 == 27 +; FAILED tests/test_builders.py::test_builder_parser[mom6/output000/19000101.ice_daily.nc-Mom6Builder-seaIce-None-XXXXXXXX_ice_daily] - KeyError: 'realm' +; FAILED tests/test_builders.py::test_builder_parser[mom6/output000/19000101.ocean_daily.nc-Mom6Builder-ocean-None-XXXXXXXX_ocean_daily] - KeyError: 'realm' +; 3 failed + +; 312 1 failed +; FAILED tests/test_builders.py::test_parse_access_ncfile[Mom6Builder-mom6/output000/19000101.ocean_annual_z.nc-expected20-False] - AssertionError: assert _AccessNCFile...ays', 'days']) == _AccessNCFile...ays', 'days']) +; 1 failed, + +; 313: All Passed From 44ad1bf67c32924ed5c673ab40b879686e2fd089 Mon Sep 17 00:00:00 2001 From: Charles Turner <52199577+charles-turner-1@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:42:43 +0800 Subject: [PATCH 2/8] 257 replace mocks (#291) * Removed lots of mocks from tests where not needed. * Replaced lots of call to os module with pathlib (#271) Co-authored-by: Marc White --------- Co-authored-by: Marc White Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/access_nri_intake/catalog/manager.py | 8 +- src/access_nri_intake/cli.py | 19 +- tests/test_cli.py | 719 +++++++++++------------ tests/test_manager.py | 72 ++- 4 files changed, 404 insertions(+), 414 deletions(-) diff --git a/src/access_nri_intake/catalog/manager.py b/src/access_nri_intake/catalog/manager.py index d4ba93cf..47982366 100644 --- a/src/access_nri_intake/catalog/manager.py +++ b/src/access_nri_intake/catalog/manager.py @@ -4,6 +4,7 @@ """Manager for adding/updating intake sources in an intake-dataframe-catalog like the ACCESS-NRI catalog""" import os +from pathlib import Path import intake from intake_dataframe_catalog.core import DfFileCatalog, DfFileCatalogError @@ -32,7 +33,7 @@ class CatalogManager: Add/update intake sources in an intake-dataframe-catalog like the ACCESS-NRI catalog """ - def __init__(self, path: str): + def __init__(self, path: Path | str): """ Initialise a CatalogManager instance to add/update intake sources in a intake-dataframe-catalog like the ACCESS-NRI catalog @@ -42,10 +43,11 @@ def __init__(self, path: str): path: str The path to the intake-dataframe-catalog """ + path = Path(path) - self.path = path + self.path = str(path) - self.mode = "a" if os.path.exists(path) else "w" + self.mode = "a" if path.exists() else "w" try: self.dfcat = DfFileCatalog( diff --git a/src/access_nri_intake/cli.py b/src/access_nri_intake/cli.py index 1d30be30..a9ef369b 100644 --- a/src/access_nri_intake/cli.py +++ b/src/access_nri_intake/cli.py @@ -406,9 +406,20 @@ def metadata_validate(argv: Sequence[str] | None = None): raise FileNotFoundError(f"No such file(s): {f}") -def metadata_template(loc=None): +def metadata_template(loc: str | Path | None = None) -> None: """ - Create an empty template for a metadata.yaml file using the experiment schema + Create an empty template for a metadata.yaml file using the experiment schema. + + Writes the template to the current working directory by default. + + Parameters: + ----- + loc (str, Path, optional): The directory in which to save the template. + Defaults to the current working directory. + + Returns: + ----- + None """ if loc is None: @@ -424,9 +435,9 @@ def metadata_template(loc=None): description = f"<{descr['description']}>" if _can_be_array(descr): - description = [description] + description = [description] # type: ignore template[name] = description - with open(os.path.join(loc, "metadata.yaml"), "w") as outfile: + with open((Path(loc) / "metadata.yaml"), "w") as outfile: yaml.dump(template, outfile, default_flow_style=False, sort_keys=False) diff --git a/tests/test_cli.py b/tests/test_cli.py index 8617336a..65692dfa 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,7 +1,6 @@ # Copyright 2023 ACCESS-NRI and contributors. See the top-level COPYRIGHT file for details. # SPDX-License-Identifier: Apache-2.0 -import argparse import glob import os import shutil @@ -192,82 +191,86 @@ def test_build_bad_version(bad_vers, test_data, tmp_path): ) -@mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2-bad.yaml", - "config/cmip5.yaml", - ], - build_base_path=None, # Use pytest fixture here? - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file="cat.csv", - version="v2024-01-01", - no_update=False, - ), -) -def test_build_bad_metadata(mockargs, get_catalog_fp, test_data, tmp_path): +def test_build_bad_metadata(test_data, tmp_path): """ Test if bad metadata is detected """ - # Update the config_yaml paths - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data - mockargs.return_value.build_base_path = str(tmp_path) - # Write the catalog.yamls to where the catalogs go - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "catalog.yaml" - ) + configs = [ + str(test_data / "config/access-om2-bad.yaml"), + str(test_data / "config/cmip5.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) with pytest.raises(MetadataCheckError): - build() + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + "v2024-01-01", + "--no_update", + ] + ) -@mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2.yaml", - "config/cmip5.yaml", - ], - build_base_path="", # Use pytest fixture here? - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file="cat.csv", - version="v2024-01-01", - no_update=False, - ), -) -def test_build_repeat_nochange(mockargs, get_catalog_fp, test_data, tmp_path): +def test_build_repeat_nochange(test_data, tmp_path): """ Test if the intelligent versioning works correctly when there is no significant change to the underlying catalogue """ - # Update the config_yaml paths - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data - mockargs.return_value.build_base_path = str(tmp_path) + configs = [ + str(test_data / "config/access-om2.yaml"), + str(test_data / "config/cmip5.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) - # Write the catalog.yamls to where the catalogs go - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "catalog.yaml" + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + "v2024-01-01", + ] ) - build() - # Update the version number and have another crack at building - mockargs.return_value.version = "v2024-01-02" - build() + NEW_VERSION = "v2024-01-02" + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + NEW_VERSION, + ] + ) # There is no change between catalogs, so we should be able to # see just a version number change in the yaml - with Path(get_catalog_fp.return_value).open(mode="r") as fobj: + with (tmp_path / "catalog.yaml").open(mode="r") as fobj: cat_yaml = yaml.safe_load(fobj) assert ( @@ -284,47 +287,52 @@ def test_build_repeat_nochange(mockargs, get_catalog_fp, test_data, tmp_path): ), f'Default version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default")} does not match expected v2024-01-02' -@mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2.yaml", - # "config/cmip5.yaml", # Save this for addition - ], - build_base_path=None, # Use pytest fixture here? - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file="cat.csv", - version="v2024-01-01", - no_update=False, - ), -) -def test_build_repeat_adddata(mockargs, get_catalog_fp, test_data, tmp_path): - # Update the config_yaml paths - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data - mockargs.return_value.build_base_path = str(tmp_path) +def test_build_repeat_adddata(test_data, tmp_path): + configs = [ + str(test_data / "config/access-om2.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) - # Write the catalog.yamls to where the catalogs go - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "catalog.yaml" + # Build the first catalog + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + "v2024-01-01", + ] ) - # Build the first catalog - build() + configs.append(str(test_data / "config/cmip5.yaml")) + NEW_VERSION = "v2024-01-02" - # Now, add the second data source & rebuild - mockargs.return_value.config_yaml.append( - os.path.join(test_data, "config/cmip5.yaml") + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + NEW_VERSION, + ] ) - mockargs.return_value.version = "v2024-01-02" - build() # There is no change between catalogs, so we should be able to # see just a version number change in the yaml - with Path(get_catalog_fp.return_value).open(mode="r") as fobj: + with Path(tmp_path / "catalog.yaml").open(mode="r") as fobj: cat_yaml = yaml.safe_load(fobj) assert ( @@ -342,22 +350,6 @@ def test_build_repeat_adddata(mockargs, get_catalog_fp, test_data, tmp_path): assert cat_yaml["sources"]["access_nri"]["metadata"]["storage"] == "gdata/al33" -@mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2.yaml", - "config/cmip5.yaml", - ], - build_base_path=None, - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file="cat.csv", - version="v2024-01-01", - no_update=False, - ), -) @pytest.mark.parametrize( "min_vers,max_vers", [ @@ -366,71 +358,57 @@ def test_build_repeat_adddata(mockargs, get_catalog_fp, test_data, tmp_path): ("v2001-01-01", None), ], ) -def test_build_existing_data( - mockargs, get_catalog_fp, test_data, min_vers, max_vers, tmp_path -): +def test_build_existing_data(test_data, min_vers, max_vers, tmp_path): """ Test if the build process can handle min and max catalog versions when an original catalog.yaml does not exist """ - # New temp directory for each test - mockargs.return_value.build_base_path = str(tmp_path) # Use pytest fixture here? - # Update the config_yaml paths - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data - - # Write the catalog.yamls to where the catalogs go - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "catalog.yaml" - ) + configs = [ + str(test_data / "config/access-om2.yaml"), + str(test_data / "config/cmip5.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) + VERSION = "v2024-01-01" # Put dummy version folders into the tempdir if min_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, min_vers), - exist_ok=False, - ) + (tmp_path / min_vers).mkdir(parents=True, exist_ok=False) if max_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, max_vers), - exist_ok=False, - ) + (tmp_path / max_vers).mkdir(parents=True, exist_ok=False) - build() + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + VERSION, + ] + ) - with Path(get_catalog_fp.return_value).open(mode="r") as fobj: + with (tmp_path / "catalog.yaml").open(mode="r") as fobj: cat_yaml = yaml.safe_load(fobj) assert cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min") == ( - min_vers if min_vers is not None else mockargs.return_value.version - ), f'Min version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min")} does not match expected {min_vers if min_vers is not None else mockargs.return_value.version}' + min_vers if min_vers is not None else VERSION + ), f'Min version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min")} does not match expected {min_vers if min_vers is not None else VERSION}' assert cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max") == ( - max_vers if max_vers is not None else mockargs.return_value.version - ), f'Max version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max")} does not match expected {max_vers if max_vers is not None else mockargs.return_value.version}' + max_vers if max_vers is not None else VERSION + ), f'Max version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max")} does not match expected {max_vers if max_vers is not None else VERSION}' # Default should always be the newly-built version assert ( cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default") - == mockargs.return_value.version - ), f'Default version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default")} does not match expected {mockargs.return_value.version}' + == VERSION + ), f'Default version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default")} does not match expected {VERSION}' -@mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2.yaml", - "config/cmip5.yaml", - ], - build_base_path=None, - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file="cat.csv", - version="v2024-01-01", - no_update=False, - ), -) @pytest.mark.parametrize( "min_vers,max_vers", [ @@ -439,56 +417,58 @@ def test_build_existing_data( ("v2001-01-01", None), ], ) -def test_build_existing_data_existing_old_cat( - mockargs, get_catalog_fp, test_data, min_vers, max_vers, tmp_path -): +def test_build_existing_data_existing_old_cat(test_data, min_vers, max_vers, tmp_path): """ Test if the build process can handle min and max catalog versions when a old-style catalog.yaml exists """ - # New temp directory for each test - mockargs.return_value.build_base_path = str(tmp_path) # Use pytest fixture here? - # Update the config_yaml paths - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data - - # Write the catalog.yamls to where the catalogs go - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "catalog.yaml" - ) + configs = [ + str(test_data / "config/access-om2.yaml"), + str(test_data / "config/cmip5.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) + VERSION = "v2024-01-01" # Put dummy version folders into the tempdir if min_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, min_vers), - exist_ok=False, - ) + (tmp_path / min_vers).mkdir(parents=True, exist_ok=False) if max_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, max_vers), - exist_ok=False, - ) + (tmp_path / max_vers).mkdir(parents=True, exist_ok=False) # Copy the test data old-style catalog yaml to this location - shutil.copy(test_data / "catalog/catalog-orig.yaml", get_catalog_fp.return_value) + shutil.copy(test_data / "catalog/catalog-orig.yaml", str(tmp_path / "catalog.yaml")) - build() + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + "v2024-01-01", + ] + ) - with Path(get_catalog_fp.return_value).open(mode="r") as fobj: + with (tmp_path / "catalog.yaml").open(mode="r") as fobj: cat_yaml = yaml.safe_load(fobj) assert cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min") == ( - min_vers if min_vers is not None else mockargs.return_value.version - ), f'Min version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min")} does not match expected {min_vers if min_vers is not None else mockargs.return_value.version}' + min_vers if min_vers is not None else VERSION + ), f'Min version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min")} does not match expected {min_vers if min_vers is not None else VERSION}' assert cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max") == ( - max_vers if max_vers is not None else mockargs.return_value.version - ), f'Max version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max")} does not match expected {max_vers if max_vers is not None else mockargs.return_value.version}' + max_vers if max_vers is not None else VERSION + ), f'Max version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max")} does not match expected {max_vers if max_vers is not None else VERSION}' # Default should always be the newly-built version assert ( cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default") - == mockargs.return_value.version - ), f'Default version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default")} does not match expected {mockargs.return_value.version}' + == VERSION + ), f'Default version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default")} does not match expected {VERSION}' # Make sure the catalog storage flags were correctly merged assert ( cat_yaml["sources"]["access_nri"]["metadata"]["storage"] @@ -496,26 +476,10 @@ def test_build_existing_data_existing_old_cat( ) # Make sure the old catalog vanished (i.e. there's only one) assert ( - len(glob.glob(mockargs.return_value.build_base_path + "/*.yaml")) == 1 + len(glob.glob(build_base_path + "/*.yaml")) == 1 ), "Found more than one catalog remains!" -@mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2.yaml", - "config/cmip5.yaml", - ], - build_base_path=None, # Use pytest fixture here? - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file="cat.csv", - version="v2024-01-01", - no_update=False, - ), -) @pytest.mark.parametrize( "min_vers,max_vers", [ @@ -525,77 +489,69 @@ def test_build_existing_data_existing_old_cat( ], ) def test_build_separation_between_catalog_and_buildbase( - mockargs, get_catalog_fp, test_data, min_vers, max_vers, tmp_path + test_data, min_vers, max_vers, tmp_path ): """ Test if the intelligent versioning works correctly when there is no significant change to the underlying catalogue """ - bbp = os.path.join(tmp_path, "bbp") - os.mkdir(bbp) - catdir = os.path.join(tmp_path, "catdir") - os.mkdir(catdir) - mockargs.return_value.build_base_path = str(bbp) - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data + + configs = [ + str(test_data / "config/access-om2.yaml"), + str(test_data / "config/cmip5.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) + VERSION = "v2024-01-01" + + bbp, catdir = tmp_path / "bbp", tmp_path / "catdir" + bbp.mkdir(parents=True), catdir.mkdir(parents=True) # Write the catalog.yamls to its own directory - catalog_dir = str(catdir) - mockargs.return_value.catalog_base_path = catalog_dir - get_catalog_fp.return_value = os.path.join(catalog_dir, "catalog.yaml") + catalog_fp = Path(catdir) / "catalog.yaml" # Create dummy version folders in the *catalog* directory # (They would normally be in the build directory) if min_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.catalog_base_path, min_vers), - exist_ok=False, - ) + (catdir / min_vers).mkdir(parents=True, exist_ok=False) if max_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.catalog_base_path, max_vers), - exist_ok=False, - ) + (catdir / max_vers).mkdir(parents=True, exist_ok=False) - build() + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + str(catdir), + "--version", + VERSION, + ] + ) # The version folders exist in the catalog directory, not the build # directory, hence they shouldn't have been found - therefore, # all the version numbers should align with the newly-built catalog - with Path(get_catalog_fp.return_value).open(mode="r") as fobj: + with catalog_fp.open(mode="r") as fobj: cat_yaml = yaml.safe_load(fobj) assert ( - cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min") - == "v2024-01-01" + cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min") == VERSION ), f'Min version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("min")} does not match expected v2024-01-01' assert ( - cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max") - == "v2024-01-01" + cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max") == VERSION ), f'Max version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("max")} does not match expected v2024-01-01' assert ( cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default") - == "v2024-01-01" + == VERSION ), f'Default version {cat_yaml["sources"]["access_nri"]["parameters"]["version"].get("default")} does not match expected v2024-01-01' @mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2.yaml", - # "config/cmip5.yaml", # Save this for addition - ], - build_base_path=None, # Use pytest fixture here? - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file="cat.csv", - version="v2024-01-01", - no_update=False, - ), -) @pytest.mark.parametrize( "min_vers,max_vers", [ @@ -605,57 +561,67 @@ def test_build_separation_between_catalog_and_buildbase( ], ) def test_build_repeat_renamecatalogyaml( - mockargs, get_catalog_fp, test_data, min_vers, max_vers, tmp_path + get_catalog_fp, test_data, min_vers, max_vers, tmp_path ): - # Update the config_yaml paths - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data - - mockargs.return_value.build_base_path = str(tmp_path) - mockargs.return_value.version = ( - "v2024-01-01" # May have been overridden in previous parametrize pass - ) + configs = [ + str(test_data / "config/access-om2.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) + VERSION = "v2024-01-01" # Write the catalog.yamls to where the catalogs go - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "catalog.yaml" - ) + get_catalog_fp.return_value = str(tmp_path / "catalog.yaml") # Build the first catalog - build() + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + VERSION, + ] + ) # Update the version number, *and* the catalog name NEW_VERSION = "v2025-01-01" - mockargs.return_value.version = NEW_VERSION - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "metacatalog.yaml" - ) + get_catalog_fp.return_value = str(tmp_path / "metacatalog.yaml") # Put dummy version folders into the tempdir # The new catalog will consider these, as the catalog.yaml # names are no longer consistent if min_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, min_vers), - exist_ok=False, - ) + (tmp_path / min_vers).mkdir(parents=True, exist_ok=False) if max_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, max_vers), - exist_ok=False, - ) + (tmp_path / max_vers).mkdir(parents=True, exist_ok=False) # Build another catalog - build() + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + NEW_VERSION, + ] + ) # There should now be two catalogs - catalog.yaml and metacatalog.yaml - with Path( - os.path.join(os.path.dirname(get_catalog_fp.return_value), "catalog.yaml") - ).open(mode="r") as fobj: + with (tmp_path / "catalog.yaml").open(mode="r") as fobj: cat_first = yaml.safe_load(fobj) - with Path( - os.path.join(os.path.dirname(get_catalog_fp.return_value), "metacatalog.yaml") - ).open(mode="r") as fobj: + with (tmp_path / "metacatalog.yaml").open(mode="r") as fobj: cat_second = yaml.safe_load(fobj) assert ( @@ -675,36 +641,20 @@ def test_build_repeat_renamecatalogyaml( cat_second["sources"]["access_nri"]["parameters"]["version"].get("min") == min_vers if min_vers is not None - else mockargs.return_value.version - ), f'Min version {cat_second["sources"]["access_nri"]["parameters"]["version"].get("min")} does not match expected {min_vers if min_vers is not None else mockargs.return_value.version}' + else VERSION + ), f'Min version {cat_second["sources"]["access_nri"]["parameters"]["version"].get("min")} does not match expected {min_vers if min_vers is not None else VERSION}' assert ( cat_second["sources"]["access_nri"]["parameters"]["version"].get("max") == max_vers if max_vers is not None - else mockargs.return_value.version - ), f'Max version {cat_second["sources"]["access_nri"]["parameters"]["version"].get("max")} does not match expected {max_vers if max_vers is not None else mockargs.return_value.version}' + else VERSION + ), f'Max version {cat_second["sources"]["access_nri"]["parameters"]["version"].get("max")} does not match expected {max_vers if max_vers is not None else VERSION}' assert ( cat_second["sources"]["access_nri"]["parameters"]["version"].get("default") == "v2025-01-01" ), f'Default version {cat_second["sources"]["access_nri"]["parameters"]["version"].get("default")} does not match expected v2025-01-01' -@mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2.yaml", - # "config/cmip5.yaml", # Save this for addition - ], - build_base_path=None, # Use pytest fixture here? - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file="cat.csv", - version="v2024-01-01", - no_update=False, - ), -) @pytest.mark.parametrize( "min_vers,max_vers", [ @@ -713,59 +663,61 @@ def test_build_repeat_renamecatalogyaml( ("v2001-01-01", None), ], ) -def test_build_repeat_altercatalogstruct( - mockargs, get_catalog_fp, test_data, min_vers, max_vers, tmp_path -): - # Update the config_yaml paths - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data - - mockargs.return_value.build_base_path = str(tmp_path) - mockargs.return_value.version = ( - "v2024-01-01" # May have been overridden in previous parametrize pass - ) - mockargs.return_value.catalog_file = "cat.csv" - - # Write the catalog.yamls to where the catalogs go - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "catalog.yaml" - ) +def test_build_repeat_altercatalogstruct(test_data, min_vers, max_vers, tmp_path): + configs = [ + str(test_data / "config/access-om2.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) # Build the first catalog - build() + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + "v2024-01-01", + ] + ) # Update the version number, *and* the catalog name NEW_VERSION = "v2025-01-01" - mockargs.return_value.version = NEW_VERSION - mockargs.return_value.catalog_file = "new_cat.csv" # Put dummy version folders into the tempdir # The new catalog will *not* consider these, as the catalog.yaml # names are no longer consistent if min_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, min_vers), - exist_ok=False, - ) + (tmp_path / min_vers).mkdir(parents=True, exist_ok=False) if max_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, max_vers), - exist_ok=False, - ) + (tmp_path / max_vers).mkdir(parents=True, exist_ok=False) # Build another catalog - build() + build( + [ + *configs, + "--catalog_file", + "new_cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + NEW_VERSION, + ] + ) # There should now be two catalogs - catalog.yaml and catalog-v2024-01-01.yaml - with Path( - os.path.join( - os.path.dirname(get_catalog_fp.return_value), "catalog-v2024-01-01.yaml" - ) - ).open(mode="r") as fobj: + with (tmp_path / "catalog-v2024-01-01.yaml").open(mode="r") as fobj: cat_first = yaml.safe_load(fobj) - with Path( - os.path.join(os.path.dirname(get_catalog_fp.return_value), "catalog.yaml") - ).open(mode="r") as fobj: + with (tmp_path / "catalog.yaml").open(mode="r") as fobj: cat_second = yaml.safe_load(fobj) assert ( @@ -795,22 +747,6 @@ def test_build_repeat_altercatalogstruct( ), f'Default version {cat_second["sources"]["access_nri"]["parameters"]["version"].get("default")} does not match expected {NEW_VERSION}' -@mock.patch("access_nri_intake.cli.get_catalog_fp") -@mock.patch( - "argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace( - config_yaml=[ - "config/access-om2.yaml", - # "config/cmip5.yaml", # Save this for addition - ], - build_base_path=None, # Use pytest fixture here? - catalog_base_path=None, # Not required, get_catalog_fp is mocked - data_base_path="", - catalog_file=None, - version="v2024-01-01", - no_update=False, - ), -) @pytest.mark.parametrize( "min_vers,max_vers", [ @@ -820,60 +756,66 @@ def test_build_repeat_altercatalogstruct( ], ) def test_build_repeat_altercatalogstruct_multivers( - mockargs, get_catalog_fp, test_data, min_vers, max_vers, tmp_path + test_data, min_vers, max_vers, tmp_path ): - # Update the config_yaml paths - for i, p in enumerate(mockargs.return_value.config_yaml): - mockargs.return_value.config_yaml[i] = os.path.join(test_data, p) - mockargs.return_value.data_base_path = test_data - - mockargs.return_value.build_base_path = str(tmp_path) - mockargs.return_value.version = ( - "v2024-01-01" # May have been overridden in previous parametrize pass - ) - mockargs.return_value.catalog_file = "cat.csv" + configs = [ + str(test_data / "config/cmip5.yaml"), + ] + data_base_path = str(test_data) + build_base_path = str(tmp_path) # Put dummy version folders into the tempdir - these will # be picked up by the first catalog if min_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, min_vers), - exist_ok=False, - ) + (tmp_path / min_vers).mkdir(parents=True, exist_ok=False) if max_vers is not None: - os.makedirs( - os.path.join(mockargs.return_value.build_base_path, max_vers), - exist_ok=False, - ) - - # Write the catalog.yamls to where the catalogs go - get_catalog_fp.return_value = os.path.join( - mockargs.return_value.build_base_path, "catalog.yaml" - ) + (tmp_path / max_vers).mkdir(parents=True, exist_ok=False) # Build the first catalog - build() + build( + [ + *configs, + "--catalog_file", + "cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + "v2024-01-01", + ] + ) # Update the version number, *and* the catalog name NEW_VERSION = "v2025-01-01" - mockargs.return_value.version = NEW_VERSION - mockargs.return_value.catalog_file = "new_cat.csv" # Build another catalog - build() + build( + [ + *configs, + "--catalog_file", + "new_cat.csv", + "--data_base_path", + data_base_path, + "--build_base_path", + build_base_path, + "--catalog_base_path", + build_base_path, + "--version", + NEW_VERSION, + ] + ) # There should now be two catalogs - catalog.yaml and catalog--.yaml cat_first_name = f"catalog-{min_vers if min_vers is not None else 'v2024-01-01'}" if max_vers is not None or min_vers is not None: cat_first_name += f"-{max_vers if max_vers is not None else 'v2024-01-01'}" cat_first_name += ".yaml" - with Path( - os.path.join(os.path.dirname(get_catalog_fp.return_value), cat_first_name) - ).open(mode="r") as fobj: + with (tmp_path / cat_first_name).open(mode="r") as fobj: cat_first = yaml.safe_load(fobj) - with Path( - os.path.join(os.path.dirname(get_catalog_fp.return_value), "catalog.yaml") - ).open(mode="r") as fobj: + with (tmp_path / "catalog.yaml").open(mode="r") as fobj: cat_second = yaml.safe_load(fobj) assert ( @@ -947,15 +889,14 @@ def test_metadata_validate_no_file(): def test_metadata_template(tmp_path): - loc = str(tmp_path) - metadata_template(loc=loc) - if not os.path.isfile(os.path.join(loc, "metadata.yaml")): + metadata_template(loc=tmp_path) + if not (tmp_path / "metadata.yaml").is_file(): raise RuntimeError("Didn't write template into temp dir") def test_metadata_template_default_loc(): metadata_template() - if os.path.isfile(os.path.join(os.getcwd(), "metadata.yaml")): - os.remove(os.path.join(os.getcwd(), "metadata.yaml")) + if (Path.cwd() / "metadata.yaml").is_file(): + (Path.cwd() / "metadata.yaml").unlink() else: raise RuntimeError("Didn't write template into PWD") diff --git a/tests/test_manager.py b/tests/test_manager.py index 5de50a13..92006abb 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -3,6 +3,7 @@ from unittest import mock +from warnings import warn import pytest from intake_dataframe_catalog.core import DfFileCatalogError @@ -184,25 +185,60 @@ def test_CatalogManager_all(tmp_path, test_data): assert len(CatalogManager(path).dfcat) == len(models) + 1 -@pytest.mark.parametrize( - "intake_dataframe_err_str, access_nri_err_str, cause_str", - [ - ( - "Expected iterable metadata columns: ['model']. Unable to add entry with iterable metadata columns '[]' to dataframe catalog: columns ['model'] must be iterable to ensure metadata entries are consistent.", - "Error adding source 'cmip5-al33' to the catalog", - "Expected iterable metadata columns: ['model']", - ), - ( - "Generic Exception for the CatalogManager class", - "Generic Exception for the CatalogManager class", - "None", - ), - ], -) -def test_CatalogManager_load_invalid_model( - tmp_path, test_data, intake_dataframe_err_str, access_nri_err_str, cause_str -): +class Cmip5MockTranslator(Cmip5Translator): + def __init__(self, source, columns): + """Mock the Cmip5Translator __init__ method - I've changed the model dispatch + to use a mock_model_translator method, which isn't tuplified. + """ + super().__init__(source, columns) + self.set_dispatch( + input_name="model", core_colname="model", func=self.mock_model_translator + ) + + # @tuplify_series + def mock_model_translator(self): + """ + The model translator method has been overriden to remove the tuplification + (commented out above for reference). + """ + return self.source.df[self._dispatch_keys.model] + + +def test_CatalogManager_load_non_iterable(tmp_path, test_data): + """Test loading and adding an Intake-ESM datastore""" + cat = CatalogManager(tmp_path / "cat.csv") + + # Load source + load_args = dict( + name="cmip5-al33", + description="cmip5-al33", + path=str(test_data / "esm_datastore/cmip5-al33.json"), + translator=Cmip5MockTranslator, + ) + + with pytest.raises(CatalogManagerError) as excinfo: + cat.load(**load_args) + + assert "Error adding source 'cmip5-al33' to the catalog" in str(excinfo.value) + try: + assert ( + "Expected iterable metadata columns: ['model', 'realm', 'frequency', 'variable']" + in str(excinfo.value.__cause__) + ) + except AssertionError: + warn( + "Expected error message not found in upstream error.", + category=RuntimeWarning, + stacklevel=2, + ) + + +def test_CatalogManager_generic_exception(tmp_path, test_data): """Test loading and adding an Intake-ESM datastore""" + intake_dataframe_err_str = "Generic Exception for the CatalogManager class" + access_nri_err_str = "Generic Exception for the CatalogManager class" + cause_str = "None" + path = str(tmp_path / "cat.csv") cat = CatalogManager(path) From 293d4848c1461c0e39257991c858070bdeefc3a1 Mon Sep 17 00:00:00 2001 From: Marc White Date: Tue, 10 Dec 2024 14:57:26 +1100 Subject: [PATCH 3/8] Progress on catalog version reporting (#295) * WIP, commit for safekeeping * Elimanate some redundant dependencies * Revert "Elimanate some redundant dependencies" This reverts commit 4b574b3f40101bdfd9fbab7cd61109173f98c95a. * Revert "WIP, commit for safekeeping" This reverts commit 1ce9631cfb70fb07483cb9aaafcae65ba60383e3. * Switch _get_catalog_rp to use Path * Switch current available_versions to use Path, not os.path * Protect against finding a non-directory catalog version * Restrict basic list of available versions to those in the current catalog.yaml * Mark 'default' version in pretty print * Remove debug pdb * Cover missing exception lines with tests * @charles-turner-1 suggestions --- src/access_nri_intake/data/utils.py | 47 ++++++++++++++----- tests/data/catalog/catalog-dirs/v2023-01-01 | 3 ++ tests/data/catalog/catalog-versions.yaml | 24 ++++++++++ tests/test_data.py | 50 +++++++++++++++------ 4 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 tests/data/catalog/catalog-dirs/v2023-01-01 create mode 100644 tests/data/catalog/catalog-versions.yaml diff --git a/src/access_nri_intake/data/utils.py b/src/access_nri_intake/data/utils.py index 04a6c168..6b2d5e1d 100644 --- a/src/access_nri_intake/data/utils.py +++ b/src/access_nri_intake/data/utils.py @@ -1,8 +1,8 @@ # Copyright 2024 ACCESS-NRI and contributors. See the top-level COPYRIGHT file for details. # SPDX-License-Identifier: Apache-2.0 -import os import re +from pathlib import Path import yaml @@ -12,7 +12,7 @@ CATALOG_PATH_REGEX = r"^(?P.*?)\{\{version\}\}.*?$" -def _get_catalog_rp(): +def _get_catalog_root(): """ Get the catalog root path. """ @@ -28,14 +28,14 @@ def _get_catalog_rp(): match = re.match(CATALOG_PATH_REGEX, catalog_fp) try: - return match.group("rootpath") + return Path(match.group("rootpath")) except AttributeError: # Match failed raise RuntimeError( f"Catalog metadata {get_catalog_fp()} contains unexpected catalog filepath: {catalog_fp}" ) -def available_versions(pretty: bool = True): +def available_versions(pretty: bool = True) -> list[str] | None: """ Report the available versions of the `intake.cat.access_nri` catalog. @@ -46,24 +46,47 @@ def available_versions(pretty: bool = True): (True, default), or to provide a list of version numbers only (False). """ # Work out where the catalogs are stored - base_path = _get_catalog_rp() + base_path = _get_catalog_root() + + # Grab the extant catalog and work out its min and max versions + try: + with open(get_catalog_fp()) as cat_file: + cat_yaml = yaml.safe_load(cat_file) + vers_min = cat_yaml["sources"]["access_nri"]["parameters"]["version"]["min"] + vers_max = cat_yaml["sources"]["access_nri"]["parameters"]["version"]["max"] + vers_def = cat_yaml["sources"]["access_nri"]["parameters"]["version"][ + "default" + ] + except FileNotFoundError: + raise FileNotFoundError(f"Unable to find catalog at {get_catalog_fp()}") + except KeyError: + raise RuntimeError(f"Catalog at {get_catalog_fp()} not correctly formatted") # Grab all the catalog names - cats = [d for d in os.listdir(base_path) if re.search(CATALOG_NAME_FORMAT, d)] + cats = [ + dir_path.name + for dir_path in base_path.iterdir() + if re.search(CATALOG_NAME_FORMAT, dir_path.name) + and dir_path.is_dir() + and ( + (dir_path.name >= vers_min and dir_path.name <= vers_max) + or dir_path.name == vers_def + ) + ] cats.sort(reverse=True) # Find all the symlinked versions - symlinks = [s for s in cats if os.path.islink(os.path.join(base_path, s))] + symlinks = [s for s in cats if (Path(base_path) / s).is_symlink()] - symlink_targets = { - s: os.path.basename(os.readlink(os.path.join(base_path, s))) for s in symlinks - } + symlink_targets = {s: (base_path / s).readlink().name for s in symlinks} if pretty: - for i, c in enumerate(cats): + for c in cats: if c in symlink_targets.keys(): c += f"(-->{symlink_targets[c]})" + if c == vers_def: + c += "*" print(c) - return + return None return cats diff --git a/tests/data/catalog/catalog-dirs/v2023-01-01 b/tests/data/catalog/catalog-dirs/v2023-01-01 new file mode 100644 index 00000000..7b02fc2c --- /dev/null +++ b/tests/data/catalog/catalog-dirs/v2023-01-01 @@ -0,0 +1,3 @@ +# This is a catalog 'file', not directory, +# to make sure the system doesn't detect such things +# as a real catalog \ No newline at end of file diff --git a/tests/data/catalog/catalog-versions.yaml b/tests/data/catalog/catalog-versions.yaml new file mode 100644 index 00000000..2c6d98c2 --- /dev/null +++ b/tests/data/catalog/catalog-versions.yaml @@ -0,0 +1,24 @@ +sources: + access_nri: + args: + columns_with_iterables: + - model + - realm + - frequency + - variable + mode: r + name_column: name + path: /g/data/xp65/public/apps/access-nri-intake-catalog/{{version}}/metacatalog.csv + yaml_column: yaml + description: ACCESS-NRI intake catalog + driver: intake_dataframe_catalog.core.DfFileCatalog + metadata: + storage: gdata/al33+gdata/cj50+gdata/dk92+gdata/fs38+gdata/ik11+gdata/oi10+gdata/p73+gdata/rr3+gdata/xp65 + version: '{{version}}' + parameters: + version: + min: v2019-02-02 + max: v2024-06-19 + default: v2025-02-28 # Check default outside range is returned + description: Catalog version + type: str \ No newline at end of file diff --git a/tests/test_data.py b/tests/test_data.py index 314fdd8c..d66b3f4c 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -2,17 +2,18 @@ # SPDX-License-Identifier: Apache-2.0 import re +from pathlib import Path from unittest import mock import pytest import access_nri_intake from access_nri_intake.data import CATALOG_NAME_FORMAT -from access_nri_intake.data.utils import _get_catalog_rp, available_versions +from access_nri_intake.data.utils import _get_catalog_root, available_versions @mock.patch("access_nri_intake.data.utils.get_catalog_fp") -def test__get_catalog_rp(mock_get_catalog_fp, test_data): +def test__get_catalog_root(mock_get_catalog_fp, test_data): """ Check that we correctly decipher to rootpath (rp) to the catalogs """ @@ -22,9 +23,9 @@ def test__get_catalog_rp(mock_get_catalog_fp, test_data): == test_data / "catalog/catalog-good.yaml" ), "Mock failed" - rp = _get_catalog_rp() - assert ( - rp == "/this/is/root/path/" + rp = _get_catalog_root() + assert rp == Path( + "/this/is/root/path/" ), f"Computed root path {rp} != expected value /this/is/root/path/" @@ -32,7 +33,7 @@ def test__get_catalog_rp(mock_get_catalog_fp, test_data): @pytest.mark.parametrize( "cat", ["catalog/catalog-bad-path.yaml", "catalog/catalog-bad-structure.yaml"] ) -def test__get_catalog_rp_runtime_errors(mock_get_catalog_fp, test_data, cat): +def test__get_catalog_root_runtime_errors(mock_get_catalog_fp, test_data, cat): """ Check that we correctly decipher to rootpath (rp) to the catalogs """ @@ -42,12 +43,14 @@ def test__get_catalog_rp_runtime_errors(mock_get_catalog_fp, test_data, cat): ), "Mock failed" with pytest.raises(RuntimeError): - _get_catalog_rp() + _get_catalog_root() -@mock.patch("access_nri_intake.data.utils._get_catalog_rp") -def test_available_versions(mock__get_catalog_rp, test_data): - mock__get_catalog_rp.return_value = test_data / "catalog/catalog-dirs" +@mock.patch("access_nri_intake.data.utils._get_catalog_root") +@mock.patch("access_nri_intake.data.utils.get_catalog_fp") +def test_available_versions(mock_get_catalog_fp, mock__get_catalog_root, test_data): + mock__get_catalog_root.return_value = test_data / "catalog/catalog-dirs" + mock_get_catalog_fp.return_value = test_data / "catalog/catalog-versions.yaml" cats = available_versions(pretty=False) assert cats == [ "v2025-02-28", @@ -57,16 +60,35 @@ def test_available_versions(mock__get_catalog_rp, test_data): ], "Did not get expected catalog list" -@mock.patch("access_nri_intake.data.utils._get_catalog_rp") -def test_available_versions_pretty(mock__get_catalog_rp, test_data, capfd): - mock__get_catalog_rp.return_value = test_data / "catalog/catalog-dirs" +@mock.patch("access_nri_intake.data.utils._get_catalog_root") +@mock.patch("access_nri_intake.data.utils.get_catalog_fp") +def test_available_versions_pretty( + mock_get_catalog_fp, mock__get_catalog_root, test_data, capfd +): + mock__get_catalog_root.return_value = test_data / "catalog/catalog-dirs" + mock_get_catalog_fp.return_value = test_data / "catalog/catalog-versions.yaml" available_versions(pretty=True) captured, _ = capfd.readouterr() assert ( - captured == "v2025-02-28\nv2024-06-19\nv2024-01-01\nv2019-02-02(-->vN.N.N)\n" + captured == "v2025-02-28*\nv2024-06-19\nv2024-01-01\nv2019-02-02(-->vN.N.N)\n" ), "Did not get expected catalog printout" +@mock.patch( + "access_nri_intake.data.utils.get_catalog_fp", return_value="/this/is/not/real.yaml" +) +def test_available_versions_no_catalog(mock_get_catalog_fp): + with pytest.raises(FileNotFoundError): + available_versions() + + +@mock.patch("access_nri_intake.data.utils.get_catalog_fp") +def test_available_versions_bad_catalog(mock_get_catalog_fp, test_data): + mock_get_catalog_fp.return_value = test_data / "catalog/catalog-bad-structure.yaml" + with pytest.raises(RuntimeError): + available_versions() + + @pytest.mark.parametrize( "name", [ From 6391c5c29b9c03a23cae491d81eb8ca653b5444c Mon Sep 17 00:00:00 2001 From: Charles Turner <52199577+charles-turner-1@users.noreply.github.com> Date: Tue, 10 Dec 2024 14:04:44 +0800 Subject: [PATCH 4/8] 297 translator errors (#298) * Wrapped translators with more helpful errors & decorator that should centralise handling that - but is broken * WIP * Typo * Fixed moving failures into translator * Added test * Updated test coverage * Cleaned interface up a touch --- src/access_nri_intake/catalog/translators.py | 34 +++++++++++++++++++- tests/test_translators.py | 33 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/access_nri_intake/catalog/translators.py b/src/access_nri_intake/catalog/translators.py index 84f215cc..ea2dc096 100644 --- a/src/access_nri_intake/catalog/translators.py +++ b/src/access_nri_intake/catalog/translators.py @@ -7,7 +7,7 @@ """ from dataclasses import dataclass -from functools import partial +from functools import partial, wraps from typing import Callable import pandas as pd @@ -17,6 +17,9 @@ from . import COLUMNS_WITH_ITERABLES from .utils import _to_tuple, tuplify_series +# Note: important that when using @tuplify_series and @trace_failure decorators, +# trace failure is the innermost decorator + FREQUENCY_TRANSLATIONS = { "monthly-averaged-by-hour": "1hr", "monthly-averaged-by-day": "1hr", @@ -36,6 +39,29 @@ } +def trace_failure(func: Callable) -> Callable: + """ + Decorator that wraps a function and prints a message if it raises an exception + """ + + @wraps(func) + def wrapper(*args, **kwargs): + func_name = func.__name__ + colname = func_name[1:].split("_")[0] + # Ensure the first argument is an instance of the class + if not isinstance(args[0], DefaultTranslator): + raise TypeError("Decorator can only be applied to class methods") + + try: + return func(*args, **kwargs) + except KeyError as exc: + raise KeyError( + f"Unable to translate '{colname}' column with translator '{args[0].__class__.__name__}'" + ) from exc + + return wrapper + + class TranslatorError(Exception): "Generic Exception for the Translator classes" @@ -192,6 +218,7 @@ def set_dispatch( self._dispatch[core_colname] = func setattr(self._dispatch_keys, core_colname, input_name) + @trace_failure def _realm_translator(self) -> pd.Series: """ Return realm, fixing a few issues @@ -199,6 +226,7 @@ def _realm_translator(self) -> pd.Series: return _cmip_realm_translator(self.source.df[self._dispatch_keys.realm]) @tuplify_series + @trace_failure def _model_translator(self) -> pd.Series: """ Return model from dispatch_keys.model @@ -206,6 +234,7 @@ def _model_translator(self) -> pd.Series: return self.source.df[self._dispatch_keys.model] @tuplify_series + @trace_failure def _frequency_translator(self) -> pd.Series: """ Return frequency, fixing a few issues @@ -215,6 +244,7 @@ def _frequency_translator(self) -> pd.Series: ) @tuplify_series + @trace_failure def _variable_translator(self) -> pd.Series: """ Return variable as a tuple @@ -407,6 +437,7 @@ def __init__(self, source, columns): ) @tuplify_series + @trace_failure def _model_translator(self): """ Get the model from the path. This is a slightly hacky approach, using the @@ -425,6 +456,7 @@ def _realm_translator(self): return self.source.df.apply(lambda x: ("none",), 1) @tuplify_series + @trace_failure def _frequency_translator(self): """ Get the frequency from the path diff --git a/tests/test_translators.py b/tests/test_translators.py index 4462efb9..e8bfbaa6 100644 --- a/tests/test_translators.py +++ b/tests/test_translators.py @@ -19,6 +19,7 @@ TranslatorError, _cmip_realm_translator, _to_tuple, + trace_failure, tuplify_series, ) @@ -361,3 +362,35 @@ def test_NarclimTranslator(test_data, groupby, n_entries): esmds.description = "description" df = NarclimTranslator(esmds, CORE_COLUMNS).translate(groupby) assert len(df) == n_entries + + +def test_translator_failure(test_data): + esmds = intake.open_esm_datastore(test_data / "esm_datastore/narclim2-zz63.json") + esmds.name = "name" + esmds.description = "description" + translator = NarclimTranslator(esmds, CORE_COLUMNS) + + default = DefaultTranslator(esmds, CORE_COLUMNS) + + translator.set_dispatch( + input_name="dud_name", + core_colname="model", + func=default._model_translator, + ) + + with pytest.raises(KeyError) as excinfo: + translator.translate() + + assert ( + "Unable to translate 'model' column with translator 'DefaultTranslator'" + in str(excinfo.value) + ) + + @trace_failure + def _(x: int) -> int: + return x + + with pytest.raises(TypeError) as excinfo: + _(1) + + assert "Decorator can only be applied to class methods" in str(excinfo.value) From b0fcefa53bb61f550e54ffdbe822128e3dd9dafe Mon Sep 17 00:00:00 2001 From: Charles Turner <52199577+charles-turner-1@users.noreply.github.com> Date: Wed, 11 Dec 2024 07:14:07 +0800 Subject: [PATCH 5/8] 290 align test datasets & Broken cordex datastore (#300) * WIP * WIP * Ready to try live translator tests on Gadi * docstring * Fixed e2e workflow, updated cordex translator & test data * Formatting --- .github/workflows/e2e.yaml | 2 +- src/access_nri_intake/catalog/translators.py | 4 +- tests/conftest.py | 5 ++ tests/data/esm_datastore/cordex-ig45.csv | 12 ++--- tests/data/esm_datastore/cordex-ig45.json | 12 ----- tests/e2e/__init__.py | 5 ++ tests/e2e/test_datasets_representative.py | 50 ++++++++++++++++++++ tests/e2e/test_end_to_end.py | 4 +- 8 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 tests/e2e/test_datasets_representative.py diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index b53d73f9..954ab856 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -18,6 +18,6 @@ jobs: key: ${{secrets.DEPLOY_KEY}} script: | cd ${{secrets.GADI_REPO_PATH}} - qsub bin/build_all.sh + qsub bin/test_end_to_end.sh diff --git a/src/access_nri_intake/catalog/translators.py b/src/access_nri_intake/catalog/translators.py index ea2dc096..432d6247 100644 --- a/src/access_nri_intake/catalog/translators.py +++ b/src/access_nri_intake/catalog/translators.py @@ -385,7 +385,9 @@ def __init__(self, source, columns): super().__init__(source, columns) self.set_dispatch( - input_name="source_id", core_colname="model", func=super()._model_translator + input_name="project_id", + core_colname="model", + func=super()._model_translator, ) self.set_dispatch( input_name="variable_id", diff --git a/tests/conftest.py b/tests/conftest.py index 8b14d9d8..fb7c2551 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,6 +25,11 @@ def config_dir(): return Path(here / "e2e/configs") +@fixture(scope="session") +def live_config_dir(): + return Path(here).parent / "config" + + @fixture(scope="session") def BASE_DIR(tmp_path_factory): yield tmp_path_factory.mktemp("catalog-dir") diff --git a/tests/data/esm_datastore/cordex-ig45.csv b/tests/data/esm_datastore/cordex-ig45.csv index 06f6a2fd..9d71aeb0 100644 --- a/tests/data/esm_datastore/cordex-ig45.csv +++ b/tests/data/esm_datastore/cordex-ig45.csv @@ -1,6 +1,6 @@ -path,file_type,project_id,resolution,institution_id,source_id,experiment_id,member_id,frequency,variable_id,version,time_range -/g/data/ig45/QldFCP-2/output/CMIP6/DD/AUS-10i/UQ-DEC/ACCESS-CM2/ssp126/r2i1p1f1/CCAMoc-v2112/v1-r1/day/hus200/v20240709/hus200_AUS-10i_ACCESS-CM2_ssp126_r2i1p1f1_UQ-DEC_CCAMoc-v2112_v1-r1_day_20580101-20581231.nc,f,output,AUS-10i,UQ-DEC,ACCESS-CM2,ssp126,r2i1p1f1,day,hus200,v20240709,20580101-20581231 -/g/data/ig45/QldFCP-2/CORDEX/CMIP6/DD/AUS-20i/UQ-DEC/ACCESS-ESM1-5/ssp126/r20i1p1f1/CCAMoc-v2112/v1-r1/mon/va925/v20240722/va925_AUS-20i_ACCESS-ESM1-5_ssp126_r20i1p1f1_UQ-DEC_CCAMoc-v2112_v1-r1_mon_208101-209012.nc,f,CORDEX,AUS-20i,UQ-DEC,ACCESS-ESM1-5,ssp126,r20i1p1f1,mon,va925,v20240722,208101-209012 -/g/data/ig45/QldFCP-2/CORDEX/CMIP6/DD/AUS-20i/UQ-DEC/ACCESS-ESM1-5/ssp370/r6i1p1f1/CCAM-v2105/v1-r1/mon/clh/v20240722/clh_AUS-20i_ACCESS-ESM1-5_ssp370_r6i1p1f1_UQ-DEC_CCAM-v2105_v1-r1_mon_201501-202012.nc,f,CORDEX,AUS-20i,UQ-DEC,ACCESS-ESM1-5,ssp370,r6i1p1f1,mon,clh,v20240722,201501-202012 -/g/data/ig45/QldFCP-2/output/CMIP6/DD/AUS-10i/UQ-DEC/ACCESS-CM2/ssp126/r2i1p1f1/CCAMoc-v2112/v1-r1/day/ta850/v20240709/ta850_AUS-10i_ACCESS-CM2_ssp126_r2i1p1f1_UQ-DEC_CCAMoc-v2112_v1-r1_day_20340101-20341231.nc,f,output,AUS-10i,UQ-DEC,ACCESS-CM2,ssp126,r2i1p1f1,day,ta850,v20240709,20340101-20341231 -/g/data/ig45/QldFCP-2/CORDEX/CMIP6/DD/AUS-20i/UQ-DEC/NorESM2-MM/ssp126/r1i1p1f1/CCAMoc-v2112/v1-r1/mon/hus200/v20240722/hus200_AUS-20i_NorESM2-MM_ssp126_r1i1p1f1_UQ-DEC_CCAMoc-v2112_v1-r1_mon_201501-202012.nc,f,CORDEX,AUS-20i,UQ-DEC,NorESM2-MM,ssp126,r1i1p1f1,mon,hus200,v20240722,201501-202012 +path,file_type,project_id,experiment_id,member_id,frequency,variable_id,version,time_range +/g/data/ig45/QldFCP-2/CORDEX/CMIP6/DD/AUS-20i/UQ-DEC/ACCESS-ESM1-5/ssp126/r20i1p1f1/CCAMoc-v2112/v1-r1/mon/va925/v20240722/va925_AUS-20i_ACCESS-ESM1-5_ssp126_r20i1p1f1_UQ-DEC_CCAMoc-v2112_v1-r1_mon_208101-209012.nc,f,ACCESS-ESM1-5,ssp126,r20i1p1f1,mon,va925,v20240722,208101-209012 +/g/data/ig45/QldFCP-2/CORDEX/CMIP6/DD/AUS-20i/UQ-DEC/ACCESS-ESM1-5/ssp370/r6i1p1f1/CCAM-v2105/v1-r1/mon/clh/v20240722/clh_AUS-20i_ACCESS-ESM1-5_ssp370_r6i1p1f1_UQ-DEC_CCAM-v2105_v1-r1_mon_201501-202012.nc,f,ACCESS-ESM1-5,ssp370,r6i1p1f1,mon,clh,v20240722,201501-202012 +/g/data/ig45/QldFCP-2/CORDEX/CMIP6/DD/AUS-20i/UQ-DEC/NorESM2-MM/ssp126/r1i1p1f1/CCAMoc-v2112/v1-r1/mon/hus200/v20240722/hus200_AUS-20i_NorESM2-MM_ssp126_r1i1p1f1_UQ-DEC_CCAMoc-v2112_v1-r1_mon_201501-202012.nc,f,NorESM2-MM,ssp126,r1i1p1f1,mon,hus200,v20240722,201501-202012 +/g/data/ig45/QldFCP-2/output/CMIP6/DD/AUS-10i/UQ-DEC/ACCESS-CM2/ssp126/r2i1p1f1/CCAMoc-v2112/v1-r1/day/hus200/v20240709/hus200_AUS-10i_ACCESS-CM2_ssp126_r2i1p1f1_UQ-DEC_CCAMoc-v2112_v1-r1_day_20580101-20581231.nc,f,ACCESS-CM2,ssp126,r2i1p1f1,day,hus200,v20240709,20580101-20581231 +/g/data/ig45/QldFCP-2/output/CMIP6/DD/AUS-10i/UQ-DEC/ACCESS-CM2/ssp126/r2i1p1f1/CCAMoc-v2112/v1-r1/day/ta850/v20240709/ta850_AUS-10i_ACCESS-CM2_ssp126_r2i1p1f1_UQ-DEC_CCAMoc-v2112_v1-r1_day_20340101-20341231.nc,f,ACCESS-CM2,ssp126,r2i1p1f1,day,ta850,v20240709,20340101-20341231 diff --git a/tests/data/esm_datastore/cordex-ig45.json b/tests/data/esm_datastore/cordex-ig45.json index fab7b871..66c92e80 100644 --- a/tests/data/esm_datastore/cordex-ig45.json +++ b/tests/data/esm_datastore/cordex-ig45.json @@ -11,9 +11,6 @@ "groupby_attrs": [ "file_type", "project_id", - "resolution", - "institution_id", - "source_id", "experiment_id", "member_id", "frequency", @@ -39,15 +36,6 @@ { "column_name": "project_id" }, - { - "column_name": "resolution" - }, - { - "column_name": "institution_id" - }, - { - "column_name": "source_id" - }, { "column_name": "experiment_id" }, diff --git a/tests/e2e/__init__.py b/tests/e2e/__init__.py index e69de29b..ee6a234d 100644 --- a/tests/e2e/__init__.py +++ b/tests/e2e/__init__.py @@ -0,0 +1,5 @@ +import pytest + +e2e = pytest.mark.skipif( + "not config.getoption('--e2e')", +) diff --git a/tests/e2e/test_datasets_representative.py b/tests/e2e/test_datasets_representative.py new file mode 100644 index 00000000..843ce8c7 --- /dev/null +++ b/tests/e2e/test_datasets_representative.py @@ -0,0 +1,50 @@ +import pytest +import yaml + +import access_nri_intake.catalog.translators as translators +from access_nri_intake.cli import build + +from . import e2e + + +@e2e +@pytest.mark.parametrize( + "translator_name", + [ + t + for t in dir(translators) + if t.endswith("Translator") and not t.startswith("Default") + ], +) +def test_alignment(translator_name, live_config_dir, BASE_DIR, v_num): + # Now live test the translator. Honestly, might be overkill - it might be easier + # to just extract the json files, open them, check they match the test data + filenames = [f for f in live_config_dir.glob("*.yaml")] + # Now we want to open them & throw away anything where builder != null. + translator_fnames = [] + + for fname in filenames: + with open(fname) as fo: + catalog_metadata = yaml.load(fo, yaml.FullLoader) + if catalog_metadata["translator"] == translator_name: + translator_fnames.append(str(fname)) + + assert len(translator_fnames) == 1 + + try: + build( + [ + *translator_fnames, + "--build_base_path", + str(BASE_DIR), + "--catalog_base_path", + "./", + "--catalog_file", + "metacatalog.csv", + "--version", + v_num, + "--no_update", + ] + ) + except Exception as exc: + assert False, f"Failed to build {translator_name} with exception {exc}" diff --git a/tests/e2e/test_end_to_end.py b/tests/e2e/test_end_to_end.py index edb31515..05262f79 100644 --- a/tests/e2e/test_end_to_end.py +++ b/tests/e2e/test_end_to_end.py @@ -6,9 +6,7 @@ from access_nri_intake.cli import build -e2e = pytest.mark.skipif( - "not config.getoption('--e2e')", -) +from . import e2e @e2e From f1702f5dfae1cd54cd3eb442b78e47bd4145c002 Mon Sep 17 00:00:00 2001 From: Marc White Date: Wed, 11 Dec 2024 12:28:18 +1100 Subject: [PATCH 6/8] Documentation updates (project/storage list, angry warning) (#301) * Add warnings about changing existing datastores * Updated storage flag/project list generator function * Remove expired code * Remove WIP code --- docs/contributing/sources.rst | 11 +++++++- docs/datastores/adding.rst | 11 +++++++- docs/generate_includes.py | 49 +++++++++++++++++++++++++---------- docs/project_list.rst | 16 +++++++----- docs/storage_flags.rst | 2 +- 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/docs/contributing/sources.rst b/docs/contributing/sources.rst index f202abda..5008bc3c 100644 --- a/docs/contributing/sources.rst +++ b/docs/contributing/sources.rst @@ -8,4 +8,13 @@ Intake-ESM datastore for some climate data on Gadi (e.g. by following :ref:`data to be findable and useable by others in the community. Or you're aware of an ACCESS-related climate data product on Gadi that you think should be included in the catalog. Either way, we'd like to hear from you. Please open a catalog data request `here `_ providing -details of the data product to add. \ No newline at end of file +details of the data product to add. + +.. warning:: + If you are providing an existing Intake-ESM datastore to be added to :code:`access-nri-intake-catalog`, the + datastore must be in its final form **before** you make a data request. If a datastore is changed + after we have verified that we are able to ingest it, it will break future catalog builds and may be + removed. + + If you need to update a datastore that is already in :code:`access-nri-intake-catalog`, please contact us as + described above. \ No newline at end of file diff --git a/docs/datastores/adding.rst b/docs/datastores/adding.rst index 0bc294e4..5ff801d2 100644 --- a/docs/datastores/adding.rst +++ b/docs/datastores/adding.rst @@ -19,4 +19,13 @@ we're happy to help you through the process. .. note:: Datastores don't have to have been created by access-nri-intake Builders in order to be added to the catalog. If you have an Intake-ESM datastore (or indeed another type of Intake source) that you think should be in the - catalog, please open a catalog data request. \ No newline at end of file + catalog, please open a catalog data request. + +.. warning:: + If you are providing an existing Intake-ESM datastore to be added to :code:`access-nri-intake-catalog`, the + datastore must be in its final form **before** you make a data request. If a datastore is changed + after we have verified that we are able to ingest it, it will break future catalog builds and may be + removed. + + If you need to update a datastore that is already in :code:`access-nri-intake-catalog`, please contact us as + described above. \ No newline at end of file diff --git a/docs/generate_includes.py b/docs/generate_includes.py index a100970d..7bc5015a 100755 --- a/docs/generate_includes.py +++ b/docs/generate_includes.py @@ -3,25 +3,46 @@ """ Generate includes for documentation """ -import os +import re +import warnings +from pathlib import Path import yaml +STORAGE_FLAG_REGEXP = r"^/g/data/(?P[a-z]{1,2}[0-9]{1,2})/.*?$" + + +def storage_includes() -> None: + here = Path(__file__).parent.absolute() + + project_list = set() + for source_yaml in (here.parent / "config").glob("*.yaml"): + print(source_yaml) + with open(source_yaml) as fobj: + contents = yaml.safe_load(fobj) + + # Loop over the sources in the YAML, extract all storage flags + # Will ignore anything that doesn't look like /g/data//.... + try: + for source in contents["sources"]: + metadata_match = re.match(STORAGE_FLAG_REGEXP, source["metadata_yaml"]) + if metadata_match: + project_list.add(metadata_match.group("proj")) + for data_path in source["path"]: + data_path_match = re.match(STORAGE_FLAG_REGEXP, data_path) + if data_path_match: + project_list.add(data_path_match.group("proj")) + except KeyError: + warnings.warn(f"Unable to parse config YAML file {source_yaml} - skipping") + continue -def storage_includes(): - here = os.path.abspath(os.path.dirname(__file__)) - with open( - os.path.join(here, "..", "src", "access_nri_intake", "data", "catalog.yaml") - ) as fobj: - contents = yaml.safe_load(fobj) - storage_flags = contents["sources"]["access_nri"]["metadata"]["storage"] - project_list = [ - f"* :code:`{proj.removeprefix('gdata/')}`" for proj in storage_flags.split("+") - ] - with open("storage_flags.rst", "w") as fobj: - fobj.write(f".. code-block::\n\n {storage_flags}") with open("project_list.rst", "w") as fobj: - fobj.write("\n".join(project_list) + "\n") + [fobj.write(f"* :code:`{proj}`\n") for proj in project_list] + storage_string = "+".join([f"gdata/{proj}" for proj in project_list]) + with open("storage_flags.rst", "w") as fobj: + fobj.write(f".. code-block::\n\n {storage_string}") + + return None if __name__ == "__main__": diff --git a/docs/project_list.rst b/docs/project_list.rst index 83e9fdba..37c0f323 100644 --- a/docs/project_list.rst +++ b/docs/project_list.rst @@ -1,9 +1,13 @@ -* :code:`al33` -* :code:`cj50` -* :code:`dk92` -* :code:`fs38` +* :code:`py18` +* :code:`xp65` * :code:`ik11` +* :code:`cj50` +* :code:`zz63` +* :code:`rt52` +* :code:`al33` * :code:`oi10` -* :code:`p73` * :code:`rr3` -* :code:`xp65` +* :code:`ig45` +* :code:`hq89` +* :code:`fs38` +* :code:`p73` diff --git a/docs/storage_flags.rst b/docs/storage_flags.rst index 165b38d8..41cbfe90 100644 --- a/docs/storage_flags.rst +++ b/docs/storage_flags.rst @@ -1,3 +1,3 @@ .. code-block:: - gdata/al33+gdata/cj50+gdata/dk92+gdata/fs38+gdata/ik11+gdata/oi10+gdata/p73+gdata/rr3+gdata/xp65 \ No newline at end of file + gdata/py18+gdata/xp65+gdata/ik11+gdata/cj50+gdata/zz63+gdata/rt52+gdata/al33+gdata/oi10+gdata/rr3+gdata/ig45+gdata/hq89+gdata/fs38+gdata/p73 \ No newline at end of file From 67829183fc32dfff434de27aa0cb63616a842982 Mon Sep 17 00:00:00 2001 From: Marc White Date: Wed, 11 Dec 2024 14:40:53 +1100 Subject: [PATCH 7/8] Post v1.0.0 release documentation updates (#302) --- docs/management/release.rst | 25 +++++++++++++++++++++++++ docs/project_list.rst | 14 +++++++------- docs/storage_flags.rst | 2 +- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/docs/management/release.rst b/docs/management/release.rst index d2f5348d..cf701f93 100644 --- a/docs/management/release.rst +++ b/docs/management/release.rst @@ -15,6 +15,13 @@ or may not include an update to the ACCESS-NRI catalog files on Gadi. #. Enter the new version (vX.X.X) as the tag and release title. Add a brief description of the release. + .. note:: + + It is recommended to attempt a beta release before committing to a major code update. + In this case, the version number requires an ordinal after the :code:`b`, e.g., :code:`vYYYY-MM-DDb0`. If the + ordinal isn't provided, the GitHub PyPI build action will append one, which breaks the linkage + between the PyPI and Conda build actions. + #. Click on "Publish release". This should create the release on GitHub and trigger the workflow that builds and uploads the new version to PyPI and conda @@ -35,9 +42,27 @@ Generating a new catalog version $ cd bin $ qsub -v version=${RELEASE} build_all.sh + .. note:: + Running the build script requires access to an up-to-date checkout of the :code:`access-nri-intake-catalog` + repository. The default location for this is :code:`/g/data/xp65/admin/access-nri-intake-catalog`. If you do + not have the ability to update this checkout, you may use a local one; however, you will need to update + the :code:`CONFIG_DIR` variable in :code:`bin/build_all.sh` to point at your checkout location. + .. note:: If :code:`version` is not provided, the default used is the current date, in the format :code:`vYYYY-MM-DD`. This should be acceptable in most cases. #. Updating :code:`access_nri_intake_catalog` is no longer necessary - the new catalog will be available immediately as :code:`intake.cat.access_nri`. + + +New release with new catalog +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In the case of a linked release of a new major :code:`access-nri-intake-catalog` and a new catalog +build, the recommened process is: + +#. Create a beta release of :code:`access-nri-intake-catalog`; +#. Use the beta release to build a new catalog; +#. Iterate over the above steps until the desired result is achieved; +#. Make a definitive code release. \ No newline at end of file diff --git a/docs/project_list.rst b/docs/project_list.rst index 37c0f323..214015e3 100644 --- a/docs/project_list.rst +++ b/docs/project_list.rst @@ -1,13 +1,13 @@ -* :code:`py18` -* :code:`xp65` -* :code:`ik11` -* :code:`cj50` -* :code:`zz63` +* :code:`rr3` * :code:`rt52` +* :code:`hq89` +* :code:`zz63` * :code:`al33` * :code:`oi10` -* :code:`rr3` +* :code:`ik11` * :code:`ig45` -* :code:`hq89` * :code:`fs38` * :code:`p73` +* :code:`xp65` +* :code:`py18` +* :code:`cj50` diff --git a/docs/storage_flags.rst b/docs/storage_flags.rst index 41cbfe90..8e5e17c9 100644 --- a/docs/storage_flags.rst +++ b/docs/storage_flags.rst @@ -1,3 +1,3 @@ .. code-block:: - gdata/py18+gdata/xp65+gdata/ik11+gdata/cj50+gdata/zz63+gdata/rt52+gdata/al33+gdata/oi10+gdata/rr3+gdata/ig45+gdata/hq89+gdata/fs38+gdata/p73 \ No newline at end of file + gdata/rr3+gdata/rt52+gdata/hq89+gdata/zz63+gdata/al33+gdata/oi10+gdata/ik11+gdata/ig45+gdata/fs38+gdata/p73+gdata/xp65+gdata/py18+gdata/cj50 \ No newline at end of file From 3590e46d9c7da46f5a297d865aa189d8f0f04caa Mon Sep 17 00:00:00 2001 From: Marc White Date: Wed, 11 Dec 2024 15:02:10 +1100 Subject: [PATCH 8/8] Add sanity check notebook (#305) * Add sanity check notebook * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Make the linters happy --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- bin/new-build-checks.ipynb | 2390 ++++++++++++++++++++++++++++++++++++ 1 file changed, 2390 insertions(+) create mode 100644 bin/new-build-checks.ipynb diff --git a/bin/new-build-checks.ipynb b/bin/new-build-checks.ipynb new file mode 100644 index 00000000..bd467cce --- /dev/null +++ b/bin/new-build-checks.ipynb @@ -0,0 +1,2390 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ca1e904e-a043-46eb-97d9-c6e073157643", + "metadata": {}, + "source": [ + "Catalog build sanity checker\n", + "============================\n", + "\n", + "This notebook is designed to do some basic sanity checking on new `access-nri-intake-catalog` catalog builds, and to examine the experiments that have made it into the new catalog." + ] + }, + { + "cell_type": "markdown", + "id": "6f4e0c57-9c5a-431c-9b76-c1fc67ca6bbc", + "metadata": {}, + "source": [ + "Basic setup\n", + "-----------" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c2e5f307-fc4c-44fe-838f-2f67839e218f", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4f486d1d-99c4-455e-a9b2-f80a925480d6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.0.0'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import access_nri_intake\n", + "\n", + "access_nri_intake.__version__" + ] + }, + { + "cell_type": "markdown", + "id": "51b7c298-e660-45f2-818f-063c0c97e490", + "metadata": {}, + "source": [ + "Load catalog & compare to older catalog\n", + "-----" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "f31e8849-2428-4ed0-afb6-7b342587e62c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

access_nri catalog with 101 source(s) across 2357 rows:

\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
modeldescriptionrealmfrequencyvariable
name
01deg_jra55v13_ryf9091{ACCESS-OM2-01}{0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.3 RYF9091 repeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 3hr, 3mon, fx, 1day}{xt_ocean, sfc_salt_flux_restore, average_T2, shear_m, fmelttn_ai_m, rhoave, alvdf_ai_m, temp_surface_ave, eta_t, total_ocean_river, total_ocean_river_heat, total_ocean_heat, bih_fric_v, NCAT, mel...
01deg_jra55v140_iaf{ACCESS-OM2-01}{Cycle 1 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, shear_m, daidtd_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, bih_fric_v, frazil...
01deg_jra55v140_iaf_cycle2{ACCESS-OM2-01}{Cycle 2 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, shear_m, daidtd_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, bih_fric_v, frazil...
01deg_jra55v140_iaf_cycle3{ACCESS-OM2-01}{Cycle 3 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, shear_m, daidtd_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, frazil, NCAT, fsur...
01deg_jra55v140_iaf_cycle4{ACCESS-OM2-01}{Cycle 4 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 3hr, 6hr, fx, 1day}{xt_ocean, paco2, alvdf_ai_m, phy, adic_int100, surface_dic, total_ocean_river_heat, surface_no3, aice_h, fsurf_ai_m, melt, geolon_c, grid_xt_ocean, surface_pot_temp_max, fswthru_ai_m, fswthru_ai,...
01deg_jra55v140_iaf_cycle4_jra55v150_extension{ACCESS-OM2-01}{Extensions of cycle 4 of 0.1 degree ACCESS-OM2 + WOMBAT BGC global model configuration with JRA55-do v1.5.0 and v1.5.0.1 interannual forcing}{ocean, seaIce}{1mon, 1day, subhr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, adic_int100, surface_dic, total_ocean_river_heat, surface_no3, fsurf_ai_m, melt, geolon_c, grid_xt_ocean, surface_pot_temp_max, fswthru_ai_m, fswthru_ai, dvidtt_...
01deg_jra55v150_iaf_cycle1{ACCESS-OM2}{Cycle 1 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.5.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, eta_t, melt, sfc_hflux_coupler, geolon_c, grid_xt_ocean, sfc_salt_flux_coupler, evap, average_T1, ekman_we, sfc_hflux_from_runoff, sea_level, TLAT, pm...
025deg_era5_iaf{ACCESS-OM2}{0.25 degree ACCESS-OM2 global model configuration with ERA5 interannual\\nforcing (1980-2021)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_x...
025deg_era5_ryf{ACCESS-OM2}{0.25 degree ACCESS-OM2 global model configuration with ERA5 RYF9091 repeat\\nyear forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_x...
025deg_jra55_iaf_era5comparison{ACCESS-OM2}{0.25 degree ACCESS-OM2 global model configuration with JRA55-do v1.5.0\\ninterannual forcing (1980-2019)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, shear_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_submeso...
025deg_jra55_iaf_omip2_cycle1{ACCESS-OM2}{Cycle 1/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, alvdf_ai_m, total_ocean_river_heat, temp_xflux_submeso_int_z, fsurf_ai_m, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekma...
025deg_jra55_iaf_omip2_cycle2{ACCESS-OM2}{Cycle 1/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, alvdf_ai_m, total_ocean_river_heat, temp_xflux_submeso_int_z, fsurf_ai_m, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekma...
025deg_jra55_iaf_omip2_cycle3{ACCESS-OM2}{Cycle 3/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, alvdf_ai_m, total_ocean_river_heat, temp_xflux_submeso_int_z, fsurf_ai_m, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekma...
025deg_jra55_iaf_omip2_cycle4{ACCESS-OM2}{Cycle 4/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, alvdf_ai_m, total_ocean_river_heat, temp_xflux_submeso_int_z, fsurf_ai_m, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekma...
025deg_jra55_iaf_omip2_cycle5{ACCESS-OM2}{Cycle 5/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, alvdf_ai_m, total_ocean_river_heat, temp_xflux_submeso_int_z, fsurf_ai_m, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekma...
025deg_jra55_iaf_omip2_cycle6{ACCESS-OM2}{Cycle 6/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, alvdf_ai_m, total_ocean_river_heat, temp_xflux_submeso_int_z, fsurf_ai_m, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekma...
025deg_jra55_ryf9091_gadi{ACCESS-OM2}{0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.3 RYF9091 repeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1yr, fx}{sfc_salt_flux_restore, xt_ocean, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, eta_t, total_ocean_river, total_ocean_river_heat, total_ocean_heat,...
025deg_jra55_ryf_era5comparison{ACCESS-OM2}{0.25 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0\\nRYF9091 repeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_x...
1deg_era5_iaf{ACCESS-OM2}{1 degree ACCESS-OM2 global model configuration with ERA5 interannual\\nforcing (1960-2019)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_x...
1deg_era5_ryf{ACCESS-OM2}{1 degree ACCESS-OM2 global model configuration with ERA5 RYF9091 repeat\\nyear forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_x...
1deg_jra55_iaf_era5comparison{ACCESS-OM2}{1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0\\ninterannual forcing (1960-2019)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_x...
1deg_jra55_iaf_omip2_cycle1{ACCESS-OM2}{Cycle 1/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, d...
1deg_jra55_iaf_omip2_cycle2{ACCESS-OM2}{Cycle 2/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, d...
1deg_jra55_iaf_omip2_cycle3{ACCESS-OM2}{Cycle 3/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, d...
1deg_jra55_iaf_omip2_cycle4{ACCESS-OM2}{Cycle 4/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, d...
1deg_jra55_iaf_omip2_cycle5{ACCESS-OM2}{Cycle 5/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, d...
1deg_jra55_iaf_omip2_cycle6{ACCESS-OM2}{Cycle 6/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, d...
1deg_jra55_iaf_omip2spunup_cycle1{ACCESS-OM2}{Cycle 1/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, fswthru_ai_m, pbot_adjust, dvidtt_m, no3os_raw, sa...
1deg_jra55_iaf_omip2spunup_cycle10{ACCESS-OM2}{Cycle 10/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle11{ACCESS-OM2}{Cycle 11/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle12{ACCESS-OM2}{Cycle 12/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle13{ACCESS-OM2}{Cycle 13/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle14{ACCESS-OM2}{Cycle 14/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle15{ACCESS-OM2}{Cycle 15/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle16{ACCESS-OM2}{Cycle 16/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle17{ACCESS-OM2}{Cycle 17/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle18{ACCESS-OM2}{Cycle 18/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle19{ACCESS-OM2}{Cycle 19/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle2{ACCESS-OM2}{Cycle 2/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, fswthru_ai_m, pbot_adjust, dvidtt_m, no3os_raw, sa...
1deg_jra55_iaf_omip2spunup_cycle20{ACCESS-OM2}{Cycle 20/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle21{ACCESS-OM2}{Cycle 21/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle22{ACCESS-OM2}{Cycle 22/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle23{ACCESS-OM2}{Cycle 23/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle24{ACCESS-OM2}{Cycle 24/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle25{ACCESS-OM2}{Cycle 25/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle26{ACCESS-OM2}{Cycle 26/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle27{ACCESS-OM2}{Cycle 27/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle28{ACCESS-OM2}{Cycle 28/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle29{ACCESS-OM2}{Cycle 29/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle3{ACCESS-OM2}{Cycle 3/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, fswthru_ai_m, pbot_adjust, dvidtt_m, no3os_raw, sa...
1deg_jra55_iaf_omip2spunup_cycle30{ACCESS-OM2}{Cycle 30/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle31{ACCESS-OM2}{Cycle 31/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle32{ACCESS-OM2}{Cycle 32/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle33{ACCESS-OM2}{Cycle 33/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle34{ACCESS-OM2}{Cycle 34/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, phy, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_heat, total_ocean_heat...
1deg_jra55_iaf_omip2spunup_cycle35{ACCESS-OM2}{Cycle 35/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, phy, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_heat, total_ocean_heat...
1deg_jra55_iaf_omip2spunup_cycle36{ACCESS-OM2}{Cycle 36/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, phy, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_heat, total_ocean_heat...
1deg_jra55_iaf_omip2spunup_cycle37{ACCESS-OM2}{Cycle 37/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, phy, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_heat, total_ocean_heat...
1deg_jra55_iaf_omip2spunup_cycle38{ACCESS-OM2}{Cycle 38/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, phy, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_heat, total_ocean_heat...
1deg_jra55_iaf_omip2spunup_cycle39{ACCESS-OM2}{Cycle 39/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, phy, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_heat, total_ocean_heat...
1deg_jra55_iaf_omip2spunup_cycle4{ACCESS-OM2}{Cycle 4/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, grid_xt_ocean, tx_trans_rho_gm, fswthru_ai_m, pbot_adjust, dvidtt_m, no3os_raw, sa...
1deg_jra55_iaf_omip2spunup_cycle40{ACCESS-OM2}{Cycle 40/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle41{ACCESS-OM2}{Cycle 41/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle42{ACCESS-OM2}{Cycle 42/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle43{ACCESS-OM2}{Cycle 43/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle44{ACCESS-OM2}{Cycle 44/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle45{ACCESS-OM2}{Cycle 45/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle5{ACCESS-OM2}{Cycle 5/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, phy, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_heat, total_ocean_heat...
1deg_jra55_iaf_omip2spunup_cycle6{ACCESS-OM2}{Cycle 6/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, phy, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_heat, total_ocean_heat...
1deg_jra55_iaf_omip2spunup_cycle7{ACCESS-OM2}{Cycle 7/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1day, 1mon, 1yr}{xt_ocean, shear_m, average_T2, daidtd_m, fhocn_ai_m, fmelttn_ai_m, alvdf_ai_m, phy, temp_surface_ave, frazil, NCAT, strtlty_m, uatm_m, tarea, fswabs_ai_m, strintx_m, alidf_ai_m, average_T1, trsig...
1deg_jra55_iaf_omip2spunup_cycle8{ACCESS-OM2}{Cycle 8/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_iaf_omip2spunup_cycle9{ACCESS-OM2}{Cycle 9/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{xt_ocean, average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, fswup_m, NCAT, uatm_m, time_bounds, tarea, time, eta_global, stf09, age_global, ad...
1deg_jra55_ryf9091_gadi{ACCESS-OM2}{1 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.3 RYF9091 repeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1yr, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, eta_t, total_ocean_river, total_ocean_river_heat, total_ocean_heat,...
1deg_jra55v14_ryf{ACCESS-OM2}{1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 RYF9091\\nrepeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1day, fx}{xt_ocean, sfc_salt_flux_restore, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, shear_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_x...
HI_CN_05{ACCESS-ESM1-5}{Historical run using same configuration as CMIP6 ACCESS-ESM1.5 historical r1i1p1f1, but with phosphorus limitation disabled within CASA-CNP}{seaIce, ocean, atmos}{1mon, 3hr, 1yr, 6hr, 1day}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
HI_C_05_r1{ACCESS-ESM1-5}{Historical run using same configuration as CMIP6 ACCESS-ESM1.5 historical r1i1p1f1, but with nitrogen and phosphorus limitations disabled within CASA-CNP}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
HI_nl_C_05_r1{ACCESS-ESM1-5}{Historical run using same configuration as CMIP6 ACCESS-ESM1.5 historical r1i1p1f1, but with nitrogen and phosphorus limitations disabled within CASA-CNP, and land-use change disabled}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
HI_noluc_CN_05{ACCESS-ESM1-5}{Historical run using same configuration as CMIP6 ACCESS-ESM1.5 historical r1i1p1f1, but with phosphorus limitation disabled within CASA-CNP, and land-use change disabled}{seaIce, ocean, atmos}{1mon, 3hr, 1yr, 6hr, 1day}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
OM4_025.JRA_RYF{SIS2, MOM6}{0.25 degree GFDL-OM4 (MOM6+SIS2) global model configuration under 1990-1991 JRA55-do repeat year forcing.}{ocean, seaIce}{1mon, 1day, 1yr, fx}{average_T2, dxCv, volo, net_massin, fsitherm, xh, hflso, geolon_c, geolat_u, areacello_bu, tauvo, heat_content_cond, masso, hfrunoffds, uh, average_T1, umo, zossq, zosmin, sithick, vmo, prsn, Cor...
PI_GWL_B2035{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2035 }{seaIce, ocean, atmos}{1mon, 1day, 1yr}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
PI_GWL_B2040{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2040}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
PI_GWL_B2045{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2045}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
PI_GWL_B2050{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2050}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
PI_GWL_B2055{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2055}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
PI_GWL_B2060{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2060}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{xt_ocean, paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho...
barpa_py18{BARPA-R}{Bureau of Meteorology Atmospheric Regional Projections for Australia (BARPA)}{none}{1mon, 6hr, fx, 1hr, 1day}{huss, wa925, sfcWind, rsdsdir, uas, ua1500m, va100, hus20, ua30, va500, rlut, ta100, hus150, omega500, va10, hus925, wa50, va200m, ta150, mrfsol, wa250, wa200, zg50, vasmean, ua50, evspsblpot, pr...
bx944{ACCESS-CM2}{Standard CMIP6 historical simulation, control experiment for by473 pacemaker experiment (948d8676-2c56-49db-8ea1-b80572b074c8)}{seaIce, ocean, atmos}{1mon, 1day}{xt_ocean, total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, grid_xt_ocean, tx_trans_rho_gm, sitempsnic...
by473{ACCESS-CM2}{Pacemaker variation of CMIP6 historical simulation, Topical Atlantic region replaced with fixed SSTs from observations}{seaIce, ocean, atmos}{1mon, 1day}{xt_ocean, total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, grid_xt_ocean, tx_trans_rho_gm, sitempsnic...
by578{ACCESS-CM2}{Pacemaker variation of CMIP6 ssp245 simulation with Tropical Atlantic region replaced with fixed SSTs from observations}{seaIce, ocean, atmos}{1mon, 1day}{xt_ocean, total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, grid_xt_ocean, tx_trans_rho_gm, sitempsnic...
by647{ACCESS-CM2}{Standard CMIP6 ssp245 simulation, control experiment for by578 pacemaker experiment (1fd9e682-d393-4b17-a9cd-934c3a48a1f8)}{seaIce, ocean, atmos}{1mon, 1day}{xt_ocean, total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, grid_xt_ocean, tx_trans_rho_gm, sitempsnic...
bz687{ACCESS-CM2}{ACCESS-CM2 CMIP6 with 1 degree ocean. Present day atmospheric forcing with 1985-2014 mean GHG, aerosol emissions etc.}{seaIce, ocean, atmos}{1mon, 1day}{xt_ocean, total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, grid_xt_ocean, tx_trans_rho_gm, sitempsnic...
cj877{ACCESS-CM2}{ACCESS-CM2 with COSIMA OM2 0.25 degree ocean configuration. Present day atmospheric forcing with 1985-2014 mean GHG, aerosol emissions etc.}{seaIce, ocean, atmos}{1mon, 1day, fx}{xt_ocean, total_ocean_river_heat, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, melt, geolon_c, fld_s03i825, fld_s00i436, grid_xt_ocean, surface_pot_temp_max, sitempsnic, theta...
cmip5_al33{CSIRO-QCCCE-CSIRO-Mk3-6-0, IPSL-CM5A-MR, GEOS-5, CESM1-CAM5, CSIRO-BOM-ACCESS1-0, GFDL-ESM2M, MIROC-ESM, CMCC-CM, miroc5, GISS-E2-H-CC, CESM1-BGC, fio-esm, MIROC-MIROC5, HadCM3, NorESM1-M, GFDL-C...{Replicated CMIP5-era datasets catalogued by NCI}{landIce, land, ocnBgchem, none, atmos, aerosol, ocean, seaIce}{1mon, 3hr, 1yr, subhr, 6hr, fx, 1day}{rsdcs, concdms, zsatcalc, tnsccwbl, bsi, fsitherm, reffclws, va500, tnsccwcm, tnsccwce, hfrunoffds, wetdms, hus, strairy, reffclic, zossq, toffset, tntr, loadpoa, va, hfcorr, lwsnl, cdnc, od550ae...
cmip5_rr3{CSIRO-BOM-ACCESS1-0, GFDL-ESM2M, MIROC-ESM, CSIRO-BOM-ACCESS1-3, MIROC-MIROC5, CSIRO-Mk3L-1-2, NorESM1-M, IPSL-CM5B-LR, NCC-NorESM1-M, CanESM2, MRI-CGCM3, NOAA-GFDL-GFDL-CM3, MPI-ESM-LR, MPI-ESM-...{Australian CMIP5-era datasets catalogued by NCI}{landIce, land, none, atmos, aerosol, ocean, seaIce}{1mon, 3hr, 3mon, 6hr, fx, 1hr, 1day}{concoa, concdms, huss, sfcWind, tossq, uas, volo, treeFrac, sconcbc, grassFrac, fsitherm, basin, rlut, va500, transix, shrubFrac, tauvo, concdust, masso, hfrunoffds, msftyrhoz, sconcdust, hus, um...
cmip6_fs38{ACCESS-OM2-025, ACCESS-OM2, ACCESS-CM2, ACCESS-ESM1-5}{Australian CMIP6-era datasets catalogued by NCI}{landIce, land, ocnBgchem, atmos, aerosol, ocean, seaIce}{1mon, 3hr, 1yr, 6hr, fx, 1day}{fsitherm, dissicnatos, phycos, sndmasssi, grassFracC3, hus, zossq, va, siextents, sisnhc, od550aer, sihc, sidconcth, nLitter, mrsol, treeFracBdlEvg, zos, tsl, rsutcs, sisnthick, sidmasstranx, rsd...
cmip6_oi10{NorCPM1, NorESM2-MM, GFDL-OM4p5B, CESM2, EC-Earth3-Veg, ACCESS-OM2-025, CMCC-CM2-SR5, GISS-E2-1-H, CESM2-FV2, HadGEM3-GC31-LM, CIESM, CanESM5-1, HiRAM-SIT-HR, BCC-CSM2-MR, CNRM-ESM2-1, CESM1-CAM5...{Replicated CMIP6-era datasets catalogued by NCI}{land, ocnBgchem, landIce, atmosChem, atmos, aerosol, ocean, seaIce}{1mon, 3hr, 1yr, subhr, 6hr, fx, 1hr, 1day}{fsitherm, opottemptend, dissicnatos, sitempsnic, grassFracC3, hus, zossq, va, hfcorr, lwsnl, od550aer, hfibthermds, sihc, nLitter, mrsol, laiLut, treeFracBdlEvg, zos, fco2fos, cOther, tsl, rsutcs...
era5_rt52{era5-1, era5, era5-preliminary, era5-derived, era5t}{ERA5 fifth generation model reanalysis of global climate from ECMWF}{none}{1day, 1mon, 1hr}{tcwv, mper, mvimd, viwvn, strdc, lai-lv, vike, cvh, cvl, ssrdc, ishf, lict, msdwlwrf, lmlt, sshf, lai-hv, tvh, mpww, sp, sro, msnswrfcs, aluvd, viiwd, z, mror, tciw, gwd, msqs, mpts, dndza, istl2...
narclim2_zz63{ACCESS-ESM1-5, UKESM1-0-LL, NorESM2-MM, MPI-ESM1-2-HR, EC-Earth3-Veg}{NARCliM2.0 climate pojections, downscaled from ACCESS-ESM1-5 over Australasia at ~18km resolution.}{atmos}{1mon, 3hr, fx, 1hr, 1day}{vegFrac, huss, wa925, sfcWind, rsdsdir, uas, va100, va500, rlut, ta100, hus150, va200m, hus925, wa750, ta150, wa250, wa200, prsn, tasmin, zg400, hus400, psl, hus300, ua150, wa400, prhmax, hus600,...
panant-01-hycom1-v13{SIS2, MOM6}{0.1 degree (MOM6+SIS2) Pan-Antarctic regional model configuration under 1990-1991 JRA55-do repeat year forcing with a hybrid (HYCOM1) vertical coordinate..}{ocean, seaIce}{1mon, 1day, fx}{dxCu, average_T2, geolat_c, dxCv, xh, geolon_c, siconc, geolat_u, areacello_bu, time, z_i, tauvo, geolon_v, wet_v, wet, areacello, time_bnds, geolon, volcello, geolon_u, average_T1, areacello_cv,...
panant-01-zstar-v13{SIS2, MOM6}{0.1 degree (MOM6+SIS2) Pan-Antarctic regional model configuration under 1990-1991 JRA55-do repeat year forcing.}{ocean, seaIce}{1mon, 1day, fx}{average_T2, dxCv, xh, geolon_c, geolat_u, areacello_bu, tauvo, intz_gKEu_2d, tauy_bot, average_T1, umo, col_height, sithick, vmo, intz_u_BT_accel_2d, Coriolis, wet_c, z_l, tos, zos, sos, areacell...
rcm_ccam_hq89{CMCC-ESM2, ACCESS-ESM1-5, NorESM2-MM, EC-Earth3, ERA5, CESM2, CNRM-ESM2-1, ACCESS-CM2}{CMIP6 Regional Climate Model Data from CCAM for Australian Climate Service}{none}{1mon, 6hr, fx, 1hr, 1day}{huss, wa925, sfcWind, rsdsdir, uas, sfturf, va500, rlut, va200m, hus925, mrfsol, wa250, wa200, evspsblpot, prsn, tasmin, zg400, hus400, psl, hus300, sund, wa400, prhmax, mrsol, hus600, prw, zg300...
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import intake\n", + "\n", + "cat = intake.cat.access_nri\n", + "cat" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "12cad695-c09a-4edb-9b91-f9c381289e81", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2357" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(cat.df)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "0a3c2c5e-ec8a-47f5-8a94-ac4d7d8e59a5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "v2024-12-10*\n", + "v2024-11-08\n", + "v2024-10-02(-->v0.1.3)\n", + "v2024-03-28(-->v0.1.2)\n", + "v2024-03-04(-->v0.1.1)\n", + "v2023-11-29(-->v0.1.0)\n", + "v2023-09-29(-->v0.0.10)\n", + "v2023-07-20(-->v0.0.9)\n", + "v2023-07-10(-->v0.0.8)\n" + ] + } + ], + "source": [ + "from access_nri_intake.data.utils import available_versions\n", + "\n", + "available_versions()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "0a92dc22-f197-47ca-b0cf-8c37bdd2c2a1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

access_nri catalog with 94 source(s) across 2272 rows:

\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
modeldescriptionrealmfrequencyvariable
name
01deg_jra55v13_ryf9091{ACCESS-OM2}{0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.3 RYF9091 repeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 3hr, 3mon, fx, 1day}{sfc_salt_flux_restore, shear_m, average_T2, fmelttn_ai_m, rhoave, alvdf_ai_m, temp_surface_ave, eta_t, total_ocean_river, total_ocean_river_heat, total_ocean_heat, bih_fric_v, NCAT, melt, sfc_hfl...
01deg_jra55v140_iaf{ACCESS-OM2}{Cycle 1 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fmelttn_ai_m, rhoave, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, bih_fric_v, frazil, NCAT, me...
01deg_jra55v140_iaf_cycle2{ACCESS-OM2}{Cycle 2 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fmelttn_ai_m, rhoave, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, bih_fric_v, frazil, NCAT, fs...
01deg_jra55v140_iaf_cycle3{ACCESS-OM2}{Cycle 3 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fmelttn_ai_m, rhoave, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, frazil, NCAT, fsurf_ai_m, me...
01deg_jra55v140_iaf_cycle4{ACCESS-OM2}{Cycle 4 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 3hr, 6hr, fx, 1day}{paco2, alvdf_ai_m, adic_int100, phy, surface_dic, total_ocean_river_heat, surface_no3, aice_h, fsurf_ai_m, melt, geolon_c, surface_pot_temp_max, fswthru_ai_m, fswthru_ai, dvidtt_m, no3_zflux_adv,...
01deg_jra55v140_iaf_cycle4_jra55v150_extension{ACCESS-OM2}{Extensions of cycle 4 of 0.1 degree ACCESS-OM2 + WOMBAT BGC global model configuration with JRA55-do v1.5.0 and v1.5.0.1 interannual forcing}{ocean, seaIce}{1mon, 1day, subhr, fx}{sfc_salt_flux_restore, shear_m, total_co2_flux, average_T2, daidtd_m, rhoave, paco2, fhocn_ai_m, alvdf_ai_m, adic_int100, temp_surface_ave, phy, total_ocean_river, surface_dic, total_ocean_river_...
01deg_jra55v150_iaf_cycle1{ACCESS-OM2}{Cycle 1 of 0.1 degree ACCESS-OM2 global model configuration with JRA55-do v1.5.0 OMIP2 interannual forcing}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, average_T2, eta_t, melt, sfc_hflux_coupler, geolon_c, sfc_salt_flux_coupler, evap, average_T1, ekman_we, sfc_hflux_from_runoff, sea_level, TLAT, pme_net, v, tx_trans, ty_tr...
025deg_era5_iaf{ACCESS-OM2}{0.25 degree ACCESS-OM2 global model configuration with ERA5 interannual\\nforcing (1980-2021)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_subme...
025deg_era5_ryf{ACCESS-OM2}{0.25 degree ACCESS-OM2 global model configuration with ERA5 RYF9091 repeat\\nyear forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_subme...
025deg_jra55_iaf_era5comparison{ACCESS-OM2}{0.25 degree ACCESS-OM2 global model configuration with JRA55-do v1.5.0\\ninterannual forcing (1980-2019)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_submeso_int_z, fr...
025deg_jra55_iaf_omip2_cycle1{ACCESS-OM2}{Cycle 1/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, shear_m, average_T2, vvel_m, salt_tendency, rhoave, daidtd_m, fhocn_ai_m, alvdf_ai_m, fmelttn_ai_m, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_he...
025deg_jra55_iaf_omip2_cycle2{ACCESS-OM2}{Cycle 1/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, shear_m, average_T2, vvel_m, salt_tendency, rhoave, daidtd_m, fhocn_ai_m, alvdf_ai_m, fmelttn_ai_m, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_he...
025deg_jra55_iaf_omip2_cycle3{ACCESS-OM2}{Cycle 3/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, shear_m, average_T2, vvel_m, salt_tendency, rhoave, daidtd_m, fhocn_ai_m, alvdf_ai_m, fmelttn_ai_m, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_he...
025deg_jra55_iaf_omip2_cycle4{ACCESS-OM2}{Cycle 4/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, shear_m, average_T2, vvel_m, salt_tendency, rhoave, daidtd_m, fhocn_ai_m, alvdf_ai_m, fmelttn_ai_m, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_he...
025deg_jra55_iaf_omip2_cycle5{ACCESS-OM2}{Cycle 5/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, shear_m, average_T2, vvel_m, salt_tendency, rhoave, daidtd_m, fhocn_ai_m, alvdf_ai_m, fmelttn_ai_m, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_he...
025deg_jra55_iaf_omip2_cycle6{ACCESS-OM2}{Cycle 6/6 of 0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2019)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, vvel_m, salt_tendency, rhoave, daidtd_m, fhocn_ai_m, alvdf_ai_m, fmelttn_ai_m, sst_sq, temp_surface_ave, total_ocean_river, eta_t, total_ocean_river_he...
025deg_jra55_ryf9091_gadi{ACCESS-OM2}{0.25 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.3 RYF9091 repeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1yr, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, eta_t, total_ocean_river, total_ocean_river_heat, total_ocean_heat, NCAT, geo...
025deg_jra55_ryf_era5comparison{ACCESS-OM2}{0.25 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0\\nRYF9091 repeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_subme...
1deg_era5_iaf{ACCESS-OM2}{1 degree ACCESS-OM2 global model configuration with ERA5 interannual\\nforcing (1960-2019)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_subme...
1deg_era5_ryf{ACCESS-OM2}{1 degree ACCESS-OM2 global model configuration with ERA5 RYF9091 repeat\\nyear forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_subme...
1deg_jra55_iaf_era5comparison{ACCESS-OM2}{1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0\\ninterannual forcing (1960-2019)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_subme...
1deg_jra55_iaf_omip2_cycle1{ACCESS-OM2}{Cycle 1/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekman_we, no3os_...
1deg_jra55_iaf_omip2_cycle2{ACCESS-OM2}{Cycle 2/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekman_we, no3os_...
1deg_jra55_iaf_omip2_cycle3{ACCESS-OM2}{Cycle 3/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekman_we, no3os_...
1deg_jra55_iaf_omip2_cycle4{ACCESS-OM2}{Cycle 4/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekman_we, no3os_...
1deg_jra55_iaf_omip2_cycle5{ACCESS-OM2}{Cycle 5/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekman_we, no3os_...
1deg_jra55_iaf_omip2_cycle6{ACCESS-OM2}{Cycle 6/6 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, surface_pot_temp_max, fswthru_ai_m, pbot_adjust, dvidtt_m, ekman_we, no3os_...
1deg_jra55_iaf_omip2spunup_cycle1{ACCESS-OM2}{Cycle 1/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, fswthru_ai_m, pbot_adjust, dvidtt_m, no3os_raw, salt_rivermix, meltb_m, pme...
1deg_jra55_iaf_omip2spunup_cycle10{ACCESS-OM2}{Cycle 10/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle11{ACCESS-OM2}{Cycle 11/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle12{ACCESS-OM2}{Cycle 12/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle13{ACCESS-OM2}{Cycle 13/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle14{ACCESS-OM2}{Cycle 14/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle15{ACCESS-OM2}{Cycle 15/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle16{ACCESS-OM2}{Cycle 16/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle17{ACCESS-OM2}{Cycle 17/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle18{ACCESS-OM2}{Cycle 18/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle19{ACCESS-OM2}{Cycle 19/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle2{ACCESS-OM2}{Cycle 2/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, fswthru_ai_m, pbot_adjust, dvidtt_m, no3os_raw, salt_rivermix, meltb_m, pme...
1deg_jra55_iaf_omip2spunup_cycle20{ACCESS-OM2}{Cycle 20/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle21{ACCESS-OM2}{Cycle 21/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle22{ACCESS-OM2}{Cycle 22/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle23{ACCESS-OM2}{Cycle 23/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle24{ACCESS-OM2}{Cycle 24/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle25{ACCESS-OM2}{Cycle 25/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle26{ACCESS-OM2}{Cycle 26/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle27{ACCESS-OM2}{Cycle 27/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle28{ACCESS-OM2}{Cycle 28/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle29{ACCESS-OM2}{Cycle 29/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle3{ACCESS-OM2}{Cycle 3/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, fswthru_ai_m, pbot_adjust, dvidtt_m, no3os_raw, salt_rivermix, meltb_m, pme...
1deg_jra55_iaf_omip2spunup_cycle30{ACCESS-OM2}{Cycle 30/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle31{ACCESS-OM2}{Cycle 31/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle32{ACCESS-OM2}{Cycle 32/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle33{ACCESS-OM2}{Cycle 33/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle34{ACCESS-OM2}{Cycle 34/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, o2os_raw, sst_sq, temp_surface_ave, total_ocean_river, phy, total_ocean_river_heat, total_ocean_heat, temp_...
1deg_jra55_iaf_omip2spunup_cycle35{ACCESS-OM2}{Cycle 35/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, o2os_raw, sst_sq, temp_surface_ave, total_ocean_river, phy, total_ocean_river_heat, total_ocean_heat, temp_...
1deg_jra55_iaf_omip2spunup_cycle36{ACCESS-OM2}{Cycle 36/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, o2os_raw, sst_sq, temp_surface_ave, total_ocean_river, phy, total_ocean_river_heat, total_ocean_heat, temp_...
1deg_jra55_iaf_omip2spunup_cycle37{ACCESS-OM2}{Cycle 37/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, o2os_raw, sst_sq, temp_surface_ave, total_ocean_river, phy, total_ocean_river_heat, total_ocean_heat, temp_...
1deg_jra55_iaf_omip2spunup_cycle38{ACCESS-OM2}{Cycle 38/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, o2os_raw, sst_sq, temp_surface_ave, total_ocean_river, phy, total_ocean_river_heat, total_ocean_heat, temp_...
1deg_jra55_iaf_omip2spunup_cycle39{ACCESS-OM2}{Cycle 39/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, o2os_raw, sst_sq, temp_surface_ave, total_ocean_river, phy, total_ocean_river_heat, total_ocean_heat, temp_...
1deg_jra55_iaf_omip2spunup_cycle4{ACCESS-OM2}{Cycle 4/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{paco2, alvdf_ai_m, phy, surface_dic, total_ocean_river_heat, temp_xflux_submeso_int_z, melt, geolon_c, tx_trans_rho_gm, fswthru_ai_m, pbot_adjust, dvidtt_m, no3os_raw, salt_rivermix, meltb_m, pme...
1deg_jra55_iaf_omip2spunup_cycle40{ACCESS-OM2}{Cycle 40/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle41{ACCESS-OM2}{Cycle 41/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle42{ACCESS-OM2}{Cycle 42/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle43{ACCESS-OM2}{Cycle 43/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle44{ACCESS-OM2}{Cycle 44/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle45{ACCESS-OM2}{Cycle 45/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle5{ACCESS-OM2}{Cycle 5/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, o2os_raw, sst_sq, temp_surface_ave, total_ocean_river, phy, total_ocean_river_heat, total_ocean_heat, temp_...
1deg_jra55_iaf_omip2spunup_cycle6{ACCESS-OM2}{Cycle 6/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1day, 1yr, fx}{sfc_salt_flux_restore, average_T2, phyos_raw, salt_tendency, rhoave, paco2, alvdf_ai_m, o2os_raw, sst_sq, temp_surface_ave, total_ocean_river, phy, total_ocean_river_heat, total_ocean_heat, temp_...
1deg_jra55_iaf_omip2spunup_cycle7{ACCESS-OM2}{Cycle 7/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1day, 1mon, 1yr}{shear_m, average_T2, daidtd_m, fhocn_ai_m, fmelttn_ai_m, alvdf_ai_m, phy, temp_surface_ave, frazil, NCAT, strtlty_m, uatm_m, tarea, fswabs_ai_m, strintx_m, alidf_ai_m, average_T1, trsig_m, fswthr...
1deg_jra55_iaf_omip2spunup_cycle8{ACCESS-OM2}{Cycle 8/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_iaf_omip2spunup_cycle9{ACCESS-OM2}{Cycle 9/45 of 1 degree ACCESS-OM2-BGC global configuration with JRA55-do v1.4 OMIP2 spunup interannual forcing (1958-2018)}{ocean, seaIce}{1mon, 1yr}{average_T2, total_volume_seawater, dyu, aicen_m, alvdf_ai_m, TLON, phy, temp_surface_ave, aice_m, sss, NCAT, fswup_m, uatm_m, time_bounds, tarea, eta_global, stf09, adic, age_global, sst, no3, al...
1deg_jra55_ryf9091_gadi{ACCESS-OM2}{1 degree ACCESS-OM2 physics-only global configuration with JRA55-do v1.3 RYF9091 repeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1yr, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, eta_t, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_vdif...
1deg_jra55v14_ryf{ACCESS-OM2}{1 degree ACCESS-OM2 global model configuration with JRA55-do v1.4.0 RYF9091\\nrepeat year forcing (May 1990 to Apr 1991)}{ocean, seaIce}{1mon, 1day, fx}{sfc_salt_flux_restore, shear_m, average_T2, daidtd_m, fhocn_ai_m, rhoave, fmelttn_ai_m, alvdf_ai_m, temp_surface_ave, total_ocean_river, total_ocean_river_heat, total_ocean_heat, temp_xflux_subme...
HI_CN_05{ACCESS-ESM1-5}{Historical run using same configuration as CMIP6 ACCESS-ESM1.5 historical r1i1p1f1, but with phosphorus limitation disabled within CASA-CNP}{seaIce, ocean, atmos}{1mon, 3hr, 1yr, 6hr, 1day}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
HI_C_05_r1{ACCESS-ESM1-5}{Historical run using same configuration as CMIP6 ACCESS-ESM1.5 historical r1i1p1f1, but with nitrogen and phosphorus limitations disabled within CASA-CNP}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
HI_nl_C_05_r1{ACCESS-ESM1-5}{Historical run using same configuration as CMIP6 ACCESS-ESM1.5 historical r1i1p1f1, but with nitrogen and phosphorus limitations disabled within CASA-CNP, and land-use change disabled}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
HI_noluc_CN_05{ACCESS-ESM1-5}{Historical run using same configuration as CMIP6 ACCESS-ESM1.5 historical r1i1p1f1, but with phosphorus limitation disabled within CASA-CNP, and land-use change disabled}{seaIce, ocean, atmos}{1mon, 3hr, 1yr, 6hr, 1day}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
PI_GWL_B2035{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2035 }{seaIce, ocean, atmos}{1mon, 1day, 1yr}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
PI_GWL_B2040{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2040}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
PI_GWL_B2045{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2045}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
PI_GWL_B2050{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2050}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
PI_GWL_B2055{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2055}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
PI_GWL_B2060{ACCESS-ESM1-5}{Climate stabilization run at different global warming levels with zero C02 emissions and pre-industrial aerosols, starting in 2060}{seaIce, ocean, atmos}{1mon, 1day, 1yr}{paco2, total_ocean_pme_sbc, snow_ai, phy, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, evap_ai, fld_s03i825, fld_s00i436, tx_trans_rho_gm, phyno...
bx944{ACCESS-CM2}{Standard CMIP6 historical simulation, control experiment for by473 pacemaker experiment (948d8676-2c56-49db-8ea1-b80572b074c8)}{seaIce, ocean, atmos}{1mon, 1day}{total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, tx_trans_rho_gm, sitempsnic, temp_xflux_ndiffuse, th...
by473{ACCESS-CM2}{Pacemaker variation of CMIP6 historical simulation, Topical Atlantic region replaced with fixed SSTs from observations}{seaIce, ocean, atmos}{1mon, 1day}{total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, tx_trans_rho_gm, sitempsnic, temp_xflux_ndiffuse, th...
by578{ACCESS-CM2}{Pacemaker variation of CMIP6 ssp245 simulation with Tropical Atlantic region replaced with fixed SSTs from observations}{seaIce, ocean, atmos}{1mon, 1day}{total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, tx_trans_rho_gm, sitempsnic, temp_xflux_ndiffuse, th...
by647{ACCESS-CM2}{Standard CMIP6 ssp245 simulation, control experiment for by578 pacemaker experiment (1fd9e682-d393-4b17-a9cd-934c3a48a1f8)}{seaIce, ocean, atmos}{1mon, 1day}{total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, tx_trans_rho_gm, sitempsnic, temp_xflux_ndiffuse, th...
bz687{ACCESS-CM2}{ACCESS-CM2 CMIP6 with 1 degree ocean. Present day atmospheric forcing with 1985-2014 mean GHG, aerosol emissions etc.}{seaIce, ocean, atmos}{1mon, 1day}{total_ocean_pme_sbc, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, diff_cbt_drag, melt, geolon_c, fld_s03i825, fld_s00i436, tx_trans_rho_gm, sitempsnic, temp_xflux_ndiffuse, th...
cj877{ACCESS-CM2}{ACCESS-CM2 with COSIMA OM2 0.25 degree ocean configuration. Present day atmospheric forcing with 1985-2014 mean GHG, aerosol emissions etc.}{seaIce, ocean, atmos}{1mon, 1day, fx}{total_ocean_river_heat, fld_s08i236, temp_xflux_submeso_int_z, fld_s03i801, fld_s02i284, melt, geolon_c, fld_s03i825, fld_s00i436, surface_pot_temp_max, sitempsnic, theta_level_height, fld_s15i10...
cmip5_al33{CSIRO-QCCCE-CSIRO-Mk3-6-0, IPSL-CM5A-MR, GEOS-5, CESM1-CAM5, CSIRO-BOM-ACCESS1-0, GFDL-ESM2M, MIROC-ESM, CMCC-CM, miroc5, GISS-E2-H-CC, CESM1-BGC, fio-esm, MIROC-MIROC5, HadCM3, NorESM1-M, GFDL-C...{Replicated CMIP5-era datasets catalogued by NCI}{landIce, land, ocnBgchem, none, atmos, aerosol, ocean, seaIce}{1mon, 3hr, 1yr, subhr, 6hr, fx, 1day}{rsdcs, concdms, zsatcalc, tnsccwbl, bsi, fsitherm, reffclws, va500, tnsccwcm, tnsccwce, hfrunoffds, wetdms, hus, strairy, reffclic, zossq, toffset, tntr, loadpoa, va, hfcorr, lwsnl, cdnc, od550ae...
cmip5_rr3{CSIRO-BOM-ACCESS1-0, GFDL-ESM2M, MIROC-ESM, CSIRO-BOM-ACCESS1-3, MIROC-MIROC5, CSIRO-Mk3L-1-2, NorESM1-M, IPSL-CM5B-LR, NCC-NorESM1-M, CanESM2, MRI-CGCM3, NOAA-GFDL-GFDL-CM3, MPI-ESM-LR, MPI-ESM-...{Australian CMIP5-era datasets catalogued by NCI}{landIce, land, none, atmos, aerosol, ocean, seaIce}{1mon, 3hr, 3mon, 6hr, fx, 1hr, 1day}{concoa, concdms, huss, sfcWind, tossq, uas, volo, treeFrac, sconcbc, grassFrac, fsitherm, basin, rlut, va500, transix, shrubFrac, tauvo, concdust, msftyrhoz, hfrunoffds, masso, sconcdust, hus, um...
cmip6_fs38{ACCESS-OM2-025, ACCESS-OM2, ACCESS-CM2, ACCESS-ESM1-5}{Australian CMIP6-era datasets catalogued by NCI}{landIce, land, ocnBgchem, atmos, aerosol, ocean, seaIce}{1mon, 3hr, 1yr, 6hr, fx, 1day}{fsitherm, dissicnatos, phycos, sndmasssi, grassFracC3, hus, zossq, va, siextents, sisnhc, od550aer, sihc, sidconcth, nLitter, mrsol, treeFracBdlEvg, zos, tsl, rsutcs, sisnthick, sidmasstranx, rsd...
cmip6_oi10{NorCPM1, NorESM2-MM, GFDL-OM4p5B, CESM2, EC-Earth3-Veg, ACCESS-OM2-025, CMCC-CM2-SR5, GISS-E2-1-H, CESM2-FV2, HadGEM3-GC31-LM, CIESM, CanESM5-1, HiRAM-SIT-HR, BCC-CSM2-MR, CNRM-ESM2-1, CESM1-CAM5...{Replicated CMIP6-era datasets catalogued by NCI}{land, ocnBgchem, landIce, atmosChem, atmos, aerosol, ocean, seaIce}{1mon, 3hr, 1yr, subhr, 6hr, fx, 1hr, 1day}{fsitherm, opottemptend, dissicnatos, sitempsnic, grassFracC3, hus, zossq, va, hfcorr, lwsnl, od550aer, hfibthermds, sihc, nLitter, mrsol, laiLut, treeFracBdlEvg, zos, fco2fos, cOther, tsl, rsutcs...
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cat_old = intake.cat.access_nri(version=\"v2024-10-02\")\n", + "cat_old" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "0f48e981-5ae6-467e-985c-7a4439c22d50", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2272" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(cat_old.df)" + ] + }, + { + "cell_type": "markdown", + "id": "7e7e3ea7-966c-4c34-a57b-c3944e641594", + "metadata": {}, + "source": [ + "Examine new catalog\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "f7b60678-50a4-4ce5-bc9a-7fedd57ca398", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/proxy/8787/status'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from distributed import Client\n", + "\n", + "client = Client(threads_per_worker=1)\n", + "client.dashboard_link" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "50b4f5b3-a5cc-40c4-93cb-f9f6a802145f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Experiment 01deg_jra55v140_iaf_cycle4_jra55v150_extension : 14273 dataframe rows\n", + "Experiment HI_CN_05 : 9435 dataframe rows\n", + "Experiment narclim2_zz63 : 2492315 dataframe rows\n", + "Experiment 025deg_jra55_iaf_omip2_cycle5 : 1769 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle15 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle33 : 915 dataframe rows\n", + "Experiment HI_noluc_CN_05 : 9435 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle5 : 1281 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle27 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle17 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle34 : 1281 dataframe rows\n", + "Experiment bz687 : 58266 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle39 : 1281 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle29 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle30 : 915 dataframe rows\n", + "Experiment cmip6_fs38 : 1054133 dataframe rows\n", + "Experiment 01deg_jra55v140_iaf : 25924 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle31 : 915 dataframe rows\n", + "Experiment 025deg_jra55_ryf_era5comparison : 3224 dataframe rows\n", + "Experiment panant-01-zstar-v13 : 2136 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle8 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2_cycle5 : 2013 dataframe rows\n", + "Experiment 01deg_jra55v13_ryf9091 : 11947 dataframe rows\n", + "Experiment 01deg_jra55v140_iaf_cycle4 : 131730 dataframe rows\n", + "Experiment 1deg_jra55_iaf_era5comparison : 7860 dataframe rows\n", + "Experiment PI_GWL_B2055 : 43000 dataframe rows\n", + "Experiment 1deg_era5_ryf : 10100 dataframe rows\n", + "Experiment PI_GWL_B2040 : 43000 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2_cycle2 : 2013 dataframe rows\n", + "Experiment 01deg_jra55v140_iaf_cycle3 : 29438 dataframe rows\n", + "Experiment 01deg_jra55v150_iaf_cycle1 : 22848 dataframe rows\n", + "Experiment cj877 : 116522 dataframe rows\n", + "Experiment by473 : 12149 dataframe rows\n", + "Experiment OM4_025.JRA_RYF : 1140 dataframe rows\n", + "Experiment HI_nl_C_05_r1 : 7875 dataframe rows\n", + "Experiment 025deg_jra55_iaf_omip2_cycle4 : 1769 dataframe rows\n", + "Experiment PI_GWL_B2050 : 43000 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2_cycle1 : 2013 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle36 : 1281 dataframe rows\n", + "Experiment barpa_py18 : 987568 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2_cycle6 : 2013 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle41 : 4575 dataframe rows\n", + "Experiment 01deg_jra55v140_iaf_cycle2 : 24954 dataframe rows\n", + "Experiment HI_C_05_r1 : 7873 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle2 : 2013 dataframe rows\n", + "Experiment 025deg_jra55_iaf_omip2_cycle3 : 1808 dataframe rows\n", + "Experiment PI_GWL_B2060 : 43000 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle32 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle24 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle38 : 1281 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle16 : 915 dataframe rows\n", + "Experiment rcm_ccam_hq89 : 637228 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle20 : 915 dataframe rows\n", + "Experiment 025deg_jra55_iaf_omip2_cycle1 : 1769 dataframe rows\n", + "Experiment 025deg_jra55_iaf_omip2_cycle2 : 1769 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle6 : 1281 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle40 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle26 : 915 dataframe rows\n", + "Experiment 025deg_era5_ryf : 3310 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle4 : 1989 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle42 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle9 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle18 : 915 dataframe rows\n", + "Experiment 025deg_era5_iaf : 4884 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle19 : 915 dataframe rows\n", + "Experiment PI_GWL_B2035 : 43000 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle14 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle1 : 2013 dataframe rows\n", + "Experiment panant-01-hycom1-v13 : 280 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle3 : 2013 dataframe rows\n", + "Experiment 1deg_jra55_ryf9091_gadi : 9677 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle44 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle22 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle25 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle13 : 915 dataframe rows\n", + "Experiment 1deg_era5_iaf : 7965 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle10 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle11 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2_cycle3 : 2013 dataframe rows\n", + "Experiment 025deg_jra55_ryf9091_gadi : 8951 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2_cycle4 : 2013 dataframe rows\n", + "Experiment bx944 : 12150 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle45 : 915 dataframe rows\n", + "Experiment PI_GWL_B2045 : 43000 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle37 : 1281 dataframe rows\n", + "Experiment 025deg_jra55_iaf_omip2_cycle6 : 1830 dataframe rows\n", + "Experiment cmip6_oi10 : 3316676 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle35 : 1281 dataframe rows\n", + "Experiment cmip5_rr3 : 2858922 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle12 : 915 dataframe rows\n", + "Experiment by578 : 1350 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle7 : 927 dataframe rows\n", + "Experiment by647 : 1350 dataframe rows\n", + "Experiment 1deg_jra55v14_ryf : 10100 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle23 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle43 : 915 dataframe rows\n", + "Experiment 025deg_jra55_iaf_era5comparison : 4883 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle21 : 915 dataframe rows\n", + "Experiment 1deg_jra55_iaf_omip2spunup_cycle28 : 915 dataframe rows\n", + "Experiment era5_rt52 : 806762 dataframe rows\n", + "Experiment cmip5_al33 : 3700255 dataframe rows\n" + ] + } + ], + "source": [ + "for exp in cat:\n", + " print(f\"Experiment {exp:48s}: {len(cat[exp].df):7d} dataframe rows\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "8f5a8d4b-b926-41d0-aba8-127d01e3bddf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2357" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(cat.df)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "ddcd3468-980c-4a58-aa82-fd708ca9ca04", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([('ACCESS-CM2',), ('ACCESS-ESM1-5',), ('ACCESS-OM2',),\n", + " ('ACCESS-OM2-01',), ('ACCESS-OM2-025',), ('ACCESS1-0',),\n", + " ('ACCESS1-3',), ('AWI-CM-1-1-MR',), ('AWI-ESM-1-1-LR',),\n", + " ('AWI-ESM-1-REcoM',), ('BARPA-R',), ('BCC-CSM2-HR',),\n", + " ('BCC-CSM2-MR',), ('BCC-ESM1',), ('BNU-ESM',), ('CAMS-CSM1-0',),\n", + " ('CAS-ESM2-0',), ('CCCma-CanESM2',), ('CCSM4',),\n", + " ('CESM1-1-CAM5-CMIP5',), ('CESM1-BGC',), ('CESM1-CAM5',),\n", + " ('CESM1-CAM5-1-FV2',), ('CESM1-CAM5-SE-HR',),\n", + " ('CESM1-CAM5-SE-LR',), ('CESM1-FASTCHEM',), ('CESM1-WACCM',),\n", + " ('CESM2',), ('CESM2-FV2',), ('CESM2-WACCM',), ('CESM2-WACCM-FV2',),\n", + " ('CFSv2-2011',), ('CIESM',), ('CMCC-CESM',), ('CMCC-CM',),\n", + " ('CMCC-CM2-HR4',), ('CMCC-CM2-SR5',), ('CMCC-CM2-VHR4',),\n", + " ('CMCC-CMS',), ('CMCC-ESM2',), ('CNRM-CERFACS-CNRM-CM5',),\n", + " ('CNRM-CERFACS-CNRM-CM6-1-HR',), ('CNRM-CM5',), ('CNRM-CM5-2',),\n", + " ('CNRM-CM6-1',), ('CNRM-CM6-1-HR',), ('CNRM-ESM2-1',),\n", + " ('CSIRO-BOM-ACCESS1-0',), ('CSIRO-BOM-ACCESS1-3',),\n", + " ('CSIRO-Mk3-6-0',), ('CSIRO-Mk3L-1-2',),\n", + " ('CSIRO-QCCCE-CSIRO-Mk3-6-0',), ('CanAM4',), ('CanCM4',),\n", + " ('CanESM2',), ('CanESM5',), ('CanESM5-1',), ('CanESM5-CanOE',),\n", + " ('E3SM-1-0',), ('E3SM-1-1',), ('E3SM-1-1-ECA',), ('E3SM-2-0',),\n", + " ('E3SM-2-0-NARRM',), ('EC-EARTH',), ('EC-Earth3',),\n", + " ('EC-Earth3-AerChem',), ('EC-Earth3-CC',), ('EC-Earth3-HR',),\n", + " ('EC-Earth3-LR',), ('EC-Earth3-Veg',), ('EC-Earth3-Veg-LR',),\n", + " ('EC-Earth3P',), ('EC-Earth3P-HR',), ('ECMWF-ERAINT',),\n", + " ('ECMWF-IFS-HR',), ('ECMWF-IFS-LR',), ('ECMWF-IFS-MR',), ('ERA5',),\n", + " ('FGOALS-f3-H',), ('FGOALS-f3-L',), ('FGOALS-g2',), ('FGOALS-g3',),\n", + " ('FGOALS-gl',), ('FGOALS-s2',), ('FIO-ESM',), ('FIO-ESM-2-0',),\n", + " ('GEOS-5',), ('GFDL-AM4',), ('GFDL-CM2p1',), ('GFDL-CM3',),\n", + " ('GFDL-CM4',), ('GFDL-CM4C192',), ('GFDL-ESM2G',), ('GFDL-ESM2M',),\n", + " ('GFDL-ESM4',), ('GFDL-HIRAM-C180',), ('GFDL-HIRAM-C360',),\n", + " ('GFDL-OM4p5B',), ('GISS-E2-1-G',), ('GISS-E2-1-G-CC',),\n", + " ('GISS-E2-1-H',), ('GISS-E2-2-G',), ('GISS-E2-2-H',),\n", + " ('GISS-E2-H',), ('GISS-E2-H-CC',), ('GISS-E2-R',),\n", + " ('GISS-E2-R-CC',), ('HadCM3',), ('HadGEM2-A',), ('HadGEM2-AO',),\n", + " ('HadGEM2-CC',), ('HadGEM2-ES',), ('HadGEM3-GC31-HH',),\n", + " ('HadGEM3-GC31-HM',), ('HadGEM3-GC31-LL',), ('HadGEM3-GC31-LM',),\n", + " ('HadGEM3-GC31-MM',), ('HiRAM-SIT-HR',), ('HiRAM-SIT-LR',),\n", + " ('ICHEC-EC-EARTH',), ('ICON-ESM-LR',), ('IITM-ESM',),\n", + " ('INM-CM4-8',), ('INM-CM5-0',), ('INM-CM5-H',), ('IPSL-CM5A-LR',),\n", + " ('IPSL-CM5A-MR',), ('IPSL-CM5A2-INCA',), ('IPSL-CM5B-LR',),\n", + " ('IPSL-CM6A-ATM-HR',), ('IPSL-CM6A-ATM-ICO-VHR',),\n", + " ('IPSL-CM6A-LR',), ('IPSL-CM6A-LR-INCA',), ('IPSL-IPSL-CM5A-LR',),\n", + " ('IPSL-IPSL-CM5A-MR',), ('KACE-1-0-G',), ('KIOST-ESM',),\n", + " ('MCM-UA-1-0',), ('MIROC-ES2H',), ('MIROC-ES2L',), ('MIROC-ESM',),\n", + " ('MIROC-ESM-CHEM',), ('MIROC-MIROC5',), ('MIROC4h',), ('MIROC5',),\n", + " ('MIROC6',), ('MOHC-HadGEM2-CC',), ('MOHC-HadGEM2-ES',),\n", + " ('MOM6', 'SIS2'), ('MPI-ESM-1-2-HAM',), ('MPI-ESM-LR',),\n", + " ('MPI-ESM-MR',), ('MPI-ESM-P',), ('MPI-ESM1-2-HR',),\n", + " ('MPI-ESM1-2-LR',), ('MPI-ESM1-2-XR',), ('MPI-M-MPI-ESM-LR',),\n", + " ('MPI-M-MPI-ESM-MR',), ('MRI-AGCM3-2-H',), ('MRI-AGCM3-2-S',),\n", + " ('MRI-AGCM3-2H',), ('MRI-AGCM3-2S',), ('MRI-CGCM3',),\n", + " ('MRI-ESM1',), ('MRI-ESM2-0',), ('NCAR-CCSM4',),\n", + " ('NCC-NorESM1-M',), ('NESM3',), ('NICAM16-7S',), ('NICAM16-8S',),\n", + " ('NICAM16-9S',), ('NOAA-GFDL-GFDL-CM3',),\n", + " ('NOAA-GFDL-GFDL-ESM2G',), ('NOAA-GFDL-GFDL-ESM2M',), ('NorCPM1',),\n", + " ('NorESM1-F',), ('NorESM1-M',), ('NorESM1-ME',), ('NorESM2-LM',),\n", + " ('NorESM2-MM',), ('SAM0-UNICON',), ('TaiESM1',),\n", + " ('TaiESM1-TIMCOM',), ('TaiESM1-TIMCOM2',), ('UKESM1-0-LL',),\n", + " ('UKESM1-1-LL',), ('bcc-csm1-1',), ('bcc-csm1-1-m',), ('era5',),\n", + " ('era5-1',), ('era5-derived',), ('era5-preliminary',), ('era5t',),\n", + " ('fio-esm',), ('gfdl-esm2m',), ('inmcm4',), ('miroc5',)],\n", + " dtype=object)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.unique(cat.df.model)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f27dbe39-b1ec-46d7-b894-787eb0073cfd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2307 (MOM6,)\n", + "2308 (MOM6,)\n", + "2309 (MOM6,)\n", + "2310 (MOM6,)\n", + "2311 (MOM6,)\n", + "2312 (MOM6,)\n", + "2313 (MOM6,)\n", + "2314 (MOM6,)\n", + "2315 (MOM6,)\n", + "2316 (MOM6,)\n", + "2317 (MOM6,)\n", + "2318 (MOM6,)\n", + "2319 (MOM6,)\n", + "2320 (MOM6,)\n", + "2321 (MOM6,)\n", + "2322 (MOM6,)\n", + "Name: model, dtype: object" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat.search(model=\".*MOM6\").df.model" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "7a634482-ee9a-4d38-8a55-d05f38f3c147", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1124,)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.unique(cat.df.variable).shape" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "e9eb4536-f550-49ad-9e82-3ef22a32e3dd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'1deg_jra55_iaf_omip2spunup_cycle26'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat.keys()[-1]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "1630b7ea-4698-42ee-903f-74b85e6fc2e1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
filenamefile_idpathfilename_timestampfrequencystart_dateend_datevariablevariable_long_namevariable_standard_namevariable_cell_methodsvariable_unitsrealmmember
0PI-GWL-B2035.pa-010101_mon.ncPI_GWL_B2035_pa_XXXXXX_mon/g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010101_mon.nc0101011mon0101-01-01, 00:00:000101-02-01, 00:00:00[fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0...[THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA...[air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_...[time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,...[K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg...atmosPI-GWL-B2035
1PI-GWL-B2035.pa-010102_mon.ncPI_GWL_B2035_pa_XXXXXX_mon/g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010102_mon.nc0101021mon0101-02-01, 00:00:000101-03-01, 00:00:00[fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0...[THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA...[air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_...[time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,...[K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg...atmosPI-GWL-B2035
2PI-GWL-B2035.pa-010103_mon.ncPI_GWL_B2035_pa_XXXXXX_mon/g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010103_mon.nc0101031mon0101-03-01, 00:00:000101-04-01, 00:00:00[fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0...[THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA...[air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_...[time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,...[K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg...atmosPI-GWL-B2035
3PI-GWL-B2035.pa-010104_mon.ncPI_GWL_B2035_pa_XXXXXX_mon/g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010104_mon.nc0101041mon0101-04-01, 00:00:000101-05-01, 00:00:00[fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0...[THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA...[air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_...[time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,...[K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg...atmosPI-GWL-B2035
4PI-GWL-B2035.pa-010105_mon.ncPI_GWL_B2035_pa_XXXXXX_mon/g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010105_mon.nc0101051mon0101-05-01, 00:00:000101-06-01, 00:00:00[fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0...[THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA...[air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_...[time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,...[K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg...atmosPI-GWL-B2035
\n", + "
" + ], + "text/plain": [ + " filename file_id \\\n", + "0 PI-GWL-B2035.pa-010101_mon.nc PI_GWL_B2035_pa_XXXXXX_mon \n", + "1 PI-GWL-B2035.pa-010102_mon.nc PI_GWL_B2035_pa_XXXXXX_mon \n", + "2 PI-GWL-B2035.pa-010103_mon.nc PI_GWL_B2035_pa_XXXXXX_mon \n", + "3 PI-GWL-B2035.pa-010104_mon.nc PI_GWL_B2035_pa_XXXXXX_mon \n", + "4 PI-GWL-B2035.pa-010105_mon.nc PI_GWL_B2035_pa_XXXXXX_mon \n", + "\n", + " path \\\n", + "0 /g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010101_mon.nc \n", + "1 /g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010102_mon.nc \n", + "2 /g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010103_mon.nc \n", + "3 /g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010104_mon.nc \n", + "4 /g/data/p73/archive/non-CMIP/ACCESS-ESM1-5/PI-GWL-B2035/history/atm/netCDF/PI-GWL-B2035.pa-010105_mon.nc \n", + "\n", + " filename_timestamp frequency start_date end_date \\\n", + "0 010101 1mon 0101-01-01, 00:00:00 0101-02-01, 00:00:00 \n", + "1 010102 1mon 0101-02-01, 00:00:00 0101-03-01, 00:00:00 \n", + "2 010103 1mon 0101-03-01, 00:00:00 0101-04-01, 00:00:00 \n", + "3 010104 1mon 0101-04-01, 00:00:00 0101-05-01, 00:00:00 \n", + "4 010105 1mon 0101-05-01, 00:00:00 0101-06-01, 00:00:00 \n", + "\n", + " variable \\\n", + "0 [fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0... \n", + "1 [fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0... \n", + "2 [fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0... \n", + "3 [fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0... \n", + "4 [fld_s00i004, theta_level_height, sigma_theta, fld_s00i010, fld_s00i023, fld_s00i024, fld_s00i030, fld_s00i031, fld_s00i032, fld_s00i033, fld_s00i103, fld_s00i104, fld_s00i105, fld_s00i108, fld_s0... \n", + "\n", + " variable_long_name \\\n", + "0 [THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA... \n", + "1 [THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA... \n", + "2 [THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA... \n", + "3 [THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA... \n", + "4 [THETA AFTER TIMESTEP, level_height, sigma, SPECIFIC HUMIDITY AFTER TIMESTEP, SNOW AMOUNT OVER LAND AFT TSTP KG/M2, SURFACE TEMPERATURE AFTER TIMESTEP, LAND MASK (No halo) (LAND=TRUE), FRAC OF SEA... \n", + "\n", + " variable_standard_name \\\n", + "0 [air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_... \n", + "1 [air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_... \n", + "2 [air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_... \n", + "3 [air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_... \n", + "4 [air_potential_temperature, atmosphere_hybrid_height_coordinate, , specific_humidity, surface_snow_amount, surface_temperature, land_binary_mask, sea_ice_area_fraction, sea_ice_thickness, surface_... \n", + "\n", + " variable_cell_methods \\\n", + "0 [time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,... \n", + "1 [time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,... \n", + "2 [time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,... \n", + "3 [time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,... \n", + "4 [time: mean, , , time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean, time: mean,... \n", + "\n", + " variable_units \\\n", + "0 [K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg... \n", + "1 [K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg... \n", + "2 [K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg... \n", + "3 [K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg... \n", + "4 [K, m, 1, 1, kg m-2, K, 1, 1, m, m, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, kg/kg, , kg m-2 s-1, 1, Pa, m, 1, Pa, Pa, kg kg-1, kg kg-1, kg kg-1, kg kg-1, kg kg... \n", + "\n", + " realm member \n", + "0 atmos PI-GWL-B2035 \n", + "1 atmos PI-GWL-B2035 \n", + "2 atmos PI-GWL-B2035 \n", + "3 atmos PI-GWL-B2035 \n", + "4 atmos PI-GWL-B2035 " + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat['PI_GWL_B2035'].df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "a325d9b0-10ca-4226-b97a-1d2a7229bcf6", + "metadata": {}, + "outputs": [], + "source": [ + "client.close()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}