smrt.core package

The core package contains the SMRT machinery. It provides the infrastructure that defines 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.core.result module

This module defines the Result class to hold the results of RT Solver calculations.

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.

Parameters:

filename – path to the file to read.

Returns:

the result object read from disk.

Return type:

Result

make_result(sensor, *args, **kwargs)

Create an active or passive result object according to the mode.

Parameters:
  • sensor – the sensor object used to create the result.

  • *args – arguments to be passed to the Result constructor.

  • **kwargs – keyword arguments to be passed to the Result constructor.

class Result(intensity, coords=None, channel_map=None, other_data={}, mother_df=None)

Bases: object

Contain the results of a/many computations and provides convenience functions to access these results.

property 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, netcdf_engine=None)

Save a result to disk.

Under the hood, this is a netCDF file produced by xarray (http://xarray.pydata.org/en/stable/io.html).

Parameters:
  • filename – The name of the file to save the result to.

  • netcdf_engine – The netCDF engine to use (optional).

return_as_dataframe(name, channel_axis=None, **kwargs)

Return the results as a dataframe

Parameters:
  • name – name of the dataframe

  • channel_axis – axis to use for the channels of the sensor. If set to “column”, the channels are in columns and the other dimensions are in rows. if set to “index”, the channels are in index with all the other dimensions.

Returns:

returns a dataframe

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.

optical_depth()

Return the optical depth of each layer tau = ke * thickness, where ke = ka + ks calculated for each layer.

This is useful to assess the e-folding depth (aka penetration depth), neglecting the layer transmittance.

For instance the direct incoming radiation (in active mode) or the radiation emanating directly (in passive mode) can be estimated as:

intensity = np.exp(-result.optical_depth().cumsum('layer'))
single_scattering_albedo()

Return the single scattering albedo of each layer: ssalb = ks / ke.

Single scattering albedo is useful to assess if multiple scattering is significant (e.g. if ssalb > 0.2). Note that ks and ke are averaged over the angle used for the calculation, use this single scattering albedo value with care.

single_scattering_albedo_using_absorption()

Return the single scattering albedo of each layer using the equation ssalb = ks / (ks + ka).

Single scattering albedo is useful to assess if multiple scattering is significant (e.g. if ssalb > 0.2).

This function uses absorption coefficient which may give different results compared to using the extinction coefficient if the energy conservation is not respected by the EM model (which is often the case unfortunately!)

class PassiveResult(intensity, coords=None, channel_map=None, other_data={}, mother_df=None)

Bases: Result

sel_data(channel=None, **kwargs)

Select data as xarray.DataArray.sel, and in addition by channel if a channel_map is defined.

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. It is also possible 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)

Return brightness temperature as a pandas.DataFrame.

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 convenient usage 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.

Parameters:

**kwargs – any parameter to slice the results.

TbH(**kwargs)

Return H polarization.

Any parameter can be added to slice the results (e.g. frequency=37e9). See xarray slicing with sel method.

Parameters:

**kwargs – any parameter to slice the results.

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.

Parameters:
  • **kwargs – any parameter to slice the results.

  • ratio – polarization ratio to compute, e.g. “H_V” or “V_H”.

class ActiveResult(intensity, coords=None, channel_map=None, other_data={}, mother_df=None)

Bases: Result

sel_data(channel=None, return_backscatter=False, **kwargs)

Select data as xarray.DataArray.sel, and in addition by channel if a channel_map is defined.

Parameters:
  • channel – channel to select

  • return_backscatter – If set to “dB”, return the backscattering coefficient in dB. If set to “natural”, return the backscattering coefficient sigma. if False (default), return the normal result (radiance or Stokes vector)

  • **kwargs – any parameter to slice the results.

Returns:

selected data

sigma(channel=None, name='sigma', **kwargs)

Return backscattering coefficient in natural values.

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

  • name – name inserted in the returned DataArray

  • **kwargs – any parameter to slice the results.

sigma_dB(name='sigma_dB', channel=None, **kwargs)

Return backscattering coefficient in dB.

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)

Parameters:
  • name – name inserted in the returned DataArray

  • channel – channel to select

  • **kwargs – any parameter to slice the results.

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 convenient usage 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.

  • **kwargs – any parameter to slice the results.

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 convenient usage 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.

Parameters:

**kwargs – any parameter to slice the results.

