SMRT Documentation¶
The SMRT API documentation describes the structure of the package and modules and provides detailed information on the classes and functions. It is not a practical guide for beginners to learn SMRT even though a few examples are sometimes given. We recommend to first read the tutorials <link here> and then use this API documentation as a further step to exploit SMRT in depth. SMRT extensively uses default/optional arguments in functions to provide a simple yet extendable interface. The API documentation is the only valid/up-to-date reference for these default behaviours as it is auto-generated from source. For developers who want to implement new behaviour in SMRT for their own use or for improving SMRT, we recomend to read the developer guidelines <link here> and to contact the authors of the model to discuss about the best/most generic approach to solve your problem. More documentation for improving SMRT will be prepared in the future.
The following package describes all the packages available in SMRT. The inputs
package includes the functions to build the medium and the sensor configuration, it will include in the future any useful functions for inputs from various sources (text file, snowpack model simulations, etc). The permittivity
package provides formulae to compute the permittivity of raw materials such as ice. The microstructure_model
package includes all the representations of the snow micro-structure available. It provides information on the required and optional parameters of each microstrcuture_model. interface
provides the formulation for different types of inter-layer interfaces (such as flat, rugged in the future).
The substrate
package and atmosphere
packages provide the lower and upper boundary conditions of the radiative transfer. Substrate can represent the soil, ice, ocean.
It is worth noting that these modules describe the half-space semi-infinite media under and above the snowpack. It means they have uniform properties and especially temperature which is common practice when the focus is on the snowpack. However, for a proper fully coupled multi-layered soil-snow-atmosphere radiative transfer model, it would be necessary to describe the soil and the atmosphere as layers (exactly as the snowpack is made of snow layers) and to implement emmodel
adequately to the soil and atmosphere.
The emmodel
package includes all the scattering theories available in SMRT (iba, dmrt, independent spheres (Rayleigh), …). In some case there is an inter-dependence between the choices of micro-structure and of electromagnetic theory. For instance, dmrt_shortrange
only works with sticky_hard_spheres
microstructure (this is inherent to theory) and rayleigh
would work with any microstructure model based on spheres (ie. that defines a radius parameter).
The rtsolver
package includes the numerical codes that solves the radiative transfer equation.
The core
package is where the SMRT machinery is implemented and especially the most important objects
Sensor
, Layer
, Snowpack
, Model
, etc. It may be useful to understand how these objects work but it is not necessary as most of them (all) are created by helper functions which are much more convenient to use than class constructors. The only exception, which is worth exploring a bit, is Result
. It provides useful methods to extract the result of the radiative calculation.
In general, it is not recommended to modify/extend core
for normal needs. This package does contain any science.
The utils
package provides various useful tools to work with SMRT, but they are not strictly necessary. This package includes wrappers to some off-the-shelf models such as DMRT-QMS, HUT and MEMLS.
smrt.inputs package¶
Submodules¶
smrt.inputs.altimeter_list module¶
-
envisat_ra2
(channel=None)¶ return an Altimeter instance for the ENVISAT RA2 altimeter.
Parameters: channel – can be ‘S’, ‘Ku’, or both. Default is both.
-
sentinel3_sral
(channel=None)¶ return an Altimeter instance for the Sentinel 3 SRAL instrument.
Parameters: channel – can be ‘Ku’ only (‘C’ is to be implemented)
-
saral_altika
()¶ return an Altimeter instance for the Saral/AltiKa instrument.
-
cryosat2_lrm
()¶ Return an altimeter instance for CryoSat-2
Parameters from https://earth.esa.int/web/eoportal/satellite-missions/c-missions/cryosat-2 Altitude from https://doi.org/10.1016/j.asr.2018.04.014 Beam width is 1.08 along track and 1.2 across track
-
cryosat2_sin
()¶ Return an altimeter instance for CryoSat-2: SIN mode
Parameters from https://earth.esa.int/web/eoportal/satellite-missions/c-missions/cryosat-2 Altitude from https://doi.org/10.1016/j.asr.2018.04.014 Beam width is 1.08 along track and 1.2 across track
-
asiras_lam
(altitude=None)¶ Return an altimeter instance for ASIRAS in Low Altitude Mode
Parameters from https://earth.esa.int/web/eoportal/airborne-sensors/asiras Beam width is 2.2 x 9.8 deg
smrt.inputs.make_medium module¶
The helper functions in this module are used to create snowpacks, sea-ice and other media. They are user-friendly and recommended for most usages. Extension of these functions is welcome on the condition they keep a generic structure.
The function make_snowpack()
is the first entry point the user should consider to build a snowpack.
For example:
from smrt import make_snowpack
sp = make_snowpack([1000], density=[300], microstructure_model='sticky_hard_spheres', radius=[0.3e-3], stickiness=0.2)
creates a semi-infinite snowpack made of sticky hard spheres with radius 0.3mm and stickiness 0.2.
The Snowpack
object is in the sp variable.
Note that make_snowpack is directly imported from smrt instead of smrt.inputs.make_medium. This feature is for convenience.
-
make_medium
(data, surface=None, interface=None, substrate=None, **kwargs)¶ build a multi-layered medium using a pandas DataFrame (or a dict that can be transformed into a DataFrame) and optinal arguments. The ‘medium’ column (or key) in data indicates the medium type: ‘snow’ or ‘ice’. If not given, it defaults to ‘snow’. ‘data’ must contain enough information to build either a snowpack or an ice_column. The minimum requirements are:
- for a snowpack: (‘z’ or ‘thickness’), ‘density’, ‘microstructure_model’ and the arguments required by the microstructural_model.
- for a ice column: ice_type, (‘z’ or ‘thickness’), ‘temperature’, ‘salinity’, ‘microstructure_model’ and the arguments required by
the microstructural_model.
When reading a dataframe from disk for instance, it is convenient to use df.rename(columns={…}) to map the column names of the file to the column names required by SMRT.
if ‘z’ is given, the thickness is deduced using
compute_thickness_from_z()
.** Warning **: Using this function is a bit dangerous as any unrecognized column names are silently ignored. For instance, a column named ‘Temperature’ is ignore (due to the uppercase), and the temperature in the snowpack will be set to its default value (273.15 K). This issue applies to any optional argument. Double ckeck the spelling of the columns.
- ** Note **: make_medium create laters using all the columns in the dataframe. It means that any column name becomes an attribute of
- the layer objects, even if not recognized/used by SMRT. This can be seen as an interesting feature to store information in layers, but this is also dangerous if column names collide with internal layer attributes or method names. For this reason,
this function is unsecure if the snowpack data are pulled from the internet. Always check the content of the file, and it is recommended to drop all the unnecessary columns with df.drop(columns=[…])) before calling make_medium.
-
make_snowpack
(thickness, microstructure_model, density, interface=None, surface=None, substrate=None, atmosphere=None, **kwargs)¶ Build a multi-layered snowpack. Each parameter can be an array, list or a constant value.
Parameters: - thickness – thicknesses of the layers in meter (from top to bottom). The last layer thickness can be “numpy.inf” for a semi-infinite layer.
- microstructure_model – microstructure_model to use (e.g. sticky_hard_spheres or independent_sphere or exponential).
- surface – type of surface interface, flat/fresnel is the default. If surface and interface are both set, the interface must be a constant refering to all the “internal” interfaces.
- interface – type of interface, flat/fresnel is the default. It is usually a string for the interfaces
without parameters (e.g. Flat or Transparent) or is created with
make_interface()
in more complex cases. Interface can be a constant or a list. In the latter case, its length must be the same as the number of layers, and interface[0] refers to the surface interface. - density – densities of the layers.
- substrate – set the substrate of the snowpack. Another way to add a substrate is to use the + operator (e.g. snowpack + substrate).
- **kwargs –
All the other parameters (temperature, microstructure parameters, emmodel, etc.) are given as optional arguments (e.g. temperature=[270, 250]). They are passed for each layer to the function
make_snow_layer()
. Thus, the documentation of this function is the reference. It describes precisely the available parameters. The microstructure parameter(s) depend on the microstructure_model used and is documented in each microstructure_model module.
e.g.:
sp = make_snowpack([1, 10], "exponential", density=[200,300], temperature=[240, 250], corr_length=[0.2e-3, 0.3e-3])
-
make_snow_layer
(layer_thickness, microstructure_model, density, temperature=273.15, ice_permittivity_model=None, background_permittivity_model=1.0, volumetric_liquid_water=None, liquid_water=None, salinity=0, medium='snow', **kwargs)¶ Make a snow layer for a given microstructure_model (see also
make_snowpack()
to create many layers). The microstructural parameters depend on the microstructural model and should be given as additional arguments to this function. To know which parameters are required or optional, refer to the documentation of the specific microstructure model used.Parameters: - layer_thickness – thickness of snow layer in m.
- microstructure_model – module name of microstructure model to be used.
- density – density of snow layer in kg m -3. Includes the ice and water phases.
- temperature – temperature of layer in K.
- ice_permittivity_model – permittivity formulation of the scatterers (default is ice_permittivity_matzler87).
- background_permittivity_model – permittivity formulation for the background (default is air).
- volumetric_liquid_water – volume of liquid water with respect to the volume of snow (default=0).
- liquid_water – May be depreciated in the future (use instead volumetric_liquid_water): volume of liquid water with respect to ice+water volume (default=0). liquid_water = water_volume / (ice_volume + water_volume).
- salinity – salinity in kg/kg, for using PSU as unit see PSU constant in smrt module (default = 0).
- medium – indicate which medium the layer is made of (“snow” is a default).
It is used when emmodel is a dictionary mapping from medium to emmodels in
make_model()
- kwargs – other microstructure parameters are given as optional arguments (in Python words) but may be required (in SMRT words). See the documentation of the microstructure model.
Returns: SnowLayer
instance
-
class
SnowLayer
(*args, density=None, volumetric_liquid_water=None, liquid_water=None, **kwargs)¶ Bases:
smrt.core.layer.Layer
- Specialized Layer class for snow. It deals with the calculation of the frac_volume and the liquid_water
- from density and volumetric_liquid_water. Alternatively it is possible to set liquid_water directly but this is not recommended anymore.
Meta private: -
update
(density=None, volumetric_liquid_water=None, liquid_water=None, **kwargs)¶ update the density and/or volumetric_liquid_water. This method must be used every time density and/or volumetric_liquid_water are changed. Setting directly the corresponding attributes of the Layer object raises an error because a recalculation of the frac_volume and liquid_volume is necessary every time one of these variables is changed.
-
static
compute_frac_volumes
(density, volumetric_liquid_water=None, liquid_water=None)¶ compute and return the fractional volumes: - frac_volume =(ice+water) / (ice+water+air) - liquid_water =(water) / (ice+water)
-
make_ice_column
(ice_type, thickness, temperature, microstructure_model, brine_inclusion_shape='spheres', salinity=0.0, brine_volume_fraction=None, brine_permittivity_model=None, ice_permittivity_model=None, saline_ice_permittivity_model=None, porosity=0, density=None, add_water_substrate=True, surface=None, interface=None, substrate=None, atmosphere=None, **kwargs)¶ Build a multi-layered ice column. Each parameter can be an array, list or a constant value.
ice_type variable determines the type of ice, which has a big impact on how the medium is modelled and the parameters: - First year ice is modelled as scattering brines embedded in a pure ice background - Multi year ice is modelled as scattering air bubbles in a saline ice background (but brines are non-scattering in this case). - Fresh ice is modelled as scattering air bubbles in a pure ice background (but brines are non-scattering in this case).
First-year and multi-year ice is equivalent only if scattering and porosity are nulls. It is important to understand that in multi-year ice scattering by brine pockets is neglected because scattering is due to air bubbles and the emmodel implemented up to now are not able to deal with three-phase media.
Parameters: - ice_type – Ice type. Options are “firstyear”, “multiyear”, “fresh”
- thickness – thicknesses of the layers in meter (from top to bottom). The last layer thickness can be “numpy.inf” for a semi-infinite layer.
- temperature – temperature of ice/water in K
- brine_inclusion_shape – assumption for shape of brine inclusions. So far, “spheres” or “random_needles” (i.e. elongated ellipsoidal inclusions), and “mix” (a mix of the two) are implemented.
- salinity – salinity of ice/water in kg/kg (see PSU constant in smrt module). Default is 0. If neither salinity nor brine_volume_fraction are given, the ice column is considered to consist of fresh water ice.
- brine_volume_fraction – brine / liquid water fraction in sea ice, optional parameter, if not given brine volume fraction is calculated from temperature and salinity in ~.smrt.permittivity.brine_volume_fraction
- density – density of ice layer in kg m -3
- porosity – porosity of ice layer (0 - 1). Default is 0.
- add_water_substrate – Adds a substrate made of water below the ice column. Possible arguments are True (default) or False. If True looks for ice_type to determine if a saline or fresh water layer is added and/or uses the optional arguments ‘water_temperature’, ‘water_salinity’ of the water substrate.
- surface – type of surface interface, flat/fresnel is the default. If surface and interface are both set, the interface must be a constant refering to all the “internal” interfaces.
- interface – type of interface, flat/fresnel is the default. It is usually a string for the interfaces without parameters
(e.g. Flat or Transparent) or is created with
make_interface()
in more complex cases. Interface can be a constant or a list. In the latter case, its length must be the same as the number of layers, and interface[0] refers to the surface interface. - substrate – if add_water_substrate is False, the substrate can be prescribed with this argument.
All the other optional arguments are passed for each layer to the function
make_ice_layer()
. The documentation of this function describes in detail the parameters used/required depending on ice_type.
-
make_ice_layer
(ice_type, layer_thickness, temperature, salinity, microstructure_model, brine_inclusion_shape='spheres', brine_volume_fraction=None, porosity=0, density=None, brine_permittivity_model=None, ice_permittivity_model=None, saline_ice_permittivity_model=None, medium='ice', **kwargs)¶ Make an ice layer for a given microstructure_model (see also
make_ice_column()
to create many layers). The microstructural parameters depend on the microstructural model and should be given as additional arguments to this function. To know which parameters are required or optional, refer to the documentation of the specific microstructure model used.Parameters: - ice_type – Assumed ice type
- layer_thickness – thickness of ice layer in m
- temperature – temperature of layer in K
- salinity – (firstyear and multiyear) salinity in kg/kg (see PSU constant in smrt module)
- brine_inclusion_shape – (firstyear and multiyear) assumption for shape of brine inclusions (so far, “spheres” and “random_needles” (i.e. elongated ellipsoidal inclusions), and “mix_spheres_needles” are implemented)
- brine_volume_fraction – (firstyear and multiyear) brine / liquid water fraction in sea ice, optional parameter, if not given brine volume fraction is calculated from temperature and salinity in ~.smrt.permittivity.brine_volume_fraction
- density – (multiyear) density of ice layer in kg m -3. If not given, density is calculated from temperature, salinity and ice porosity.
- porosity – (mutliyear and fresh) air porosity of ice layer (0..1). Default is 0.
- ice_permittivity_model – (all) pure ice permittivity formulation (default is ice_permittivity_matzler06 for firstyear and fresh, and saline_ice_permittivity_pvs_mixing for multiyear)
- brine_permittivity_model – (firstyear and multiyear) brine permittivity formulation (default is brine_permittivity_stogryn85)
- saline_ice_permittivity_model – (multiyear) model to mix ice and brine. The default uses polder van staten and ice_permittivity_model and brine_permittivity_model. It is highly recommanded to use the default.
- kwargs – other microstructure parameters are given as optional arguments (in Python words) but may be required (in SMRT words).
- medium – indicate which medium the layer is made of (“ice” is a default).
It is used when emmodel is a dictionary mapping from medium to emmodels in
make_model()
See the documentation of the microstructure model.
Returns: Layer
instance
-
make_water_body
(layer_thickness=1000, temperature=273, salinity=0, water_permittivity_model=None, surface=None, atmosphere=None, substrate=None)¶ Make a water body with a single layer of water at given temperature and salinity.
Note that water is a very strong absorber even fresh water, it is unlikely that the layers under a water body could be seen by microwaves. If really needed anyway, a multi-layer water body or
a water layer on another medium (e.g. ice) can be build using the addition operator.Parameters: - layer_thickness – thickness of ice layer in m
- temperature – temperature of layer in K
- salinity – salinity in kg/kg (see PSU constant in smrt module)
- water_permittivity_model – water permittivity formulation (default is seawater_permittivity_klein76)
- surface – type of surface interface. Flat surface (Fresnel coefficient) is the default.
- substrate – the substrate under the water layer.
-
make_water_layer
(layer_thickness, temperature=273, salinity=0, water_permittivity_model=None, **kwargs)¶ Make a water layer at given temperature and salinity.
Parameters: - layer_thickness – thickness of ice layer in m
- temperature – temperature of layer in K
- salinity – salinity in kg/kg (see PSU constant in smrt module)
- water_permittivity_model – water permittivity formulation (default is seawater_permittivity_klein76)
-
water_parameters
(ice_type, **kwargs)¶ Make a semi-infinite water layer.
Parameters: ice_type – ice_type is used to determine if a saline or fresh water layer is added The optional arguments are ‘water_temperature’, ‘water_salinity’ and ‘water_depth’ of the water layer.
-
bulk_ice_density
(temperature, salinity, porosity)¶ Computes bulk density of sea ice (in kg m -3), when considering the influence from brine, solid salts, and air bubbles in the ice. Formulation from Cox & Weeks (1983): Equations for determining the gas and brine volumes in sea ice samples, J Glac. Developed for temperatures between -2–30°C. For higher temperatures (>2°C) is used the formulation from Lepparanta & Manninen (1988): The brine and gas content of sea ice with attention to low salinities and high temperatures.
Parameters: - temperature – Temperature in K
- salinity – salinity in kg/kg (see PSU constant in smrt module)
- porosity – Fractional volume of air inclusions (0..1)
Returns: Density of ice mixture in kg m -3
-
make_generic_stack
(thickness, temperature=273, ks=0, ka=0, effective_permittivity=1, interface=None, substrate=None, atmosphere=None)¶ build a multi-layered medium with prescribed scattering and absorption coefficients and effective permittivity. Must be used with presribed_kskaeps emmodel.
Parameters: - thickness – thicknesses of the layers in meter (from top to bottom). The last layer thickness can be “numpy.inf” for a semi-infinite layer.
- temperature – temperature of layers in K
- ks – scattering coefficient of layers in m^-1
- ka – absorption coefficient of layers in m^-1
- interface – type of interface, flat/fresnel is the default
-
make_generic_layer
(layer_thickness, ks=0, ka=0, effective_permittivity=1, temperature=273)¶ Make a generic layer with prescribed scattering and absorption coefficients and effective permittivity. Must be used with presribed_kskaeps emmodel.
Parameters: - layer_thickness – thickness of ice layer in m
- temperature – temperature of layer in K
- ks – scattering coefficient of layers in m^-1
- ka – absorption coefficient of layers in m^-1
Returns: Layer
instance
-
make_atmosphere
(atmosphere_model, **kwargs)¶ make a atmospheric single-layer using the prescribed atmosphere model. Warning: this function is subject to change in the future when refactoring how SMRT deals with atmosphere.
Parameters: - atmosphere_model – the name of the model to use. The available models are in smrt.atmosphere.
- **kwargs –
all the parameters used by the atmosphere_model.
-
compute_thickness_from_z
(z)¶ - Compute the thickness of layers given the elevation z. Whatever the sign of z, the order MUST be from the topmost layer to the
- lowermost.
Several situation are accepted and interpretated as follows: - z is positive and decreasing. The first value is the height of the surface about the ground (z=0) and z represents the top elevation of each layer. This is typical of the seasonal snowpack. - z is negative and decreasing. The first value is the elevation of the bottom of the first layer with respect to the surface (z=0). This is typical of a snowpack on ice-sheet. - z is positive and increasing. The first value is the depth of the bottom of the first layer with respect to the surface. This is typical of a snowpack on ice-sheet. - other case, when z is not monoton or is increasing with negative value raises an error.
Because z indicate the top or the bottom of a layer depending whether z=0 is the ground or the surface, the value 0 can never be in z. This raises an error.
smrt.inputs.make_soil module¶
This module provides a function to build soil model and provides some soil permittivity formulae.
To create a substrate, use/implement an helper function such as make_soil()
. This function is able to
automatically load a specific soil model and provides some soil permittivity formulae as well.
Examples:
from smrt import make_soil
soil = make_soil("soil_wegmuller", "dobson85", moisture=0.2, sand=0.4, clay=0.3, drymatter=1100, roughness_rms=1e-2)
It is recommand to first read the documentation of make_soil()
and then explore the different types of soil
models.
-
make_soil
(substrate_model, permittivity_model, temperature, moisture=None, sand=None, clay=None, drymatter=None, **kwargs)¶ Construct a soil instance based on a given surface electromagnetic model, a permittivity model and parameters
Parameters: - substrate_model – name of substrate model, can be a class or a string. e.g. fresnel, wegmuller…
- permittivity_model – permittivity_model to use. Can be a name (“hut_epss”, “dobson85”, “montpetit2008”), a function of frequency and temperature or a complex value.
- moisture – soil moisture in m:sup:3 m:sup:-3 to compute the permittivity. This parameter is used depending on the permittivity_model.
- sand – soil relative sand content. This parameter is used or not depending on the permittivity_model.
- clay – soil relative clay content. This parameter is used or not depending on the permittivity_model.
- drymatter – soil content in dry matter in kg m:sup:-3. This parameter is used or not depending on the permittivity_model.
- **kwargs –
geometrical parameters depending on the substrate_model. Refer to the document of each model to see the list of required and optional parameters. Usually, it is roughness_rms, corr_length, …
Usage example:
- ::
- TOTEST: bottom = substrate.make(‘Flat’, permittivity_model=complex(‘6-0.5j’)) TOTEST: bottom = substrate.make(‘Wegmuller’, permittivity_model=’soil’, roughness_rms=0.25, moisture=0.25)
-
soil_dielectric_constant_dobson
(frequency, tempK, SM, S, C)¶
-
soil_dielectric_constant_hut
(frequency, tempK, SM, sand, clay, dm_rho)¶
-
soil_dielectric_constant_monpetit2008
(frequency, temperature)¶ Soil dielectric constant formulation based on the formulation Montpetit et al. 2018. The formulation is only valid for below-frrezing point temperature.
Reference: Montpetit, B., Royer, A., Roy, A., & Langlois, A. (2018). In-situ passive microwave emission model parameterization of sub-arctic frozen organic soils. Remote Sensing of Environment, 205, 112–118. https://doi.org/10.1016/j.rse.2017.10.033
smrt.inputs.make_substrate module¶
smrt.inputs.sensor_list module¶
The sensor configuration includes all the information describing the sensor viewing geometry (incidence, …)
and operating parameters (frequency, polarization, …). The easiest and recommended way to create a Sensor
instance is
to use one of the convenience functions listed below. The generic functions passive()
and active()
should cover all the usages,
but functions for specific sensors are more convenient. See examples in the functions documentation below. We recommend to add new sensors/functions here and share your file to be included in SMRT.
-
passive
(frequency, theta, polarization=None, channel_map=None, name=None)¶ Generic configuration for passive microwave sensor.
Return a
Sensor
for a microwave radiometer with given frequency, incidence angle and polarizationParameters: - frequency – frequency in Hz
- theta – viewing angle or list of viewing angles in degrees from vertical. Note that some RT solvers compute all viewing angles whatever this configuration because it is internally needed part of the multiple scattering calculation. It it therefore often more efficient to call the model once with many viewing angles instead of calling it many times with a single angle.
- polarization (list of characters) – H and/or V polarizations. Both polarizations is the default. Note that most RT solvers compute all the polarizations whatever this configuration because the polarizations are coupled in the RT equation.
- channel_map (dict) – map channel names (keys) to configuration (values). A configuration is a dict with frequency, polarization and other such parameters to be used by Result to select the results.
- name (string) – name of the sensor
Returns: Sensor
instanceUsage example:
from smrt import sensor_list radiometer = sensor_list.passive(18e9, 50) radiometer = sensor_list.passive(18e9, 50, "V") radiometer = sensor_list.passive([18e9,36.5e9], [50,55], ["V","H"])
-
active
(frequency, theta_inc, theta=None, phi=None, polarization_inc=None, polarization=None, channel_map=None, name=None)¶ Configuration for active microwave sensor.
Return a
Sensor
for a radar with given frequency, incidence and viewing angles and polarizationIf polarizations are not specified, quad-pol is the default (VV, VH, HV and HH). If the angle of incident radiation is not specified, backscatter will be simulated
Parameters: - frequency – frequency in Hz
- theta_inc – incident angle in degrees from the vertical
- theta – viewing zenith angle in degrees from the vertical. By default, it is equal to theta_inc which corresponds to the backscatter direction
- phi – viewing azimuth angle in degrees from the incident direction. By default, it is pi which corresponds to the backscatter direction
- polarization_inc (list of 1-character strings) – list of polarizations of the incidence wave (‘H’ or ‘V’ or both.)
- polarization (list of 1-character strings) – list of viewing polarizations (‘H’ or ‘V’ or both)
- channel_map (dict) – map channel names (keys) to configuration (values). A configuration is a dict with frequency, polarization and other such parameters to be used by Result to select the results.
- name (string) – name of the sensor
Returns: Sensor
instanceUsage example:
from smrt import sensor_list scatterometer = sensor_list.active(frequency=18e9, theta_inc=50) scatterometer = sensor_list.active(18e9, 50, 50, 0, "V", "V") scatterometer = sensor_list.active([18e9,36.5e9], theta=50, theta_inc=50, polarization_inc=["V", "H"], polarization=["V", "H"])
-
amsre
(channel=None, frequency=None, polarization=None, theta=55)¶ Configuration for AMSR-E sensor.
This function can be used to simulate all 12 AMSR-E channels i.e. frequencies of 6.925, 10.65, 18.7, 23.8, 36.5 and 89 GHz at both polarizations H and V. Alternatively single channels can be specified with 3-character identifiers. 18 and 19 GHz can be used interchangably to represent 18.7 GHz, similarly either 36 and 37 can be used to represent the 36.5 GHz channel. Note that if you need both H and V polarization (at 37 GHz for instance), use channel=”37” instead of channel=[“37V”, “37H”] as this will result in a more efficient simulation, because most rtsolvers anyway compute both polarizations in one shot.
Parameters: channel (3-character string) – single channel identifier Returns: Sensor
instanceUsage example:
from smrt import sensor radiometer = sensor.amsre() # Simulates all channels radiometer = sensor.amsre('36V') # Simulates 36.5 GHz channel only radiometer = sensor.amsre('06H') # 6.925 GHz channel
-
amsr2
(channel=None, frequency=None, polarization=None, theta=55)¶ Configuration for AMSR-2 sensor.
This function can be used to simulate all 14 AMSR2 channels i.e. frequencies of 6.925, 10.65, 18.7, 23.8, 36.5 and 89 GHz at both polarizations H and V. Alternatively single channels can be specified with 3-character identifiers. 18 and 19 GHz can be used interchangably to represent 18.7 GHz, similarly either 36 and 37 can be used to represent the 36.5 GHz channel. Note that if you need both H and V polarization (at 37 GHz for instance), use channel=”37” instead of channel=[“37V”, “37H”] as this will result in a more efficient simulation, because most rtsolvers anyway compute both polarizations in one shot.
Parameters: channel (3-character string) – single channel identifier Returns: Sensor
instanceUsage example:
from smrt import sensor radiometer = sensor.amsre() # Simulates all channels radiometer = sensor.amsre('36V') # Simulates 36.5 GHz channel only radiometer = sensor.amsre('06H') # 6.925 GHz channel
-
cimr
(channel=None, frequency=None, polarization=None, theta=55)¶ Configuration for AMSR-2 sensor.
This function can be used to simulate all 10 CIMR channels i.e. frequencies of 1.4, 6.9, 10.6, 18.7, 36.5 GHz at both polarizations H and V. Alternatively single channels can be specified with 3-character identifiers. 18 and 19 GHz can be used interchangably to represent 18.7 GHz, similarly either 36 and 37 can be used to represent the 36.5 GHz channel. Note that if you need both H and V polarization (at 37 GHz for instance), use channel=”37” instead of channel=[“37V”, “37H”] as this will result in a more efficient simulation, because most rtsolvers anyway compute both polarizations in one shot.
Parameters: channel (3-character string) – single channel identifier Returns: Sensor
instance
-
common_conical_pmw
(sensor_name, frequency_dict, channel=None, frequency=None, polarization=None, theta=55, name=None)¶
-
quikscat
(channel=None, theta=None)¶ Configuration for quikscat sensor.
This function can be used to simulate the 4 QUIKSCAT channels i.e. incidence angles 46° and 54° and HH and VV polarizations. Alternatively a subset of these channels can be specified with 4-character identifiers with polarization first .e.g. HH46, VV54
Parameters: channel (4-character string) – single channel identifier Returns: Sensor
instance
-
ascat
(theta=None)¶ Configuration for ASCAT on ENVISAT sensor.
This function returns a sensor at 5.255 GHz (C-band) and VV polarization. The incidence angle can be chosen or is by defaut from 25° to 65° every 5°
Parameters: theta (float or sequence) – incidence angle (between 25 and 65° in principle) Returns: Sensor
instance
-
sentinel1
(theta=None)¶ Configuration for C-SAR on Sentinel 1.
This function return a sensor at 5.405 GHz (C-band). The incidence angle can be chosen or is by defaut from 20 to 45° by step of 5°
Parameters: theta (float or sequence) – incidence angle Returns: Sensor
instance
-
smos
(theta=None)¶ Configuration for MIRAS on SMOS.
This function returns a passive sensor at 1.41 GHz (L-band). The incidence angle can be chosen or is by defaut from 0 to 60° by step of 5°
Parameters: theta (float or sequence) – incidence angle Returns: Sensor
instance
-
smap
(mode, theta=40)¶ Configuration for the passive (mode=P) and active (mode=A) sensor on smap
This function returns either a passive sensor at 1.4 GHz (L-band) sensor or an active sensor at 1.26 GHz. The incidence angle is 40°.
-
filter_channel_map
(channel_map, channel)¶
-
extract_configuration
(channel_map)¶
smrt.inputs.test_make_medium module¶
-
test_make_snowpack
()¶
-
test_make_snowpack_surface_interface
()¶
-
test_make_snowpack_interface
()¶
-
test_make_snowpack_surface_and_list_interface
()¶
-
test_make_snowpack_with_scalar_thickness
()¶
-
test_make_snowpack_array_size
()¶
-
test_make_lake_ice
()¶
-
test_make_medium
()¶
-
test_make_snowpack_volumetric_liquid_water
()¶
-
test_update_volumetric_liquid_water
()¶
-
test_snow_set_readonly
()¶
smrt.inputs.test_make_substrate module¶
smrt.inputs.test_sensor_list module¶
-
test_map_channel19_to_dictionary
()¶
-
test_map_channel37_to_dictionary
()¶
-
test_amsre_theta_is_55
()¶
-
test_amsre_channel_recognized
()¶
-
test_map_channel06_to_dictionary
()¶
-
test_map_channel07_to_dictionary
()¶
-
test_amsr2_theta_is_55
()¶
-
test_cimr_channel01_to_dictionary
()¶
-
test_cimr_is_55
()¶
Module contents¶
This package includes modules to create the medium and sensor configuration required for the simulations. The recommended way to build these objects:
from smrt import make_snowpack, sensor_list
sp = make_snowpack([1000], density=[300], microstructure_model='sticky_hard_spheres', radius=[0.3e-3], stickiness=0.2)
radiometer = sensor_list.amsre()
Note that the function make_snowpack()
and the module sensor_list
is directly imported from smrt, which is convenient but they effectively lie
in the package smrt.inputs
. They could be imported using the full path as follows:
from smrt.inputs.make_medium import make_snowpack
from smrt.inputs import sensor_list
sp = make_snowpack([1000], density=[300], microstructure_model='sticky_hard_spheres', radius=[0.3e-3], stickiness=0.2)
radiometer = sensor_list.amsre()
Extension of the modules in the inputs package is welcome. This is as simple as adding new functions in the modules (e.g. in sensor_list
) or
adding a new modules (e.g. my_make_medium.py) in this package and use the full path import.
smrt.permittivity package¶
Submodules¶
smrt.permittivity.brine module¶
-
brine_conductivity
(temperature)¶ computes ionic conductivity of dissolved salts, Stogryn and Desargant, 1985
Parameters: temperature – thermometric temperature [K]
-
brine_relaxation_time
(temperature)¶ computes relaxation time of brine, Stogryn and Desargant, 1985
Parameters: temperature – thermometric temperature [K]
-
static_brine_permittivity
(temperature)¶ computes static dielectric constant of brine, Stogryn and Desargant, 1985
Parameters: temperature – thermometric temperature [K]
-
calculate_brine_salinity
(temperature)¶ Computes the salinity of brine (in ppt) for a given temperature (Cox and Weeks, 1975)
Parameters: temperature – snow temperature in K :return salinity_brine in ppt
-
permittivity_high_frequency_limit
(temperature)¶ computes permittivity.
Parameters: temperature – ice or snow temperature in K
-
brine_volume
(temperature, salinity, porosity=0, bulk_density=None)¶ computes brine volume fraction using coefficients from Cox and Weeks (1983): ‘Equations for determining the gas and brine volumes in sea-ice samples’, J. of Glac. if ice temperature is below -2 deg C or coefficients determined by Lepparanta and Manninen (1988): ‘The brine and gas content of sea ice with attention to low salinities and high temperatures’ for warmer temperatures.
Parameters: - temperature – ice temperature in K
- salinity – salinity of ice in kg/kg (see PSU constant in smrt module)
- porosity – fractional air volume in ice (0..1). Default is 0.
- bulk_density – density of bulk ice in kg m -3
-
calculate_freezing_temperature
(salinity)¶ calculates temperature at which saline water freezes using polynomial fits of the Gibbs function given in TEOS-10: The international thermodynamic equation of seawater - 2010 (’http://www.teos-10.org/pubs/TEOS-10_Manual.pdf). The error of this fit ranges between -5e-4 K and 6e-4 K when compared with the temperature calculated from the exact in-situ freezing temperature, which is found by a Newton-Raphson iteration of the equality of the chemical potentials of water in seawater and in ice.
Parameters: salinity – salinity of ice in kg/kg (see PSU constant in smrt module)
smrt.permittivity.generic_mixing_formula module¶
This module contains functions that are not tied to a particular electromagnetic model and are available to be imported by any electromagnetic model. It is the responsibility of the developer to ensure these functions, if used, are appropriate and consistent with the physics of the electromagnetic model.
-
depolarization_factors
(length_ratio=None)¶ Calculates depolarization factors for use in effective permittivity models. These are a measure of the anisotropy of the snow. Default is spherical isotropy.
Parameters: length_ratio – [Optional] ratio of microstructure length measurement in x/y direction to z-direction [unitless]. Returns: [x, y, z] depolarization factor array Usage example:
from smrt.permittivity.generic_mixing_formula import depolarization_factors depol_xyz = depolarization_factors(length_ratio=1.2) depol_xyz = depolarization_factors()
-
polder_van_santen
(frac_volume, e0=1, eps=3.185, depol_xyz=None, length_ratio=None, inclusion_shape=None, mixing_ratio=1)¶ Calculates effective permittivity of snow by solution of quadratic Polder Van Santen equation for spherical inclusion.
Parameters: - frac_volume – Fractional volume of inclusions
- e0 – Permittivity of background (default is 1)
- eps – Permittivity of scattering material (default is 3.185 to compare with MEMLS)
- depol_xyz – [Optional] Depolarization factors, spherical isotropy is default. It is not taken into account here.
- length_ratio – Length_ratio. Used to estimate depolarization factors when they are not given.
- inclusion_shape – Assumption for shape(s) of brine inclusions. Can be a string for single shape, or a list/tuple/dict of strings for mixture of shapes. So far, we have the following shapes: “spheres” and “random_needles” (i.e. randomly-oriented elongated ellipsoidal inclusions). If the argument is a dict, the keys are the shapes and the values are the mixing ratio. If it is a list, the mixing_ratio argument is required.
- mixing_ratio – The mixing ratio of the shapes. This is only relevant when inclusion_shape is a list/tuple. Mixing ratio must be a sequence with length len(inclusion_shape)-1. The mixing ratio of the last shapes is deduced as the sum of the ratios must equal to 1.
Returns: Effective permittivity
Usage example:
from smrt.permittivity.generic_mixing_formula import polder_van_santen effective_permittivity = polder_van_santen(frac_volume, e0, eps) # for a mixture of 30% spheres and 70% needles effective_permittivity = polder_van_santen(frac_volume, e0, eps, inclusion_shape={"spheres": 0.3, "random_needles": 0.7}) # or effective_permittivity = polder_van_santen(frac_volume, e0, eps, inclusion_shape=("spheres", "random_needles"), mixing_ratio=0.3)
Todo
Extend Polder Van Santen model to account for ellipsoidal inclusions
-
bruggeman
(frac_volume, e0=1, eps=3.185, depol_xyz=None, length_ratio=None, inclusion_shape=None, mixing_ratio=1)¶ Calculates effective permittivity of snow by solution of quadratic Polder Van Santen equation for spherical inclusion.
Parameters: - frac_volume – Fractional volume of inclusions
- e0 – Permittivity of background (default is 1)
- eps – Permittivity of scattering material (default is 3.185 to compare with MEMLS)
- depol_xyz – [Optional] Depolarization factors, spherical isotropy is default. It is not taken into account here.
- length_ratio – Length_ratio. Used to estimate depolarization factors when they are not given.
- inclusion_shape – Assumption for shape(s) of brine inclusions. Can be a string for single shape, or a list/tuple/dict of strings for mixture of shapes. So far, we have the following shapes: “spheres” and “random_needles” (i.e. randomly-oriented elongated ellipsoidal inclusions). If the argument is a dict, the keys are the shapes and the values are the mixing ratio. If it is a list, the mixing_ratio argument is required.
- mixing_ratio – The mixing ratio of the shapes. This is only relevant when inclusion_shape is a list/tuple. Mixing ratio must be a sequence with length len(inclusion_shape)-1. The mixing ratio of the last shapes is deduced as the sum of the ratios must equal to 1.
Returns: Effective permittivity
Usage example:
from smrt.permittivity.generic_mixing_formula import polder_van_santen effective_permittivity = polder_van_santen(frac_volume, e0, eps) # for a mixture of 30% spheres and 70% needles effective_permittivity = polder_van_santen(frac_volume, e0, eps, inclusion_shape={"spheres": 0.3, "random_needles": 0.7}) # or effective_permittivity = polder_van_santen(frac_volume, e0, eps, inclusion_shape=("spheres", "random_needles"), mixing_ratio=0.3)
Todo
Extend Polder Van Santen model to account for ellipsoidal inclusions
-
polder_van_santen_three_spherical_components
(f1, f2, eps0, eps1, eps2)¶ Calculates effective permittivity using Polder and van Santen with three components assuming spherical inclusions
Parameters: - f1 – fractional volume of component 1
- f2 – fractional volume of component 2
- eps0 – permittivity of material 0
- eps1 – permittivity of material 1
- eps2 – permittivity of material 2
-
polder_van_santen_three_components
(f1, f2, eps0, eps1, eps2, A1, A2)¶ Calculates effective permittivity using Polder and van Santen with three components
Parameters: - f1 – fractional volume of component 1
- f2 – fractional volume of component 2
- eps0 – permittivity of material 0
- eps1 – permittivity of material 1
- eps2 – permittivity of material 2
- A1 – depolarization factor for material 1
- A2 – depolarization factor for material 2
-
maxwell_garnett
(frac_volume, e0, eps, depol_xyz=None, inclusion_shape=None, length_ratio=None)¶ Calculates effective permittivity using Maxwell-Garnett equation.
Parameters: - frac_volume – Fractional volume of snow
- e0 – Permittivity of background (no default, must be provided)
- eps – Permittivity of scattering material (no default, must be provided)
- depol_xyz – [Optional] Depolarization factors, spherical isotropy is default. It is not taken into account here.
- length_ratio – Length_ratio. Used to estimate depolarization factors when they are not given.
- inclusion_shape – Assumption for shape(s) of brine inclusions. Can be a string for single shape, or a list/tuple/dict of strings for mixture of shapes. So far, we have the following shapes: “spheres” and “random_needles” (i.e. randomly-oriented elongated ellipsoidal inclusions). If the argument is a dict, the keys are the shapes and the values are the mixing ratio. If it is a list, the mixing_ratio argument is required.
Returns: random orientation effective permittivity
Usage example:
# If used by electromagnetic model module: from .commonfunc import maxwell_garnett effective_permittivity = maxwell_garnett(frac_volume=0.2, e0=1, eps=3.185, depol_xyz=[0.3, 0.3, 0.4]) # If accessed from elsewhere, use absolute import from smrt.emmodel.commonfunc import maxwell_garnett
-
maxwell_garnett_for_spheres
(frac_volume, e0, eps)¶ Calculates effective permittivity using Maxwell-Garnett equation assuming spherical inclusion. This function is essentially an optimized version of py:func:maxwell_garnett.
smrt.permittivity.ice module¶
-
ice_permittivity_maetzler06
(frequency, temperature)¶ Calculates the complex ice dielectric constant depending on the frequency and temperature
Based on Mätzler, C. (2006). Thermal Microwave Radiation: Applications for Remote Sensing p456-461 This is the default model used in smrt.inputs.make_medium.make_snow_layer().
Parameters: - frequency – frequency in Hz
- temperature – temperature in K
Returns: Complex permittivity of pure ice
Usage example:
from smrt.permittivity.ice import ice_permittivity_maetzler06 eps_ice = ice_permittivity_maetzler06(frequency=18e9, temperature=270)
Note
Ice permittivity is automatically calculated in smrt.inputs.make_medium.make_snow_layer() and is not set by the electromagnetic model module. An alternative to ice_permittivity_maetzler06 may be specified as an argument to the make_snow_layer function. The usage example is provided for external reference or testing purposes.
-
ice_permittivity_maetzler98
(frequency, temperature)¶ computes permittivity of ice (accounting for ionic impurities in ice?), equations from Hufford (1991) as given in Maetzler (1998): ‘Microwave properties of ice and snow’, in B. Schmitt et al. (eds.): ‘Solar system ices’, p. 241-257, Kluwer.
Parameters: - temperature – ice temperature in K
- frequency – Frequency in Hz
-
ice_permittivity_maetzler87
(frequency, temperature)¶ Calculates the complex ice dielectric constant depending on the frequency and temperature
Based on Mätzler, C. and Wegmüller (1987). Dielectric properties of fresh-water ice at microwave frequencies. J. Phys. D: Appl. Phys. 20 (1987) 1623-1630.
Parameters: - frequency – frequency in Hz
- temperature – temperature in K
Returns: Complex permittivity of pure ice
Usage example:
from smrt.permittivity.ice import ice_permittivity_maetzler87 eps_ice = ice_permittivity_maetzler87(frequency=18e9, temperature=270)
Note
This is only suitable for testing at -5 deg C and -15 deg C. If used at other temperatures a warning will be displayed.
-
ice_permittivity_tiuri84
(frequency, temperature)¶ Calculates the complex ice dielectric constant depending on the frequency and temperature
Based on Tiuri et al. (1984). The Complex Dielectric Constant of Snow at Microwave Frequencies. IEEE Journal of Oceanic Engineering, vol. 9, no. 5., pp. 377-382
Parameters: - frequency – frequency in Hz
- temperature – temperature in K
Returns: Complex permittivity of pure ice
Usage example:
from smrt.permittivity.ice import ice_permittivity_tiuri84 eps_ice = ice_permittivity_tiuri84(frequency=1.9e9, temperature=250)
smrt.permittivity.saline_ice module¶
-
impure_ice_permittivity_maetzler06
(frequency, temperature, salinity)¶ - Computes permittivity of impure ice from Maetzler 2006 - Thermal Microwave Radiation: Applications for Remote Sensing.
Model developed for salinity around 0.013 PSU. The extrapolation is based on linear assumption to salinity, so it is not recommended for much higher salinity.
param temperature: ice temperature in K param salinity: salinity of ice in kg/kg (see PSU constant in smrt module)
Usage example:
from smrt.permittivity.saline_ice import impure_ice_permittivity_maetzler06 eps_ice = impure_ice_permittivity_maetzler06(frequency=18e9, temperature=270, salinity=0.013)
-
saline_ice_permittivity_pvs_mixing
(frequency, temperature, brine_volume_fraction, brine_inclusion_shape='spheres', brine_mixing_ratio=1, ice_permittivity_model=None, brine_permittivity_model=None)¶ Computes effective permittivity of saline ice using the Polder Van Santen mixing formulaes.
Parameters: - frequency – frequency in Hz
- temperature – ice temperature in K
- brine_volume_fraction – brine / liquid water fraction in sea ice
- brine_inclusion_shape – Assumption for shape(s) of brine inclusions. Can be a string for single shape, or a list/tuple/dict of strings for mixture of shapes. So far, we have the following shapes: “spheres” and “random_needles” (i.e. randomly-oriented elongated ellipsoidal inclusions). If the argument is a dict, the keys are the shapes and the values are the mixing ratio. If it is a list, the mixing_ratio argument is required.
- brine_mixing_ratio – The mixing ratio of the shapes. This is only relevant when inclusion_shape is a list/tuple. Mixing ratio must be a sequence with length len(inclusion_shape)-1. The mixing ratio of the last shapes is deduced as the sum of the ratios must equal to 1.
- ice_permittivity_model – pure ice permittivity formulation (default is ice_permittivity_matzler87)
- brine_permittivity_model – brine permittivity formulation (default is brine_permittivity_stogryn85)
smrt.permittivity.saline_snow module¶
-
saline_snow_permittivity_geldsetzer09
(frequency, density, temperature, salinity)¶ Computes permittivity of saline snow using the frequency dispersion model published by Geldsetzer et al., 2009 (CRST). DOI: 10.1016/j.coldregions.2009.03.009. In-situ measurements collected had salinity concentration between 0.1e-3 and 12e3 kg/kg, temperatures ranging between 257 and 273 K, and a mean snow density of 352 kg/m3.
Validity between 10 MHz and 40 GHz.
Source: Matlab code, Ludovic Brucker
Parameters: - frequency – frequency in Hz
- density – snow density in kg m-3
- temperature – ice temperature in K
- salinity – salinity of ice in kg/kg (see PSU constant in smrt module)
-
saline_snow_permittivity_scharien_with_stogryn71
(frequency, density, temperature, salinity)¶ Computes permittivity of saline snow. See saline_snow_permittivity_scharien documentation
-
saline_snow_permittivity_scharien_with_stogryn95
(frequency, density, temperature, salinity)¶ Computes permittivity of saline snow. See saline_snow_permittivity_scharien documentation
-
saline_snow_permittivity_scharien
(density, temperature, salinity, brine_permittivity)¶ Computes permittivity of saline snow using the Denoth / Matzler Mixture Model - Dielectric Contsant of Saline Snow.
Assumptions: (1) Brine inclusion geometry as oblate spheroids
Depolarization factor, A0 = 0.053 (Denoth, 1980)- Brine inclusions are isotropically oriented Coupling factor, X = 2/3 (Drinkwater and Crocker, 1988)
Validity ranges:
- Temperature, Ts, down to - 22.9 degrees Celcius;
(2) Brine salinity, Sb, up to 157ppt; i.e.up to a Normality of 3 for NaCl Not valid for wet snow
Source: Matlab code, Randall Scharien
Parameters: - density – snow density in kg m-3
- temperature – snow temperature in K
- salinity – snow salinity in kg/kg (see PSU constant in smrt module)
- brine_permittivity – brine_permittivity
smrt.permittivity.saline_water module¶
-
seawater_permittivity_klein76
(frequency, temperature, salinity)¶ Calculates permittivity (dielectric constant) of water using an empirical relationship described by Klein and Swift (1976).
Parameters: - frequency – frequency in Hz
- temperature – water temperature in K
- salinity – water salinity in kg/kg (see PSU constant in smrt module)
Returns complex water permittivity for a frequency f.
-
seawater_permittivity_stogryn71
(frequency, temperature)¶ Computes dielectric constant of brine, complex_b (Stogryn, 1971 approach)
Input parameters: from polynomial fit in Stogryn and Desargent, 1985
Source: Matlab code, Ludovic Brucker
Parameters: - frequency – frequency in Hz
- temperature – water temperature in K
Returns complex water permittivity for a frequency f.
-
brine_permittivity_stogryn85
(frequency, temperature)¶ computes permittivity and loss of brine using equations given in Stogryn and Desargant (1985): ‘The Dielectric Properties of Brine in Sea Ice at Microwave Frequencies’, IEEE.
Parameters: - frequency – em frequency [Hz]
- temperature – ice temperature in K
-
seawater_permittivity_stogryn95
(frequency, temperature, salinity)¶ Computes seawater dielectric constant using Stogryn 1995.
source: Stogryn 1995 + http://rime.aos.wisc.edu/MW/models/src/eps_sea_stogryn.f90; Matlab code, Ludovic Brucker
Parameters: - frequency – frequency in Hz
- temperature – water temperature in K
- salinity – water salinity in kg/kg (see PSU constant in smrt module)
Returns complex water permittivity for a frequency f.
smrt.permittivity.snow_mixing_formula module¶
Mixing formulae relevant to snow. This module contains equations to compute the effective permittivity of snow.
Note that by default most emmodels (IBA, DMRT, SFT Rayleigh) uses the generic mixing formula Polder van Staten that mixes the permittivities of the background (e.g.) and the scatterer materials (e.g. ice) to compute the effective permittivity of snow in a proportion determined by frac_volume. See py:meth:~smrt.emmolde.derived_IBA.
Many semi-empirical mixing formulae have been developed for specific mixture of materials (e.g. snow). They can be used to replace the Polder van Staten in the EM models. They should not be used to set the material permittivities as input of py:meth:~smrt.smrt_inputs.make_snowpack and similar functions (because the emmodel would re-mix the already mixed materials with the background material).
-
wetsnow_permittivity_tinga73
(frequency, temperature, density, liquid_water, ice_permittivity_model=None, water_permittivity_model=None)¶ - effective permittivity proposed by Tinga et al. 1973 for three-component mixing. The component 1 is the background (“a” here),
the compoment 2 (“w” here) is a spherical shell surrounding the component 3 (“i” here).
It was used by Tiuri as well as T. Mote to compute wet snolw permittivity.
Tinga, W.R., Voss, W.A.G. and Blossey, D. F.: General approach to multiphase dielectric mixture theory. Journal of Applied Physics, Vol.44(1973) No.9,pp.3897-3902. doi: /10.1063/1.1662868
Tiuri, M. and Schultz, H., Theoretical and experimental studies of microwave radiation from a natural snow field. In Rango, A. , ed. Microwave remote sensing of snowpack properties. Proceedings of a workshop … Fort Collins, Colorado, May 20-22, 1980. Washington, DC, National Aeronautics and Space Center, 225-234. (Conference Publication 2153.)
-
compute_frac_volumes
(density, liquid_water)¶ compute the fractional volume of ice+water, the fractional volume of ice, and the fractional volume of water from the (wet) snow density and the liquid_water which is the volume fraction of liquid with respect to ice + liquid (but no air).
Parameters: - density – density of the snow, including the ice and water phases.
- liquid_water – (fractional volume of water with respect to ice+water volume).
Returns: frac_volume, fi, fw
-
wetsnow_permittivity_colbeck80_caseI
(frequency, temperature, density, liquid_water, ice_permittivity_model=None, water_permittivity_model=None)¶ effective permittivity proposed by Colbeck, 1980 for the pendular regime.
Colbeck, S. C. (1980). Liquid distribution and the dielectric constant of wet snow. Goddard Space Flight Center Microwave Remote Sensing of Snowpack Properties, 21–40.
-
wetsnow_permittivity_colbeck80_caseII
(frequency, temperature, density, liquid_water, ice_permittivity_model=None, water_permittivity_model=None)¶ effective permittivity proposed by Colbeck, 1980 for the funicular regime and low dry snow density.
Colbeck, S. C. (1980). Liquid distribution and the dielectric constant of wet snow. Goddard Space Flight Center Microwave Remote Sensing of Snowpack Properties, 21–40.
-
wetsnow_permittivity_colbeck80_caseIII
(frequency, temperature, density, liquid_water, ice_permittivity_model=None, water_permittivity_model=None)¶ effective permittivity proposed by Colbeck, 1980 for the low porosity.
Colbeck, S. C. (1980). Liquid distribution and the dielectric constant of wet snow. Goddard Space Flight Center Microwave Remote Sensing of Snowpack Properties, 21–40.
-
wetsnow_permittivity_hallikainen86
(frequency, density, liquid_water)¶ effective permittivity of a snow mixture calculated with the Modified Debye model by Hallikainen 1986
The implemented equation are 10, 11 and 13a-c.
- The validity of the model is: frequency between 3 and 37GHz;
- mv between 1% and 12%; dry_snow_density between 0.09 and 0.38g/cm3.
The implementation of this function follows the equations formulation of the original paper Hallikainen, M., F. Ulaby, and M. Abdelrazik, “Dielectric properties of snow in 3 to 37 GHz range,” IEEE Trans. on Antennasand Propagation,Vol. 34, No. 11, 1329–1340, 1986. DOI: 10.1109/TAP.1986.1143757 Anyway this formulation does not allow the reproduction of the results as reported in the paper. A new formulation of eq. 12a have been presented in the book Microwave Radar and Radiometric Remote Sensing by Ulaby et al. 2014 from which the SMRT function wetsnow_permittivity_hallikainen86_ulaby14 have been implemented. The users are pointed to that definition.
-
wetsnow_permittivity_hallikainen86_ulaby14
(frequency, density, liquid_water)¶ effective permittivity of a snow mixture calculated with the Modified Debye model by Hallikainen 1986 and revised in Microwave Radar and Radiometric Remote Sensing by Ulaby et al. 2014 Equations implemented are ch 4 pp 143-15 4.60a - 4.61h.
- The validity of the model is: frequency between 3 and 37GHz;
- mv between 1% and 12%; dry_snow_density between 0.09 and 0.38g/cm3.
Same formulation can be reproduced by the book code https://mrs.eecs.umich.edu/codes/Module4_6/Module4_6.html
-
wetsnow_permittivity_wiesmann99
(frequency, temperature, density, liquid_water, ice_permittivity_model=None)¶ effective permittivity of a snow mixture as presented in MEMLS by Wiesmann and Matzler, 1999. Note that the version implemented in MEMLS v3 is different.
-
wetsnow_permittivity_memls
(frequency, temperature, density, liquid_water, ice_permittivity_model=None, water_permittivity_model=None)¶ effective permittivity of a snow mixture as calculated in MEMLS using Maxwell-Garnett Mixing rule of water in dry snow for prolate spheroidal water with experimentally determined. Dry snow permittivity is here determined with Polder van Santen.
-
wetsnow_permittivity_three_component_polder_van_santen
(frequency, temperature, density, liquid_water, ice_permittivity_model=None, water_permittivity_model=None)¶ effective permittivity of a snow mixture using the three components polder_van_santen, assuming spherical inclusions
-
depolarization_factors_maetzler96
(density)¶ - The empirical depolarization factors of snow estimated by Mäzler 1996. It is supposed to provide more accurate
- permittivity=f(density) than using constant depolarization factors in Polder van Santen (e.g. spheres)
Biblio: C. Mäzler, Microwave Permittivity of dry snow, IEEE TRANSACTIONS ON GEOSCIENCE AND REMOTE SENSING, VOL. 34, NO. 2, MARCH 1996
-
drysnow_permittivity_maetzler96
(density, e0=1, eps=3.185)¶
-
default_ice_water_permittivity
(ice_permittivity_model, water_permittivity_model)¶
smrt.permittivity.test_generic_mixing_formula module¶
-
test_isotropic_default_depolarization_factors
()¶
-
test_plates_depol
()¶
-
test_hoar_columns_depol
()¶
-
test_depol_approach_to_isotropy_above
()¶
-
test_depol_approach_to_isotropy_below
()¶
-
test_pvsl_spheres
()¶
-
test_pvsl_needles
()¶
-
test_pvsl_mix_spheres_needles
()¶
smrt.permittivity.test_ice module¶
-
test_ice_permittivity_output_matzler_temp_270
()¶
-
test_ice_permittivity_output_matzler_temp_250
()¶
-
test_imaginary_ice_permittivity_output_matzler_temp_270_freq_20GHz
()¶
-
test_imaginary_ice_permittivity_output_matzler_temp_250_freq_20GHz
()¶
-
test_imaginary_ice_permittivity_output_matzler_temp_270_freq_30GHz
()¶
-
test_imaginary_ice_permittivity_output_matzler_temp_250_freq_30GHz
()¶
-
test_imaginary_ice_permittivity_output_matzler_temp_270_freq_40GHz
()¶
-
test_imaginary_ice_permittivity_output_matzler_temp_250_freq_40GHz
()¶
-
test_real_ice_permittivity_output_maetzler87_temp_268
()¶
-
test_imag_ice_permittivity_output_maetzler87_temp_minus5
()¶
-
test_imag_ice_permittivity_output_maetzler87_temp_minus15
()¶
-
test_ice_permittivity_output_tuiri84_temp_minus10_freq_10GHz
()¶
-
test_ice_permittivity_output_tuiri84_temp_minus10_freq_40GHz
()¶
-
test_ice_permittivity_output_tuiri84_temp_250K_freq_10GHz
()¶
-
test_ice_permittivity_output_tuiri84_temp_250K_freq_40GHz
()¶
-
test_real_ice_permittivity_output_HUT
()¶
-
test_imaginary_ice_permittivity_output_HUT
()¶
-
test_real_ice_permittivity_output_DMRTML
()¶
-
test_imaginary_ice_permittivity_output_DMRTML
()¶
-
test_real_ice_permittivity_output_matzler_temp_270_MEMLS
()¶
-
test_imaginary_ice_permittivity_output_matzler_temp_270_freq_10GHz
()¶
-
test_salty_imaginary_ice_permittivity_output_matzler_temp_270_freq_10GHz
()¶
smrt.permittivity.test_saline_ice module¶
-
test_impure_permittivity_same_as_pure_for_zero_salinty
()¶
-
test_impure_ice_freezing_point_0p013psu_10GHz
()¶
-
test_saline_permittivity_same_as_pure_for_zero_salinity
()¶
-
test_saline_permittivity_with_mixtures
()¶
smrt.permittivity.water module¶
-
water_permittivity_maetzler87
(frequency, temperature)¶ Calculates the complex water dielectric constant depending on the frequency and temperature Based on Mätzler, C., & Wegmuller, U. (1987). Dielectric properties of freshwater ice at microwave frequencies. Journal of Physics D: Applied Physics, 20(12), 1623-1630.
Parameters: - frequency – frequency in Hz
- temperature – temperature in K
Raises: Exception – if liquid water > 0 or salinity > 0 (model unsuitable)
Returns: Complex permittivity of pure ice
-
water_permittivity
(frequency, temperature)¶ Calculates the complex water dielectric constant depending on the frequency and temperature Based on Mätzler, C., & Wegmuller, U. (1987). Dielectric properties of freshwater ice at microwave frequencies. Journal of Physics D: Applied Physics, 20(12), 1623-1630.
Parameters: - frequency – frequency in Hz
- temperature – temperature in K
Raises: Exception – if liquid water > 0 or salinity > 0 (model unsuitable)
Returns: Complex permittivity of pure ice
-
water_permittivity_tiuri80
(frequency, temperature)¶ Calculates the complex water dielectric constant reported by:
Tiuri, M. and Schultz, H., Theoretical and experimental studies of microwave radiation from a natural snow field. In Rango, A. , ed.Microwave remote sensing of snowpack properties. Proceedings of a workshop … Fort Collins, Colorado, May 20-22, 1980. Washington, DC, National Aeronautics and Space Center, 225-234. (Conference Publication 2153.)
smrt.permittivity.wetice module¶
-
wetice_permittivity_bohren83
(frequency, temperature, liquid_water)¶ calculate the dielectric constant of wet particules of ice using Maxwell Garnet equation using water as the background and ice as the inclusions. As reported by Bohren and Huffman 1983 according to Ya Qi Jin, eq 8-69, 1996 p282
see also: K L CHOPRA and G B REDDY, Praman.a- Optically selective coatings, J. Phys., Vol. 27, Nos 1 & 2, July & August 1986, pp. 193-217.
Parameters: - frequency – frequency in Hz
- temperature – temperature in K
:param liquid_water (fractional volume of water with respect to ice+water volume). :returns: Complex permittivity of pure ice
-
symmetric_wetice_permittivity
(frequency, temperature, liquid_water)¶ calculate the dielectric constant of wet particules of ice using Polder van Santen Maxwell equation assuming both ice and water are fully mixed. This applies to intermediate content of wetness. Typically liquid_water=0.5.
Parameters: - frequency – frequency in Hz
- temperature – temperature in K
:param liquid_water (fractional volume of water with respect to ice+water volume). :returns: Complex permittivity of pure ice
smrt.permittivity.wetsnow module¶
-
wetsnow_permittivity
(frequency, temperature, liquid_water)¶ calculate the dielectric constant of wet particule of ice using Bohren and Huffman 1983 according to Ya Qi Jin, eq 8-69, 1996 p282
Parameters: - frequency – frequency in Hz
- temperature – temperature in K
:param liquid_water (fractional volume of water with respect to ice+water volume) :returns: Complex permittivity of pure ice
Module contents¶
This module contains permittivity formulations for different materials. They are organised in different files for easy access but this is not strictly required.
E.g. ice.py contains formulation for pure ice permittivity.
For developers
To add a new permittivity function proceed as follows:
1. To add a new permittivity formulation add a function either in an existing file or in a new file (recommended for testing). E.g. for salty ice permittivity formulations should be in saltyice.py and so on.
2. Any function defining a permittivity model must declare the mapping between the layer properties and the arguments of the function (see ice.py for examples). It means that the arguments of the function must be listed (in order) in the @required_layer_properties decorator. In most cases, the name of the arguments should be the same as a properties, but this is not strictly necessary, only the order matters. E.g.:
@required_layer_properties("temperature", "salinity")
def permittivity_something(frequency, t, s):
maps the layer property “temperature” to the argument “t” of the function (and “salinity” to s) However, we recommend to change t into temperature for sake of clarity.
For curious ones, this declaration is required because the function can be called either with its arguments (normal case) or with only two arguments like this (frequency, layer). In this latter case, the arguments required by the original function are automatically extracted from the layer attributes (=properties) based on the declaration in @required_layer_properties. This complication is necessary because there is no way in Python to inspect the name of the arguments of a function, so the need for explicit declaration.
3. to use the new function, import the module (e.g. from smrt.permittivity.ice import permittivity_something) and
pass this function to smrt.core.snowpack.make_snowpack()
or smrt.core.layer:make_snow_layer()
.
smrt.microstructure_model package¶
Submodules¶
smrt.microstructure_model.autocorrelation module¶
This module contains the base classes for the microstructure classes. It is not used directly.
-
class
AutocorrelationBase
(params)¶ Bases:
object
Low level base class for the Autocorrelation base class to handle optional and required arguments. It should not be used directly.
-
classmethod
compute_all_arguments
()¶
-
classmethod
valid_arguments
()¶
-
classmethod
-
class
Autocorrelation
(params)¶ Bases:
smrt.microstructure_model.autocorrelation.AutocorrelationBase
Base class for autocorrelation function classes. It should not be used directly but sub-classed. It provides generic handling of the numerical fft and invfft when required by the user or when necessary due to the lack of implementation of the real or ft autocorrelation functions. See the source of
Exponential
to see how to use this class.-
args
= []¶
-
optional_args
= {'ft_numerical': False, 'real_numerical': False}¶
-
ft_autocorrelation_function_fft
(k)¶ compute the fourier transform of the autocorrelation function via fft Args: k: array of wave vector magnitude values, ordered, and non-negative
-
autocorrelation_function_invfft
(r)¶ Compute the autocorrelation function from an analytically known FT via fft Args: r: array of lag vector magnitude values, ordered, non-negative
-
inverted_medium
()¶ return the same autocorrelation for the inverted medium. In general, it is only necessary to invert the fractional volume if the autocorrelation function is numerically symmetric as it should be. This needs to be reimplemented in the sub classes if this is not sufficient.
-
smrt.microstructure_model.exponential module¶
Exponential autocorrelation function model of the microstructure. This microstructure model is used by MEMLS when IBA is selected.
parameters: frac_volume, corr_length
-
class
Exponential
(params)¶ Bases:
smrt.microstructure_model.autocorrelation.Autocorrelation
-
args
= ['frac_volume', 'corr_length']¶
-
optional_args
= {}¶
-
corr_func_at_origin
¶
-
inv_slope_at_origin
¶
-
basic_check
()¶ check consistency between the parameters
-
compute_ssa
()¶ compute the ssa for the exponential model according to Debye 1957. See also Maetzler 2002 Eq. 11
-
autocorrelation_function
(r)¶ compute the real space autocorrelation function
-
ft_autocorrelation_function
(k)¶ compute the fourier transform of the autocorrelation function analytically
-
smrt.microstructure_model.gaussian_random_field module¶
Gaussian Random field model of the microstructure.
parameters: frac_volume, corr_length, repeat_distance
-
class
GaussianRandomField
(params)¶ Bases:
smrt.microstructure_model.autocorrelation.Autocorrelation
-
args
= ['frac_volume', 'corr_length', 'repeat_distance']¶
-
optional_args
= {}¶
-
corr_func_at_origin
¶
-
inv_slope_at_origin
¶
-
basic_check
()¶ check consistency between the parameters
-
compute_ssa
()¶ Compute the ssa for a sphere
-
autocorrelation_function
(r)¶ compute the real space autocorrelation function for the Gaussian random field model
-
smrt.microstructure_model.homogeneous module¶
Homogeneous microstructure. This microstructure model is to be used with non-scattering emmodel.
parameters: none
-
class
Homogeneous
(params)¶ Bases:
smrt.microstructure_model.autocorrelation.Autocorrelation
-
args
= ['frac_volume']¶
-
optional_args
= {}¶
-
corr_func_at_origin
¶
-
inv_slope_at_origin
¶
-
basic_check
()¶ check consistency between the parameters
-
compute_ssa
()¶ compute the ssa of an homogeneous medium
-
autocorrelation_function
(r)¶ compute the real space autocorrelation function
-
ft_autocorrelation_function
(k)¶ compute the fourier transform of the autocorrelation function analytically
-
smrt.microstructure_model.independent_sphere module¶
Independent sphere model of the microstructure.
parameters: frac_volume, radius
-
class
IndependentSphere
(params)¶ Bases:
smrt.microstructure_model.autocorrelation.Autocorrelation
-
args
= ['frac_volume', 'radius']¶
-
optional_args
= {}¶
-
corr_func_at_origin
¶
-
inv_slope_at_origin
¶
-
basic_check
()¶ check consistency between the parameters
-
compute_ssa
()¶ Compute the ssa for a sphere
-
autocorrelation_function
(r)¶ compute the real space autocorrelation function for an independent sphere
-
ft_autocorrelation_function
(k)¶ Compute the 3D Fourier transform of the isotropic correlation function for an independent sphere for given magnitude k of the 3D wave vector (float).
-
smrt.microstructure_model.sampled_autocorrelation module¶
Sampled autocorrelation function model. To use when no analytical form of the autocorrelation function but the values of the autocorrelation function (acf) is known at a series of lag.
parameters: frac_volume, lag, acf
acf contains the values at different lag. These parameters must be lists or arrays.
-
class
SampledAutocorrelation
(params)¶ Bases:
smrt.microstructure_model.autocorrelation.Autocorrelation
-
args
= ['frac_volume', 'lag', 'acf']¶
-
optional_args
= {}¶
-
corr_func_at_origin
¶
-
basic_check
()¶ check consistency between the parameters
-
compute_ssa
()¶ compute the ssa according to Debye 1957. See also Maetzler 2002 Eq. 11
-
autocorrelation_function
(r)¶ compute the real space autocorrelation function by interpolation of requested values from known values
-
smrt.microstructure_model.sticky_hard_spheres module¶
Monodisperse sticky hard sphere model of the microstructure.
parameters: frac_volume, radius, stickiness.
The stickiness is optional but it is recommended to use value around 0.2 as a first guess.
Be aware that low values of stickiness are invalid, the limit depends on the fractional volume
(see for instance Loewe and Picard, 2015). See the tau_min()
method.
Currently the implementation is specific to ice / snow. It can not be used for other materials.
-
class
StickyHardSpheres
(params)¶ Bases:
smrt.microstructure_model.autocorrelation.Autocorrelation
-
args
= ['frac_volume', 'radius']¶
-
optional_args
= {'stickiness': 1000}¶
-
corr_func_at_origin
¶
-
inv_slope_at_origin
¶
-
basic_check
()¶ check consistency between the parameters
-
compute_ssa
()¶ Compute the ssa of a sphere assembly
-
ft_autocorrelation_function
(k)¶ Compute the 3D Fourier transform of the isotropic correlation function for sticky hard spheres in Percus–Yevick approximation for given magnitude k of the 3D wave vector (float).
-
compute_t
()¶ compute the t parameter used in the stickiness
-
tau_min
(frac_volume)¶ compute the minimum possible stickiness value for given ice volume fraction
-
smrt.microstructure_model.test_autocorrelation module¶
smrt.microstructure_model.test_sticky_hard_spheres module¶
-
test_constructor
()¶
-
test_autocorrelation
()¶
smrt.microstructure_model.teubner_strey module¶
Teubner Strey model model of the microstructure.
parameters: frac_volume, corr_length, repeat_distance
-
class
TeubnerStrey
(params)¶ Bases:
smrt.microstructure_model.autocorrelation.Autocorrelation
-
args
= ['frac_volume', 'corr_length', 'repeat_distance']¶
-
optional_args
= {}¶
-
corr_func_at_origin
¶
-
basic_check
()¶ check consistency between the parameters
-
compute_ssa
()¶ Compute the ssa for a sphere
-
autocorrelation_function
(r)¶ compute the real space autocorrelation function for the Teubner Strey model
-
ft_autocorrelation_function
(k)¶ Compute the 3D Fourier transform of the isotropic correlation function for Teubner Strey for given magnitude k of the 3D wave vector (float).
-
Module contents¶
Microstructure models are different representations of the snow microstructure. Because these representations are different, the
parameters to describe actual snow micro-structure depends on the model. For instance, the Sticky Hard Spheres medium is implemented
in sticky_hard_spheres
and its parameters are: the radius (required) and
the stickiness (optional, default value is non-sticky, even though we do recommend to use a stickiness of ~0.1-0.3 in practice).
Because IBA is one of the important electromagnetic theories provided by SMRT, the first/main role of microstructure models is to provide
the Fourier transform of the autocorrelation functions. Hence most microstructure models are named after the autocorrelation function.
For instance, the exponential
autocorrelation function is that used in MEMLS. Its only parameter is the
corr_length.
To use microstructure models, it is only required to read the documentation of each model to determine the required and optional parameters. Selecting the microstructure model is usually done with make_snowpack which only requires the name of the module (the filename with .py). The import of the module is automatic. For instance:
from smrt import make_snowpack
sp = make_snowpack([1, 1000], "exponential", density=[200, 300], corr_length=[0.2e-3, 0.5e-3])
This snippet creates a snowpack with the exponential autocorrelation function for all (2) layers. Import of the exponential
is automatic and creation of instance of the class Exponential
is done by the model
smrt.core.model.Model.run()
method.
smrt.interface package¶
Submodules¶
smrt.interface.coherent_flat module¶
Implement the coherent flat pseudo-interface, as in MEMLS. This interface is obtained by collapsing one layer and two interfaces into a single interface. Scattering in the layer is neglected.
-
process_coherent_layers
(snowpack, emmodel_list, sensor)¶
-
class
CoherentFlat
(interfaces, layer, permittivity)¶ Bases:
object
A flat surface. The reflection is in the specular direction and the coefficient is calculated with the Fresnel coefficients
-
args
= []¶
-
optional_args
= {}¶
-
specular_reflection_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the reflection coefficients for an array of incidence angles (given by their cosine)
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium.
- mu1 – array of cosine of incident angles.
- npol – number of polarization.
Returns: the reflection matrix
-
diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶
-
coherent_transmission_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the transmission coefficients for the azimuthal mode m
- and for an array of incidence angles (given by their cosine) in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium.
- mu1 – array of cosine of incident angles.
- npol – number of polarization.
Returns: the transmission matrix
-
diffuse_transmission_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶
-
smrt.interface.flat module¶
Implement the flat interface boundary condition between layers charcterized by their effective permittivities. The reflection and transmission are computed using the Fresnel coefficient.
-
class
Flat
(**kwargs)¶ Bases:
smrt.core.interface.Interface
A flat surface. The reflection is in the specular direction and the coefficient is calculated with the Fresnel coefficients
-
args
= []¶
-
optional_args
= {}¶
-
specular_reflection_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the reflection coefficients for an array of incidence angles (given by their cosine)
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium.
- mu1 – array of cosine of incident angles.
- npol – number of polarization.
Returns: the reflection matrix
-
diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶
-
coherent_transmission_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the transmission coefficients for an array of incidence angles (given by their cosine)
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium.
- mu1 – array of cosine of incident angles.
- npol – number of polarization.
Returns: the transmission matrix
-
diffuse_transmission_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶
-
smrt.interface.geometrical_optics module¶
Implement the interface boundary condition under the Geometrical Approximation between layers charcterized by their effective permittivities. This approximation is suitable for surface with roughness much larger than the roughness scales, typically k*s >> 1 and k*l >> 1, where s the rms heigth and l the correlation length. The precise validity range must be investigated by the user, this code does not raise any warning. An important charcateristic of this approximation is that the scattering do not directly depend on frequency, the only (probably weak) dependence is through the permittivities of the media.
The model is parameterized by the mean_square_slope which can be calculated as mean_square_slope = 2*s**2/l**2 for surface with a Gaussian autocorrelation function. Other equations may exist for other autocorrelation function.
This implementation is largely based on Tsang and Kong, Scattering of Electromagnetic Waves: Advanced Topics, 2001 (Tsang_tomeIII in the following)
-
class
GeometricalOptics
(**kwargs)¶ Bases:
smrt.core.interface.Interface
A very rough surface.
-
args
= ['mean_square_slope']¶
-
optional_args
= {'shadow_correction': True}¶
-
clip_mu
(mu)¶
-
specular_reflection_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the reflection coefficients for an array of incidence angles (given by their cosine)
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the reflection matrix
-
diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶ - compute the reflection coefficients for an array of incident, scattered and azimuth angles
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the reflection matrix
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, m_max, npol)¶
-
ft_even_diffuse_transmission_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, m_max, npol)¶
-
coherent_transmission_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the transmission coefficients for the azimuthal mode m
- and for an array of incidence angles (given by their cosine) in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the transmission matrix
-
diffuse_transmission_matrix
(frequency, eps_1, eps_2, mu_t, mu_i, dphi, npol)¶ - compute the transmission coefficients for an array of incident, scattered and azimuth angles
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu_i – array of cosine of incident angles
- mu_t – array of cosine of transmitted wave angles
- npol – number of polarization
Returns: the transmission matrix
-
reflection_integrand_for_energy_conservation_test
(frequency, eps_1, eps_2, mu_s, mu_i, dphi)¶ function relevant to compute energy conservation. See p87 in Tsang_tomeIII.
-
transmission_integrand_for_energy_conservation_test
(frequency, eps_1, eps_2, mu_t, mu_i, dphi)¶ function relevant to compute energy conservation. See p87 in Tsang_tomeIII.
-
reflection_coefficients
(frequency, eps_1, eps_2, mu_i)¶
-
transmission_coefficients
(frequency, eps_1, eps_2, mu_i)¶
-
-
shadow_function
(mean_square_slope, cotan)¶
smrt.interface.geometrical_optics_backscatter module¶
Implement the interface boundary condition under the Geometrical Approximation between layers charcterized by their effective permittivities. This code is
for backscatter only, that is, to use as a substrate and at low frequency when the backscatter is the main mecahnism, and conversely when mulitple scattering
and double bounce between snow and substrate are negligible. In any other case, it is recommended to use GeometricalOptics
.
The transmitted energy is also computed in an approximate way suitable for 1st order scattering. We use energy conservation to compute the total transmitted energy and consider that all this energy is transmitted in the refraction (specular) direction.
-
class
GeometricalOpticsBackscatter
(**kwargs)¶ Bases:
smrt.core.interface.Interface
A very rough surface.
-
args
= ['mean_square_slope']¶
-
optional_args
= {'shadow_correction': True}¶
-
specular_reflection_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the reflection coefficients for an array of incidence angles (given by their cosine)
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the reflection matrix
-
diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶ - compute the reflection coefficients for an array of incident, scattered and azimuth angles
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the reflection matrix
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, m_max, npol)¶
-
coherent_transmission_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the transmission coefficients for an array of incidence angles (given by their cosine)
- in medium 1. Medium 2 is where the beam is transmitted. While Geometrical Optics, we here consider that power not reflected is scattered in the specular transmitted direction. This is an approximation which is reasonable in the context of a “1st order” geometrical optics.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the transmission matrix
-
smrt.interface.iem_fung92 module¶
Implement the interface boundary condition under IEM formulation provided by Fung et al. 1992. in IEEE TGRS. Use of this code requires special attention because of two issues:
1) it only computes the backscatter diffuse reflection as described in Fung et al. 1992, the specular reflection and the coherent transmission. It does not compute the full bi-static diffuse reflection and transmission. As a consequence it is only suitable when single scattering is dominant, usually at low frequency when the medium is weakly scattering. This happends when the main mechanism is the backscatter from the interface attenuated by the medium. Another case is when the rough surface is relatively smooth, the specular reflection is relatively strong and the energy can be scattered back by the medium (double bounce). For other situations, this code is not recommended.
2) Additionaly, IEM is known to work for a limited range of roughness. Usually it is considered valid for ks < 3 and ks*kw < sqrt(eps) where k is the wavenumber, s the rms height and l the correlation length. The code print a warning when out of this range. There is also limitation for smooth surfaces but no warning is printed.
Usage example:
- ::
# rms height and corr_length values work at 10 GHz substrate = make_soil(“iem_fung92”, “dobson85”, temperature=260,
roughness_rms=1e-3, corr_length=5e-2, autocorrelation_function=”exponential”, moisture=moisture, clay=clay, sand=sand, drymatter=drymatter)
-
class
IEM_Fung92
(**kwargs)¶ Bases:
smrt.core.interface.Interface
A moderate rough surface model with backscatter, specular reflection and transmission only. Use with care!
-
args
= ['roughness_rms', 'corr_length']¶
-
optional_args
= {'autocorrelation_function': 'exponential', 'series_truncation': 10, 'warning_handling': 'print'}¶
-
specular_reflection_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the reflection coefficients for an array of incidence angles (given by their cosine)
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the reflection matrix
-
check_validity
(ks, kl, eps_r)¶
-
fresnel_coefficients
(eps_1, eps_2, mu_i, ks, kl)¶ calculate the fresnel coefficients at the angle mu_i whatever is ks and kl according to the original formulation of Fung 1992
-
diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol, debug=False)¶ - compute the reflection coefficients for an array of incident, scattered and azimuth angles
- in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the reflection matrix
-
W_n
(n, k)¶
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, m_max, npol)¶
-
coherent_transmission_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the transmission coefficients for the azimuthal mode m
- and for an array of incidence angles (given by their cosine) in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the transmission matrix
-
smrt.interface.iem_fung92_brogioni10 module¶
Implement the interface boundary condition under IEM formulation provided by Fung et al. 1992. in IEEE TGRS with an extended domain of validity (for large roughness or correlation length) by switching the Fresnel coefficients according to Brogioni et al. 2010, IJRS (doi: 10.1080/01431160903232808). A better but more complex approach is given by Wu et al. 2003 (to be implemented).
Use of this code requires special attention.
-
class
IEM_Fung92_Briogoni10
(**kwargs)¶ Bases:
smrt.interface.iem_fung92.IEM_Fung92
A moderate rough surface model with backscatter, specular reflection and transmission only. Use with care!
-
check_validity
(ks, kl, eps_r)¶
-
fresnel_coefficients
(eps_1, eps_2, mu_i, ks, kl)¶ calculate the fresnel coefficients at the angle mu_i or 0° depending on ks*kl. The transition is abrupt.
-
smrt.interface.radar_calibration_sphere module¶
Surface with a backscatter of 4pi.
-
class
RadarCalibrationSphere
(**kwargs)¶ Bases:
smrt.core.interface.Interface
-
args
= []¶
-
optional_args
= {}¶
-
specular_reflection_matrix
(frequency, eps_1, eps_2, mu1, npol)¶
-
diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, m_max, npol)¶
-
coherent_transmission_matrix
(frequency, eps_1, eps_2, mu1, npol)¶
-
smrt.interface.test_geometrical_optics module¶
-
test_compare_geometrical_optics
()¶
-
test_reflectance_reciprocity
()¶
-
test_transmission_reciprocity
()¶
smrt.interface.test_iem_fung92_brogioni10 module¶
-
test_iem_fung92_biogoni10_continuty
()¶
-
test_iem_fung92_brogioni10
()¶
smrt.interface.transparent module¶
A transparent interface (no reflection). Useful for the unit-test mainly.
-
class
Transparent
¶ Bases:
object
-
args
= []¶
-
optional_args
= {}¶
-
specular_reflection_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the reflection coefficients for the azimuthal mode m
- and for an array of incidence angles (given by their cosine) in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mhu1 – array of cosine of incident angles
- npol – number of polarization
-
diffuse_reflection_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶
-
coherent_transmission_matrix
(frequency, eps_1, eps_2, mu1, npol)¶ - compute the transmission coefficients for the azimuthal mode m
- and for an array of incidence angles (given by their cosine) in medium 1. Medium 2 is where the beam is transmitted.
Parameters: - eps_1 – permittivity of the medium where the incident beam is propagating.
- eps_2 – permittivity of the other medium
- mu1 – array of cosine of incident angles
- npol – number of polarization
Returns: the transmission matrix
-
diffuse_transmission_matrix
(frequency, eps_1, eps_2, mu_s, mu_i, dphi, npol)¶
-
smrt.interface.vector3 module¶
Module contents¶
This module contains different type of boundary conditions between the layers. Currently only flat interfaces are implemented.
For developers
All the different type of interface must defined the methods: specular_reflection_matrix and coherent_transmission_matrix.
It is currently not possible to implement rough interface, a (small) change is needed in DORT. Please contact the authors.
smrt.substrate package¶
Submodules¶
smrt.substrate.flat module¶
Implement the flat interface boundary for the bottom layer (substrate). The reflection and transmission are computed using the Fresnel coefficients. This model does not take any specific parameter.
-
class
Flat
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.SubstrateBase
-
args
= []¶
-
diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, dphi, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
optional_args
= {}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.geometrical_optics module¶
Implement the geometrical optics rough substrate. See the documentation in geometrical_optics
-
class
GeometricalOptics
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.SubstrateBase
-
args
= ['mean_square_slope']¶
-
diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, dphi, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, m_max, npol)¶
-
optional_args
= {'shadow_correction': True}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.geometrical_optics_backscatter module¶
Implement the geometrical optics rough substrate. See the documentation in geometrical_optics_backscatter
.
-
class
GeometricalOpticsBackscatter
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.SubstrateBase
-
args
= ['mean_square_slope']¶
-
diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, dphi, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, m_max, npol)¶
-
optional_args
= {'shadow_correction': True}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.iem_fung92 module¶
Implement the flat interface boundary for the bottom layer (substrate). The reflection and transmission are computed using the Fresnel coefficients. This model does not take any specific parameter.
-
class
IEM_Fung92
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.SubstrateBase
-
args
= ['roughness_rms', 'corr_length']¶
-
diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, dphi, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, m_max, npol)¶
-
optional_args
= {'autocorrelation_function': 'exponential', 'series_truncation': 10, 'warning_handling': 'print'}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.iem_fung92_brogioni10 module¶
Implement the flat interface boundary for the bottom layer (substrate). The reflection and transmission are computed using the Fresnel coefficients. This model does not take any specific parameter.
-
class
IEM_Fung92_Briogoni10
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.SubstrateBase
-
args
= ['roughness_rms', 'corr_length']¶
-
diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, dphi, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, m_max, npol)¶
-
optional_args
= {'autocorrelation_function': 'exponential', 'series_truncation': 10, 'warning_handling': 'print'}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.radar_calibration_sphere module¶
Implement the radar_calibration_sphere interface boundary for the bottom layer (substrate).
-
class
RadarCalibrationSphere
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.SubstrateBase
-
args
= []¶
-
diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, dphi, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, m_max, npol)¶
-
optional_args
= {}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.reflector module¶
Implement a reflective boundary conditions with prescribed reflection coefficient in the specular direction. The reflection is set to a value or a function of theta. Azimuthal symmetry is assumed (no dependence on phi).
The specular_reflection parameter can be a scalar, a function or a dictionary.
- scalar: same reflection is use for all angles
- function: the function must take a unique argument theta array (in radians) and return the reflection as an array of the same size as theta
- dictionary: in this case, the keys must be ‘H’ and ‘V’ and the values are a scalar or a function and are interpreted as for the non-polarized case.
To make a reflector, it is recommended to use the helper function make_reflector()
.
Examples:
# the full path import is required
from smrt.substrate.reflector import make_reflector
# return a perfect reflector (the temperature is useless in this specific case)
ref = make_reflector(temperature=260, specular_reflection=1)
# return a perfect absorber / black body.
ref = make_reflector(temperature=260, specular_reflection=0)
# Specify a frequency and polarization dictionary of reflectivity
ref = make_reflector(specular_reflection={(21e9, 'H'): 0.5, (21e9, 'V'): 0.6, (36e9, 'H'): 0.7, (36e9, 'V'): 0.8})
Note
the backscatter coefficient argument is not implemented/documented yet.
-
make_reflector
(temperature=None, specular_reflection=None)¶ Construct a reflector or absorber instance.
-
class
Reflector
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.Substrate
-
args
= []¶
-
optional_args
= {'backscatter_coefficient': None, 'specular_reflection': None}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.reflector_backscatter module¶
Implement a reflective boundary conditions with prescribed reflection coefficient in the specular direction. The reflection is set to a value or a function of theta. Azimuthal symmetry is assumed (no dependence on phi).
The specular_reflection parameter can be a scalar, a function or a dictionary.
- scalar: same reflection is use for all angles
- function: the function must take a unique argument theta array (in radians) and return the reflection as an array of the same size as theta
- dictionary: in this case, the keys must be ‘H’ and ‘V’ and the values are a scalar or a function and are interpreted as for the non-polarized case.
To make a reflector, it is recommended to use the helper function make_reflector()
.
Examples:
# the full path import is required
from smrt.substrate.reflector import make_reflector
# return a perfect reflector (the temperature is useless in this specific case)
ref = make_reflector(temperature=260, specular_reflection=1)
# return a perfect absorber / black body.
ref = make_reflector(temperature=260, specular_reflection=0)
Note
the backscatter coefficient argument is not implemented/documented yet.
-
make_reflector
(temperature=None, specular_reflection=None, backscattering_coefficient=None)¶ Construct a reflector or absorber instance.
-
class
Reflector
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.Substrate
-
args
= []¶
-
optional_args
= {'backscattering_coefficient': None, 'specular_reflection': None}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
ft_even_diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, m_max, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.rough_choudhury79 module¶
Implement the rough boundary reflectivity presented in Choudhury et al. (1979). It is not suitable for the active mode.
Applicable for ksigma<<1
parameters: roughness_rms
-
class
ChoudhuryReflectivity
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.Substrate
-
args
= ['roughness_rms']¶
-
optional_args
= {}¶
-
adjust
(rh, rv, frequency, eps_1, mu1)¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.soil_qnh module¶
Implement the QNH soil model proposed by Wang, 1983. This model is for the passive mode, it is not suitable for the active mode.
parameters: Q, N, H (or Nv and Nh instead of N)
Q and N are set to zero by default. The roughness rms is called H and is a required parameter (note: it is called roughness_rms in soil_wegmuller)
- Examples:
- soil = make_soil(“soil_qnh”, “dobson85”, moisture=0.2, sand=0.4, clay=0.3, drymatter=1100,
- Q=0, N=0, H=1e-2)
-
class
SoilQNH
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.Substrate
-
args
= ['H']¶
-
optional_args
= {'N': 0.0, 'Nh': nan, 'Nv': nan, 'Q': 0.0}¶
-
adjust
(rh, rv, mu1)¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.soil_wegmuller module¶
Implement the empirical soil model presented in Wegmuller and Maetzler 1999. It is often used in microwave radiometry. It is not suitable for the active mode.
parameters: roughness_rms
-
class
SoilWegmuller
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.Substrate
-
args
= ['roughness_rms']¶
-
optional_args
= {}¶
-
adjust
(rh, rv, frequency, eps_1, mu1)¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
smrt.substrate.test_reflector module¶
-
test_scalar_specular
()¶
-
test_dict_specular
()¶
-
test_func_specular
()¶
-
test_dict_multifrequency
()¶
-
test_missing_frequency_warning
()¶
-
test_emissivity_reflectivity_relation
()¶
-
test_tuple_dict_multifrequency
()¶
-
test_inverted_reflector_dictionary
()¶
smrt.substrate.test_rough_choudhury79 module¶
-
test_make_rough_choudhury
()¶
-
test_rough_choudhury_reflection
()¶
-
test_raises_ksigma_warning
()¶
-
test_make_rough_water
()¶
-
test_equivalence_fresnel
()¶
smrt.substrate.test_soil_qnh module¶
-
test_make_soil_qnh
()¶
-
test_make_soil_qnh_params
()¶
-
soil_setup
()¶
-
test_soil_qnh_reflection
()¶
-
test_soil_qnh_emissivity
()¶
smrt.substrate.test_soil_wegmuller module¶
-
test_make_soil_wegmuller
()¶
-
test_soil_wegmuller_reflection
()¶
smrt.substrate.transparent module¶
Implement the geometrical optics rough substrate. See the documentation in geometrical_optics_backscatter
.
-
class
Transparent
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.SubstrateBase
-
args
= []¶
-
diffuse_reflection_matrix
(frequency, eps_1, mu_s, mu_i, dphi, npol)¶
-
emissivity_matrix
(frequency, eps_1, mu1, npol)¶
-
optional_args
= {}¶
-
specular_reflection_matrix
(frequency, eps_1, mu1, npol)¶
-
Module contents¶
This directory contains different options to represent the substrate, that is the lower boundary conditions of the radiation transfer equation. This is usually the soil or ice or water but can be an aluminium plate or an absorber.
To create a substrate, use/implement an helper function such as make_soil()
. This function is able to
automatically load a specific soil model .
Examples:
from smrt import make_soil
soil = make_soil("soil_wegmuller", "dobson85", moisture=0.2, sand=0.4, clay=0.3, drymatter=1100, roughness_rms=1e-2)
It is recommended to read first the documentation of make_soil()
and then explore the different types of soil
models.
For developers
To develop a new substrate formulation, you must add a file in the smrt/substrate directory. The name of the file is used by make_soil to build the substrate object.
smrt.atmosphere package¶
Submodules¶
smrt.atmosphere.simple_isotropic_atmosphere module¶
Implement an isotropic atmosphere with prescribed frequency-dependent emission (up and down) and transmittivity.
TB and transmissivity can be specified as a constant, or a frequency-dependent dictionary
To make an atmosphere, it is recommended to use the helper function
make_atmosphere()
.
Examples:
# the full path import is required
from smrt.atmosphere.simple_isotropic_atmosphere import make_atmosphere
# Constant
atmos = make_atmosphere(tbdown=20., tbup=6., trans=1)
# Frequency-dependent
atmos = make_atmosphere(tbdown={10e9: 15.2, 21e9: 23.5})
-
make_atmosphere
(tbdown=0, tbup=0, trans=1)¶ Construct an atmosphere instance.
-
class
SimpleIsotropicAtmosphere
(tbdown=0, tbup=0, trans=1)¶ Bases:
smrt.core.atmosphere.AtmosphereBase
-
tbdown
(frequency, costheta, npol)¶
-
tbup
(frequency, costheta, npol)¶
-
trans
(frequency, costheta, npol)¶
-
smrt.atmosphere.test_atmosphere module¶
-
test_simple_isotropic_atmosphere
()¶
-
test_frequency_dependent_atmosphere
()¶
Module contents¶
This directory contains different options to represent the atmosphere, that is the upper boundary conditions of the radiation transfer equation.
This part is currently not fully developed but should work for an isotropic atmosphere.
Example:
from smrt.atmosphere.basic import ConstantAtmosphere
atmosphere = ConstantAtmosphere(tbdown=2.7, tbup=2.7, trans=0.998)
The API is subject to change.
smrt.emmodel package¶
Submodules¶
smrt.emmodel.common module¶
-
rayleigh_scattering_matrix_and_angle_tsang00
(mu_s, mu_i, dphi, npol=2)¶ compute the Rayleigh matrix and half scattering angle. Based on Tsang theory and application p271 Eq 7.2.16
-
phase_matrix_from_scattering_amplitude
(fvv, fvh, fhv, fhh, npol=2)¶ compute the phase function according to the scattering amplitude. This follows Tsang’s convention.
-
extinction_matrix
(sigma_V, sigma_H=None, npol=2, mu=None)¶ compute the extinction matrix from the extinction in V and in H-pol. If sigma_V or sigma_H are a scalar, they are expanded in a diagonal matrix provided mu is given. If sigma_H is None, sigma_V is used.
-
rayleigh_scattering_matrix_and_angle_maetzler06
(mu_s, mu_i, dphi, npol=2)¶ compute the Rayleigh matrix and half scattering angle. Based on Mätzler 2006 book p111. This version is relatively slow because it uses phase matrix rotations which is unnecessarily complex for the Rayleigh phase matrix but would be of interest for other phase matrices.
-
Lmatrix
(cos_phi, sin_phi_sign, npol)¶
-
rayleigh_scattering_matrix_and_angle
(mu_s, mu_i, dphi, npol=2)¶ compute the Rayleigh matrix and half scattering angle. Based on Tsang theory and application p271 Eq 7.2.16
-
class
AdjustableEffectivePermittivityMixins
¶ Bases:
object
Mixin that allow an EM model to have the effective permittivity model defined by the user instead of by the theory of the EM Model.The EM model must declare a default effective permittivity model.
-
effective_permittivity
()¶ Calculation of complex effective permittivity of the medium.
Returns effective_permittivity: complex effective permittivity of the medium
-
-
derived_EMModel
(base_class, effective_permittivity_model)¶ return a new IBA model with variant from the default IBA.
Parameters: effective_permittivity_model – permittivity mixing formula. :returns a new class inheriting from IBA but with patched methods
smrt.emmodel.commontest module¶
-
test_energy_conservation
(em, tolerance_pc, npol=None, subset=16)¶ test energy conservation
Parameters: - em – the electromagnetic model that has been set up
- tolerance_pc – relative tolerance
smrt.emmodel.dmrt_qca_shortrange module¶
Compute scattering with DMRT QCA Short range. Short range means that it is accurate only for small and weakly sticky spheres (high stickiness value). It diverges (increasing scattering coefficient) if these conditions are not met. Numerically the size conditions can be evaluated with the ratio radius/wavelength as for Rayleigh scatterers. For the stickiness, it is more difficult as this depends on the size of the scatterers and the fractional volume. In any case, it is dangerous to use too small a stickiness value, especially if the grains are big.
This model is only compatible with the SHS microstructure model.
Examples:
from smrt import make_snowpack, make_sensor
density = [345.0] temperature = [260.0] thickness = [70] radius = [750e-6] stickiness = [0.1]
- snowpack = make_snowpack(thickness, “sticky_hard_spheres”,
- density=density, temperature=temperature, radius=radius, stickiness=stickiness)
# create the EM Model - Equivalent DMRTML m = make_model(“dmrt_shortrange”, “dort”)
# create the sensor theta = np.arange(5.0, 80.0, 5.0) radiometer = sensor.amsre()
-
class
DMRT_QCA_ShortRange
(sensor, layer, dense_snow_correction='auto')¶ Bases:
smrt.emmodel.rayleigh.Rayleigh
DMRT electromagnetic model in the short range limit (grains AND aggregates are small) as implemented in DMRTML
Parameters: - sensor – sensor instance
- layer – layer instance
Dense_snow_correction: set how snow denser than half the ice density (ie. fractional volume larger than 0.5 is handled).
“auto” means that snow is modeled as air bubble in ice instead of ice spheres in air. “bridging” should be developed in the future.
-
basic_check
()¶
smrt.emmodel.dmrt_qcacp_shortrange module¶
Compute scattering with DMRT QCACP Short range like in DMRT-ML. Short range means that it is accurate only for small and weakly sticky spheres (high stickiness value). It diverges (increasing scattering coefficient) if these conditions are not met. Numerically the size conditions can be evaluated with the ratio radius/wavelength as for Rayleigh scatterers. For the stickiness, it is more difficult as this depends on the size of the scatterers and the fractional volume. In any case, it is dangerous to use too small a stickiness value, especially if the grains are big.
This model is only compatible with the SHS microstructure model.
Examples:
from smrt import make_snowpack, make_sensor
density = [345.0] temperature = [260.0] thickness = [70] radius = [750e-6] stickiness = [0.1]
- snowpack = make_snowpack(thickness, “sticky_hard_spheres”,
- density=density, temperature=temperature, radius=radius, stickiness=stickiness)
# create the EM Model - Equivalent DMRTML m = make_model(“dmrt_shortrange”, “dort”)
# create the sensor theta = np.arange(5.0, 80.0, 5.0) radiometer = sensor.amsre()
-
class
DMRT_QCACP_ShortRange
(sensor, layer, dense_snow_correction='auto')¶ Bases:
smrt.emmodel.rayleigh.Rayleigh
DMRT electromagnetic model in the short range limit (grains AND aggregates are small) as implemented in DMRTML
Parameters: - sensor – sensor instance
- layer – layer instance
Dense_snow_correction: set how snow denser than half the ice density (ie. fractional volume larger than 0.5 is handled).
“auto” means that snow is modeled as air bubble in ice instead of ice spheres in air. “bridging” should be developed in the future.
-
basic_check
()¶
smrt.emmodel.iba module¶
Compute scattering from Improved Born Approximation theory as described in Mätzler 1998 and Mätzler and Wiesman 1999, except the absorption coefficient which is computed with Polden von Staten formulation instead of the Eq 24 in Mätzler 1998. See iba_original.py for a fully conforming IBA version.
This model allows for different microstructural models provided that the Fourier transform of the correlation function
may be performed. All properties relate to a single layer.
-
derived_IBA
(effective_permittivity_model=<function polder_van_santen>)¶ return a new IBA model with variant from the default IBA.
Parameters: effective_permittivity_model – permittivity mixing formula. :returns a new class inheriting from IBA but with patched methods
-
class
IBA
(sensor, layer)¶ Bases:
smrt.emmodel.common.AdjustableEffectivePermittivityMixins
Improved Born Approximation electromagnetic model class.
As with all electromagnetic modules, this class is used to create an electromagnetic object that holds information about the effective permittivity, extinction coefficient and phase function for a particular snow layer. Due to the frequency dependence, information about the sensor is required. Passive and active sensors also have different requirements on the size of the phase matrix as redundant information is not calculated for the passive case.
Parameters: - sensor – object containing sensor characteristics
- layer – object containing snow layer characteristics (single layer)
Usage Example:
This class is not normally accessed directly by the user, but forms part of the smrt model, together with the radiative solver (in this example, dort) i.e.:
from smrt import make_model model = make_model("iba", "dort")
iba does not need to be imported by the user due to autoimport of electromagnetic model modules
-
static
effective_permittivity_model
(frac_volume, e0=1, eps=3.185, depol_xyz=None, length_ratio=None, inclusion_shape=None, mixing_ratio=1)¶ Calculates effective permittivity of snow by solution of quadratic Polder Van Santen equation for spherical inclusion.
Parameters: - frac_volume – Fractional volume of inclusions
- e0 – Permittivity of background (default is 1)
- eps – Permittivity of scattering material (default is 3.185 to compare with MEMLS)
- depol_xyz – [Optional] Depolarization factors, spherical isotropy is default. It is not taken into account here.
- length_ratio – Length_ratio. Used to estimate depolarization factors when they are not given.
- inclusion_shape – Assumption for shape(s) of brine inclusions. Can be a string for single shape, or a list/tuple/dict of strings for mixture of shapes. So far, we have the following shapes: “spheres” and “random_needles” (i.e. randomly-oriented elongated ellipsoidal inclusions). If the argument is a dict, the keys are the shapes and the values are the mixing ratio. If it is a list, the mixing_ratio argument is required.
- mixing_ratio – The mixing ratio of the shapes. This is only relevant when inclusion_shape is a list/tuple. Mixing ratio must be a sequence with length len(inclusion_shape)-1. The mixing ratio of the last shapes is deduced as the sum of the ratios must equal to 1.
Returns: Effective permittivity
Usage example:
from smrt.permittivity.generic_mixing_formula import polder_van_santen effective_permittivity = polder_van_santen(frac_volume, e0, eps) # for a mixture of 30% spheres and 70% needles effective_permittivity = polder_van_santen(frac_volume, e0, eps, inclusion_shape={"spheres": 0.3, "random_needles": 0.7}) # or effective_permittivity = polder_van_santen(frac_volume, e0, eps, inclusion_shape=("spheres", "random_needles"), mixing_ratio=0.3)
Todo
Extend Polder Van Santen model to account for ellipsoidal inclusions
-
compute_iba_coeff
()¶ Calculate angular independent IBA coefficient: used in both scattering coefficient and phase function calculations
Note
Requires mean squared field ratio (uses mean_sq_field_ratio method)
-
mean_sq_field_ratio
(e0, eps)¶ Mean squared field ratio calculation
Uses layer effective permittivity
Parameters: - e0 – background relative permittivity
- eps – scattering constituent relative permittivity
-
basic_check
()¶
-
compute_ks
()¶ Calculate scattering coefficient: integrate p11+p12 over mu
-
ks_integrand
(mu)¶ This is the scattering function for the IBA model.
It uses the phase matrix in the 1-2 frame. With incident angle chosen to be 0, the scattering angle becomes the scattering zenith angle:
Scattering coefficient is determined by integration over the scattering angle (0 to pi)
Parameters: mu – cosine of the scattering angle (single angle) The integration is performed outside this method.
-
phase
(mu_s, mu_i, dphi, npol=2)¶ IBA Phase function (not decomposed).
-
ft_even_phase
(mu_s, mu_i, m_max, npol=None)¶ Calculation of the Fourier decomposed IBA phase function.
This method calculates the Improved Born Approximation phase matrix for all Fourier decomposition modes and return the output.
Coefficients within the phase function are
Passive case (m = 0 only) and active (m = 0)
M = [Pvvp Pvhp] [Phvp Phhp]
Active case (m > 0):
M = [Pvvp Pvhp Pvup] [Phvp Phhp Phup] [Puvp Puhp Puup]
The IBA phase function is given in Mätzler, C. (1998). Improved Born approximation for scattering of radiation in a granular medium. Journal of Applied Physics, 83(11), 6111-6117. Here, calculation of the phase matrix is based on the phase matrix in the 1-2 frame, which is then rotated according to the incident and scattering angles, as described in e.g. Thermal Microwave Radiation: Applications for Remote Sensing, Mätzler (2006). Fourier decomposition is then performed to separate the azimuthal dependency from the incidence angle dependency.
Parameters: - mu_s – 1-D array of cosine of viewing radiation stream angles (set by solver)
- mu_i – 1-D array of cosine of incident radiation stream angles (set by solver)
- m_max – maximum Fourier decomposition mode needed
- npol – number of polarizations considered (set from sensor characteristics)
-
compute_ka
()¶ IBA absorption coefficient calculated from the low-loss assumption of a general lossy medium.
Calculates ka from wavenumber in free space (determined from sensor), and effective permittivity of the medium (snow layer property)
Return ka: absorption coefficient [m -1] Note
This may not be suitable for high density material
-
ke
(mu, npol=2)¶ IBA extinction coefficient matrix
The extinction coefficient is defined as the sum of scattering and absorption coefficients. However, the radiative transfer solver requires this in matrix form, so this method is called by the solver.
param mu: 1-D array of cosines of radiation stream incidence angles param npol: number of polarization returns ke: extinction coefficient matrix [m -1] Note
Spherical isotropy assumed (all elements in matrix are identical).
Size of extinction coefficient matrix depends on number of radiation streams, which is set by the radiative transfer solver.
-
class
IBA_MM
(sensor, layer)¶ Bases:
smrt.emmodel.iba.IBA
smrt.emmodel.iba_original module¶
Compute scattering from Improved Born Approximation theory. This model allows for different microstructural models provided that the Fourier transform of the correlation function may be performed. All properties relate to a single layer. The absorption is calculated with the original formula in Mätzler 1998
-
class
IBA_original
(sensor, layer)¶ Bases:
smrt.emmodel.iba.IBA
Original Improved Born Approximation electromagnetic model class.
As with all electromagnetic modules, this class is used to create an electromagnetic object that holds information about the effective permittivity, extinction coefficient and phase function for a particular snow layer. Due to the frequency dependence, information about the sensor is required. Passive and active sensors also have different requirements on the size of the phase matrix as redundant information is not calculated for the passive case.
Parameters: - sensor – object containing sensor characteristics
- layer – object containing snow layer characteristics (single layer)
-
compute_ka
()¶ IBA absorption coefficient calculated from the low-loss assumption of a general lossy medium.
Calculates ka from wavenumber in free space (determined from sensor), and effective permittivity of the medium (snow layer property)
Return ka: absorption coefficient [m -1] Note
This may not be suitable for high density material
smrt.emmodel.nonscattering module¶
Non-scattering medium can be applied to medium without heteoreneity (like water or pure ice layer).
smrt.emmodel.prescribed_kskaeps module¶
- Use prescribed scattering ks and absorption ka coefficients and effective permittivity in the layer.
The phase matrix has the Rayleigh form with prescribed scattering coefficient
This model is compatible with any microstructure but requires that ks, ka, and optionally effective permittivity to be set in the layer
Example:
m = make_model("prescribed_kskaeps", "dort")
snowpack.layers[0].ks = ks
snowpack.layers[0].ka = ka
snowpack.layers[0].effective_permittivity = eff_eps
-
class
Prescribed_KsKaEps
(sensor, layer)¶
smrt.emmodel.rayleigh module¶
Compute Rayleigh scattering. This theory requires the scatterers to be smaller than the wavelength and the medium to be sparsely populated (eq. very low density in the case of snow).
This model is only compatible with the Independent Sphere microstructure model
-
class
Rayleigh
(sensor, layer)¶ Bases:
object
-
basic_check
()¶
-
ft_even_phase_baseonUlaby
(mu_s, mu_i, m_max, npol=None)¶ # # Equations are from pg 1188-1189 Ulaby, Moore, Fung. Microwave Remote Sensing Vol III. # See also pg 157 of Tsang, Kong and Shin: Theory of Microwave Remote Sensing (1985) - can be used to derive # the Ulaby equations.
-
ft_even_phase_basedonJin
(mu_s, mu_i, m_max, npol=None)¶ Rayleigh phase matrix.
These are the Fourier decomposed phase matrices for modes m = 0, 1, 2. It is based on Y.Q. Jin
Coefficients within the phase function are:
- M = [Pvvp Pvhp]
- [Phvp Phhp]
Inputs are: :param m: mode for decomposed phase matrix (0, 1, 2) :param mu: vector of cosines of incidence angle
Returns P: phase matrix
-
ft_even_phase_tsang
(mu_s, mu_i, m_max, npol=None)¶ Rayleigh phase matrix.
These are the Fourier decomposed phase matrices for modes m = 0, 1, 2. Equations are from p128 Tsang Application and Theory 200 and sympy calculations
Coefficients within the phase function are:
- M = [P[v, v] P[v, h] -P[v, u]]
- [P[h, v] P[h, h] -P[h, u]] [P[u, v] P[u, h] P[u, u]]
Inputs are: :param m: mode for decomposed phase matrix (0, 1, 2) :param mu: vector of cosines of incidence angle
Returns P: phase matrix
-
ft_even_phase
(mu_s, mu_i, m_max, npol=None)¶ # # Equations are from pg 1188-1189 Ulaby, Moore, Fung. Microwave Remote Sensing Vol III. # See also pg 157 of Tsang, Kong and Shin: Theory of Microwave Remote Sensing (1985) - can be used to derive # the Ulaby equations.
-
phase
(mu_s, mu_i, dphi, npol=2)¶
-
ke
(mu, npol=2)¶ return the extinction coefficient matrix
The extinction coefficient is defined as the sum of scattering and absorption coefficients. However, the radiative transfer solver requires this in matrix form, so this method is called by the solver.
param mu: 1-D array of cosines of radiation stream incidence angles param npol: number of polarizations returns ke: extinction coefficient matrix [m -1] Note
Spherical isotropy assumed (all elements in matrix are identical).
Size of extinction coefficient matrix depends on number of radiation streams, which is set by the radiative transfer solver.
-
effective_permittivity
()¶
-
smrt.emmodel.sft_rayleigh module¶
Compute Strong Fluctuation Theory scattering. This theory requires the scatterers to be smaller than the wavelength
This model is only compatible with the Exponential autocorrelation function only
-
class
SFT_Rayleigh
(sensor, layer)¶
smrt.emmodel.test_iba module¶
-
setup_func_sp
()¶
-
setup_func_indep
(radius=0.0005)¶
-
setup_func_shs
()¶
-
setup_func_pc
(pc)¶
-
setup_func_em
(testpack=None)¶
-
setup_func_active
(testpack=None)¶
-
setup_func_rayleigh
()¶
-
setup_mu
(stepsize, bypass_exception=None)¶
-
test_ks_pc_is_0p3_mm
()¶
-
test_ks_pc_is_0p25_mm
()¶
-
test_ks_pc_is_0p15_mm
()¶
-
test_ks_pc_is_0p1_mm
()¶
-
test_ks_pc_is_0p2_mm
()¶
-
test_energy_conservation_exp
()¶
-
test_energy_conservation_indep
()¶
-
test_energy_conservation_shs
()¶
-
test_npol_passive_is_2
()¶
-
test_npol_active_is_3
()¶
-
test_energy_conservation_exp_active
()¶
-
test_energy_conservation_indep_active
()¶
-
test_energy_conservation_shs_active
()¶
-
test_iba_vs_rayleigh_passive_m0
()¶
-
test_iba_vs_rayleigh_active_m0
()¶
-
test_iba_vs_rayleigh_active_m1
()¶
-
test_iba_vs_rayleigh_active_m2
()¶
-
test_permittivity_model
()¶
-
test_iba_raise_exception_mu_is_1
()¶
smrt.emmodel.test_iba_original module¶
-
setup_func_sp
()¶
-
setup_func_indep
(radius=0.0005)¶
-
setup_func_shs
()¶
-
setup_func_pc
(pc)¶
-
setup_func_em
(testpack=None)¶
-
setup_func_active
(testpack=None)¶
-
setup_func_rayleigh
()¶
-
setup_mu
(stepsize, bypass_exception=None)¶
-
test_ks_pc_is_0p3_mm
()¶
-
test_ks_pc_is_0p25_mm
()¶
-
test_ks_pc_is_0p15_mm
()¶
-
test_ks_pc_is_0p1_mm
()¶
-
test_ks_pc_is_0p2_mm
()¶
-
test_energy_conservation_exp
()¶
-
test_energy_conservation_indep
()¶
-
test_energy_conservation_shs
()¶
-
test_npol_passive_is_2
()¶
-
test_npol_active_is_3
()¶
-
test_energy_conservation_exp_active
()¶
-
test_energy_conservation_indep_active
()¶
-
test_energy_conservation_shs_active
()¶
-
test_iba_vs_rayleigh_passive_m0
()¶
-
test_iba_vs_rayleigh_active_m0
()¶
-
test_iba_vs_rayleigh_active_m1
()¶
-
test_iba_vs_rayleigh_active_m2
()¶
-
test_iba_raise_exception_mu_is_1
()¶
smrt.emmodel.test_prescribed_kskaeps module¶
-
setup_func_sp
()¶
-
setup_func_em
(testpack=None)¶
-
test_energy_conservation
()¶
smrt.emmodel.test_rayleigh module¶
-
setup_func_sp
()¶
-
setup_func_em
(testpack=None)¶
-
test_energy_conservation
()¶
-
test_energy_conservation_tsang
()¶
-
test_energy_conservation_jin
()¶
smrt.emmodel.test_sft_rayleigh module¶
-
setup_func_sp
()¶
-
setup_func_em
(testpack=None)¶
-
test_energy_conservation
()¶
Module contents¶
This directory contains the different electromagnetic (EM) models that compute the scattering and absorption coefficients
and the phase function in a _given_ _layer_. The computation of the inter-layer propagation is done by the
rtsolver
package.
The EM models differ in many aspects, one of which is the constraint on the microstructure model
they can be used with. The smrt.emmodel.iba
model can use any
microstructure model that defines autocorrelation functions (or its FT). In contrast others such as
smrt.emmodel.dmrt_shortrange
is bound to the smrt.microstructuremodel.sticky_hard_spheres
microstructure
for theoretical reasons.
The selection of the EM model is done with the smrt.core.model.make_model()
function
For developers
To implement a new scattering formulation / phase function, we recommend to start from an existing module, probably rayleigh.py is the simplest.
Copy this file to myscatteringtheory.py or any meaningful name. It can be directly used with make_model()
function as follows:
m = make_model("myscatteringtheory", "dort")
Note that if the file is not in the emmodels directory, you must explicitly import the module and pass it to make_model as a module object (instead of a string).
- An emmodel model must define:
- ks and ka attributes/properties
- ke() and effective_permittivity() methods
- at least one of the phase and ft_even_phase methods (both is better).
For the details it is recommended to contact the authors as the calling arguments and required methods may change time to time.
smrt.rtsolver package¶
Submodules¶
smrt.rtsolver.dort module¶
The Discrete Ordinate and Eigenvalue Solver is a multi-stream solver of the radiative transfer model. It is precise but less efficient than 2 or 6 flux solvers. Different flavours of DORT (or DISORT) exist depending on the mode (passive or active), on the density of the medium (sparse media have trivial inter-layer boundary conditions), on the way the streams are connected between the layers and on the way the phase function is prescribed. The actual version is a blend between Picard et al. 2004 (active mode for sparse media) and DMRT-ML (Picard et al. 2013) which works in passive mode only for snow. The DISORT often used in optics (Stamnes et al. 1988) works only for sparse medium and uses a development of the phase function in Legendre polynomia on theta. The version used in DMRT-QMS (L. Tsang’s group) is similar to the present implementation except it uses spline interpolation to connect constant-angle streams between the layers although we use direct connection by varying the angle according to Snell’s law. A practical consequence is that the number of streams vary (due to internal reflection) and the value n_max_stream only applies in the most refringent layer. The number of outgoing streams in the air is usually smaller, sometimes twice smaller (depends on the density profile). It is important not to set too low a value for n_max_streams. E.g. 32 is usually fine, 64 or 128 are better but simulations will be much slower.
-
class
DORT
(n_max_stream=32, m_max=2, stream_mode='most_refringent', phase_normalization=True, error_handling='exception', process_coherent_layers=False, prune_deep_snowpack=None)¶ Bases:
object
Discrete Ordinate and Eigenvalue Solver
Parameters: - n_max_stream – number of stream in the most refringent layer
- m_max – number of mode (azimuth)
- phase_normalization – the integral of the phase matrix should in principe be equal to the scattering coefficient. However, some emmodels do not respect this strictly. In general a small difference is due to numerical rounding and is acceptable, but a large difference rather indicates either a bug in the emmodel or input parameters that breaks the assumption of the emmodel. The most typical case is when the grain size is too big compared to wavelength for emmodels that rely on Rayleigh assumption. If this argument is to True (the default), the phase matrix is normalized to be coherent with the scattering coefficient, but only when the difference is moderate (0.7 to 1.3). If set to “force” the normalization is always performed. This option is dangerous because it may hide bugs or unappropriate input parameters (typically too big grains). If set to False, no normalization is performed.
- error_handling – If set to “exception” (the default), raise an exception in cause of error, stopping the code. If set to “nan”, return a nan, so the calculation can continue, but the result is of course unusuable and the error message is not accessible. This is only recommended for long simulations that sometimes produce an error.
- process_coherent_layers – Adapt the layers thiner than the wavelegnth using the MEMLS method. The radiative transfer theory is inadequate layers thiner than the wavelength and using DORT with thin layers is generally not recommended. In some parcticular cases (such as ice lenses) where the thin layer is isolated between large layers, it is possible to replace the thin layer by an equivalent reflective interface. This neglects scattering in the thin layer, which is acceptable in most case, because the layer is thin. To use this option and more generally to investigate ice lenses, it is recommended to read MEMLS documentation on this topic.
- prune_deep_snowpack – this value is the optical depth from which the layers are discarded in the calculation. It is to be use to accelerate the calculations for deep snowpacks or at high frequencies when the contribution of the lowest layers is neglegible. The optical depth is a good criteria to determine this limit. A value of about 6 is recommended. Use with care, especially values lower than 6.
-
solve
(snowpack, emmodels, sensor, atmosphere=None)¶ solve the radiative transfer equation for a given snowpack, emmodels and sensor configuration.
-
dort
(m_max=0, special_return=False)¶
-
prepare_intensity_array
(streams)¶
-
dort_modem_banded
(m, streams, eigenvalue_solver, interfaces, intensity_down_m, compute_coherent_only=False, special_return=False)¶
-
muleye
(x)¶
-
matmul
(a, b, *args)¶
-
compiled_todiag
¶
-
todiag
(bmat, oi, oj, dmat)¶
-
extend_2pol_npol
(x, npol)¶
-
class
EigenValueSolver
(ke, ks, ft_even_phase_function, mu, weight, m_max, normalization)¶ Bases:
object
-
solve
(m, compute_coherent_only, debug_A=False)¶
-
normalize
(m, A)¶
-
-
class
InterfaceProperties
(frequency, interfaces, substrate, permittivity, streams, m_max, npol)¶ Bases:
object
-
reflection_top
(l, m, compute_coherent_only)¶
-
reflection_bottom
(l, m, compute_coherent_only)¶
-
transmission_top
(l, m, compute_coherent_only)¶
-
transmission_bottom
(l, m, compute_coherent_only)¶
-
static
combine_coherent_diffuse_matrix
(coh, diff, m, compute_coherent_only)¶
-
-
normalize_diffuse_matrix
(mat, mu_st, mu_i, weights)¶
-
class
Streams
¶ Bases:
object
-
compute_stream
(n_max_stream, permittivity, permittivity_substrate, mode='most_refringent')¶
-
gaussquad
(n)¶
smrt.rtsolver.dort_nonormalization module¶
The Discrete Ordinate and Eigenvalue Solver is a multi-stream solver of the radiative transfer model. It is precise but less efficient than 2 or 6 flux solvers. Different flavours of DORT (or DISORT) exist depending on the mode (passive or active), on the density of the medium (sparse media have trivial inter-layer boundary conditions), on the way the streams are connected between the layers and on the way the phase function is prescribed. The actual version is a blend between Picard et al. 2004 (active mode for sparse media) and DMRT-ML (Picard et al. 2013) which works in passive mode only for snow. The DISORT often used in optics (Stamnes et al. 1988) works only for sparse medium and uses a development of the phase function in Legendre polynomia on theta. The version used in DMRT-QMS (L. Tsang’s group) is similar to the present implementation except it uses spline interpolation to connect constant-angle streams between the layers although we use direct connection by varying the angle according to Snell’s law. A practical consequence is that the number of streams vary (due to internal reflection) and the value n_max_stream only applies in the most refringent layer. The number of outgoing streams in the air is usually smaller, sometimes twice smaller (depends on the density profile). It is important not to set too low a value for n_max_stream. E.g. 32 is usually fine, 64 or 128 are better but simulations will be much slower.
-
class
DORT
(n_max_stream=32, m_max=2, stream_mode='most_refringent')¶ Bases:
object
Discrete Ordinate and Eigenvalue Solver
Parameters: - n_max_stream – number of stream in the most refringent layer
- m_max – number of mode (azimuth)
-
solve
(snowpack, emmodels, sensor, atmosphere=None)¶ solve the radiative transfer equation for a given snowpack, emmodels and sensor configuration.
-
dort
(m_max=0, special_return=False)¶
-
prepare_intensity_array
(outmu, outweight)¶
-
dort_modem_banded
(m, n_stream, mu, weight, outmu, n_stream_substrate, intensity_down_m, compute_coherent_only=False, special_return=False)¶
-
fix_matrix
(x)¶
-
muleye
(x)¶
-
todiag
(bmat, ij, dmat)¶
-
extend_2pol_npol
(x, npol)¶
-
solve_eigenvalue_problem
(m, ke, ft_even_phase, mu, weight)¶
-
compute_stream
(n_max_stream, permittivity, permittivity_substrate, mode='most_refringent')¶
-
gaussquad
(n)¶
smrt.rtsolver.nadir_lrm_altimetry module¶
-
class
NadirLRMAltimetry
(waveform_model=None, oversampling=10, return_oversampled=False, skip_pfs_convolution=False, return_contributions=False, theta_inc_sampling=1, return_theta_inc_sampling=False, error_handling='exception')¶ Bases:
object
Solver based on Adams and Brown 1998 and Lacroix et al. 2008. Both models differ in the specific choices for the scattering and backscatter of the interface, but are similar in the way the waveform is calculated, which concerns the solver here.
Parameters: - oversampling – integer number defining the number of subgates used for the computation in each altimeter gate. This is equivalent to multiply the bandwidth by this number. It is used to perform more accurate computation.
- return_oversampled – by default the backscatter is returned for each gate. If set to True, the oversampled waveform is returned instead. See the ‘oversampling’ argument.
- return_contributions – return volume, surface and interface backscatter contributions in addition to the total backscatter.
-
solve
(snowpack, emmodels, sensor, atmosphere=None)¶ solve the radiative transfer equation for a given snowpack, emmodels and sensor configuration.
-
convolve_with_PFS_PTR_PDF
(t_gate, backscatter, t_inc_sample)¶
-
gate_depth
(eps=None)¶ return gate depth that cover the snowpack for a regular time sampling
-
combined_depth_grid
()¶
-
vertical_scattering_distribution
(return_contributions, mu_i=1.0)¶ - Compute the vertical backscattering distribution due to “grain” or volume scattering (symbol pvg in Eq 9 in Lacroix 2008) and
“interfaces” or ‘surface’ scattering (symbol pvl in Eq 9 in Lacroix 2008)
param mu: cosine of the incidence angles. Only the dependence on the surface scattering depend on mu_i
-
PFS_numerical
(tau)¶
-
fill_forward
(a, where, axis=-1)¶
-
fill
(a, where, novalue=0)¶
smrt.rtsolver.test_dort module¶
-
setup_snowpack
()¶
-
setup_snowpack_with_DH
()¶
-
setup_2layer_snowpack
()¶
-
test_noabsoprtion
()¶
-
test_returned_theta
()¶
-
test_selectby_theta
()¶
-
test_depth_hoar_stream_numbers
()¶
-
test_2layer_pack
()¶
-
test_shallow_snowpack
()¶
smrt.rtsolver.waveform_model module¶
-
class
WaveformModel
¶ Bases:
object
-
class
Brown1977
(sensor, numerical_convolution=False)¶ Bases:
smrt.rtsolver.waveform_model.WaveformModel
Antenna Gain formulation used by Brown 1977. The formula is exp(2/gamma * sin(theta)**2) for the perfect nadir case, but is also available with off-nadir angles.
-
G
(theta, phi)¶
-
PFS
(tau, surface_slope=0, shift_nominal_gate=True)¶
-
PFS_PTR_PDF
(tau, sigma_surface=0, surface_slope=0)¶ compute the convolution of the PFS and PTR
Parameters: - sensor – sensor to apply the antenna gain
- tau – time to which to compute the PFSxPTR
- sigma_surface – RMS height of the surface topography (meter)
-
-
class
Newkrik1992
(sensor)¶ Bases:
smrt.rtsolver.waveform_model.WaveformModel
Antenna Gain formulation proposed by Newkrik and Brown, 1992. Compared to the classical Bronw 1977, it takes into account the asymmetry of the antenna pattern in the co and cross-track direction.
-
G
(theta, phi)¶
-
PFS
(sensor, tau)¶
-
Module contents¶
This directory contains different solvers of the radiative transfer equation. Based on the electromagnetic properties of
each layer computed by the EM model, these RT solvers compute the emission and propagation of energy in the medium up to the surface (the atmosphere is usually
dealt with independently in dedicated modules in smrt.atmosphere
).
The solvers differ by the approximations and numerical methods. dort
is currently the most accurate and recommended
in most cases unless the computation time is a constraint.
The selection of the solver is done with the make_model()
function.
For Developers
To experiment with DORT, we recommand to copy the file dort.py to e.g. dort_mytest.py so it is immediately available through
make_model()
.
To develop a new solver that will be accessible by the make_model()
function, you need to add
a file in this directory, give a look at dort.py which is not simple but the only one at the moment. Only the method solve needs
to be implemented. It must return a Result
instance with the results. Contact the core developers to have more details.
smrt.core package¶
Submodules¶
smrt.core.error module¶
Definition of the Exception specific to SMRT.
-
exception
SMRTError
¶ Bases:
Exception
Error raised by the model
-
exception
SMRTWarning
¶ Bases:
Warning
Warning raised by the model
-
smrt_warn
(message)¶
smrt.core.filelock module¶
A platform independent file lock that supports the with-statement.
-
exception
Timeout
(lock_file)¶ Bases:
TimeoutError
Raised when the lock could not be acquired in timeout seconds.
-
lock_file
= None¶ The path of the file lock.
-
-
class
BaseFileLock
(lock_file, timeout=-1)¶ Bases:
object
Implements the base class of a file lock.
-
lock_file
¶ The path to the lock file.
-
timeout
¶ You can set a default timeout for the filelock. It will be used as fallback value in the acquire method, if no timeout value (None) is given.
If you want to disable the timeout, set it to a negative value.
A timeout of 0 means, that there is exactly one attempt to acquire the file lock.
New in version 2.0.0.
-
is_locked
¶ True, if the object holds the file lock.
Changed in version 2.0.0: This was previously a method and is now a property.
-
acquire
(timeout=None, poll_intervall=0.05)¶ Acquires the file lock or fails with a
Timeout
error.# You can use this method in the context manager (recommended) with lock.acquire(): pass # Or use an equivalent try-finally construct: lock.acquire() try: pass finally: lock.release()
Parameters: - timeout (float) – The maximum time waited for the file lock.
If
timeout < 0
, there is no timeout and this method will block until the lock could be acquired. Iftimeout
is None, the defaulttimeout
is used. - poll_intervall (float) – We check once in poll_intervall seconds if we can acquire the file lock.
Raises: Timeout – if the lock could not be acquired in timeout seconds.
Changed in version 2.0.0: This method returns now a proxy object instead of self, so that it can be used in a with statement without side effects.
- timeout (float) – The maximum time waited for the file lock.
If
-
release
(force=False)¶ Releases the file lock.
Please note, that the lock is only completly released, if the lock counter is 0.
Also note, that the lock file itself is not automatically deleted.
Parameters: force (bool) – If true, the lock counter is ignored and the lock is released in every case.
-
-
class
WindowsFileLock
(lock_file, timeout=-1)¶ Bases:
smrt.core.filelock.BaseFileLock
Uses the
msvcrt.locking()
function to hard lock the lock file on windows systems.
-
class
UnixFileLock
(lock_file, timeout=-1)¶ Bases:
smrt.core.filelock.BaseFileLock
Uses the
fcntl.flock()
to hard lock the lock file on unix systems.
-
class
SoftFileLock
(lock_file, timeout=-1)¶ Bases:
smrt.core.filelock.BaseFileLock
Simply watches the existence of the lock file.
-
FileLock
¶ Alias for the lock, which should be used for the current platform. On Windows, this is an alias for
WindowsFileLock
, on Unix forUnixFileLock
and otherwise forSoftFileLock
.alias of
smrt.core.filelock.UnixFileLock
smrt.core.fresnel module¶
fresnel coefficients formulae used in the packages smrt.interface
and smrt.substrate
.
-
fresnel_coefficients_old
(eps_1, eps_2, mu1)¶ compute the reflection in two polarizations (H and V). The equations are only valid for lossless media. Applying these equations for (strongly) lossy media result in (large) errors. Don’t use it. It is here for reference only.
Parameters: - eps_1 – permittivity of medium 1.
- eps_2 – permittivity of medium 2.
- mu1 – cosine zenith angle in medium 1.
Returns: rv, rh, mu2 the cosine of the angle in medium 2
-
fresnel_coefficients_maezawa09_classical
(eps_1, eps_2, mu1, full_output=False)¶ compute the reflection in two polarizations (H and V) for lossly media with the “classical Fresnel” based on Maezawa, H., & Miyauchi, H. (2009). Rigorous expressions for the Fresnel equations at interfaces between absorbing media. Journal of the Optical Society of America A, 26(2), 330. https://doi.org/10.1364/josaa.26.000330
The classical derivation does not respect energy conservation, especially the transmittivity. Don’t use it. It is here for reference only.
Parameters: - eps_1 – permittivity of medium 1.
- eps_2 – permittivity of medium 2.
- mu1 – cosine zenith angle in medium 1.
Returns: rv, rh, mu2 the cosine of the angle in medium 2
-
fresnel_coefficients_maezawa09_rigorous
(eps_1, eps_2, mu1, full_output=False)¶ compute the reflection in two polarizations (H and V) for lossly media with the “rigorous Fresnel” based on Maezawa, H., & Miyauchi, H. (2009). Rigorous expressions for the Fresnel equations at interfaces between absorbing media. Journal of the Optical Society of America A, 26(2), 330. https://doi.org/10.1364/josaa.26.000330
The ‘rigorous’ derivation respect the energy conservation even for strongly loosly media.
Parameters: - eps_1 – permittivity of medium 1.
- eps_2 – permittivity of medium 2.
- mu1 – cosine zenith angle in medium 1.
Returns: rv, rh, mu2 the cosine of the angle in medium 2
-
fresnel_coefficients
(eps_1, eps_2, mu1, full_output=False)¶ compute the reflection in two polarizations (H and V) for lossly media with the “rigorous Fresnel” based on Maezawa, H., & Miyauchi, H. (2009). Rigorous expressions for the Fresnel equations at interfaces between absorbing media. Journal of the Optical Society of America A, 26(2), 330. https://doi.org/10.1364/josaa.26.000330
The ‘rigorous’ derivation respect the energy conservation even for strongly loosly media.
Parameters: - eps_1 – permittivity of medium 1.
- eps_2 – permittivity of medium 2.
- mu1 – cosine zenith angle in medium 1.
Returns: rv, rh, mu2 the cosine of the angle in medium 2
-
snell_angle
(eps_1, eps_2, mu1)¶ compute mu2 the cos(angle) in the second medium according to Snell’s law.
-
brewster_angle
(eps_1, eps_2)¶ compute the brewster angle
Parameters: - eps_1 – permittivity of medium 1.
- eps_2 – permittivity of medium 2.
Returns: angle in radians
-
fresnel_reflection_matrix
(eps_1, eps_2, mu1, npol)¶ compute the fresnel reflection matrix for/in medium 1 laying above medium 2.
Parameters: - npol – number of polarizations to return.
- eps_1 – permittivity of medium 1.
- eps_2 – permittivity of medium 2.
- mu1 – cosine zenith angle in medium 1.
Returns: a matrix or the diagional depending on return_as_diagonal
-
fresnel_transmission_matrix
(eps_1, eps_2, mu1, npol)¶ compute the fresnel reflection matrix for/in medium 1 laying above medium 2.
Parameters: - npol – number of polarizations to return.
- eps_1 – permittivity of medium 1.
- eps_2 – permittivity of medium 2.
- mu1 – cosine zenith angle in medium 1.
Returns: a matrix or the diagional depending on return_as_diagonal
smrt.core.globalconstants module¶
Global constants used throughout the model are defined here and imported as needed. The constants are:
Parameter | Description | Value |
---|---|---|
DENSITY_OF_ICE | Density of pure ice at 273.15K | 916.7 kg m -3 |
FREEZING_POINT | Freezing point of pure water | 273.15 K |
C_SPEED | Speed of light in a vacuum | 2.99792458 x 10 8 ms -1 |
PERMITTIVITY_OF_AIR | Relative permittivity of air | 1 |
Usage example:
from smrt.core.globalconstants import DENSITY_OF_ICE
smrt.core.interface module¶
This module implements the base class for all the substrate models.
To create a substrate, it is recommended to use help functions such as make_soil()
rather than the class constructor.
-
make_interface
(inst_class_or_modulename, broadcast=True, **kwargs)¶ return an instance corresponding to the interface model with the provided arguments.
This function imports the interface module if necessary and return an instance of the interface class with the provided arguments in **kwargs.
Parameters: - inst_class_or_modulename – a class, and instance or the name of the python module in smrt/interface
- **kwargs –
all the arguments required by the interface class
-
class
Interface
(**kwargs)¶ Bases:
object
Abstract class for interface between layer and substrate at the bottom of the snowpack. It provides argument handling.
-
args
= []¶
-
optional_args
= {}¶
-
-
class
SubstrateBase
(temperature=None, permittivity_model=None)¶ Bases:
object
Abstract class for substrate at the bottom of the snowpack. It provides calculation of the permittivity constant for soil case. Argument handline is delegated to the instance of the interface
-
permittivity
(frequency)¶ compute the permittivity for the given frequency using permittivity_model. This method returns None when no permittivity model is available. This must be handled by the calling code and interpreted suitably.
-
-
substrate_from_interface
(interface_cls)¶ this decorator transform an interface class into a substrate class with automatic method
-
class
Substrate
(temperature=None, permittivity_model=None, **kwargs)¶ Bases:
smrt.core.interface.SubstrateBase
,smrt.core.interface.Interface
-
get_substrate_model
(substrate_model)¶ return the class corresponding to the substrate model called name. This function imports the correct module if possible and returns the class
smrt.core.layer module¶
Layer
instance contains all the properties for a single snow layer (e.g. temperature, frac_volume, etc).
It also contains a microstructure attribute that holds the microstructural properties (e.g. radius, corr_length, etc).
The class of this attribute defines the microstructure model to use (see smrt.microstructure_model
package).
To create a single layer, it is recommended to use the function make_snow_layer()
rather than the class constructor. However it is usually more convenient
to create a snowpack using make_snowpack()
.
For developers
The Layer
class should not be modified at all even if you need new properties to define the layer (e.g. brine concentration, humidity, …). If the property you need to add is
related to geometric aspects, it is probably better to use an existing microstructure model or to create a new one. If the new parameter is not related to geometrical aspect,
write a function similar to make_snow_layer()
(choose an explicit name for your purpose). In this function, create the layer by calling the Layer
constructor as in make_snow_layer()
and then add your properties with lay.myproperty=xxx, … See the example of liquid water in make_snow_layer()
.
This approach avoids specialization of the Layer class. The new function can be in any file (inc. out of smrt directories), and should be added in make_medium
if it is of general interest and written in a generic way, that is, covers many use cases for many users with default arguments, etc.
-
class
Layer
(thickness, microstructure_model=None, temperature=273.15, permittivity_model=None, inclusion_shape=None, **kwargs)¶ Bases:
object
Contains the properties for a single layer including the microstructure attribute which holds the microstructure properties.
To create layer, it is recommended to use of the functions
make_snow_layer()
and similar-
ssa
¶ return the SSA, compute it if necessary
-
frac_volume
¶
-
permittivity
(i, frequency)¶ return the permittivity of the i-th medium depending on the frequency and internal layer properties. Usually i=0 is air and i=1 is ice for dry snow with a low or moderate density.
Parameters: - i – number of the medium. 0 is reserved for the background
- frequency – frequency of the wave (Hz)
Returns: complex permittivity of the i-th medium
-
basic_checks
()¶ Function to provide very basic input checks on the layer information
Currently checks:
- temperature is between 100 and the freezing point (Kelvin units check),
- density is between 1 and DENSITY_OF_ICE (SI units check)
- layer thickness is above zero
-
inverted_medium
()¶ return the layer with inverted autocorrelation and inverted permittivities.
-
-
get_microstructure_model
(modulename, classname=None)¶ return the class corresponding to the microstructure_model defined in modulename.
This function import the correct module if possible and return the class. It is used internally and should not be needed for normal usage.
Parameters: modulename – name of the python module in smrt/microstructure_model
-
make_microstructure_model
(modelname_or_class, **kwargs)¶ create an microstructure instance.
This function is called internally and should not be needed for normal use.
param modelname_or_class: name of the module or directly the class. param type: string param **kwargs: all the arguments need for the specific autocorrelation. returns: instance of the autocorrelation modelname with the parameters given in **kwargs Example: To import the StickyHardSpheres class with spheres radius of 1mm, stickiness of 0.5 and fractional_volume of 0.3:
shs = make_autocorrelation("StickyHardSpheres", radius=0.001, stickiness=0.5, frac_volume=0.3)
-
layer_properties
(*required_arguments, optional_arguments=None, **kwargs)¶ This decorator is used for the permittivity functions (or any other functions) to inject layer’s attributes as arguments. The decorator declares the layer properties needed to call the function and the optional ones. This allows permittivity functions to use any property of the layer, as long as it is defined.
smrt.core.lib module¶
-
get
(x, i, name=None)¶
-
check_argument_size
(x, n, name=None)¶
-
is_sequence
(x)¶
-
len_atleast_1d
(x)¶
-
class
smrt_diag
(arr)¶ Bases:
object
Scipy.sparse is very slow for diagonal matrix and numpy has no good support for linear algebra. This diag class implements simple diagonal object without numpy subclassing (but without much features). It seems that proper subclassing numpy and overloading matmul is a very difficult problem.
-
diagonal
()¶
-
shape
¶
-
check_type
(other)¶
-
-
class
smrt_matrix
(mat, mtype=None)¶ Bases:
object
SMRT uses two formats of matrix: one most suitable to implement emmodel where equations are different for each polarization and another one suitable for DORT computation where stream and polarization are collapsed in one dimension to allow matrix operation. In addition, the reflection and transmission matrix are often diagonal matrix, which needs to be handled because it saves space and allow much faster operations. This class implemented all these features.
-
static
empty
(dims, mtype=None)¶
-
static
zeros
(dims, mtype=None)¶
-
static
ones
(dims, mtype=None)¶
-
static
full
(dims, value, mtype=None)¶
-
npol
¶
-
is_equal_zero
()¶
-
compress
(mode=None, auto_reduce_npol=False)¶ compress a matrix. This comprises several actions: 1) select one mode, if relevant (dense5, and diagonal5). 2) reduce the number of polarization from 3 to 2 if mode==0 and auto_reduce_npol=True. 3) convert the format of the matrix to compressed numpy, involving a change of the dimension order (pola and streams are merged).
-
diagonal
¶
-
sel
(**kwargs)¶
-
static
-
is_zero_scalar
(m)¶
-
is_equal_zero
(m)¶ return true if the smrt matrix is null
-
generic_ft_even_matrix
(phase_function, m_max, nsamples=None)¶ Calculation of the Fourier decomposed of the phase or reflection or transmission matrix provided by the function.
This method calculates the Fourier decomposition modes and return the output.
Coefficients within the phase function are
Passive case (m = 0 only) and active (m = 0)
M = [Pvvp Pvhp] [Phvp Phhp]
Active case (m > 0):
M = [Pvvp Pvhp Pvup] [Phvp Phhp Phup] [Puvp Puhp Puup]
Parameters: - phase_function – must be a function taking dphi as input. It is assumed that phi is symmetrical (it is in cos(phi))
- m_max – maximum Fourier decomposition mode needed
-
set_max_numerical_threads
(nthreads)¶ set the maximum number of threads for a few known library. This is useful to disable parallel computing in SMRT when using parallel computing to call multiple // SMRT runs. This avoid over-committing the CPUs and results in much better performance. Inspire from joblib.
-
cached_roots_legendre
(n)¶ Cache roots_legendre results to speed up calls of the fixed_quad function.
smrt.core.model module¶
A model in SMRT is composed of the electromagnetic scattering theory (smrt.emmodel
) and
the radiative transfer solver (smrt.rtsolver
).
The smrt.emmodel
is responsible for computation of the scattering and absorption coefficients and the phase function of a layer.
It is applied to each layer and it is even possible
to choose different emmodel for each layer (for instance for a complex medium made of different materials: snow, soil, water, atmosphere, …).
The smrt.rtsolver
is responsible for propagation of the incident or emitted energy through the layers, up to the surface, and eventually
through the atmosphere.
To build a model, use the make_model()
function with the type of emmodel and type of rtsolver as arguments.
Then call the Model.run()
method of the model instance by specifying the sensor (smrt.core.sensor.Sensor
),
snowpack (smrt.core.snowpack.Snowpack
) and optionally atmosphere (see smrt.atmosphere
).
The results are returned as a Result
which can then been interrogated to retrieve brightness temperature,
backscattering coefficient, etc.
Example:
m = make_model("iba", "rtsolver")
result = m.run(sensor, snowpack) # sensor and snowpack are created before
print(result.TbV())
The model can be run on a list of snowpacks or even more conveniently on a pandas.Series or pandas.DataFrame including snowpacks.
The first advantage is that by setting parallel_computation=True, the Model.run()
method performs the simulation in parallel
on all the available cores of your machine and even possibly remotely on a high performance cluster using dask. The second advantage is that the returnedResult
object contains all the simulations and provide an easier way to plot the results or compute statistics.
- If a list of snowpacks is provided, it is recommended to also set the snowpack_dimension argument. It takes the form of a tuple
- (list of snowpack_dimension values, dimension name). The name and values are used to define the coordinates in the
Result
object. This is useful with timeseries or sensitivity analysis for instance.
Example:
snowpacks = []
times = []
for file in filenames:
# create a snowpack for each time series
sp = ...
snowpacks.append(sp)
times.append(sp)
# now run the model
res = m.run(sensor, snowpacks, snowpack_dimension=('time', times))
The res variable has now a coordinate time and res.TbV() returns a timeseries.
Using pandas.Series offers an even more elegant way to run SMRT and assemble the results of all the simulations.
thickness_list = np.arange(0, 10, 1) snowpacks = pd.Series([make_snowpack(thickness=t, ……..) for t in thickness_list], index=thickness_list) # snowpacks is a pandas Series of snowpack objects with the thickness as index
# now run the model
res = m.run(sensor, snowpacks, parallel_computation=True)
# convert the result into a datframe res = res.to_dataframe()
The res variable is a dataframe with the thickness as index and the channels of the sensor as column.
Using pandas.DataFrame is similar. One column must contain Snowpack objects (see snowpack_column argument).
The results of the simulations are automatically joined with this dataframe and returned by
to_dataframe()
or to_dataframe()
.
# df is a DataFrame with several parameters in each row.
# add a snowpack object for each row df[‘snowpack’] = [make_snowpack(thickness=row[‘thickness’], ……..) for i, row in df.iterrows()]]
# now run the model res = m.run(sensor, snowpacks, parallel_computation=True)
# convert the result into a datframe res = res.to_dataframe()
The res variable is a pandas.DataFrame equal to df + the results at all sensor’s channel added.
-
make_model
(emmodel, rtsolver=None, emmodel_options=None, rtsolver_options=None, emmodel_kwargs=None, rtsolver_kwargs=None)¶ create a new model with a given EM model and RT solver. The model is then ready to be run using the
Model.run()
method. This function is the privileged way to create models compared to class instantiation. It supports automatic import of the emmodel and rtsolver modules.Parameters: emmodel – type of emmodel to use. Can be given by the name of a file/module in the emmodel directory (as a string) or a class. List (and dict, respectively) can be provided when a different emmodel is needed for every layer (or every kind of layer medium). :type emmodel: string or class or list of strings or classes or dict of strings or classes. If a list of emmodels is given, the size must be the same as the number of layers in the snowpack. If a dict is given, the keys are the kinds of medium and the values are the associated emmodels to each sort of medium. The layer attribute ‘medium’ is used to determine the emmodel to use for each layer. :type emmodel: string or class; or list of strings or classes; or dict of strings or classes. :param rtsolver: type of RT solver to use. Can be given by the name of a file/module in the rtsolver directeory (as a string) or a class. :type rtsolver: string or class. Can be None when only computation of the layer electromagnetic properties is needed. :param emmodel_options: extra arguments to use to create emmodel instance. Valid arguments depend on the selected emmodel. It is documented in for each emmodel class. :type emmodel_options: dict or a list of dict. In the latter case, the size of the list must be the same as the number of layers in the snowpack. :param rtsolver_options: extra to use to create the rtsolver instance (see __init__ of the solver used). :type rtsolver_options: dict
Returns: a model instance
-
get_emmodel
(emmodel)¶ get a new emmodel class from the file name
-
make_emmodel
(emmodel, sensor, layer, **emmodel_options)¶ create a new emmodel instance based on the emmodel class or string :param emmodel: type of emmodel to use. Can be given by the name of a file/module in the emmodel directory (as a string) or a class. :param sensor: sensor to use for the calculation. :param layer: layer to use for the calculation
-
class
Model
(emmodel, rtsolver, emmodel_options=None, rtsolver_options=None)¶ Bases:
object
This class drives the whole calculation
-
set_rtsolver_options
(options=None, **kwargs)¶ set the option for the rtsolver
-
set_emmodel_options
(options=None, **kwargs)¶ set the options for the emmodel
-
run
(sensor, snowpack, atmosphere=None, snowpack_dimension=None, snowpack_column='snowpack', progressbar=False, parallel_computation=False, runner=None)¶ Run the model for the given sensor configuration and return the results
Parameters: - sensor – sensor to use for the calculation. Can be a list of the same size as the snowpack list. In this case, the computation is performed for each pair (sensor, snowpack).
- snowpack – snowpack to use for the calculation. Can be a single snowpack, a list of snowpack, a dict of snowpack or a SensitivityStudy object.
- snowpack_dimension – name and values (as a tuple) of the dimension to create for the results when a list of snowpack is provided. E.g. time, point, longitude, latitude. By default the dimension is called ‘snowpack’ and the values are rom 1 to the number of snowpacks.
- snowpack_column – when snowpack is a DataFrame this argument is used to specify which column contians the Snowpack objects
- progressbar – if True, display a progress bar during multi-snowpacks computation
- parallel_computation – if True, use the joblib library to run the simulation in parallel. Otherwise, the simulations are run sequentially. See ‘runner’ arguments.
- runner – a ‘runner’ is a function (or more likely a class with a __call__ method) that takes a function and a list/generator of simulations, executes the function on each simulation and returns a list of results. ‘parallel_computation’ allows to select between two default (basic) runners (sequential and joblib). Use ‘runner’ for more advanced parallel distributed computations.
Returns: result of the calculation(s) as a
Results
instance
-
prepare_simulations
(sensor, snowpack, snowpack_dimension, snowpack_column)¶
-
prepare_emmodels
(sensor, snowpack)¶
-
run_single_simulation
(simulation, atmosphere)¶
-
run_later
(sensor, snowpack, **kwargs)¶
-
-
class
SequentialRunner
(progressbar=False)¶ Bases:
object
Run the simulations sequentially on a single (local) core. This is the most simple way to run smrt simulations, but the efficiency is poor.
-
class
JoblibParallelRunner
(backend='loky', n_jobs=-1, max_numerical_threads=1)¶ Bases:
object
Run the simulations on the local machine on all the cores, using the joblib library for parallelism.
smrt.core.optional_numba module¶
smrt.core.plugin module¶
-
register_package
(pkg)¶
-
import_class
¶ Import the modulename and return either the class named “classname” or the first class defined in the module if classname is None.
Parameters: - scope – scope where to search for the module.
- modulename – name of the module to load.
- classname – name of the class to read from the module.
-
do_import_class
(modulename, classname)¶
smrt.core.progressbar module¶
A progress bar copied and adapted from pyMC code (dec 2014)
-
class
TextProgressBar
(iterations, printer, width=40, interval=None)¶ Bases:
smrt.core.progressbar.ProgressBar
Use
Progress
-
animate
(i, dummy=None)¶
-
progbar
(i)¶
-
bar
(percent)¶
-
-
progress_bar
(iters, interval=None)¶ A progress bar for Python/IPython/IPython notebook
Parameters: - iters (int) – number of iterations (steps in the loop)
- interval – number of intervals to use to update the progress bar (20 by default)
from easydev import progress_bar pb = progress_bar(10) for i in range(1,10): import time time.sleep(0.1) pb.animate(i)
smrt.core.result module¶
The results of RT Solver are hold by the Result
class. This class provides several functions
to access to the Stokes Vector and Muller matrix in a simple way. Most notable ones are Result.TbV()
and Result.TbH()
for the passive mode calculations and Result.sigmaHH()
and Result.sigmaVV()
. Result.to_dataframe()
is also
very convenient for the sensors with a channel map (all specific satellite sensors have such a map,
only generic sensors as smrt.sensor_list.active()
and smrt.sensor_list.passive()
does not provide a map by default).
In addition, the RT Solver stores some information in Result.other_data. Currently this includes the effective_permittivity, ks and ka for each layer. The data are accessed directly with e.g. result.other_data[‘ks’].
To save results of calculations in a file, simply use the pickle module or other serialization schemes. We may provide a unified and inter-operable solution in the future.
Under the hood, Result
uses xarray module which provides multi-dimensional array with explicit, named, dimensions. Here the
common dimensions are frequency, polarization, polarization_inc, theta_inc, theta, and phi. They are created by the RT Solver. The interest
of using named dimension is that slice of the xarray (i.e. results) can be selected based on the dimension name whereas with numpy the order of the dimensions matters. Because this is very convenient, users may be interested in adding other dimensions specific to their context such
as time, longitude, latitude, points, … To do so,smrt.core.model.Model.run()
accepts a list of snowpack and optionally the parameter snowpack_dimension is used to specify the name and values of the new dimension to build.
Example:
times = [datetime(2012, 1, 1), datetime(2012, 1, 5), , datetime(2012, 1, 10)]
snowpacks = [snowpack_1jan, snowpack_5jan, snowpack_10jan]
res = model.run(sensor, snowpacks, snowpack_dimension=('time', times))
The res variable is a Result
instance, so that for all the methods of this class that can be called, they will return a timeseries.
For instance result.TbV(theta=53) returns a time-series of brightness temperature at V polarization and 53° incidence angle and the following code
plots this timeseries:
plot(times, result.TbV(theta=53))
-
open_result
(filename)¶ read a result save to disk. See
Result.save()
method.
-
make_result
(sensor, *args, **kwargs)¶ create an active or passive result object according to the mode
-
class
Result
(intensity, coords=None, channel_map=None, other_data={}, mother_df=None)¶ Bases:
object
Contains the results of a/many computations and provides convenience functions to access these results
-
coords
¶ Return the coordinates of the result (theta, frequency, …). Note that the coordinates are also result attribute, so result.frequency works (and so on for all the coordinates).
-
save
(filename)¶ save a result to disk. Under the hood, this is a netCDF file produced by xarray (http://xarray.pydata.org/en/stable/io.html).
-
sel_data
(channel=None, **kwargs)¶
-
return_as_dataframe
(name, channel_axis=None, **kwargs)¶
-
to_series
(**kwargs)¶ return the result as a series with the channels defined in the sensor as index. This requires that the sensor has declared a channel list.
-
-
class
PassiveResult
(intensity, coords=None, channel_map=None, other_data={}, mother_df=None)¶ Bases:
smrt.core.result.Result
-
mode
= 'P'¶
-
sel_data
(channel=None, **kwargs)¶
-
Tb
(channel=None, **kwargs)¶ Return brightness temperature. Any parameter can be added to slice the results (e.g. frequency=37e9 or polarization=’V’). See xarray slicing with sel method (to document). It is also posisble to select by channel if the sensor has a channel_map.
Parameters: - channel – channel to select
- **kwargs –
any parameter to slice the results.
-
Tb_as_dataframe
(channel_axis=None, **kwargs)¶ See
PassiveResult()
.to_dataframe
-
to_dataframe
(channel_axis='auto', **kwargs)¶ Return brightness temperature as a pandas.DataFrame. Any parameter can be added to slice the results (e.g. frequency=37e9 or polarization=’V’). See xarray slicing with sel method (to document). In addition channel_axis controls the format of the output. If set to None, the DataFrame has a multi-index with all the dimensions (frequency, polarization, …). If channel_axis is set to “column”, and if the sensor has a channel map, the channels are in columns and the other dimensions are in index. If set to “index”, the channel are in index with all the other dimensions.
The most conviennent is probably channel_axis=”column” while channel_axis=None (default) contains all the data even those not corresponding to a channel and applies to any sensor even those without channel_map. If set to “auto”, the channel_axis is “column” if the channel map exit, otherwise is None.
Parameters: channel_axis – controls whether to use the sensor channel or not and if yes, as a column or index.
-
TbV
(**kwargs)¶ Return V polarization. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
TbH
(**kwargs)¶ Return H polarization. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
polarization_ratio
(ratio='H_V', **kwargs)¶ Return polarization ratio. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
-
class
ActiveResult
(intensity, coords=None, channel_map=None, other_data={}, mother_df=None)¶ Bases:
smrt.core.result.Result
-
mode
= 'A'¶
-
sel_data
(channel=None, return_backscatter=False, **kwargs)¶
-
sigma
(channel=None, **kwargs)¶ Return backscattering coefficient. Any parameter can be added to slice the results (e.g. frequency=37e9 or polarization=’V’). See xarray slicing with sel method (to document). It is also posisble to select by channel if the sensor has a channel_map.
Parameters: - channel – channel to select
- **kwargs –
any parameter to slice the results.
-
sigma_dB
(channel=None, **kwargs)¶ Return backscattering coefficient. Any parameter can be added to slice the results (e.g. frequency=37e9, polarization_inc=’V’, polarization=’V’). See xarray slicing with sel method (to document)
-
sigma_as_dataframe
(channel_axis=None, **kwargs)¶ Return backscattering coefficient as a pandas.DataFrame. Any parameter can be added to slice the results (e.g. frequency=37e9 or polarization=’V’). See xarray slicing with sel method (to document). In addition channel_axis controls the format of the output. If set to None, the DataFrame has a multi-index formed with all the dimensions (frequency, polarization, …). If channel_axis is set to “column”, and if the sensor has named channels (channel_map in SMRT wording), the channel are in columns and the other dimensions are in index. If set to “index”, the channel are in index with all the other dimensions.
The most conviennent is probably channel_axis=”column” while channel_axis=None (default) contains all the data even those not corresponding to a channel and applies to any sensor even those without channel_map.
Parameters: channel_axis – controls whether to use the sensor channel or not and if yes, as a column or index.
-
sigma_dB_as_dataframe
(channel_axis=None, **kwargs)¶ See
ActiveResult()
.to_dataframe
-
to_dataframe
(channel_axis=None, **kwargs)¶ Return backscattering coefficient in dB as a pandas.DataFrame. Any parameter can be added to slice the results (e.g. frequency=37e9 or polarization=’V’). See xarray slicing with sel method (to document). In addition channel_axis controls the format of the output. If set to None, the DataFrame has a multi-index with all the dimensions (frequency, polarization, …). If channel_axis is set to “column”, and if the sensor has named channels (channel_map in SMRT wording), the channel are in columns and the other dimensions are in index. If set to “index”, the channel are in index with all the other dimensions.
If channel_axis is set to “column”, and if the sensor has a channel map, the channels are in columns and the other dimensions are in index. If set to “index”, the channel are in index with all the other dimensions.
The most conviennent is probably channel_axis=”column” while channel_axis=None (default) contains all the data even those not corresponding to a channel and applies to any sensor even those without channel_map. If set to “auto”, the channel_axis is “column” if the channel map exit, otherwise is None.
Parameters: channel_axis – controls whether to use the sensor channel or not and if yes, as a column or index.
-
to_series
(**kwargs)¶ return backscattering coefficients in dB as a series with the channels defined in the sensor as index. This requires that the sensor has declared a channel list.
-
sigmaVV
(**kwargs)¶ Return VV backscattering coefficient. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
sigmaVV_dB
(**kwargs)¶ Return VV backscattering coefficient in dB. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
sigmaHH
(**kwargs)¶ Return HH backscattering coefficient. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
sigmaHH_dB
(**kwargs)¶ Return HH backscattering coefficient in dB. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
sigmaHV
(**kwargs)¶ Return HV backscattering coefficient. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
sigmaHV_dB
(**kwargs)¶ Return HV backscattering coefficient in dB. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
sigmaVH
(**kwargs)¶ Return VH backscattering coefficient. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
sigmaVH_dB
(**kwargs)¶ Return VH backscattering coefficient in dB. Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method (to document)
-
-
concat_results
(result_list, coord)¶ Concatenate several results from
smrt.core.model.Model.run()
(of typeResult
) into a single result (of typeResult
). This extends the number of dimension in the xarray hold by the instance. The new dimension is specified with coordParameters: - result_list – list of results returned by
smrt.core.model.Model.run()
or other functions. - coord – a tuple (dimension_name, dimension_values) for the new dimension. Dimension_values must be a sequence or
array with the same length as result_list.
Returns: Result
instance- result_list – list of results returned by
smrt.core.run_promise module¶
-
honour_all_promises
(directory_or_filename, save_result_to=None, show_progress=True, force_compute=True)¶ Honour many promises and save the results
Parameters: - directory_or_filename – can be a directory, a filename or a list of them
- save_result_to – directory where to save the results. If None, the results are not saved. The results are always returned as a list by this function.
- show_progress – print progress of the calculation.
- force_computate – If False and if a result or lock file is present, the computation is skipped. The order of promise processing is randomized to allow more efficient parallel computation using many calls of this function on the same directory. A lock file is used between the start of a computation and writting the result in order to prevent from running several times the same computation. If the process is interupted (e.g. walltime on clusters), the lock file may persist and prevent any future computation. In this case, lock files must be manually deleted. IF False, the save_result_to argument must be set to a valid directory where the results.
-
honour_promise
(filename, save_result_to=None, force_compute=True)¶ Honour a promise and optionally save the result.
Parameters: - filename – file name of the promise
- save_result_to – directory where to save the result.
- force_compute – see honour_all_promise.
-
load_promise
(filename)¶
smrt.core.sensitivity_study module¶
SensitivityStudy is used to easily conduct sensitivity studies.
Example:
times = [datetime(2012, 1, 1), datetime(2012, 1, 5), , datetime(2012, 1, 10)]
snowpacks = SensitivityStudy("time", times, [snowpack_1jan, snowpack_5jan, snowpack_10jan])
res = model.run(sensor, snowpacks)
The res variable is a Result
instance, so that for all the methods of this class that can be called, they will return a timeseries.
For instance result.TbV(theta=53) returns a time-series of brightness temperature at V polarization and 53° incidence angle and the following code
plots this timeseries:
plot(times, result.TbV(theta=53))
-
class
SensitivityStudy
(name, values, snowpacks)¶ Bases:
object
-
sensitivity_study
(name, values, snowpacks)¶ create a sensitivity study
Parameters: - name – name of the variable to investigate
- values – values taken by the variable
- snowpacks – list of snowpacks. Can be a sequence or a function that takes one argument and return a snowpack.
In the latter case, the function is called for each values to build the list of snowpacks
smrt.core.sensor module¶
The sensor configuration includes all the information describing the sensor viewing geometry (incidence, …)
and operating parameters (frequency, polarization, …). The easiest and recommended way to create a Sensor
instance is
to use one of the convenience functions such as passive()
, active()
, amsre()
, etc.
Adding a function for a new or unlisted sensor can be done in sensor_list
if the sensor is common and of general interest.
Otherwise, we recommend to add these functions in your own files (outside of smrt directories).
-
passive
(frequency, theta, polarization=None, channel_map=None, name=None)¶ Generic configuration for passive microwave sensor.
Return a
Sensor
for a microwave radiometer with given frequency, incidence angle and polarizationParameters: - frequency – frequency in Hz
- theta – viewing angle or list of viewing angles in degrees from vertical. Note that some RT solvers compute all viewing angles whatever this configuration because it is internally needed part of the multiple scattering calculation. It it therefore often more efficient to call the model once with many viewing angles instead of calling it many times with a single angle.
- polarization (list of characters) – H and/or V polarizations. Both polarizations is the default. Note that most RT solvers compute all the polarizations whatever this configuration because the polarizations are coupled in the RT equation.
- channel_map (dict) – map channel names (keys) to configuration (values). A configuration is a dict with frequency, polarization and other such parameters to be used by Result to select the results.
- name (string) – name of the sensor
Returns: Sensor
instanceUsage example:
from smrt import sensor_list radiometer = sensor_list.passive(18e9, 50) radiometer = sensor_list.passive(18e9, 50, "V") radiometer = sensor_list.passive([18e9,36.5e9], [50,55], ["V","H"])
-
channel_map_for_radar
(frequency=None, polarization='HV', order='fp')¶ return a channel_map to convert channel name to frequency and polarization. This function assumes the frequency is coded as a two-digit number in GHz with leading 0 if necessary. The polarization is after the frequency if order is ‘fp’ and before if order is ‘pf’.
-
active
(frequency, theta_inc, theta=None, phi=None, polarization_inc=None, polarization=None, channel_map=None, name=None)¶ Configuration for active microwave sensor.
Return a
Sensor
for a radar with given frequency, incidence and viewing angles and polarizationIf polarizations are not specified, quad-pol is the default (VV, VH, HV and HH). If the angle of incident radiation is not specified, backscatter will be simulated
Parameters: - frequency – frequency in Hz
- theta_inc – incident angle in degrees from the vertical
- theta – viewing zenith angle in degrees from the vertical. By default, it is equal to theta_inc which corresponds to the backscatter direction
- phi – viewing azimuth angle in degrees from the incident direction. By default, it is pi which corresponds to the backscatter direction
- polarization_inc (list of 1-character strings) – list of polarizations of the incidence wave (‘H’ or ‘V’ or both.)
- polarization (list of 1-character strings) – list of viewing polarizations (‘H’ or ‘V’ or both)
- channel_map (dict) – map channel names (keys) to configuration (values). A configuration is a dict with frequency, polarization and other such parameters to be used by Result to select the results.
- name (string) – name of the sensor
Returns: Sensor
instanceUsage example:
from smrt import sensor_list scatterometer = sensor_list.active(frequency=18e9, theta_inc=50) scatterometer = sensor_list.active(18e9, 50, 50, 0, "V", "V") scatterometer = sensor_list.active([18e9,36.5e9], theta=50, theta_inc=50, polarization_inc=["V", "H"], polarization=["V", "H"])
-
altimeter
(channel, **kwargs)¶
-
make_multi_channel_altimeter
(config, channel)¶
-
class
SensorBase
¶ Bases:
object
-
class
Sensor
(frequency=None, theta_inc_deg=None, theta_deg=None, phi_deg=None, polarization_inc=None, polarization=None, channel_map=None, name=None, wavelength=None)¶ Bases:
smrt.core.sensor.SensorBase
Configuration for sensor. Use of the functions
passive()
,active()
, or the sensor specific functions e.g.amsre()
are recommended to access this class.-
wavelength
¶
-
wavenumber
¶
-
mode
¶ returns the mode of observation: “A” for active or “P” for passive.
-
basic_checks
()¶
-
configurations
()¶
-
iterate
(axis)¶ Iterate over the configuration for the given axis.
Parameters: axis – one of the attribute of the sensor (frequency, …) to iterate along
-
-
class
SensorList
(sensor_list, axis='channel')¶ Bases:
smrt.core.sensor.SensorBase
-
channel
¶
-
frequency
¶
-
configurations
()¶
-
iterate
(axis=None)¶
-
-
class
Altimeter
(frequency, altitude, beamwidth, pulse_bandwidth, sigma_p=None, off_nadir_angle=0, beam_asymmetry=0, ngate=1024, nominal_gate=40, theta_inc_deg=0.0, polarization_inc=None, polarization=None, channel=None)¶ Bases:
smrt.core.sensor.Sensor
Configuration for altimeter. Use of the functions
altimeter()
, or the sensor specific functions e.g.envisat_ra2()
are recommended to access this class.
smrt.core.snowpack module¶
Snowpack
instance contains the description of the snowpack, including a list of layers and interfaces between the layers, and the substrate (soil, ice, …).
To create a snowpack, it is recommended to use the make_snowpack()
function which avoids the complexity of creating
each layer and then the snowpack from the layers. For more complex media (like lake ice or sea ice), it may be necessary to directly call the functions
to create the different layers (such as make_snow_layer()
).
Example:
# create a 10-m thick snowpack with a single layer,
# density is 350 kg/m3. The exponential autocorrelation function is
# used to describe the snow and the "size" parameter is therefore
# the correlation length which is given as an optional
# argument of this function (but is required in practice)
sp = make_snowpack([10], "exponential", [350], corr_length=[3e-3])
-
class
Snowpack
(layers=None, interfaces=None, substrate=None, atmosphere=None)¶ Bases:
object
holds the description of the snowpack, including the layers, interfaces, and the substrate
-
nlayer
¶ return the number of layers
-
layer_thicknesses
¶ return the thickness of each layer
-
layer_depths
¶ return the depth of the bottom of each layer
-
bottom_layer_depths
¶ return the depth of the bottom of each layer
-
top_layer_depths
¶ return the depth of the bottom of each layer
-
mid_layer_depths
¶ return the depth of the bottom of each layer
-
z
¶ return the depth of each interface, that is, 0 and the depth of the bottom of each layer
-
layer_densities
¶ return the density of each layer
-
profile
(property_name, where='all', raise_attributeerror=False)¶ return the vertical profile of property_name. The property is searched either in the layer, microstructure or interface.
Parameters: - property_name – name of the property
- where – where to search the property. Can be ‘all’, ‘layer’, ‘microstructure’, or ‘interface’
- raise_attributeerror – raise an attribute error if the attribute is not found
-
append
(layer, interface=None)¶ append a new layer at the bottom of the stack of layers. The interface is that at the top of the appended layer.
Parameters: - layer – instance of
Layer
- interface – type of interface. By default, flat surface (
Flat
) is considered meaning the coefficients are calculated with Fresnel coefficient and using the effective permittivity of the surrounding layers
- layer – instance of
-
delete
(ilayer)¶ delete a layer and the upper interface
Parameters: ilayer – index of the layer
-
copy
()¶ make a shallow copy of a snowpack by copying the list of layers and interfaces but not the layers and interfaces themselves which are still shared with the original snowpack. This method allows the user to create a new snowpack and remove, append or replace some layers or interfaces afterward. It does not allow to alter the layers or interfaces without changing the original snowpack. See py:meth:~deepcopy.
-
deepcopy
()¶ make a deep copy of a snowpack.
-
basic_check
()¶
-
check_addition_validity
(other)¶
-
update_layer_number
()¶
-
to_dataframe
(default_columns=True, other_columns=None)¶
-
smrt.core.test_globalconstants module¶
-
test_density_of_ice
()¶
-
test_freezing_point
()¶
-
test_permittivity_of_air
()¶
-
test_speed_of_light
()¶
smrt.core.test_lib module¶
-
setup_func_sp
()¶
-
setup_func_em
(testpack=None)¶
-
test_generic_ft_even_matrix
()¶
smrt.core.test_result module¶
-
test_methods
()¶
-
test_positive_sigmaVV
()¶
-
test_positive_sigmaVH
()¶
-
test_positive_sigmaHV
()¶
-
test_positive_sigmaHH
()¶
-
test_sigma_dB
()¶
-
test_sigma_dB_as_dataframe
()¶
-
test_to_dataframe_with_channel_axis_on_column
()¶
-
test_to_dataframe_without_channel_axis
()¶
-
test_return_as_series
()¶
-
test_concat_results
()¶
-
test_concat_results_other_data
()¶
smrt.core.test_sensor module¶
-
test_iterate
()¶
-
test_wavelength
()¶
-
test_no_theta
()¶
-
test_passive_wrong_frequency_units_warning
()¶
-
test_duplicate_theta
()¶
-
test_duplicate_theta_active
()¶
-
test_passive_mode
()¶
-
test_active_wrong_frequency_units_warning
()¶
-
test_active_mode
()¶
smrt.core.test_snowpack module¶
-
test_profile
()¶
-
create_two_snowpacks
()¶
-
test_addition
()¶
-
test_layer_addition
()¶
-
test_inplace_addition
()¶
-
test_inplace_layer_addition
()¶
-
test_substrate_addition
()¶
-
test_atmosphere_addition
()¶
-
test_atmosphere_addition_double_snowpack
()¶
-
test_invalid_addition_atmosphere
()¶
-
test_invalid_addition_atmosphere2
()¶
-
test_invalid_addition_substrate
()¶
-
test_invalid_addition_substrate2
()¶
Module contents¶
The core
package contains the SMRT machinery. It provides the infrastructure that provides basic objects and orchestrates the “science” modules in the
other packages (such as smrt.emmodel
or smrt.rtsolver
).
Amongst all, we suggest looking at the documentation of the Result
object.
For developers
We strongly warn against changing anything in this directory. In principle this is not needed because no “science” is present and most objects and functions are generic enough to be extendable from outside (without affecting the core definition). Ask advice from the authors if you really want to change something here.
smrt.utils package¶
Submodules¶
smrt.utils.dmrt_qms_legacy module¶
Wrapper to the original DMRT_QMS matlab code using the SMRT framework. To use this module, extra installation are needed:
- get DMRT_QMS from http://web.eecs.umich.edu/~leutsang/Available%20Resources.html and extract the model somewhere
- install the oct2py module using
pip install oct2py
oreasy_install install oct2py
- install Octave version 3.6 or above.
- for convenience you can set the DMRT_QMS_DIR environment variable to point to DMRT-QMS path. This path can also be programmatically set with and use
set_dmrt_qms_path()
function.
In case of problem check the instructions given in http://blink1073.github.io/oct2py/source/installation.html
You may also want to increase the number of streams in passive/DMRT_QMS_passive.m
-
set_dmrt_qms_path
(path)¶ set the path where dmrt_qms archive has been uncompressed, i.e. where the file dmrt_qmsmain.m is located.
-
run
(sensor, snowpack, dmrt_qms_path=None, snowpack_dimension=None, full_output=False)¶ call DMRT-QMS for the snowpack and sensor configuration given as argument. The
sticky_hard_spheres
microstructure model must be used.Parameters: - snowpack – describe the snowpack.
- sensor – describe the sensor configuration.
- full_output – determine if ks, ka and effective permittivity are return in addition to the result object
-
dmrt_qms_active
(sensor, snowpack)¶
-
dmrt_qms_emmodel
(sensor, layer, dmrt_qms_path=None)¶ Compute scattering and absorption coefficients using DMRT QMS
Parameters: - layer – describe the layer.
- sensor – describe the sensor configuration.
smrt.utils.hut_legacy module¶
Wrapper to original HUT matlab using SMRT framework. To use this module, extra installation are needed:
- get HUT. Decompress the archive somewhere on your disk.
- in the file snowemis_nlayers change the 6 occurences of the “do” variable into “dos” because it causes a syntax error in Octave.
- install the oct2py module using
pip install oct2py
oreasy_install install oct2py
. - install Octave version 3.6 or above.
- for convenience you can set the HUT_DIR environment variable to point to HUT path. This path can also be programmatically set with
set_hut_path()
.
In case of problem check the instructions given in http://blink1073.github.io/oct2py/source/installation.html
-
set_hut_path
(path)¶ set the path where MEMLS archive has been uncompressed, i.e. where the file memlsmain.m is located.
-
run
(sensor, snowpack, ke_option=0, grainsize_option=1, hut_path=None)¶ call HUT for the snowpack and sensor configuration given as argument. Any microstructure model that defines the “radius” parameter is valid.
Parameters: - snowpack – describe the snowpack.
- sensor – describe the sensor configuration.
- ke_option – see HUT snowemis_nlayers.m code
- grainsize_option – see HUT snowemis_nlayers.m code
smrt.utils.memls_legacy module¶
Wrapper to the original MEMLS matlab code using the SMRT framework. To use this module, extra installation are needed:
- download MEMLS from http://www.iapmw.unibe.ch/research/projects/snowtools/memls.html. Decompress the archive somewhere on your disk.
- install the oct2py module using
pip install oct2py
oreasy_install install oct2py
- install Octave version 3.6 or above.
- for convenience you can set the MEMLS_DIR environment variable to point to MEMLS path. This path can also be programmatically set with
set_memls_path()
In case of problem check the instructions given in http://blink1073.github.io/oct2py/source/installation.html
-
set_memls_path
(path)¶ set the path where MEMLS archive has been uncompressed, i.e. where the file memlsmain.m is located.
-
run
(sensor, snowpack, scattering_choice=12, atmosphere=None, memls_path=None, memls_driver=None, snowpack_dimension=None)¶ call MEMLS for the snowpack and sensor configuration given as argument. Any microstructure model that defines the “corr_length” parameter is valid, but it must be clear that MEMLS only considers exponential autocorrelation.
Parameters: - snowpack – describe the snowpack.
- sensor – describe the sensor configuration.
- scattering_choice – MEMLS proposes several formulation to compute scattering_function. scattering_choice=ABORN (equals 12) is the default here and is recommended choice to compare with IBA. Note that some comments in memlsmain.m suggest to use scattering_choice=MEMLS_RECOMMENDED (equals 11). Note also that the default grain type in memlsmain is graintype=1 corresponding to oblate spheroidal calculation of effective permittivity from the empirical representation of depolarization factors. To use a Polder-Van Santen representation of effective permittivity for small spheres, graintype=2 must be set in your local copy of MEMLS.
- atmosphere – describe the atmosphere. Only tbdown is used for the Tsky argument of memlsmain.
- memls_path – directory path to the memls Matlab scripts
- memls_driver – matlab function to call to run memls. memlsmain.m is the default driver in the original MEMLS distribution for the passive case and amemlsmain.m for the active case.
- snowpack_dimension – name and values (as a tuple) of the dimension to create for the results when a list of snowpack is provided. E.g. time, point, longitude, latitude. By default the dimension is called ‘snowpack’ and the values are from 1 to the number of snowpacks.
-
memls_emmodel
(sensor, layer, scattering_choice=12, graintype=2)¶ Compute scattering (gs6) and absorption coefficients (gai) using MEMLS
Parameters: - layer – describe the layer.
- sensor – describe the sensor configuration.
- scattering_choice – MEMLS proposes several formulation to compute scattering_function. scattering_choice=ABORN (equals 12) is the defaut here and is recommended choice to compare with IBA.
smrt.utils.mpl_plots module¶
-
plot_snowpack
(sp, show_vars=None, show_shade=False, ax=None)¶
-
plot_streams
(sp, emmodel, sensor, ilayer=None, ax=None)¶
-
format_vars
(lay, show_vars, delimiter=' ')¶
-
class
ReciprocalScale
(axis)¶ Bases:
matplotlib.scale.LinearScale
-
name
= 'stickiness_reciprocal'¶
-
set_default_locators_and_formatters
(axis)¶ Set the locators and formatters of axis to instances suitable for this scale.
-
get_transform
()¶ Return the transform for linear scaling, which is just the ~matplotlib.transforms.IdentityTransform.
-
class
ReciprocalTransform
(shorthand_name=None)¶ Bases:
matplotlib.transforms.Transform
-
input_dims
= 1¶
-
output_dims
= 1¶
-
is_separable
= True¶
-
transform_non_affine
(a)¶ Apply only the non-affine part of this transformation.
transform(values)
is always equivalent totransform_affine(transform_non_affine(values))
.In non-affine transformations, this is generally equivalent to
transform(values)
. In affine transformations, this is always a no-op.- values : array
- The input values as NumPy array of length
input_dims
or shape (N xinput_dims
).
- array
- The output values as NumPy array of length
output_dims
or shape (N xoutput_dims
), depending on the input.
-
inverted
()¶ Return the corresponding inverse transformation.
It holds
x == self.inverted().transform(self.transform(x))
.The return value of this method should be treated as temporary. An update to self does not cause a corresponding update to its inverted copy.
-
has_inverse
= True¶
-
-
class
InvertedReciprocalTransform
(shorthand_name=None)¶ Bases:
matplotlib.transforms.Transform
-
input_dims
= 1¶
-
output_dims
= 1¶
-
is_separable
= True¶
-
transform_non_affine
(a)¶ Apply only the non-affine part of this transformation.
transform(values)
is always equivalent totransform_affine(transform_non_affine(values))
.In non-affine transformations, this is generally equivalent to
transform(values)
. In affine transformations, this is always a no-op.- values : array
- The input values as NumPy array of length
input_dims
or shape (N xinput_dims
).
- array
- The output values as NumPy array of length
output_dims
or shape (N xoutput_dims
), depending on the input.
-
inverted
()¶ Return the corresponding inverse transformation.
It holds
x == self.inverted().transform(self.transform(x))
.The return value of this method should be treated as temporary. An update to self does not cause a corresponding update to its inverted copy.
-
has_inverse
= True¶
-
-
smrt.utils.repo_tools module¶
General tools related to code repository
-
get_hg_rev
(file_path)¶ get_hg_rev is a tool to print out which commit of the model you are using.
This is useful when revisiting ipython notebooks, can be used to compare the original model commit ID with the latest version.
Usage:
from smrt.utils.repo_tools import get_hg_rev path_to_file = "/path/to/your/repository" get_hg_rev(path_to_file)
Note
This is for a mercurial repository
Module contents¶
This packages contain various utilities that works with/for SMRT.
The wrappers to legacy snow radiative transfer models can be used to run DMRT-QMS (passive mode), HUT and MEMLS (passive mode). Other tools are listed below.
-
dB
(x)¶ computes the ratio x in dB.
-
invdB
(x)¶ computes the dB value x in natural value.
Guidelines for Developers¶
At the moment this is an organic document to collect all the model design and developer style decisions. This will also include information on how to get started with useful developer tools. At the moment, it contains personal experience of installing and using these tools although these may be removed if they do not appear to be useful to others.
These guidelines will be turned into a formal document towards the end of the project.
Use of import statements¶
In short:
- use fully qualified names
from blabla import *
should never be used.from blabla import passive
should be avoided in SMRT but can be used in user code.- keep at least the module e.g. “from smrt import sensor_list” is the best compromise.
- use “as” with moderation and everyone should agree to use it.
- but
import numpy as np
is good. - to start, we will use an explicit import at the top of the driver file, making the code more cumbersome, but may later consider a plugin framework to do the import and introspection in a nice way.
Note: it’s part of the Google Python style guides that all imports must import a module, not a class or function from that module. There are way more classes and functions than there are modules, so recalling where a particular thing comes from is much easier if it is prefixed with a module name. Often multiple modules happen to define things with the same name – so a reader of the code doesn’t have to go back to the top of the file to see from which module a given name is imported.
Python¶
Python was chosen because of its growing use in the scientific community and higher flexibility than compiled legacy languages like FORTRAN. This enables the model to be modular much more easily, which is a main constraint of the project, allows faster development and an easier exploration of new ideas. The performance should not be an issue as the time consuming part of the model should be localized in the RT solver and numerical integrations which uses the highly optimized scipy module facility that basically uses BLAS, LAPACK and MINPACK libraries as would be done in FORTRAN. Compilation of the Python code with Numba or Pypy will be considered in case of performance issues later in the project or even more probably after. Parallelization could be done later e.g. through joblib module.
The model in the framework of the current project mainly aims at exploring new ideas involving the microstructure and tests various modelling solutions. It is quite likely that operational needs (especially very intensive ones) will require rewritting a selected subset of the model.
Python versions¶
The target version is Python 3.4+ which is better optimized and is the only supported version in the future (after 2020) with the use of a subset syntax to ensure compatibility with the lastest 2.7.x and PyPy. It means in practice that the model will be compatible with the last 2.7.x version but is “ready” for Python 3 and later. For this “__future__” directives and six module will be used. The tests must pass the two versions. This choice is overall a weak constraint for developers and big asset for users.
Anaconda is probably the easiest way to install python, especially when several versions are needed. See also Installing multiple versions of python is system dependent and also depends on your preferred install method.
Perhaps it’s not strictly necessary to follow all steps, but I followed these instructions for Mac OSX to install python 3.5. Then pip
installs
packages into python 2.7 and pip3
installs packages into python 3.5. Note on Tcl/Tk for Mac OSX. I have installed ActiveTcl 8.6.4 and am keeping my fingers crossed that these changes have not broken anything…I have subsequently installed python 3.4.3. This means that python3
will run version 3.4.3 by default. It doesn’t seem trivial to get python3
to point back to python 3.5, but that’s probably ok as the target version is 3.4, and it will be worth testing for 3.5 alongside.
tox: testing multiple python versions¶
The tox package allows multiple versions of python to be tested. Although not clear whether this needs to be installed in python 2 or 3, I installed with pip
rather than pip3
and trust that it will take care of everything. This seems to work fine.
The setup to run tox is contained in the tox.ini file. At the moment this is setup for nosetests against python versions 2.7, 3.4 and 3.5. Also, at present tox.ini does not require a setup.py to run. Once the model is fully operational the line skipsdist = True
should be deleted, or this parameter set to False. Note that all modules to be imported need to be listed in the dependencies (deps) in the tox.ini file. An ImportError may indicate that the module it is trying to import has not been included in the tox.ini.
To run the nosetests for all the different versions, using the installed tox package, simply type:
tox
If you want to test for only one python version, type e.g:
tox -e py27
setup.py¶
This is needed in order to build, install and distribute the model through Distutils (instructions). To be done for the public release.
bug correction¶
Every bug should result in writing a test.
Classes¶
If the compulsary argument list becomes too long (say 4?), use optional arguments to make things easier to read.
PEP008¶
Code must conform to PEP8 - with the exception that lines of up to 140 characters are allowed and extra space are allowed in long formula for readability. Particular points of note:
- 4 spaces for the indentation.
- one space after comma and around operators.
- all names (variable, function, …) are meaningful. Abbreviations are used in a very limited number of cases.
- function names are lowercase only and word a spaced by underscore.
- Constants are usually defined on a module level and written in all capital letters with underscores separating words
You can check for PEP8 compliance automatically with nosetests. To do this, install tissue and pep8. Then type:
nosetests --with-tissue --tissue-ignore=E501
or:
nosetests --with-tissue --tissue-ignore=E501 **specific filename**
to run nosetests with the pep8 checks. As we have allowed 140 characters per line, the E501 longer line warning needs to be suppressed.
Sphinx¶
Documentation is done in-code, and is automatically generated with Sphinx. If no new modules are added, generate the rst and html documentation from the in-code Sphinx comments, by typing (whilst in smrt/doc directory):
make fullhtml
The documentation can be accessed via the index.html page in the smrt/doc/build/html folder.
If you have math symbols to be displayed, this can be done with the imgmath extension (already used), which generates a png and inserts the image at the appropriate place. You may need to set the path to latex and dvipng on your system. From the source directory, this can be done with e.g.:
sphinx-build -b html -D imgmath_latex=/sw/bin/latex -D imgmath_dvipng=/sw/bin/dvipng . ../build/html
or to continue to use :make html
or make fullhtml
, by setting your path (C-shell) e.g.:
set path = ($path /sw/bin)
or bash:
PATH=$PATH:/sw/bin
Note
Math symbols will need double backslashes in place of the single backslash used in latex.
To generate a list of undocumented elements, whilst in the source directory:
sphinx-build -b coverage . coverage
The files will be listed in the coverage/python.txt file