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()