Skip to content

Open in Colab

PACE Level 3

The Plankton, Aerosol, Cloud, ocean Ecosystem (PACE) Level-3 products provide globally gridded derived from Level-2 swath observations. Satellite measurements are spatially and temporally aggregated (daily, 8-day, monthly, seasonal) onto regular latitude–longitude grids at two resolutions (~4 km and 0.1°). These products include ocean color variables such as chlorophyll-a, diffuse attenuation (Kd), and hyperspectral remote sensing reflectance (Rrs), along with derived biogeochemical indicators. For this notebook, we use

  • PACE_OCI_L3M_Rrs
  • PACE_OCI_L3M_AVW

Steps:

  • Create a plan for files to use pc.plan()
  • Print the plan to check it print(plan.summary())
  • Get matchups pc.matchup(plan)

Note: In a virtual machine in AWS us-west-2, where NASA cloud data is, the point matchups are fast. In Colab, say, your comppute is not in the same data region nor provider (Google versus AWS), and the same matchups might take 10x longer. Thus if you have big matchup tasks, 10s of thousands of points, it is wise to do that in AWS us-west-2.

Prerequisites

# install if needed
!pip install point-collocation --quiet
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
xmip 0.7.2 requires xarrayutils, which is not installed.
xmip 0.7.2 requires xgcm<0.7.0, which is not installed.

# Make sure you are logged in
import earthaccess
earthaccess.login()
<earthaccess.auth.Auth at 0x7f880073fd70>

Read in some points

import pandas as pd
time = "2025-04-09"
lat = 30.0
lon = -89.0

df = pd.DataFrame(
    {
        "lat": [lat],
        "lon": [lon],
        "time": [time],
    }
)
df
lat lon time
0 30.0 -89.0 2025-04-09

Create a plan

%%time
import point_collocation as pc
plan = pc.plan(
    df,
    data_source="earthaccess",
    source_kwargs={
        "short_name": "PACE_OCI_L3M_AOP",
        "granule_name": "*.8D.*.4km.*",
    }
)
CPU times: user 20.9 ms, sys: 0 ns, total: 20.9 ms
Wall time: 484 ms
plan.summary()
Plan: 1 points → 1 unique granule(s)
  Points with 0 matches : 0
  Points with >1 matches: 0
  Time buffer: 0 days 00:00:00

First 1 point(s):
  [0] lat=30.0000, lon=-89.0000, time=2025-04-09 00:00:00: 1 match(es)
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250407_20250414.L3m.8D.AOP.V3_2.4km.nc

Look at variables in that dataset

We will open a granule and inspect.

%%time
plan.open_dataset(0)
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'
CPU times: user 438 ms, sys: 157 ms, total: 595 ms
Wall time: 1.36 s
<xarray.Dataset> Size: 26GB
Dimensions:     (lat: 4320, lon: 8640, wavelength: 172)
Coordinates:
  * lat         (lat) float32 17kB 89.98 89.94 89.9 ... -89.9 -89.94 -89.98
  * lon         (lon) float32 35kB -180.0 -179.9 -179.9 ... 179.9 179.9 180.0
  * wavelength  (wavelength) float32 688B 346.0 348.5 350.9 ... 716.8 719.3
Data variables:
    Rrs         (lat, lon, wavelength) float32 26GB dask.array<chunksize=(16, 1024, 8), meta=np.ndarray>
    nflh        (lat, lon) float32 149MB dask.array<chunksize=(16, 1024), meta=np.ndarray>
    avw         (lat, lon) float32 149MB dask.array<chunksize=(16, 1024), meta=np.ndarray>
    aot_865     (lat, lon) float32 149MB dask.array<chunksize=(16, 1024), meta=np.ndarray>
    angstrom    (lat, lon) float32 149MB dask.array<chunksize=(16, 1024), meta=np.ndarray>
