import earthaccess
import xarray as xr
from xarray.backends.api import open_datatree
import matplotlib.pyplot as plt
import numpy as np
auth = earthaccess.login(persist=True)
results = earthaccess.search_datasets(
    keyword="L2 ocean color",
    instrument="olci",
)
set((i.summary()["short-name"] for i in results))
set()
tspan = ("2020-10-15", "2020-10-23")
bbox = (-89.4474, 30.064, -88.337, 30.064)
cc = (0, 50)
results = earthaccess.search_data(
    short_name="OLCIS3A_L2_EFR_OC",
    temporal=tspan,
    bounding_box=bbox,
    cloud_cover=cc,
)
paths = earthaccess.download(results, "data")
paths[0]
'data\\S3A_OLCI_EFRNT.20201015T155218.L2.OC.nc'
from affine import Affine
prod = xr.open_dataset(paths[0])
obs = xr.open_dataset(paths[0], group="geophysical_data")
nav = xr.open_dataset(paths[0], group="navigation_data")
nav = (
    nav
    .set_coords(("longitude", "latitude"))
    .rename({"pixel_control_points": "pixels_per_line"})
)
dataset = xr.merge((prod, obs, nav.coords))
# set latitude and longitude as coordinates
dataset = dataset.set_coords(("latitude", "longitude"))
# slice (-89.4474, 30.064, -88.337, 30.064)
# dataset = dataset.sel(
#     latitude=slice(30.064, 30.064),
#     longitude=slice(-89.4474, -88.337),
# )
dataset
<xarray.Dataset> Size: 1GB
Dimensions:    (number_of_lines: 4091, pixels_per_line: 4865)
Coordinates:
    longitude  (number_of_lines, pixels_per_line) float32 80MB ...
    latitude   (number_of_lines, pixels_per_line) float32 80MB ...
Dimensions without coordinates: number_of_lines, pixels_per_line
Data variables: (12/16)
    aot_865    (number_of_lines, pixels_per_line) float32 80MB ...
    angstrom   (number_of_lines, pixels_per_line) float32 80MB ...
    Rrs_400    (number_of_lines, pixels_per_line) float32 80MB ...
    Rrs_412    (number_of_lines, pixels_per_line) float32 80MB ...
    Rrs_443    (number_of_lines, pixels_per_line) float32 80MB ...
    Rrs_490    (number_of_lines, pixels_per_line) float32 80MB ...
    ...         ...
    Rrs_674    (number_of_lines, pixels_per_line) float32 80MB ...
    Rrs_681    (number_of_lines, pixels_per_line) float32 80MB ...
    Rrs_709    (number_of_lines, pixels_per_line) float32 80MB ...
    chlor_a    (number_of_lines, pixels_per_line) float32 80MB ...
    Kd_490     (number_of_lines, pixels_per_line) float32 80MB ...
    l2_flags   (number_of_lines, pixels_per_line) int32 80MB ...
Attributes: (12/46)
    title:                          OLCIS3A Level-2 Data
    product_name:                   S3A_OLCI_EFRNT.20201015T155218.L2.OC.nc
    processing_version:             R2022.0
    orbit_number:                   24282
    history:                        l2gen par=/data9/sdpsoper/vdc/vpu20/workb...
    instrument:                     OLCI
    ...                             ...
    geospatial_lon_max:             -79.75462
    geospatial_lon_min:             -94.42871
    startDirection:                 Descending
    endDirection:                   Descending
    day_night_flag:                 Day
    earth_sun_distance_correction:  1.0060665607452393
import datatree
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[69], line 1
----> 1 import datatree

ModuleNotFoundError: No module named 'datatree'
array = dataset["Rrs_709"]
array.attrs.update(
    {
        "units": f'({dataset["Rrs_709"].attrs["units"]})',
    }
)

array
# save to geotiff
array
# array.plot(
#     x="longitude", y="latitude", aspect=2, size=4, cmap="jet", robust=True
# )
<xarray.DataArray 'Rrs_709' (number_of_lines: 4091, pixels_per_line: 4865)> Size: 80MB
array([[nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       ...,
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan],
       [nan, nan, nan, ..., nan, nan, nan]], dtype=float32)
Coordinates:
    longitude  (number_of_lines, pixels_per_line) float32 80MB ...
    latitude   (number_of_lines, pixels_per_line) float32 80MB ...
Dimensions without coordinates: number_of_lines, pixels_per_line
Attributes:
    long_name:         Remote sensing reflectance at 709 nm
    units:             ((((((((((((sr^-1))))))))))))
    standard_name:     surface_ratio_of_upwelling_radiance_emerging_from_sea_...
    valid_min:         -30000
    valid_max:         25000
    solar_irradiance:  1403.1101
