A collection of diagnostic and interpolation routines for use with output from the Weather Research and Forecasting (WRF-ARW) Model.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

293 lines
9.7 KiB

;*************************************************************************
; Note: several of the functions/procedures are used
; to invoke old [ugly!] function names.
;*************************************************************************
; D. Shea
;
; convert WRF character variable "Times" to udunits
; 2001-06-11_12:00:00
;
; convert WRF character variable "Times" to a coordinate variable "Time"
; opt can be "integer" or "string"
; . integer: opt = 0 : hours since initial time: Times(0,:)
; . opt = 1 : hours since 1901-01-01 00:00:00
; . string: opt = 'any udunits compatible string'
;
undef ("WRF_Times2Udunits_c")
function WRF_Times2Udunits_c(Times:character, opt)
local dimT, rank, year, month, day, hour, minute, sec, units, time
begin
dimT = dimsizes(Times)
rank = dimsizes(dimT)
if (rank.ne.2) then
print("===> WRF_contributed.ncl: WRF_Times2Udunits_c expects 2D array: rank="+rank)
exit
end if
if (.not.(typeof(opt).eq."integer" .or. typeof(opt).eq."string")) then
print("===> WRF_contributed.ncl: opt must be integer or string: type="+typeof(opt))
exit
end if
year = stringtointeger((/Times(:, 0:3) /))
month = stringtointeger((/Times(:, 5:6) /))
day = stringtointeger((/Times(:, 8:9) /))
hour = stringtointeger((/Times(:,11:12)/))
minute = stringtointeger((/Times(:,14:15)/))
sec = stringtointeger((/Times(:,17:18)/))
if (typeof(opt).eq."integer") then
if (opt.eq.0) then
units = "hours since "+year(0)+"-" \
+sprinti("%0.2i",month(0)) +"-" \
+sprinti("%0.2i",day(0)) +" " \
+sprinti("%0.2i",hour(0)) +":" \
+sprinti("%0.2i",minute(0))+":" \
+sprinti("%0.2i",sec(0))
else
units = "hours since 1901-01-01 00:00:00"
end if
else
units = opt ; opt is udunits compatible string
end if
Time = ut_inv_calendar(year,month,day,hour,minute,sec, units, 0)
Time!0 = "Time"
Time@long_name = "Time"
Time@description= "Time"
Time@units = units
Time&Time = Time ; make coordinate variable
return (Time)
end
;*************************************************************************
; D. Shea
; interface to WRF_Times2Udunits_c
undef ("WRF_Times_to_udunits")
function WRF_Times_to_udunits(Times:character, opt)
begin
return( WRF_Times2Udunits_c(Times, 0) ) ; old name
end
;*************************************************************************
; D. Shea
; convert WRF character variable "Times" to
; a coordinate variable of type double
; time(double) = yyyymmddhhmnss
; 2001-06-11_12:00:00 ==> 20010611120000
;
; opt: currently not used [dummy]
;
undef ("WRF_Times2double_c")
function WRF_Times2double_c(Times:character, opt)
local dimT, rank, N, time, i, tmp_c
begin
dimT = dimsizes(Times)
rank = dimsizes(dimT)
if (rank.ne.2) then
print("===> WRF_contributed.ncl: WRF_Times2Udunits_c expects 2D array: rank="+rank)
exit
end if
N = dimT(0)
Time = new( N ,"double") ; preset to "double"
delete(Time@_FillValue) ; coord variables should not have a _FillValue
Time = stringtointeger((/Times(:,0:3)/)) *1d10 + \ ; yyyy
stringtointeger((/Times(:,5:6)/)) *1d8 + \ ; mm
stringtointeger((/Times(:,8:9)/)) *1d6 + \ ; dd
stringtointeger((/Times(:,11:12)/))*1d4 + \ ; hh
stringtointeger((/Times(:,14:15)/))*1d2 + \ ; mn
stringtointeger((/Times(:,17:18)/))*1d0 ; ss
Time!0 = "Time"
Time@long_name = "Time"
Time@description= "Time"
Time@units = "yyyymmddhhmnss"
Time&Time = Time ; make coordinate variable
return (Time)
end
;*************************************************************************
; D. Shea
; interface to WRF_Times2double_c
; more explicit function name
undef ("WRF_Times_to_ymdhms")
function WRF_Times_to_ymdhms(Times:character, opt)
begin
return( WRF_Times2double_c(Times, 0) ) ; old name
end
;*************************************************************************
; D. Shea
; convert WRF character variable "Times" to
; a coordinate variable of type integer
; time(integer)= yyyymmddhh [->ymdh]
; 2001-06-11_12:00:00 ==> 2001061112
;
; Note: mminute and second are not part of the returned time
;
; opt: currently not used [dummy]
;
undef ("WRF_Times_to_ymdh")
function WRF_Times_to_ymdh(Times:character, opt)
local dimT, rank, N, time, i, tmp_c
begin
dimT = dimsizes(Times)
rank = dimsizes(dimT)
if (rank.ne.2) then
print("===> WRF_contributed.ncl: WRF_Times2yyyymmddhh expects 2D array: rank="+rank)
exit
end if
N = dimT(0)
Time = new( N ,"integer")
delete(Time@_FillValue) ; coord variables should not have a _FillValue
Time = stringtointeger((/Times(:,0:3)/)) *1000000 + \ ; yyyy
stringtointeger((/Times(:,5:6)/)) *10000 + \ ; mm
stringtointeger((/Times(:,8:9)/)) *100 + \ ; dd
stringtointeger((/Times(:,11:12)/)) ; hh
Time!0 = "Time"
Time@long_name = "Time"
Time@description= "Time"
Time@units = "yyyymmddhh"
Time&Time = Time ; make coordinate variable
return (Time)
end
;*************************************************************************
; D. Shea
; This is a driver that selects the appropriate
; mapping function based upon the file attribute: MAP_PROJ
; MAP_PROJ=1 [Lambert Conformal]; =2 [Stereographic]; =3 [Mercator]
;
; opt: currently not used [potentail use: time counter for XLAT/XLONG]
;
; Sample usage:
; ncdf = addfile("...", r")
; res = True
; WRF_map_c (ncdf, res, 0)
; res = ...
;
undef("WRF_map_c")
procedure WRF_map_c (f:file, res:logical, opt)
local rank, dimll, nlat, mlon, lat2d, lon2d
begin
if (isatt(f,"MAP_PROJ")) then
if (f@MAP_PROJ.eq.1) then
res@mpProjection = "LambertConformal"
end if
if (f@MAP_PROJ.eq.2) then
res@mpProjection = "Stereographic"
end if
if (f@MAP_PROJ.eq.3) then
res@mpProjection = "Mercator"
end if
else
print ("WRF_mapProj: no MAP_PROJ attribute")
end if
rank = dimsizes(filevardimsizes(f,"XLAT")) ; # of dimensions
if (rank.eq.3) then
lat2d = f->XLAT(0,:,:) ; opt could bt "nt" f->XLAT(opt,:,:)
lon2d = f->XLONG(0,:,:)
else
if (rank.eq.2) then
lat2d = f->XLAT
lon2d = f->XLONG
else
print ("WRF_resLamCon_c: unexpected lat/lon rank: rank="+rank)
exit
end if
end if
lat2d@units = "degrees_north" ; not needed
lon2d@units = "degrees_east"
dimll = dimsizes(lat2d)
nlat = dimll(0)
mlon = dimll(1)
res@mpLimitMode = "Corners"
res@mpLeftCornerLatF = lat2d(0,0)
res@mpLeftCornerLonF = lon2d(0,0)
res@mpRightCornerLatF = lat2d(nlat-1,mlon-1)
res@mpRightCornerLonF = lon2d(nlat-1,mlon-1)
res@mpCenterLonF = f@CEN_LON
res@mpCenterLatF = f@CEN_LAT ; default
if (res@mpProjection.eq."Mercator") then
res@mpCenterLatF = 0.0 ; Cindy Bruyere MMM/WRF 24 Mar 2006
end if
if (res@mpProjection.eq."LambertConformal") then
res@mpLambertParallel1F = f@TRUELAT1
res@mpLambertParallel2F = f@TRUELAT2
if (isatt(f, "STAND_LON") ) then
res@mpLambertMeridianF = f@STAND_LON ; use if present
; CB MMM/WRF 4 Aug 2006
else
if (isatt(f, "CEN_LON") ) then
res@mpLambertMeridianF = f@CEN_LON
else
print("WRF_map_c: STAND_LON and CEN_LON missing")
end if
end if
end if
res@mpFillOn = False ; turn off map fill
res@mpOutlineDrawOrder = "PostDraw" ; draw continental outline last
res@mpOutlineBoundarySets = "GeophysicalAndUSStates" ; state boundaries
res@mpPerimDrawOrder = "PostDraw" ; force map perim
; commented 5/17/2007
;;res@tfDoNDCOverlay = True ; True for 'native' grid
; some WRF are not native
res@gsnAddCyclic = False ; data are not cyclic
end
;*************************************************************************
; D. Shea
; interface for backward compatibility
undef("WRF_resLamCon_c")
procedure WRF_resLamCon_c (f:file, res:logical, opt)
begin
WRF_map_c (f, res, opt)
end
;*************************************************************************
; D. Shea
; interface for newly named procedure
undef("wrf_mapres_c")
procedure wrf_mapres_c(f:file, res:logical, opt)
begin
WRF_map_c (f, res, opt)
end
;*************************************************************************
; D. Shea
; single interface to convert WRF character variable "Times"
; to user specified numeric values
;
; M. Haley
; At some point we decided to rename this from WRF_Times to wrf_times_c
; Also added error check for opt.
;
undef ("wrf_times_c")
function wrf_times_c(Times:character, opt:integer)
begin
if (opt.ge.0 .and. opt.le.1) then
return(WRF_Times2Udunits_c(Times, opt) )
end if
if (opt.eq.2) then
return(WRF_Times2double_c(Times, opt) )
end if
if (opt.eq.3) then
return(WRF_Times_to_ymdh(Times, opt) )
end if
end