panache.plume_algorithm#

Functions

assemble_and_order_directions(directions_1, ...)

Assembles and orders direction vectors based on a specified order.

compute_directional_gradients(spm_map, ...)

Computes the gradient in multiple directions from a starting point using vectorized operations.

create_polygon_mask(dataset, parameters)

Create a polygon mask that covers the searching area.

delineate_plume_pipeline(ds_reduced, ...[, ...])

Run the full Create_the_plume_mask refinement sequence for one plume.

derive_masks_from_bathymetry(bathymetry_map, ...)

Derive cloud-screening and land masks directly from bathymetry.

estimate_near_mouth_bounds(spm_values, ...)

Estimate SPM threshold bounds from pixels within a window around the river mouth.

fast_delimit_plume_area(spm_map, land_mask, ...)

Delimits a river plume area based on a Suspended Particulate Matter (SPM) map by computing gradients in specified directions and creating a polygon boundary.

filter_gradient_points(gradient_values, ...)

Filters gradient points based on the gradient values and proximity to land.

find_SPM_threshold(spm_map, land_mask, ...)

Finds the Suspended Particulate Matter (SPM) threshold by analyzing gradients in specified directions and filtering gradient points.

find_connected_shapes(shape_1, shape_2)

Identify connected shapes in one mask that overlap with another mask.

find_direction_indices_and_values(mask_area, ...)

Identify and retrieve index and values along multiple directions in the plume area.

find_first_nan_after_finite(arr)

Detects the first NaN value that occurs after finite values in a 3D array.

find_high_value_pixels(data, center_lat, ...)

Identify pixels in a 2D dataset that are within a specified radius from a given center point and have values exceeding a threshold.

find_nearest_valid_start(data, start, directions)

Find the nearest finite pixel to start along the principal fan direction.

find_starting_point_index(ds_reduced, ...)

Locate the index of the plume's starting point in the reduced dataset.

first_true_block(arr)

Finds the position of the first contiguous block of True values in a boolean array.

flood_fill(data, start, SPM_threshold, ...)

Perform a flood fill on a 2D array, starting from a given point and marking cells based on a specified threshold and direction vectors.

haversine(lat1, lon1, lat2, lon2)

Calculate the great-circle distance between two points on the Earth's surface.

identify_plume_shape_label(mask_area, ...)

Assigns a label to the main plume area, which is the one covering the coordinates of the plume core.

is_area_too_cloudy(dataset, ...)

Check if a specific area within the dataset is too cloudy based on a threshold.

last_true_block(arr)

Finds the position of the last contiguous block of True values in a boolean array.

load_and_filter_arrays(file_name)

Loads a file and filters its arrays based on specific criteria.

main_process(file_name, ds, parameters, ...)

Process a single, already-loaded satellite data scene for plume detection.

make_the_plot(...[, coast_shape, mask_area, ...])

Generate and save a visualization comparing the original and processed datasets, including optional plume and bathymetric masks.

merge_close_shapes(mask_area, ...)

Merges the main plume shape in a mask with nearby shapes if they are close enough.

pixels_far_from_land(land_mask, ...)

Filters pixel positions based on their proximity to land.

remove_resuspension_pixels(ds_reduced, ...)

Remove coastal areas influenced by sediment resuspension based on given criteria.

return_stats_dictionnary(final_mask_area, ...)

Compute or return an empty dictionary with statistics about the plume area.

set_cloudy_regions_true(ds_reduced, ...)

Refines the plume shape by marking cloudy areas as part of the plume if they are enclosed by SPM concentrations higher than the SPM_threshold.

set_mask_false_by_index(mask_area, ...)

Modify a mask array by setting values to False for points outside a polygon defined by gradient points.

Classes

Create_the_plume_mask(spm_reduced_map, ...)

A class to detect and refine plume areas based on SPM, bathymetry, and land masks.

class panache.plume_algorithm.Create_the_plume_mask(spm_reduced_map, bathymetry_map_aligned_to_spm_reduced_map, land_mask, parameters, plume_name)[source]#

Bases: object

A class to detect and refine plume areas based on SPM, bathymetry, and land masks.

spm_map#

Map of [SPM] concentrations.

Type:

xr.DataArray

bathymetry_map#

Aligned map of bathymetry values.

Type:

xr.DataArray

land_mask#

Boolean map indicating land regions (True = land).

Type:

xr.DataArray

protocol#

List of executed methods in order.

Type:

list of str

plume_name#

Name of the plume being processed.

Type:

str

parameters#

Configuration and parameters for plume detection.

Type:

dict

determine_SPM_threshold(dynamic_determination_of_SPM_threshold, precomputed_threshold=None)[source]#

Determine the SPM threshold for plume detection.

