If you're new to NDFD, take a look at the documentation. It shows the different file formats, types of data available and period of forecast for each type. The data directories are divided by forcast days: 1-3 day, 4-7 day and 8 to 450. The 1-3 day is a good place to start.
Primarily, I'll be working in a Linux envrinment, with GDAL 3.12 and jq (CLI json parser). We'll look at 1-3 day QPF and show how to aggregate it for "How much rain in 3 days?" type of forecast.
First, we need to choose at start and end time for the forecast. We want to aggregate all 3 days. So, whatever time it is now (or when you run your script) will be the start time, getting the latest data.
starttime=$(date +%s -u -d "now") endtime=$(date +%s -u -d "now + 3 days")
If we look at the NDFD documentation we'll see the 1-3 QPF data is forecast out to 72 hours, in 6 hour increments. That equates to a 12 band raster. To our virtual url looks like:
rast='/vsicurl/https://tgftp.nws.noaa.gov/SL.us008001/ST.opnl/DF.gr2/DC.ndfd/AR.conus/VP.001-003/ds.qpf.bin'
Here you can see where start time and end time are important. If we only wanted a forecast starting 12 hours from now and ending 24 hours from now, we can change that above. That would only be 2 bands.
bands=$( \
gdalinfo $rast -json \
| sed 's/"":/"item":/g' \
| jq ".bands[] \
| select((.metadata.item.GRIB_VALID_TIME \
| tonumber >= ${starttime}) and (.metadata.item.GRIB_VALID_TIME | tonumber <= ${endtime})).band" \
| tr "\n" "," |sed 's/,$//' \
)
Now, the business end. Read the remote raster, select only the bands we want and write it out to a command stream virtual file (it's just json).
gdal raster pipeline \
! read -i $rast \
! select --band $bands \
! write -o qpf.gdalg.json --overwrite
Let's aggregate the bands. Read our .json file, specify an output file, how to calc all the bands (sum), and flatten or sum all the bands as 1 band. Dialect is the math parser we're using. We'll compress it and save it as a Cloud Optimized Geotiff (COG).
gdal raster calc -i A=qpf.gdalg.json -o agg.tif --calc=sum --flatten --dialect=builtin --overwrite --co COMPRESS=DEFLATE --of COG
For added fun, let's add a color map and save it as a.png:
gdal raster pipeline \
! read -i agg.tif \
! resize --size=800,0 \
! reproject --dst-crs EPSG:5070 \
! color-map --color-map qpf-color-map.txt --add-alpha \
! write -o agg.png --progress
That's it!