def getdelay(self, dataobj, wvl=np.pi * 4., writeStations=True): '''Write delay to a matrix / HDF5 object or a file directly. Bilinear Interpolation is used. Args: * dataobj : Final output. (str or HDF5 or np.array) If str, output is written to file. Kwargs: * wvl : Wavelength in meters. 4*pi (by default) --> output results in delay in meters. 0.056 --> output results in delay in radians for C-band SAR. .. note:: If dataobj is string, output is written to the file. If np.array or HDF5 object, it should be of size (ny,nx). ''' # To know the type of incidence (float, array) if isinstance(self.inc, (int, float, np.float32, np.float64)): cinc = np.cos(self.inc * np.pi / 180.) incFileFlag = 'number' else: incFileFlag = 'array' # Get some info from the dictionary minAltp = self.dict['minAltP'] # Check output and open file if necessary outFile = isinstance(dataobj, str) if outFile: fout = open(dataobj, 'wb') dout = np.zeros((self.ny, self.nx)) else: assert dataobj.shape == ( self.ny, self.nx), 'PyAPS: Not a valid data object.' dout = dataobj ####################################################################################### # BILINEAR INTERPOLATION # Create the 1d interpolator to interpolate delays in altitude direction if self.verb: print('PROGRESS: FINE INTERPOLATION OF HEIGHT LEVELS') intp_1d = si.interp1d(self.hgt, self.Delfn, kind='cubic', axis=-1) # Interpolate the delay function every meter, for each station self.dem[np.isnan(self.dem)] = minAltp self.dem[self.dem < minAltp] = minAltp minH = np.max([np.nanmin(self.dem * self.mask), self.hgt.min()]) maxH = int(np.nanmax(self.dem * self.mask)) + 100. kh = np.arange(minH, maxH) self.Delfn_1m = intp_1d(kh) self.alti = kh # no reshape Lonu = self.lonlist[0, :] Latu = self.latlist[:, 0] # Create the cube interpolator for the bilinear method, to interpolate delays into a grid (x,y,z) if self.verb: print('PROGRESS: CREATE THE BILINEAR INTERPOLATION FUNCTION') # Define a linear interpolating function on the 3D grid: ((x, y, z), data) # We do the weird trick of [::-1,:,:] because Latu has to be in increasing order # for the RegularGridInterpolator method of scipy.interpolate linearint = si.RegularGridInterpolator((Latu[::-1], Lonu, kh), self.Delfn_1m[::-1, :, :], method='linear', bounds_error=False, fill_value=0.0) # Show progress bar if self.verb: toto = utils.ProgressBar(maxValue=self.ny) print('PROGRESS: MAPPING THE DELAY') # Loop on the lines for m in range(self.ny): # Update progress bar if self.verb: toto.update(m + 1, every=5) # Get latitude and longitude arrays lati = self.lat[m, :] * self.mask[m, :] loni = self.lon[m, :] * self.mask[m, :] # Remove negative values loni[loni < 0.] += 360. # Remove NaN values ii = np.where(np.isnan(lati)) jj = np.where(np.isnan(loni)) xx = np.union1d(ii, jj) lati[xx] = 0.0 loni[xx] = 0.0 # Get incidence if file provided if incFileFlag == 'array': cinc = np.cos(self.mask[m, :] * self.inc[m, :] * np.pi / 180.) # Make the bilinear interpolation D = self.dem[m, :] val = linearint(np.vstack( (lati, loni, D)).T) * np.pi * 4.0 / (cinc * wvl) val[xx] = np.nan # Write outfile if outFile: resy = val.astype(np.float32) resy.tofile(fout) else: dataobj[m, :] = val if self.verb: toto.close() if outFile: fout.close() # All done return
def merisfactor(self, dataobj, inc=0.0, wvl=4 * np.pi): ''' Write pi-factor from Li et al 2012 to a matrix / HDF5 object or a file directly. Args: * dataobj (str or HDF5 or np.array): Final output. If str, output is written to file. Kwargs: * inc (np.float): Incidence angle in degrees. Default is vertical. * wvl (np.float): Wavelength in meters. Default output results in delay in meters. .. note:: If dataobj is string, output is written to the file. If np.array or HDF5 object, it should be of size (ny,nx). ''' minAltp = self.dict['minAltP'] # Incidence cinc = np.cos(inc * np.pi / 180.0) # Compute the two integrals WonT = self.Vi / self.Ti WonT2 = WonT / self.Ti S1 = intg.cumtrapz(WonT, x=self.hgt, axis=-1) val = 2 * S1[:, -1] - S1[:, -2] val = val[:, None] S1 = np.concatenate((S1, val), axis=-1) del WonT S2 = intg.cumtrapz(WonT2, x=self.hgt, axis=-1) val = 2 * S2[:, -1] - S2[:, -2] val = val[:, None] S2 = np.concatenate((S2, val), axis=-1) del WonT2 Tm = S1 / S2 self.Tm = Tm # Reading in the DEM if self.verb: print('PROGRESS: READING DEM') fin = open(self.hfile, 'rb') if self.fmt in ('HGT'): dem = np.fromfile(file=fin, dtype=self.demtype, count=self.nx * self.ny).reshape( self.ny, self.nx) elif self.fmt in ('RMG'): dem = np.fromfile(file=fin, dtype=self.demtype, count=2 * self.nx * self.ny).reshape( self.ny, 2 * self.nx) dem = dem[:, self.nx:] dem = np.round(dem).astype(np.int) fin.close() # check output, and open file if necessary outFile = isinstance(dataobj, str) if outFile: fout = open(dataobj, 'wb') dout = np.zeros((self.ny, self.nx)) else: assert ((dataobj.shape[0] == self.ny) & (dataobj.shape[1] == self.nx)), 'PyAPS: Not a valid data object.' dout = dataobj # Create the lon/lat arrays laty = np.linspace(self.maxlat - self.bufspc, self.minlat + self.bufspc, self.ny) lonx = np.linspace(self.minlon + self.bufspc, self.maxlon - self.bufspc, self.nx) # Create the 1d interpolator if self.verb: print('PROGRESS: FINE INTERPOLATION OF HEIGHT LEVELS') intp_1d = si.interp1d(self.hgt, Tm, kind='cubic', axis=1) # Interpolate the Tm variable every meter dem[dem < minAltp] = minAltp minH = dem.min() maxH = dem.max() + 1 kh = np.arange(minH, maxH) Tm_1m = intp_1d(kh) self.alti = kh # Reshape Tm Lonu = np.unique(self.lonlist) Latu = np.unique(self.latlist) nLon = len(Lonu) nLat = len(Latu) Tm_1m = np.reshape(Tm_1m.T, (len(kh), nLat, nLon)) self.Tm_1m = Tm_1m # Create the cube interpolator for the bilinear method if self.verb: print('PROGRESS: CREATE THE BILINEAR INTERPOLATION FUNCTION') bilicube = processor.Bilinear2DInterpolator(Lonu, Latu, Tm_1m, cube=True) # Get the values from the dictionnary k1 = self.dict['k1'] k2 = self.dict['k2'] k3 = self.dict['k3'] mmO = self.dict['mmO'] mmH = self.dict['mmH'] mma = self.dict['mma'] w = (2 * mmH + mmO) / mma Rv = self.dict['Rv'] Rho = self.dict['Rho'] # Loop on the lines if self.verb: toto = utils.ProgressBar(maxValue=self.ny) print('PROGRESS: MAPPING THE DELAY') for m in range(self.ny): if self.verb: toto.update(m, every=5) # Get Lon/Lat loni = lonx lati = laty[m] * np.ones((loni.shape)) # Make the bilinear interpolation D = dem[m, :] - minH val = bilicube(loni, lati, D) val = 0.000001 * Rho * Rv * (k3 / val + k2 - w * k1) * np.pi * 4.0 / (cinc * wvl) if outFile: resy = val.astype(np.float32) resy.tofile(fout) else: dataobj[m, :] = val if self.verb: toto.close() # Close if outfile if outFile: fout.close()
def getdelay(self, dout=None, outFile=None, wvl=np.pi * 4., writeStations=True): '''Get the 2D matrix of tropospheric delay with bilinear interpolation. Kwargs: * dout : 2D np.ndarray, output delay matrix * outFile : str, file path of output delay matrix * wvl : Wavelength in meters. 4*pi (by default) --> output results in delay in meters. 0.056 --> output results in delay in radians for C-band SAR. Returns: * dout : 2D np.ndarray in size of (ny, nx) in float32. ''' # To know the type of incidence (float, array) if isinstance(self.inc, (int, float, np.float32, np.float64)): cinc = np.cos(self.inc * np.pi / 180.) incFileFlag = 'number' else: incFileFlag = 'array' # Get some info from the dictionary minAltp = self.dict['minAltP'] # initiate output dout = np.zeros( (self.ny, self.nx), dtype=np.float32) if dout is None else dout fout = open(outFile, 'wb') if outFile else None ####################################################################################### # BILINEAR INTERPOLATION # Create the 1d interpolator to interpolate delays in altitude direction if self.verb: print('PROGRESS: FINE INTERPOLATION OF HEIGHT LEVELS') intp_1d = si.interp1d(self.hgt, self.Delfn, kind='cubic', axis=-1) # Interpolate the delay function every meter, for each station self.dem[np.isnan(self.dem)] = minAltp self.dem[self.dem < minAltp] = minAltp minH = np.max([np.nanmin(self.dem * self.mask), self.hgt.min()]) maxH = int(np.nanmax(self.dem * self.mask)) + 100. kh = np.arange(minH, maxH) self.Delfn_1m = intp_1d(kh) self.alti = kh # no reshape Lonu = self.lonlist[0, :] Latu = self.latlist[:, 0] # Create the cube interpolator for the bilinear method, to interpolate delays into a grid (x,y,z) if self.verb: print('PROGRESS: CREATE THE BILINEAR INTERPOLATION FUNCTION') # Define a linear interpolating function on the 3D grid: ((x, y, z), data) # We do the weird trick of [::-1,:,:] because Latu has to be in increasing order # for the RegularGridInterpolator method of scipy.interpolate linearint = si.RegularGridInterpolator((Latu[::-1], Lonu, kh), self.Delfn_1m[::-1, :, :], method='linear', bounds_error=False, fill_value=0.0) # Show progress bar if self.verb: toto = utils.ProgressBar(maxValue=self.ny) print('PROGRESS: MAPPING THE DELAY') # Loop on the lines for m in range(self.ny): # Update progress bar if self.verb: toto.update(m + 1, every=5) # Get latitude and longitude arrays lati = self.lat[m, :] * self.mask[m, :] loni = self.lon[m, :] * self.mask[m, :] # Remove negative values if self.grib in ('ERA5', 'ERAINT', 'HRES'): loni[loni > 180.] -= 360. else: loni[loni < 0.] += 360. # Remove NaN values ii = np.where(np.isnan(lati)) jj = np.where(np.isnan(loni)) xx = np.union1d(ii, jj) lati[xx] = 0.0 loni[xx] = 0.0 # Get incidence if file provided if incFileFlag == 'array': cinc = np.cos(self.mask[m, :] * self.inc[m, :] * np.pi / 180.) # Make the bilinear interpolation D = self.dem[m, :] val = linearint(np.vstack( (lati, loni, D)).T) * np.pi * 4.0 / (cinc * wvl) val[xx] = np.nan # save output dout[m, :] = val if outFile: val.astype(np.float32).tofile(fout) if self.verb: toto.close() if outFile: fout.close() return dout