Skip to content
Open
24 changes: 12 additions & 12 deletions docs/users_guide/era5-forcing.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ Or using the wrapper script:
`./download_ERA5_input_wrapper.sh`
after changing dates and output directory in the `Settings` section inside this wrapper script.

Non-JSC users should adapt the download script to include temperature, specific humidity and horizontal wind speed.
Non-JSC users should adapt the download script to include temperature,
dewpoint temperature (`d2m`), surface pressure (`sp`), and horizontal
wind speed. The `d2m` and `sp` variables are required by
`dewpoint_to_specific_humidity.py` when using Option 2 below.

### Preparation of ERA5 data

Expand Down Expand Up @@ -91,19 +94,16 @@ after adapting `year` and `month` loops according to needed dates.
For users who do not have access to the Meteocloud, the required
variables can be derived from the CDS API download directly.

For ERA5, specific humidity can be computed from dewpoint temperature
and surface pressure using
When running `prepare_ERA5_input.sh` with `lmeteo=false`, the script
automatically calls:

```
python dewpoint_to_specific_humidity.py <era5_filename>
```

Also temperature and specific humidity can be converted from 2m to 10m
using:
1. `dewpoint_to_specific_humidity.py` — computes specific humidity (`q2m`)
from dewpoint temperature (`d2m`) and surface pressure (`sp`)
2. `2m_to_10m_conversion.py` — extrapolates temperature and specific
humidity from 2m to 10m (`t10m`, `q10m`)

```
python 2m_to_10m_conversion.py <era5_filename>
```
Both scripts modify the ERA5 instant file in place before remapping.
No manual invocation of these scripts is needed.

### Remapping, Data merging, CLM3.5

Expand Down
14 changes: 7 additions & 7 deletions mkforcing/custom_request_ERA5.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
request = {
"product_type": ["reanalysis"],
"variable": [
"surface_pressure",
"mean_surface_downward_long_wave_radiation_flux",
"mean_surface_downward_short_wave_radiation_flux",
"mean_total_precipitation_rate",
"10m_u_component_of_wind",
"10m_v_component_of_wind",
"2m_temperature",
"2m_dewpoint_temperature",
"2m_temperature",
"surface_pressure",
"mean_surface_downward_long_wave_radiation_flux",
"mean_surface_downward_short_wave_radiation_flux",
"mean_total_precipitation_rate"
],
"time": [
"00:00", "01:00", "02:00",
Expand All @@ -27,8 +27,8 @@
"21:00", "22:00", "23:00"
],
"data_format": "netcdf",
"download_format": "unarchived",
"area": [50.870906, 6.4421445, 50.870906, 6.4421445] # Selhausen
"download_format": "zip",
"area": [50.865906 + 0.125, 6.4471445 - 0.125, 50.865906 - 0.125, 6.4471445 + 0.125] # Selhausen ± 0.125° → single ERA5 grid point [N, W, S, E]
# "area": [74, -42, 20, 69] # Europe
}

