Пример #1
0
    def get_albedo(self, grid):
        """
        Retrieve the Rayleigh single scattering albedo.

        Parameters
        ----------
        grid: shdom.Grid
            The new grid to which the data will be resampled

        Returns
        -------
        albedo: list of shdom.GridData
            A list of GridData objects containing the single scattering albedo [0,1] on a grid.
            The length of the list is the number of wavelengths.
        """
        if self.num_wavelengths == 1:
            albedo = shdom.GridData(grid,
                                    data=np.full(shape=grid.shape,
                                                 fill_value=1.0,
                                                 dtype=np.float32))
        else:
            albedo = [
                shdom.GridData(grid,
                               data=np.full(shape=grid.shape,
                                            fill_value=1.0,
                                            dtype=np.float32))
                for wavelength in self._wavelength
            ]
        return albedo
Пример #2
0
    def get_extinction(self, grid):
        """
        Retrieve the Rayleigh extinction profile (as a function of altitude).

        Parameters
        ----------
        grid: shdom.Grid
            The new grid to which the data will be resampled

        Returns
        -------
        extinction_profile: list of shdom.GridData
            A list of GridData objects containing the extinction on a 1D grid.
            The length of the list is the number of wavelengths.
        """
        if self.num_wavelengths == 1:
            ext_profile = core.rayleigh_extinct(
                nzt=grid.nz,
                zlevels=grid.z,
                temp=self.temperature_profile.data,
                raysfcpres=self.surface_pressure,
                raylcoef=self._raylcoef)
            extinction = shdom.GridData(grid, ext_profile)
        else:
            ext_profile = [
                core.rayleigh_extinct(nzt=grid.nz,
                                      zlevels=grid.z,
                                      temp=self.temperature_profile.data,
                                      raysfcpres=self.surface_pressure,
                                      raylcoef=raylcoef)
                for raylcoef in self._raylcoef
            ]
            extinction = [shdom.GridData(grid, ext) for ext in ext_profile]
        return extinction
Пример #3
0
    def load_from_csv(self, path, veff=0.1):
        """ 
        A utility function to load a microphysical medium.

        Parameters
        ----------
        path: str
            Path to file. 
        veff: float
            If effective variance is not specified in the csv file as a 6th column,
            this value is used as a homogeneous value. 
            Default value is veff=0.1

        Notes
        -----
        CSV format should be as follows:

        # comment line (description)
        nx ny nz
        dz dy dz     z_levels[0]     z_levels[1] ...  z_levels[nz-1]
        ix iy iz     lwc[ix, iy, iz]    reff[ix, iy, iz]  veff[ix, iy, iz](optional)
        .
        .
        .
        ix iy iz     lwc[ix, iy, iz]    reff[ix, iy, iz]  veff[ix, iy, iz](optional)
        """
        grid = self.load_grid(path)
        data = np.genfromtxt(path, skip_header=3)

        grid_index = data[:, :3].astype(int)
        lwc = data[:, 3]
        reff = data[:, 4]
        if data.shape[1] == 6:
            veff = data[:, 5]
        else:
            veff = veff * np.ones_like(reff)

        lwc_data = np.full(shape=(grid.nx, grid.ny, grid.nz),
                           fill_value=np.nan)
        reff_data = np.full(shape=(grid.nx, grid.ny, grid.nz),
                            fill_value=np.nan)
        veff_data = np.full(shape=(grid.nx, grid.ny, grid.nz),
                            fill_value=np.nan)
        lwc_data[grid_index[:, 0], grid_index[:, 1], grid_index[:, 2]] = lwc
        reff_data[grid_index[:, 0], grid_index[:, 1], grid_index[:, 2]] = reff
        veff_data[grid_index[:, 0], grid_index[:, 1], grid_index[:, 2]] = veff

        self.set_microphysics(lwc=shdom.GridData(grid,
                                                 lwc_data).squeeze_dims(),
                              reff=shdom.GridData(grid,
                                                  reff_data).squeeze_dims(),
                              veff=shdom.GridData(grid,
                                                  veff_data).squeeze_dims())
Пример #4
0
    def get_phase(self, grid):
        """
        Retrieve the Rayleigh phase function.

        Parameters
        ----------
        grid: shdom.Grid
            The new grid to which the data will be resampled

        Returns
        -------
        phase: list of shdom.GridPhase
            A list of GridPhase objects containing the phase function on a grid.
            The length of the list is the number of wavelengths.
        """
        phase = []
        for wavelength in self._wavelength:
            index = shdom.GridData(grid,
                                   data=np.ones(shape=grid.shape,
                                                dtype=np.int32))
            table, table_type = core.rayleigh_phase_function(
                wavelen=wavelength)
            table = LegendreTable(table.astype(np.float32),
                                  table_type.decode())
            phase.append(GridPhase(table, index))

        if self.num_wavelengths == 1:
            phase = phase[0]
        return phase