Priority: dynamic (gradient-based, per-scene) > precomputed_threshold (from global quantile or user scalar) > fixed (zone preset per-plume value). The runner ensures precomputed_threshold=None when dynamic mode is active, so this method uses whichever non-None value it receives.

dilate_and_merge_close_areas()[source]#

Dilate the plume mask to merge closely located plume areas.

do_a_raw_plume_detection()[source]#

Perform the initial detection of the plume area.

include_cloudy_regions()[source]#

Expand the detected plume area to include cloudy regions.

remove_close_river_mouth(positions_of_river_mouths={})[source]#

Removes the area of a close river plume from the current plume mask.

This function identifies and removes regions of overlapping plumes associated with nearby river mouths. It uses the plume boundary determined by fast_delimit_plume_area and updates the plume mask accordingly.

Parameters:

positions_of_river_mouths (dict, optional) – A dictionary of positions of river mouths. Each key corresponds to a river mouth’s identifier, and the value is a tuple of coordinates (row, column).

Returns:

The method modifies self.plume_mask in place, removing the areas of close river plumes. It also updates the self.protocol attribute to log the operation.

Return type:

None

Notes

  • This function assumes the presence of self.spm_map, self.land_mask, self.plume_mask, and self.SPM_threshold attributes.

  • The plume boundaries are determined using a convex hull polygon.

remove_post_shrink_widening()[source]#

Remove parts of the plume area that widen after the shrinking phase.

remove_resuspension_areas(maximal_bathymetry=None, minimal_distance_from_estuary=None)[source]#

Remove areas with sediment resuspension from the plume mask.

Parameters:
  • maximal_bathymetry (float, optional) – Maximum bathymetry value to consider as part of sediment resuspension zones. If None, it is retrieved from the parameters dictionary.

  • minimal_distance_from_estuary (float, optional) – Minimum distance from the estuary to consider as part of sediment resuspension zones. If None, it is retrieved from the parameters dictionary.

remove_shallow_waters(bathymetric_threshold=None)[source]#

Remove shallow water regions from the plume mask.

Parameters:

bathymetric_threshold (float, optional) – Bathymetric depth threshold. Pixels with bathymetry values greater than the negative of this threshold are excluded from the plume mask. If None, the value is retrieved from the parameters dictionary.

remove_undersized_shapes(minimum_size_threshold=3)[source]#

Remove small shapes from the plume mask based on a size criterion.

Parameters:

minimum_size_threshold (int, optional) – Minimum size (number of pixels) for a shape to be retained in the plume mask. Default is 3.

select_shape_by_core(plume_core_location=None)[source]#

Identify the main plume shape using the plume core location.

Parameters:

plume_core_location (tuple of int, optional) – Coordinates of the plume core. If None, the value is retrieved from the parameters dictionary.

set_false_outside_search_area(searching_area)[source]#

Exclude pixels outside the specified searching area from the plume mask.

Parameters:

searching_area (xr.DataArray) – Boolean mask indicating the valid searching area (True = valid).

panache.plume_algorithm.assemble_and_order_directions(directions_1, directions_2, order_of_elements)[source]#

Assembles and orders direction vectors based on a specified order.

Parameters:
  • directions_1 (np.ndarray) – Array of direction vectors labeled as group 1.

  • directions_2 (np.ndarray) – Array of direction vectors labeled as group 2.

  • order_of_elements (list) – A list specifying the order in which directions should be assembled, where elements are labeled as 1 (group 1) or 2 (group 2).

Returns:

A 2D array containing assembled and ordered direction vectors.

Return type:

np.ndarray

panache.plume_algorithm.compute_directional_gradients(spm_map, start_point, directions, max_steps, lower_high_values_to=None, create_X_intermediates_between_each_direction=1)[source]#

Computes the gradient in multiple directions from a starting point using vectorized operations.

Parameters:
  • spm_map (ndarray) – A 2D array of Suspended Particulate Matter (SPM) concentrations.

  • start_point (tuple) – Coordinates (y, x) of the starting point in the map.

  • directions (list of tuple) – List of direction vectors (dy, dx) for gradient computation.

  • max_steps (int, optional) – Maximum number of steps to compute in each direction (default is 100).

  • create_X_intermediates_between_each_direction (int, optional) – Number of intermediate direction vectors to generate between existing ones (default is 1).

Returns:

  • relative_gradient_values (ndarray) – Array of normalized gradient values for each direction and step.

  • gradient_points (ndarray) – Array of coordinates (y, x) corresponding to the gradient values.

  • spm_values (ndarray) – SPM values at the computed gradient points.

panache.plume_algorithm.create_polygon_mask(dataset, parameters)[source]#

Create a polygon mask that covers the searching area.

Parameters:
  • dataset (xarray.DataArray) – The input dataset to be used to extract polygon coordinates.

  • parameters (dict) – Configuration parameters for plume detection. It contains the limits of the polygon defining the searching area.