sigmaVV(name='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)

Parameters:
  • name – name inserted in the returned DataArray

  • **kwargs – any parameter to slice the results.

sigmaVV_dB(name='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)

Parameters:
  • name – name inserted in the returned DataArray

  • **kwargs – any parameter to slice the results.

sigmaHH(name='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.

Parameters:
  • name – name inserted in the returned DataArray

  • **kwargs – any parameter to slice the results.

sigmaHH_dB(name='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.

Parameters:
  • name – name inserted in the returned DataArray

  • **kwargs – any parameter to slice the results.

sigmaHV(name='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(name='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.

Parameters:
  • name – name inserted in the returned DataArray

  • **kwargs – any parameter to slice the results.

sigmaVH(name='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.

Parameters:
  • name – name inserted in the returned DataArray

  • **kwargs – any parameter to slice the results.

sigmaVH_dB(name='sigmaVH_dB', **kwargs)

Returns 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)

Parameters:
  • name – name inserted in the returned DataArray

  • **kwargs – any parameter to slice the results.

class AltimetryResult(intensity, coords=None, channel_map=None, other_data={}, mother_df=None)

Bases: ActiveResult

delay_doppler_map(name='delay_doppler_map', **kwargs)

Return the delay Doppler map

waveform(name='waveform', **kwargs)

Return the waveform.

For simulations with return_contributions, this function returns the total only by default. Use explicit contribution=”all”” to get all the contributions or contribution=’…’ to access each contribution.

Parameters:
  • name – name inserted in the returned DataArray

  • **kwargs – any dimension to select. See xarray.DataArray.sel.

contributions()

Return the list of the contribution dimension. Raise an exception if the contribution does not exist.

concat_results(result_list, coord)

Concatenate several results from smrt.core.model.Model.run() (of type Result) into a single result (of type Result).

This extends the number of dimension in the xarray hold by the instance. The new dimension is specified with coord

Parameters:
  • 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

  • result_list. (array with the same length as)

Returns:

Result instance

smrt.core.globalconstants module

This module defines 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.atmosphere module

class AtmosphereResult(tb_down: numpy.ndarray, tb_up: numpy.ndarray, transmittance: numpy.ndarray)

Bases: object

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, **kwargs)

Issue a SMRT warning with a standard message about disabling warnings.

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 results in (large) errors. Don’t use it. It is here for reference only. The returned reflection coefficients apply to the electric field. Use abs2(rv), abs2(rh) to obtain the power reflection coefficient.

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. The returned reflection coefficients apply to the electric field. Use abs2(rv), abs2(rh) to obtain the power reflection coefficient.

Parameters:
  • eps_1 – permittivity of medium 1.

  • eps_2 – permittivity of medium 2.

  • mu1 – cosine zenith angle in medium 1.

  • full_output – return full output (Default value = False).

Returns:

rv, rh, mu2 the cosine of the angle in medium 2

fresnel_coefficients_maezawa09_rigorous(eps_1, eps_2, mu1) tuple[complex, complex, float]

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 respects the energy conservation even for strongly loosly media. The returned reflection coefficients apply to the electric field. Use abs2(rv), abs2(rh) to obtain the power reflection coefficient.

This function only returns the FIELD reflection coefficients and the cosine angle in the medium 2

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_full_output(eps_1, eps_2, mu1)

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 respects the energy conservation even for strongly loosly media. The returned reflection coefficients apply to the electric field. Use abs2(rv), abs2(rh) to obtain the power reflection coefficient.

This function returns the FIELF and INTENSITY reflection and transmission coefficients and the cosine angle in the medium 2

Parameters:
  • eps_1 – permittivity of medium 1.

  • eps_2 – permittivity of medium 2.

  • mu1 – cosine zenith angle in medium 1.

  • full_output – return full output (Default value = False).

Returns:

rv, rh, mu2 the cosine of the angle in medium 2

fresnel_coefficients(eps_1, eps_2, mu1) tuple[complex, complex, float]

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 respects the energy conservation even for strongly loosly media. The returned reflection coefficients apply to the electric field. Use abs2(rv), abs2(rh) to obtain the power reflection coefficient.

This function only returns the FIELD reflection coefficients and the cosine angle in the medium 2

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.

Parameters:
  • eps_1 – permittivity of medium 1.

  • eps_2 – permittivity of medium 2.

  • mu1 – cosine zenith angle in medium 1.

Returns:

cosine zenith angle in medium 2.

Return type:

mu2

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 power reflection matrix for/in medium 1 laying above medium 2.

Parameters:
  • eps_1 – permittivity of medium 1.

  • eps_2 – permittivity of medium 2.

  • mu1 – cosine zenith angle in medium 1.

  • npol – number of polarizations to return.

Returns:

a matrix or the diagional depending on return_as_diagonal

fresnel_transmission_matrix(eps_1, eps_2, mu1, npol)

Compute the fresnel power transmission matrix for/in medium 1 lying above medium 2.

Parameters:
  • eps_1 – permittivity of medium 1.

  • eps_2 – permittivity of medium 2.

  • mu1 – cosine zenith angle in medium 1.

  • npol – number of polarizations to return.

Returns:

a matrix or the diagional depending on return_as_diagonal

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 returns 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

  • broadcast – (Default value = True)

  • **kwargs

class Interface(**kwargs)

Bases: object

Abstract class for interface between layer and substrate at the bottom of the snowpack. It provides argument handling.

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.

Parameters:

frequency – frenquency in Hz

substrate_from_interface(interface_cls)

Decorator to transform an interface class into a substrate class with automatic method

Parameters:

interface_cls

class Substrate(temperature=None, permittivity_model=None, **kwargs)

Bases: SubstrateBase, Interface

get_substrate_model(substrate_model)

Return the class corresponding to the substrate model called name.

Parameters:

substrate_model

Returns:

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

This class contains the properties for a single layer including the microstructure attribute which holds the microstructure properties.

To create a layer, it is recommended to use the functions make_snow_layer or similar.

property ssa

Return the SSA, computing it if necessary.

permittivity(i: int, frequency)

Return the permittivity of the i-th medium depending on the frequency and internal layer properties.

Parameters:
  • i (int) – Number of the medium. 0 is reserved for the background.

  • frequency (float) – Frequency of the wave in Hz.

Returns:

Permittivity of the i-th medium.

Return type:

complex

Raises:

SMRTError – If the permittivity model is not defined.

basic_checks()

Perform basic input checks on the layer information.

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.

Raises:

SMRTError – If any of the checks fail.

inverted_medium()

Return the layer with inverted autocorrelation and inverted permittivities.

Returns:

A new layer object with inverted properties.

Return type:

Layer

Raises:

SMRTError – If the microstructure model does not support inversion.

update(**kwargs)

Update the attributes. This method is to be used when recalculation of the state of the object is necessary. See for instance SnowLayer.

Parameters:

**kwargs

get_microstructure_model(modulename, classname=None)

Return the class corresponding to the microstructure_model defined in modulename.

This function imports the correct module modulename if possible and returns the first class found in the module. It is used internally and should not be needed for normal usage.

Parameters:
  • modulename – name of the python module in smrt/microstructure_model

  • classname – (Default value = None)

make_microstructure_model(modelname_or_class, **kwargs)

Create a microstructure instance.

Parameters:
  • modelname_or_class (str or type) – Name of the module or directly the class.

  • **kwargs – Arguments needed for the specific autocorrelation.

  • modelname_or_class

  • **kwargs

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.

Parameters:
  • *required_arguments

  • optional_arguments – (Default value = None)

  • **kwargs

smrt.core.lib module

get(x, i, name=None)

Return the i-th value in an array or dict of array. Can deal with scalar as well. In this case, it repeats the value.

Parameters:
  • x – flexible array like object or scalar

  • i – i index to get

  • name – name of the object x, for reporting error messages. Defaults to None.

Raises:

SMRTError – if x is too short compared to i

Returns:

element from x

check_argument_size(x, n, name=None)

Check that x is either a scalar or a sequence of exactly n items and raise an error otherwise.

Parameters:
  • x – array like object or scalar

  • n – expected size

  • name – name of the object x, for reporting error messages. Defaults to None.

Raises:

SMRTError – if x is not a scalar or a sequence of size n

is_sequence(x)

Check that x is a sequence

Parameters:

x – flexible object

Returns:

True if x is a sequence, False otherwise

class_specializer(domain: str, cls: str | Type, **options) Type

Return a subclass of cls (imported from the domain if cls is a string) that use the provided “options” for __init__.

This is equivalent to functools.partial but for a class.

This is the same idea as: https://stackoverflow.com/questions/38911146/python-equivalent-of-functools-partial-for-a-class-constructor

len_atleast_1d(x)

Return length of x if it is an array or similar, otherwise return 1, or 0 if None.

Parameters:

x – object to return the length of

Returns:

length of x

class smrt_diag(arr)

Bases: object

Define a simple diagonal matrix class.

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.

class smrt_matrix(mat, mtype=None)

Bases: object

Return a smrt_matrix 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.

compress(mode=None, auto_reduce_npol=False)

Compresses 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).

is_zero_scalar(m)

Returns true if the object is a scalar equal to zero

Parameters:

m – object to test

Returns:

True if m is a scalar equal to zero

is_equal_zero(m)

Returns true if the smrt matrix is null

Parameters:

m – object to test

Returns:

True if m is equal to zero

generic_ft_even_matrix(phase_function, m_max, nsamples=None)

Compute the Fourier transform of an even matrix.

This matrix can be a phase function, reflection or transmission matrix.

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

  • nsamples – number of samples to use for the Fourier decomposition. If None, it is automatically computed.

vectorize_angles(mu_s, mu_i, dphi, compute_cross_product=True, compute_sin=True)

Return angular cosines and sinus with proper dimensions, ready for vectorized calculations.

Parameters:
  • mu_s – scattering cosine angle.

  • mu_i – incident cosine angle.

  • dphi – azimuth angle between the scattering and incident directions.

  • compute_cross_product – if True perform the computation for all elements in mu_s, mu_i, dphi (cross product) and if False perform the computation for each successive configuration in mu_s, mu_i and dphi (they must have the same shape).

Returns:

vectorize angles

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

This module defines a Model class that drives the whole calculation of SMRT.

A model in SMRT is composed of the electromagnetic scattering theory (smrt.emmodel) and the radiative transfer solver (smrt.rtsolver).

The smrt.emmodel computes 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 emmodels for each layer (e.g., for a complex medium made of different materials: snow, soil, water, atmosphere, …). The smrt.rtsolver propagates 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, and other information.

Example:

m = make_model("iba", "dort")

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 returned Result 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.

Example:

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().

Example:

# 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.

Most rtsolvers and some emmodels take arguments (usually optional but still useful) that can be specified in two ways in make_model. Either using the rtsolver_options and emmodel_options arguments of that function or using the functions make_rtsolver() and make_emmodel() to build a new class where the prescribed options are applied by default.

Examples of usage:

make_model("iba", "dort", rtsolver_options=dict(n_max_stream=128))   # original approach to specify options

make_model("iba", make_rtsolver("dort", n_max_stream=128))                # newer approach that is more readible

Both are equivalent. There is no plan to depreciate the original approach that has some nice use-cases.

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 (string or class; or list of strings or classes; or dict of strings or classes.) – 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). 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.

  • rtsolver (string or class., optional) – 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. This argument is optional when only the computation of the layer electromagnetic properties is needed. (Default value = None)

  • emmodel_options – arguments applied to create the emmodel instance of each layer. Valid arguments depend on the selected emmodel (refer to the documentation of the selected emmodel). The function emmodel() provides an alternative to setting emmodel_options.

  • rtsolver_options (dict, optional) – arguments applied to create the rtsolver instance (refer to the documentation of the rtsolvers). The function rtsolver() provides an alternative to setting rtsolver_options. (Default value = None)

  • emmodel_kwargs – (Default value = None) rtsolver_kwargs: (Default value = None)

Returns:

a model instance

make_rtsolver(rtsolver_class: str | Type, **options) Type

Return a rtsolver subclass of cls (either given as a string or a class) where the provided options are applied to __init__.

Parameters:

rtsolver_class (Union[str, Type]) – **options:

Returns:

This function provides an alternative to setting rtsolver_options in make_model()).

Return type:

Type

Example:

make_model(..., make_rtsolver("dort", n_max_stream=128))
make_emmodel(emmodel_class: str | Type, **options) Type

Return a emmodel subclass of cls (either given as a string or a class) where the provided options are applied to __init__.

Parameters:

emmodel_class (Union[str, Type]) – **options:

Returns:

This function provides an alternative to setting emmodel_options in make_model()).

