pyfvcom2.tide module
- class pyfvcom2.tide.HarmonicAnalysisWriter(filename, dimensions, global_attributes=None, **kwargs)[source]
Bases:
FVCOMWriterWrite tidal harmonic analysis results to a NetCDF file.
Subclasses FVCOMWriter to provide methods for writing the grid, sigma coordinates, constituent names, harmonic amplitudes/phases, and optionally raw or predicted time series.
Typical usage:
dims = { 'node': nx, 'nele': ne, 'siglay': nz, 'siglev': nzlev, 'three': 3, 'nconsts': len(consts), 'NameStrLen': 4, 'DateStrLen': 26, } global_atts = {'title': 'FVCOM harmonic analysis', ...} with HarmonicAnalysisWriter('harmonics.nc', dims, global_atts) as nc: nc.add_grid(lon, lat, lonc, latc, h, h_center, nv, siglay, siglev, consts) nc.write_fvcom_time(times) # only needed when writing time series nc.add_harmonics('zeta', z_amp, z_phase) nc.add_harmonics('ua', ua_amp, ua_phase) nc.add_harmonics('u', u_amp, u_phase)
Notes
Dimensions must be passed to __init__ before calling add_grid() or add_harmonics(). The ‘time’ dimension should be set to 0 (unlimited) when writing raw or predicted time series, and omitted otherwise.
The ncopts compression settings default to zlib level 7, matching the original PyFVCOM HarmonicOutput behaviour.
- add_grid(lon, lat, lonc, latc, h, h_center, nv, siglay, siglev, consts)[source]
Write grid coordinates, bathymetry, connectivity and constituent names.
- Parameters:
lon (array-like) – Node longitudes and latitudes.
lat (array-like) – Node longitudes and latitudes.
lonc (array-like) – Element centre longitudes and latitudes.
latc (array-like) – Element centre longitudes and latitudes.
h (array-like) – Node bathymetry (m, positive down).
h_center (array-like) – Element centre bathymetry (m, positive down).
nv (array-like) – Node-to-element connectivity table, shape (3, nele).
siglay (array-like) – Sigma layer coordinates, shape (siglay, node).
siglev (array-like) – Sigma level coordinates, shape (siglev, node).
consts (list of str) – Tidal constituent names, padded to 4 characters (e.g. ‘M2 ‘).
- add_harmonics(variable, amplitude, phase)[source]
Write harmonic amplitude and phase for a given variable.
- Parameters:
variable (str) – One of ‘zeta’, ‘ua’, ‘va’, ‘u’, ‘v’.
amplitude (array-like) – Harmonic amplitudes (m or m/s). Shape is (nconsts, node) for ‘zeta’, (nconsts, nele) for depth-averaged velocity, or (nconsts, siglay, nele) for depth-resolved velocity.
phase (array-like) – Harmonic phases (degrees), same shape as amplitude.
- add_predicted(variable, data)[source]
Write a predicted time series reconstructed from the harmonics.
Requires a ‘time’ dimension to have been created and write_fvcom_time() to have been called first.
- Parameters:
variable (str) – One of ‘zeta’, ‘ua’, ‘va’, ‘u’, ‘v’.
data (array-like) – Predicted time series. Same shape conventions as add_raw().
- add_raw(variable, data)[source]
Write the raw (input) time series used in the harmonic analysis.
Requires a ‘time’ dimension to have been created and write_fvcom_time() to have been called first.
- Parameters:
variable (str) – One of ‘zeta’, ‘ua’, ‘va’, ‘u’, ‘v’.
data (array-like) – Time series data. Shape is (time, node) for ‘zeta’, (time, nele) for depth-averaged, or (time, siglay, nele) for depth-resolved.
- class pyfvcom2.tide.HarmonicsAnalyser(reader: FVCOMReader, output_file: str, constit: tuple = ('M2', 'S2', 'N2', 'K2', 'K1', 'O1', 'P1', 'Q1', 'M4', 'MS4', 'MN4'), predict: bool = False, dump_raw: bool = False, node_indices: ndarray = None, element_indices: ndarray = None, verbose: bool = False, pool_size: int = 1, show_progress: bool = True)[source]
Bases:
objectOrchestrate tidal harmonic analysis from FVCOM output.
Loads data from a
FVCOMReader, runs UTide harmonic analysis for each requested variable, and writes results to aHarmonicAnalysisWriterNetCDF file.- Parameters:
reader (FVCOMReader) – Open reader for the FVCOM model output to analyse.
output_file (str) – Path to the NetCDF output file to create.
constit (tuple, optional) – Tidal constituent names. Defaults to
DEFAULT_CONSTIT.predict (bool, optional) – If True, also write a predicted (reconstructed) time series for each variable. Defaults to False.
dump_raw (bool, optional) – If True, also write the raw (input) time series for each variable. Defaults to False.
node_indices (array-like of int, optional) –
Integer indices into the full node array selecting the subset of nodes to analyse. If None (default), all nodes are analysed. Useful for restricting the analysis to a spatial region of interest and avoiding the cost of analysing the full mesh. Typically constructed as:
mask = (lon >= lon_min) & (lon <= lon_max) & (lat >= lat_min) & (lat <= lat_max) node_indices = np.where(mask)[0]
element_indices (array-like of int, optional) – Integer indices into the full element array selecting the subset of elements to analyse. If None (default), all elements are analysed. Constructed analogously to node_indices using element-centred coordinates (
reader.lon_elements,reader.lat_elements).verbose (bool, optional) – If True, print UTide’s per-solve progress messages (
"solve: matrix prep … solution … done."). Defaults to False.pool_size (int, optional) – Number of worker processes for parallel analysis.
1(default) runs serially. Set to the number of physical cores (e.g.multiprocessing.cpu_count()) for maximum throughput. Passed directly toanalyse_harmonics().show_progress (bool, optional) – If True (default), print a live progress line to stdout for each variable (and each sigma layer for 3-D variables) showing the count of completed positions, elapsed time, and estimated time remaining. Set to False to suppress all progress output.
Examples
reader = FVCOMReader(['output_0001.nc', 'output_0002.nc']) analyser = HarmonicsAnalyser(reader, 'harmonics.nc', predict=True) analyser.run(['zeta', 'u', 'v'])
- run(variables: list = None)[source]
Run harmonic analysis for the specified variables.
Opens the output file, writes the grid and (when applicable) time, then runs the analysis variable by variable.
- Parameters:
variables (list of str, optional) – FVCOM variable names to analyse. Valid values are
'zeta','u','v','ua','va'. Defaults to all five.
- class pyfvcom2.tide.TideManager(constituents: list[str], parallel: bool = True, pool_size: int | None = None)[source]
Bases:
objectManages tidal harmonics interpolation and prediction.
Orchestrates the pipeline from TPXO tidal harmonic data through interpolation onto target positions to tidal time series prediction via UTide.
- Typical usage:
Create a TideManager with the desired constituents.
Register TPXOInterpolator instances for each variable (zeta, u, v) via add_interpolator.
Pass the TideManager to NestManager.add_tidal_data(), which calls predict() for each variable with the appropriate target positions.
- Args:
constituents: List of tidal constituent names (e.g. [‘M2’, ‘S2’]). parallel: Whether to run UTide predictions in parallel. Default True. pool_size: Number of parallel processes. Default None (use all CPUs).
- add_interpolator(variable: str, interpolator) None[source]
Register a TPXOInterpolator for a tidal variable.
- Args:
variable: Tidal variable name (‘zeta’, ‘u’, or ‘v’). interpolator: TPXOInterpolator loaded with harmonics data
for this variable.
- property constituents: list[str]
List of tidal constituent names.
- predict(variable: str, datetimes: ndarray, longitudes: ndarray, latitudes: ndarray) ndarray[source]
Interpolate harmonics onto target positions and predict tides.
- Args:
variable: Variable name (‘zeta’, ‘u’, or ‘v’). datetimes: Array of datetime objects for prediction times. longitudes: Target longitude positions. latitudes: Target latitude positions.
- Returns:
Predicted tidal time series, shape (n_times, n_points).
- pyfvcom2.tide.analyse_harmonics(times: ndarray, elevations: ndarray, latitudes: ndarray, predict: bool = False, constit: tuple = ('M2', 'S2', 'N2', 'K2', 'K1', 'O1', 'P1', 'Q1', 'M4', 'MS4', 'MN4'), pool_size: int = 1, label: str = '', **kwargs) ndarray[source]
Run UTide harmonic analysis on a set of time series.
- Parameters:
times (np.ndarray) – Modified Julian Day times, shape (ntimes,).
elevations (np.ndarray) – Time series data, shape (npositions, ntimes).
latitudes (np.ndarray) – Latitude for each position, shape (npositions,). Positions with a NaN latitude are skipped and left as NaN in the output.
predict (bool, optional) – If True, also return a reconstructed predicted time series alongside the harmonics. Defaults to False.
constit (tuple, optional) – Tidal constituent names to include in the analysis. Defaults to DEFAULT_CONSTIT.
pool_size (int, optional) – Number of worker processes to use.
1(default) runs a simple serial loop. Values greater than 1 dispatch positions across amultiprocessing.Poolviaimap, producing near-linear speedup on multi-core machines. Usemultiprocessing.cpu_count()to utilise all available cores. Tasks are yielded lazily so that memory use scales with pool_size, not with npositions — important for long records (hourly or sub-hourly over months).label (str, optional) – If non-empty, a live progress line is printed to stdout showing completed positions, elapsed time, and estimated time remaining.
HarmonicsAnalysersets this automatically whenshow_progress=True; it can also be set directly when callinganalyse_harmonics()standalone. Defaults to''(no output).**kwargs – Additional keyword arguments forwarded to
utide.solve(). Theverbosekey is also forwarded toutide.reconstruct()when predict is True.
- Returns:
harmonics (np.ndarray) – Shape
(npositions, 2, len(constit)). Index 0 along the second axis is phase (degrees), index 1 is amplitude (m or m/s). Positions with a NaN latitude are left as NaN.predicted (np.ndarray) – Only returned when predict is True. Shape
(npositions, ntimes). Positions with a NaN latitude are left as NaN.
Notes
UTide returns constituents in an order that may differ from constit. The output arrays are always re-sorted to match the order given in constit.
- pyfvcom2.tide.extend_datetime_array(datetimes: ndarray, extension_length_in_days: float = 1.0) ndarray[source]
Extend a datetime array by a given number of days at both ends.
TODO This was in the original PyFVCOM, although in a different form. Unsure whether it is actually needed for UTide. A simpler approach would be to just add one day at each end, but this might create unevenly spaced time arrays. Would this matter? Need to test it.
- Args:
datetimes (np.ndarray): Original array of datetime objects. extension_length_in_days (float): Number of days to extend at both ends.
- Returns:
np.ndarray: Extended array of datetime objects.
- pyfvcom2.tide.predict_tide(datetimes: ndarray, constituents: list[str], amplitudes: ndarray, phases: ndarray, latitudes: ndarray, parallel: bool = True, pool_size: int | None = None)[source]
Reconstruct tidal variations in zeta, u, v etc at the provided datetimes and latitudes using the provided tidal constituent amplitudes and phases.
Args: datetimes : np.ndarray
Array of datetime objects for prediction times.
- intervalfloat
Time interval between datetimes in days.
- constituentslist[str]
List of tidal constituent names to read.
- amplitudesnp.ndarray
Amplitude of the relevant constituents shaped [nlocs, nconst].
- phasesnp.ndarray
Array of the phase of the relevant constituents shaped [nlocs, nconst].
- latitudesnp.ndarray
Latitudes of the positions to predict.
- parallelbool, optional
Whether to run the predictions in parallel using multiprocessing. Default is True.
- pool_sizeint, optional
Number of parallel processes to use. If 1, runs serially. Default is 1.
Returns: results : list[np.ndarray]
List of predicted zeta time series arrays for each location.
- pyfvcom2.tide.reconstruct_wrapper(args: tuple) ndarray[source]
For the given time and coefficients (in coef) reconstruct the tidal elevation or current component time series at the given latitude.
Args: args : tuple
Tuple of (lats, times, coef, amplitudes, phases) where: - lats: Latitude of the position to predict. - times: Array of datenums (days since MJD zero point). - coef: UTide coefficients Bunch. - amplitudes: Amplitude of the relevant constituents shaped [nconst]. - phases: Phase of the relevant constituents shaped [nconst].
Returns: zeta : np.ndarray
Time series of surface elevations.
Notes
Uses utide.reconstruct() for the predicted tide. Accepts a single tuple argument for compatibility with multiprocessing.Pool.map.