Returns:

Boolean mask where True represents areas inside the polygon.

Return type:

xarray.DataArray

panache.plume_algorithm.delineate_plume_pipeline(ds_reduced, bathymetry_data_aligned_to_reduced_map, land_mask, parameters, plume_name, inside_polygon_mask, dynamic_thresh, precomputed_threshold=None)[source]#

Run the full Create_the_plume_mask refinement sequence for one plume.

Instantiates Create_the_plume_mask and drives it through threshold determination, raw detection, cloud-region inclusion, resuspension and shallow-water removal, close-river-mouth removal, dilation/merging, small-shape removal, restriction to the searching area, and main-shape identification. The final shrink-widen cleanup step is skipped for the 'Seine' plume.

Parameters:
  • ds_reduced (xr.DataArray) – SPM dataset at reduced resolution.

  • bathymetry_data_aligned_to_reduced_map (xr.DataArray) – Bathymetry aligned to the reduced-resolution grid.

  • land_mask (xr.DataArray) – Boolean map where True indicates land.

  • parameters (dict) – Configuration and parameters for plume detection.

  • plume_name (str) – Name of the plume being processed.

  • inside_polygon_mask (xr.DataArray) – Boolean mask restricting detection to the configured plume-area polygon.

  • dynamic_thresh (bool) – Whether to determine the SPM threshold dynamically rather than using the configured fixed value.

Returns:

The plume object after all refinement steps have been applied.

Return type:

Create_the_plume_mask

panache.plume_algorithm.derive_masks_from_bathymetry(bathymetry_map, parameters)[source]#

Derive cloud-screening and land masks directly from bathymetry.

Water pixels are defined as finite bathymetry values strictly below sea level.

Parameters:
  • bathymetry_map (xarray.DataArray) – Bathymetry aligned to the input dataset.

  • parameters (dict) – Configuration parameters for plume detection.

Returns:

A two-element tuple:

  • Boolean mask on the input grid where True represents water inside the cloud-checking area.

  • Boolean mask on the input grid where True represents land.

Return type:

tuple of xarray.DataArray

panache.plume_algorithm.estimate_near_mouth_bounds(spm_values, land_mask_values, start_pixel, lower_quantile=0.25, upper_quantile=0.75, radius_pixels=15, window_shape='circle')[source]#

Estimate SPM threshold bounds from pixels within a window around the river mouth.

Samples all finite, non-land pixels within radius_pixels of start_pixel and returns (lower_quantile, upper_quantile) of their SPM distribution. These replace hand-tuned minimal_threshold / maximal_threshold values when those are set to None, making the dynamic threshold self-calibrating.

Falls back to the full water-pixel distribution if fewer than five valid near-mouth pixels are found (e.g. when the starting point is cloud-covered).

Parameters:
  • spm_values (ndarray) – 2D numpy array of SPM concentrations (reduced-resolution scene).

  • land_mask_values (ndarray) – 2D boolean array; True indicates land.

  • start_pixel (tuple of int) – (row, col) pixel index of the river-mouth starting point.

  • lower_quantile (float) – Quantile for minimal_threshold (default 0.25).

  • upper_quantile (float) – Quantile for maximal_threshold (default 0.75).

  • radius_pixels (int) – Sampling radius in pixels around start_pixel (default 15). For window_shape='circle' this is a Euclidean radius; for window_shape='square' it is the half-width of a square window (e.g. 1 gives a 3x3 window, 2 a 5x5 window, 3 a 7x7 window).

  • window_shape (str) – 'circle' (default, Euclidean distance <= radius_pixels) or 'square' (Chebyshev distance <= radius_pixels, i.e. a full 2 * radius_pixels + 1 side square block).

Returns:

  • minimal_threshold (float)

  • maximal_threshold (float)

panache.plume_algorithm.fast_delimit_plume_area(spm_map, land_mask, start_point, SPM_threshold, maximal_threshold, max_steps=20)[source]#

Delimits a river plume area based on a Suspended Particulate Matter (SPM) map by computing gradients in specified directions and creating a polygon boundary.

Parameters:
  • spm_map (xarray.DataArray) – A 2D array representing the SPM concentration map.

  • land_mask (xarray.DataArray) – A boolean mask where True indicates land areas.

  • start_point (tuple) – Coordinates of the river mouth (row, column) to begin plume delimitation.

  • max_steps (int, optional) – Maximum number of steps to compute gradients in each direction, by default 20.

  • SPM_threshold (float, optional) – Threshold for SPM concentration to distinguish plume areas, by default 0.5.

Returns:

A polygon path object representing the delimited river plume area.

Return type:

matplotlib.path.Path

