Source code for sar_pre_processing.netcdf_stack


from netCDF4 import Dataset, date2num
import xarray as xr
import numpy as np
import os, fnmatch
import datetime
import logging

[docs]class NetcdfStackCreator(object): """ Create NetCDF stack """ def __init__(self, **kwargs): self.input_folder = kwargs.get('input_folder', None) self.output_path = kwargs.get('output_path', None) self.step1_folder = kwargs.get('step1_folder', None) self.output_filename = kwargs.get('output_filename', None) self.temporal_filter = kwargs.get('temporal_filter', None) self.user_defined_graphs = kwargs.get('user_defined_graphs', None) self._check() def _check(self): assert self.input_folder is not None, 'ERROR: Folder with input files need to be specified' assert self.output_path is not None, 'ERROR: Path of output file need to be provided' assert self.output_filename is not None, 'ERROR: Name of output file need to be provided'
[docs] def create_netcdf_stack(self): self._create_filelist() self._create_empty_netcdf_file() self.stacking()
def _create_filelist(self): """create a list containing all files in specified input folder""" # Create list containing all files to be processed self.filelist = [] for root, dirnames, filenames in os.walk(self.input_folder): for filename in fnmatch.filter(filenames, '*.nc'): self.filelist.append(os.path.join(root, filename)) logging.info(f'Number of scenes found for processing: {len(self.filelist)}') # sort filelist by time (ascending) length = len(self.input_folder) self.filelist = sorted(self.filelist, key=lambda x:x[(length+18):(length+18+16)]) def _create_empty_netcdf_file(self): """ create empty netcdf file""" # create output netcdf file self.dataset = Dataset(os.path.join(self.output_path, self.output_filename + '.nc'), 'w', format='NETCDF4') # load example data for dummy creation data = Dataset(self.filelist[0]) # create dimensions self.lat = self.dataset.createDimension('lat', len(data.variables['lat'][:])) self.lon = self.dataset.createDimension('lon', len(data.variables['lon'][:])) self.time = self.dataset.createDimension('time', None) # create 1-D variables (time, orbitdirection, relativorbit, satellite, latitude, longitude) self.times = self.dataset.createVariable('time', np.float32, ('time')) self.times.calendar = 'gregorian' self.times.units = 'days since ' + '1970-01-01 00:00:00' self.orbitdirection = self.dataset.createVariable('orbitdirection', np.float32, ('time')) self.relativeorbit = self.dataset.createVariable('relorbit', np.float32, ('time')) self.satellite = self.dataset.createVariable('satellite', np.float32, ('time')) self.latitude = self.dataset.createVariable('lat', np.float32, ('lat')) self.longitude = self.dataset.createVariable('lon', np.float32, ('lon')) # create 3-D variables (localIncidenceangle ... ) for i in data.variables.keys(): if i == 'lat': pass elif i == 'lon': pass elif i == 'crs': pass else: if self.user_defined_graphs == 'yes': self.dataset.createVariable(i[:-15], np.float32,('time','lat','lon'), fill_value=-99999) #self.dataset[i[:-15]].units = 'linear' else: self.dataset.createVariable(i, np.float32,('time','lat','lon'), fill_value=-99999) self.dataset[i].units = 'linear'
[docs] def stacking(self): """stack all files into a new netcdf file created by function _create_empty_netcef_file""" # 1-D Elements data = Dataset(self.filelist[0]) self.latitude[:] = data.variables['lat'][:] self.longitude[:] = data.variables['lon'][:] # loop over all files in filelist for index, sarfile in enumerate(self.filelist): print() print("Scene", self.filelist.index(sarfile) + 1, "of", len(self.filelist)) print(sarfile) # load sarfile data = xr.open_dataset(sarfile) # encoding of satellite if data.satellite == 'S1A': sat = 0 elif data.satellite == 'S1B': sat = 1 else: sat = -9999 # encoding of orbitdirection if data.orbitdirection == 'ASCENDING': orbitdir = 0 elif data.orbitdirection =='DESCENDING': orbitdir = 1 else: orbitdir = -9999 # fill 1-D variable self.times[index] = date2num(datetime.datetime.strptime(data.date, '%Y-%m-%d %H:%M:%S'), units ='days since ' + '1970-01-01 00:00:00', calendar='gregorian') self.orbitdirection[index] = orbitdir self.orbitdirection.description = '0 = Ascending, 1 = Descending' self.relativeorbit[index] = int(data.relativeorbit) self.satellite[index] = sat self.satellite.description = '0 = Sentinel 1A, 1 = Sentinel 1B' # fill 3-D variables for i in data.variables.keys(): if i == 'lat': pass elif i == 'lon': pass elif i == 'crs': pass else: if self.user_defined_graphs == 'yes': self.dataset[i[:-15]][index,:,:] = data.variables[i][:] else: self.dataset[i][index,:,:] = data.variables[i][:] self.dataset.close()