Skip to content

Commit 041a869

Browse files
committed
Add RAP data support with tests and documentation
1 parent ea9e89d commit 041a869

3 files changed

Lines changed: 169 additions & 1 deletion

File tree

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,25 @@ Global weather model with 6-hour update cycles.
8585
| `resolution` | `"0p25"`, `"0p50"`, `"1p00"` | Grid resolution in degrees |
8686
| `product` | `"atmos"`, `"wave"` | Atmospheric or wave |
8787
| `forecast` | `"f000"` to `"f384"` | Forecast hour |
88+
89+
## Generating Datasets for a Time Range
90+
91+
Use `datasets()` to generate all dataset instances covering a time period:
92+
93+
```julia
94+
using RapidRefreshData, Dates
95+
96+
# Get all HRRR datasets for a 6-hour window (returns 7 datasets, one per hour)
97+
hrrr_list = datasets(HRRRDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,6))
98+
99+
# Get all RAP datasets for a day (returns 4 datasets, one per 6-hour cycle)
100+
rap_list = datasets(RAPDataset, DateTime(2024,1,15), DateTime(2024,1,16))
101+
102+
# Get all GFS datasets for two days (returns 8 datasets)
103+
gfs_list = datasets(GFSDataset, DateTime(2024,1,15), DateTime(2024,1,16,18))
104+
105+
# Download all datasets in a time range
106+
for dset in datasets(HRRRDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,3))
107+
get(dset)
108+
end
109+
```

src/RapidRefreshData.jl

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using Dates, Scratch, Downloads
44

55
export AbstractDataset, RAPDataset, GFSDataset, HRRRDataset
66
export Band, bands, index_url
7-
export url, local_path, nextcycle, list, clear_cache!!, resolution_km, metadata
7+
export url, local_path, nextcycle, list, clear_cache!!, resolution_km, metadata, datasets
88

99
#-----------------------------------------------------------------------------# __init__
1010
"scratch directory for caching downloaded datasets"
@@ -335,6 +335,77 @@ function metadata()
335335
)
336336
end
337337

