ashdisperse.core package
Submodules
ashdisperse.core.core module
- ashdisperse.core.core.LowerODE(kx, ky, fxy_ij, grain_i, cheby, parameters, velocities)
- ashdisperse.core.core.UpperODE(kx, ky, grain_i, cheby, parameters, velocities)
ashdisperse.core.getters module
- ashdisperse.core.getters.Source_z(z, profile, Suzuki_k, lower, upper)
- ashdisperse.core.getters.Source_z_dimless(z, profile, Suzuki_k, lower, upper, H)
- ashdisperse.core.getters.Source_z_dimless_value(z, profile, Suzuki_k, lower, upper, H)
- ashdisperse.core.getters.Source_z_value(z, profile, Suzuki_k, lower, upper)
- ashdisperse.core.getters.Ws_surface(velocities, k)
- ashdisperse.core.getters.lower_U(velocities, k)
- ashdisperse.core.getters.lower_V(velocities, k)
- ashdisperse.core.getters.lower_Ws(velocities, k)
- ashdisperse.core.getters.lower_dWsdz(velocities, k)
- ashdisperse.core.getters.lower_z(velocities, k)
- ashdisperse.core.getters.upper_U(velocities, k)
- ashdisperse.core.getters.upper_V(velocities, k)
- ashdisperse.core.getters.upper_Ws(velocities, k)
- ashdisperse.core.getters.upper_dWsdz(velocities, k)
- ashdisperse.core.getters.upper_z(velocities, k)
ashdisperse.core.results module
- class ashdisperse.core.results.AshDisperseResult(params: Parameters, C0_FT: ndarray[tuple[Any, ...], dtype[complex128]], Cz_FT: ndarray[tuple[Any, ...], dtype[complex128]])
Bases:
objectResults of an AshDisperse simulation
- C0: ndarray[tuple[Any, ...], dtype[float64]]
- C0_FT: ndarray[tuple[Any, ...], dtype[complex128]]
- C0_dimless: ndarray[tuple[Any, ...], dtype[float64]]
- Cz: ndarray[tuple[Any, ...], dtype[float64]]
- Cz_FT: ndarray[tuple[Any, ...], dtype[complex128]]
- Cz_dimless: ndarray[tuple[Any, ...], dtype[float64]]
- POI_ashload(latlon: tuple[float, float] | list[tuple[float, float]], vmin: float = 1e-05) tuple[float | ndarray[tuple[Any, ...], dtype[float64]], list[dict[str, float | ndarray[tuple[Any, ...], dtype[float64]] | None]]]
Retrieve the ground-level ash load at a points-of-interest, aggregated over all grain classes.
Ash load represents the total deposited mass per unit area (kg/m²) summed over all grain class, computed as:
ashload = sum (settling_flux_igrain) * eruption_durationParameters
- latlontuple[float, float] | list[tuple[float, float]]
Point- or points-of-interest. A single point is passed as a tuple as (latitude, longitude). Multiple points-of-interest are passed as a list of single points.
- vminfloat, optional
Minimum ash load threshold (kg/m²). Values below this threshold are treated as absent. Default is
1e-5.
Returns
- tuple[float | NDArray[np.float64], list[dict[str, float | NDArray[np.float64] | None]]]
If valid data exists, returns a tuple
(total_load, load_by_grain): -total_load: the cummulative ash load, returned as either:float if latlon is a single point
list[float] if latlon is a list of points
If no valid data is found, the total load is zero.
load_by_grain: the loads for each grain class, returned as dict containing:diameter: the grain diameterdensity: the grain densityproportion: the grain proportionload: the grain load, returned asfloat if latlon is a single point
list[float] if latlon is a list of points
None if no valid data is found
- POI_ashload_for_grain_class(grain_i: int, latlon: tuple[float, float] | list[tuple[float, float]], vmin: float = 1e-05) float | ndarray[tuple[Any, ...], dtype[float64]] | None
Retrieve the ground-level ash load at a points-of-interest for a specific grain class
Ash load represents the total deposited mass per unit area (kg/m²) for the specified grain class, computed as:
ashload = settling_flux * eruption_durationParameters
- grain_iint
Zero-based index of the grain size class to extract.
- latlontuple[float, float] | list[tuple[float, float]]
Point- or points-of-interest. A single point is passed as a tuple as (latitude, longitude). Multiple points-of-interest are passed as a list of single points.
- vminfloat, optional
Minimum ash load threshold (kg/m²). Values below this threshold are treated as absent. Default is
1e-5.
Returns
- float | NDArray[np.float64] | None
If valid data exists, returns: - a float if latlon is a single point - a 1D ndarray of floats if latlon is a list of points If no valid data exists (e.g., all values below
vmin), returnsNone.
- POI_groundconc(latlon: tuple[float, float] | list[tuple[float, float]], vmin: float = 0.001) tuple[float | ndarray[tuple[Any, ...], dtype[float64]], list[dict[str, float | ndarray[tuple[Any, ...], dtype[float64]]]]]
- POI_groundconc_for_grain_class(grain_i: int, latlon: tuple[float, float] | list[tuple[float, float]], vmin: float = 0.001) float | ndarray[tuple[Any, ...], dtype[float64]] | None
- POI_settlingflux(latlon: tuple[float, float] | list[tuple[float, float]], vmin: float = 0.001) tuple[float | ndarray[tuple[Any, ...], dtype[float64]], list[dict[str, float | ndarray[tuple[Any, ...], dtype[float64]]]]]
- POI_settlingflux_for_grain_class(grain_i: int, latlon: tuple[float, float] | list[tuple[float, float]], vmin: float = 0.001) float | ndarray[tuple[Any, ...], dtype[float64]] | None
- SettlingFlux: ndarray[tuple[Any, ...], dtype[float64]]
- change_MER(MER: float) AshDisperseResult
Create a new AshDisperseResult with updated mass eruption rate (MER).
This method does not modify the original object; instead, it returns a new instance with the specified MER applied.
Parameters
- MERfloat
A float representing the new MER. The MER must be positive.
Returns
- AshDisperseResult
A new AshDisperseResult instance with updated MER.
Raises
- ValueError
If MER is not positive.
Examples
- Change original_result with new MER of 1e7
>>> result = original_result.change_duration(1e6) >>> result.params.source.MER 1000000.0
- change_duration(duration: float) AshDisperseResult
Create a new AshDisperseResult with updated duration.
This method does not modify the original object; instead, it returns a new instance with the specified duration applied.
Parameters
- durationfloat
A float representing the new duration. The duration must be positive.
Returns
- AshDisperseResult
A new AshDisperseResult instance with updated duration.
Raises
- ValueError
If duration is not positive.
Examples
- Change original_result with new duration of one hour
>>> result = original_result.change_duration(3600) >>> result.params.source.duration 3600.0
- change_grain_proportions(props: list[float]) AshDisperseResult
Create a new AshDisperseResult with updated grain size proportions.
This method does not modify the original object; instead, it returns a new instance with the specified grain size proportions applied.
Parameters
- propslist of float
A list of floats representing the new proportions for each grain size class. The length of this list must equal the number of grain size classes defined in self.params.grains.bins. Each value must be in the range [0, 1].
Returns
- AshDisperseResult
A new AshDisperseResult instance with updated grain proportions.
Raises
- RuntimeError
If the length of props does not match the number of grain size classes (self.params.grains.bins).
- ValueError
If any element in props is outside the valid range [0, 1]. Each proportion must be a float between 0 and 1 inclusive, representing the fraction of material in that grain size class.
Examples
- Change original_result with three grain classes
>>> result = original_result.change_grain_proportions([0.2, 0.3, 0.5]) >>> result.params.grains.proportion array([0.2, 0.3, 0.5])
- contour_ashload_for_grain_class(grain_i, cntrs_levels='log', vmin=0.01)
- contour_settling_flux(grain_i, logscale=True, vmin=1e-06)
- classmethod create(params, C0_FT, Cz_FT) Self
- folium_ashloads(savename, vmin=0.001)
- classmethod from_netcdf(filename: str) AshDisperseResult
Create an
AshDisperseResultfrom a NetCDF file.This classmethod loads a NetCDF dataset, reconstructs the full set of model parameters (solver, grains, source, emission, physical, meteorology, output, and model parameters), and returns a new result object populated with the spectral fields C0_FT and Cz_FT.
The method attempts to handle both scalar and array encodings for several parameter groups (e.g., grains, emission, model), choosing between
from_valuesandfrom_listsdepending on the underlying type.Parameters
- filenamestr
Path to the NetCDF file containing AshDisperse output. This file is expected to include fields such as
version, solver domain and grid settings, grain properties (diameter, density, proportion), source parameters, emission profile parameters, physical constants, meteorology, output scheduling, model scaling parameters, and the real/imaginary parts of the spectral fields:C0_FT_r,C0_FT_i,Cz_FT_r, andCz_FT_i.
Returns
- Self
A new instance of
AshDisperseResultinitialized from the contents of the NetCDF file.
Raises
- FileNotFoundError
If
filenamedoes not exist.- OSError
If the file cannot be opened or read as a NetCDF dataset.
- KeyError
If required variables are missing from the dataset (e.g., grid settings, grain properties, spectral components).
- ValueError
If variable shapes or dtypes are incompatible with the expected parameter constructors (e.g., mismatched array lengths across diameter/density/ proportion or emission profiles).
Warnings
- UserWarning
If the dataset version (
da.version) differs from the current library version (__version__). The method continues but warns about possible incompatibilities.
Notes
Grain parameters:
Switches between
GrainParameters.from_valuesandGrainParameters.from_listsdepending on whetherda.diameteris loaded as a scalar (np.float64) or an array-like. - Emission parameters: Similarly selectsEmissionParameters.from_valuesvsfrom_listsbased on the type ofda.emission_lower. - Model parameters: ChoosesModelParameters.from_valuesvsfrom_listsusing the type ofda.SettlingScale. - Spectral fields: The complex arrays are reconstructed from their real and imaginary parts asC0_FT = C0_FT_r + 1j * C0_FT_iandCz_FT = Cz_FT_r + 1j * Cz_FT_i.Examples
>>> result = AshDisperseResult.from_netcdf("outputs/ashdisperse_run.nc") >>> result.params.solver.Nx_log2, result.params.solver.Ny_log2 (10, 10) >>> result.C0_FT.shape, result.Cz_FT.shape ((256, 256), (256, 256))
- get_ashload(resolution: float = 300.0, vmin: float = 0.001, nodata: float = -1.0) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]
- get_ashload_for_grain_class(grain_i: int, vmin: float = 1e-05, masked: bool = False, clipped: bool = True) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]] | None
Retrieve the ground-level ash load grid for a specific grain size class.
Ash load represents the total deposited mass per unit area (kg/m²) for the specified grain class, computed as:
ashload = settling_flux * eruption_durationParameters
- grain_iint
Zero-based index of the grain size class to extract.
- vminfloat, optional
Minimum ash load threshold (kg/m²). Values below this threshold are treated as absent. Default is
1e-5.- maskedbool, optional
If
True, return a masked array where values belowvminare masked. Default isFalse.- clippedbool, optional
If
True, clip the returned grid to the smallest bounding box that contains all values abovevmin. IfFalse, return the full model grid for the grain class. Default isTrue.
Returns
- tuple of ndarray or None
If valid data exists, returns a tuple
(x, y, ashload): -x: 1D ndarray of x-coordinates (model units) -y: 1D ndarray of y-coordinates (model units) -ashload: 2D ndarray or MaskedArray of ash load values (kg/m²) with shape(ny, nx)If no valid data exists (e.g., all values belowvminor clipped region is empty), returnsNone.
Raises
- IndexError
If
grain_iis out of range for the available grain size classes.- ValueError
If
grain_iis negative.
Notes
Ash load is derived from the precomputed settling flux multiplied by the
eruption duration. - Use
masked=Trueto obtain a masked array suitable for plotting or further filtering. - Whenclipped=True, the returned coordinates and grid are cropped to the minimal region containing ash load values abovevmin. - If all ash load values are belowvmin, the method returnsNone.See Also
get_settlingflux_for_grain_class : Retrieve settling flux (kg/m²/s) for a grain class. raster_ashload_for_grain_class : Export ash load as an xarray.Dataset with geospatial metadata.
Examples
>>> x, y, ashload = result.get_ashload_for_grain_class(2, vmin=1e-4, masked=True)
- get_groundconc_for_grain_class(grain_i: int, vmin: float = 1e-09, masked: bool = False, clipped: bool = True) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]] | None
Retrieve the ground-level concentration grid for a specific grain size class.
This method extracts the concentration field for the given grain class at ground level, optionally masking low values and/or clipping the grid to the minimal bounding region containing valid data.
Parameters
- grain_iint
Zero-based index of the grain size class to extract.
- vminfloat, optional
Minimum concentration threshold. Values below this threshold are treated as absent. Default is
1e-9.- maskedbool, optional
If
True, return a masked array where values belowvminare masked. Default isFalse.- clippedbool, optional
If
True, clip the returned grid to the smallest bounding box that contains all values abovevmin. IfFalse, return the full model grid for the grain class. Default isTrue.
Returns
- tuple of ndarray or None
If valid data exists, returns a tuple
(x, y, conc): -x: 1D ndarray of x-coordinates (model units) -y: 1D ndarray of y-coordinates (model units) -conc: 2D ndarray or MaskedArray of concentrations with shape(ny, nx)If no valid data exists (e.g., all values belowvminor clipped region is empty), returnsNone.
Raises
- IndexError
If
grain_iis out of range for the available grain size classes.- ValueError
If
grain_iis negative.
Notes
Use
masked=Trueto obtain a masked array suitable for plotting or
further filtering. - When
clipped=True, the returned coordinates and grid are cropped to the minimal region containing concentrations abovevmin. - If all concentrations are belowvmin, the method returnsNone.Examples
>>> x, y, conc = result.get_groundconc_for_grain_class(0, vmin=1e-8, masked=True)
- get_settlingflux_for_grain_class(grain_i: int, vmin: float = 1e-07, masked: bool = False, clipped: bool = True) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]] | None
Retrieve the ground-level settling flux (mass flux to surface) for a specific grain size class.
This method extracts the settling flux field for the given grain class at ground level, optionally masking low values and/or clipping the grid to the minimal bounding region containing valid flux data.
Parameters
- grain_iint
Zero-based index of the grain size class to extract.
- vminfloat, optional
Minimum flux threshold (kg/m²/s). Values below this threshold are treated as absent. Default is
1e-7.- maskedbool, optional
If
True, return a masked array where values belowvminare masked. Default isFalse.- clippedbool, optional
If
True, clip the returned grid to the smallest bounding box that contains all values abovevmin. IfFalse, return the full model grid for the grain class. Default isTrue.
Returns
- tuple of ndarray or None
If valid data exists, returns a tuple
(x, y, flux): -x: 1D ndarray of x-coordinates (model units) -y: 1D ndarray of y-coordinates (model units) -flux: 2D ndarray or MaskedArray of settling flux values with shape(ny, nx)If no valid data exists (e.g., all values belowvminor clipped region is empty), returnsNone.
Raises
- IndexError
If
grain_iis out of range for the available grain size classes.- ValueError
If
grain_iis negative.
Notes
Settling flux represents the mass flux to the ground surface for the specified grain class.
Use
masked=Trueto obtain a masked array suitable for plotting or further filtering.When
clipped=True, the returned coordinates and grid are cropped to the minimal region
containing flux values above
vmin. - If all flux values are belowvmin, the method returnsNone.Examples
>>> x, y, flux = result.get_settlingflux_for_grain_class(1, vmin=1e-6, masked=True)
- get_total_ashload(resolution: float = 300.0, vmin: float = 0.001, nodata: float = -1.0) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]
Compute aggregated total ash load raster from all grain-class settling fluxes.
Parameters
- resolutionfloat, optional
Output grid resolution in model units (default: 300.0).
- vminfloat, optional
Minimum value to keep (values below are masked/nodata, default: 1e-3).
- nodatafloat, optional
Value to use for nodata in output arrays (default: -1).
Returns
- (x, y, totalAshLoad)tuple of arrays,
x, y are 1D arrays of coordinates; totalAshLoad is a masked 2D array.
- property interpolated: bool
Check if this AshDisperseResult is produced by interpolation
Returns
- bool
True if this AshDisperseResult is produced by zero-padding interpolation from a computed AshDisperseResult, False otherwise
- kx: ndarray[tuple[Any, ...], dtype[float64]]
- ky: ndarray[tuple[Any, ...], dtype[float64]]
- linear_interp(Nx_log2: int, Ny_log2: int) AshDisperseResult
Return a new AshDisperseResult with bilinear interpolation by zero-padding the FFTs.
Parameters
- Nx_log2int
log2 of the number of Fourier modes in x
- Ny_log2int
log2 of the number of Fourier modes in y
Returns
- AshDisperseResult
A new AshDisperseResult. The original object is unchanged.
Notes
The internal stored parameters are updated for the new sizes. A class private variable _interpolated is set to True to indicate this AshDisperseResult is generated by zero-padding interpolation.
- max_ashload_for_grain_class(grain_i: int) float
- params: Parameters
- plot_ashload(resolution=300.0, logscale=True, cmap='viridis', vmin=0.001, nodata=-1, alpha=0.5, basemap=False, export_gtiff=False, export_name='AshLoad.tif', show=True, ds=None)
Plot total ash load as filled contours.
Parameters
- resolutionfloat, optional
Output grid resolution (default: 300.0). Ignored if ds is provided.
- logscalebool, optional
Use logarithmic color scale (default: True).
- cmapmatplotlib colormap, optional
Colormap to use (default: viridis).
- vminfloat, optional
Minimum value to plot (default: 1e-3).
- nodatafloat, optional
Value to use for nodata (default: -1).
- alphafloat, optional
Alpha blending for filled contours (default: 0.5).
- basemapbool, optional
If True, add a basemap (default: False).
- export_gtiffbool, optional
If True, write a GeoTIFF (default: False).
- export_namestr, optional
Filename for GeoTIFF (default: ‘AshLoad.tif’).
- showbool, optional
If True, show the plot (default: True).
- dsxarray.Dataset, optional
If provided, use this dataset (must have ‘ash_load’). Otherwise, compute from model.
Returns
- fig, ax, cbartuple
Matplotlib Figure, Axes, and Colorbar objects.
Notes
If ds is not provided, the function computes the total ash load using current model parameters.
- plot_ashload_for_grain_class(grain_i: int, logscale: bool = True, vmin: float = 1e-06, vmax: float | None = None, cmap: str | Colormap = 'plasma', basemap: bool = True, alpha: float = 0.5, max_zoom: int | None = None, show: bool = True, save: bool = False, save_name: str = 'ashdisperse_result.png', min_ax_width: float | None = None, min_ax_height: float | None = None) tuple[Figure, Axes, Colorbar]
- plot_conc_for_grain_class(grain_i, logscale=True, vmin=1e-06, cmap='bone', basemap=False)
- plot_iso_conc_for_grain_class(grain_i, conc)
- plot_settling_flux_for_grain_class(grain_i: int, logscale: bool = True, vmin: float = 1e-06, vmax: float | None = None, cmap: str | Colormap = 'Purples', basemap: bool = True, alpha: float = 0.5, max_zoom: int | None = None, show: bool = True, save: bool = False, save_name: str = 'ashdisperse_result.png', min_ax_width: float | None = None, min_ax_height: float | None = None) tuple[Figure, Axes, Colorbar]
- plot_spectrum_for_grainsize(grain_i, vmin=None, vmax=None)
- raster_ashload_for_grain_class(grain_i: int, vmin: float = 0.01, nodata: float = nan, masked: bool = False, clipped: bool = True, crs: str | None = None) Dataset | None
- raster_groundconc_for_grain_class(grain_i: int, vmin: float = 1e-09, nodata: float = nan, masked: bool = False, clipped: bool = True, crs: str | None = None) Dataset | None
- raster_settlingflux_for_grain_class(grain_i: int, vmin: float = 1e-06, nodata: float = nan, masked: bool = False, clipped: bool = True, crs: str | None = None) Dataset | None
- raster_total_ashload(resolution: float = 300.0, vmin: float = 0.001, nodata: float = -1.0, crs: str | None = None) Dataset | None
Compute aggregated total ash load raster from all grain-class settling fluxes
Parameters
- resolutionfloat, optional
Output grid resolution in model units (default: 300.0).
- vminfloat, optional
Minimum value to keep (values below are masked/nodata, default: 1e-3).
- nodatafloat, optional
Value to use for nodata in output arrays (default: -1).
Returns
- property source_marker: GeoDataFrame
GeoDataFrame containing the source location
Returns
- gpd.GeoDataFrame
GeoDataFrame containing the source location in WGS84 coordinates
- to_netcdf(filename: str = 'AshDisperse.nc', compress: bool = True, complevel: int = 5) None
Save the current
AshDisperseResultto a NetCDF file.This method writes the complex spectral fields and all associated model parameters to a NetCDF file using the
h5netcdfengine. Complex arrays are stored as separate real and imaginary components.Parameters
- filenamestr, optional
Output file path. If the file exists, it will be overwritten. Default is
"AshDisperse.nc".- compressbool, optional
Whether to apply zlib compression to data variables. Default is
True.- complevelint, optional
Compression level passed to zlib (typically in the range 0-9). Ignored if
compress=False. Default is5.
Returns
None
Raises
- PermissionError
If the file cannot be created or overwritten due to insufficient permissions or the path is not writable.
- OSError
If there is a low-level I/O or HDF5/NetCDF issue while writing.
- ValueError
If an invalid
complevelis provided (e.g., out of the supported range for the underlying zlib implementation) or if array shapes are inconsistent with the declared dimensions.
Notes
Data variables (stored as float arrays): -
C0_FT_r: Real part ofC0_FTwith dims("ky", "kx", "grains")-C0_FT_i: Imag part ofC0_FTwith dims("ky", "kx", "grains")-Cz_FT_r: Real part ofCz_FTwith dims("ky", "kx", "z", "grains")-Cz_FT_i: Imag part ofCz_FTwith dims("ky", "kx", "z", "grains")Coordinates: -
grains:range(self.params.grains.bins)-kx:self.kx[: Nx // 2 + 1](positive and zero wavenumbers) -ky:self.ky-z:self.params.output.altitudesGlobal attributes include solver/domain configuration, grain parameters (
diameter,density,proportion), source parameters (location, plume, MER, duration), emission profile, physical constants, meteorology, model scaling, and output schedule. The current packageversionis also recorded.Compression and encoding: If
compress=True, all data variables are written withzlib=Trueandcomplevel=complevel. Ifcompress=False, the dataset is written without compression.File format and engine: The file is written with
format="NETCDF4"using theengine="h5netcdf"backend.Examples
>>> result.to_netcdf("outputs/ashdisperse_run.nc") >>> result.to_netcdf("outputs/run_compressed.nc", compress=True, complevel=9) >>> result.to_netcdf("outputs/run_uncompressed.nc >>> result.to_netcdf("outputs/run_uncompressed.nc", compress=False)
- utm: tuple[Any | float, Any | float, Any | int, Any | LiteralString | None]
- utmepsg: int
- write_ashload_for_grain_class(grain_i: int, vmin: float = 0.001, resolution: float | None = None, outname: str | None = None, compress: str = 'LZW') None
- write_gtiff(raster: ndarray[tuple[Any, ...], dtype[float64]], x: ndarray[tuple[Any, ...], dtype[float64]], y: ndarray[tuple[Any, ...], dtype[float64]], outname: str, nodata: float = -1, vmin: float = 1e-06, resolution: float | None = None) None
- write_settling_flux_for_grain_class(grain_i: int, nodata: float = -1.0, vmin: float = 1e-06, resolution: float | None = None) None
- x: ndarray[tuple[Any, ...], dtype[float64]]
- x_dimless: ndarray[tuple[Any, ...], dtype[float64]]
- y: ndarray[tuple[Any, ...], dtype[float64]]
- y_dimless: ndarray[tuple[Any, ...], dtype[float64]]
- ashdisperse.core.results.compat_warning(message: str, category: type[Warning], filename: str, lineno, file=None, line=None) str