diff --git a/docs/users_guide/era5-forcing.md b/docs/users_guide/era5-forcing.md index cea7bf8..bcede41 100644 --- a/docs/users_guide/era5-forcing.md +++ b/docs/users_guide/era5-forcing.md @@ -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 @@ -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 -``` - -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 -``` +Both scripts modify the ERA5 instant file in place before remapping. +No manual invocation of these scripts is needed. ### Remapping, Data merging, CLM3.5 diff --git a/mkforcing/custom_request_ERA5.py b/mkforcing/custom_request_ERA5.py index 9e9eb19..e16322d 100644 --- a/mkforcing/custom_request_ERA5.py +++ b/mkforcing/custom_request_ERA5.py @@ -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", @@ -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 } diff --git a/mkforcing/download_ERA5_input.py b/mkforcing/download_ERA5_input.py index 6bf1467..6c7ec21 100755 --- a/mkforcing/download_ERA5_input.py +++ b/mkforcing/download_ERA5_input.py @@ -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 @@ -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: diff --git a/mkforcing/download_ERA5_input_wrapper.sh b/mkforcing/download_ERA5_input_wrapper.sh index 5903282..cb81c67 100755 --- a/mkforcing/download_ERA5_input_wrapper.sh +++ b/mkforcing/download_ERA5_input_wrapper.sh @@ -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 diff --git a/mkforcing/prepare_ERA5_input.sh b/mkforcing/prepare_ERA5_input.sh index f3684fb..b49eaef 100755 --- a/mkforcing/prepare_ERA5_input.sh +++ b/mkforcing/prepare_ERA5_input.sh @@ -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 @@ -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() { @@ -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} @@ -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 @@ -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 @@ -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