338+
#-----------------------------------------------------------------------------# datasets
339+
"""
340+
datasets(::Type{T}, start::DateTime, stop::DateTime) where {T <: AbstractDataset}
341+
342+
Return a Vector of all datasets of type `T` that cover the time period from `start` to `stop`.
343+
344+
Each dataset represents one model cycle (initialization time). The function returns all cycles
345+
whose initialization time falls within the specified range.
346+
347+
# Examples
348+
```julia
349+
using Dates
350+
351+
# Get all HRRR datasets for a 6-hour window (hourly cycles)
352+
datasets(HRRRDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,6))
353+
354+
# Get all RAP datasets for a day (6-hourly cycles)
355+
datasets(RAPDataset, DateTime(2024,1,15), DateTime(2024,1,16))
356+
357+
# Get all GFS datasets for a day (6-hourly cycles)
358+
datasets(GFSDataset, DateTime(2024,1,15), DateTime(2024,1,16))
359+
```
360+
"""
361+
function datasets end
362+
363+
function datasets(::Type{RAPDataset}, start::DateTime, stop::DateTime)
364+
result = RAPDataset[]
365+
cycles = ["t00z", "t06z", "t12z", "t18z"]
366+
cycle_hours = [0, 6, 12, 18]
367+
368+
for date in Date(start):Day(1):Date(stop)
369+
for (cycle, hour) in zip(cycles, cycle_hours)
370+
dt = DateTime(date) + Hour(hour)
371+
if start <= dt <= stop
372+
push!(result, RAPDataset(date=date, cycle=cycle))
373+
end
374+
end
375+
end
376+
return result
377+
end
378+
379+
function datasets(::Type{GFSDataset}, start::DateTime, stop::DateTime)
380+
result = GFSDataset[]
381+
cycles = ["00", "06", "12", "18"]
382+
cycle_hours = [0, 6, 12, 18]
383+
384+
for date in Date(start):Day(1):Date(stop)
385+
for (cycle, hour) in zip(cycles, cycle_hours)
386+
dt = DateTime(date) + Hour(hour)
387+
if start <= dt <= stop
388+
push!(result, GFSDataset(date=date, cycle=cycle))
389+
end
390+
end
391+
end
392+
return result
393+
end
394+
395+
function datasets(::Type{HRRRDataset}, start::DateTime, stop::DateTime)
396+
result = HRRRDataset[]
397+
398+
for date in Date(start):Day(1):Date(stop)
399+
for hour in 0:23
400+
dt = DateTime(date) + Hour(hour)
401+
if start <= dt <= stop
402+
push!(result, HRRRDataset(date=date, cycle=lpad(hour, 2, '0')))
403+
end
404+
end
405+
end
406+
return result
407+
end
408+
338409
#-----------------------------------------------------------------------------# Band/Variable Subsetting
339410
"""
340411
Band

test/runtests.jl

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,81 @@ using Dates
604604
@test next7.cycle == "10"
605605
end
606606

607+
@testset "datasets() function" begin
608+
# Test HRRRDataset - hourly cycles
609+
hrrr_dsets = datasets(HRRRDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,5))
610+
@test length(hrrr_dsets) == 6 # hours 0,1,2,3,4,5
611+
@test all(d -> d isa HRRRDataset, hrrr_dsets)
612+
@test all(d -> d.date == Date(2024,1,15), hrrr_dsets)
613+
@test [d.cycle for d in hrrr_dsets] == ["00", "01", "02", "03", "04", "05"]
614+
615+
# Test HRRRDataset - crossing midnight
616+
hrrr_midnight = datasets(HRRRDataset, DateTime(2024,1,15,22), DateTime(2024,1,16,2))
617+
@test length(hrrr_midnight) == 5 # 22,23,00,01,02
618+
@test hrrr_midnight[1].date == Date(2024,1,15)
619+
@test hrrr_midnight[1].cycle == "22"
620+
@test hrrr_midnight[end].date == Date(2024,1,16)
621+
@test hrrr_midnight[end].cycle == "02"
622+
623+
# Test RAPDataset - 6-hourly cycles
624+
rap_dsets = datasets(RAPDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,23))
625+
@test length(rap_dsets) == 4 # t00z, t06z, t12z, t18z
626+
@test all(d -> d isa RAPDataset, rap_dsets)
627+
@test all(d -> d.date == Date(2024,1,15), rap_dsets)
628+
@test [d.cycle for d in rap_dsets] == ["t00z", "t06z", "t12z", "t18z"]
629+
630+
# Test RAPDataset - partial day
631+
rap_partial = datasets(RAPDataset, DateTime(2024,1,15,7), DateTime(2024,1,15,17))
632+
@test length(rap_partial) == 1 # only t12z
633+
@test rap_partial[1].cycle == "t12z"
634+
635+
# Test RAPDataset - crossing midnight
636+
rap_midnight = datasets(RAPDataset, DateTime(2024,1,15,12), DateTime(2024,1,16,12))
637+
@test length(rap_midnight) == 5 # t12z, t18z, t00z, t06z, t12z
638+
@test rap_midnight[1].date == Date(2024,1,15)
639+
@test rap_midnight[1].cycle == "t12z"
640+
@test rap_midnight[end].date == Date(2024,1,16)
641+
@test rap_midnight[end].cycle == "t12z"
642+
643+
# Test GFSDataset - 6-hourly cycles
644+
gfs_dsets = datasets(GFSDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,23))
645+
@test length(gfs_dsets) == 4 # 00, 06, 12, 18
646+
@test all(d -> d isa GFSDataset, gfs_dsets)
647+
@test all(d -> d.date == Date(2024,1,15), gfs_dsets)
648+
@test [d.cycle for d in gfs_dsets] == ["00", "06", "12", "18"]
649+
650+
# Test GFSDataset - multi-day
651+
gfs_multiday = datasets(GFSDataset, DateTime(2024,1,15,0), DateTime(2024,1,16,23))
652+
@test length(gfs_multiday) == 8 # 4 per day × 2 days
653+
@test gfs_multiday[1].date == Date(2024,1,15)
654+
@test gfs_multiday[end].date == Date(2024,1,16)
655+
656+
# Test empty range (no datasets match)
657+
gfs_empty = datasets(GFSDataset, DateTime(2024,1,15,1), DateTime(2024,1,15,5))
658+
@test length(gfs_empty) == 0
659+
660+
# Test exact boundary match
661+
hrrr_exact = datasets(HRRRDataset, DateTime(2024,1,15,12), DateTime(2024,1,15,12))
662+
@test length(hrrr_exact) == 1
663+
@test hrrr_exact[1].cycle == "12"
664+
665+
# Test that default fields are preserved
666+
hrrr_defaults = datasets(HRRRDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,0))
667+
@test hrrr_defaults[1].region == "conus"
668+
@test hrrr_defaults[1].product == "wrfsfc"
669+
@test hrrr_defaults[1].forecast == "f00"
670+
671+
rap_defaults = datasets(RAPDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,0))
672+
@test rap_defaults[1].grid == "awp130"
673+
@test rap_defaults[1].product == "pgrb"
674+
@test rap_defaults[1].forecast == "f00"
675+
676+
gfs_defaults = datasets(GFSDataset, DateTime(2024,1,15,0), DateTime(2024,1,15,0))
677+
@test gfs_defaults[1].resolution == "0p25"
678+
@test gfs_defaults[1].product == "atmos"
679+
@test gfs_defaults[1].forecast == "f000"
680+
end
681+
607682
@testset "Band subsetting" begin
608683
# Test with HRRR dataset
609684
test_date = Date(2024, 1, 15)

0 commit comments

Comments
 (0)