Return type:

Type

Example:

make_model(make_emmodel("iba", dense_snow_correction=True), ...)
get_emmodel(emmodel)

Return an emmodel class from the file name ‘emmodel’.

Parameters:

emmodel

make_emmodel_instance(emmodel, sensor, layer, **emmodel_options)

Create a new emmodel instance based on the emmodel class or string. This function used to be called make_emmodel but has been renamed from SMRT v1.4 and will soon be depreciated. It is recommended to use instead:

em = make_emmodel(emmodel)(sensor, layer, **emmodel_options)

or:

emmodel_class = make_emmodel(emmodel) em = emodel_class(sensor, layer, **emmodel_options)
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.

  • sensor – sensor to use for the calculation.

  • layer – layer to use for the calculation **emmodel_options:

class Model(emmodel, rtsolver, emmodel_options=None, rtsolver_options=None)

Bases: object

Drive the whole calculation.

set_rtsolver_options(options=None, **kwargs)

Set the option for the rtsolver.

Parameters:
  • options – (Default value = None)

  • **kwargs

set_emmodel_options(options=None, **kwargs)

Set the options for the emmodel.

Parameters:
  • options – (Default value = None)

  • **kwargs

run(sensor, snowpack, atmosphere=None, snowpack_dimension=None, snowpack_column='snowpack', progressbar=False, parallel_computation=True, runner=None)

