Skip to content

Repository files navigation

ERA5 Single-Point Wave and Wind Downloader

1. Purpose

download_era5_data.py is a Windows-oriented Python application for downloading and post-processing an ERA5 hourly time-series at one user-defined point. It is intended for engineering and metocean workflows that need a compact, repeatable CSV time series containing:

  • significant wave height of combined wind waves and swell;
  • mean wave period;
  • mean wave direction;
  • 10 m wind velocity components;
  • computed 10 m wind speed;
  • computed meteorological 10 m wind direction.

The program uses the Copernicus Climate Data Store dataset:

reanalysis-era5-single-levels-timeseries

This is the CDS ERA5 hourly time-series data on single levels from 1940 to present product, not the older regional GRIB-extraction workflow. The current script performs a single CDS API request for a point location and requests CSV output. It then reads the returned payload, normalises the returned tables, merges the wave and wind variables by timestamp, and writes two CSV files.

The script is GUI-first. When launched without command-line arguments it opens a Tkinter graphical interface. It also supports a simple command-line mode with explicit longitude, latitude and date range.


2. What this README describes

This README describes the current production script with these defining characteristics:

Item Current implementation
Main script download_era5_data.py
Build file download_era5_data.spec
CDS dataset reanalysis-era5-single-levels-timeseries
CDS request style One point request using location and a continuous date interval
CDS requested format data_format = "csv"
GUI toolkit Tkinter / ttk
Main table engine pandas
Numerical engine numpy
CDS client cdsapi
CDS credential lookup .ecmwfapirc and .cdsapirc; searched first in %USERPROFILE%, then in the script/executable directory
Optional Excel reader openpyxl through pandas.read_excel
Required output files era5_data.csv, output.csv, download_era5_data.log, defaults.json
Compiled executable mode One-file Windows GUI executable built with PyInstaller and console=False

The current script does not use:

  • monthly GRIB files;
  • xarray;
  • cfgrib;
  • ecCodes;
  • pygrib;
  • local GRIB archive extraction;
  • inverse-distance interpolation in the script;
  • multiprocessing extraction of GRIB files;
  • a grib/ input folder;
  • a results/ output folder.

Those items belonged to an older design and are intentionally not part of the current dependency or usage model.


3. ERA5 scientific background

3.1 What ERA5 is

ERA5 is the fifth-generation ECMWF atmospheric reanalysis produced for the Copernicus Climate Change Service. Reanalysis combines a numerical weather prediction model with observations from many observing systems to produce a physically consistent reconstruction of past atmospheric, land-surface and ocean-wave conditions.

The core reanalysis principle is data assimilation: every assimilation cycle blends a previous model forecast with newly available observations, taking account of their uncertainties, to produce a new best estimate of the state of the Earth system. This analysed state is then used to initialise the next forecast cycle. Reanalysis applies this principle over a long historical period rather than only for operational forecasting.

For engineering use, ERA5 is valuable because it provides long, homogeneous and globally complete hourly data. It is particularly useful where buoy, anemometer or wave-rider records are short, discontinuous, or absent.

3.2 ERA5 versus observations

ERA5 is not a measurement record at the exact project coordinate. It is a model-data assimilation product. It assimilates observations, but the resulting values are gridded analyses generated by the ECMWF modelling and assimilation system. For maritime and coastal engineering, ERA5 is generally suitable for:

  • screening long-term wave and wind climate;
  • preparing offshore reference time series;
  • selecting storm events for further modelling;
  • supporting preliminary extreme-value analysis;
  • generating boundary-condition candidates for nearshore wave transformation;
  • contextualising shorter local measurements.

ERA5 should not be treated as a direct replacement for:

  • local wave-buoy records;
  • harbour agitation modelling;
  • nearshore spectral wave transformation;
  • site-specific bathymetric refraction and breaking analysis;
  • physical model testing;
  • final overtopping assessment at a breakwater crest or revetment without transformation to the structure toe.

3.3 ERA5T and final ERA5

Recent ERA5 data are initially released as ERA5T, a timely preliminary product. ERA5T is normally available with a latency of about 5 days. Final ERA5 replaces ERA5T later, typically after a delay of about two to three months. For formal engineering reports, it is therefore prudent to record:

  • the date of data acquisition;
  • the dataset name;
  • the CDS request payload;
  • the script used;
  • whether the requested period included recent ERA5T data.

For bankable design, claims, litigation-sensitive work, or contractual deliverables, recent ERA5T periods should be treated with caution until final ERA5 has replaced them.

3.4 ERA5 uncertainty