results = earthaccess.search_datasets(instrument="olci")
for item in results:
    summary = item.summary()
    print(summary["short-name"])
    #OLCIS3A_L2_EFR_OC
S3A_OL_1_EFR
MERGED_S3_OLCI_L3b_CYANTC
MERGED_S3_OLCI_L3b_ILW
MERGED_S3_OLCI_L3m_CYAN
MERGED_S3_OLCI_L3m_CYANTC
MERGED_S3_OLCI_L3m_ILW
OLCIS3A_L1_EFR
OLCIS3A_L1_ERR
OLCIS3A_L2_EFR_IOP
OLCIS3A_L2_EFR_IOP_NRT
OLCIS3A_L2_EFR_OC
OLCIS3A_L2_EFR_OC_NRT
OLCIS3A_L2_ERR_IOP
OLCIS3A_L2_ERR_IOP_NRT
OLCIS3A_L2_ERR_OC
OLCIS3A_L2_ERR_OC_NRT
OLCIS3A_L2_ILW
OLCIS3A_L3b_ERR_CHL
OLCIS3A_L3b_ERR_CHL_NRT
OLCIS3A_L3b_ERR_IOP
OLCIS3A_L3b_ERR_IOP_NRT
OLCIS3A_L3b_ERR_KD
OLCIS3A_L3b_ERR_KD_NRT
OLCIS3A_L3b_ERR_RRS
OLCIS3A_L3b_ERR_RRS_NRT
OLCIS3A_L3b_ILW
OLCIS3A_L3m_ERR_CHL
OLCIS3A_L3m_ERR_CHL_NRT
OLCIS3A_L3m_ERR_IOP
OLCIS3A_L3m_ERR_IOP_NRT
OLCIS3A_L3m_ERR_KD
OLCIS3A_L3m_ERR_KD_NRT
OLCIS3A_L3m_ERR_RRS
OLCIS3A_L3m_ERR_RRS_NRT
OLCIS3A_L3m_ILW
OLCIS3B_L1_EFR
OLCIS3B_L1_ERR
OLCIS3B_L2_EFR_IOP
OLCIS3B_L2_EFR_IOP_NRT
OLCIS3B_L2_EFR_OC
OLCIS3B_L2_EFR_OC_NRT
OLCIS3B_L2_ERR_IOP
OLCIS3B_L2_ERR_IOP_NRT
OLCIS3B_L2_ERR_OC
OLCIS3B_L2_ERR_OC_NRT
OLCIS3B_L2_ILW
OLCIS3B_L3b_ERR_CHL
OLCIS3B_L3b_ERR_CHL_NRT
OLCIS3B_L3b_ERR_IOP
OLCIS3B_L3b_ERR_IOP_NRT
OLCIS3B_L3b_ERR_KD
OLCIS3B_L3b_ERR_KD_NRT
OLCIS3B_L3b_ERR_RRS
OLCIS3B_L3b_ERR_RRS_NRT
OLCIS3B_L3b_ILW
OLCIS3B_L3m_ERR_CHL
OLCIS3B_L3m_ERR_CHL_NRT
OLCIS3B_L3m_ERR_IOP
OLCIS3B_L3m_ERR_IOP_NRT
OLCIS3B_L3m_ERR_KD
OLCIS3B_L3m_ERR_KD_NRT
OLCIS3B_L3m_ERR_RRS
OLCIS3B_L3m_ERR_RRS_NRT
OLCIS3B_L3m_ILW
S3A_OL_1_ERR
S3A_SY_2_SYN
S3B_OL_1_EFR
S3B_OL_1_ERR
S3B_SY_2_SYN
results = earthaccess.search_data(
    short_name="OLCIS3A_L2_EFR_OC",
    count=1,
)
tspan = ("2024-01-01", "2024-10-31")
bbox = (-89.4474, 30.064, -88.337, 30.064)
clouds = (0, 50)
results = earthaccess.search_data(
    short_name="OLCIS3A_L2_EFR_OC",
    temporal=tspan,
    bounding_box=bbox,
    cloud_cover=clouds,
)
paths = earthaccess.open(results)
dataset = xr.open_dataset(paths[0], engine='netcdf4')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[20], line 1
----> 1 dataset = xr.open_dataset(paths[0], engine='netcdf4')

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\api.py:571, in open_dataset(filename_or_obj, engine, chunks, cache, decode_cf, mask_and_scale, decode_times, decode_timedelta, use_cftime, concat_characters, decode_coords, drop_variables, inline_array, chunked_array_type, from_array_kwargs, backend_kwargs, **kwargs)
    559 decoders = _resolve_decoders_kwargs(
    560     decode_cf,
    561     open_backend_dataset_parameters=backend.open_dataset_parameters,
   (...)
    567     decode_coords=decode_coords,
    568 )
    570 overwrite_encoded_chunks = kwargs.pop("overwrite_encoded_chunks", None)