Notes

  • The function relies on computing gradients in multiple directions from the start point to determine the boundaries of the plume.

  • Gradients are analyzed to determine areas where SPM concentration decreases sharply.

  • A convex hull is constructed to define the plume boundary.

Examples

>>> plume_path = fast_delimit_plume_area(
...     spm_map=spm_map,
...     land_mask=land_mask,
...     start_point=(50, 50),
...     max_steps=30,
...     SPM_threshold=0.5
... )
>>> plt.imshow(spm_map, cmap='viridis')
>>> plt.plot(plume_path.vertices[:, 0], plume_path.vertices[:, 1], 'r-')
>>> plt.show()
panache.plume_algorithm.filter_gradient_points(gradient_values, gradient_points, absolute_values, land_mask, threshold_on_gradient_values)[source]#

Filters gradient points based on the gradient values and proximity to land.

Parameters:
  • gradient_values (ndarray) – 2D array of gradient values for each direction and step.

  • gradient_points (ndarray) – Array of coordinates (y, x) corresponding to the gradient values.

  • absolute_values (ndarray) – Absolute values associated with the gradient points.

  • land_mask (ndarray) – Binary mask indicating land (1) and water (0) areas.

  • threshold_on_gradient_values (float) – Threshold for gradient value filtering.

Returns:

  • gradient_points_to_keep (ndarray) – Filtered coordinates of gradient points that meet the criteria.

  • gradient_values_to_keep (ndarray) – Filtered gradient values corresponding to the kept points.

  • absolute_values_to_keep (ndarray) – Filtered absolute values corresponding to the kept points.

panache.plume_algorithm.find_SPM_threshold(spm_map, land_mask, start_point, directions, max_steps, maximal_threshold, minimal_threshold, quantile_to_use, gradient_steepness_fraction=0.9)[source]#

Finds the Suspended Particulate Matter (SPM) threshold by analyzing gradients in specified directions and filtering gradient points.

Parameters:
  • spm_map (ndarray) – 2D array representing SPM concentrations.

  • land_mask (ndarray) – Boolean mask where True indicates land and False indicates water.

  • start_point (tuple) – Starting point (y, x) for gradient computation.

  • directions (list) – List of direction vectors for gradient computation.

  • gradient_steepness_fraction (float, optional) – Fraction of the single steepest finite gradient (not a percentile of the gradient distribution) that a transect point’s gradient must clear to be kept as an edge candidate (default 0.9).

Returns:

SPM_threshold – The computed SPM threshold value.

Return type:

float

panache.plume_algorithm.find_connected_shapes(shape_1, shape_2)[source]#

Identify connected shapes in one mask that overlap with another mask.

Parameters:
  • shape_1 (xr.DataArray) – First boolean mask for connected shape identification.

  • shape_2 (xr.DataArray) – Second boolean mask indicating overlap regions.

Returns:

Boolean mask of connected shapes in shape_1 overlapping with shape_2.

Return type:

xr.DataArray

panache.plume_algorithm.find_direction_indices_and_values(mask_area, ds_reduced, pixel_starting_point, searching_strategy_direction, max_steps)[source]#

Identify and retrieve index and values along multiple directions in the plume area.

Parameters:
  • mask_area (xr.DataArray) – Boolean mask indicating the plume area.

  • ds_reduced (xr.DataArray) – Reduced spatial dataset for analysis.

  • pixel_starting_point (tuple) – Starting pixel coordinates (row, column) for the search.

  • searching_strategy_direction (np.ndarray) – Array of direction vectors for searching in the plume area.

Returns:

  • boolean_values_in_the_area_of_the_plume : list Boolean values of pixels in the identified plume area.

  • values_in_the_area_of_the_plume : list Data values of the identified plume area.

  • direction_points : np.ndarray Coordinates of the points in the identified directions.

Return type:

tuple

panache.plume_algorithm.find_first_nan_after_finite(arr)[source]#

Detects the first NaN value that occurs after finite values in a 3D array.

Parameters:

arr (ndarray) – 3D array of shape (n_steps, 1, n_directions), where the second dimension is 1.

Returns:

first_nan_indices – Array containing the index of the first NaN value after finite values for each direction. If no such NaN exists, returns -1 for that direction.

Return type:

ndarray

panache.plume_algorithm.find_high_value_pixels(data, center_lat, center_lon, radius_km, SPM_threshold)[source]#

Identify pixels in a 2D dataset that are within a specified radius from a given center point and have values exceeding a threshold.

Parameters:
  • data (numpy.ndarray) – A 2D array representing the input data (e.g., satellite data).

  • center_lat (float) – Latitude of the center point in degrees.

  • center_lon (float) – Longitude of the center point in degrees.

  • radius_km (float) – Radius within which pixels are considered, in kilometers.

  • SPM_threshold (float) – Threshold value. Pixels with values greater than this threshold will be included in the mask.