ERA5 includes an uncertainty estimate through an underlying reduced-resolution ensemble. The dataset used by this script is a selected time-series subset and this script does not request ensemble mean or spread. The generated CSV therefore contains deterministic hourly values only. It does not contain uncertainty envelopes, ensemble spread, or probabilistic quantiles.


4. CDS time-series dataset used by the script

4.1 Dataset identity

The script requests:

DATASET_NAME = "reanalysis-era5-single-levels-timeseries"

The CDS catalogue title is:

ERA5 hourly time-series data on single levels from 1940 to present

The CDS catalogue entry is organised around the usual Overview, Download and Documentation tabs. The Overview tab gives the dataset description, spatial and temporal metadata, licence and related resources. The Download tab is the interactive form that can be used to test the dataset and accept the licence before API use. The Documentation tab links to the Product User Guide and ERA5 technical documentation.

At the time this README was prepared, the catalogue entry identified the dataset as published on 2025-03-17 and updated on 2026-05-13. These dates are catalogue metadata and should not be treated as a substitute for the actual acquisition date recorded in download_era5_data.log.

The dataset is a regridded subset of the full ERA5 single-level product, stored and served for efficient long time-series retrieval at a single point. It is used by the ERA Explorer application to provide rapid interactive time-series responses.

4.2 Data description

The dataset is described by CDS as follows:

Property Description
Data type Time-series
Projection Regular latitude-longitude grid
Horizontal coverage Global
Atmospheric horizontal resolution 0.25° × 0.25°
Ocean-wave horizontal resolution 0.5° × 0.5°
Temporal coverage 1940 to present
Temporal resolution Hourly
File formats NetCDF and CSV
Update frequency Daily
Licence CC-BY

4.3 ARCO / Zarr processing concept

The ERA5 time-series dataset is generated from ERA5 source GRIB data after applying homogenisation conventions. The processed data are stored in an Analysis Ready Cloud Optimised Zarr archive. CDS then serves point time-series requests from that archive and writes the result to NetCDF or CSV, depending on the request.

This architecture is different from downloading monthly GRIB tiles and decoding them locally. The current script deliberately uses this time-series product to avoid maintaining local GRIB decoding dependencies and to keep the operational workflow lighter.

4.4 Nearest-grid-point behaviour

For this CDS time-series product, the requested location is not interpolated by this script. If the requested longitude and latitude do not coincide exactly with the dataset grid, the CDS time-series service uses the nearest grid point.

This point matters because atmospheric variables and wave variables are on different spatial grids:

  • atmospheric variables such as 10m_u_component_of_wind and 10m_v_component_of_wind are on a 0.25° grid;
  • wave variables such as mean_wave_direction, mean_wave_period and significant_height_of_combined_wind_waves_and_swell are on a 0.5° grid.

Consequently, for a requested coastal or offshore point, the nearest atmospheric grid point and nearest wave grid point may not be identical. CDS may also return atmospheric and wave parameters in separate table files to avoid conflicts in coordinate definitions. The script is designed to handle that by reading all returned tables and merging them by datetime.


5. Variables requested by the script

The current script requests exactly five ERA5 variables.

ERA5_VARIABLES = [
    "10m_u_component_of_wind",
    "10m_v_component_of_wind",
    "mean_wave_direction",
    "mean_wave_period",
    "significant_height_of_combined_wind_waves_and_swell",
]
Short output name CDS variable name Unit Meaning
swh significant_height_of_combined_wind_waves_and_swell m Significant height of combined wind waves and swell
mwp mean_wave_period s Mean wave period
mwd mean_wave_direction degrees Mean wave direction
u10 10m_u_component_of_wind m/s Eastward 10 m wind component; positive towards east
v10 10m_v_component_of_wind m/s Northward 10 m wind component; positive towards north

The script does not request wind gust, 100 m wind, pressure, temperature, precipitation, swell partitions, wind-sea partitions, peak wave period, maximum wave height, wave spectra, or ensemble variables.

5.1 Why u10 and v10 are used

The script requests wind components and computes wind speed and meteorological wind direction locally. This avoids relying on a separate wind-speed/wind-direction parameter that may belong to the wave-model grid or have a different physical definition. The computed wind fields in output.csv are therefore derived from atmospheric 10 m wind vector components.

5.2 Mean wave period versus peak wave period

The current output uses mwp, the ERA5 mean wave period. It does not request pp1d, the peak wave period. This is an intentional distinction:

  • mwp is an integrated mean period quantity;
  • pp1d is a peak-period quantity and is not part of the current CDS request.

