Beispiel #1
0
    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
Beispiel #2
0
    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()
Beispiel #3
0
    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