Skip to content

Commit 2c6e287

Browse files
committed
Adding methods for LandSea downloads and retrievals
1 parent fcebf39 commit 2c6e287

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

src/landsea/landsea.jl

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,195 @@ function saveLandSea(
195195

196196
end
197197

198+
function getLandSea(
199+
efol :: AbstractString,
200+
ereg :: ERA5Region = ERA5Region(GeoRegion("GLB"));
201+
returnlsd = true,
202+
FT = Float32
203+
)
204+
205+
lsmfnc = joinpath(efol,"emask-$(ereg.gstr).nc")
206+
207+
if !isfile(lsmfnc)
208+
209+
@info "$(modulelog()) - The ERA5 Land-Sea mask dataset for the \"$(ereg.geoID)\" ERA5Region is not available, extracting from Global ERA5 Land-Sea mask dataset ..."
210+
211+
glbfnc = joinpath(efol,"emask-GLBx$(@sprintf("%.2f",ereg.gres)).nc")
212+
if !isfile(glbfnc)
213+
@info "$(modulelog()) - The Global ERA5 Land-Sea mask dataset for the \"$(ereg.geoID)\" ERA5Region is not available, downloading from the Climate Data Store ..."
214+
downloadLandSea(efol,ereg)
215+
end
216+
217+
gds = NCDataset(glbfnc)
218+
glon = gds["longitude"][:]
219+
glat = gds["latitude"][:]
220+
glsm = gds["lsm"][:] * 1
221+
goro = gds["z"][:] * 1
222+
close(gds)
223+
224+
rinfo = ERA5RegionGrid(ereg,glon,glat)
225+
ilon = rinfo.ilon; nlon = length(rinfo.ilon)
226+
ilat = rinfo.ilat; nlat = length(rinfo.ilat)
227+
rlsm = zeros(nlon,nlat)
228+
roro = zeros(nlon,nlat)
229+
230+
if typeof(rinfo) <: PolyGrid
231+
mask = rinfo.mask; mask[isnan.(mask)] .= 0
232+
else; mask = ones(Int16,nlon,nlat)
233+
end
234+
235+
@info "$(modulelog()) - Extracting regional ERA5 Land-Sea mask for the \"$(ereg.geoID)\" ERA5Region from the Global ERA5 Land-Sea mask dataset ..."
236+
237+
for iglat = 1 : nlat, iglon = 1 : nlon
238+
if isone(mask[iglon,iglat])
239+
rlsm[iglon,iglat] = glsm[ilon[iglon],ilat[iglat]]
240+
roro[iglon,iglat] = goro[ilon[iglon],ilat[iglat]]
241+
else
242+
rlsm[iglon,iglat] = NaN
243+
roro[iglon,iglat] = NaN
244+
end
245+
end
246+
247+
saveLandSea(efol,ereg,rinfo.glon,rinfo.glat,rlsm,roro,Int16.(mask))
248+
249+
end
250+
251+
if returnlsd
252+
253+
lds = NCDataset(lsmfnc)
254+
lon = lds["longitude"][:]
255+
lat = lds["latitude"][:]
256+
lsm = nomissing(lds["lsm"][:], NaN)
257+
oro = nomissing(lds["z"][:], NaN)
258+
msk = lds["mask"][:]
259+
close(lds)
260+
261+
@info "$(modulelog()) - Retrieving the regional ERA5 Land-Sea mask for the \"$(ereg.geoID)\" ERA5Region ..."
262+
263+
return LandSea{FT}(lon,lat,lsm,oro,msk)
264+
265+
else
266+
267+
return nothing
268+
269+
end
270+
271+
end
272+
273+
function downloadLandSea(
274+
efol :: AbstractString,
275+
ereg :: ERA5Region
276+
)
277+
278+
tmpfnc = joinpath(efol,"tmp.nc")
279+
retrieve(
280+
"reanalysis-era5-single-levels-monthly-means", Dict(
281+
"product_type" => "monthly_averaged_reanalysis",
282+
"year" => 2021,
283+
"month" => 12,
284+
"format" => "netcdf",
285+
"variable" => ["geopotential", "land_sea_mask"],
286+
"grid" => [ereg.gres, ereg.gres],
287+
"time" => "00:00"
288+
), tmpfnc
289+
)
290+
291+
tds = NCDataset(tmpfnc)
292+
lon = tds["longitude"][:]; nlon = length(lon)
293+
lat = tds["latitude"][:]; nlat = length(lat)
294+
lsm = tds["lsm"][:,:,1] * 1
295+
oro = tds["z"][:,:,1] * 1
296+
msk = ones(Int16,nlon,nlat)
297+
close(tds)
298+
299+
saveLandSea(
300+
efol,ERA5Region(GeoRegion("GLB"),gres=ereg.gres),
301+
lon,lat,lsm,oro,msk
302+
)
303+
304+
rm(tmpfnc,force=true)
305+
306+
end
307+
308+
function saveLandSea(
309+
efol :: AbstractString,
310+
ereg :: ERA5Region,
311+
lon :: Vector{<:Real},
312+
lat :: Vector{<:Real},
313+
lsm :: Array{<:Real,2},
314+
oro :: Array{<:Real,2},
315+
mask :: Array{Int16,2},
316+
)
317+
318+
fnc = joinpath(efol,"emask-$(ereg.gstr).nc")
319+
if isfile(fnc)
320+
rm(fnc,force=true)
321+
end
322+
323+
ds = NCDataset(fnc,"c",attrib = Dict(
324+
"Conventions" => "CF-1.6",
325+
"history" => "Created on $(Dates.now())"
326+
))
327+
328+
ds.dim["longitude"] = length(lon)
329+
ds.dim["latitude"] = length(lat)
330+
331+
lscale,loffset = ncoffsetscale(lsm)
332+
zscale,zoffset = ncoffsetscale(oro)
333+
334+
nclon = defVar(ds,"longitude",Float32,("longitude",),attrib = Dict(
335+
"units" => "degrees_east",
336+
"long_name" => "longitude",
337+
))
338+
339+
nclat = defVar(ds,"latitude",Float32,("latitude",),attrib = Dict(
340+
"units" => "degrees_north",
341+
"long_name" => "latitude",
342+
))
343+
344+
nclsm = defVar(ds,"lsm",Int16,("longitude","latitude",),attrib = Dict(
345+
"long_name" => "land_sea_mask",
346+
"full_name" => "Land-Sea Mask",
347+
"units" => "0-1",
348+
"scale_factor" => lscale,
349+
"add_offset" => loffset,
350+
"_FillValue" => Int16(-32767),
351+
"missing_value" => Int16(-32767),
352+
))
353+
354+
ncoro = defVar(ds,"z",Int16,("longitude","latitude",),attrib = Dict(
355+
"long_name" => "geopotential",
356+
"full_name" => "Surface Geopotential",
357+
"units" => "m**2 s**-2",
358+
"scale_factor" => zscale,
359+
"add_offset" => zoffset,
360+
"_FillValue" => Int16(-32767),
361+
"missing_value" => Int16(-32767),
362+
))
363+
364+
ncmsk = defVar(ds,"mask",Int16,("longitude","latitude",),attrib = Dict(
365+
"long_name" => "georegion_mask",
366+
"full_name" => "GeoRegion Mask",
367+
"units" => "0-1",
368+
))
369+
370+
nclon[:] = lon
371+
nclat[:] = lat
372+
373+
if iszero(sum(iszero.(mask)))
374+
nclsm[:] = lsm
375+
ncoro[:] = oro
376+
else
377+
nclsm.var[:] = real2int16(lsm,lscale,loffset)
378+
ncoro.var[:] = real2int16(oro,zscale,zoffset)
379+
end
380+
381+
ncmsk[:] = mask
382+
383+
close(ds)
384+
385+
end
386+
198387
function show(io::IO, lsd::LandSea)
199388
nlon = length(lsd.lon)
200389
nlat = length(lsd.lat)

0 commit comments

Comments
 (0)