--> 571 backend_ds = backend.open_dataset(
    572     filename_or_obj,
    573     drop_variables=drop_variables,
    574     **decoders,
    575     **kwargs,
    576 )
    577 ds = _dataset_from_backend_dataset(
    578     backend_ds,
    579     filename_or_obj,
   (...)
    589     **kwargs,
    590 )
    591 return ds

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\netCDF4_.py:645, in NetCDF4BackendEntrypoint.open_dataset(self, filename_or_obj, mask_and_scale, decode_times, concat_characters, decode_coords, drop_variables, use_cftime, decode_timedelta, group, mode, format, clobber, diskless, persist, lock, autoclose)
    624 def open_dataset(  # type: ignore[override]  # allow LSP violation, not supporting **kwargs
    625     self,
    626     filename_or_obj: str | os.PathLike[Any] | BufferedIOBase | AbstractDataStore,
   (...)
    642     autoclose=False,
    643 ) -> Dataset:
    644     filename_or_obj = _normalize_path(filename_or_obj)
--> 645     store = NetCDF4DataStore.open(
    646         filename_or_obj,
    647         mode=mode,
    648         format=format,
    649         group=group,
    650         clobber=clobber,
    651         diskless=diskless,
    652         persist=persist,
    653         lock=lock,
    654         autoclose=autoclose,
    655     )
    657     store_entrypoint = StoreBackendEntrypoint()
    658     with close_on_error(store):

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\netCDF4_.py:381, in NetCDF4DataStore.open(cls, filename, mode, format, group, clobber, diskless, persist, lock, lock_maker, autoclose)
    378     filename = os.fspath(filename)
    380 if not isinstance(filename, str):
--> 381     raise ValueError(
    382         "can only read bytes or file-like objects "
    383         "with engine='scipy' or 'h5netcdf'"
    384     )
    386 if format is None:
    387     format = "NETCDF4"

ValueError: can only read bytes or file-like objects with engine='scipy' or 'h5netcdf'
dataset = xr.open_dataset(paths[0])
dataset
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\file_manager.py:211, in CachingFileManager._acquire_with_cache_info(self, needs_lock)
    210 try:
--> 211     file = self._cache[self._key]
    212 except KeyError:

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\lru_cache.py:56, in LRUCache.__getitem__(self, key)
     55 with self._lock:
---> 56     value = self._cache[key]
     57     self._cache.move_to_end(key)