Returns:

A boolean 2D array where True indicates pixels that are within the specified radius and exceed the threshold.

Return type:

numpy.ndarray

Notes

The function uses the Haversine formula to calculate the great-circle distance between each pixel and the specified center point. Only pixels within the radius and above the threshold are included in the returned mask.

Examples

>>> import numpy as np
>>> # Create a sample 2D dataset with latitudes and longitudes
>>> lat = np.linspace(-10, 10, 5)  # 5 latitudes from -10 to 10 degrees
>>> lon = np.linspace(-20, 20, 5)  # 5 longitudes from -20 to 20 degrees
>>> data = np.random.rand(len(lat), len(lon)) * 100  # Random data values
>>> # Define center and parameters
>>> center_lat = 0
>>> center_lon = 0
>>> radius_km = 1000
>>> SPM_threshold = 50
>>> mask = find_high_value_pixels(data, center_lat, center_lon, radius_km, SPM_threshold)
>>> print(mask)
[[False  True False ...  True]
 [ True False False ...]]
panache.plume_algorithm.find_nearest_valid_start(data, start, directions, max_radius=50)[source]#

Find the nearest finite pixel to start along the principal fan direction.

If start itself is finite it is returned immediately. Otherwise the function walks one pixel at a time in the principal direction of the fan (the middle element of directions) until it finds a finite pixel or exhausts max_radius steps. If no finite pixel is found the original start is returned unchanged (preserving the pre-existing empty-mask behaviour as a fallback).

panache.plume_algorithm.find_starting_point_index(ds_reduced, starting_point)[source]#

Locate the index of the plume’s starting point in the reduced dataset.

Parameters:
  • ds_reduced (xr.DataArray) – Reduced spatial dataset.

  • starting_point (tuple) – Latitude and longitude of the plume’s starting point.

Returns:

Index of the starting point as (row, column).

Return type:

tuple

panache.plume_algorithm.first_true_block(arr)[source]#

Finds the position of the first contiguous block of True values in a boolean array.

Parameters:

arr (np.ndarray) – A 1D boolean array.

Returns:

A tuple (start, end) indicating the start and end indices of the first block of True values. If no True values are found, returns (-1, -1).

Return type:

tuple

panache.plume_algorithm.flood_fill(data, start, SPM_threshold, directions)[source]#

Perform a flood fill on a 2D array, starting from a given point and marking cells based on a specified threshold and direction vectors.

Parameters:
  • data (numpy.ndarray) – A 2D array representing the input data (e.g., satellite or environmental data).

  • start (tuple of int) – The starting position for the flood fill as (row, column).

  • SPM_threshold (float) – Threshold value. Cells with values greater than or equal to this threshold will be marked as part of the mask.

  • directions (list of tuple of int) – List of direction vectors (e.g., [(0, 1), (1, 0), …]) that determine how neighboring cells are inspected during the flood fill process.

Returns:

  • mask (numpy.ndarray) – A boolean 2D array with True indicating cells that meet the threshold and are part of the flood-filled region.

  • done_pixels (numpy.ndarray) – A boolean 2D array with True indicating all cells that were visited during the flood fill process.

Notes

  • The flood fill checks neighboring cells based on the specified directions.

  • Handles special cases where neighboring cells are NaN by searching for the closest finite values.

  • Ensures continuity in marking when there are gaps exceeding the threshold within the same direction.

Examples

>>> import numpy as np
>>> from collections import deque
>>> # Create sample data
>>> data = np.array([
...     [0, 0, 3, 4, 5],
...     [0, 2, 4, 5, 6],
...     [1, 3, 5, 7, 8],
...     [0, 1, 2, 3, 4]
... ])
>>> start = (2, 2)
>>> SPM_threshold = 4
>>> directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
>>> mask, done_pixels = flood_fill(data, start, SPM_threshold, directions)
>>> print(mask)
[[False False False  True False]
 [False False  True  True  True]
 [False False  True  True  True]
 [False False False False False]]

Note: (0, 4) remains False despite having value 5 because it can only be reached from boundary pixels (0, 3) and (1, 4), both of which trigger the any-neighbour- out-of-bounds guard and do not expand further.

panache.plume_algorithm.haversine(lat1, lon1, lat2, lon2)[source]#

Calculate the great-circle distance between two points on the Earth’s surface.

Parameters:
  • lat1 (float) – Latitude of the first point in degrees.

  • lon1 (float) – Longitude of the first point in degrees.

  • lat2 (float) – Latitude of the second point in degrees.

  • lon2 (float) – Longitude of the second point in degrees.

Returns:

Distance between the two points in kilometers.

Return type:

float

panache.plume_algorithm.identify_plume_shape_label(mask_area, core_of_the_plume)[source]#