Downstream design formulas that require peak period should not use mwp as if it were Tp without a justified conversion or a revised request including the appropriate period parameter.


6. CDS request generated by the script

For one run, the request dictionary is structurally equivalent to:

request = {
    "variable": [
        "10m_u_component_of_wind",
        "10m_v_component_of_wind",
        "mean_wave_direction",
        "mean_wave_period",
        "significant_height_of_combined_wind_waves_and_swell",
    ],
    "location": {
        "longitude": longitude,
        "latitude": latitude,
    },
    "date": ["YYYY-MM-DD/YYYY-MM-DD"],
    "data_format": "csv",
}

The script then initialises the CDS client from the configured API-key file and executes the request:

client = initialize_cds_client()
result = client.retrieve(DATASET_NAME, request)
result.download(str(payload_path))

The client initialisation is deliberately explicit. The script searches for a CDS API credential file before creating the cdsapi.Client, then passes the parsed url, key and optional verify value directly to the client. This avoids depending on a single fixed credential location.

The temporary payload is written to:

_era5_cds_download_payload.zip

The extension is .zip because CDS often returns a ZIP archive for mixed-grid time-series requests, but the script also supports a plain CSV response and an Office Open XML table response.


7. Output files

All files are written in the application directory.

In normal Python execution, the application directory is the directory containing download_era5_data.py.

In a PyInstaller one-file executable, the application directory is the directory containing download_era5_data.exe, not the temporary _MEI... extraction directory.

File Purpose
defaults.json Last-used longitude, latitude, start date and end date
download_era5_data.log Execution log for the latest run
_era5_cds_download_payload.zip Temporary CDS payload, deleted after successful or failed processing where possible
era5_data.csv Merged raw ERA5 table after normalisation to compact columns
output.csv Final engineering table with computed wind speed and wind direction

7.1 Intermediate file: era5_data.csv

The intermediate merged CSV has fixed columns:

datetime,swh,mwp,mwd,u10,v10
Column Unit Description
datetime UTC-like timestamp string Parsed ERA5 valid time, formatted as YYYY-MM-DD HH:MM:SS
swh m Significant height of combined wind waves and swell
mwp s Mean wave period
mwd degrees Mean wave direction
u10 m/s 10 m U wind component
v10 m/s 10 m V wind component

7.2 Final file: output.csv

The final processed CSV has fixed columns:

datetime,swh,mwp,mwd,wind,dwi,u10,v10
Column Unit Description
datetime UTC-like timestamp string ERA5 valid time, formatted as YYYY-MM-DD HH:MM:SS
swh m Significant height of combined wind waves and swell
mwp s Mean wave period
mwd degrees Mean wave direction
wind m/s Computed 10 m wind speed from u10 and v10
dwi degrees Computed meteorological wind direction, North = 0°, clockwise positive
u10 m/s 10 m U wind component
v10 m/s 10 m V wind component

The final CSV is sorted by datetime, duplicate timestamps are dropped by keeping the first occurrence, and timestamps are formatted consistently.


8. Wind calculations implemented by the script

8.1 Wind speed

The 10 m wind speed is computed from the horizontal components:

wind = sqrt(u10^2 + v10^2)

where:

  • u10 is the eastward component;
  • v10 is the northward component;
  • wind is the scalar speed.

8.2 Meteorological wind direction

The script computes dwi as:

dwi = (180 + atan2(u10, v10) * 180 / pi) mod 360

This gives a meteorological direction in degrees:

  • 0° means wind from north;
  • 90° means wind from east;
  • 180° means wind from south;
  • 270° means wind from west;
  • values are wrapped into the interval [0, 360).

This is the conventional “direction from which the wind blows” representation. It differs from a mathematical vector direction “towards which the vector points”.

8.3 Examples

u10 v10 Wind vector points towards Meteorological dwi
0 -10 South
-10 0 West 90°
0 10 North 180°
10 0 East 270°

9. Data parsing and normalisation

9.1 Payload formats accepted

Although the CDS request asks for CSV, the response can be one of several practical payload types. The script supports:

Payload type Handling
Plain text CSV Decoded and parsed directly
ZIP archive containing CSV files Each table member is read and merged
ZIP archive containing XLS/XLSX files Each workbook/sheet is read through pandas.read_excel
Single Office Open XML table Read as Excel if the payload starts with PK but is not a ZIP table archive

The script rejects payloads that look like unsupported binary formats, including NetCDF/HDF-like content, because the current workflow is intentionally CSV/table based.

9.2 Robust CSV reading

