model_output package#
Submodules#
PyHydroGeophysX.model_output.base module#
Base classes for model output processing.
- class PyHydroGeophysX.model_output.base.HydroModelOutput(model_directory: str)[source]#
Bases:
ABCBase class for all hydrological model outputs.
- calculate_saturation(water_content: ndarray, porosity: float | ndarray) ndarray[source]#
Calculate saturation from water content and porosity.
- Parameters:
water_content – Water content array
porosity – Porosity value(s)
- Returns:
Saturation array
- abstractmethod get_timestep_info() List[Tuple][source]#
Get information about each timestep.
- Returns:
List of timestep information tuples
- abstractmethod load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs) ndarray[source]#
Load data for a range of timesteps.
- Parameters:
start_idx – Starting timestep index
end_idx – Ending timestep index (exclusive)
**kwargs – Additional parameters specific to the model type
- Returns:
Data array for the specified timestep range
PyHydroGeophysX.model_output.modflow_output module#
Deprecated import path for canonical MODFLOW water-content readers.
- class PyHydroGeophysX.model_output.modflow_output.MODFLOWPorosity(model_directory: str, model_name: str)[source]#
Bases:
HydroModelOutputClass for processing porosity data from MODFLOW simulations.
- get_timestep_info() List[Tuple][source]#
Get information about each timestep in the model. Returns a minimal placeholder since porosity doesn’t vary with time.
- Returns:
List with single dummy timestep info
- load_porosity() ndarray[source]#
Load porosity data from MODFLOW model (supports both MODFLOW 6 and earlier versions).
- Returns:
3D array of porosity values (nlay, nrow, ncol)
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs) ndarray[source]#
Load porosity for a range of timesteps. Since porosity is typically constant, this returns a stack of identical arrays.
- Parameters:
start_idx – Starting timestep index (unused)
end_idx – Ending timestep index (unused)
- Returns:
4D array of porosity values (nt, nlay, nrow, ncol) where all timesteps are identical
- load_timestep(timestep_idx: int, **kwargs) ndarray[source]#
Load porosity for a specific timestep. Note: For MODFLOW, porosity is typically constant over time, so this returns the same array regardless of timestep.
- Parameters:
timestep_idx – Index of the timestep (unused)
- Returns:
3D array of porosity values
- class PyHydroGeophysX.model_output.modflow_output.MODFLOWWaterContent(model_directory: str, idomain: ndarray)[source]#
Bases:
HydroModelOutputClass for processing water content data from MODFLOW simulations.
- get_timestep_info() List[Tuple[int, int, float, float]][source]#
Get information about each timestep in the WaterContent file.
- Returns:
List of tuples (kstp, kper, pertim, totim) for each timestep
- load_time_range(start_idx: int = 0, end_idx: int | None = None, nlay: int = 3) ndarray[source]#
Load water content for a range of timesteps.
- Parameters:
start_idx – Starting timestep index (default: 0)
end_idx – Ending timestep index (exclusive, default: None loads all)
nlay – Number of layers in the model (default: 3)
- Returns:
Water content array with shape (timesteps, nlay, nrows, ncols)
- PyHydroGeophysX.model_output.modflow_output.binaryread(file: Any, vartype: Any, shape: Any = (1,), charlen: Any = 16) Any[source]#
Uses numpy to read from binary file. This was found to be faster than the struct approach and is used as the default.
- Parameters:
file – Open file object in binary read mode
vartype – Variable type to read
shape – Shape of the data to read (default: (1,))
charlen – Length of character strings (default: 16)
- Returns:
The read data
PyHydroGeophysX.model_output.parflow_output module#
Module for processing ParFlow model outputs.
This module provides classes to handle specific types of ParFlow outputs, such as saturation and porosity, by reading ParFlow Binary Files (PFB). It includes a standalone PFB reader that works without the parflow package, falling back to the parflow package if available for maximum compatibility.
- class PyHydroGeophysX.model_output.parflow_output.ParflowOutput(model_directory: str, run_name: str)[source]#
Bases:
HydroModelOutputBase class for processing ParFlow model outputs.
This class handles common ParFlow output functionalities, such as identifying available timesteps and reading PFB files. It uses the standalone PFB reader that works without the parflow package installed.
- get_pfb_dimensions(pfb_file_path: str) Tuple[int, int, int][source]#
Reads a PFB file and returns its data dimensions (nz, ny, nx).
- Parameters:
pfb_file_path (str) – The full path to the PFB file.
- Returns:
- The dimensions of the data in the PFB file,
typically in (nz, ny, nx) order for ParFlow.
- Return type:
Tuple[int, int, int]
- Raises:
FileNotFoundError – If the pfb_file_path does not exist.
Exception – If self.read_pfb (from parflow.tools.io) fails to read the file.
- class PyHydroGeophysX.model_output.parflow_output.ParflowPorosity(model_directory: str, run_name: str)[source]#
Bases:
ParflowOutputProcesses porosity data from ParFlow simulations. Porosity in ParFlow is typically static (time-invariant) and stored in a single PFB file (e.g., <run_name>.out.porosity.pfb or similar).
- get_timestep_info() List[Tuple[int, float]][source]#
Returns timestep information, typically based on other ParFlow outputs (like saturation) as porosity itself is static.
- Returns:
- A list of (timestep_number, time_value) tuples,
derived from self.available_timesteps.
- Return type:
List[Tuple[int, float]]
- load_mask() ndarray[source]#
Load the domain mask data from a ParFlow model. The mask file (.out.mask.pfb) indicates active (1) and inactive (0) cells.
- Returns:
- A 3D NumPy array representing the domain mask (nz, ny, nx).
Values are typically 0 or 1.
- Return type:
np.ndarray
- Raises:
FileNotFoundError – If no standard mask PFB file can be found.
ValueError – If there’s an error reading or processing the PFB file.
- load_porosity() ndarray[source]#
Load the static porosity data from the ParFlow model.
It searches for common ParFlow porosity filename patterns within the model directory.
- Returns:
A 3D NumPy array of porosity values (nz, ny, nx).
- Return type:
np.ndarray
- Raises:
FileNotFoundError – If no standard porosity PFB file can be found.
ValueError – If there’s an error reading or processing the PFB file.
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs: Any) ndarray[source]#
Load porosity data for a conceptual range of timesteps. Since porosity is time-invariant, this method returns a 4D array where the static 3D porosity data is repeated along the time axis.
The number of repetitions along the time axis (nt) is determined by the length of self.available_timesteps (discovered from saturation/pressure files) if end_idx is None, or by min(end_idx - start_idx, len(available_timesteps)). A minimum of 1 repetition is ensured if any timesteps are notionally available.
- Parameters:
start_idx (int, optional) – Starting timestep index (used to determine nt). Defaults to 0.
end_idx (Optional[int], optional) – Ending timestep index (exclusive, used for nt). Defaults to None (use all available timesteps).
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
- A 4D NumPy array of porosity values (nt, nz, ny, nx).
All slices along the time dimension are identical.
- Return type:
np.ndarray
- load_timestep(timestep_idx: int, **kwargs: Any) ndarray[source]#
Load porosity data. For ParFlow, porosity is typically time-invariant. This method returns the static porosity array, ignoring timestep_idx.
- Parameters:
timestep_idx (int) – Index of the timestep (ignored, as porosity is static).
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
A 3D NumPy array of porosity values (nz, ny, nx).
- Return type:
np.ndarray
- class PyHydroGeophysX.model_output.parflow_output.ParflowSaturation(model_directory: str, run_name: str)[source]#
Bases:
ParflowOutputProcesses saturation data from ParFlow simulations (.out.satur.*.pfb files).
- get_timestep_info() List[Tuple[int, float]][source]#
Provides information about available ParFlow timesteps.
For ParFlow, the timestep number from the filename often directly corresponds to the simulation time (e.g., if output is every 1 hour, timestep 24 is 24 hours). This method returns a list of tuples: (timestep_number, simulation_time). Currently, simulation_time is simply cast from timestep_number. More accurate time mapping would require parsing ParFlow timing files if complex.
- Returns:
- A list where each tuple is (timestep_number, time_value).
Time_value is float representation of timestep_number.
- Return type:
List[Tuple[int, float]]
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs: Any) ndarray[source]#
Load saturation data for a specified range of zero-based timestep indices.
- Parameters:
start_idx (int, optional) – Starting zero-based timestep index. Defaults to 0.
end_idx (Optional[int], optional) – Ending zero-based timestep index (exclusive). If None, loads up to the last available timestep. Defaults to None.
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
- A 4D NumPy array of saturation values (num_timesteps, nz, ny, nx).
Returns an empty 4D array if the range is invalid or no data is found.
- Return type:
np.ndarray
- Raises:
ValueError – If no timesteps are available, or if the specified range is invalid (e.g., start_idx out of bounds, end_idx <= start_idx leading to empty range).
- load_timestep(timestep_idx: int, **kwargs: Any) ndarray[source]#
Load saturation data for a specific, zero-based timestep index.
- Parameters:
timestep_idx (int) – The zero-based index of the timestep to load from the list of available timesteps discovered during initialization.
**kwargs (Any) – Additional keyword arguments (not used by this method).
- Returns:
A 3D NumPy array of saturation values (nz, ny, nx).
- Return type:
np.ndarray
- Raises:
ValueError – If no timesteps are available or if timestep_idx is out of range.
- PyHydroGeophysX.model_output.parflow_output.read_pfb(filename: str) ndarray[source]#
Read a ParFlow Binary (PFB) file.
Attempts to use the parflow package if available, otherwise falls back to the standalone pure-Python reader.
- Parameters:
filename – Path to the .pfb file
- Returns:
3D array of shape (nz, ny, nx) containing the data
- Return type:
np.ndarray
- PyHydroGeophysX.model_output.parflow_output.read_pfb_standalone(filename: str) ndarray[source]#
Read a ParFlow Binary (PFB) file without requiring the parflow package.
This is a pure Python/NumPy implementation that parses the PFB file format directly. PFB files store 3D data in a hierarchical subgrid structure.
- Parameters:
filename – Path to the .pfb file
- Returns:
3D array of shape (nz, ny, nx) containing the data
- Return type:
np.ndarray
- Raises:
FileNotFoundError – If the file does not exist
ValueError – If the file format is invalid
PyHydroGeophysX.model_output.water_content module#
Module for processing MODFLOW model outputs.
- class PyHydroGeophysX.model_output.water_content.MODFLOWPorosity(model_directory: str, model_name: str)[source]#
Bases:
HydroModelOutputClass for processing porosity data from MODFLOW simulations.
- get_timestep_info() List[Tuple][source]#
Get information about each timestep in the model. Returns a minimal placeholder since porosity doesn’t vary with time.
- Returns:
List with single dummy timestep info
- load_porosity() ndarray[source]#
Load porosity data from MODFLOW model (supports both MODFLOW 6 and earlier versions).
- Returns:
3D array of porosity values (nlay, nrow, ncol)
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs) ndarray[source]#
Load porosity for a range of timesteps. Since porosity is typically constant, this returns a stack of identical arrays.
- Parameters:
start_idx – Starting timestep index (unused)
end_idx – Ending timestep index (unused)
- Returns:
4D array of porosity values (nt, nlay, nrow, ncol) where all timesteps are identical
- load_timestep(timestep_idx: int, **kwargs) ndarray[source]#
Load porosity for a specific timestep. Note: For MODFLOW, porosity is typically constant over time, so this returns the same array regardless of timestep.
- Parameters:
timestep_idx – Index of the timestep (unused)
- Returns:
3D array of porosity values
- class PyHydroGeophysX.model_output.water_content.MODFLOWWaterContent(model_directory: str, idomain: ndarray)[source]#
Bases:
HydroModelOutputClass for processing water content data from MODFLOW simulations.
- get_timestep_info() List[Tuple[int, int, float, float]][source]#
Get information about each timestep in the WaterContent file.
- Returns:
List of tuples (kstp, kper, pertim, totim) for each timestep
- load_time_range(start_idx: int = 0, end_idx: int | None = None, nlay: int = 3) ndarray[source]#
Load water content for a range of timesteps.
- Parameters:
start_idx – Starting timestep index (default: 0)
end_idx – Ending timestep index (exclusive, default: None loads all)
nlay – Number of layers in the model (default: 3)
- Returns:
Water content array with shape (timesteps, nlay, nrows, ncols)
- PyHydroGeophysX.model_output.water_content.binaryread(file: Any, vartype: Any, shape: Any = (1,), charlen: Any = 16) Any[source]#
Uses numpy to read from binary file. This was found to be faster than the struct approach and is used as the default.
- Parameters:
file – Open file object in binary read mode
vartype – Variable type to read
shape – Shape of the data to read (default: (1,))
charlen – Length of character strings (default: 16)
- Returns:
The read data
Module contents#
Module for processing model outputs from various hydrological models.
- class PyHydroGeophysX.model_output.HydroModelOutput(model_directory: str)[source]#
Bases:
ABCBase class for all hydrological model outputs.
- calculate_saturation(water_content: ndarray, porosity: float | ndarray) ndarray[source]#
Calculate saturation from water content and porosity.
- Parameters:
water_content – Water content array
porosity – Porosity value(s)
- Returns:
Saturation array
- abstractmethod get_timestep_info() List[Tuple][source]#
Get information about each timestep.
- Returns:
List of timestep information tuples
- abstractmethod load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs) ndarray[source]#
Load data for a range of timesteps.
- Parameters:
start_idx – Starting timestep index
end_idx – Ending timestep index (exclusive)
**kwargs – Additional parameters specific to the model type
- Returns:
Data array for the specified timestep range
- class PyHydroGeophysX.model_output.MODFLOWPorosity(model_directory: str, model_name: str)[source]#
Bases:
HydroModelOutputClass for processing porosity data from MODFLOW simulations.
- get_timestep_info() List[Tuple][source]#
Get information about each timestep in the model. Returns a minimal placeholder since porosity doesn’t vary with time.
- Returns:
List with single dummy timestep info
- load_porosity() ndarray[source]#
Load porosity data from MODFLOW model (supports both MODFLOW 6 and earlier versions).
- Returns:
3D array of porosity values (nlay, nrow, ncol)
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs) ndarray[source]#
Load porosity for a range of timesteps. Since porosity is typically constant, this returns a stack of identical arrays.
- Parameters:
start_idx – Starting timestep index (unused)
end_idx – Ending timestep index (unused)
- Returns:
4D array of porosity values (nt, nlay, nrow, ncol) where all timesteps are identical
- load_timestep(timestep_idx: int, **kwargs) ndarray[source]#
Load porosity for a specific timestep. Note: For MODFLOW, porosity is typically constant over time, so this returns the same array regardless of timestep.
- Parameters:
timestep_idx – Index of the timestep (unused)
- Returns:
3D array of porosity values
- class PyHydroGeophysX.model_output.MODFLOWWaterContent(model_directory: str, idomain: ndarray)[source]#
Bases:
HydroModelOutputClass for processing water content data from MODFLOW simulations.
- get_timestep_info() List[Tuple[int, int, float, float]][source]#
Get information about each timestep in the WaterContent file.
- Returns:
List of tuples (kstp, kper, pertim, totim) for each timestep
- load_time_range(start_idx: int = 0, end_idx: int | None = None, nlay: int = 3) ndarray[source]#
Load water content for a range of timesteps.
- Parameters:
start_idx – Starting timestep index (default: 0)
end_idx – Ending timestep index (exclusive, default: None loads all)
nlay – Number of layers in the model (default: 3)
- Returns:
Water content array with shape (timesteps, nlay, nrows, ncols)
- class PyHydroGeophysX.model_output.ParflowPorosity(model_directory: str, run_name: str)[source]#
Bases:
ParflowOutputProcesses porosity data from ParFlow simulations. Porosity in ParFlow is typically static (time-invariant) and stored in a single PFB file (e.g., <run_name>.out.porosity.pfb or similar).
- get_timestep_info() List[Tuple[int, float]][source]#
Returns timestep information, typically based on other ParFlow outputs (like saturation) as porosity itself is static.
- Returns:
- A list of (timestep_number, time_value) tuples,
derived from self.available_timesteps.
- Return type:
List[Tuple[int, float]]
- load_mask() ndarray[source]#
Load the domain mask data from a ParFlow model. The mask file (.out.mask.pfb) indicates active (1) and inactive (0) cells.
- Returns:
- A 3D NumPy array representing the domain mask (nz, ny, nx).
Values are typically 0 or 1.
- Return type:
np.ndarray
- Raises:
FileNotFoundError – If no standard mask PFB file can be found.
ValueError – If there’s an error reading or processing the PFB file.
- load_porosity() ndarray[source]#
Load the static porosity data from the ParFlow model.
It searches for common ParFlow porosity filename patterns within the model directory.
- Returns:
A 3D NumPy array of porosity values (nz, ny, nx).
- Return type:
np.ndarray
- Raises:
FileNotFoundError – If no standard porosity PFB file can be found.
ValueError – If there’s an error reading or processing the PFB file.
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs: Any) ndarray[source]#
Load porosity data for a conceptual range of timesteps. Since porosity is time-invariant, this method returns a 4D array where the static 3D porosity data is repeated along the time axis.
The number of repetitions along the time axis (nt) is determined by the length of self.available_timesteps (discovered from saturation/pressure files) if end_idx is None, or by min(end_idx - start_idx, len(available_timesteps)). A minimum of 1 repetition is ensured if any timesteps are notionally available.
- Parameters:
start_idx (int, optional) – Starting timestep index (used to determine nt). Defaults to 0.
end_idx (Optional[int], optional) – Ending timestep index (exclusive, used for nt). Defaults to None (use all available timesteps).
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
- A 4D NumPy array of porosity values (nt, nz, ny, nx).
All slices along the time dimension are identical.
- Return type:
np.ndarray
- load_timestep(timestep_idx: int, **kwargs: Any) ndarray[source]#
Load porosity data. For ParFlow, porosity is typically time-invariant. This method returns the static porosity array, ignoring timestep_idx.
- Parameters:
timestep_idx (int) – Index of the timestep (ignored, as porosity is static).
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
A 3D NumPy array of porosity values (nz, ny, nx).
- Return type:
np.ndarray
- class PyHydroGeophysX.model_output.ParflowSaturation(model_directory: str, run_name: str)[source]#
Bases:
ParflowOutputProcesses saturation data from ParFlow simulations (.out.satur.*.pfb files).
- get_timestep_info() List[Tuple[int, float]][source]#
Provides information about available ParFlow timesteps.
For ParFlow, the timestep number from the filename often directly corresponds to the simulation time (e.g., if output is every 1 hour, timestep 24 is 24 hours). This method returns a list of tuples: (timestep_number, simulation_time). Currently, simulation_time is simply cast from timestep_number. More accurate time mapping would require parsing ParFlow timing files if complex.
- Returns:
- A list where each tuple is (timestep_number, time_value).
Time_value is float representation of timestep_number.
- Return type:
List[Tuple[int, float]]
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs: Any) ndarray[source]#
Load saturation data for a specified range of zero-based timestep indices.
- Parameters:
start_idx (int, optional) – Starting zero-based timestep index. Defaults to 0.
end_idx (Optional[int], optional) – Ending zero-based timestep index (exclusive). If None, loads up to the last available timestep. Defaults to None.
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
- A 4D NumPy array of saturation values (num_timesteps, nz, ny, nx).
Returns an empty 4D array if the range is invalid or no data is found.
- Return type:
np.ndarray
- Raises:
ValueError – If no timesteps are available, or if the specified range is invalid (e.g., start_idx out of bounds, end_idx <= start_idx leading to empty range).
- load_timestep(timestep_idx: int, **kwargs: Any) ndarray[source]#
Load saturation data for a specific, zero-based timestep index.
- Parameters:
timestep_idx (int) – The zero-based index of the timestep to load from the list of available timesteps discovered during initialization.
**kwargs (Any) – Additional keyword arguments (not used by this method).
- Returns:
A 3D NumPy array of saturation values (nz, ny, nx).
- Return type:
np.ndarray
- Raises:
ValueError – If no timesteps are available or if timestep_idx is out of range.
- PyHydroGeophysX.model_output.binaryread(file: Any, vartype: Any, shape: Any = (1,), charlen: Any = 16) Any[source]#
Uses numpy to read from binary file. This was found to be faster than the struct approach and is used as the default.
- Parameters:
file – Open file object in binary read mode
vartype – Variable type to read
shape – Shape of the data to read (default: (1,))
charlen – Length of character strings (default: 16)
- Returns:
The read data