# Path: src/pys5p/s5p_xarray.py
# def data_to_xr(data, *, dims=None, name=None, long_name=None, units=None):
#     """
#     Create xarray::DataArray from a dataset
# 
#     Parameters
#     ----------
#     data :  array-like
#        Data to be stored in the xarray
#     dims :  list of strings
#        Names for the dataset dimensions
#     name : str
#        A string that names the instance
#     units :  str
#        Units of the data, default: '1'
#     long_name : str
#        Long name describing the data, default: empty string
# 
#     Returns
#     -------
#     xarray.DataArray
#     """
#     coords = __set_coords(data, None, dims)
#     attrs = {}
#     attrs['units'] = '1' if units is None else units
#     attrs['long_name'] = '' if long_name is None else long_name
# 
#     return xr.DataArray(data, name=name, attrs=attrs, coords=coords)
# 
# def h5_to_xr(h5_dset, data_sel=None, *, dims=None, field=None):
#     """
#     Create xarray::DataArray from a HDF5 dataset (with dimension scales)
# 
#     Parameters
#     ----------
#     h5_dset :  h5py.Dataset
#        Data, dimensions, coordinates and attributes are read for this dataset
#     data_sel :  slice, optional
#        A numpy slice generated for example numpy.s_
#     dims :  list of strings, optional
#        Alternative names for the dataset dimensions if not attached to dataset
#     field : str, optional
#        Name of field in compound dataset or None
# 
#     Returns
#     -------
#     xarray.DataArray
# 
#     Notes
#     -----
#     If data_sel is used to select data from a dataset then the number of
#     dimensions of data_sel should agree with the HDF5 dataset or one and
#     only one Ellipsis has to be used.
#     Thus allowed values for data_sel are:
#     * [always]: (), np.s_[:], np.s_[...]
#     * [1-D dataset]: np.s_[:-1], np.s_[0]
#     * [2-D dataset]: np.s_[:-1, :], np.s_[0, :], np.s_[:-1, 0]
#     * [3-D dataset]: np.s_[:-1, :, 2:4], np.s_[0, :, :], np.s_[:-1, 0, 2:4]
#     * [Ellipsis] np.s_[0, ...], np.s_[..., 4], np.s_[0, ..., 4]
# 
#     Examples
#     --------
#     >>> fid = h5py.File(flname, 'r')        # flname is a HDF5/netCDF4 file
#     >>> xdata = h5_to_xr(fid['signal'])
#     >>> fid.close()
# 
#     Combine Tropomi SWIR data of band7 and band8
#     >>> fid = h5py.File(s5p_b7_prod, 'r')   # Tropomi band7 product
#     >>> xdata7 = h5_to_xr(fid['signal'])
#     >>> fid.close()
#     >>> fid = h5py.File(s5p_b8_prod, 'r')   # Tropomi band8 product
#     >>> xdata8 = h5_to_xr(fid['signal'])
#     >>> fid.close()
#     >>> xdata = xr.concat((xdata7, xdata8), dim='spectral_channel')
# 
#     Optionally, fix the 'column' dimension
#     >>> xdata = xdata.assign_coords(
#     >>> ... column=np.arange(xdata.column.size, dtype='u4'))
#     """
#     if data_sel is not None:
#         if data_sel in (np.s_[:], np.s_[...], np.s_[()]):
#             data_sel = None
#         elif np.isscalar(data_sel):
#             data_sel = (np.s_[data_sel:data_sel+1],)
#         else:
#             buff = ()
#             for val in data_sel:
#                 if val == Ellipsis:
#                     for _ in range(h5_dset.ndim - len(data_sel) + 1):
#                         buff += np.index_exp[:]
#                 elif np.isscalar(val):
#                     buff += (np.s_[val:val+1],)
#                 else:
#                     buff += (val,)
#             data_sel = buff
# 
#     # Name of this array
#     name = PurePath(h5_dset.name).name
# 
#     # Values for this array
#     data = __get_data(h5_dset, data_sel, field)
# 
#     # Coordinates (tick labels) to use for indexing along each dimension
#     coords = []
#     if dims is None:
#         coords = __get_coords(h5_dset, data_sel)
#     if not coords:
#         coords = __set_coords(h5_dset, data_sel, dims)
# 
#     # Attributes to assign to the array
#     attrs = __get_attrs(h5_dset, field)
# 
#     # check if dimension of dataset and coordinates agree
#     if data.ndim < len(coords):
#         for ii in reversed(range(len(coords))):
#             if np.isscalar(coords[ii][1]):
#                 del coords[ii]
# 
#     return xr.DataArray(data, name=name, attrs=attrs, coords=coords)


from datetime import datetime, timedelta
from pathlib import Path
from netCDF4 import Dataset
from .s5p_xarray import data_to_xr, h5_to_xr
import h5py
import numpy as np
    def __h5_data_as_xds(self, name, data_sel, mol_m2):
        """
        Read dataset from group target_product using HDF5

        Input: operational product

        Return: xarray.Dataset
        """
        if name not in self.fid['/PRODUCT']:
            raise ValueError(f'dataset {name} for found')
        dset = self.fid[f'/PRODUCT/{name}']

        # ToDo handle parameter mol_m2
        return h5_to_xr(dset, (0,) + data_sel).squeeze()

    def __nc_data_as_xds(self, name, data_sel):
        """
        Read dataset from group PRODUCT using netCDF4

        Input: science product

        Return: xarray.DataArray
        """
        if name in self.fid['/target_product'].variables.keys():
            group = '/target_product'
        elif name in self.fid['/instrument'].variables.keys():
            group = '/instrument'
        else:
            raise ValueError('dataset {name} for found')


