def _build_stack(self): """ Building file stack and initialize netCDF4.mfdataset. """ if self.inventory is not None: if self._dims == 2: self.mfdataset = xr.open_mfdataset( self.inventory.dropna()['filepath'].tolist(), chunks=self.chunks, combine="nested", concat_dim=self.inventory.index.name, mask_and_scale=self.auto_decode, use_cftime=False) self.mfdataset = self.mfdataset.assign_coords( {self.inventory.index.name: self.inventory.index}) gm_name = NcFile.get_gm_name(self.mfdataset) if gm_name is not None: self.mfdataset[gm_name] = self.mfdataset[gm_name].sel( **{self.inventory.index.name: 0}, drop=True) else: self.mfdataset = xr.open_mfdataset( self.inventory.dropna()['filepath'].tolist(), chunks=self.chunks, combine='by_coords', mask_and_scale=self.auto_decode, use_cftime=False) else: raise RuntimeError('Building stack failed')
def read(self, row=None, col=None, n_rows=1, n_cols=1, band="1", nodataval=-9999, decoder=None, decoder_kwargs=None): """ Read data from netCDF4 file. Parameters ---------- row : int, optional Row number/index. If None and `col` is not None, then `row_size` rows with the respective column number will be loaded. col : int, optional Column number/index. If None and `row` is not None, then `col_size` columns with the respective row number will be loaded. n_rows : int, optional Number of rows to read (default is 1). n_cols : int, optional Number of columns to read (default is 1). band : str or list of str, optional Band numbers/names. If None, all bands will be read. nodataval : tuple or list, optional List of no data values for each band. Default: -9999 for each band. decoder : function, optional Decoding function expecting a NumPy array as input. decoder_kwargs : dict, optional Keyword arguments for the decoder. Returns ------- data : xarray.Dataset Data set with the dimensions [time, y, x] and one data variable. """ decoder_kwargs = {} if decoder_kwargs is None else decoder_kwargs if row is None and col is None: # read whole dataset row = 0 col = 0 n_rows = self.shape[-2] n_cols = self.shape[-1] elif row is None and col is not None: # read by row row = 0 n_cols = self.shape[-1] elif row is not None and col is None: # read by column col = 0 n_rows = self.shape[-2] if len(self.shape) == 3: slices = (slice(None), slice(row, row + n_rows), slice(col, col + n_cols)) else: slices = (slice(row, row + n_rows), slice(col, col + n_cols)) data_ar = self.mfdataset[band][slices] if decoder: data_ar.data = decoder(data_ar.data, nodataval, **decoder_kwargs) data = data_ar.to_dataset() if 'time' in list( data.dims.keys()) and data.variables['time'].dtype == 'float': timestamps = netCDF4.num2date(data['time'], self.time_units, only_use_cftime_datetimes=False) data = data.assign_coords({'time': timestamps}) # add projection informations again gm_name = NcFile.get_gm_name(self.mfdataset) if gm_name is not None: data[gm_name] = self.mfdataset[gm_name] #add attributes data.attrs = self.mfdataset.attrs return self._fill_nan(data)