Run the model for the given sensor configuration and returns 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.

  • atmosphere – (Default value = None) 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.

  • snowpack_column – when snowpack is a DataFrame this argument is used to specify which column contains the Snowpack objects (Default value = ‘snowpack’) progressbar: if True, display a progress bar during multi-snowpacks computation (Default value = False)

  • parallel_computation – if True (default), use the joblib library to run the simulations of many snowpacks in parallel. Otherwise, the simulations are run sequentially, one after one. See ‘runner’ for a more advanced control on parallel computations. Note for users seeking performances: numpy and scipy usually also perform low- level parallel computations that may (inefficiently) interact with the high-level parallelism activated by parallel_computation. For this reason joblib and other parallel runners try to desactivate numpy and scipy low-level parallelism (see set_max_numerical_threads()) to maximize performances. Conversely it means that when parallel_computation is False, the simulations are run sequentially, but numpy and scipy parallelism is NOT disabled. If you really want to use a single core for the simulations, you must first call set_max_numerical_threads() with 1 as argument and then call Model.run with parallel_computation=False. (Default value = False)

  • 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. To develop a costum runner, see the implementation of JoblibParallelRunner for instance.

Returns:

result of the calculation(s) as a Results instance

prepare_simulations(sensor, snowpack, snowpack_dimension, snowpack_column)