Assigns a label to the main plume area, which is the one covering the coordinates of the plume core.

Parameters:
  • mask_area (xarray.DataArray) – A boolean array indicating the pixels inside (True) or outside (False) the plume area.

  • core_of_the_plume (tuple of float) – A tuple containing the (latitude, longitude) coordinates of the plume’s core.

Returns:

  • label_of_the_plume_shape (int) – The label corresponding to the main plume area.

  • labeled_array (numpy.ndarray) – A 2D array where each connected shape in the mask is assigned a unique label.

  • num_features (int) – The total number of unique connected shapes (features) identified in the mask.

Notes

If the core pixel does not belong to any labeled shape (label is 0), the function identifies the closest shape to the plume core based on centroid distance.

panache.plume_algorithm.is_area_too_cloudy(dataset, cloud_check_water_mask, parameters)[source]#

Check if a specific area within the dataset is too cloudy based on a threshold.

This function evaluates cloud coverage within a defined sub-area of the dataset by counting missing pixels over water against a user-defined threshold.

Parameters:
  • dataset (xarray.DataArray) – The dataset containing the data to evaluate for cloud coverage.

  • cloud_check_water_mask (xarray.DataArray) – Boolean mask on the input grid where True represents water pixels to include in the cloud-coverage calculation.

  • parameters (dict) –

    Dictionary of parameters, including:

    • lat_range_of_plume_area (tuple of float): latitude range of the sub-area to evaluate.

    • lon_range_of_plume_area (tuple of float): longitude range of the sub-area to evaluate.

    • threshold_of_cloud_coverage_in_percentage (float): percentage threshold above which the area is considered too cloudy.

Returns:

True if the area is too cloudy (exceeds the threshold), False otherwise.

Return type:

bool

panache.plume_algorithm.last_true_block(arr)[source]#

Finds the position of the last contiguous block of True values in a boolean array.

Parameters:

arr (np.ndarray) – A 1D boolean array.

Returns:

A tuple (start, end) indicating the start and end indices of the last block of True values. If no True values are found, returns (-1, -1).

Return type:

tuple

panache.plume_algorithm.load_and_filter_arrays(file_name)[source]#

Loads a file and filters its arrays based on specific criteria.

Parameters:

file_name (str) – Path to the file to load.

Returns:

A dictionary containing filtered arrays and other values from the file.

Return type:

dict

panache.plume_algorithm.main_process(file_name, ds, parameters, bathy_data_aligned, cloud_check_water_mask, land_mask, inside_polygon_mask, output_stem, dynamic_thresh, coast_shape=None, precomputed_threshold=None, color_limits=None)[source]#

Process a single, already-loaded satellite data scene for plume detection.

This function detects and analyzes plumes in a satellite data scene by applying thresholds, masks, and other criteria.

Parameters:
  • file_name (str) – Path to the satellite data file (used only for output naming).

  • ds (xr.DataArray) – Pre-loaded SPM map for this scene, as returned by load_map_data.

  • parameters (dict) – Configuration parameters for plume detection.

  • bathymetry_data_aligned_to_reduced_map (xr.DataArray) – Bathymetric data aligned to the input grid.

  • coast_shapefolder (gpd.GeoDataFrame) – Shapefile of coastline for plotting.

  • cloud_check_water_mask (xr.DataArray) – Water mask used for cloud coverage checks on the input grid.

  • land_mask (xr.DataArray) – Mask identifying land pixels.

  • inside_polygon_mask (xr.DataArray) – Mask to limit processing area inside a specific polygon.

Returns:

(rows, mask_out): one statistics dict per river plus one zone-wide river='ALL' aggregate row, and a (time, river, lat, lon) int8 mask array (one layer per river plus an 'ALL' union layer).

Return type:

tuple[list[dict], xr.DataArray]

panache.plume_algorithm.make_the_plot(path_to_the_figure_file_to_save, ds, ds_reduced, lon_range_of_plume_area, lat_range_of_plume_area, bathymetric_threshold, bathymetry_data_aligned_to_reduced_map, thresholds, plot_the_plume_area, coast_shape=None, mask_area=None, close_river_mouth_area=None, pixel_done=None, show_bathymetric_mask=False, color_limits=None, starting_points=None, core_of_the_plumes=None, plume_masks=None, transect_points_explored=None, transect_points_used=None, resuspension_removed_masks=None, resuspension_distance_threshold=None, resuspension_bathymetric_threshold=None)[source]#

Generate and save a visualization comparing the original and processed datasets, including optional plume and bathymetric masks.