The CSV reader is intentionally defensive because CDS table payloads may include metadata lines before the real header. The parser:

  1. decodes bytes using fallback encodings;
  2. detects the real table header by searching for a row containing a recognised time field and at least one recognised ERA5 variable;
  3. detects the delimiter among comma, semicolon and tab;
  4. filters malformed or metadata lines;
  5. reads the cleaned text with pandas.read_csv;
  6. strips quotes and whitespace from column names.

9.3 Column mapping

The script maps long CDS variable names and shorter aliases to the compact internal schema.

Internal column Accepted source names
datetime datetime, valid_time, time, timestamp, date
swh significant_height_of_combined_wind_waves_and_swell, swh
mwp mean_wave_period, mwp, pp1d
mwd mean_wave_direction, mwd
u10 10m_u_component_of_wind, u10
v10 10m_v_component_of_wind, v10

The pp1d alias is only a defensive legacy alias in the column-mapping stage. The current request does not request peak period.

9.4 Wide and long tables

The script can standardise both:

  • wide tables, where variables are already columns;
  • long tables, where a variable/value pair must be pivoted into columns.

This makes the post-processing robust to small differences in CDS table structure.

9.5 Merging multiple returned tables

When CDS returns separate atmospheric and wave tables, the script:

  1. standardises each returned table;
  2. parses and sorts the datetime field;
  3. converts recognised variable columns to numeric values;
  4. drops duplicate timestamps inside each table;
  5. sets datetime as the index;
  6. combines tables using first non-empty values;
  7. writes one merged era5_data.csv.

Missing variable columns are created as empty columns during the merge stage, but the final output.csv stage requires non-empty swh, mwp, mwd, u10 and v10. This prevents silently generating an incomplete engineering file.


10. Runtime validation and safe writing

Before the CDS download starts, the script checks whether the output files can be written. It tests:

  • write access to the output directory;
  • whether era5_data.csv can be opened for appending if it already exists;
  • whether output.csv can be opened for appending if it already exists.

If a CSV is open in Excel, LibreOffice, a text editor, Windows Preview Pane, or another process, the script stops before downloading data and gives a practical message asking the user to close the file.

CSV writing uses a temporary file followed by atomic replacement:

.era5_data.writing.csv  -> era5_data.csv
.output.writing.csv     -> output.csv

This avoids leaving partially written final outputs after a failed write.


11. Defaults and date behaviour

The script stores GUI/CLI defaults in:

defaults.json

The hardcoded defaults are:

Field Default
Longitude -9.58166667
Latitude 41.14833299
Start date 1940-01-01
End date current local date minus 5 days

The minus-5-days default reflects the approximate ERA5 latency and reduces the likelihood of requesting data not yet available.

Dates must be entered as:

YYYY-MM-DD

The script validates that the start date is less than or equal to the end date.


12. Graphical interface

12.1 Launching the GUI

Run without arguments:

python download_era5_data.py

or explicitly:

python download_era5_data.py --gui

In the compiled executable, double-click:

dist\download_era5_data.exe

12.2 GUI tabs

The GUI contains three tabs:

Tab Purpose
Run Enter coordinates and dates, start the workflow, view progress
Log Read the execution log inside the GUI
Instructions Read embedded usage and build notes

12.3 Run tab

The Run tab contains:

  • longitude field;
  • latitude field;
  • start date field;
  • end date field;
  • Start button;
  • Open Log tab button;
  • Quit button;
  • progress bar;
  • progress text;
  • estimated completion time text.

Longitude and latitude must be decimal degrees, with longitude first and latitude second.

12.4 GUI layout

The GUI uses fixed minimum dimensions and structured panels for the Run, Log and Instructions tabs. The current main dimensions are defined in the script through constants such as:

DEFAULT_WINDOW_WIDTH = 980
DEFAULT_WINDOW_HEIGHT = 700
DEFAULT_WINDOW_MIN_WIDTH = 940
DEFAULT_WINDOW_MIN_HEIGHT = 660

The window is resizable, but the minimum dimensions are chosen so that the main controls remain visible without requiring scrolling during normal use.

12.5 Background worker thread

The CDS request and processing pipeline run in a worker thread so that the Tkinter main loop remains responsive. Messages are sent back to the GUI through a queue and displayed as log, status and progress events.

12.6 GUI log writer

The GUI log uses a TkTextWriter adapter exposing write() and flush(). This allows log-style writing into the Tkinter text widget and prevents failures from code paths expecting a file-like writer.


13. Command-line interface

13.1 Basic CLI run