Return a flat list of pairs (sensor, snowpack).

Each is a unique simulation. The second returned parameter is the list of (axis, values) to be used to concatenate the results.

Parameters:
  • sensor – sensor object or list of sensor objects

  • snowpack – snowpack object or list of snowpack objects

  • snowpack_dimension – snowpack dimension information

  • snowpack_column – snowpack column information

prepare_emmodels(sensor, snowpack)

Return emmodels instances for each layer.

Parameters:
  • sensor – sensor to use for the calculation.

  • snowpack – snowpack to use for the calculation.

run_single_simulation(simulation, atmosphere)

Run a single simulation.

Parameters:
  • simulation – a tuple (sensor, snowpack)

  • atmosphere – atmosphere information

class SequentialRunner(progressbar, max_numerical_threads=1)

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(progressbar, backend='loky', n_jobs=None, 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.plugin module

register_package(pkg)

Register an external package having the same structure as the smrt package, to make available the modules as plugins.

This is useful for development of independent packages.

Parameters:

pkg – name of the package to register.

Raises:

SMRTError – if the package cannot be imported.

import_class(scope: str, modulename: str, classname: str | None = None) Type

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)

Import a class from the module name and the class name.

Parameters:
  • modulename – name of the module to import

  • classname – name of the class to load. If None, the first class found in the module is returned.

Raises:

SMRTError – if the module can not be found

smrt.core.sensitivity_study module

This module defines the SensitivityStudy class. It is used to easily conduct sensitivity studies. This class may be depreciated in the future. A more modern alternative is to use a pandas.DataFrame of snowpacks.

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))
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

Returns:

An instance of SensitivityStudy

smrt.core.sensor module