Parameters:
  • path_to_the_figure_file_to_save (str) – Path to save the generated figure as a PNG file.

  • ds (xarray.DataArray) – Original dataset to be plotted on the first subplot.

  • ds_reduced (xarray.DataArray) – Processed or reduced dataset used to determine color bar limits and optional masking.

  • lon_range_of_plume_area (tuple of float) – Longitude range (min, max) for both subplots.

  • lat_range_of_plume_area (tuple of float) – Latitude range (min, max) for both subplots.

  • bathymetric_threshold (float) – Depth threshold (in meters) used to create a bathymetric mask.

  • bathymetry_data_aligned_to_reduced_map (xarray.DataArray) – Bathymetry dataset aligned with the reduced dataset grid.

  • thresholds (dict) – Dictionary containing SPM thresholds to describe the plume area in the title (e.g., {“threshold1”: value1, “threshold2”: value2}).

  • plot_the_plume_area (bool) – If True, plots the plume area on the second subplot; otherwise, the second subplot contains a placeholder message.

  • coast_shape (geopandas.GeoDataFrame) – Shapefile of coastal boundary used for overlaying on the plots. Optional, default is None.

  • mask_area (xarray.DataArray, optional) – Mask indicating the plume area to highlight, with True values for plume pixels. Default is None.

  • plume_masks (dict[str, xarray.DataArray], optional) – Per-river boolean masks. When provided, each river’s mask is drawn in its own shade of red with a legend at the bottom of the figure, instead of mask_area being drawn as a single flat red region. Default is None.

  • pixel_done (xarray.DataArray, optional) – Boolean mask indicating pixels that were processed, with True for processed pixels. Default is None.

  • show_bathymetric_mask (bool, optional) – If True, overlays a bathymetric mask on the second subplot. Default is False.

  • transect_points_explored (dict[str, ndarray], optional) – Per-river (N, 2) arrays of [lon, lat] pairs sampled by the dynamic-threshold gradient search: every point explored, and the subset actually retained to compute the threshold. Drawn as grey dots and river-coloured/black-edged dots respectively on the second subplot. Default is None.

  • transect_points_used (dict[str, ndarray], optional) – Per-river (N, 2) arrays of [lon, lat] pairs sampled by the dynamic-threshold gradient search: every point explored, and the subset actually retained to compute the threshold. Drawn as grey dots and river-coloured/black-edged dots respectively on the second subplot. Default is None.

  • resuspension_removed_masks (dict[str, xarray.DataArray], optional) – Per-river boolean masks of pixels removed by the resuspension filter, drawn as a hatched overlay in that river’s colour on the second subplot. Default is None.

  • resuspension_distance_threshold (dict[str, float], optional) – Per-river minimal_distance_from_estuary_for_zone_with_resuspension (km) and maximal_bathymetric_for_zone_with_resuspension (m) values, drawn as a dashed circle and a contour line respectively, both in that river’s colour, on the second subplot. Default is None.

  • resuspension_bathymetric_threshold (dict[str, float], optional) – Per-river minimal_distance_from_estuary_for_zone_with_resuspension (km) and maximal_bathymetric_for_zone_with_resuspension (m) values, drawn as a dashed circle and a contour line respectively, both in that river’s colour, on the second subplot. Default is None.

Returns:

The function saves the figure to the specified path and does not return any value.

Return type:

None

Notes

  • The function uses logarithmic normalization for the color scale of the plotted datasets.

  • The bathymetric mask is created based on the specified depth threshold.

  • The title of the second subplot dynamically includes SPM thresholds and bathymetric information.

  • If plot_the_plume_area is False, the second subplot shows a placeholder message indicating no plume detection.

Examples

>>> import xarray as xr
>>> import geopandas as gpd
>>> # Example inputs
>>> ds = xr.DataArray(...)
>>> ds_reduced = xr.DataArray(...)
>>> coast_shapefolder = geopandas.GeoDataFrame(...)
>>> lon_range = (-10, 10)
>>> lat_range = (40, 50)
>>> bathymetry = xr.DataArray(...)
>>> thresholds = {"threshold1": 0.5, "threshold2": 1.0}
>>> make_the_plot(
...     "output_figure",
...     ds,
...     ds_reduced,
...     lon_range,
...     lat_range,
...     coast_shape,
...     bathymetric_threshold=50,
...     bathymetry_data_aligned_to_reduced_map=bathymetry,
...     thresholds=thresholds,
...     plot_the_plume_area=True
... )
panache.plume_algorithm.merge_close_shapes(mask_area, core_of_the_plume, land_mask, structure_of_the_dilation)[source]#

Merges the main plume shape in a mask with nearby shapes if they are close enough. This process adjusts the mask to include neighboring shapes that, when connected, form a single larger shape.

Parameters:
  • mask_area (xarray.DataArray) – A boolean array (mask) indicating the pixels inside (True) or outside (False) the plume area.

  • core_of_the_plume (tuple of float) – Coordinates (latitude, longitude) identifying the core of the plume shape to be preserved (i.e., the main plume shape).

  • land_mask (xarray.DataArray) – A boolean array where True indicates land areas that must not be part of the plume shape.

  • structure_of_the_dilation (numpy.ndarray) – Structuring element used for the morphological dilation of the main plume shape to connect it to neighboring plume areas if they are close enough.

