Source code for vtools.functions.ha_utils

import numpy as np
from utide.harmonics import FUV
from utide._ut_constants import constit_index_dict
from utide._time_conversion import _normalize_time

import pandas as pd

__all__=["nodal_factors"]


[docs] def nodal_factors( t_dates, tref_date, constituents, lat_deg, nodal_linear_time=False, phase="Greenwich", ): """ Compute nodal factors F, nodal phase U (cycles), and astronomical argument V (cycles). Parameters ---------- t_dates : array-like pandas.Timestamp or array-like of datetime Time in datetime. tref_date : datetime or pandas.Timestamp Reference date, used for nodal amp and phase correction calculations. Resulted nodal factors will be computed at this reference date if nodal_linear_time=True, a single nodal factor(F/U) is returned for each constituent, otherwise nodal factors will be computed at t_dates for all constituents. constituents : sequence[str] Constituent abbreviations, e.g. ["M2", "K1", "MK3", "MO3"]. lat_deg : float Latitude in degrees. nodal_linear_time : bool Linearized nodal variation, check with tref_date for details. phase : {"Greenwich", "linear_time", "raw"} Tide Greenwich equilibrium phase correction convention. Greenwich: Greenwich equilibrium argument computed on all t_dates linear_time: single Greenwich equilibrium argument computed at tref_date (UT) and applied to all t_dates raw: no Greenwich equilibrium argument applied. Returns ------- F : ndarray (n, nc) Nodal amplitude factors. n is the length of t_dates when nodal_linear_time=False, otherwise n=1. nc is the number of constituents. U : ndarray (n, nc) Nodal phase corrections (cycles). n is the length of t_dates when nodal_linear_time=False, otherwise n=1. nc is the number of constituents. V : ndarray (nt, nc) Astronomical arguments reckoned from tref_date (cycles). nt is the length of t_dates. nc is the number of constituents. """ ## check input t_dates and tref_date are pandas.Timestamp or datetime if not (isinstance(t_dates, pd.Series) or isinstance(t_dates, pd.DatetimeIndex) or isinstance(t_dates, pd.Timestamp)): raise ValueError("t_dates must be a pandas Series, DatetimeIndex, or Timestamp, or a datetime object") if not (isinstance(tref_date, pd.Timestamp) ): raise ValueError("tref_date must be a pandas Timestamp or datetime object") # Convert t_dates and tref_date to days since epoch t_days = _normalize_time(t_dates) tref_days = _normalize_time(tref_date) nodal = True return _fuv( t_days, tref_days, constituents, lat_deg, nodal=nodal, nodal_linear_time=nodal_linear_time, phase=phase )
[docs] def _fuv( t_days, tref_days, constituents, lat_deg, *, nodal=True, nodal_linear_time=False, phase="Greenwich", ): """ Compute nodal factors F, nodal phase U (cycles), and astronomical argument V (cycles). Parameters ---------- t_days : array-like Time in days since epoch. tref_days : float Reference time in days since epoch. constituents : sequence[str] Constituent abbreviations, e.g. ["M2", "K1", "MK3", "MO3"]. lat_deg : float Latitude in degrees. nodal : bool Apply nodal/satellite corrections. nodal_linear_time : bool Linearized nodal variation. phase : {"Greenwich", "linear_time", "raw"} Phase convention. Returns ------- F : ndarray (nt, nc) Nodal amplitude factors. U : ndarray (nt, nc) Nodal phase corrections (cycles). V : ndarray (nt, nc) Astronomical arguments (cycles). """ if phase not in {"Greenwich", "linear_time", "raw"}: raise ValueError(f"Invalid phase={phase!r}") try: lind = np.array([constit_index_dict[c] for c in constituents], dtype=int) except KeyError as e: raise KeyError(f"Unknown tide constituent {e.args[0]!r}") from None ngflgs = np.zeros(4, dtype=bool) if not nodal: ngflgs[1] = True elif nodal_linear_time: ngflgs[0] = True if phase == "raw": ngflgs[3] = True elif phase == "linear_time": ngflgs[2] = True t_days = np.asarray(t_days, dtype=float) F, U, V = FUV( t_days, float(tref_days), lind, float(lat_deg), ngflgs, ) return F, U, V