Attributes: (12/55)
    product_name:                      PACE_OCI.20250407_20250414.L3m.8D.AOP....
    instrument:                        OCI
    title:                             OCI Level-3 Standard Mapped Image
    project:                           Ocean Biology Processing Group (NASA/G...
    platform:                          PACE
    source:                            satellite observations from OCI-PACE
    ...                                ...
    keywords:                          Earth Science > Oceans > Ocean Optics ...
    id:                                L3/PACE_OCI.20250407_20250414.L3m.8D.A...
    history:                           /sdps/sdpsoper/Science/OCSSW/V2026.2/b...
    processing_version:                3.2
    identifier_product_doi_authority:  https://dx.doi.org
    identifier_product_doi:            10.5067/PACE/OCI/L3M/OC_AOP/3.2

Get the matchups

For variables with a 3rd dimension, like wavelength, all variables will be shown with _3rd dim value. The lat, lon, and time for the matching granules is added as a column. pc_id is the point id/row from the data you are matching. This is added in case there are multiple granules (files) per data point.|

%%time
res = pc.matchup(plan, variables=["Rrs"])
res
CPU times: user 875 ms, sys: 244 ms, total: 1.12 s
Wall time: 2.38 s
lat lon time pc_id granule_id granule_time granule_lat granule_lon Rrs_346 Rrs_348 ... Rrs_705 Rrs_706 Rrs_708 Rrs_709 Rrs_710 Rrs_711 Rrs_713 Rrs_714 Rrs_716 Rrs_719
0 30.0 -89.0 2025-04-09 0 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2025-04-10 23:59:59+00:00 30.020832 -89.020828 -0.000272 -0.000106 ... 0.003782 0.00368 0.003564 0.00344 0.003306 0.003166 0.003012 0.002802 0.002206 0.001736

1 rows × 180 columns

What if you only want some Rrs wavelengths?

You can filter the dataframe.

res[['lat', 'lon', 'time', 'Rrs_348', 'Rrs_711']]
lat lon time Rrs_348 Rrs_711
0 30.0 -89.0 2025-04-09 -0.000106 0.003166

Also match on wavelength

point-collocation is designed to match lat/lon/time but you can also match other coordinates that appear in the data. depth, wavelength are common examples. For wavelength, using the filtering above probably makes mose sense, but imagine that you wanted different wavelengths for different locations. To do this, we 2 things:

  • The additional coordinate as a column in our dataframe.
  • A coord_spec dict that says what the extra coordinate we want to match is.

*Note. In an xarray Dataset, you will see the coordinates in the data variable information, like Rrs (lat, lon, wavelength). Inside the parentheses are the coordinates for that variable.

import pandas as pd
df = pd.DataFrame(
    {
        "lat": [30.0, 31.0],
        "lon": [-89.0, -70.0],
        "time": ["2025-04-09", "2025-04-09"],
        "wave": [400,700]
    }
)
df
lat lon time wave
0 30.0 -89.0 2025-04-09 400
1 31.0 -70.0 2025-04-09 700

Create our coord_spec

You will need to look at the dataset with plan.open_dataset(0) to see what the coordinates are called in the source.

# Add wavelength as something we can match
coord_spec = {
    "wavelength": {"source": "wavelength", "points": "wave"}
}

Now we make a plan and pass in the coord spec

Rrs in the output is just for the wavelength in the wave column.

import point_collocation as pc
plan = pc.plan(
    df,
    data_source="earthaccess",
    source_kwargs={
        "short_name": "PACE_OCI_L3M_AOP",
        "granule_name": "*.8D.*.4km.*",
    }
)
res = pc.matchup(plan, variables=["Rrs"], coord_spec=coord_spec)
res
lat lon time wave pc_id granule_id granule_time granule_lat granule_lon Rrs
0 30.0 -89.0 2025-04-09 400 0 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2025-04-10 23:59:59+00:00 30.020832 -89.020828 0.001892
1 31.0 -70.0 2025-04-09 700 1 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2025-04-10 23:59:59+00:00 31.020832 -70.020828 0.000358

Data variables that are 1D (lat, lon)

In this case, just the variable appears, no _xxx, in the returned dataframe.

%%time
import point_collocation as pc
plan = pc.plan(
    df,
    data_source="earthaccess",
    source_kwargs={
        "short_name": "PACE_OCI_L3M_AOP",
        "granule_name": "*.DAY.*.4km.*",
    }
)
res = pc.matchup(plan, variables=["avw"])
res
CPU times: user 545 ms, sys: 131 ms, total: 676 ms
Wall time: 1.63 s
lat lon time wave pc_id granule_id granule_time granule_lat granule_lon avw
0 30.0 -89.0 2025-04-09 400 0 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2025-04-09 11:59:59+00:00 30.020832 -89.020828 549.833496
1 31.0 -70.0 2025-04-09 700 1 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2025-04-09 11:59:59+00:00 31.020832 -70.020828 NaN

Plan with many files

If you are not sure what files to use, you can use a short name without granule_name. Then look at the plan summary to see the file names. You just need to look at one file (n=1). In this example, there are 16 files that match. 2 resolutions (4km and 0.1 deg) and 8 temporal resolutions:

  • R32: rolling 32 days starting every 7 days, 4 dates
  • SNSP: seasonal/quarterly
  • 8D: 8 day
  • DAY: daily
  • MO: monthly starting 1st day of each month to last
%%time
import point_collocation as pc
plan = pc.plan(
    df,
    data_source="earthaccess",
    source_kwargs={
        "short_name": "PACE_OCI_L3M_AOP",
    }
)
CPU times: user 17.6 ms, sys: 1.63 ms, total: 19.3 ms
Wall time: 410 ms
plan.summary(n=1)
Plan: 2 points → 6 unique granule(s)
  Points with 0 matches : 0
  Points with >1 matches: 2
  Time buffer: 0 days 00:00:00

First 1 point(s):
  [0] lat=30.0000, lon=-89.0000, time=2025-04-09 00:00:00: 6 match(es)
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250401_20250430.L3m.MO.AOP.V3_2.0p1deg.nc
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250401_20250430.L3m.MO.AOP.V3_2.4km.nc
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250407_20250414.L3m.8D.AOP.V3_2.0p1deg.nc
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250407_20250414.L3m.8D.AOP.V3_2.4km.nc
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250409.L3m.DAY.AOP.V3_2.0p1deg.nc
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250409.L3m.DAY.AOP.V3_2.4km.nc

Filter to the files you want

Once you see the files names, you can filter to the ones you want. using granule_name. For example *.SNSP.*.4km.* to get the seasonal (quarterly) values. * are wildcard values.

%%time
import point_collocation as pc
plan = pc.plan(
    df,
    data_source="earthaccess",
    source_kwargs={
        "short_name": "PACE_OCI_L3M_AOP",
        "granule_name": "*.DAY.*.4km.*"
    }
)
CPU times: user 19.1 ms, sys: 258 μs, total: 19.3 ms
Wall time: 440 ms
plan.summary()
Plan: 2 points → 1 unique granule(s)
  Points with 0 matches : 0
  Points with >1 matches: 0
  Time buffer: 0 days 00:00:00

First 2 point(s):
  [0] lat=30.0000, lon=-89.0000, time=2025-04-09 00:00:00: 1 match(es)
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250409.L3m.DAY.AOP.V3_2.4km.nc
  [1] lat=31.0000, lon=-70.0000, time=2025-04-09 00:00:00: 1 match(es)
    → https://obdaac-tea.earthdatacloud.nasa.gov/ob-cumulus-prod-public/PACE_OCI.20250409.L3m.DAY.AOP.V3_2.4km.nc

Try many points

import pandas as pd
url = (
    "https://raw.githubusercontent.com/"
    "fish-pace/point-collocation/main/"
    "examples/fixtures/points.csv"
)
df_points = pd.read_csv(url)
print(len(df_points))

# Let's add on our own pc_id column
df_points = df_points.reset_index(drop=True)
df_points["pc_id"] = df_points.index + 1
df_points["pc_label"] = "pace_" + df_points["pc_id"].astype(str)

df_points.head()
595
lat lon date pc_id pc_label
0 27.3835 -82.7375 2024-06-13 1 pace_1
1 27.1190 -82.7125 2024-06-14 2 pace_2
2 26.9435 -82.8170 2024-06-14 3 pace_3
3 26.6875 -82.8065 2024-06-14 4 pace_4
4 26.6675 -82.6455 2024-06-14 5 pace_5

Get a plan for matchups from PACE data

For this example, we will just get a plan for the first 100 points so that it runs quickly.

%%time
import point_collocation as pc
plan = pc.plan(
    df_points[0:100],
    data_source="earthaccess",
    source_kwargs={
        "short_name": "PACE_OCI_L3M_AOP",
        "granule_name": "*.DAY.*.4km.*",
    }
)
CPU times: user 40 ms, sys: 0 ns, total: 40 ms
Wall time: 547 ms
plan.summary(n=0)
Plan: 100 points → 18 unique granule(s)
  Points with 0 matches : 0
  Points with >1 matches: 0
  Time buffer: 0 days 00:00:00
plan.open_dataset(0)
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='date'
<xarray.Dataset> Size: 26GB
Dimensions:     (lat: 4320, lon: 8640, wavelength: 172)
Coordinates:
  * lat         (lat) float32 17kB 89.98 89.94 89.9 ... -89.9 -89.94 -89.98
  * lon         (lon) float32 35kB -180.0 -179.9 -179.9 ... 179.9 179.9 180.0
  * wavelength  (wavelength) float32 688B 346.0 348.5 350.9 ... 716.8 719.3
Data variables:
    Rrs         (lat, lon, wavelength) float32 26GB dask.array<chunksize=(16, 1024, 8), meta=np.ndarray>
    nflh        (lat, lon) float32 149MB dask.array<chunksize=(16, 1024), meta=np.ndarray>
    avw         (lat, lon) float32 149MB dask.array<chunksize=(16, 1024), meta=np.ndarray>
    aot_865     (lat, lon) float32 149MB dask.array<chunksize=(16, 1024), meta=np.ndarray>
    angstrom    (lat, lon) float32 149MB dask.array<chunksize=(16, 1024), meta=np.ndarray>
Attributes: (12/55)
    product_name:                      PACE_OCI.20240613.L3m.DAY.AOP.V3_2.4km.nc
    instrument:                        OCI
    title:                             OCI Level-3 Standard Mapped Image
    project:                           Ocean Biology Processing Group (NASA/G...
    platform:                          PACE
    source:                            satellite observations from OCI-PACE
    ...                                ...
    keywords:                          Earth Science > Oceans > Ocean Optics ...
    id:                                L3/PACE_OCI.20240613.L3m.DAY.AOP.V3_2....
    history:                           /sdps/sdpsoper/Science/OCSSW/V2026.2/b...
    processing_version:                3.2
    identifier_product_doi_authority:  https://dx.doi.org
    identifier_product_doi:            10.5067/PACE/OCI/L3M/OC_AOP/3.2

Get 100 matchups using that plan

In a virtual machine in AWS us-west-2, where NASA cloud data is, this is 12 seconds. In Colab, say, this might be over a minute since you are not in the same data region nor provider (Google versus AWS).

%%time
res = pc.matchup(plan, variables = ["avw"])
CPU times: user 6.63 s, sys: 1.15 s, total: 7.78 s
Wall time: 21.7 s
res.head()
lat lon time pc_id pc_label granule_id granule_time granule_lat granule_lon avw
0 27.3835 -82.7375 2024-06-13 12:00:00 1 pace_1 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2024-06-13 11:59:59+00:00 27.395832 -82.729164 NaN
1 27.1190 -82.7125 2024-06-14 12:00:00 2 pace_2 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2024-06-14 11:59:59+00:00 27.104164 -82.729164 NaN
2 26.9435 -82.8170 2024-06-14 12:00:00 3 pace_3 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2024-06-14 11:59:59+00:00 26.937498 -82.812500 NaN
3 26.6875 -82.8065 2024-06-14 12:00:00 4 pace_4 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2024-06-14 11:59:59+00:00 26.687498 -82.812500 NaN
4 26.6675 -82.6455 2024-06-14 12:00:00 5 pace_5 https://obdaac-tea.earthdatacloud.nasa.gov/ob-... 2024-06-14 11:59:59+00:00 26.687498 -82.645828 NaN

Try lots of products

Pick a recent data point so NRT works. Not all products have files.

import pandas as pd
time = "2026-01-09"
lat = 30.0
lon = -89.0

df = pd.DataFrame(
    {
        "lat": [lat],
        "lon": [lon],
        "time": [time],
    }
)
df["time"] = pd.to_datetime(df["time"])
import earthaccess
results = earthaccess.search_datasets(instrument="oci")

short_names = [
    item.summary()["short-name"]
    for item in results
    if "L3M" in item.summary()["short-name"]
]

print(short_names)
['PACE_OCI_L3M_UVAI_UAA_NRT', 'PACE_OCI_L3M_UVAI_UAA', 'PACE_OCI_L3M_AER_UAA_NRT', 'PACE_OCI_L3M_AER_UAA', 'PACE_OCI_L3M_AOP_NRT', 'PACE_OCI_L3M_AOP', 'PACE_OCI_L3M_CLOSE', 'PACE_OCI_L3M_CLOUD_MASK_NRT', 'PACE_OCI_L3M_CLOUD_MASK', 'PACE_OCI_L3M_CLOUD_NRT', 'PACE_OCI_L3M_CLOUD', 'PACE_OCI_L3M_KD_NRT', 'PACE_OCI_L3M_KD', 'PACE_OCI_L3M_LANDVI_NRT', 'PACE_OCI_L3M_LANDVI', 'PACE_OCI_L3M_BGC_NRT', 'PACE_OCI_L3M_BGC', 'PACE_OCI_L3M_IOP_NRT', 'PACE_OCI_L3M_IOP', 'PACE_OCI_L3M_PAR_NRT', 'PACE_OCI_L3M_PAR', 'PACE_OCI_L3M_SFREFL_NRT', 'PACE_OCI_L3M_SFREFL', 'PACE_OCI_L3M_TRGAS_NRT', 'PACE_OCI_L3M_TRGAS']
%%time
# Confirm works for all L3 products
# Good. PACE_OCI_L3M_TRGAS is slow.
import point_collocation as pc
for short_name in short_names:
    print(f"\n===== {short_name} =====")

    try:
        plan = pc.plan(
            df,
            data_source="earthaccess",
            source_kwargs={
                "short_name": short_name,
                "granule_name":"*.DAY.*",
             }
        )
        plan.open_dataset(0)
    except Exception as e:
        print("Failed:", e)
===== PACE_OCI_L3M_UVAI_UAA_NRT =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_UVAI_UAA =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_AER_UAA_NRT =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_AER_UAA =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_AOP_NRT =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_AOP =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_CLOSE =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_CLOUD_MASK_NRT =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_CLOUD_MASK =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_CLOUD_NRT =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_CLOUD =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_KD_NRT =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_KD =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_LANDVI_NRT =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_LANDVI =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_BGC_NRT =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_BGC =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_IOP_NRT =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_IOP =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_PAR_NRT =====
Failed: result index 0 is out of range for a plan with 0 result(s). Valid indices are 0 to -1.

===== PACE_OCI_L3M_PAR =====
open_method: {'xarray_open': 'dataset', 'open_kwargs': {'chunks': {}, 'engine': 'h5netcdf', 'decode_timedelta': False}, 'coords': 'auto', 'set_coords': True, 'dim_renames': None, 'auto_align_phony_dims': None, 'merge': None}
Geolocation auto detected with cf_xarray: ('lon', 'lat') — lon dims=('lon',), lat dims=('lat',)
Points columns used: y='lat', x='lon', time='time'

===== PACE_OCI_L3M_SFREFL_NRT =====