# Path: src/pys5p/s5p_xarray.py
# def data_to_xr(data, *, dims=None, name=None, long_name=None, units=None):
#     """
#     Create xarray::DataArray from a dataset
# 
#     Parameters
#     ----------
#     data :  array-like
#        Data to be stored in the xarray
#     dims :  list of strings
#        Names for the dataset dimensions
#     name : str
#        A string that names the instance
#     units :  str
#        Units of the data, default: '1'
#     long_name : str
#        Long name describing the data, default: empty string
# 
#     Returns
#     -------
#     xarray.DataArray
#     """
#     coords = __set_coords(data, None, dims)
#     attrs = {}
#     attrs['units'] = '1' if units is None else units
#     attrs['long_name'] = '' if long_name is None else long_name
# 
#     return xr.DataArray(data, name=name, attrs=attrs, coords=coords)
# 
# def h5_to_xr(h5_dset, data_sel=None, *, dims=None, field=None):
#     """
#     Create xarray::DataArray from a HDF5 dataset (with dimension scales)
# 
#     Parameters
#     ----------
#     h5_dset :  h5py.Dataset
#        Data, dimensions, coordinates and attributes are read for this dataset
#     data_sel :  slice, optional
#        A numpy slice generated for example numpy.s_
#     dims :  list of strings, optional
#        Alternative names for the dataset dimensions if not attached to dataset
#     field : str, optional
#        Name of field in compound dataset or None
# 
#     Returns
#     -------
#     xarray.DataArray
# 
#     Notes
#     -----
#     If data_sel is used to select data from a dataset then the number of
#     dimensions of data_sel should agree with the HDF5 dataset or one and
#     only one Ellipsis has to be used.
#     Thus allowed values for data_sel are:
#     * [always]: (), np.s_[:], np.s_[...]
#     * [1-D dataset]: np.s_[:-1], np.s_[0]
#     * [2-D dataset]: np.s_[:-1, :], np.s_[0, :], np.s_[:-1, 0]
#     * [3-D dataset]: np.s_[:-1, :, 2:4], np.s_[0, :, :], np.s_[:-1, 0, 2:4]
#     * [Ellipsis] np.s_[0, ...], np.s_[..., 4], np.s_[0, ..., 4]
# 
#     Examples
#     --------
#     >>> fid = h5py.File(flname, 'r')        # flname is a HDF5/netCDF4 file
#     >>> xdata = h5_to_xr(fid['signal'])
#     >>> fid.close()
# 
#     Combine Tropomi SWIR data of band7 and band8
#     >>> fid = h5py.File(s5p_b7_prod, 'r')   # Tropomi band7 product
#     >>> xdata7 = h5_to_xr(fid['signal'])
#     >>> fid.close()
#     >>> fid = h5py.File(s5p_b8_prod, 'r')   # Tropomi band8 product
#     >>> xdata8 = h5_to_xr(fid['signal'])
#     >>> fid.close()
#     >>> xdata = xr.concat((xdata7, xdata8), dim='spectral_channel')
# 
#     Optionally, fix the 'column' dimension
#     >>> xdata = xdata.assign_coords(
#     >>> ... column=np.arange(xdata.column.size, dtype='u4'))
#     """
#     if data_sel is not None:
#         if data_sel in (np.s_[:], np.s_[...], np.s_[()]):
#             data_sel = None
#         elif np.isscalar(data_sel):
#             data_sel = (np.s_[data_sel:data_sel+1],)
#         else:
#             buff = ()
#             for val in data_sel:
#                 if val == Ellipsis:
#                     for _ in range(h5_dset.ndim - len(data_sel) + 1):
#                         buff += np.index_exp[:]
#                 elif np.isscalar(val):
#                     buff += (np.s_[val:val+1],)
#                 else:
#                     buff += (val,)
#             data_sel = buff
# 
#     # Name of this array
#     name = PurePath(h5_dset.name).name
# 
#     # Values for this array
#     data = __get_data(h5_dset, data_sel, field)
# 
#     # Coordinates (tick labels) to use for indexing along each dimension
#     coords = []
#     if dims is None:
#         coords = __get_coords(h5_dset, data_sel)
#     if not coords:
#         coords = __set_coords(h5_dset, data_sel, dims)
# 
#     # Attributes to assign to the array
#     attrs = __get_attrs(h5_dset, field)
# 
#     # check if dimension of dataset and coordinates agree
#     if data.ndim < len(coords):
#         for ii in reversed(range(len(coords))):
#             if np.isscalar(coords[ii][1]):
#                 del coords[ii]
# 
#     return xr.DataArray(data, name=name, attrs=attrs, coords=coords)


# Path: src/pys5p/lv2_io.py
from datetime import datetime, timedelta
from pathlib import Path
from netCDF4 import Dataset
from .s5p_xarray import data_to_xr, h5_to_xr
import h5py
import numpy as np

    def __h5_data_as_xds(self, name, data_sel, mol_m2):
        """
        Read dataset from group target_product using HDF5

        Input: operational product

        Return: xarray.Dataset
        """
        if name not in self.fid['/PRODUCT']:
            raise ValueError(f'dataset {name} for found')
        dset = self.fid[f'/PRODUCT/{name}']

        # ToDo handle parameter mol_m2
        return h5_to_xr(dset, (0,) + data_sel).squeeze()

    def __nc_data_as_xds(self, name, data_sel):
        """
        Read dataset from group PRODUCT using netCDF4

        Input: science product

        Return: xarray.DataArray
        """
        if name in self.fid['/target_product'].variables.keys():
            group = '/target_product'
        elif name in self.fid['/instrument'].variables.keys():
            group = '/instrument'
        else:
            raise ValueError('dataset {name} for found')


        return data_to_xr(self.get_dataset(name, data_sel),