KeyError: [<class 'h5netcdf.core.File'>, (<File-like object HTTPFileSystem, https://oceandata.sci.gsfc.nasa.gov/cmr/getfile/S3A_OLCI_EFRNT.20210703T162305.L2.OC.nc>,), 'r', (('decode_vlen_strings', True), ('driver', None), ('invalid_netcdf', None)), 'd5f858e9-e7aa-41a3-a406-35d327c30633']

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
Cell In[13], line 1
----> 1 dataset = xr.open_dataset(paths[0])
      2 dataset

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\api.py:571, in open_dataset(filename_or_obj, engine, chunks, cache, decode_cf, mask_and_scale, decode_times, decode_timedelta, use_cftime, concat_characters, decode_coords, drop_variables, inline_array, chunked_array_type, from_array_kwargs, backend_kwargs, **kwargs)
    559 decoders = _resolve_decoders_kwargs(
    560     decode_cf,
    561     open_backend_dataset_parameters=backend.open_dataset_parameters,
   (...)
    567     decode_coords=decode_coords,
    568 )
    570 overwrite_encoded_chunks = kwargs.pop("overwrite_encoded_chunks", None)
--> 571 backend_ds = backend.open_dataset(
    572     filename_or_obj,
    573     drop_variables=drop_variables,
    574     **decoders,
    575     **kwargs,
    576 )
    577 ds = _dataset_from_backend_dataset(
    578     backend_ds,
    579     filename_or_obj,
   (...)
    589     **kwargs,
    590 )
    591 return ds

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\h5netcdf_.py:404, in H5netcdfBackendEntrypoint.open_dataset(self, filename_or_obj, mask_and_scale, decode_times, concat_characters, decode_coords, drop_variables, use_cftime, decode_timedelta, format, group, lock, invalid_netcdf, phony_dims, decode_vlen_strings, driver, driver_kwds)
    383 def open_dataset(  # type: ignore[override]  # allow LSP violation, not supporting **kwargs
    384     self,
    385     filename_or_obj: str | os.PathLike[Any] | BufferedIOBase | AbstractDataStore,
   (...)
    401     driver_kwds=None,
    402 ) -> Dataset:
    403     filename_or_obj = _normalize_path(filename_or_obj)
--> 404     store = H5NetCDFStore.open(
    405         filename_or_obj,
    406         format=format,
    407         group=group,
    408         lock=lock,
    409         invalid_netcdf=invalid_netcdf,
    410         phony_dims=phony_dims,
    411         decode_vlen_strings=decode_vlen_strings,
    412         driver=driver,
    413         driver_kwds=driver_kwds,
    414     )
    416     store_entrypoint = StoreBackendEntrypoint()
    418     ds = store_entrypoint.open_dataset(
    419         store,
    420         mask_and_scale=mask_and_scale,
   (...)
    426         decode_timedelta=decode_timedelta,
    427     )

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\h5netcdf_.py:184, in H5NetCDFStore.open(cls, filename, mode, format, group, lock, autoclose, invalid_netcdf, phony_dims, decode_vlen_strings, driver, driver_kwds)
    181         lock = combine_locks([HDF5_LOCK, get_write_lock(filename)])
    183 manager = CachingFileManager(h5netcdf.File, filename, mode=mode, kwargs=kwargs)
--> 184 return cls(manager, group=group, mode=mode, lock=lock, autoclose=autoclose)

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\h5netcdf_.py:130, in H5NetCDFStore.__init__(self, manager, group, mode, lock, autoclose)
    127 self.format = None
    128 # todo: utilizing find_root_and_group seems a bit clunky
    129 #  making filename available on h5netcdf.Group seems better
--> 130 self._filename = find_root_and_group(self.ds)[0].filename
    131 self.is_remote = is_remote_uri(self._filename)
    132 self.lock = ensure_lock(lock)

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\h5netcdf_.py:195, in H5NetCDFStore.ds(self)
    193 @property
    194 def ds(self):
--> 195     return self._acquire()

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\h5netcdf_.py:187, in H5NetCDFStore._acquire(self, needs_lock)
    186 def _acquire(self, needs_lock=True):
--> 187     with self._manager.acquire_context(needs_lock) as root:
    188         ds = _nc4_require_group(
    189             root, self._group, self._mode, create_group=_h5netcdf_create_group
    190         )
    191     return ds

File c:\Users\hafez\miniconda3\Lib\contextlib.py:137, in _GeneratorContextManager.__enter__(self)
    135 del self.args, self.kwds, self.func
    136 try:
--> 137     return next(self.gen)
    138 except StopIteration:
    139     raise RuntimeError("generator didn't yield") from None

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\file_manager.py:199, in CachingFileManager.acquire_context(self, needs_lock)
    196 @contextlib.contextmanager
    197 def acquire_context(self, needs_lock=True):
    198     """Context manager for acquiring a file."""
--> 199     file, cached = self._acquire_with_cache_info(needs_lock)
    200     try:
    201         yield file

File c:\Users\hafez\miniconda3\Lib\site-packages\xarray\backends\file_manager.py:217, in CachingFileManager._acquire_with_cache_info(self, needs_lock)
    215     kwargs = kwargs.copy()
    216     kwargs["mode"] = self._mode
--> 217 file = self._opener(*self._args, **kwargs)
    218 if self._mode == "w":
    219     # ensure file doesn't get overridden when opened again
    220     self._mode = "a"

File c:\Users\hafez\miniconda3\Lib\site-packages\h5netcdf\core.py:1102, in File.__init__(self, path, mode, invalid_netcdf, phony_dims, **kwargs)
   1100 # This maps keeps track of all HDF5 datasets corresponding to this group.
   1101 self._all_h5groups = ChainMap(self._h5group)
-> 1102 super().__init__(self, self._h5path)
   1103 # get maximum dimension id and count of labeled dimensions
   1104 if self._writable:

File c:\Users\hafez\miniconda3\Lib\site-packages\h5netcdf\core.py:504, in Group.__init__(self, parent, name)
    501 if self._root._phony_dims_mode is not None:
    502     phony_dims = Counter()
--> 504 for k, v in self._h5group.items():
    505     if isinstance(v, self._root._h5py.Group):
    506         # add to the groups collection if this is a h5py(d) Group
    507         # instance
    508         self._groups.add(k)

File c:\Users\hafez\miniconda3\Lib\site-packages\h5py\_hl\base.py:438, in ItemsViewHDF5.__iter__(self)
    436 with phil:
    437     for key in self._mapping:
--> 438         yield (key, self._mapping.get(key))

File c:\Users\hafez\miniconda3\Lib\site-packages\h5py\_hl\group.py:400, in Group.get(self, name, default, getclass, getlink)
    398 if not (getclass or getlink):
    399     try:
--> 400         return self[name]
    401     except KeyError:
    402         return default

File h5py\_objects.pyx:54, in h5py._objects.with_phil.wrapper()

File h5py\_objects.pyx:55, in h5py._objects.with_phil.wrapper()

File c:\Users\hafez\miniconda3\Lib\site-packages\h5py\_hl\group.py:357, in Group.__getitem__(self, name)
    355         raise ValueError("Invalid HDF5 object reference")
    356 elif isinstance(name, (bytes, str)):
--> 357     oid = h5o.open(self.id, self._e(name), lapl=self._lapl)
    358 else:
    359     raise TypeError("Accessing a group is done with bytes or str, "
    360                     "not {}".format(type(name)))

File h5py\_objects.pyx:54, in h5py._objects.with_phil.wrapper()

File h5py\_objects.pyx:55, in h5py._objects.with_phil.wrapper()

File h5py\h5o.pyx:189, in h5py.h5o.open()

File h5py\h5fd.pyx:163, in h5py.h5fd.H5FD_fileobj_read()

File c:\Users\hafez\miniconda3\Lib\site-packages\fsspec\spec.py:1959, in AbstractBufferedFile.readinto(self, b)
   1954 """mirrors builtin file's readinto method
   1955 
   1956 https://docs.python.org/3/library/io.html#io.RawIOBase.readinto
   1957 """
   1958 out = memoryview(b).cast("B")
-> 1959 data = self.read(out.nbytes)
   1960 out[: len(data)] = data
   1961 return len(data)

File c:\Users\hafez\miniconda3\Lib\site-packages\fsspec\spec.py:1941, in AbstractBufferedFile.read(self, length)
   1938 if length == 0:
   1939     # don't even bother calling fetch
   1940     return b""
-> 1941 out = self.cache._fetch(self.loc, self.loc + length)
   1943 logger.debug(
   1944     "%s read: %i - %i %s",
   1945     self,
   (...)
   1948     self.cache._log_stats(),
   1949 )
   1950 self.loc += len(out)

File c:\Users\hafez\miniconda3\Lib\site-packages\fsspec\caching.py:503, in BytesCache._fetch(self, start, end)
    501 elif end - self.end > self.blocksize:
    502     self.total_requested_bytes += bend - start
--> 503     self.cache = self.fetcher(start, bend)
    504     self.start = start
    505 else:

File c:\Users\hafez\miniconda3\Lib\site-packages\fsspec\asyn.py:118, in sync_wrapper.<locals>.wrapper(*args, **kwargs)
    115 @functools.wraps(func)
    116 def wrapper(*args, **kwargs):
    117     self = obj or args[0]
--> 118     return sync(self.loop, func, *args, **kwargs)

File c:\Users\hafez\miniconda3\Lib\site-packages\fsspec\asyn.py:103, in sync(loop, func, timeout, *args, **kwargs)
    101     raise FSTimeoutError from return_result
    102 elif isinstance(return_result, BaseException):
--> 103     raise return_result
    104 else:
    105     return return_result

File c:\Users\hafez\miniconda3\Lib\site-packages\fsspec\asyn.py:56, in _runner(event, coro, result, timeout)
     54     coro = asyncio.wait_for(coro, timeout=timeout)
     55 try:
---> 56     result[0] = await coro
     57 except Exception as ex:
     58     result[0] = ex

File c:\Users\hafez\miniconda3\Lib\site-packages\fsspec\implementations\http.py:669, in HTTPFile.async_fetch_range(self, start, end)
    667     out = await r.read()
    668 elif start > 0:
--> 669     raise ValueError(
    670         "The HTTP server doesn't appear to support range requests. "
    671         "Only reading this file from the beginning is supported. "
    672         "Open with block_size=0 for a streaming file interface."
    673     )
    674 else:
    675     # Response is not a range, but we want the start of the file,
    676     # so we can read the required amount anyway.
    677     cl = 0

ValueError: The HTTP server doesn't appear to support range requests. Only reading this file from the beginning is supported. Open with block_size=0 for a streaming file interface.