Expand Down
17 changes: 10 additions & 7 deletions mkforcing/download_ERA5_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ def generate_datarequest(year, monthstr, days,
# Detect the actual file type
extension = detect_file_type(target)

# Rename to final target with correct extension
final_target = f'{target}{extension}'
# Rename to clean predictable filename with correct extension
final_target = f'download_era5_{year}_{monthstr}{extension}'
os.rename(target, final_target)
target = final_target

Expand Down Expand Up @@ -223,25 +223,28 @@ def generate_datarequest(year, monthstr, days,
if not os.path.exists(dirout):
os.makedirs(dirout)

# Resolve request path before changing directory
request_path = os.path.abspath(args.request) if args.request else None

# change to output directory
os.chdir(dirout)

# Load custom request if provided
custom_request = None
custom_dataset = args.dataset
if args.request:
if request_path:
import importlib.util
spec = importlib.util.spec_from_file_location("custom_request_module", args.request)
spec = importlib.util.spec_from_file_location("custom_request_module", request_path)
custom_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(custom_module)
if hasattr(custom_module, 'request'):
custom_request = custom_module.request
print(f"Loaded custom request from: {args.request}")
print(f"Loaded custom request from: {request_path}")
else:
print(f"Warning: No 'request' variable found in {args.request}, using default")
print(f"Warning: No 'request' variable found in {request_path}, using default")
if hasattr(custom_module, 'dataset'):
custom_dataset = custom_module.dataset
print(f"Loaded custom dataset from: {args.request}")
print(f"Loaded custom dataset from: {request_path}")

# Handle year: extract from custom request if not provided
if year is None:
Expand Down
4 changes: 2 additions & 2 deletions mkforcing/download_ERA5_input_wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ parse_arguments() {
parse_arguments "$@"


# create output directory
mkdir -p $out_dir
# create output directory (now handled by download_ERA5_input.py)
# mkdir -p $out_dir

# loop over months
current_date=$start_date
Expand Down
25 changes: 18 additions & 7 deletions mkforcing/prepare_ERA5_input.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env bash
set -eo pipefail

# Resolve script directory before any cd
script_dir=$(cd "$(dirname "$0")" && pwd)

# default values of parameters
lrmp=true
lmerge=true
Expand Down Expand Up @@ -28,8 +31,8 @@ iyear=2017
imonth=07
tmpdir=tmpdir
wrkdir=""
author="Stefan POLL"
email="s.poll@fz-juelich.de"
author=$(git config user.name 2>/dev/null || echo "${USER}")
email=$(git config user.email 2>/dev/null || echo "")

# Function to parse input
parse_arguments() {
Expand Down Expand Up @@ -81,13 +84,14 @@ do
if [ -z ${wrkdir} ];then
wrkdir=${iyear}-${imonth}
fi
mkdir -pv $wrkdir
cd $wrkdir
mkdir -pv $tmpdir

if $lrmp; then
if $lunzip; then
# Unzip ERA5-downloaded data from zip file
unzip ${pathdata}/download_era5_${year}_${month}.zip -d ${tmpdir}
unzip -o ${pathdata}/download_era5_${year}_${month}.zip -d ${tmpdir}
else
# Copy already unzipped data
cp ${pathdata}/data_stream-oper_stepType-instant.nc ${pathdata}/data_stream-oper_stepType-avg.nc ${tmpdir}
Expand All @@ -105,6 +109,13 @@ do
done
fi

if ! $lmeteo; then
# Compute specific humidity (q2m) from dewpoint temperature and surface pressure
python ${script_dir}/dewpoint_to_specific_humidity.py ${tmpdir}/data_stream-oper_stepType-instant.nc
# Extrapolate temperature (t10m) and specific humidity (q10m) from 2m to 10m
python ${script_dir}/2m_to_10m_conversion.py ${tmpdir}/data_stream-oper_stepType-instant.nc
fi

if $lwgtdis; then
cdo gendis,${domainfile} ${tmpdir}/data_stream-oper_stepType-instant.nc ${wgtcaf}
if $lmeteo; then
Expand Down Expand Up @@ -162,8 +173,8 @@ do
# ncap2 -O -s 'where(FSDS<0.) FSDS=0' ${year}_${month}.nc
ncatted -O -a units,ZBOT,m,c,"m" ${year}-${month}.nc

ncks -O -h --glb author="${author}" ${year}-${month}.nc
ncks -O -h --glb contact="${email}" ${year}-${month}.nc
ncks -O -h --glb author="${author}" ${year}-${month}.nc ${year}-${month}.nc
ncks -O -h --glb contact="${email}" ${year}-${month}.nc ${year}-${month}.nc

rm ${tmpdir}/${year}_${month}_temp*nc ${tmpdir}/${year}_${month}_const.nc
fi
Expand All @@ -184,8 +195,8 @@ do
ncrename -d rlon,lon ${year}-${month}.nc
ncrename -d rlat,lat ${year}-${month}.nc

ncks -O -h --glb author="${author}" ${year}-${month}.nc
ncks -O -h --glb contact="${email}" ${year}-${month}.nc
ncks -O -h --glb author="${author}" ${year}-${month}.nc ${year}-${month}.nc
ncks -O -h --glb contact="${email}" ${year}-${month}.nc ${year}-${month}.nc

#
rm ${year}_${month}_tmp.nc ${tmpdir}/${year}_${month}_temp11.nc
Expand Down
Loading