Returns:

mask_area – The updated mask where the plume shape has potentially been merged with nearby shapes.

Return type:

xarray.DataArray

panache.plume_algorithm.pixels_far_from_land(land_mask, pixel_positions, distance_threshold)[source]#

Filters pixel positions based on their proximity to land.

Parameters:
  • land_mask (ndarray) – Boolean array where True indicates land and False indicates water.

  • pixel_positions (ndarray) – Array of shape (n_positions, 2) representing pixel coordinates [(y, x), …].

  • distance_threshold (float) – Minimum allowable distance from land in pixels.

Returns:

filtered_positions – Boolean array of shape (n_positions,) indicating whether each pixel is sufficiently far from land.

Return type:

ndarray

panache.plume_algorithm.remove_resuspension_pixels(ds_reduced, mask_area, land_mask, bathymetry_data_aligned_to_reduced_map, core_of_the_plume, bathymetric_threshold_for_zone_with_resuspension, distance_from_estuary_threshold)[source]#

Remove coastal areas influenced by sediment resuspension based on given criteria.

Parameters:
  • ds_reduced (xr.DataArray) – Reduced spatial dataset representing suspended particulate matter (SPM).

  • mask_area (xr.DataArray) – Boolean mask indicating areas currently considered part of the plume (including any cloud-gap pixels already promoted by include_cloudy_regions).

  • land_mask (xr.DataArray) – Boolean mask indicating land areas.

  • bathymetry_data_aligned_to_reduced_map (xr.DataArray) – Aligned bathymetry data for the reduced dataset.

  • core_of_the_plume (tuple) – Latitude and longitude of the plume core (estuary location).

  • bathymetric_threshold_for_zone_with_resuspension (float) – Depth threshold (negative values) for zones with sediment resuspension.

  • distance_from_estuary_threshold (float) – Maximum allowable distance (in kilometers) from the estuary for resuspension zones.

Returns:

Updated mask with resuspension areas removed.

Return type:

xr.DataArray

panache.plume_algorithm.return_stats_dictionnary(final_mask_area, spm_reduced_map, spm_map, parameters, river_name, spm_threshold=None, return_empty_dict=False)[source]#

Compute or return an empty dictionary with statistics about the plume area.

Parameters:
  • final_mask_area (xr.DataArray) – Boolean mask of the plume area (a single river’s mask, or the zone-wide union when river_name='ALL').

  • spm_reduced_map (xr.DataArray) – SPM dataset at reduced resolution.

  • spm_map (xr.DataArray) – Original SPM dataset.

  • parameters (dict) – Dictionary of map parameters (e.g., resolution, ranges).

  • river_name (str) – Name of the river this row is attributed to, or 'ALL' for the zone-wide aggregate row.

  • spm_threshold (float or None, optional) – SPM threshold used for this river; None (e.g. for the 'ALL' row, which spans multiple rivers/thresholds) is stored as NaN.

  • return_empty_dict (bool, optional) – If True, return an empty dictionary with NaN values.

Returns:

Dictionary containing plume statistics or an empty dictionary with NaN values.

Return type:

dict

panache.plume_algorithm.set_cloudy_regions_true(ds_reduced, mask_area, land_mask, SPM_threshold)[source]#

Refines the plume shape by marking cloudy areas as part of the plume if they are enclosed by SPM concentrations higher than the SPM_threshold. This function helps address the issue of cloudy regions disrupting plume detection.

Parameters:
  • ds_reduced (xarray.DataArray) – The Suspended Particulate Matter (SPM) map containing concentration values.

  • mask_area (xarray.DataArray) – A boolean mask indicating the plume area (True for plume, False otherwise).

  • land_mask (xarray.DataArray) – A mask indicating land areas (True for land, False for ocean).

  • SPM_threshold (float) – The SPM threshold value used to detect and confirm the plume area.

Returns:

mask_area – Updated boolean mask where additional cloudy areas have been marked as True.

Return type:

xarray.DataArray

panache.plume_algorithm.set_mask_false_by_index(mask_area, index_object, gradient_points)[source]#

Modify a mask array by setting values to False for points outside a polygon defined by gradient points.

Parameters:
  • mask_area (numpy.ndarray) – A 2D array representing the mask area where True values indicate active regions.

  • index_object (numpy.ndarray) – Array of indices representing the points used to define the polygon.

  • gradient_points (numpy.ndarray) – Array of points representing gradient vectors.

Returns:

Updated mask area with False values outside the polygon.

Return type:

numpy.ndarray