-
Notifications
You must be signed in to change notification settings - Fork 3
Adapt ERA5 atmospheric forcing generation script #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 13 commits
1f3804d
f331c9e
95c1b66
ba833bb
1ec7e5c
926d4b9
75a1755
05cca5c
a737522
02dcd7f
858634d
898b539
4ee3f8d
62961e7
7fd7b35
fcc3bea
dcb4c22
46647a5
aee694e
e6ede36
4a3a8e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/usr/bin/env python3 | ||
import calendar | ||
import cdsapi | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we include a edit: ah, except for the NCL script they need to evben do a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed; it is written in the linked documentation. |
||
import sys | ||
import os | ||
|
||
def generate_days(year, month): | ||
# Get the number of days in the given month | ||
num_days = calendar.monthrange(year, month)[1] | ||
|
||
# Generate the list of days as integers | ||
days = [day for day in range(1, num_days + 1)] | ||
|
||
return days | ||
|
||
def generate_datarequest(year, monthstr, days): | ||
|
||
# active download client for climate data service (cds) | ||
client = cdsapi.Client() | ||
mvhulten marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# dataset to download rom cds | ||
dataset = "reanalysis-era5-single-levels" | ||
# request for cds | ||
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" | ||
], | ||
"year": [str(year)], | ||
"month": [monthstr], | ||
"day": days, | ||
"time": [ | ||
"00:00", "01:00", "02:00", | ||
"03:00", "04:00", "05:00", | ||
"06:00", "07:00", "08:00", | ||
"09:00", "10:00", "11:00", | ||
"12:00", "13:00", "14:00", | ||
"15:00", "16:00", "17:00", | ||
"18:00", "19:00", "20:00", | ||
"21:00", "22:00", "23:00" | ||
], | ||
"data_format": "netcdf", | ||
"download_format": "unarchived", | ||
"area": [74, -42, 20, 69] | ||
} | ||
# filename of downloaded file | ||
target = 'download_era5_'+str(year)+'_'+monthstr+'.zip' | ||
|
||
# Get the data from cds | ||
client.retrieve(dataset, request, target) | ||
|
||
if __name__ == "__main__": | ||
# Check if the correct number of arguments are provided | ||
if len(sys.argv) != 4: | ||
print("Usage: python download_ERA5_input.py <year> <month> <output_directory>") | ||
sys.exit(1) | ||
|
||
# Get the year and month from command-line arguments | ||
year = int(sys.argv[1]) | ||
month = int(sys.argv[2]) | ||
dirout = sys.argv[3] | ||
|
||
# Ensure the output directory exists, if not, create it | ||
if not os.path.exists(dirout): | ||
os.makedirs(dirout) | ||
|
||
# change to output directory | ||
os.chdir(dirout) | ||
|
||
# Format the month with a leading zero if needed | ||
monthstr = f"{month:02d}" | ||
|
||
# Get the list of days for the request | ||
days = generate_days(year, month) | ||
|
||
# do download request | ||
generate_datarequest(year, monthstr, days) |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Is a wrapper (in Bash) needed? Why not pass the user arguments to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, the linked standard is maybe overly restricted. At least on OpenBSD there is no Also breaks on OSX: no I don't know how to make it platform indenpendent in (Bourne) shell. Python would be nice (and better to use |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#!/usr/bin/env bash | ||
# Before using this script CDSAPI has to be configured (see README) | ||
# Needs to be executed at LOGIN node as connection to "outside" is required | ||
set -eo pipefail | ||
|
||
# load environment | ||
module load Python | ||
|
||
# Settings | ||
start_date="2017-07" # yyyy-mm | ||
end_date="2018-08" # yyyy-mm + 1 | ||
out_dir="cdsapidwn" | ||
|
||
# Function to parse input | ||
parse_arguments() { | ||
for arg in "$@"; do | ||
key="${arg%%=*}" | ||
value="${arg#*=}" | ||
|
||
case "$key" in | ||
start_date) start_date="$value" ;; | ||
end_date) end_date="$value" ;; | ||
out_dir) out_dir="$value" ;; | ||
*) echo "Warning: Unknown parameter: $key" ;; | ||
esac | ||
done | ||
} | ||
|
||
# Call the function to parse the input arguments | ||
# Users needs to make sure for consistent input | ||
parse_arguments "$@" | ||
|
||
|
||
# create output directory | ||
mkdir -p $out_dir | ||
|
||
# loop over months | ||
current_date=$start_date | ||
while [[ "$current_date" < "$end_date" ]]; do | ||
echo "Processing month: $current_date" | ||
|
||
year="${current_date%%-*}" | ||
month="${current_date#*-}" | ||
|
||
# start download script with data request | ||
./download_ERA5_input.py $year $month $out_dir | ||
|
||
# Increment the month | ||
current_date=$(date -I -d "$current_date-01 + 1 month" | cut -d'-' -f1,2) | ||
done |
This file was deleted.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get some warnings:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I use here
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,105 @@ | ||
#!/usr/bin/env bash | ||
set -eo pipefail | ||
|
||
# load env -> not all CDO are compiled with "-t ecmwf" | ||
# module use $OTHERSTAGES | ||
# ml Stages/2022 NVHPC/22.9 ParaStationMPI/5.5.0-1 CDO/2.0.2 | ||
|
||
if [ -z "$1" ] | ||
then | ||
iyear=2017 | ||
echo "Take the default year "$iyear | ||
else | ||
iyear=$1 | ||
echo "Calculate the year "$iyear | ||
fi | ||
function message(){ | ||
if [ -z "${quiet}" ];then | ||
echo "$1" | ||
fi # quiet | ||
} | ||
|
||
# default values of parameters | ||
iyear=2017 | ||
imonth=07 | ||
ihour=(00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23) | ||
outdir=${iyear}-${imonth} | ||
runpp=1 | ||
area=(-48 74 20 74) | ||
|
||
# Function to parse input | ||
parse_arguments() { | ||
for arg in "$@"; do | ||
key="${arg%%=*}" | ||
value="${arg#*=}" | ||
|
||
case "$key" in | ||
quiet) quiet=y;; | ||
iyear) iyear="$value" ;; | ||
imonth) imonth="$value" ;; | ||
ihour) ihour="$value" ;; | ||
outdir) outdir="$value" ;; | ||
runpp) runpp="$value" ;; | ||
area) area="$value" ;; | ||
*) echo "Warning: Unknown parameter: $key" ;; | ||
esac | ||
done | ||
} | ||
|
||
# Call the function to parse the input arguments | ||
# Users needs to make sure for consistent input | ||
parse_arguments "$@" | ||
|
||
message "==========================" | ||
message "Year: "$iyear | ||
message "Month: "$imonth | ||
message "Hours: "$ihour | ||
message "Selected area W: "${area[0]} | ||
message "Selected area E: "${area[1]} | ||
message "Selected area S: "${area[2]} | ||
message "Selected area N: "${area[3]} | ||
message "Output directory: "$outdir | ||
message "Max running procs: "$runpp | ||
message "==========================" | ||
|
||
cd ${outdir} | ||
|
||
# start a counter for background jobs | ||
running_jobs=0 | ||
|
||
for year in ${iyear} | ||
do | ||
for month in 01 #02 03 04 05 06 07 08 09 10 11 12 | ||
for month in ${imonth} | ||
do | ||
days_per_month=$(cal ${month} ${year} | awk 'NF {DAYS = $NF}; END {print DAYS}') | ||
for my_date in $(seq -w 1 ${days_per_month}) | ||
for day in $(seq -w 1 ${days_per_month}) | ||
do | ||
for time in 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ||
for hour in "${ihour[@]}" | ||
do | ||
|
||
cdo sellonlatbox,-48,74,20,74 /p/fastdata/slmet/slmet111/met_data/ecmwf/era5/grib/${year}/${month}/${year}${month}${my_date}${time}_ml.grb cut_domain_${year}${month}${my_date}${time}.grb | ||
# increment the running job counter | ||
running_jobs=$((running_jobs+1)) | ||
|
||
message "Process "$year"-"$month"-"$day"-"$hour" prun: "$running_jobs | ||
|
||
cdo sellevel,137 cut_domain_${year}${month}${my_date}${time}.grb lower_level_${year}${month}${my_date}${time}.grb | ||
#cdo -t ecmwf -f nc4 copy lower_level_${month}${my_date}${time}.grb lower_level_${month}${my_date}${time}.nc | ||
cdo -t ecmwf selname,t,u,v,q lower_level_${year}${month}${my_date}${time}.grb variables_lower_level_${year}${month}${my_date}${time}.grb | ||
# select domain area | ||
cdo sellonlatbox,${area[0]},${area[1]},${area[2]},${area[3]} /p/data1/slmet/met_data/ecmwf/era5/grib/${year}/${month}/${year}${month}${day}${hour}_ml.grb cut_domain_${year}${month}${day}${hour}.grb | ||
# select lowermost model level | ||
cdo sellevel,137 cut_domain_${year}${month}${day}${hour}.grb lower_level_${year}${month}${day}${hour}.grb | ||
# select temperature, horizontal wind speed, humidity | ||
cdo -t ecmwf selname,t,u,v,q lower_level_${year}${month}${day}${hour}.grb variables_lower_level_${year}${month}${day}${hour}.grb | ||
|
||
# if the max number of parallel tasks is reached, wait for a job to finish | ||
if [[ ${running_jobs} -ge ${runpp} ]]; then | ||
wait -n # wait for one job to finish before starting another | ||
running_jobs=$((running_jobs-1)) # decrement the running job counter | ||
fi | ||
|
||
done | ||
done | ||
|
||
wait | ||
|
||
# merge hourly files to monthly | ||
cdo merge variables_lower_level_${year}*.grb meteocloud_${year}_${month}.grb | ||
rm variables_lower_level_${year}*.grb cut_domain_${year}* lower_level_${year}* | ||
# transform from grib to netcdf format | ||
cdo -t ecmwf -f nc4 copy meteocloud_${year}_${month}.grb meteocloud_${year}_${month}.nc | ||
|
||
# clean-up | ||
rm variables_lower_level_${year}*.grb cut_domain_${year}* lower_level_${year}* | ||
|
||
done | ||
done | ||
|
Uh oh!
There was an error while loading. Please reload this page.