Пример #5
0
    def compute_extinction(self, veff=0.1):
        # extrarc grid data:
        bounding_box = shdom.BoundingBox(self.bounding_box_xmin,
                                         self.bounding_box_ymin,
                                         self.bounding_box_xmin,
                                         self.bounding_box_xmax,
                                         self.bounding_box_ymax,
                                         self.bounding_box_zmax)

        grid = shdom.Grid(bounding_box=bounding_box,
                          nx=self.nx,
                          ny=self.ny,
                          nz=self.nz)

        # self.extinction = np.zeros([self.nx,self.ny,self.nz])
        veff = veff * np.ones_like(self.re)
        lwc = shdom.GridData(grid, self.lwc).squeeze_dims()
        reff = shdom.GridData(grid, self.re).squeeze_dims()
        veff = shdom.GridData(grid, veff).squeeze_dims()
        extinction = self.mie.get_extinction(lwc, reff, veff)
        self.extinction = extinction.data
Пример #6
0
 def get_mask(self, threshold):
     """
     Get a mask based on the optical extinction.
     
     Parameters
     ----------
     threshold: float
         A threshold which above this value it is considered a populated voxel.
     
     Returns
     -------
     mask: shdom.GridData object
         A boolean mask with True for dense voxels and False for optically thin regions.
     """
     data = self.extinction.data > threshold
     return shdom.GridData(self.grid, data)
Пример #7
0
 def get_mask(self, threshold):
     """
     Get a mask based on the liquid water content.
 
     Parameters
     ----------
     threshold: float
         A threshold which above this value it is considered a populated voxel.
 
     Returns
     -------
     mask: shdom.GridData object
         A boolean mask with True for dense voxels and False for thin voxels.
     """
     data = self.lwc.data > threshold
     return shdom.GridData(self.grid, data)
Пример #8
0
 def get_albedo(self, reff, veff):
     """
     Interpolate the single scattering albedo over a grid.
     
     Parameters
     ----------
     reff: shdom.GridData 
         A shdom.GridData object containing the effective radii (micron) on a 3D grid.
     veff: shdom.GridData 
         A GridData object containing effective variances on a 3D grid.
         
     Returns
     -------
     albedo: shdom.GridData object
         A shdom.GridData object containing the single scattering albedo unitless in range [0, 1] on a 3D grid
     """
     grid = veff.grid + reff.grid
     data = self._ssalb_interpolator(
         (reff.resample(grid).data, veff.resample(grid).data))
     albedo = shdom.GridData(grid, data)
     return albedo
Пример #9
0
 def get_extinction(self, lwc, reff, veff):
     """
     Retrieve the extinction coefficient over a grid.
 
     Parameters
     ----------
     lwc: shdom.GridData 
         A GridData object containing liquid water content (g/m^3) on a grid.
     reff: shdom.GridData 
         A GridData object containing effective radii (micron) on a grid.
     veff: shdom.GridData 
         A GridData object containing effective variances on a grid.
     
     Returns
     -------
     extinction: shdom.GridData object
         A GridData object containing the extinction (1/km) on a grid
     """
     grid = lwc.grid + veff.grid + reff.grid
     data = self._ext_interpolator(
         (reff.resample(grid).data, veff.resample(grid).data))
     extinction = lwc.resample(grid) * shdom.GridData(grid, data)
     return extinction
Пример #10
0
    def get_phase(self, reff, veff, squeeze_table=True):
        """
        Interpolate the phase function over a grid.
    
        Parameters
        ----------
        reff: shdom.GridData 
            A shdom.GridData object containing the effective radii (micron) on a 3D grid.
        veff: shdom.GridData 
            A GridData object containing effective variances on a 3D grid.
        squeeze_table: boolean
            True: return compact table containing the range of provided reff, veff. 
            False will return the current table.
            
        Returns
        -------
        phase: GridPhase
            A GridPhase object containing the phase function legendre coeffiecients as a table.
        """
        grid = veff.grid + reff.grid

        index = self._legen_index_interpolator(
            (reff.resample(grid).data,
             veff.resample(grid).data)).astype(np.int32)
        nre, nve = self.size_distribution.nretab, self.size_distribution.nvetab

        # Clip table to make it compact
        if squeeze_table:
            max_re_idx = min(
                nre - 1,
                find_nearest(self.size_distribution.reff, reff.data.max()))
            max_ve_idx = min(
                nve - 1,
                find_nearest(self.size_distribution.veff, veff.data.max()))
            min_re_idx = max(
                0,
                find_nearest(self.size_distribution.reff,
                             reff.data[reff.data > 0.0].min()))
            min_ve_idx = max(
                0,
                find_nearest(self.size_distribution.veff,
                             veff.data[veff.data > 0.0].min()))
            legcoef = self.legcoef_2d[..., min_re_idx:max_re_idx + 1,
                                      min_ve_idx:max_ve_idx + 1]
            nre, nve = legcoef.shape[-2:]
            legcoef = legcoef.reshape(self.legcoef.shape[:-1] + (-1, ),
                                      order='F')
            index[..., 0] -= min_re_idx
            index[..., 1] -= min_ve_idx

        else:
            legcoef = self.legcoef

        legen_table = shdom.LegendreTable(legcoef, self.table_type)
        index = np.ravel_multi_index(np.rollaxis(index, axis=-1),
                                     dims=(nre, nve),
                                     order='F',
                                     mode='clip') + 1
        legen_index = shdom.GridData(grid, index.astype(np.int32))
        phase = GridPhase(legen_table, legen_index)
        return phase