Create Hindcast Wave

Source Code

create_hindcast_wave.py
  1"""Create a metocean hindcast wave data file for SIMA.
  2
  3This example demonstrates how to extract wave data from the NORA3 dataset and convert it
  4into a metocean hindcast format that can be read by SIMA. It focuses on a specific storm
  5event in Sulafjord, Norway.
  6
  7Features:
  8    Data Retrieval:
  9        Uses metocean_api to extract wave data from the NORA3 dataset
 10    Wave Parameter Processing:
 11        Processes wave parameters including significant height, peak period, and direction
 12    SIMA Integration:
 13        Converts data to a format compatible with SIMA's metocean module
 14
 15Requirements:
 16    - metocean_api for data retrieval
 17    - simapy.metocean for hindcast data handling
 18    - xarray for data processing
 19    - Access to NORA3 wave dataset
 20
 21Example:
 22    Basic usage of this script:
 23    
 24    >>> python create_hindcast_wave.py
 25    
 26    The script generates hindcast files in the output/simamet/ directory.
 27"""
 28
 29from pathlib import Path
 30from datetime import datetime
 31import time
 32import numpy as np
 33import pandas as pd
 34from dmt.dmt_writer import DMTWriter
 35from metocean_api import ts
 36import simapy.metocean.hindcast as hc
 37
 38
 39def __create_wave(wave_name, hs, tp, direction):
 40    # NORA3_wave_sub: North East Down, wave_going_to
 41    # SIMA MET: North East Down, wave coming from
 42    dir_sima = (180.0 + direction) % 360.0
 43    return hc.StochasticWave(name=wave_name, hs=hs, tp=tp, direction=dir_sima)
 44
 45
 46def __create_hindcast(hc_name, product, hc_values: pd.DataFrame, lat_pos, lon_pos):
 47    waves = []
 48
 49    waves.append(
 50        __create_wave("total", hc_values["hs"], hc_values["tp"], hc_values["thq"])
 51    )
 52    waves.append(
 53        __create_wave(
 54            "windSea", hc_values["hs_sea"], hc_values["tp_sea"], hc_values["thq_sea"]
 55        )
 56    )
 57    waves.append(
 58        __create_wave(
 59            "swell",
 60            hc_values["hs_swell"],
 61            hc_values["tp_swell"],
 62            hc_values["thq_swell"],
 63        )
 64    )
 65
 66    # Time is given in Unix epoch
 67    # convert dates to strings
 68    dates = hc_values.index
 69    sdates = np.datetime_as_string(dates, unit="h", timezone="UTC").astype("|S")
 70
 71    hindcast = hc.Hindcast()
 72    hindcast.description = f"Collected using Norway MET metocean-api with product {product}"
 73    hindcast.name = hc_name.replace("-", "_")
 74    hindcast.date = sdates
 75    hindcast.latitude = lat_pos
 76    hindcast.longitude = lon_pos
 77    hindcast.wave = waves
 78
 79    return hindcast
 80
 81
 82def main():
 83    """Execute the main hindcast example.
 84    
 85    Retrieves wave data for a specific storm event in Sulafjord, Norway, and
 86    converts it to a SIMA-compatible hindcast format. The data is saved as
 87    both CSV and DMT files for further use in SIMA simulations.
 88    """
 89    # https://www.met.no/publikasjoner/met-report  Section Storms in Sulafjord, wind waves and currents
 90    # https://www.met.no/publikasjoner/met-report/_/attachment/inline/86f02fd2-a979-43ef-a17e-3bdba201e584:c70eb4b6ffe6f3b7b98016f4a0ebfc5ca501c766/MET-report-03-2024.pdf
 91
 92    # Storm 14th of March 2017
 93    sd = datetime(2017, 3, 14, 10, 0)
 94    ed = datetime(2017, 3, 14, 13, 0)
 95
 96    start_date = sd.strftime("%Y-%m-%d")
 97    end_date = ed.strftime("%Y-%m-%d")
 98
 99    positions = {
100        "Sulesund": {"lat": 62.402865086109195, "lon": 6.028359996993728},
101        "Kvitneset": {"lat": 62.421049661227585, "lon": 6.000482407215768},
102        "BuoyA": {"description": "Sulafjorden", "lat": 62.4263, "lon": 6.0447},
103        "BuoyB": {"description": "Sulafjorden", "lat": 62.4038, "lon": 6.0806},
104        "BuoyD": {"description": "Breisundet", "lat": 62.4464, "lon": 5.9336},
105    }
106
107    location = "BuoyB"
108
109    lat_pos = positions[location]["lat"]
110    lon_pos = positions[location]["lon"]
111
112    product = "NORA3_wave_sub"
113
114    name = f"hindcast-{location}-{product}-{start_date}-{end_date}"
115
116    output_dir = Path("./output/simamet")
117    output_dir.mkdir(exist_ok=True, parents=True)
118
119    csv_file = str(output_dir / f"{name}.csv")
120
121    nc_file = csv_file.replace(".csv", ".nc")
122
123    df_ts = ts.TimeSeries(
124        lon=lon_pos,
125        lat=lat_pos,
126        datafile=nc_file,
127        start_time=start_date,
128        end_time=end_date,
129        product=product,
130    )
131
132    # Start timing
133    start = time.time()
134    df_ts.import_data(save_csv=False, save_nc=True, use_cache=True)
135
136    # End timing and print elapsed time
137    end = time.time()
138    print("Elapsed time: " + str(end - start) + " seconds")
139
140    values = df_ts.data
141
142    hindcast = __create_hindcast(name,product, values, lat_pos, lon_pos)
143
144    dmtw = DMTWriter()
145    output_dir = Path("./output/simamet")
146    output_dir.mkdir(exist_ok=True, parents=True)
147    print(f"Writing hindcast to {output_dir / name}.dmt")
148    dmtw.write(hindcast, output_dir / name)
149    print(f"Successfully created hindcast files in {output_dir}")
150
151
152if __name__ == "__main__":
153    main()