python download_era5_data.py --longitude -9.58166667 --latitude 41.14833299 --start-date 1940-01-01 --end-date 2026-05-08

13.2 Multiline Windows cmd example

python download_era5_data.py ^
  --longitude -9.58166667 ^
  --latitude 41.14833299 ^
  --start-date 1940-01-01 ^
  --end-date 2026-05-08

13.3 CLI options

Option Meaning
--gui Launch GUI mode explicitly
--longitude Target longitude in decimal degrees
--latitude Target latitude in decimal degrees
--start-date Start date in YYYY-MM-DD format
--end-date End date in YYYY-MM-DD format

There is no --download, --extract, --data-dir, --results-dir, --output-csv, or --log-file option in the current script.


14. Installation

14.1 Python version

Use a current standard Windows Python installation from python.org. Tkinter is normally included with standard Windows Python distributions.

14.2 Create a local virtual environment

Run these commands in Windows cmd from the project folder:

python -m venv venv
venv\Scripts\activate
python -m pip install --upgrade pip
python -m pip install "cdsapi>=0.7.7" numpy pandas openpyxl pyinstaller

The quoted cdsapi>=0.7.7 requirement follows the current CDS recommendation to use the latest available CDS API client. pyinstaller is only needed when building the standalone Windows executable.

14.3 Install only the CDS API client

If the objective is only to install or update the CDS API client in an existing Python environment, run:

python -m pip install --upgrade "cdsapi>=0.7.7"

On Unix/Linux or macOS, the equivalent command is:

python3 -m pip install --upgrade "cdsapi>=0.7.7"

14.4 Runtime dependencies

Package Required Purpose
cdsapi Yes CDS API client used to submit and download CDS requests
numpy Yes Wind speed and direction calculations
pandas Yes CSV/Excel reading, time parsing, table merging and CSV writing
openpyxl Conditional Reading XLSX payload members if CDS returns Excel tables
pyinstaller Build only Creating the Windows standalone executable
tkinter GUI mode GUI; normally included with Windows Python

14.5 Dependencies intentionally not required

Do not install these for the current script unless another tool in the repository needs them:

xarray cfgrib eccodes pygrib

They are not used by this script.


15. CDS API installation and configuration

A configured CDS API account is required before download_era5_data.py can retrieve data from the Copernicus Climate Data Store.

15.1 Required CDS account steps

Before running the script:

  1. Register for a Copernicus Climate Data Store account if you do not already have one.
  2. Log in to the CDS website.
  3. Open the ERA5 time-series dataset page used by this script.
  4. Accept the dataset Terms of Use / licence from the dataset download form.
  5. Open the CDS API setup page and copy the personal API credentials shown for your account.

The dataset Terms of Use must be accepted manually in the browser. Installing cdsapi and creating an API-key file is not sufficient if the dataset licence has not been accepted.

15.2 Supported CDS API credential files

The script supports both of these credential file names:

.ecmwfapirc
.cdsapirc

On Windows, the official CDS API configuration location is normally the user profile folder:

%USERPROFILE%\.cdsapirc

For operational redundancy, the script also accepts .ecmwfapirc and searches the script/executable directory if no usable credential file is found in %USERPROFILE%.

15.3 Credential-file search order

The search order is fixed:

Priority Location searched
1 %USERPROFILE%\.ecmwfapirc
2 %USERPROFILE%\.cdsapirc
3 <script-or-exe-directory>\.ecmwfapirc
4 <script-or-exe-directory>\.cdsapirc

In normal Python execution, <script-or-exe-directory> is the folder containing download_era5_data.py.

In the PyInstaller executable, <script-or-exe-directory> is the folder containing download_era5_data.exe. It is not the temporary _MEI... extraction folder.

This redundancy allows the program to run even when the user forgets to copy the API-key file to %USERPROFILE%, provided that a valid .ecmwfapirc or .cdsapirc file is placed beside the script or executable.

15.4 Credential-file contents

The usual CDS API two-line format is supported:

url: https://cds.climate.copernicus.eu/api
key: <PERSONAL-ACCESS-TOKEN>

Replace <PERSONAL-ACCESS-TOKEN> with the personal access token displayed in the logged-in CDS account. Do not include angle brackets in the real file.

The script also supports JSON-style ECMWF credential files with at least url and key fields, for example:

{
  "url": "https://cds.climate.copernicus.eu/api",
  "key": "<PERSONAL-ACCESS-TOKEN>"
}

An optional verify entry is also read if present. It may be useful in controlled corporate environments with customised certificate verification settings.

15.5 Practical Windows setup

To create the standard CDS credential file in the Windows user profile folder, run from Windows cmd:

notepad %USERPROFILE%\.cdsapirc

Paste the credentials and save the file.

To use the redundant local fallback instead, place either of these files in the same folder as download_era5_data.py or download_era5_data.exe:

.ecmwfapirc
.cdsapirc

The local fallback is useful when distributing the executable in a working folder or when the operator does not have the API-key file in %USERPROFILE%.

15.6 CDS API key file on Unix/Linux or macOS

On Unix/Linux or macOS, the conventional CDS API credentials file is:

$HOME/.cdsapirc

Its contents should follow the same structure:

url: https://cds.climate.copernicus.eu/api
key: <PERSONAL-ACCESS-TOKEN>

The script is Windows-oriented, but the same credential-file parser can read .ecmwfapirc or .cdsapirc from the user home directory and from the script directory.

15.7 Install the CDS API client

The CDS API client is a Python library and supports Python 3. Install it with pip:

python -m pip install --upgrade "cdsapi>=0.7.7"

or, on Unix/Linux/macOS:

python3 -m pip install --upgrade "cdsapi>=0.7.7"

For this project, the full dependency installation command is still:

python -m pip install "cdsapi>=0.7.7" numpy pandas openpyxl pyinstaller

15.8 Quick configuration test

After creating .ecmwfapirc or .cdsapirc, check that Python can import the CDS API client:

python -c "import cdsapi; print('cdsapi import OK')"

A successful import confirms that the package is installed. The first real download performed by the script confirms that the credential file, personal access token, CDS endpoint and dataset licence are all valid.

15.9 Security note

The .ecmwfapirc or .cdsapirc file contains a personal access token. Do not commit it to GitHub, send it by email, include it in screenshots, or package it with a public executable. Each operator should configure CDS credentials in their own user profile or keep a private copy beside the local script/executable.


16. Syntax check

Before building or distributing the tool, run:

python -m py_compile download_era5_data.py

This confirms that the script is syntactically valid Python source.


17. Standalone Windows executable compilation

17.1 Required files

Place these files in the same folder:

download_era5_data.py
download_era5_data.spec

17.2 Build command using the spec file

Activate the virtual environment, then run:

python -m PyInstaller --clean --noconfirm download_era5_data.spec

The executable is created at:

dist\download_era5_data.exe

17.3 Why the spec file is used

The spec file controls how PyInstaller builds the executable. The current GUI executable must be built with:

console=False

inside the EXE(...) block. This prevents the background command-prompt/MS-DOS window from appearing before the Tkinter GUI window.

17.4 Expected download_era5_data.spec

The essential EXE(...) configuration is:

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='download_era5_data',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

17.5 No-console stream handling

When a PyInstaller executable is built with console=False, Windows may set sys.stdout, sys.stderr or sys.stdin to None. Some third-party libraries can still attempt to call .write(), .flush() or .isatty() on those streams.

The script therefore includes a startup compatibility function that redirects missing standard streams to os.devnull. This preserves silent GUI behaviour while avoiding errors such as:

'NoneType' object has no attribute 'write'

17.6 Running the executable

Double-click:

dist\download_era5_data.exe

The program should open only the graphical window, without a background console window.

17.7 Output location in compiled mode

In one-file PyInstaller mode, the script itself is extracted into a temporary _MEI... folder. The current script avoids writing outputs there. Instead, it writes all persistent files next to the executable:

folder-containing-exe\defaults.json
folder-containing-exe\download_era5_data.log
folder-containing-exe\era5_data.csv
folder-containing-exe\output.csv

18. Operational workflow

A recommended production workflow is:

  1. Create and activate the Python virtual environment.
  2. Install dependencies.
  3. Configure CDS API credentials in %USERPROFILE% or beside the script/executable, and accept the dataset licence.
  4. Run python -m py_compile download_era5_data.py.
  5. Launch the GUI with python download_era5_data.py.
  6. Run a short date range first to verify CDS access and output format.
  7. Close any open CSV files before running a long extraction.
  8. Run the full target period.
  9. Check download_era5_data.log.
  10. Inspect era5_data.csv and output.csv.
  11. Archive the README, script, spec file, log file, output files and acquisition date.

For repeated use by non-Python operators:

  1. Build download_era5_data.exe using the spec file.
  2. Place the EXE in a clean working folder.
  3. Double-click the EXE.
  4. Run from the GUI.
  5. Collect outputs from the same folder as the EXE.

19. Engineering QA/QC checks

Before using output.csv in design calculations, check:

19.1 Time coverage