This module defines the configuration for sensors used in radiative transfer simulations. 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)

Return a generic configuration for passive microwave sensor.

Return a Sensor for a microwave radiometer with given frequency, incidence angle and polarization

Parameters:
  • 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 – 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 – 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. (Default value = None)

  • name – name of the sensor (Default value = None)

Returns:

py:class:Sensor instance

Usage 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')

Create a channel map for radar sensors.

Parameters:
  • frequency – frequency

  • polarization – polarization

  • order – order of the channels

Returns:

name of the channels is 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)

Return a generic configuration for active microwave sensor.

Return a Sensor for a radar with given frequency, incidence and viewing angles and polarization

If 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 polarizations of the incidence wave (‘H’ or ‘V’ or both).

  • polarization – list of viewing polarizations (‘H’ or ‘V’ or both).

  • channel_map (dict, optional) – 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, optional) – name of the sensor

Returns:

py:class:Sensor instance

Usage 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”])

lrm_altimeter(channel, **kwargs)

Return a generic configuration for a LRM altimeter.

sar_altimeter(channel, **kwargs)

Return a generic configuration for a SAR altimeter.

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: SensorBase

This class contains a sensor configuration.

Use of the functions passive(), active(), or the sensor specific functions e.g. amsre() are recommended to access this class.

property mode

“A” for active or “P” for passive.

Type:

Return the mode of observation

iterate(axis)

Iterate over the configuration for the given axis.

Parameters:

axis – one of the attribute of the sensor (frequency, …) to iterate along

class Altimeter(frequency, altitude, pulse_bandwidth, beamwidth_alongtrack, beamwidth_acrosstrack, pulse_repetition_frequency=0, velocity=0, antenna_gain=1, ngate=128, ndoppler=0, nominal_gate=40, doppler_window='rect', pitch_angle_deg=0.0, roll_angle_deg=0.0, theta_inc_deg=0.0, polarization_inc=None, polarization=None, channel=None)

Bases: Sensor

Configuration for LRM and SAR altimeters. Use of the functions sar_altimeter(), or the sensor specific functions e.g. sentinel3_sarm() are recommended to access this class.

smrt.core.snowpack module

This module defines the Snowpack class. A 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, terrain_info=None)

Bases: object

Hold the description of the snowpack, including the layers, interfaces, and the substrate.

property nlayer

Return the number of layers.

property layer_thicknesses

Return the thickness of each layer.

property layer_depths

Return the depth of the bottom of each layer.

property bottom_layer_depths

Return the depth of the bottom of each layer.

property top_layer_depths

Return the depth of the bottom of each layer.

property mid_layer_depths

Return the depth of the bottom of each layer.

property z

Return the depth of each interface, that is, 0 and the depths of the bottom of each layer.

property layer_densities

Return the density of each layer.

profile(property_name: str, where: str = 'all', raise_attributeerror: bool = False) ndarray

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.

Returns:

Array of the property values.

Return type:

np.ndarray

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.

delete(ilayer)

Delete a layer and the upper interface.

Parameters:

ilayer (int) – Index of the layer.

delete_layer(ilayer)

Delete a layer and the upper interface.

Parameters:

ilayer (int) – Index of the layer.

delete_bottom(ilayer)

Delete the bottom of the snowpack from layer n. Deletes also the substrate.

Parameters:

ilayer (int) – Index of the first layer to delete.

shallow_copy(cut_bottom=None)

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 advanced 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 deep_copy.

Warning

This function is for advanced users, understanding the concept and consequence of shallow copy. It is likely to generate bugs. It may be removed in the future, if snowpack becomes immutable.

Parameters:
  • cut_bottom (int, optional) – If cut_bottom is a number, all layers below the layer indexed by ‘cut_bottom’

  • substrate. (are removed as well as the)

Returns:

The shallow copy of the snowpack.

Return type:

Snowpack

deepcopy()

Make a deep copy of a snowpack.

Returns:

The deep copy of the snowpack.

Return type:

Snowpack

deep_copy()

Make a deep copy of a snowpack.

Returns:

The deep copy of the snowpack.

Return type:

Snowpack

to_dataframe()

Transform the snowpack in a DataFrame represation.

This is not to be used for serialization as some information may be lost.

Returns:

A pandas DataFrame representing the snowpack.

Return type:

_type_