NECOFS
The NECOFS class fetches vertical profiles of oceanographic variables
(temperature, salinity, current speed, and sound speed) from the North-East
Coastal Ocean Forecast System (NECOFS GOM3 FVCOM model) via OPeNDAP.
- class ecosound.environment.necofs.NECOFS(url: str | None = None, verbose: bool = True)[source]
Bases:
objectClass for fetching FVCOM-GOM (NECOFS GOM3) ocean model data via OPeNDAP.
NECOFS GOM3 is an unstructured-grid (FVCOM) ocean model covering the Gulf of Maine and surrounding waters. Because FVCOM uses a triangular unstructured grid, spatial queries find the nearest grid node (for scalar fields) or element center (for velocity fields) using a fast distance search.
Grid coordinates and bathymetry are downloaded once on the first query and cached for subsequent calls.
- Parameters:
url – OPeNDAP URL for the NECOFS GOM3 dataset. Defaults to the 30-year hindcast endpoint.
verbose – Print progress messages (default: True).
- vertical_profile
Most recent single vertical profile from get_vertical_profile(). Dimensions: sigma_layer. Coordinates: time (scalar), lat, lon. None until first call.
- Type:
xr.Dataset | None
- vertical_profiles
Collection of vertical profiles from get_vertical_profiles(). Dimensions: time, sigma_layer. Coordinates: time, lat, lon. None until first call.
- Type:
xr.Dataset | None
Examples
>>> from ecosound.environment import NECOFS >>> from datetime import datetime >>> necofs = NECOFS() >>> necofs.get_vertical_profile(lat=42.5, lon=-70.0, dt=datetime(2015, 8, 1, 12)) >>> necofs.plot_vertical_profile()
- GOM3_HINDCAST_URL = 'http://www.smast.umassd.edu:8080/thredds/dodsC/fvcom/hindcasts/30yr_gom3'
- GOM3_FORECAST_URL = 'http://www.smast.umassd.edu:8080/thredds/dodsC/models/fvcom/NECOFS/Forecasts/NECOFS_GOM3_FORECAST.nc'
- get_vertical_profile(lat: float, lon: float, dt: datetime | Timestamp | str) Dataset[source]
Extract a vertical profile of temperature, salinity, currents, and sound speed at the nearest FVCOM grid node for a given location and time.
The result is always stored in self.vertical_profile and always returned, so the method can be used with or without assignment:
necofs.get_vertical_profile(lat, lon, dt) # stored in self.vertical_profile ds = necofs.get_vertical_profile(lat, lon, dt) # also captured locally
Temperature, salinity, and sound speed are returned at FVCOM sigma-layer centers converted to physical depths. Current components (u, v) come from the nearest element center (FVCOM stores velocities at element centroids, not nodes). Sound speed is derived from temperature, salinity, and depth using the Mackenzie (1981) empirical formula.
- Parameters:
lat – Latitude of the query point (decimal degrees, WGS84).
lon – Longitude of the query point (decimal degrees, WGS84, negative west).
dt – Date and time for the profile. Accepts datetime, pd.Timestamp, or ISO 8601 string (e.g. “2015-08-01T12:00”). The nearest available model time step is used.
- Returns:
- Data variables:
temperature_C (sigma_layer) : in-situ temperature (°C)
salinity_PSU (sigma_layer) : practical salinity (PSU)
u_ms (sigma_layer) : eastward current (m/s)
v_ms (sigma_layer) : northward current (m/s)
sound_speed_ms(sigma_layer) : sound speed, Mackenzie 1981 (m/s)
depth_m (sigma_layer) : depth below surface (m, positive down)
zeta_m () : sea surface elevation (m)
- Coordinates:
sigma_layer : integer layer index (0 = surface)
time : model time step (scalar datetime64)
lat : nearest node latitude
lon : nearest node longitude
- Dataset.attrs:
requested_lat/lon/time, nearest_node_lat/lon/idx, nearest_elem_idx, bathymetry_m, total_depth_m, url
- Return type:
xr.Dataset with dimension sigma_layer (sorted surface to bottom)
- Raises:
ConnectionError – If the OPeNDAP dataset cannot be opened.
- get_vertical_profiles(lat: float, lon: float, dt: List[datetime | Timestamp | str] | None = None, start_dt: datetime | Timestamp | str | None = None, end_dt: datetime | Timestamp | str | None = None) Dataset[source]
Extract vertical profiles at multiple time steps in a single efficient OPeNDAP request.
All variables (temp, salinity, u, v, zeta) for the target node are fetched in one contiguous block per variable — regardless of whether discrete times or a range are requested — keeping network round trips to a minimum (5 requests total, one per variable, vs. 5×N for N repeated calls to get_vertical_profile).
Provide either a list of discrete datetimes (dt) OR a time range (start_dt + end_dt), not both.
- Parameters:
lat – Latitude of the query point (decimal degrees, WGS84).
lon – Longitude of the query point (decimal degrees, WGS84, negative west).
dt – List of datetimes to extract. Each is snapped to the nearest model time step. Accepts datetime, pd.Timestamp, or ISO strings.
start_dt – Start of a time range (inclusive). Must be paired with end_dt.
end_dt – End of a time range (inclusive). Must be paired with start_dt.
- Returns:
xr.Dataset stored in
self.vertical_profileswith dimensions(time, sigma_layer). Data variables:temperature_C,salinity_PSU,u_ms,v_ms,sound_speed_ms,depth_m(varies with time due to sea-surface elevation), andzeta_m. Coordinates:time,sigma_layer,lat,lon.- Raises:
ValueError – If neither dt nor start_dt/end_dt are provided, or both are.
ConnectionError – If the OPeNDAP dataset cannot be opened.
Examples
Discrete time list:
ds = necofs.get_vertical_profiles( lat=42.5, lon=-70.0, dt=["2015-08-01T00:00", "2015-08-01T06:00", "2015-08-01T12:00"])
Time range (all hourly steps between start and end):
ds = necofs.get_vertical_profiles( lat=42.5, lon=-70.0, start_dt="2015-08-01", end_dt="2015-08-07")
Access a single time step:
ds.sel(time="2015-08-01T06:00", method="nearest")
- plot_vertical_profile(figsize: tuple = (14, 6), display: bool = True, filename: str | None = None) None[source]
Plot the single vertical profile stored in self.vertical_profile.
Produces a figure with five subplots (one per variable): temperature, salinity, eastward current (u), northward current (v), and sound speed — all versus depth (surface at top, seafloor at bottom). Each x-axis is auto-scaled to the data range of that variable.
- Parameters:
figsize – Figure size as (width, height) in inches (default: (14, 6)).
display – Show the figure on screen (default: True).
filename – If provided, save the figure to this path (e.g. “profile.png”). Any format supported by matplotlib is accepted. Default: None.
- Raises:
RuntimeError – If get_vertical_profile() has not been called yet.
- plot_vertical_profiles(figsize: tuple = (16, 6), cmap: str = 'viridis', display: bool = True, filename: str | None = None) None[source]
Overlay all vertical profiles stored in self.vertical_profiles.
Produces a figure with five subplots (one per variable). Each time step is drawn as a separate line; line colour encodes model time using the chosen colormap and a shared colorbar on the right.
- Parameters:
figsize – Figure size as (width, height) in inches (default: (16, 6)).
cmap – Matplotlib colormap name for the time axis (default: “viridis”).
display – Show the figure on screen (default: True).
filename – If provided, save the figure to this path. Default: None.
- Raises:
RuntimeError – If get_vertical_profiles() has not been called yet.