Verify that the first and last timestamps match the requested date range. For a complete hourly record, most days should contain 24 samples.

19.2 Missing values

Check non-empty counts for:

swh,mwp,mwd,u10,v10,wind,dwi

The script logs non-empty counts for the main variables. Any unexpected empty column should be investigated before use.

19.3 Directional conventions

Confirm that the downstream tool expects:

  • wave directions as ERA5 mean wave directions in degrees;
  • wind directions as meteorological “from” directions;
  • degrees clockwise from true north.

Do not mix “from” and “to” conventions.

19.4 Grid-point representativeness

For coastal points, remember that the wave grid is coarser than the atmospheric grid. A requested point near land, islands, breakwaters or complex bathymetry may be represented by a grid point that is not suitable for local nearshore design without transformation or validation.

19.5 Comparison with local data

Where buoy, weather-station, hindcast or measured data exist, compare at least:

  • overlapping storm peaks;
  • seasonal wave-height distribution;
  • mean and extreme wind speed;
  • directional sectors;
  • missing-data periods;
  • outliers and unrealistic values.

19.6 Derived design parameters

The script does not compute return periods, joint probability, persistence, storm duration, overtopping, wave transformation, extreme-value fits, or design sea states. Those analyses should be performed in a separate controlled workflow.


20. Troubleshooting

20.1 A black console window appears before the GUI

Cause: the executable was built as a console application.

Fix: compile with the spec file and make sure the spec contains console=False:

python -m PyInstaller --clean --noconfirm download_era5_data.spec

20.2 Error: 'NoneType' object has no attribute 'write'

Cause: a GUI executable built with console=False has no real standard output/error stream, and a third-party package attempted to write to it.

Fix: use the current script, which redirects missing standard streams to os.devnull at startup.

20.3 Output CSV is locked

Cause: era5_data.csv or output.csv is open in another program.

Fix: close the file in Excel, LibreOffice, Notepad, Windows Preview Pane, or any program that may hold the file lock, then run again.

20.4 CDS returns multiple files in a ZIP

This is expected for mixed atmospheric and wave parameters. The script reads all supported CSV/XLS/XLSX members and merges them by timestamp.

20.5 Empty wave or wind columns

The script stops before writing final output.csv if a required column is entirely empty. Check:

  • CDS service status;
  • requested location;
  • requested date range;
  • whether the selected location is valid for wave-model output;
  • the log file;
  • whether the returned payload changed structure.

20.6 cdsapi cannot authenticate

Check that a valid .ecmwfapirc or .cdsapirc file exists in one of the supported locations:

%USERPROFILE%\.ecmwfapirc
%USERPROFILE%\.cdsapirc
<script-or-exe-directory>\.ecmwfapirc
<script-or-exe-directory>\.cdsapirc

The file must contain valid url and key entries. Also confirm that the dataset licence has been accepted in the CDS website. If CDS changes the API endpoint, update the url value according to the current instructions in the logged-in CDS account page.

20.7 The EXE writes files to an unexpected folder

The current script writes files beside the executable in compiled mode. Move the EXE to the folder where you want outputs to be created, then run it from there.

20.8 The GUI appears frozen during download

The processing runs in a background worker thread. For long date ranges, the CDS request itself may take time. Use the Log tab and download_era5_data.log to check progress.


21. Engineering limitations

This tool gives a compact point time-series. It does not perform:

  • nearshore wave transformation;
  • spectral wave modelling;
  • tide/current coupling;
  • bathymetric refraction;
  • diffraction around port structures;
  • harbour agitation modelling;
  • wave overtopping analysis;
  • run-up calculation;
  • extreme-value analysis;
  • physical model scaling;
  • storm-event clustering;
  • directional sector fitting;
  • climate-change correction.

For breakwater, harbour, dredging, coastal protection or runway-extension design, the output should normally be treated as an offshore or regional metocean input that may require transformation to the project site.


22. Repository structure

A minimal folder for source execution is:

project-folder\
├─ download_era5_data.py
├─ download_era5_data.spec
└─ README.md

After a run, the folder may contain:

project-folder\
├─ defaults.json
├─ download_era5_data.log
├─ era5_data.csv
└─ output.csv

After compilation, PyInstaller creates:

project-folder\
├─ build\
├─ dist\
│  └─ download_era5_data.exe
└─ download_era5_data.spec

The build\ folder can be deleted after successful compilation. The dist\download_era5_data.exe file is the standalone executable.


23. Developer notes

23.1 Main execution path

The main execution path is:

main()
  -> build_parser()
  -> validate_runtime_dependencies()
  -> GUI mode or CLI mode
  -> execute_pipeline()
  -> setup_logging()
  -> _preflight_output_files()
  -> download_raw_csv()
  -> build_output_csv()

23.2 Main processing functions

Function Role
_ensure_standard_streams() Prevents no-console Windows EXE stream errors
_application_directory() Resolves script/EXE output directory
load_defaults() / save_defaults() Handles defaults.json
validate_runtime_dependencies() Checks required imports
resolve_cds_api_config() Finds and parses .ecmwfapirc / .cdsapirc credentials in the supported search order
initialize_cds_client() Creates cdsapi.Client with the parsed url, key and optional verify setting
_build_cds_request() Builds the CDS API request dictionary
_download_cds_payload() Downloads the CDS response payload
_read_tables_from_cds_payload() Detects plain CSV, ZIP or Excel-like payloads
standardize_dataframe() Maps raw table columns to compact names
_normalize_cds_payload_to_merged_csv() Produces era5_data.csv
build_output_csv() Computes wind and dwi, writes output.csv
Era5DownloaderGUI Tkinter GUI controller
TkTextWriter File-like adapter for the GUI log text widget

23.3 Adding more variables

To add more variables, modify:

  1. the LONG_* constants or add new constants;
  2. ERA5_VARIABLES;
  3. MERGED_COLUMNS if the variable should be preserved in era5_data.csv;
  4. OUTPUT_COLUMNS if the variable should appear in output.csv;
  5. RAW_TO_SHORT_CANDIDATES for mapping aliases;
  6. build_output_csv() if derived variables are required;
  7. this README.

For additional variables, verify whether they belong to the atmospheric grid or wave grid and whether CDS returns them in separate files.


24. References and source material

24.1 Copernicus / ECMWF dataset references

  1. Copernicus Climate Data Store. ERA5 hourly time-series data on single levels from 1940 to present.
    https://cds.climate.copernicus.eu/datasets/reanalysis-era5-single-levels-timeseries

  2. Copernicus Knowledge Base / ECMWF Confluence. ERA5 hourly time-series data on single levels from 1940 to present: Product User Guide (PUG).
    https://confluence.ecmwf.int/pages/viewpage.action?pageId=505390919

  3. Copernicus Knowledge Base / ECMWF Confluence. ERA5: data documentation.
    https://confluence.ecmwf.int/display/CKB/ERA5%3A+data+documentation

  4. Copernicus Knowledge Base / ECMWF Confluence. How to download ERA5.
    https://confluence.ecmwf.int/display/CKB/How+to+download+ERA5

  5. Copernicus Knowledge Base / ECMWF Confluence. How to install and use CDS API on Windows.
    https://confluence.ecmwf.int/display/CKB/How+to+install+and+use+CDS+API+on+Windows

24.2 Scientific references

  1. Hersbach, H., Bell, B., Berrisford, P., et al. (2020). The ERA5 global reanalysis. Quarterly Journal of the Royal Meteorological Society, 146, 1999–2049.
    https://doi.org/10.1002/qj.3803

  2. Bell, B., Hersbach, H., Simmons, A., et al. (2021). The ERA5 global reanalysis: Preliminary extension to 1950. Quarterly Journal of the Royal Meteorological Society, 147, 4186–4227.
    https://doi.org/10.1002/qj.4174

24.3 Software references

  1. Python Software Foundation. Python documentation.
    https://docs.python.org/

  2. PyInstaller. PyInstaller documentation.
    https://pyinstaller.org/

  3. pandas Development Team. pandas documentation.
    https://pandas.pydata.org/docs/

  4. NumPy Developers. NumPy documentation.
    https://numpy.org/doc/

  5. Copernicus Climate Data Store. CDS API package and access instructions.
    https://cds.climate.copernicus.eu/how-to-api


25. Citation and attribution note

When data generated by this script are used in reports, papers, design notes or contractual submissions, cite the relevant Copernicus/ECMWF ERA5 dataset entry and the scientific ERA5 references. Also archive the generated download_era5_data.log, because it records the requested variables, target point, date range and output files.

Suggested report wording:

ERA5 hourly time-series data were retrieved from the Copernicus Climate Data Store using the dataset `reanalysis-era5-single-levels-timeseries`. The selected variables were significant height of combined wind waves and swell, mean wave period, mean wave direction, and the 10 m U and V wind components. Wind speed and meteorological wind direction were computed from the 10 m vector components during post-processing.

About

This program downloads wave & wind data from the ERA5 reanalysis model using the Climate Data Store (CDS) API provided by ECMWF.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages