Density#
- Hydrological_model_validator.Processing.Density.calc_density(temp_3d: ndarray, sal_3d: ndarray, depths: ndarray, valid_mask, density_method: str) ndarray[source]#
Calculate seawater density based on temperature, salinity, and depth using the specified density method.
- Parameters:
temp_3d (np.ndarray) – 3D array of temperature values (depth x lat x lon).
sal_3d (np.ndarray) – 3D array of salinity values (depth x lat x lon).
depths (np.ndarray) – 1D array of depth levels in meters (length = depth dimension of temp_3d).
valid_mask (np.ndarray or None) – Optional mask array; if None, valid values are where temp and sal are not NaN. (In this function, valid_mask is redefined internally, so input is ignored.)
density_method (str) – Method for density calculation. One of: “EOS”, “EOS80”, “TEOS10”.
- Returns:
3D array of seawater density values (depth x lat x lon).
- Return type:
np.ndarray
- Raises:
ValueError – If density_method is not one of the supported options.
Examples
>>> import numpy as np >>> import gsw >>> depth_levels = np.array([0, 10, 20]) >>> temp = np.array([ ... [[10, 11], [12, 13]], ... [[9, 10], [11, 12]], ... [[8, 9], [10, 11]] ... ]) >>> sal = np.array([ ... [[35, 35], [35, 35]], ... [[34.5, 34.5], [34.5, 34.5]], ... [[34, 34], [34, 34]] ... ]) >>> density = calc_density(temp, sal, depth_levels, None, "EOS") >>> print(density.shape) (3, 2, 2) >>> print(np.round(density, 2)) [[[1025. 1024.8 ] [1025.2 1025.4 ]]
- [[1024.6 1024.4 ]
[1024.8 1025. ]]
- [[1024.2 1024. ]
[1024.4 1024.6 ]]]
- Hydrological_model_validator.Processing.Density.compute_Bleast(mask3d: ndarray) ndarray[source]#
Extract the first (top) layer from a 3D mask array along the depth axis.
- Parameters:
mask3d (np.ndarray) – 3D array of shape (depth, rows, cols).
- Returns:
2D array of shape (rows, cols) corresponding to the first layer mask3d[0, :, :].
- Return type:
np.ndarray
Examples
>>> mask3d = np.array([[[1, 0], [0, 1]], [[0, 1], [1, 0]]]) >>> compute_Bleast(mask3d) array([[1, 0], [0, 1]])
- Hydrological_model_validator.Processing.Density.compute_Bmost(mask3d: ndarray) ndarray[source]#
Compute a 2D array by summing the 3D mask array along the depth axis.
- Parameters:
mask3d (np.ndarray) – 3D binary mask array with shape (depth, rows, cols), where valid data points are typically marked as 1, invalid as 0.
- Returns:
2D array (rows, cols) where each element is the count of valid depth levels (sum of mask) at that spatial location.
- Return type:
np.ndarray
Notes
Summation is performed over the depth dimension (axis=0), equivalent to counting valid levels for each (row, col).
Examples
>>> mask3d = np.array([[[1, 0], [0, 1]], [[0, 1], [1, 0]]]) >>> compute_Bmost(mask3d) array([[1, 1], [1, 1]])
- Hydrological_model_validator.Processing.Density.compute_dense_water_volume(IDIR: str | Path, mask3d: ndarray, filename_fragments: dict, density_method: str, dz: float = 2.0, dx: float = 800.0, dy: float = 800.0, dens_threshold: float = 1029.2) List[Dict][source]#
Compute the volume of dense water masses (density >= dens_threshold kg/m³) over time from oceanographic temperature and salinity data.
- Parameters:
IDIR (Union[str, Path]) – Directory path containing yearly subfolders with compressed NetCDF files. Each subfolder named like ‘outputYYYY’ contains the data for year YYYY.
mask3d (np.ndarray) – 3D boolean mask array of shape (depth, Y, X), where True means the cell is masked/excluded.
filename_fragments (dict) – Dictionary with keys ‘ffrag1’, ‘ffrag2’, ‘ffrag3’ used to construct filenames for the data files.
density_method (str) – Method to calculate seawater density. Must be one of “EOS”, “EOS80”, or “TEOS10”.
dz (float, optional) – Vertical thickness of each grid layer in meters (default 2.0 m).
dx (float, optional) – Horizontal grid spacing in meters along the x-axis (default 800.0 m).
dy (float, optional) – Horizontal grid spacing in meters along the y-axis (default 800.0 m).
dens_threshold (float, optional) – Density threshold in kg/m³ to define dense water (default 1029.2 kg/m³).
- Returns:
List of dictionaries, each containing: - ‘date’: datetime object for the first day of each month, - ‘volume_m3’: volume of dense water (in cubic meters) for that month.
- Return type:
List[Dict]
Notes
The function expects yearly subdirectories named as ‘outputYYYY’ inside IDIR.
Temperature and salinity are read from compressed NetCDF files.
Cells masked by mask3d are excluded from volume calculation.
Density is computed per cell per time using the specified density method.
The dense water volume is calculated by counting cells exceeding the density threshold and multiplying by the cell volume (dx * dy * dz).
Examples
>>> from pathlib import Path >>> import numpy as np >>> mask = np.zeros((50, 100, 100), dtype=bool) # no masked cells >>> filename_fragments = {'ffrag1': 'data', 'ffrag2': 'temp', 'ffrag3': 'sal'} >>> IDIR = Path('/path/to/ocean_data') >>> dense_volumes = compute_dense_water_volume( ... IDIR=IDIR, ... mask3d=mask, ... filename_fragments=filename_fragments, ... density_method="EOS80", ... dz=2.0, ... dx=800.0, ... dy=800.0, ... dens_threshold=1029.2 ... ) >>> print(dense_volumes[0]) {'date': datetime.datetime(2000, 1, 1, 0, 0), 'volume_m3': 1234567.89}
- Hydrological_model_validator.Processing.Density.compute_density_bottom(temperature_data: dict, salinity_data: dict, Bmost: ndarray, method: str, dz: float = 2.0) dict[source]#
Compute seawater density (kg/m³) at benthic depth using the specified method.
- Parameters:
temperature_data (dict) – Dictionary keyed by year (int or str), each containing a list of 12 arrays representing bottom temperature for each month.
salinity_data (dict) – Dictionary keyed by year, each containing a list of 12 arrays representing bottom salinity for each month.
Bmost (np.ndarray) – 2D array (Y, X) containing the 1-based index of the deepest valid vertical level.
method (str) – Method to compute density. Supported options: - ‘EOS’: Linear equation of state approximation. - ‘EOS80’: EOS-80 potential density at surface. - ‘TEOS10’: TEOS-10 absolute density with pressure.
dz (float, optional) – Vertical layer thickness in meters (default is 2.0 m).
- Returns:
density_data – Dictionary keyed by year, each containing a list of 12 arrays with computed density fields corresponding to the monthly bottom data.
- Return type:
dict
- Raises:
ValueError – If an unsupported method is passed or the density output shape is unexpected.
Example
>>> # Assume temperature_data and salinity_data are loaded dictionaries as described >>> # Bmost is a 2D numpy array indicating bottom layer indices >>> method = 'EOS80' >>> density = compute_density_bottom(temperature_data, salinity_data, Bmost, method) >>> # density is a dict {year: [12 arrays]}, each array is density at benthic depth for that month
- Hydrological_model_validator.Processing.Density.filter_dense_water_masses(density_data: Dict[int, List[ndarray]], threshold: float = 1029.2) Dict[int, List[ndarray]][source]#
Filter density data to retain only dense water masses with density values greater than or equal to the specified threshold.
- Parameters:
density_data (dict) – Dictionary with keys as years (int) and values as lists of 12 2D numpy arrays, each representing monthly seawater density fields.
threshold (float, optional) – Density threshold in kg/m³ for defining dense water masses. Values below this threshold will be masked out (default is 1029.2).
- Returns:
filtered_data – Dictionary with the same structure as input, where density values below the threshold are replaced with np.nan, retaining only dense water masses.
- Return type:
dict
Examples
>>> import numpy as np >>> density_data = { ... 2000: [np.array([[1029.3, 1028.9], [1029.5, 1027.0]]) for _ in range(12)], ... 2001: [np.array([[1029.1, 1029.0], [1028.0, 1030.0]]) for _ in range(12)] ... } >>> filtered = filter_dense_water_masses(density_data, threshold=1029.2) >>> print(filtered[2000][0]) [[1029.3 nan] [1029.5 nan]] >>> print(filtered[2001][0]) [[ nan nan] [ nan 1030.0]]