Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature suggestion: Custom tide prediction import #27

Open
lucas-langlois opened this issue Nov 12, 2024 · 5 comments
Open

Feature suggestion: Custom tide prediction import #27

lucas-langlois opened this issue Nov 12, 2024 · 5 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@lucas-langlois
Copy link

lucas-langlois commented Nov 12, 2024

Describe your idea or suggestion
For some places I have been testing out in Australia using the global tide models for tide prediction are quite a bit off. It would be great to have a easy way to import the more specific port tide predictions from the Australian Hydrographic Office (Austides)? Could be done as importing the prediction as txt file or better yet some way to import the tide constituents for the port and reconstitute the tidal model for it. Indeed it's sometime hard to obtain the historic tidal predictions (I have to email them to get them).

Thanks

Lucas

@lucas-langlois lucas-langlois added the enhancement New feature or request label Nov 12, 2024
@robbibt
Copy link
Member

robbibt commented Nov 14, 2024

Thanks @lucas-langlois, this is a great suggestion. I'd had a look at this and it seems like it's definitely possible - here's an example of tides modelled from AusTides constituents vs. the FES2014 model at Broome:
image

The challenge will be fitting it into the eo-tides framework so it can be nice and seamless, but I think that's achievable! Will let you know when I have something ready to test.

@robbibt
Copy link
Member

robbibt commented Nov 14, 2024

@lucas-langlois Here's some prototype code if you want to give it a go: you need to manually set both time and austides_path (pointing to your XXXXX_HCons.txt file).

An important detail: to get correct modelled tides, you have to change this option in AusTides to "Zulu", which will give the constituents relative to UTC time (otherwise they are completely messed up):

image

import pandas as pd
import numpy as np
import io
import pyTMD
from pyTMD.io.constituents import constituents
from eo_tides.utils import _standardise_time
from eo_tides.model import model_tides


def extract_constants_austides(file_path):
    """
    Parse harmonic constants from an AusTides harmonic constants file.
    """
    # Open file containing harmonic constants
    with open(file_path, "r") as f:
        text = f.read()

    # Break into sections
    sections = text.split("\n\n")

    # Find section containing LAT and LONG
    coord_section = next(s for s in sections if "LAT" in s and "LONG" in s)
    parts = coord_section.split()

    # Convert to decimal degrees (assuming parts will be:
    # ['Time', 'Zone', '−0800', 'LAT', '-18', '0', 'LONG', '122', '13'])
    lat = float(parts[4]) + float(parts[5]) / 60
    lon = float(parts[7]) + float(parts[8]) / 60

    # Find section containing constants
    harmonic_idx = sections.index("HARMONIC CONSTANTS")
    data_text = sections[harmonic_idx + 2]

    # Read constants
    constant_df = pd.read_csv(
        io.StringIO(data_text),
        sep="\s+",
        names=["c", "amp", "ph"],
    )

    # Rename constants to match pyTMD conventions
    c = [constituents.parse(i) for i in constant_df.c]

    # Reshape extracted constants and convert to
    # masked arrays to for pyTMD compatability
    amp = np.expand_dims(constant_df.amp, axis=0)
    ph = np.expand_dims(constant_df.ph, axis=0)
    amp = np.ma.array(amp, mask=False)
    ph = np.ma.array(ph, mask=False)

    # Return constants and lat/lon coords
    return amp, ph, c, lon, lat


# Input params
time = pd.date_range("2020-01", "2020-02", freq="3h")
austides_path = "/home/jovyan/Robbi/eo-tides/tests/data/63564_HCons.txt"

# Extract AusTides constants
amp, ph, c, lon, lat = extract_constants_austides(austides_path)

# Model tides with `eo-tides` and a global model
tides_df = model_tides(
    x=lon,
    y=lat,
    time=time,
    model="EOT20",
    directory="/var/share/tide_models/",
    output_format="wide",
)

# Standardise time to numpy datetime64 format
time = _standardise_time(time)

# Convert datetime
timescale = pyTMD.time.timescale().from_datetime(time.flatten())

# Calculate complex phase in radians for Euler's
cph = -1j * ph * np.pi / 180.0

# Calculate constituent oscillation
hc = amp * np.exp(cph)

# Convert datetime
deltat = np.zeros_like(timescale.tt_ut1)
t = timescale.tide

# Create arrays to hold outputs
tide = np.ma.zeros((len(t)), fill_value=np.nan)
tide.mask = np.any(hc.mask, axis=1)

# Predict tides
tides_austide = pyTMD.predict.time_series(
    t,
    hc,
    c,
    deltat=deltat.flatten(),
)

# Add modelled AusTides to original dataframe
tides_df["AusTides"] = tides_austide

# Plot
tides_df.droplevel(["x", "y"]).plot()
tides_df.droplevel(["x", "y"]).plot.scatter("AusTides", "EOT20")

image

@robbibt
Copy link
Member

robbibt commented Nov 14, 2024

Noting that this is very much a work in progress - I wouldn't trust these values yet 🙂

@lucas-langlois
Copy link
Author

Hi Robbi,
Very cool, code worked a charm. See below the results for me location. Definitely a big difference between the EOT20 predictions and the ones from the Austides constituents.
Now it would be good to be able to compare that to the predictions given from Austides just to make sure the calculations are correct. But they are given as height above LAT in Austides and also seem to have some correction factors applied to it too so might be tricky.

image

@robbibt
Copy link
Member

robbibt commented Nov 14, 2024

@lucas-langlois Great that it worked! But yeah, at some sites there are some big differences between the results we get with this code and what the app produces - I'll try and get more detail about what additonal corrections they apply and see if it's something we can implement:
image

@robbibt robbibt added this to the v1.0.0 milestone Nov 15, 2024
@robbibt robbibt self-assigned this Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants