forked from 3rdparty/wrf-python
				
			
			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.
		
		
		
		
		
			
		
			
				
					
					
						
							5454 lines
						
					
					
						
							168 KiB
						
					
					
				
			
		
		
	
	
							5454 lines
						
					
					
						
							168 KiB
						
					
					
				;-------------------------------------------------------------------------------- | 
						|
; function wrf_user_set_xy( var:numeric, xp:numeric, yp:numeric, x1:numeric, \ | 
						|
;                           y1:numeric,angle:numeric ,opts ) | 
						|
; function wrf_user_intrp3d( var3d:numeric, z:numeric, plot_type:string, \ | 
						|
;                            loc_param:numeric, angle:numeric, opts:logical ) | 
						|
; function wrf_user_intrp2d( var2d:numeric, \ | 
						|
;                            loc_param:numeric, angle:numeric, opts:logical ) | 
						|
; function wrf_user_vert_interp(file_handle,field:float,\ | 
						|
;                               vert_coordinate[1]:string, \ | 
						|
        ;                       interp_levels[*]:numeric,opts[1]:logical) | 
						|
; function wrf_user_getvar( file_handle, variable:string, time:integer ) | 
						|
; function wrf_user_list_times( file_handle ) | 
						|
; function wrf_user_ll_to_ij( nc_file:file, longitude:numeric, latitude:numeric, \ | 
						|
;                             opts:logical ) | 
						|
; function wrf_user_ij_to_ll( nc_file:file, i:numeric, j:numeric \ | 
						|
;                             opts:logical ) | 
						|
; function wrf_contour(nc_file:file,wks[1]: graphic, data[*][*]:numeric, \ | 
						|
;                      opt_args[1]:logical) | 
						|
; function wrf_vector(nc_file:file,wks[1]: graphic, data_u[*][*]:numeric, \ | 
						|
;                     data_v[*][*]:numeric, opt_args[1]:logical) | 
						|
; function wrf_map_resources(in_file[1]:file,opt_args[1]:logical)    | 
						|
; function wrf_map(wks[1]:graphic,in_file[1]:file,opt_args[1]:logical)    | 
						|
; function wrf_map_overlays(in_file[1]:file,wks:graphic,base[1]:graphic, \ | 
						|
;                           plots[*]:graphic,opt_arg[1]:logical,mp_arg[1]:logical) | 
						|
; function wrf_overlays(in_file[1]:file,wks:graphic, plots[*]:graphic, \ | 
						|
;                       opt_arg[1]:logical) | 
						|
; function wrf_user_unstagger( varin:numeric, unstagDim:string ) | 
						|
; | 
						|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 
						|
; Thse functions are still experimental | 
						|
; function wrf_wps_dom(wks[1]:graphic,mpres[1]:logical,lnres[1]:logical,txres[1]:logical)    | 
						|
; function wrf_contour_ps(nc_file:file,wks[1]: graphic, data[*][*]:numeric, \ | 
						|
;                         opt_args[1]:logical) | 
						|
; function wrf_vector_ps(nc_file:file,wks[1]: graphic, \ | 
						|
;                        data_u[*][*]:numeric, data_v[*][*]:numeric, \ | 
						|
;                        opt_args[1]:logical) | 
						|
; | 
						|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 
						|
; These functions/procedures are obsolete as of version 5.0.1 of NCL. | 
						|
; Do not use them.  | 
						|
; Use wrf_overlays instead of wrf_overlay | 
						|
; Use wrf_map_overlays instead of wrf_map_overlay | 
						|
; Use wrf_user_ll_to_ij instead of wrf_user_latlon_to_ij | 
						|
; | 
						|
; function wrf_map_zoom(wks[1]:graphic,in_file[1]:file,opt_args[1]:logical, \ | 
						|
;                       y1:integer,y2:integer,x1:integer,x2:integer) | 
						|
; procedure wrf_map_overlay(wks:graphic,base[1]:graphic, \ | 
						|
;                           plots[*]:graphic, \ | 
						|
;                           opt_arg[1]:logical) | 
						|
; procedure wrf_overlay(wks:graphic, plots[*]:graphic, \ | 
						|
;                           opt_arg[1]:logical) | 
						|
; function wrf_user_latlon_to_ij( nc_file:file, latitude:numeric,  | 
						|
;                                 longitude:numeric ) | 
						|
; | 
						|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 
						|
; | 
						|
; function add_white_space(str:string,maxlen:integer) | 
						|
; procedure print_opts(opts_name,opts,debug) | 
						|
; procedure print_header(icount:integer,debug) | 
						|
; | 
						|
;-------------------------------------------------------------------------------- | 
						|
  | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("wrf_user_set_xy") | 
						|
function wrf_user_set_xy( var:numeric, xp:numeric, yp:numeric, x1:numeric, \ | 
						|
                          y1:numeric, angle:numeric, opts ) | 
						|
 | 
						|
;  mass coordinate version of ncl user routines | 
						|
 | 
						|
local dims,x,y,slope,intercept,distance,dx,dy,dxy,npts,xy | 
						|
 | 
						|
begin | 
						|
 | 
						|
; find intersection of line and domain boundaries | 
						|
 | 
						|
  dims = dimsizes(var) | 
						|
 | 
						|
  if (.not. opts) then        ; We have a pivot point and location and  | 
						|
			      ; need to calculate the start and end points of  | 
						|
			      ; the cross section | 
						|
 | 
						|
     if ((angle .gt. 315.) .or. (angle .lt. 45.) .or. \ | 
						|
         ((angle .gt. 135.) .and. (angle .lt. 225.)) )  then | 
						|
 | 
						|
;  x = y*slope + intercept | 
						|
 | 
						|
          slope = -(360.-angle)/45. | 
						|
          if( angle .lt. 45. ) then | 
						|
            slope = angle/45. | 
						|
          end if | 
						|
          if( angle .gt. 135.) then | 
						|
            slope = (angle-180.)/45. | 
						|
          end if | 
						|
          intercept = xp - yp*slope | 
						|
 | 
						|
; find intersections with domain boundaries | 
						|
 | 
						|
          y0 = 0. | 
						|
          x0 = y0*slope + intercept | 
						|
    | 
						|
          if( x0 .lt. 0.) then  ; intersect outside of left boundary | 
						|
            x0 = 0. | 
						|
            y0 =  (x0 - intercept)/slope | 
						|
          end if | 
						|
          if( x0 .gt. dims(2)-1) then  ; intersect outside of right boundary | 
						|
            x0 = dims(2)-1 | 
						|
            y0 =  (x0 - intercept)/slope | 
						|
          end if | 
						|
    | 
						|
          y1 = dims(1)-1.  ;  need to make sure this will be a float? | 
						|
          x1 = y1*slope + intercept | 
						|
    | 
						|
          if( x1 .lt. 0.) then  ; intersect outside of left boundary | 
						|
            x1 = 0. | 
						|
            y1 =  (x1 - intercept)/slope | 
						|
          end if | 
						|
          if( x1 .gt. dims(2)-1) then  ; intersect outside of right boundary | 
						|
            x1 = dims(2)-1 | 
						|
            y1 =  (x1 - intercept)/slope | 
						|
          end if | 
						|
 | 
						|
     else | 
						|
 | 
						|
;  y = x*slope + intercept | 
						|
 | 
						|
          slope = (90.-angle)/45. | 
						|
          if( angle .gt. 225. ) then | 
						|
            slope = (270.-angle)/45. | 
						|
          end if | 
						|
          intercept = yp - xp*slope | 
						|
 | 
						|
; find intersections with domain boundaries | 
						|
 | 
						|
          x0 = 0. | 
						|
          y0 = x0*slope + intercept | 
						|
    | 
						|
          if( y0 .lt. 0.) then  ; intersect outside of bottom boundary | 
						|
            y0 = 0. | 
						|
            x0 =  (y0 - intercept)/slope | 
						|
          end if | 
						|
          if( y0 .gt. dims(1)-1) then  ; intersect outside of top boundary | 
						|
            y0 = dims(1)-1 | 
						|
            x0 =  (y0 - intercept)/slope | 
						|
          end if | 
						|
 | 
						|
          x1 = dims(2)-1.  ;  need to make sure this will be a float? | 
						|
          y1 = x1*slope + intercept | 
						|
    | 
						|
          if( y1 .lt. 0.) then  ; intersect outside of bottom boundary | 
						|
            y1 = 0. | 
						|
            x1 =  (y1 - intercept)/slope | 
						|
          end if | 
						|
          if( y1 .gt. dims(1)-1) then  ; intersect outside of top boundary | 
						|
            y1 = dims(1)-1 | 
						|
            x1 =  (y1 - intercept)/slope | 
						|
          end if | 
						|
    | 
						|
     end if  ; we have beginning and ending points | 
						|
 | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if (opts) then   	; We have a specified start and end point | 
						|
    x0 = xp | 
						|
    y0 = yp | 
						|
    if ( x1 .gt. dims(2)-1 ) then  | 
						|
      x1 = dims(2) | 
						|
    end if | 
						|
    if ( y1 .gt. dims(1)-1 ) then  | 
						|
      y1 = dims(1) | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  dx = x1 - x0 | 
						|
  dy = y1 - y0 | 
						|
  distance = (dx*dx + dy*dy)^0.5 | 
						|
  npts = tointeger(distance) | 
						|
  dxy = new(1,typeof(distance)) | 
						|
  dxy = distance/npts | 
						|
 | 
						|
  xy = new((/ npts, 2 /),typeof(x1)) | 
						|
 | 
						|
  dx = dx/npts | 
						|
  dy = dy/npts | 
						|
 | 
						|
  do i=0,npts-1 | 
						|
    xy(i,0) = x0 + i*dx | 
						|
    xy(i,1) = y0 + i*dy | 
						|
  end do | 
						|
 | 
						|
; print(xy) | 
						|
  return(xy) | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
  | 
						|
undef("wrf_user_intrp3d") | 
						|
function wrf_user_intrp3d( var3d:numeric, z_in:numeric, \ | 
						|
                           plot_type:string, \ | 
						|
                           loc_param:numeric, angle:numeric, opts:logical ) | 
						|
 | 
						|
; var3d      - 3d field to interpolate (all input fields must be unstaggered) | 
						|
; z_in       - interpolate to this field (either p/z) | 
						|
; plot_type  - interpolate horizontally "h", or vertically "v" | 
						|
; loc_param  - level(s) for horizontal plots (eg. 500hPa ; 3000m - scalar),  | 
						|
;              plane for vertical plots (2 values representing an xy point  | 
						|
;              on the model domain through which the vertical plane will pass | 
						|
;              OR 4 values specifying start and end values | 
						|
; angle      - 0.0 for horizontal plots, and  | 
						|
;              an angle for vertical plots - 90 represent a WE cross section | 
						|
; opts         Used IF opts is TRUE, else use loc_param and angle to determine crosssection | 
						|
 | 
						|
begin | 
						|
 | 
						|
  if(plot_type .eq. "h" ) then   ;  horizontal cross section needed | 
						|
 | 
						|
     dimL = dimsizes(loc_param) | 
						|
 | 
						|
     dims = dimsizes(var3d) | 
						|
     nd = dimsizes(dims) | 
						|
 | 
						|
     dimX = dims(nd-1) | 
						|
     dimY = dims(nd-2) | 
						|
     dimZ = dims(nd-3) | 
						|
     dim4 = 1 | 
						|
     dim5 = 1 | 
						|
     if ( nd .eq. 4 ) then | 
						|
       dim4 = dims(nd-4) | 
						|
     end if | 
						|
     if ( nd .eq. 5 ) then | 
						|
       dim4 = dims(nd-4) | 
						|
       dim5 = dims(nd-5) | 
						|
     end if | 
						|
 | 
						|
     var3  = new ( (/ dim5, dim4, dimZ, dimY, dimX /) , typeof(var3d) ) | 
						|
     z     = new ( (/ dim5, dim4, dimZ, dimY, dimX /) , typeof(var3d) ) | 
						|
     var2d = new ( (/ dim5, dim4, dimL, dimY, dimX /) , typeof(var3d) ) | 
						|
 | 
						|
     if ( nd .eq. 5 ) then | 
						|
       var3 = var3d | 
						|
          z =  z_in | 
						|
     end if | 
						|
     if ( nd .eq. 4 ) then | 
						|
       var3(0,:,:,:,:) = var3d(:,:,:,:) | 
						|
          z(0,:,:,:,:) =  z_in(:,:,:,:) | 
						|
     end if | 
						|
     if ( nd .eq. 3 ) then | 
						|
       var3(0,0,:,:,:) = var3d(:,:,:) | 
						|
          z(0,0,:,:,:) =  z_in(:,:,:) | 
						|
     end if | 
						|
 | 
						|
 | 
						|
     if ( z(0,0,dimZ-1,0,0) .lt. z(0,0,dimZ-2,0,0) ) then | 
						|
       ; We must be interpolating to pressure | 
						|
       ; This routine needs input field and level in hPa - lets make sure of this | 
						|
       if ( max(z) .gt. 2000. ) then | 
						|
         ; looks like we have Pa as input - make this hPa | 
						|
         z = z * 0.01 | 
						|
       end if | 
						|
       if ( loc_param(0) .gt. 2000. ) then | 
						|
         ; looks like the input was specified in Pa - change this | 
						|
         loc_param = loc_param * 0.01 | 
						|
       end if | 
						|
     end if | 
						|
 | 
						|
     do il = 0,dimL-1 | 
						|
       var = wrf_interp_3d_z(var3,z,loc_param(il)) | 
						|
       var2d(:,:,il,:,:) = var(:,:,:,:) | 
						|
     end do | 
						|
 | 
						|
     copy_VarAtts(var3d,var3) | 
						|
     if(isatt(var3,"description")) then | 
						|
       delete_VarAtts(var3,(/"description"/)) | 
						|
     end if | 
						|
     if(isatt(var3,"units")) then | 
						|
       delete_VarAtts(var3,(/"units"/)) | 
						|
     end if | 
						|
     if(isatt(var3,"MemoryOrder")) then | 
						|
       delete_VarAtts(var3,(/"MemoryOrder"/)) | 
						|
     end if | 
						|
     if(isatt(var3,"_FillValue")) then | 
						|
       delete_VarAtts(var3,(/"_FillValue"/)) | 
						|
     end if | 
						|
     copy_VarAtts(var3,var2d) | 
						|
 | 
						|
     nn = nd-2 | 
						|
     var2d!nn = "plevs" | 
						|
 | 
						|
     if ( dimL .gt. 1 ) then | 
						|
       if ( nd .eq. 5 ) then | 
						|
         return( var2d ) | 
						|
       end if | 
						|
       if ( nd .eq. 4 ) then | 
						|
         return( var2d(0,:,:,:,:) ) | 
						|
       end if | 
						|
       if ( nd .eq. 3 ) then | 
						|
         return( var2d(0,0,:,:,:) ) | 
						|
       end if | 
						|
     else | 
						|
       if ( z(0,0,dimZ-1,0,0) .lt. z(0,0,dimZ-2,0,0) ) then | 
						|
          var2d@PlotLevelID = loc_param + " hPa" | 
						|
       else | 
						|
          var2d@PlotLevelID = .001*loc_param + " km" | 
						|
       end if | 
						|
       if ( nd .eq. 5 ) then | 
						|
         return( var2d(:,:,0,:,:) ) | 
						|
       end if | 
						|
       if ( nd .eq. 4 ) then | 
						|
         return( var2d(0,:,0,:,:) ) | 
						|
       end if | 
						|
       if ( nd .eq. 3 ) then | 
						|
         return( var2d(0,0,0,:,:) ) | 
						|
       end if | 
						|
     end if | 
						|
 | 
						|
 | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
  if(plot_type .eq. "v" ) then   ;  vertical cross section needed | 
						|
 | 
						|
     dims = dimsizes(var3d) | 
						|
     nd = dimsizes(dims) | 
						|
 | 
						|
     dimX = dims(nd-1) | 
						|
     dimY = dims(nd-2) | 
						|
     dimZ = dims(nd-3) | 
						|
 | 
						|
     if ( nd .eq. 4 ) then | 
						|
       if ( z_in(0,dimZ-1,0,0) .lt. z_in(0,dimZ-2,0,0) ) then | 
						|
         ; We must be interpolating to pressure | 
						|
           ; This routine needs input field and level in hPa - lets make sure of this | 
						|
         if ( max(z_in) .gt. 2000. ) then | 
						|
           ; looks like we have Pa as input - make this hPa | 
						|
           z_in = z_in * 0.01 | 
						|
         end if | 
						|
       end if | 
						|
       z = z_in(0,:,:,:) | 
						|
     else | 
						|
       if ( z_in(dimZ-1,0,0) .lt. z_in(dimZ-2,0,0) ) then | 
						|
         ; We must be interpolating to pressure | 
						|
           ; This routine needs input field and level in hPa - lets make sure of this | 
						|
         if ( z_in(0,0,0) .gt. 2000. ) then | 
						|
           ; looks like we have Pa as input - make this hPa | 
						|
           z_in = z_in * 0.01 | 
						|
         end if | 
						|
       end if | 
						|
       z = z_in | 
						|
     end if | 
						|
 | 
						|
        | 
						|
; set vertical cross section | 
						|
     if (opts) then | 
						|
       xy = wrf_user_set_xy( z, loc_param(0)-1, loc_param(1)-1, \    ; the -1 is for NCL dimensions | 
						|
                                loc_param(2)-1, loc_param(3)-1, \ | 
						|
                                angle, opts ) | 
						|
     else | 
						|
       xy = wrf_user_set_xy( z, loc_param(0), loc_param(1), \ | 
						|
                                0.0, 0.0, angle, opts ) | 
						|
     end if | 
						|
     xp = dimsizes(xy) | 
						|
   | 
						|
   | 
						|
; first we interp z | 
						|
     var2dz   = wrf_interp_2d_xy( z, xy) | 
						|
 | 
						|
;  interp to constant z grid | 
						|
     if(var2dz(0,0) .gt. var2dz(1,0) ) then  ; monotonically decreasing coordinate | 
						|
        z_max = floor(max(z)/10)*10     ; bottom value | 
						|
        z_min = ceil(min(z)/10)*10      ; top value | 
						|
        dz = 10 | 
						|
        nlevels = tointeger( (z_max-z_min)/dz) | 
						|
        z_var2d = new( (/nlevels/), typeof(z)) | 
						|
        z_var2d(0) = z_max | 
						|
        dz = -dz | 
						|
     else | 
						|
        z_max = max(z) | 
						|
        z_min = 0. | 
						|
        dz = 0.01 * z_max | 
						|
        nlevels = tointeger( z_max/dz ) | 
						|
        z_var2d = new( (/nlevels/), typeof(z)) | 
						|
        z_var2d(0) = z_min | 
						|
     end if | 
						|
   | 
						|
     do i=1, nlevels-1 | 
						|
        z_var2d(i) = z_var2d(0)+i*dz | 
						|
     end do | 
						|
   | 
						|
 | 
						|
; interp the variable | 
						|
     if ( dimsizes(dims) .eq. 4 ) then | 
						|
       var2d = new( (/dims(0), nlevels, xp(0)/), typeof(var2dz)) | 
						|
       do it = 0,dims(0)-1 | 
						|
         var2dtmp = wrf_interp_2d_xy( var3d(it,:,:,:), xy) | 
						|
         do i=0,xp(0)-1 | 
						|
            var2d(it,:,i) = wrf_interp_1d( var2dtmp(:,i), var2dz(:,i), z_var2d) | 
						|
         end do | 
						|
       end do | 
						|
       var2d!0 = var3d!0 | 
						|
       var2d!1 = "Vertical" | 
						|
       var2d!2 = "Horizontal" | 
						|
     else | 
						|
       var2d = new( (/nlevels, xp(0)/), typeof(var2dz)) | 
						|
       var2dtmp = wrf_interp_2d_xy( var3d, xy) | 
						|
       do i=0,xp(0)-1 | 
						|
          var2d(:,i) = wrf_interp_1d( var2dtmp(:,i), var2dz(:,i), z_var2d) | 
						|
       end do | 
						|
       var2d!0 = "Vertical" | 
						|
       var2d!1 = "Horizontal" | 
						|
     end if | 
						|
 | 
						|
 | 
						|
 | 
						|
     st_x = tointeger(xy(0,0)) + 1 | 
						|
     st_y = tointeger(xy(0,1)) + 1 | 
						|
     ed_x = tointeger(xy(xp(0)-1,0)) + 1 | 
						|
     ed_y = tointeger(xy(xp(0)-1,1)) + 1 | 
						|
     if (opts) then | 
						|
       var2d@Orientation = "Cross-Section: (" + \ | 
						|
                            st_x + "," + st_y + ") to (" + \ | 
						|
                            ed_x + "," + ed_y + ")" | 
						|
     else | 
						|
       var2d@Orientation = "Cross-Section: (" + \ | 
						|
                            st_x + "," + st_y + ") to (" + \ | 
						|
                            ed_x + "," + ed_y + ") ; center=(" + \ | 
						|
                            loc_param(0) + "," + loc_param(1) + \ | 
						|
                            ") ; angle=" + angle | 
						|
     end if | 
						|
 | 
						|
     return(var2d) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
  | 
						|
undef("wrf_user_intrp2d") | 
						|
function wrf_user_intrp2d( var2d:numeric, \ | 
						|
                           loc_param:numeric, angle:numeric, opts:logical ) | 
						|
 | 
						|
; var2d      - 2d field to interpolate  | 
						|
; loc_param  - plane for vertical plots (2 values representing an xy point  | 
						|
;              on the model domain through which the vertical plane will pass | 
						|
;              OR 4 values specifying start and end values | 
						|
; angle      - 0.0 for horizontal plots, and  | 
						|
;              an angle for vertical plots - 90 represent a WE cross section | 
						|
; opts         Used IF opts is TRUE, else use loc_param and angle to determine crosssection | 
						|
 | 
						|
begin | 
						|
 | 
						|
     dims = dimsizes(var2d) | 
						|
     nd = dimsizes(dims) | 
						|
     dimX = dims(nd-1) | 
						|
     dimY = dims(nd-2) | 
						|
     dimT = 1 | 
						|
     if ( nd .eq. 3 ) then | 
						|
       dimT = dims(nd-3) | 
						|
     end if | 
						|
     var2dtmp = new( (/ 1, dimY, dimX /), typeof(var2d) ) | 
						|
      | 
						|
 | 
						|
; set vertical cross section | 
						|
     if ( nd .eq. 3 ) then | 
						|
       var2dtmp(0,:,:) = var2d(0,:,:) | 
						|
     else | 
						|
       var2dtmp(0,:,:) = var2d(:,:) | 
						|
     end if | 
						|
     if (opts) then | 
						|
       xy = wrf_user_set_xy( var2dtmp, \ | 
						|
                             loc_param(0)-1, loc_param(1)-1, \    ; the -1 is for NCL dimensions | 
						|
                             loc_param(2)-1, loc_param(3)-1, \ | 
						|
                             angle, opts ) | 
						|
     else | 
						|
       xy = wrf_user_set_xy( var2dtmp, \ | 
						|
                             loc_param(0), loc_param(1), \ | 
						|
                             0.0, 0.0, angle, opts ) | 
						|
     end if | 
						|
     xp = dimsizes(xy) | 
						|
 | 
						|
     var2dout = new( (/ dimT, xp(0) /), typeof(var2d) ) | 
						|
 | 
						|
     var1dtmp = wrf_interp_2d_xy( var2dtmp, xy ) | 
						|
     var2dout(0,:) = var1dtmp(0,:) | 
						|
     if ( dimT .eq. 1 ) then | 
						|
       var2dout!1 = "Horizontal" | 
						|
       return ( var2dout(0,:) ) | 
						|
     end if | 
						|
 | 
						|
     do it = 1,dimT-1 | 
						|
       var2dtmp(0,:,:) = var2d(it,:,:) | 
						|
       var1dtmp = wrf_interp_2d_xy( var2dtmp, xy ) | 
						|
       var2dout(it,:) = var1dtmp(0,:) | 
						|
     end do | 
						|
     var2dout!0 = "Time" | 
						|
     var2dout!1 = "Horizontal" | 
						|
     return(var2dout) | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_user_unstagger") | 
						|
function wrf_user_unstagger( varin:numeric, unstagDim:string ) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  dims = dimsizes(varin) | 
						|
  nd = dimsizes(dims) | 
						|
 | 
						|
  if ( unstagDim .eq. "X" .or. unstagDim .eq. "U" ) then | 
						|
    dimU = dims(nd-1) | 
						|
    if ( nd .eq. 5 ) then | 
						|
      varout = 0.5*(varin(:,:,:,:,:dimU-2) + varin(:,:,:,:,1:dimU-1)) | 
						|
    end if | 
						|
    if ( nd .eq. 4 ) then | 
						|
      varout = 0.5*(varin(:,:,:,:dimU-2) + varin(:,:,:,1:dimU-1)) | 
						|
    end if | 
						|
    if ( nd .eq. 3 ) then | 
						|
      varout = 0.5*(varin(:,:,:dimU-2) + varin(:,:,1:dimU-1)) | 
						|
    end if | 
						|
    if ( nd .eq. 2 ) then | 
						|
      varout = 0.5*(varin(:,:dimU-2) + varin(:,1:dimU-1)) | 
						|
    end if | 
						|
    do i = 0,nd-2 | 
						|
      varout!i = varin!i | 
						|
    end do | 
						|
    i = nd-1 | 
						|
    varout!i = "west_east" | 
						|
    copy_VarAtts(varin,varout) | 
						|
    varout@coordinates = "XLONG XLAT" | 
						|
    varout@stagger = " " | 
						|
  end if | 
						|
 | 
						|
  if ( unstagDim .eq. "Y" .or. unstagDim .eq. "V" ) then | 
						|
    dimV = dims(nd-2) | 
						|
    if ( nd .eq. 5 ) then | 
						|
      varout = 0.5*(varin(:,:,:,:dimV-2,:)+varin(:,:,:,1:dimV-1,:)) | 
						|
    end if | 
						|
    if ( nd .eq. 4 ) then | 
						|
      varout = 0.5*(varin(:,:,:dimV-2,:)+varin(:,:,1:dimV-1,:)) | 
						|
    end if | 
						|
    if ( nd .eq. 3 ) then | 
						|
      varout = 0.5*(varin(:,:dimV-2,:)+varin(:,1:dimV-1,:)) | 
						|
    end if | 
						|
    if ( nd .eq. 2 ) then | 
						|
      varout = 0.5*(varin(:dimV-2,:)+varin(1:dimV-1,:)) | 
						|
    end if | 
						|
    do i = 0,nd-1 | 
						|
      varout!i = varin!i | 
						|
    end do | 
						|
    i = nd-2 | 
						|
    varout!i = "south_north" | 
						|
    copy_VarAtts(varin,varout) | 
						|
    varout@coordinates = "XLONG XLAT" | 
						|
    varout@stagger = " " | 
						|
  end if | 
						|
 | 
						|
  if ( unstagDim .eq. "Z" ) then | 
						|
    dimW = dims(nd-3) | 
						|
    if ( nd .eq. 5 ) then | 
						|
      varout = 0.5*(varin(:,:,0:dimW-2,:,:)+varin(:,:,1:dimW-1,:,:)) | 
						|
    end if | 
						|
    if ( nd .eq. 4 ) then | 
						|
      varout = 0.5*(varin(:,0:dimW-2,:,:)+varin(:,1:dimW-1,:,:)) | 
						|
    end if | 
						|
    if ( nd .eq. 3 ) then | 
						|
      varout = 0.5*(varin(0:dimW-2,:,:)+varin(1:dimW-1,:,:)) | 
						|
    end if | 
						|
    do i = 0,nd-1 | 
						|
      varout!i = varin!i | 
						|
    end do | 
						|
    i = nd-3 | 
						|
    varout!i = "bottom_top"  | 
						|
    copy_VarAtts(varin,varout) | 
						|
    varout@coordinates = "XLONG XLAT" | 
						|
    varout@stagger = " " | 
						|
  end if | 
						|
 | 
						|
  if( any( unstagDim .eq. (/"X","U","Y","V","Z"/) ) ) then | 
						|
    return(varout)  | 
						|
  else | 
						|
    print("NOTE: No unstaggering required, as the input field is already on mass points.") | 
						|
    return(varin) | 
						|
  end if | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
; This function was modified in May 2011 to allow a list of files. | 
						|
; | 
						|
undef("wrf_user_getvar") | 
						|
function wrf_user_getvar( file_handle, varin[*]:string, time_in:integer ) | 
						|
local variable, time, var, u, v, u_in, v_in, pii, radians_per_degree, \ | 
						|
dims, nd, latitude, longitude, rank | 
						|
begin | 
						|
 | 
						|
;---As of NCL V6.0.0, wrf_user_getvar can now handle a file or a list of files. | 
						|
  if(typeof(file_handle).eq."file") then | 
						|
    ISFILE = True | 
						|
    nc_file = file_handle | 
						|
  else if(typeof(file_handle).eq."list") then | 
						|
    ISFILE = False | 
						|
    nc_file = file_handle[0] | 
						|
  else | 
						|
    print("wrf_user_getvar: error: the first argument must be a file or a list of files opened with addfile or addfiles") | 
						|
    return | 
						|
  end if | 
						|
  end if | 
						|
 | 
						|
  variable = varin(0) | 
						|
  time = time_in(0) | 
						|
 | 
						|
  if( (variable .eq. "uvmet") .or. (variable .eq. "uvmet10") ) then | 
						|
       ;; Calculate winds rotated to earth coord.  | 
						|
 | 
						|
       pii = 3.14159265 | 
						|
       radians_per_degree = pii/180. | 
						|
 | 
						|
       if( (variable .eq. "uvmet") )  then | 
						|
         getU = "U"  | 
						|
         getV = "V"  | 
						|
         if(.not. isfilevar(nc_file,"U")) then | 
						|
           if(isfilevar(nc_file,"UU")) then | 
						|
             getU = "UU" | 
						|
             getV = "VV" | 
						|
           end if | 
						|
         end if | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             u_in = nc_file->$getU$ | 
						|
             v_in = nc_file->$getV$ | 
						|
           else | 
						|
             u_in = file_handle[:]->$getU$ | 
						|
             v_in = file_handle[:]->$getV$ | 
						|
           end if | 
						|
           u = wrf_user_unstagger(u_in,u_in@stagger) | 
						|
           v = wrf_user_unstagger(v_in,v_in@stagger) | 
						|
       else | 
						|
           if(ISFILE) then | 
						|
             u_in   = nc_file->$getU$(time_in,:,:,:) | 
						|
             v_in   = nc_file->$getV$(time_in,:,:,:) | 
						|
           else | 
						|
             u_in   = file_handle[:]->$getU$(time_in,:,:,:) | 
						|
             v_in   = file_handle[:]->$getV$(time_in,:,:,:) | 
						|
           end if | 
						|
           u = wrf_user_unstagger(u_in,u_in@stagger) | 
						|
           v = wrf_user_unstagger(v_in,v_in@stagger) | 
						|
         end if | 
						|
       end if   | 
						|
 | 
						|
       if( (variable .eq. "uvmet10") )  then | 
						|
         if(isfilevar(nc_file,"U10")) then | 
						|
           if ( time .eq. -1 ) then | 
						|
             if(ISFILE) then | 
						|
               u_in   = nc_file->U10 | 
						|
               v_in   = nc_file->V10 | 
						|
             else | 
						|
               u_in   = file_handle[:]->U10 | 
						|
               v_in   = file_handle[:]->V10 | 
						|
             end if | 
						|
             u = wrf_user_unstagger(u_in,u_in@stagger) | 
						|
             v = wrf_user_unstagger(v_in,v_in@stagger) | 
						|
           else | 
						|
             if(ISFILE) then | 
						|
               u_in  = nc_file->U10(time_in,:,:) | 
						|
               v_in  = nc_file->V10(time_in,:,:) | 
						|
             else | 
						|
               u_in  = file_handle[:]->U10(time_in,:,:) | 
						|
               v_in  = file_handle[:]->V10(time_in,:,:) | 
						|
             end if | 
						|
             u = wrf_user_unstagger(u_in,u_in@stagger) | 
						|
             v = wrf_user_unstagger(v_in,v_in@stagger) | 
						|
           end if | 
						|
         else  ; may be a met file, so get lowest level of UU and VV | 
						|
           if(isfilevar(nc_file,"UU")) then | 
						|
             print("wrf_user_getvar: Assume this is a met_em file - getting lowest level from UU and VV fields") | 
						|
             if ( time .eq. -1 ) then | 
						|
               if(ISFILE) then | 
						|
                 u_in  = nc_file->UU(:,0,:,:) | 
						|
                 v_in  = nc_file->VV(:,0,:,:) | 
						|
               else | 
						|
                 u_in  = file_handle[:]->UU(:,0,:,:) | 
						|
                 v_in  = file_handle[:]->VV(:,0,:,:) | 
						|
               end if | 
						|
               u = wrf_user_unstagger(u_in,u_in@stagger) | 
						|
               v = wrf_user_unstagger(v_in,v_in@stagger) | 
						|
             else | 
						|
               if(ISFILE) then | 
						|
                 u_in  = nc_file->UU(time_in,0,:,:) | 
						|
                 v_in  = nc_file->VV(time_in,0,:,:) | 
						|
               else | 
						|
                 u_in  = file_handle[:]->UU(time_in,0,:,:) | 
						|
                 v_in  = file_handle[:]->VV(time_in,0,:,:) | 
						|
               end if | 
						|
               u = wrf_user_unstagger(u_in,u_in@stagger) | 
						|
               v = wrf_user_unstagger(v_in,v_in@stagger) | 
						|
             end if | 
						|
           end if | 
						|
         end if   | 
						|
       end if   | 
						|
 | 
						|
 | 
						|
       map_projection = nc_file@MAP_PROJ | 
						|
 | 
						|
 | 
						|
       if( any(map_projection.eq.(/0,3,6/)) ) then  ; no rotation needed | 
						|
         dims = dimsizes(u) | 
						|
         nd = dimsizes(dims) | 
						|
         if ( nd .eq. 5 ) then | 
						|
           uvmet = new( (/ 2, dims(0), dims(1), dims(2), dims(3), dims(4) /), typeof(u)) | 
						|
           uvmet(0,:,:,:,:,:) = u(:,:,:,:,:)  | 
						|
           uvmet(1,:,:,:,:,:) = v(:,:,:,:,:) | 
						|
         end if | 
						|
         if ( nd .eq. 4 ) then | 
						|
           uvmet = new( (/ 2, dims(0), dims(1), dims(2), dims(3) /), typeof(u)) | 
						|
           uvmet(0,:,:,:,:) = u(:,:,:,:)  | 
						|
           uvmet(1,:,:,:,:) = v(:,:,:,:) | 
						|
         end if | 
						|
         if ( nd .eq. 3 ) then | 
						|
           uvmet = new( (/ 2, dims(0), dims(1), dims(2) /), typeof(u)) | 
						|
           uvmet(0,:,:,:) = u(:,:,:)  | 
						|
           uvmet(1,:,:,:) = v(:,:,:) | 
						|
         end if | 
						|
         if ( nd .eq. 2 ) then | 
						|
           uvmet = new( (/ 2, dims(0), dims(1) /), typeof(u)) | 
						|
           uvmet(0,:,:) = u(:,:)  | 
						|
           uvmet(1,:,:) = v(:,:) | 
						|
         end if | 
						|
         delete_VarAtts(u,(/"description","units"/)) | 
						|
         copy_VarAtts(u,uvmet) | 
						|
         uvmet@description = " u,v met velocity" | 
						|
         uvmet!0 = "u_v" | 
						|
       end if | 
						|
 | 
						|
 | 
						|
       if( any(map_projection.eq.(/1,2/)) ) then  ; no rotation needed | 
						|
         cen_lat  = nc_file@CEN_LAT | 
						|
         if(isatt(nc_file,"STAND_LON")) then | 
						|
             cen_long = nc_file@STAND_LON | 
						|
         else | 
						|
             cen_long = nc_file@CEN_LON | 
						|
         end if | 
						|
         true_lat1 = nc_file@TRUELAT1 | 
						|
         true_lat2 = nc_file@TRUELAT2 | 
						|
   | 
						|
         getLAT = "XLAT"  | 
						|
         getLON = "XLONG"  | 
						|
         if(.not. isfilevar(nc_file,"XLAT")) then | 
						|
           if(isfilevar(nc_file,"XLAT_M")) then | 
						|
             getLAT = "XLAT_M" | 
						|
             getLON = "XLONG_M" | 
						|
           end if | 
						|
         end if | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             latitude  = nc_file->$getLAT$ | 
						|
             longitude = nc_file->$getLON$ | 
						|
           else | 
						|
             latitude  = file_handle[:]->$getLAT$ | 
						|
             longitude = file_handle[:]->$getLON$ | 
						|
           end if | 
						|
         else | 
						|
           if(ISFILE) then | 
						|
             latitude  = nc_file->$getLAT$(time_in,:,:) | 
						|
             longitude = nc_file->$getLON$(time_in,:,:) | 
						|
           else | 
						|
             latitude  = file_handle[:]->$getLAT$(time_in,:,:) | 
						|
             longitude = file_handle[:]->$getLON$(time_in,:,:) | 
						|
           end if | 
						|
         end if | 
						|
 | 
						|
         cone = 1. | 
						|
         if( map_projection .eq. 1) then    ; Lambert Conformal mapping | 
						|
           if( (fabs(true_lat1 - true_lat2) .gt. 0.1) .and.  \ | 
						|
               (fabs(true_lat2 - 90. )      .gt. 0.1)       ) then | 
						|
               cone = log(cos(true_lat1*radians_per_degree)) \  | 
						|
                     -log(cos(true_lat2*radians_per_degree))  | 
						|
               cone = cone/( log(tan(( 45. -fabs(true_lat1/2.))*radians_per_degree)) - \  | 
						|
                             log(tan((45. -fabs(true_lat2/2.))*radians_per_degree)) )  | 
						|
           else | 
						|
               cone = sin(fabs(true_lat1)*radians_per_degree) | 
						|
           end if | 
						|
         end if | 
						|
         if(map_projection .eq. 2) then      ; polar stereographic | 
						|
           cone = 1. | 
						|
         end if | 
						|
         if(map_projection .eq. 3) then      ; Mercator | 
						|
           cone = 0. | 
						|
         end if | 
						|
 | 
						|
         uvmet = wrf_uvmet( u, v, latitude, longitude, cen_long, cone ) | 
						|
         delete_VarAtts(u,(/"description","units"/)) | 
						|
         copy_VarAtts(u,uvmet) | 
						|
 | 
						|
       end if   | 
						|
        | 
						|
       if( (variable .eq. "uvmet10") )  then | 
						|
         uvmet@description = " u10,v10 met velocity" | 
						|
       end if | 
						|
       return(uvmet) | 
						|
 | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "ua" ) then | 
						|
       ;  U interpolated to mass points | 
						|
       getTHIS = "U"  | 
						|
       if(.not. isfilevar(nc_file,"U")) then | 
						|
         if(isfilevar(nc_file,"UU")) then | 
						|
           getTHIS = "UU" | 
						|
         end if | 
						|
       end if | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           var = nc_file->$getTHIS$ | 
						|
         else | 
						|
           var = file_handle[:]->$getTHIS$ | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           var = nc_file->$getTHIS$(time_in,:,:,:) | 
						|
         else | 
						|
           var = file_handle[:]->$getTHIS$(time_in,:,:,:) | 
						|
         end if | 
						|
       end if | 
						|
 | 
						|
       ua = wrf_user_unstagger(var,var@stagger) | 
						|
 | 
						|
       return(ua) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "va" ) then | 
						|
       ; V interpolated to mass points | 
						|
       getTHIS = "V"  | 
						|
       if(.not. isfilevar(nc_file,"V")) then | 
						|
         if(isfilevar(nc_file,"VV")) then | 
						|
           getTHIS = "VV" | 
						|
         end if | 
						|
       end if | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           var = nc_file->$getTHIS$ | 
						|
         else | 
						|
           var = file_handle[:]->$getTHIS$ | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           var = nc_file->$getTHIS$(time_in,:,:,:) | 
						|
         else | 
						|
           var = file_handle[:]->$getTHIS$(time_in,:,:,:) | 
						|
         end if | 
						|
       end if | 
						|
 | 
						|
       va = wrf_user_unstagger(var,var@stagger) | 
						|
 | 
						|
       return(va) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "wa" ) then | 
						|
       ; W interpolated to mass points | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           var = nc_file->W | 
						|
         else | 
						|
           var = file_handle[:]->W | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           var = nc_file->W(time_in,:,:,:) | 
						|
         else | 
						|
           var = file_handle[:]->W(time_in,:,:,:) | 
						|
         end if | 
						|
       end if | 
						|
 | 
						|
       wa = wrf_user_unstagger(var,var@stagger) | 
						|
 | 
						|
       return(wa) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"p","pres","pressure"/) ) ) then | 
						|
       ; Full model pressure [=base pressure (PB) + pertubation pressure (P)] | 
						|
       if(isfilevar(nc_file,"P")) then | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             var = nc_file->P | 
						|
             PB  = nc_file->PB | 
						|
           else | 
						|
             var = file_handle[:]->P | 
						|
             PB  = file_handle[:]->PB | 
						|
           end if | 
						|
         else | 
						|
           if(ISFILE) then | 
						|
             var = nc_file->P(time_in,:,:,:) | 
						|
             PB  = nc_file->PB(time_in,:,:,:) | 
						|
           else | 
						|
             var = file_handle[:]->P(time_in,:,:,:) | 
						|
             PB  = file_handle[:]->PB(time_in,:,:,:) | 
						|
           end if | 
						|
         end if | 
						|
         var = var + PB | 
						|
       else | 
						|
         ;; may be a met_em file - see if we can get PRES | 
						|
         if(isfilevar(nc_file,"PRES")) then | 
						|
           if ( time .eq. -1 ) then | 
						|
             if(ISFILE) then | 
						|
               var = nc_file->PRES | 
						|
             else | 
						|
               var = file_handle[:]->PRES | 
						|
             end if | 
						|
           else | 
						|
             if(ISFILE) then | 
						|
               var = nc_file->PRES(time_in,:,:,:) | 
						|
             else | 
						|
               var = file_handle[:]->PRES(time_in,:,:,:) | 
						|
             end if | 
						|
           end if | 
						|
         end if | 
						|
       end if | 
						|
       var@description = "Pressure" | 
						|
       if( variable .eq. "pressure" ) then | 
						|
         var = var * 0.01 | 
						|
         var@units = "hPa" | 
						|
       end if | 
						|
       return(var) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"geopt","geopotential","z","height"/) ) ) then | 
						|
       ; Height [=full geopotentail height / 9.81] | 
						|
       if(isfilevar(nc_file,"PH")) then | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             var = nc_file->PH | 
						|
             PHB = nc_file->PHB | 
						|
           else | 
						|
             var = file_handle[:]->PH | 
						|
             PHB = file_handle[:]->PHB | 
						|
           end if | 
						|
         else | 
						|
           if(ISFILE) then | 
						|
             var = nc_file->PH(time,:,:,:) | 
						|
             PHB = nc_file->PHB(time,:,:,:) | 
						|
           else | 
						|
             var = file_handle[:]->PH(time,:,:,:) | 
						|
             PHB = file_handle[:]->PHB(time,:,:,:) | 
						|
           end if | 
						|
         end if | 
						|
 | 
						|
         var = var + PHB | 
						|
         z = wrf_user_unstagger(var,var@stagger) | 
						|
         z@description = "Geopotential" | 
						|
 | 
						|
       else | 
						|
         ;; may be a met_em file - see if we can get GHT - data in met_em file is Height in M | 
						|
         if(isfilevar(nc_file,"GHT")) then | 
						|
           if ( time .eq. -1 ) then | 
						|
             if(ISFILE) then | 
						|
               z = nc_file->GHT | 
						|
             else | 
						|
               z = file_handle[:]->GHT | 
						|
             end if | 
						|
           else | 
						|
             if(ISFILE) then | 
						|
               z = nc_file->GHT(time,:,:,:) | 
						|
             else | 
						|
               z = file_handle[:]->GHT(time,:,:,:) | 
						|
             end if | 
						|
           end if | 
						|
           z = z * 9.81 | 
						|
           z@description = "Geopotential" | 
						|
           z@units       = "m2 s-2" | 
						|
         end if | 
						|
       end if | 
						|
 | 
						|
       if( any( variable .eq. (/"z","height"/) ) ) then | 
						|
         z = z / 9.81 | 
						|
         z@description = "Height" | 
						|
         z@units       = "m" | 
						|
       end if | 
						|
       return(z) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"th","theta"/) ) ) then | 
						|
       ; Potentail Temperature is model output T + 300K | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           var = nc_file->T | 
						|
         else | 
						|
           var = file_handle[:]->T | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           var = nc_file->T(time_in,:,:,:) | 
						|
         else | 
						|
           var = file_handle[:]->T(time_in,:,:,:) | 
						|
         end if | 
						|
       end if   | 
						|
       var = var + 300. | 
						|
       var@description = "Potential Temperature (theta) " | 
						|
       return(var) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"tk","tc"/) ) ) then | 
						|
       ;; function wrf_tk needs theta and pressure (Pa) on input and returns temperature in K on return | 
						|
       if(isfilevar(nc_file,"T")) then | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             T  = nc_file->T | 
						|
             P  = nc_file->P | 
						|
             PB = nc_file->PB | 
						|
           else | 
						|
             T  = file_handle[:]->T | 
						|
             P  = file_handle[:]->P | 
						|
             PB = file_handle[:]->PB | 
						|
           end if | 
						|
         else | 
						|
           if(ISFILE) then | 
						|
             T  = nc_file->T(time_in,:,:,:) | 
						|
             P  = nc_file->P(time_in,:,:,:) | 
						|
             PB = nc_file->PB(time_in,:,:,:) | 
						|
           else | 
						|
             T  = file_handle[:]->T(time_in,:,:,:) | 
						|
             P  = file_handle[:]->P(time_in,:,:,:) | 
						|
             PB = file_handle[:]->PB(time_in,:,:,:) | 
						|
           end if | 
						|
         end if   | 
						|
         T = T + 300. | 
						|
         P = P + PB | 
						|
         t = wrf_tk( P , T ) | 
						|
         delete_VarAtts(T,(/"description"/)) | 
						|
         copy_VarAtts(T,t) | 
						|
       else | 
						|
         ;; may be a met_em file - see if we can get TT | 
						|
         if(isfilevar(nc_file,"TT")) then | 
						|
           if ( time .eq. -1 ) then | 
						|
             if(ISFILE) then | 
						|
               t = nc_file->TT | 
						|
             else | 
						|
               t = file_handle[:]->TT | 
						|
             end if | 
						|
           else | 
						|
             if(ISFILE) then | 
						|
               t = nc_file->TT(time_in,:,:,:) | 
						|
             else | 
						|
               t = file_handle[:]->TT(time_in,:,:,:) | 
						|
             end if | 
						|
           end if   | 
						|
         end if   | 
						|
       end if   | 
						|
       if( variable .eq. "tc" ) then | 
						|
         t = t - 273.16 | 
						|
         t@units = "C"     ; Overwrite return units | 
						|
       end if | 
						|
       return(t) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
   if( variable .eq. "eth" ) then | 
						|
   ;Equivalent Potential Temperature in degrees K | 
						|
       if(isfilevar(nc_file,"T")) then | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             T  = nc_file->T | 
						|
             P  = nc_file->P | 
						|
             PB = nc_file->PB | 
						|
             QV = nc_file->QVAPOR | 
						|
           else | 
						|
             T  = file_handle[:]->T | 
						|
             P  = file_handle[:]->P | 
						|
             PB = file_handle[:]->PB | 
						|
             QV = file_handle[:]->QVAPOR | 
						|
           end if | 
						|
         else | 
						|
           if(ISFILE) then | 
						|
             T  = nc_file->T(time_in,:,:,:) | 
						|
             P  = nc_file->P(time_in,:,:,:) | 
						|
             PB = nc_file->PB(time_in,:,:,:) | 
						|
             QV = nc_file->QVAPOR(time_in,:,:,:) | 
						|
           else | 
						|
             T  = file_handle[:]->T(time_in,:,:,:) | 
						|
             P  = file_handle[:]->P(time_in,:,:,:) | 
						|
             PB = file_handle[:]->PB(time_in,:,:,:) | 
						|
             QV = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
           end if | 
						|
         end if   | 
						|
         T  = T + 300.        ; potential temperature in K. | 
						|
         P  = P + PB          ; full pressure in Pa.    | 
						|
         tk = wrf_tk( P , T ) ; temperature in K. | 
						|
         eth = wrf_eth ( QV, tk, P ) | 
						|
         delete_VarAtts(T,(/"description"/)) | 
						|
         copy_VarAtts(T,eth) | 
						|
         return(eth) | 
						|
       else | 
						|
         print("This diagnostic only for with WRF data file and not for WPS files") | 
						|
         exit | 
						|
       end if   | 
						|
 | 
						|
   end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "td" ) then | 
						|
       ;; function wrf_td needs qv and pressure (Pa) on input and returns dewpoint temperature on return | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           P      = nc_file->P | 
						|
           PB     = nc_file->PB | 
						|
           QVAPOR = nc_file->QVAPOR | 
						|
         else | 
						|
           P      = file_handle[:]->P | 
						|
           PB     = file_handle[:]->PB | 
						|
           QVAPOR = file_handle[:]->QVAPOR | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           P      = nc_file->P(time_in,:,:,:) | 
						|
           PB     = nc_file->PB(time_in,:,:,:) | 
						|
           QVAPOR = nc_file->QVAPOR(time_in,:,:,:) | 
						|
         else | 
						|
           P      = file_handle[:]->P(time_in,:,:,:) | 
						|
           PB     = file_handle[:]->PB(time_in,:,:,:) | 
						|
           QVAPOR = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
         end if | 
						|
       end if | 
						|
       P = P + PB | 
						|
       td  = wrf_td( P , QVAPOR ) | 
						|
       delete_VarAtts(QVAPOR,(/"description","units"/)) | 
						|
       copy_VarAtts(QVAPOR,td) | 
						|
       return(td) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "td2" ) then | 
						|
       ;; function wrf_td needs qv and pressure (Pa) on input and returns dewpoint temperature on return | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           PSFC = nc_file->PSFC | 
						|
           Q2   = nc_file->Q2 | 
						|
         else | 
						|
           PSFC = file_handle[:]->PSFC | 
						|
           Q2   = file_handle[:]->Q2 | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           PSFC = nc_file->PSFC(time_in,:,:)  | 
						|
           Q2   = nc_file->Q2(time_in,:,:) | 
						|
         else | 
						|
           PSFC = file_handle[:]->PSFC(time_in,:,:)  | 
						|
           Q2   = file_handle[:]->Q2(time_in,:,:) | 
						|
         end if | 
						|
       end if | 
						|
       td = wrf_td( PSFC , Q2 ) | 
						|
       delete_VarAtts(Q2,(/"description","units"/)) | 
						|
       copy_VarAtts(Q2,td) | 
						|
       td@description = "2m Dewpoint Temperature"   ; Overwrite return description | 
						|
       return(td) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "slp" ) then | 
						|
       if(isfilevar(nc_file,"T")) then | 
						|
         ;; first compute theta - function wrf_tk needs theta and pressure (Pa) on input | 
						|
         ;; THEN compute sea level pressure, from qv, p (Pa), tk, z | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             T      = nc_file->T | 
						|
             P      = nc_file->P | 
						|
             PB     = nc_file->PB | 
						|
             QVAPOR = nc_file->QVAPOR | 
						|
             PH     = nc_file->PH | 
						|
             PHB    = nc_file->PHB | 
						|
           else | 
						|
             T      = file_handle[:]->T | 
						|
             P      = file_handle[:]->P | 
						|
             PB     = file_handle[:]->PB | 
						|
             QVAPOR = file_handle[:]->QVAPOR | 
						|
             PH     = file_handle[:]->PH | 
						|
             PHB    = file_handle[:]->PHB | 
						|
           end if | 
						|
         else | 
						|
           if(ISFILE) then | 
						|
             T      = nc_file->T(time_in,:,:,:) | 
						|
             P      = nc_file->P(time_in,:,:,:) | 
						|
             PB     = nc_file->PB(time_in,:,:,:) | 
						|
             QVAPOR = nc_file->QVAPOR(time_in,:,:,:) | 
						|
             PH     = nc_file->PH(time_in,:,:,:) | 
						|
             PHB    = nc_file->PHB(time_in,:,:,:) | 
						|
           else | 
						|
             T      = file_handle[:]->T(time_in,:,:,:) | 
						|
             P      = file_handle[:]->P(time_in,:,:,:) | 
						|
             PB     = file_handle[:]->PB(time_in,:,:,:) | 
						|
             QVAPOR = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
             PH     = file_handle[:]->PH(time_in,:,:,:) | 
						|
             PHB    = file_handle[:]->PHB(time_in,:,:,:) | 
						|
           end if | 
						|
         end if | 
						|
         T = T + 300. | 
						|
         P = P + PB | 
						|
         QVAPOR = QVAPOR > 0.000 | 
						|
         PH    = ( PH + PHB ) / 9.81 | 
						|
         z = wrf_user_unstagger(PH,PH@stagger) | 
						|
 | 
						|
         tk = wrf_tk( P , T )    ; calculate TK | 
						|
         slp   = wrf_slp( z, tk, P, QVAPOR )  ; calculate slp | 
						|
         delete_VarAtts(T,(/"description","units"/)) | 
						|
         copy_VarAtts(T,slp) | 
						|
       else | 
						|
         ;; may be a met_em file - see if we can get PMSL | 
						|
         if(isfilevar(nc_file,"PMSL")) then | 
						|
           if ( time .eq. -1 ) then | 
						|
             if(ISFILE) then | 
						|
               slp = nc_file->PMSL | 
						|
             else | 
						|
               slp = file_handle[:]->PMSL | 
						|
             end if | 
						|
           else | 
						|
             if(ISFILE) then | 
						|
               slp = nc_file->PMSL(time_in,:,:) | 
						|
             else | 
						|
               slp = file_handle[:]->PMSL(time_in,:,:) | 
						|
             end if | 
						|
           end if | 
						|
         end if | 
						|
       end if   | 
						|
 | 
						|
       return(slp) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "rh" ) then | 
						|
       if(isfilevar(nc_file,"T")) then | 
						|
         ;; first compute theta - function wrf_tk needs theta and pressure (Pa) on input | 
						|
         ;; THEN compute rh, using tk, p (Pa), QVAPOR | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             T      = nc_file->T | 
						|
             P      = nc_file->P | 
						|
             PB     = nc_file->PB | 
						|
             QVAPOR = nc_file->QVAPOR | 
						|
           else | 
						|
             T      = file_handle[:]->T | 
						|
             P      = file_handle[:]->P | 
						|
             PB     = file_handle[:]->PB | 
						|
             QVAPOR = file_handle[:]->QVAPOR | 
						|
           end if | 
						|
         else | 
						|
           if(ISFILE) then | 
						|
             T      = nc_file->T(time_in,:,:,:) | 
						|
             P      = nc_file->P(time_in,:,:,:) | 
						|
             PB     = nc_file->PB(time_in,:,:,:) | 
						|
             QVAPOR = nc_file->QVAPOR(time_in,:,:,:) | 
						|
           else | 
						|
             T      = file_handle[:]->T(time_in,:,:,:) | 
						|
             P      = file_handle[:]->P(time_in,:,:,:) | 
						|
             PB     = file_handle[:]->PB(time_in,:,:,:) | 
						|
             QVAPOR = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
           end if | 
						|
         end if   | 
						|
         T = T + 300. | 
						|
         P  = P + PB | 
						|
         QVAPOR = QVAPOR > 0.000 | 
						|
         tk = wrf_tk( P , T ) | 
						|
         rh = wrf_rh( QVAPOR, P, tk ) | 
						|
         delete_VarAtts(T,(/"description","units"/)) | 
						|
         copy_VarAtts(T,rh) | 
						|
       else | 
						|
         ;; may be a met_em file - see if we can get RH | 
						|
         if(isfilevar(nc_file,"RH")) then | 
						|
           if ( time .eq. -1 ) then | 
						|
             if(ISFILE) then | 
						|
               rh = nc_file->RH | 
						|
             else | 
						|
               rh = file_handle[:]->RH | 
						|
             end if | 
						|
           else | 
						|
             if(ISFILE) then | 
						|
               rh = nc_file->RH(time_in,:,:,:) | 
						|
             else | 
						|
               rh = file_handle[:]->RH(time_in,:,:,:) | 
						|
             end if | 
						|
           end if | 
						|
         end if | 
						|
       end if   | 
						|
       return(rh) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "rh2" ) then | 
						|
       if(isfilevar(nc_file,"T2")) then | 
						|
         ;; Compute rh2, using T2, PSFC, Q2 | 
						|
         if ( time .eq. -1 ) then | 
						|
           if(ISFILE) then | 
						|
             T2   = nc_file->T2 | 
						|
             PSFC = nc_file->PSFC | 
						|
             Q2   = nc_file->Q2 | 
						|
           else | 
						|
             T2   = file_handle[:]->T2 | 
						|
             PSFC = file_handle[:]->PSFC | 
						|
             Q2   = file_handle[:]->Q2 | 
						|
           end if | 
						|
         else | 
						|
           if(ISFILE) then | 
						|
             T2   = nc_file->T2(time_in,:,:) | 
						|
             PSFC = nc_file->PSFC(time_in,:,:) | 
						|
             Q2   = nc_file->Q2(time_in,:,:) | 
						|
           else | 
						|
             T2   = file_handle[:]->T2(time_in,:,:) | 
						|
             PSFC = file_handle[:]->PSFC(time_in,:,:) | 
						|
             Q2   = file_handle[:]->Q2(time_in,:,:) | 
						|
           end if | 
						|
         end if   | 
						|
         Q2 = Q2 > 0.000 | 
						|
         rh = wrf_rh( Q2, PSFC, T2 ) | 
						|
         delete_VarAtts(T2,(/"description","units"/)) | 
						|
         copy_VarAtts(T2,rh) | 
						|
         rh@description = "2m Relative Humidity"            | 
						|
       else | 
						|
         ;; may be a met_em file - see if we can get RH | 
						|
         if(isfilevar(nc_file,"RH")) then | 
						|
           print("Probably a met_em file - get lowerst level from RH field") | 
						|
           if ( time .eq. -1 ) then | 
						|
             if(ISFILE) then | 
						|
               rh2 = nc_file->RH(:,0,:,:) | 
						|
             else | 
						|
               rh2 = file_handle[:]->RH(:,0,:,:) | 
						|
             end if | 
						|
           else | 
						|
             if(ISFILE) then | 
						|
               rh2 = nc_file->RH(time_in,0,:,:) | 
						|
             else | 
						|
               rh2 = file_handle[:]->RH(time_in,0,:,:) | 
						|
             end if | 
						|
           end if | 
						|
         end if | 
						|
       end if   | 
						|
       return(rh) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "pvo" ) then | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           U    = nc_file->U | 
						|
           V    = nc_file->V | 
						|
           T    = nc_file->T | 
						|
           P    = nc_file->P | 
						|
           PB   = nc_file->PB | 
						|
           MSFU = nc_file->MAPFAC_U | 
						|
           MSFV = nc_file->MAPFAC_V | 
						|
           MSFM = nc_file->MAPFAC_M | 
						|
           COR  = nc_file->F | 
						|
         else | 
						|
           U    = file_handle[:]->U | 
						|
           V    = file_handle[:]->V | 
						|
           T    = file_handle[:]->T | 
						|
           P    = file_handle[:]->P | 
						|
           PB   = file_handle[:]->PB | 
						|
           MSFU = file_handle[:]->MAPFAC_U | 
						|
           MSFV = file_handle[:]->MAPFAC_V | 
						|
           MSFM = file_handle[:]->MAPFAC_M | 
						|
           COR  = file_handle[:]->F | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           U    = nc_file->U(time_in,:,:,:) | 
						|
           V    = nc_file->V(time_in,:,:,:) | 
						|
           T    = nc_file->T(time_in,:,:,:) | 
						|
           P    = nc_file->P(time_in,:,:,:) | 
						|
           PB   = nc_file->PB(time_in,:,:,:) | 
						|
           MSFU = nc_file->MAPFAC_U(time_in,:,:) | 
						|
           MSFV = nc_file->MAPFAC_V(time_in,:,:) | 
						|
           MSFM = nc_file->MAPFAC_M(time_in,:,:) | 
						|
           COR  = nc_file->F(time_in,:,:) | 
						|
         else | 
						|
           U    = file_handle[:]->U(time_in,:,:,:) | 
						|
           V    = file_handle[:]->V(time_in,:,:,:) | 
						|
           T    = file_handle[:]->T(time_in,:,:,:) | 
						|
           P    = file_handle[:]->P(time_in,:,:,:) | 
						|
           PB   = file_handle[:]->PB(time_in,:,:,:) | 
						|
           MSFU = file_handle[:]->MAPFAC_U(time_in,:,:) | 
						|
           MSFV = file_handle[:]->MAPFAC_V(time_in,:,:) | 
						|
           MSFM = file_handle[:]->MAPFAC_M(time_in,:,:) | 
						|
           COR  = file_handle[:]->F(time_in,:,:) | 
						|
         end if | 
						|
       end if   | 
						|
       T = T + 300. | 
						|
       P = P + PB | 
						|
       DX = nc_file@DX | 
						|
       DY = nc_file@DY | 
						|
 | 
						|
       pvo = wrf_pvo( U, V, T, P, MSFU, MSFV, MSFM, COR, DX, DY, 0) | 
						|
 | 
						|
       delete_VarAtts(T,(/"description","units"/)) | 
						|
       copy_VarAtts(T,pvo) | 
						|
       return(pvo) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "avo" ) then | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           U    = nc_file->U | 
						|
           V    = nc_file->V | 
						|
           MSFU = nc_file->MAPFAC_U | 
						|
           MSFV = nc_file->MAPFAC_V | 
						|
           MSFM = nc_file->MAPFAC_M | 
						|
           COR  = nc_file->F | 
						|
         else | 
						|
           U    = file_handle[:]->U | 
						|
           V    = file_handle[:]->V | 
						|
           MSFU = file_handle[:]->MAPFAC_U | 
						|
           MSFV = file_handle[:]->MAPFAC_V | 
						|
           MSFM = file_handle[:]->MAPFAC_M | 
						|
           COR  = file_handle[:]->F | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           U    = nc_file->U(time_in,:,:,:) | 
						|
           V    = nc_file->V(time_in,:,:,:) | 
						|
           MSFU = nc_file->MAPFAC_U(time_in,:,:) | 
						|
           MSFV = nc_file->MAPFAC_V(time_in,:,:) | 
						|
           MSFM = nc_file->MAPFAC_M(time_in,:,:) | 
						|
           COR  = nc_file->F(time_in,:,:) | 
						|
         else | 
						|
           U    = file_handle[:]->U(time_in,:,:,:) | 
						|
           V    = file_handle[:]->V(time_in,:,:,:) | 
						|
           MSFU = file_handle[:]->MAPFAC_U(time_in,:,:) | 
						|
           MSFV = file_handle[:]->MAPFAC_V(time_in,:,:) | 
						|
           MSFM = file_handle[:]->MAPFAC_M(time_in,:,:) | 
						|
           COR  = file_handle[:]->F(time_in,:,:) | 
						|
         end if | 
						|
       end if   | 
						|
       DX = nc_file@DX | 
						|
       DY = nc_file@DY | 
						|
 | 
						|
       avo = wrf_avo( U, V, MSFU, MSFV, MSFM, COR, DX, DY, 0) | 
						|
 | 
						|
       delete_VarAtts(COR,(/"description","units"/)) | 
						|
       copy_VarAtts(COR,avo) | 
						|
       return(avo) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "dbz" .or. variable .eq. "mdbz" ) then | 
						|
       ; calculate dbz | 
						|
       ivarint  = 0  | 
						|
       iliqskin = 0 | 
						|
       dim_vars = dimsizes(varin) | 
						|
       do idims = 1,dim_vars-1 | 
						|
         if ( idims .eq. 1 ) then | 
						|
           if ( varin(idims) .eq. "1" ) then | 
						|
             ivarint = 1 | 
						|
           end if | 
						|
         end if | 
						|
         if ( idims .eq. 2 ) then | 
						|
           if ( varin(idims) .eq. "1" ) then | 
						|
             iliqskin = 1 | 
						|
           end if | 
						|
         end if | 
						|
       end do | 
						|
 | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T | 
						|
           P  = nc_file->P | 
						|
           PB = nc_file->PB | 
						|
           qv = nc_file->QVAPOR | 
						|
           qr = nc_file->QRAIN | 
						|
         else | 
						|
           T  = file_handle[:]->T | 
						|
           P  = file_handle[:]->P | 
						|
           PB = file_handle[:]->PB | 
						|
           qv = file_handle[:]->QVAPOR | 
						|
           qr = file_handle[:]->QRAIN | 
						|
         end if | 
						|
         if(isfilevar(nc_file,"QSNOW")) | 
						|
           if(ISFILE) then | 
						|
             qs = nc_file->QSNOW | 
						|
           else | 
						|
             qs = file_handle[:]->QSNOW | 
						|
           end if | 
						|
         end if | 
						|
         if(isfilevar(nc_file,"QGRAUP")) | 
						|
           if(ISFILE) then | 
						|
             qg = nc_file->QGRAUP | 
						|
           else | 
						|
             qg = file_handle[:]->QGRAUP | 
						|
           end if | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T(time_in,:,:,:) | 
						|
           P  = nc_file->P(time_in,:,:,:) | 
						|
           PB = nc_file->PB(time_in,:,:,:) | 
						|
           qv = nc_file->QVAPOR(time_in,:,:,:) | 
						|
           qr = nc_file->QRAIN(time_in,:,:,:) | 
						|
         else | 
						|
           T  = file_handle[:]->T(time_in,:,:,:) | 
						|
           P  = file_handle[:]->P(time_in,:,:,:) | 
						|
           PB = file_handle[:]->PB(time_in,:,:,:) | 
						|
           qv = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
           qr = file_handle[:]->QRAIN(time_in,:,:,:) | 
						|
         end if | 
						|
         if(isfilevar(nc_file,"QSNOW")) | 
						|
           if(ISFILE) then | 
						|
             qs = nc_file->QSNOW(time_in,:,:,:) | 
						|
           else | 
						|
             qs = file_handle[:]->QSNOW(time_in,:,:,:) | 
						|
           end if | 
						|
         end if | 
						|
         if(isfilevar(nc_file,"QGRAUP")) | 
						|
           if(ISFILE) then | 
						|
             qg = nc_file->QGRAUP(time_in,:,:,:) | 
						|
           else | 
						|
             qg = file_handle[:]->QGRAUP(time_in,:,:,:) | 
						|
           end if | 
						|
         end if | 
						|
       end if | 
						|
       T  = T + 300. | 
						|
       P  = P + PB | 
						|
       tk = wrf_tk( P , T ) | 
						|
 | 
						|
       if ( .not. isvar("qs") ) then | 
						|
         qs = qv | 
						|
         qs = 0.0 | 
						|
       end if | 
						|
       if ( .not. isvar("qg") ) then | 
						|
         qg = qv | 
						|
         qg = 0.0 | 
						|
       end if | 
						|
 | 
						|
       dbz = wrf_dbz ( P, tk, qv, qr, qs, qg, ivarint, iliqskin) | 
						|
       delete(qs) | 
						|
       delete(qg) | 
						|
 | 
						|
       delete_VarAtts(T,(/"description","units"/)) | 
						|
       copy_VarAtts(T,dbz) | 
						|
 | 
						|
 | 
						|
       if ( variable .eq. "mdbz") then | 
						|
         dims = getvardims(dbz) | 
						|
         rank = dimsizes(dims) | 
						|
         if ( rank .eq. 5 ) then | 
						|
            mdbz = dim_max ( dbz($dims(0)$|:,$dims(1)$|:,$dims(3)$|:,$dims(4)$|:,$dims(2)$|:) ) | 
						|
            mdbz!0 = dbz!0 | 
						|
            mdbz!1 = dbz!1 | 
						|
         end if | 
						|
         if ( rank .eq. 4 ) then | 
						|
            mdbz = dim_max ( dbz($dims(0)$|:,$dims(2)$|:,$dims(3)$|:,$dims(1)$|:) ) | 
						|
            mdbz!0 = dbz!0 | 
						|
         end if | 
						|
         if ( rank .eq. 3 ) then | 
						|
            mdbz = dim_max ( dbz($dims(1)$|:,$dims(2)$|:,$dims(0)$|:) ) | 
						|
         end if | 
						|
         nn = rank-1 | 
						|
         nm = rank-2 | 
						|
         mdbz!nm = dbz!nn | 
						|
         nn = rank-2 | 
						|
         nm = rank-3 | 
						|
         mdbz!nm = dbz!nn | 
						|
         copy_VarAtts(dbz,mdbz) | 
						|
         mdbz@description = "Max Reflectivity" | 
						|
         return(mdbz) | 
						|
       else | 
						|
         return(dbz) | 
						|
       end if | 
						|
 | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"cape_3d","cape_2d"/) ) ) then | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T | 
						|
           P  = nc_file->P | 
						|
           PB = nc_file->PB | 
						|
           QV = nc_file->QVAPOR | 
						|
           PH  = nc_file->PH | 
						|
           PHB = nc_file->PHB | 
						|
           HGT = nc_file->HGT | 
						|
           PSFC = nc_file->PSFC | 
						|
         else | 
						|
           T  = file_handle[:]->T | 
						|
           P  = file_handle[:]->P | 
						|
           PB = file_handle[:]->PB | 
						|
           QV = file_handle[:]->QVAPOR | 
						|
           PH  = file_handle[:]->PH | 
						|
           PHB = file_handle[:]->PHB | 
						|
           HGT = file_handle[:]->HGT | 
						|
           PSFC = file_handle[:]->PSFC | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T(time_in,:,:,:) | 
						|
           P  = nc_file->P(time_in,:,:,:) | 
						|
           PB = nc_file->PB(time_in,:,:,:) | 
						|
           QV = nc_file->QVAPOR(time_in,:,:,:) | 
						|
           PH  = nc_file->PH(time_in,:,:,:) | 
						|
           PHB = nc_file->PHB(time_in,:,:,:) | 
						|
           HGT = nc_file->HGT(time_in,:,:) | 
						|
           PSFC = nc_file->PSFC(time_in,:,:) | 
						|
         else | 
						|
           T  = file_handle[:]->T(time_in,:,:,:) | 
						|
           P  = file_handle[:]->P(time_in,:,:,:) | 
						|
           PB = file_handle[:]->PB(time_in,:,:,:) | 
						|
           QV = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
           PH  = file_handle[:]->PH(time_in,:,:,:) | 
						|
           PHB = file_handle[:]->PHB(time_in,:,:,:) | 
						|
           HGT = file_handle[:]->HGT(time_in,:,:) | 
						|
           PSFC = file_handle[:]->PSFC(time_in,:,:) | 
						|
         end if | 
						|
       end if | 
						|
       T = T + 300. | 
						|
       P  = P + PB  | 
						|
       tk = wrf_tk( P , T ) | 
						|
       PH =  PH + PHB  | 
						|
       z = wrf_user_unstagger(PH,PH@stagger) | 
						|
       z = z/9.81 | 
						|
 | 
						|
       if( variable .eq. "cape_3d" ) then | 
						|
         cape = wrf_cape_3d( P, tk, QV, z, HGT, PSFC, True ) | 
						|
         cape@description = "cape ; cin" | 
						|
       end if | 
						|
       if( variable .eq. "cape_2d" ) then | 
						|
         cape = wrf_cape_2d( P, tk, QV, z, HGT, PSFC, True ) | 
						|
         delete_VarAtts(T,(/"MemoryOrder"/)) | 
						|
         cape@MemoryOrder = "XY" | 
						|
         cape@description = "mcape ; mcin ; lcl ; lfc" | 
						|
       end if | 
						|
       delete_VarAtts(T,(/"description","units"/)) | 
						|
       copy_VarAtts(T,cape) | 
						|
 | 
						|
       return(cape) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"pw"/) ) ) then | 
						|
       ;Precipitable Water  | 
						|
        print("calculating precipitable water") | 
						|
        gas_const = 287.  ; J/K/kg | 
						|
        Cp        = 1004. ; J/K/kg      | 
						|
       if ( time .eq. -1 ) then | 
						|
        if(ISFILE) then | 
						|
          T   = nc_file->T | 
						|
          P   = nc_file->P | 
						|
          PB  = nc_file->PB | 
						|
          PH  = nc_file->PH | 
						|
          PHB = nc_file->PHB | 
						|
          QV  = nc_file->QVAPOR | 
						|
        else | 
						|
          T   = file_handle[:]->T | 
						|
          P   = file_handle[:]->P | 
						|
          PB  = file_handle[:]->PB | 
						|
          PH  = file_handle[:]->PH | 
						|
          PHB = file_handle[:]->PHB | 
						|
          QV  = file_handle[:]->QVAPOR | 
						|
        end if | 
						|
       else | 
						|
        if(ISFILE) then | 
						|
          T   = nc_file->T(time_in,:,:,:) | 
						|
          P   = nc_file->P(time_in,:,:,:) | 
						|
          PB  = nc_file->PB(time_in,:,:,:) | 
						|
          PH  = nc_file->PH(time_in,:,:,:) | 
						|
          PHB = nc_file->PHB(time_in,:,:,:) | 
						|
          QV  = nc_file->QVAPOR(time_in,:,:,:) | 
						|
        else | 
						|
          T   = file_handle[:]->T(time_in,:,:,:) | 
						|
          P   = file_handle[:]->P(time_in,:,:,:) | 
						|
          PB  = file_handle[:]->PB(time_in,:,:,:) | 
						|
          PH  = file_handle[:]->PH(time_in,:,:,:) | 
						|
          PHB = file_handle[:]->PHB(time_in,:,:,:) | 
						|
          QV  = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
        end if | 
						|
       end if   | 
						|
        | 
						|
       pres   =  P + PB | 
						|
       height = (PH + PHB)/9.8           ; height at full levels  | 
						|
       theta  =  T + 300. | 
						|
       temp   = theta * (pres/100000) ^ (gas_const/Cp) | 
						|
       vtemp  = (1 + 0.61*QV) * temp  ; virtual temp | 
						|
 | 
						|
       dims = dimsizes(T) | 
						|
       nd = dimsizes(dims) | 
						|
 | 
						|
       if ( nd .eq. 4 ) then | 
						|
         zdiff  = height(:,0,:,:) | 
						|
         zdiff  = 0. | 
						|
         pw_sfc_ptop = height(:,0,:,:) | 
						|
         pw_sfc_ptop = 0. | 
						|
         do k = 0,dims(1)-1 | 
						|
           zdiff(:,:,:) = (height(:,k+1,:,:) - height(:,k,:,:)) | 
						|
           pw_sfc_ptop(:,:,:) =  pw_sfc_ptop(:,:,:) + ((pres(:,k,:,:)/(gas_const * vtemp(:,k,:,:))) * QV(:,k,:,:) * zdiff(:,:,:)) | 
						|
         end do | 
						|
       end if | 
						|
       if ( nd .eq. 3 ) then | 
						|
         zdiff  = height(0,:,:) | 
						|
         zdiff  = 0. | 
						|
         pw_sfc_ptop = height(0,:,:) | 
						|
         pw_sfc_ptop = 0. | 
						|
         do k = 0,dims(0)-1 | 
						|
           zdiff(:,:) = (height(k+1,:,:) - height(k,:,:)) | 
						|
           pw_sfc_ptop(:,:) =  pw_sfc_ptop(:,:) + ((pres(k,:,:)/(gas_const * vtemp(k,:,:))) * QV(k,:,:) * zdiff(:,:)) | 
						|
         end do | 
						|
       end if | 
						|
 | 
						|
       pw_sfc_ptop@description = "Precipitable Water" | 
						|
       return(pw_sfc_ptop) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"helicity"/) ) ) then | 
						|
       getU = "U"  | 
						|
       getV = "V"  | 
						|
       if(.not. isfilevar(nc_file,"U")) then | 
						|
         if(isfilevar(nc_file,"UU")) then | 
						|
           getU = "UU" | 
						|
           getV = "VV" | 
						|
        end if | 
						|
       end if | 
						|
       if ( time .eq. -1 ) then | 
						|
        if(ISFILE) then | 
						|
          u_in  = nc_file->$getU$ | 
						|
          v_in  = nc_file->$getV$ | 
						|
          PH    = nc_file->PH | 
						|
          geopt = nc_file->PHB  | 
						|
          ter   = nc_file->HGT | 
						|
        else | 
						|
          u_in  = file_handle[:]->$getU$ | 
						|
          v_in  = file_handle[:]->$getV$ | 
						|
          PH    = file_handle[:]->PH | 
						|
          geopt = file_handle[:]->PHB  | 
						|
          ter   = file_handle[:]->HGT | 
						|
        end if | 
						|
       else | 
						|
        if(ISFILE) then | 
						|
          u_in  = nc_file->$getU$(time_in,:,:,:) | 
						|
          v_in  = nc_file->$getV$(time_in,:,:,:) | 
						|
          PH    = nc_file->PH(time_in,:,:,:) | 
						|
          geopt = nc_file->PHB(time_in,:,:,:) | 
						|
          ter   = nc_file->HGT(time_in,:,:) | 
						|
        else | 
						|
          u_in  = file_handle[:]->$getU$(time_in,:,:,:) | 
						|
          v_in  = file_handle[:]->$getV$(time_in,:,:,:) | 
						|
          PH    = file_handle[:]->PH(time_in,:,:,:) | 
						|
          geopt = file_handle[:]->PHB(time_in,:,:,:) | 
						|
          ter   = file_handle[:]->HGT(time_in,:,:) | 
						|
        end if | 
						|
       end if | 
						|
 | 
						|
       ua    = wrf_user_unstagger(u_in,u_in@stagger) | 
						|
       va    = wrf_user_unstagger(v_in,v_in@stagger) | 
						|
       geopt  = geopt + PH | 
						|
       za     = wrf_user_unstagger(geopt,geopt@stagger) | 
						|
       za     = za / 9.81  ; change to height | 
						|
 | 
						|
       ua1    = ua(::-1,:,:) | 
						|
       va1    = va(::-1,:,:) | 
						|
       za1    = za(::-1,:,:) | 
						|
 | 
						|
       top_ok = 0 | 
						|
       top = 3000. | 
						|
 | 
						|
       dim_vars = dimsizes(varin) | 
						|
       if(dim_vars .eq. 2) then | 
						|
        if( varin(1) .eq. "3000" ) then | 
						|
           top = 3000. | 
						|
           top_ok = 1 | 
						|
        end if | 
						|
 | 
						|
        if( varin(1) .eq. "1000" ) then | 
						|
           top = 1000. | 
						|
           top_ok = 1 | 
						|
        end if | 
						|
 | 
						|
        if(top_ok .eq. 0) then | 
						|
          print("Top values of 1000 or 3000 are accepted.") | 
						|
          top = 3000. | 
						|
        end if | 
						|
       end if | 
						|
 | 
						|
       print("Calculations are done with a top of " + top) | 
						|
       sreh = wrf_helicity(ua1, va1, za1, ter, top) | 
						|
       return(sreh) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
  if( any(variable .eq. (/"updraft_helicity"/) ) )then | 
						|
       getU = "U" | 
						|
       getV = "V" | 
						|
       if(.not. isfilevar(nc_file,"U")) then | 
						|
         if(isfilevar(nc_file,"UU")) then | 
						|
           getU = "UU" | 
						|
           getV = "VV" | 
						|
         end if | 
						|
       end if | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
            u_in = nc_file->$getU$ | 
						|
            v_in = nc_file->$getV$ | 
						|
            w    = nc_file->W | 
						|
            ph   = nc_file->PH | 
						|
            phb  = nc_file->PHB | 
						|
         else | 
						|
            u_in = file_handle[:]->$getU$ | 
						|
            v_in = file_handle[:]->$getV$ | 
						|
            w    = file_handle[:]->W | 
						|
            ph   = file_handle[:]->PH | 
						|
            phb  = file_handle[:]->PHB | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
            u_in = nc_file->$getU$(time_in,:,:,:) | 
						|
            v_in = nc_file->$getV$(time_in,:,:,:) | 
						|
            w    = nc_file->W(time_in,:,:,:) | 
						|
            ph   = nc_file->PH(time_in,:,:,:) | 
						|
            phb  = nc_file->PHB(time_in,:,:,:) | 
						|
         else | 
						|
            u_in = file_handle[:]->$getU$(time_in,:,:,:) | 
						|
            v_in = file_handle[:]->$getV$(time_in,:,:,:) | 
						|
            w    = file_handle[:]->W(time_in,:,:,:) | 
						|
            ph   = file_handle[:]->PH(time_in,:,:,:) | 
						|
            phb  = file_handle[:]->PHB(time_in,:,:,:) | 
						|
         end if | 
						|
       end if | 
						|
       ua   = wrf_user_unstagger(u_in,u_in@stagger) | 
						|
       va   = wrf_user_unstagger(v_in,v_in@stagger) | 
						|
       mapfct = nc_file->MAPFAC_M(0,:,:) | 
						|
       zp = ph + phb | 
						|
       dx = nc_file@DX | 
						|
       dy = nc_file@DY | 
						|
 | 
						|
       uh_opt = True | 
						|
       uh_opt@uhmnhgt = 2000. | 
						|
       uh_opt@uhmxhgt = 5000. | 
						|
       dim_vars = dimsizes(varin) | 
						|
 | 
						|
       print("Calculating updraft helicity") | 
						|
       if(dim_vars .eq. 1) then | 
						|
         print("  Using defaults for the integration limits") | 
						|
       end if | 
						|
        | 
						|
       if(dim_vars .eq. 2) then | 
						|
         print("  Please enter both the minimum and maximum integration limits") | 
						|
         print("  Going to use defaults for the integration limits") | 
						|
       end if | 
						|
        | 
						|
       if(dim_vars .eq. 3) then | 
						|
         if ( stringtofloat(varin(1)) .lt. 1000. ) then | 
						|
           print("  Integration limits needs to be greater than 1000 meter") | 
						|
           print("  Going to use defaults for the integration limits") | 
						|
         else | 
						|
           uh_opt@uhmnhgt = stringtofloat(varin(1)) | 
						|
           uh_opt@uhmxhgt = stringtofloat(varin(2)) | 
						|
           print("  Setting custom integration limits") | 
						|
         end if | 
						|
       end if | 
						|
        | 
						|
       print("  min = "+uh_opt@uhmnhgt+" max = "+uh_opt@uhmxhgt) | 
						|
       uh = wrf_updraft_helicity(zp, mapfct, ua, va, w, dx, dy, uh_opt) | 
						|
       delete(uh_opt) | 
						|
        | 
						|
       return(uh) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "twb" ) then | 
						|
       ; Wet bulb temperature | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T | 
						|
           P  = nc_file->P | 
						|
           PB = nc_file->PB | 
						|
           QV = nc_file->QVAPOR | 
						|
         else | 
						|
           T  = file_handle[:]->T | 
						|
           P  = file_handle[:]->P | 
						|
           PB = file_handle[:]->PB | 
						|
           QV = file_handle[:]->QVAPOR | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T(time_in,:,:,:) | 
						|
           P  = nc_file->P(time_in,:,:,:) | 
						|
           PB = nc_file->PB(time_in,:,:,:) | 
						|
           QV = nc_file->QVAPOR(time_in,:,:,:) | 
						|
         else | 
						|
           T  = file_handle[:]->T(time_in,:,:,:) | 
						|
           P  = file_handle[:]->P(time_in,:,:,:) | 
						|
           PB = file_handle[:]->PB(time_in,:,:,:) | 
						|
           QV = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
         end if | 
						|
       end if | 
						|
       T = T + 300. | 
						|
       P = P + PB | 
						|
       t = wrf_tk(P,T) | 
						|
 | 
						|
       twb = wrf_wetbulb(P,t,QV) | 
						|
 | 
						|
       delete_VarAtts(T,(/"description"/)) | 
						|
       copy_VarAtts(T,twb) | 
						|
       return(twb) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "omg" ) then | 
						|
       ; Omega | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T | 
						|
           P  = nc_file->P | 
						|
           W  = nc_file->W | 
						|
           PB = nc_file->PB | 
						|
           QV = nc_file->QVAPOR | 
						|
         else | 
						|
           T  = file_handle[:]->T | 
						|
           P  = file_handle[:]->P | 
						|
           W  = file_handle[:]->W | 
						|
           PB = file_handle[:]->PB | 
						|
           QV = file_handle[:]->QVAPOR | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T(time_in,:,:,:) | 
						|
           P  = nc_file->P(time_in,:,:,:) | 
						|
           W  = nc_file->W(time_in,:,:,:) | 
						|
           PB = nc_file->PB(time_in,:,:,:) | 
						|
           QV = nc_file->QVAPOR(time_in,:,:,:) | 
						|
         else | 
						|
           T  = file_handle[:]->T(time_in,:,:,:) | 
						|
           P  = file_handle[:]->P(time_in,:,:,:) | 
						|
           W  = file_handle[:]->W(time_in,:,:,:) | 
						|
           PB = file_handle[:]->PB(time_in,:,:,:) | 
						|
           QV = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
         end if | 
						|
       end if | 
						|
       T = T + 300. | 
						|
       P = P + PB | 
						|
       t = wrf_tk(P,T) | 
						|
       wa = wrf_user_unstagger(W,W@stagger) | 
						|
 | 
						|
       omg = wrf_omega(QV,t,wa,P) | 
						|
 | 
						|
       delete_VarAtts(T,(/"description","units"/)) | 
						|
       copy_VarAtts(T,omg) | 
						|
       return(omg) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if( variable .eq. "tv" ) then | 
						|
       ; Virtual temperature | 
						|
       if ( time .eq. -1 ) then | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T | 
						|
           P  = nc_file->P | 
						|
           PB = nc_file->PB | 
						|
           QV = nc_file->QVAPOR | 
						|
         else | 
						|
           T  = file_handle[:]->T | 
						|
           P  = file_handle[:]->P | 
						|
           PB = file_handle[:]->PB | 
						|
           QV = file_handle[:]->QVAPOR | 
						|
         end if | 
						|
       else | 
						|
         if(ISFILE) then | 
						|
           T  = nc_file->T(time_in,:,:,:) | 
						|
           P  = nc_file->P(time_in,:,:,:) | 
						|
           PB = nc_file->PB(time_in,:,:,:) | 
						|
           QV = nc_file->QVAPOR(time_in,:,:,:) | 
						|
         else | 
						|
           T  = file_handle[:]->T(time_in,:,:,:) | 
						|
           P  = file_handle[:]->P(time_in,:,:,:) | 
						|
           PB = file_handle[:]->PB(time_in,:,:,:) | 
						|
           QV = file_handle[:]->QVAPOR(time_in,:,:,:) | 
						|
         end if | 
						|
       end if | 
						|
       T = T + 300. | 
						|
       P = P + PB | 
						|
       t = wrf_tk(P,T) | 
						|
 | 
						|
       tv = wrf_virtual_temp(t,QV) | 
						|
 | 
						|
       delete_VarAtts(T,(/"description"/)) | 
						|
       copy_VarAtts(T,tv) | 
						|
       return(tv) | 
						|
  end if | 
						|
 | 
						|
  if( variable .eq. "ctt") then | 
						|
      if ( time .eq. -1 ) then | 
						|
         explicit_time = 0 | 
						|
         if(ISFILE) then | 
						|
            P     = nc_file->P | 
						|
            PB    = nc_file->PB | 
						|
            T     = nc_file->T | 
						|
 | 
						|
;geopotential height | 
						|
            PHB   = nc_file->PHB | 
						|
            PH    = nc_file->PH | 
						|
 | 
						|
            if(isfilevar(nc_file,"QVAPOR")) then | 
						|
               qvp =  nc_file->QVAPOR * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               print("wrf_user_getvar: QVAPOR is needed to calculate the cloud top temperature.") | 
						|
               print("It has not been found in the data set.") | 
						|
               exit | 
						|
            end if | 
						|
 | 
						|
 | 
						|
            haveqci = 1 | 
						|
            if(isfilevar(nc_file,"QICE")) then | 
						|
               qci = nc_file->QICE * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               qci = new( (/Pdims(0),Pdims(1),Pdims(2),Pdims(3)/),float) | 
						|
               haveqci = 0 | 
						|
            end if | 
						|
 | 
						|
 | 
						|
            if(isfilevar(nc_file,"QCLOUD")) then | 
						|
               qcw = nc_file->QCLOUD * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               print("wrf_user_getvar: QCLOUD is needed to calculate the cloud top temperature.") | 
						|
               print("It has not been found in the data set.") | 
						|
               exit | 
						|
            end if | 
						|
 | 
						|
            ter = nc_file->HGT(0,:,:) | 
						|
 | 
						|
         else ; the else for ISFILE | 
						|
            P      = file_handle[:]->P | 
						|
            PB     = file_handle[:]->PB | 
						|
            T      = file_handle[:]->T | 
						|
            PHB    = file_handle[:]->PHB | 
						|
            PH     = file_handle[:]->PH | 
						|
            nc_file =  file_handle[0] | 
						|
            ter    = nc_file->HGT(0,:,:) | 
						|
            if(isfilevar(nc_file,"QVAPOR")) then | 
						|
               qvp = file_handle[:]->QVAPOR * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               print("wrf_user_getvar: QVAPOR is needed to calculate the cloud top temperature.") | 
						|
               print("It has not been found in the data set.") | 
						|
               exit | 
						|
            end if  | 
						|
  | 
						|
            haveqci = 1 | 
						|
            if(isfilevar(nc_file,"QICE")) then | 
						|
               qci = file_handle[:]->QICE * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               qci = new( (/Pdims(0),Pdims(1),Pdims(2),Pdims(3)/),float) | 
						|
               haveqci = 0 | 
						|
            end if | 
						|
 | 
						|
 | 
						|
            if(isfilevar(nc_file,"QCLOUD")) then | 
						|
               qcw = file_handle[:]->QCLOUD * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               print("wrf_user_getvar: QCLOUD is needed to calculate the cloud top temperature.") | 
						|
               print("It has not been found in the data set.") | 
						|
               exit | 
						|
            end if | 
						|
 | 
						|
         end if ;if ISFILE | 
						|
       else     ;the else for time = -1 | 
						|
          if(ISFILE) then | 
						|
            explicit_time = 1 | 
						|
            P     = nc_file->P(time_in,:,:,:) | 
						|
            PB    = nc_file->PB(time_in,:,:,:) | 
						|
            T     = nc_file->T(time_in,:,:,:) | 
						|
 | 
						|
;geopotential height | 
						|
            PHB   = nc_file->PHB(time_in,:,:,:) | 
						|
            PH    = nc_file->PH(time_in,:,:,:) | 
						|
 | 
						|
            if(isfilevar(nc_file,"QVAPOR")) then | 
						|
               qvp =  nc_file->QVAPOR(time_in,:,:,:) * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               print("wrf_user_getvar: QVAPOR is needed to calculate the cloud top temperature.") | 
						|
               print("It has not been found in the data set") | 
						|
               exit | 
						|
            end if | 
						|
 | 
						|
 | 
						|
            haveqci = 1 | 
						|
            if(isfilevar(nc_file,"QICE")) then | 
						|
               qci = nc_file->QICE(time_in,:,:,:) * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               qci = new( (/Pdims(0),Pdims(1),Pdims(2),Pdims(3)/),float) | 
						|
               haveqci = 0 | 
						|
            end if | 
						|
 | 
						|
 | 
						|
            if(isfilevar(nc_file,"QCLOUD")) then | 
						|
               qcw = nc_file->QCLOUD(time_in,:,:,:) * 1000.  ; kg/kg -> g/kg | 
						|
            else | 
						|
               print("wrf_user_getvar: QCLOUD is needed to calculate the cloud top temperature.") | 
						|
               print("It has not been found in the data set.") | 
						|
               exit | 
						|
            end if | 
						|
 | 
						|
            ter = nc_file->HGT(0,:,:) | 
						|
          end if ;end if for ISFILE | 
						|
       end if   ;time = -1 | 
						|
 | 
						|
 | 
						|
;Get total pressure | 
						|
         Pdims = dimsizes(P) | 
						|
         pres  = P + PB | 
						|
         pres  = pres * 0.01 | 
						|
 | 
						|
;Get temperature in degrees K | 
						|
         T     = T +300. | 
						|
         tk    = wrf_tk( pres , T ) | 
						|
 | 
						|
;Get geopotential height on mass points | 
						|
         stag_ght   = PH | 
						|
         stag_ght   = (PHB + PH)/9.81 | 
						|
         ght        =  wrf_user_unstagger(stag_ght,PHB@stagger) | 
						|
 | 
						|
         fctt = wrf_ctt(pres,tk,qci,qcw,qvp,ght,ter,haveqci) | 
						|
; fctt will have description, units, and dimension names attached | 
						|
       delete_VarAtts(T,(/"description","units"/)) | 
						|
       copy_VarAtts(T,fctt) | 
						|
       return(fctt) | 
						|
  end if         ;variable is ctt | 
						|
  | 
						|
 | 
						|
  if( any( variable .eq. (/"ter","HGT","HGT_M"/) ) ) then | 
						|
    variable = "HGT"  | 
						|
    if(.not. isfilevar(nc_file,"HGT")) then | 
						|
      variable = "HGT_M" | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"lat","XLAT","XLAT_M"/) ) ) then | 
						|
    variable = "XLAT"  | 
						|
    if(.not. isfilevar(nc_file,"XLAT")) then | 
						|
      variable = "XLAT_M" | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"lon","long","XLONG","XLONG_M"/) ) ) then | 
						|
    variable = "XLONG"  | 
						|
    if(.not. isfilevar(nc_file,"XLONG")) then | 
						|
      variable = "XLONG_M" | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if( any( variable .eq. (/"times"/) ) ) then | 
						|
    if ( time .eq. -1 ) then | 
						|
      if(ISFILE) then | 
						|
        var = nc_file->Times | 
						|
      else | 
						|
        var = file_handle[:]->Times | 
						|
      end if | 
						|
    else | 
						|
      if(ISFILE) then | 
						|
        var = nc_file->Times(time_in,:) | 
						|
      else | 
						|
        var = file_handle[:]->Times(time_in,:) | 
						|
      end if | 
						|
    end if | 
						|
    dims = dimsizes(var) | 
						|
    times = new(dims(0),string) | 
						|
    do i=0,dims(0)-1 | 
						|
      times(i) = chartostring(var(i,:)) | 
						|
    end do | 
						|
    times@description = "times in file" | 
						|
    return (times) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
 | 
						|
;  end of diagnostic variable list - we must want a variable already in the file.   | 
						|
 | 
						|
  if ( time .eq. -1 ) then | 
						|
    if(ISFILE) then | 
						|
      var = nc_file->$variable$ | 
						|
    else | 
						|
      var = file_handle[:]->$variable$ | 
						|
    end if | 
						|
  else | 
						|
    ;  check variable dimensionality and pull proper time  out of file | 
						|
    ndims = dimsizes(filevardimsizes(nc_file,variable)) | 
						|
    if( ndims .eq. 4) then | 
						|
      if(ISFILE) then | 
						|
        var = nc_file->$variable$(time_in,:,:,:) | 
						|
      else | 
						|
        var = file_handle[:]->$variable$(time_in,:,:,:) | 
						|
      end if | 
						|
    end if | 
						|
    if( ndims .eq. 3) then | 
						|
      if(ISFILE) then | 
						|
        var = nc_file->$variable$(time_in,:,:) | 
						|
      else | 
						|
        var = file_handle[:]->$variable$(time_in,:,:) | 
						|
      end if | 
						|
    end if | 
						|
    if( ndims .eq. 2) then | 
						|
      if(ISFILE) then | 
						|
        var = nc_file->$variable$(time_in,:) | 
						|
      else | 
						|
        var = file_handle[:]->$variable$(time_in,:) | 
						|
      end if | 
						|
    end if | 
						|
    if( ndims .eq. 1) then | 
						|
      if(ISFILE) then | 
						|
      var = nc_file->$variable$(time_in) | 
						|
      else | 
						|
      var = file_handle[:]->$variable$(time_in) | 
						|
      end if | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  return(var) | 
						|
 | 
						|
end | 
						|
 | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("wrf_user_getvar_from_files") | 
						|
function wrf_user_getvar_from_files( nc_files:string, varin[*]:string, time[*]:integer, opts_args:logical ) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  numFiles = dimsizes(nc_files) | 
						|
  f = addfiles(nc_files,"r") | 
						|
 | 
						|
  var_tmp = wrf_user_getvar(f[0],varin,-1) | 
						|
  varDims = dimsizes(var_tmp) | 
						|
  varRank = dimsizes(varDims) | 
						|
  time_req = 0 | 
						|
  time_inc = 1 | 
						|
  time_end = varDims(0)*numFiles | 
						|
  if ( dimsizes(time) .eq. 1 ) then | 
						|
    if ( time(0) .ge. 0 ) then | 
						|
      numTimes = 1 | 
						|
      time_req = time(0) | 
						|
      time_end = time(0) | 
						|
      time_inc = 1 | 
						|
    else | 
						|
      numTimes = varDims(0)*numFiles | 
						|
    end if | 
						|
  end if | 
						|
  if ( dimsizes(time) .eq. 2 ) then | 
						|
    if ( time(0) .ge. 0 ) then | 
						|
      numTimes = (time(1)-time(0))+1 | 
						|
      time_req = time(0) | 
						|
      time_end = time(1) | 
						|
      time_inc = 1 | 
						|
    else | 
						|
      numTimes = varDims(0)*numFiles | 
						|
    end if | 
						|
  end if | 
						|
  if ( dimsizes(time) .eq. 3 ) then | 
						|
    if ( time(0) .ge. 0 ) then | 
						|
      numTimes = ((time(1)-time(0))+1)/time(2) | 
						|
      time_req = time(0) | 
						|
      time_end = time(1) | 
						|
      time_inc = time(2) | 
						|
    else | 
						|
      numTimes = varDims(0)*numFiles | 
						|
    end if | 
						|
  end if | 
						|
  outtime = 0 | 
						|
  outtime_avail = 0 | 
						|
 | 
						|
 | 
						|
  if ( varRank .eq. 4 ) | 
						|
    varout = new ( (/numTimes,varDims(1),varDims(2),varDims(3)/), typeof(var_tmp) ) | 
						|
    varout = 0 | 
						|
    do it = 0,varDims(0)-1 | 
						|
      if ( (outtime_avail.eq.time_req) .and. (time_req.le.time_end) ) then | 
						|
        varout(outtime,:,:,:) = var_tmp(it,:,:,:) | 
						|
        outtime = outtime + 1 | 
						|
        time_req = time_req + time_inc | 
						|
      end if | 
						|
      outtime_avail = outtime_avail + 1 | 
						|
    end do | 
						|
    delete(var_tmp) | 
						|
    do ifil = 1,numFiles-1 | 
						|
      var_tmp = wrf_user_getvar(f[ifil],varin,-1) | 
						|
      dimLoop = dimsizes(var_tmp) | 
						|
      do it = 0,dimLoop(0)-1 | 
						|
        if ( (outtime_avail.eq.time_req) .and. (time_req.le.time_end) ) then | 
						|
          varout(outtime,:,:,:) = var_tmp(it,:,:,:) | 
						|
          outtime = outtime + 1 | 
						|
          time_req = time_req + time_inc | 
						|
        end if | 
						|
        outtime_avail = outtime_avail + 1 | 
						|
      end do | 
						|
      delete(var_tmp) | 
						|
    end do | 
						|
  end if | 
						|
  if ( varRank .eq. 3 ) | 
						|
    varout = new ( (/numTimes,varDims(1),varDims(2)/), typeof(var_tmp) ) | 
						|
    varout = 0 | 
						|
    do it = 0,varDims(0)-1 | 
						|
      if ( (outtime_avail.eq.time_req) .and. (time_req.le.time_end) ) then | 
						|
        varout(outtime,:,:) = var_tmp(it,:,:) | 
						|
        outtime = outtime + 1 | 
						|
        time_req = time_req + time_inc | 
						|
      end if | 
						|
      outtime_avail = outtime_avail + 1 | 
						|
    end do | 
						|
    delete(var_tmp) | 
						|
    do ifil = 1,numFiles-1 | 
						|
      var_tmp = wrf_user_getvar(f[ifil],varin,-1) | 
						|
      dimLoop = dimsizes(var_tmp) | 
						|
      do it = 0,dimLoop(0)-1 | 
						|
        if ( (outtime_avail.eq.time_req) .and. (time_req.le.time_end) ) then | 
						|
          varout(outtime,:,:) = var_tmp(it,:,:) | 
						|
          outtime = outtime + 1 | 
						|
          time_req = time_req + time_inc | 
						|
        end if | 
						|
        outtime_avail = outtime_avail + 1 | 
						|
      end do | 
						|
      delete(var_tmp) | 
						|
    end do | 
						|
  end if | 
						|
  if ( varRank .eq. 2 ) | 
						|
    varout = new ( (/numTimes,varDims(1)/), typeof(var_tmp) ) | 
						|
    if ( typeof(var_tmp) .eq. "float" .or. typeof(var_tmp) .eq. "integer" ) then | 
						|
      varout = 0 | 
						|
    end if | 
						|
    do it = 0,varDims(0)-1 | 
						|
      if ( (outtime_avail.eq.time_req) .and. (time_req.le.time_end) ) then | 
						|
        varout(outtime,:) = var_tmp(it,:) | 
						|
        outtime = outtime + 1 | 
						|
        time_req = time_req + time_inc | 
						|
      end if | 
						|
      outtime_avail = outtime_avail + 1 | 
						|
    end do | 
						|
    delete(var_tmp) | 
						|
    do ifil = 1,numFiles-1 | 
						|
      var_tmp = wrf_user_getvar(f[ifil],varin,-1) | 
						|
      dimLoop = dimsizes(var_tmp) | 
						|
      do it = 0,dimLoop(0)-1 | 
						|
        if ( (outtime_avail.eq.time_req) .and. (time_req.le.time_end) ) then | 
						|
          varout(outtime,:) = var_tmp(it,:) | 
						|
          outtime = outtime + 1 | 
						|
          time_req = time_req + time_inc | 
						|
        end if | 
						|
        outtime_avail = outtime_avail + 1 | 
						|
      end do | 
						|
      delete(var_tmp) | 
						|
    end do | 
						|
  end if | 
						|
  if ( varRank .eq. 1 ) | 
						|
    varout = new ( (/numTimes/), typeof(var_tmp) ) | 
						|
    if ( typeof(var_tmp) .eq. "float" .or. typeof(var_tmp) .eq. "integer" ) then | 
						|
      varout = 0 | 
						|
    end if | 
						|
    do it = 0,varDims(0)-1 | 
						|
      if ( (outtime_avail.eq.time_req) .and. (time_req.le.time_end) ) then | 
						|
        varout(outtime) = var_tmp(it) | 
						|
        outtime = outtime + 1 | 
						|
        time_req = time_req + time_inc | 
						|
      end if | 
						|
      outtime_avail = outtime_avail + 1 | 
						|
    end do | 
						|
    delete(var_tmp) | 
						|
    do ifil = 1,numFiles-1 | 
						|
      var_tmp = wrf_user_getvar(f[ifil],varin,-1) | 
						|
      dimLoop = dimsizes(var_tmp) | 
						|
      do it = 0,dimLoop(0)-1 | 
						|
        if ( (outtime_avail.eq.time_req) .and. (time_req.le.time_end) ) then | 
						|
          varout(outtime) = var_tmp(it) | 
						|
          outtime = outtime + 1 | 
						|
          time_req = time_req + time_inc | 
						|
        end if | 
						|
        outtime_avail = outtime_avail + 1 | 
						|
      end do | 
						|
      delete(var_tmp) | 
						|
    end do | 
						|
  end if | 
						|
 | 
						|
  return(varout) | 
						|
end | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
; This function was modified in May 2011 to allow a list of files. | 
						|
; | 
						|
undef("wrf_user_list_times") | 
						|
function wrf_user_list_times( nc_file ) | 
						|
 | 
						|
local times, times_in_file, dims, i | 
						|
begin | 
						|
 | 
						|
;---As of NCL V6.0.0, wrf_user_getvar can now handle a file or a list of files. | 
						|
  if(all(typeof(nc_file).ne.(/"file","list"/))) then | 
						|
    print("wrf_user_list_times: error: the input argument must be a file or a list of files opened with addfile or addfiles") | 
						|
    return | 
						|
  end if | 
						|
 | 
						|
  if(typeof(nc_file).eq."file") then | 
						|
    times_in_file = nc_file->Times | 
						|
  else | 
						|
    times_in_file = nc_file[:]->Times | 
						|
  end if | 
						|
  dims = dimsizes(times_in_file) | 
						|
  times = new(dims(0),string) | 
						|
  do i=0,dims(0)-1 | 
						|
    times(i) = chartostring(times_in_file(i,:)) | 
						|
  end do | 
						|
  times@description = "times in file" | 
						|
  print(times) | 
						|
  return(times) | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_user_latlon_to_ij") | 
						|
function wrf_user_latlon_to_ij( nc_file:file, latitude:numeric, \ | 
						|
                                longitude:numeric ) | 
						|
 | 
						|
begin | 
						|
  WE       = "WEST-EAST_GRID_DIMENSION" | 
						|
  SN       = "SOUTH-NORTH_GRID_DIMENSION" | 
						|
  wedim    = nc_file@$WE$ | 
						|
  sndim    = nc_file@$SN$ | 
						|
 | 
						|
  if(isfilevar(nc_file,"XLAT")) | 
						|
    XLAT  = nc_file->XLAT(0,:,:) | 
						|
    XLONG = nc_file->XLONG(0,:,:) | 
						|
  else | 
						|
    XLAT  = nc_file->XLAT_M(0,:,:) | 
						|
    XLONG = nc_file->XLONG_M(0,:,:) | 
						|
  end if | 
						|
 | 
						|
  loc = wrf_latlon_to_ij( XLAT, XLONG, latitude, longitude ) | 
						|
 | 
						|
  loc!0 = "j & i locations" | 
						|
  return(loc) | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_user_ll_to_ij") | 
						|
function wrf_user_ll_to_ij( file_handle, longitude:numeric, latitude:numeric, \ | 
						|
                            opts_args:logical ) | 
						|
 | 
						|
begin | 
						|
; | 
						|
; As of NCL V6.0.0, wrf_user_ll_to_ij can now handle a file  | 
						|
; or a list of files. | 
						|
; | 
						|
  if(typeof(file_handle).eq."file") then | 
						|
    ISFILE = True | 
						|
    nc_file = file_handle | 
						|
  else if(typeof(file_handle).eq."list") then | 
						|
    ISFILE = False | 
						|
    nc_file = file_handle[0] | 
						|
  else | 
						|
    print("wrf_user_ll_to_ij: error: the first argument must be a file or a list of files opened with addfile or addfiles") | 
						|
    return | 
						|
  end if | 
						|
  end if | 
						|
 | 
						|
  opts = opts_args | 
						|
  useT  = get_res_value(opts,"useTime",0) | 
						|
  returnI= get_res_value(opts,"returnInt",True) | 
						|
 | 
						|
  res = True | 
						|
  res@MAP_PROJ  = nc_file@MAP_PROJ | 
						|
  res@TRUELAT1  = nc_file@TRUELAT1 | 
						|
  res@TRUELAT2  = nc_file@TRUELAT2 | 
						|
  res@STAND_LON = nc_file@STAND_LON | 
						|
  res@DX        = nc_file@DX | 
						|
  res@DY        = nc_file@DY | 
						|
 | 
						|
  if (res@MAP_PROJ .eq. 6) then | 
						|
    res@POLE_LAT  = nc_file@POLE_LAT | 
						|
    res@POLE_LON  = nc_file@POLE_LON | 
						|
    res@LATINC = (res@DY*360.)/2.0/3.141592653589793/6370000. | 
						|
    res@LONINC = (res@DX*360.)/2.0/3.141592653589793/6370000. | 
						|
  else | 
						|
    res@POLE_LAT = 90.0 | 
						|
    res@POLE_LON =  0.0 | 
						|
    res@LATINC = 0.0 | 
						|
    res@LONINC = 0.0 | 
						|
  end if | 
						|
 | 
						|
  if(isfilevar(nc_file,"XLAT")) | 
						|
    if(ISFILE) then | 
						|
      XLAT  = nc_file->XLAT(useT,:,:) | 
						|
      XLONG = nc_file->XLONG(useT,:,:) | 
						|
    else | 
						|
      XLAT  = file_handle[useT]->XLAT | 
						|
      XLONG = file_handle[useT]->XLONG | 
						|
    end if | 
						|
  else | 
						|
    if(ISFILE) then | 
						|
      XLAT  = nc_file->XLAT_M(useT,:,:) | 
						|
      XLONG = nc_file->XLONG_M(useT,:,:) | 
						|
    else | 
						|
      XLAT  = file_handle[useT]->XLAT_M | 
						|
      XLONG = file_handle[useT]->XLONG_M | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if(dimsizes(dimsizes(XLAT)).eq.2) then | 
						|
; Rank 2 | 
						|
    res@REF_LAT = XLAT(0,0) | 
						|
    res@REF_LON = XLONG(0,0) | 
						|
  else | 
						|
; Rank 3 | 
						|
    res@REF_LAT = XLAT(0,0,0) | 
						|
    res@REF_LON = XLONG(0,0,0) | 
						|
  end if | 
						|
  res@KNOWNI  = 1.0 | 
						|
  res@KNOWNJ  = 1.0 | 
						|
 | 
						|
  loc = wrf_ll_to_ij (longitude, latitude, res) | 
						|
 | 
						|
  if ( returnI  ) then | 
						|
    loci = new(dimsizes(loc),integer) | 
						|
    ;loci@_FillValue = default_fillvalue("integer")   ; was -999 | 
						|
    loci = tointeger(loc + .5) | 
						|
    loci!0 = loc!0 | 
						|
    return(loci) | 
						|
  else | 
						|
    return(loc) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_user_ij_to_ll") | 
						|
function wrf_user_ij_to_ll( file_handle, i:numeric, j:numeric, \ | 
						|
                            opts_args:logical ) | 
						|
 | 
						|
begin | 
						|
; | 
						|
; As of NCL V6.0.0, wrf_user_ll_to_ij can now handle a file  | 
						|
; or a list of files. | 
						|
; | 
						|
  if(typeof(file_handle).eq."file") then | 
						|
    ISFILE = True | 
						|
    nc_file = file_handle | 
						|
  else if(typeof(file_handle).eq."list") then | 
						|
    ISFILE = False | 
						|
    nc_file = file_handle[0] | 
						|
  else | 
						|
    print("wrf_user_ij_to_ll: error: the first argument must be a file or a list of files opened with addfile or addfiles") | 
						|
    return | 
						|
  end if | 
						|
  end if | 
						|
 | 
						|
  opts = opts_args | 
						|
  useT  = get_res_value(opts,"useTime",0) | 
						|
 | 
						|
  res = True | 
						|
  res@MAP_PROJ  = nc_file@MAP_PROJ | 
						|
  res@TRUELAT1  = nc_file@TRUELAT1 | 
						|
  res@TRUELAT2  = nc_file@TRUELAT2 | 
						|
  res@STAND_LON = nc_file@STAND_LON | 
						|
  res@DX        = nc_file@DX | 
						|
  res@DY        = nc_file@DY | 
						|
 | 
						|
  if (res@MAP_PROJ .eq. 6) then | 
						|
    res@POLE_LAT  = nc_file@POLE_LAT | 
						|
    res@POLE_LON  = nc_file@POLE_LON | 
						|
    res@LATINC = (res@DY*360.)/2.0/3.141592653589793/6370000. | 
						|
    res@LONINC = (res@DX*360.)/2.0/3.141592653589793/6370000. | 
						|
  else | 
						|
    res@POLE_LAT = 90.0 | 
						|
    res@POLE_LON =  0.0 | 
						|
    res@LATINC = 0.0 | 
						|
    res@LONINC = 0.0 | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if(isfilevar(nc_file,"XLAT")) then | 
						|
    if(ISFILE) then | 
						|
      XLAT  = nc_file->XLAT(useT,:,:) | 
						|
      XLONG = nc_file->XLONG(useT,:,:) | 
						|
    else | 
						|
      XLAT  = file_handle[useT]->XLAT | 
						|
      XLONG = file_handle[useT]->XLONG | 
						|
    end if | 
						|
  else | 
						|
    if(ISFILE) then | 
						|
      XLAT  = nc_file->XLAT_M(useT,:,:) | 
						|
      XLONG = nc_file->XLONG_M(useT,:,:) | 
						|
    else | 
						|
      XLAT  = file_handle[useT]->XLAT_M | 
						|
      XLONG = file_handle[useT]->XLONG_M | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  if(dimsizes(dimsizes(XLAT)).eq.2) then | 
						|
; Rank 2 | 
						|
    res@REF_LAT = XLAT(0,0) | 
						|
    res@REF_LON = XLONG(0,0) | 
						|
  else | 
						|
; Rank 3 | 
						|
    res@REF_LAT = XLAT(0,0,0) | 
						|
    res@REF_LON = XLONG(0,0,0) | 
						|
  end if | 
						|
  res@KNOWNI  = 1.0 | 
						|
  res@KNOWNJ  = 1.0 | 
						|
 | 
						|
  loc = wrf_ij_to_ll (i,j,res) | 
						|
 | 
						|
  return(loc) | 
						|
 | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("wrf_user_vert_interp") | 
						|
function wrf_user_vert_interp(file_handle,field:numeric, \ | 
						|
                              vert_coordinate[1]:string, \ | 
						|
                              interp_levels[*]:numeric,opts[1]:logical) | 
						|
local valid_vert_coords, nc_file, valid_field_types | 
						|
begin | 
						|
 | 
						|
  valid_vert_coords = (/"pressure","pres","ght_msl","ght_agl","theta","theta-e"/) | 
						|
  if(.not.any(vert_coordinate.eq.valid_vert_coords)) then | 
						|
    print("wrf_user_vert_interp: Unrecognized vertical coordinate.") | 
						|
    print("   Accepted vertical coordinates are:") | 
						|
    print(     "pressure, pres   hPa") | 
						|
    print(     "ght_msl          km") | 
						|
    print(     "ght_agl          km") | 
						|
    print(     "theta            K") | 
						|
    print(     "theta-e          K") | 
						|
    exit | 
						|
  end if | 
						|
 | 
						|
  if(typeof(file_handle).eq."file") then | 
						|
    ISFILE = True | 
						|
    nc_file = file_handle | 
						|
  else if(typeof(file_handle).eq."list") then | 
						|
    ISFILE = False | 
						|
    nc_file = file_handle[0] | 
						|
  else | 
						|
    print("wrf_user_vert_interp: error: the first argument must be a file or a list of files opened with addfile or addfiles") | 
						|
    return | 
						|
  end if | 
						|
  end if | 
						|
 | 
						|
  rgas    = 287.04     ;J/K/kg | 
						|
  ussalr  = .0065      ; deg C per m | 
						|
  sclht   = rgas*256./9.81 | 
						|
   | 
						|
;read grid sizes from the nc_file.  Check to make | 
						|
;sure that we don't have a staggered field. | 
						|
  dNames      = getvardims(nc_file) | 
						|
  dSizes      = getfiledimsizes(nc_file) | 
						|
  thedims     = dimsizes(dSizes) | 
						|
  number_dims = thedims(0) | 
						|
 | 
						|
  ew = dSizes(ind(dNames .eq. "west_east")) | 
						|
  ns = dSizes(ind(dNames .eq. "south_north")) | 
						|
  nz = dSizes(ind(dNames .eq. "bottom_top")) | 
						|
 | 
						|
  field_dims     = dimsizes(field) | 
						|
  num_field_dims = dimsizes(field_dims) | 
						|
 | 
						|
 if(num_field_dims .lt. 3 .or. num_field_dims .gt. 4) then | 
						|
    print("wrf_user_vert_interp: We can only interpolate a 3D or 4D field") | 
						|
    exit | 
						|
 end if | 
						|
 | 
						|
; Check to see if the field comes in unstaggered. | 
						|
  if(field_dims(num_field_dims-3) .ne. nz) then | 
						|
     print("wrf_user_vert_interp: Please unstagger the field in the vertical") | 
						|
     exit | 
						|
  end if | 
						|
 | 
						|
  if(field_dims(num_field_dims-2) .ne. ns .or. \ | 
						|
     field_dims(num_field_dims-1) .ne. ew) then | 
						|
     print("wrf_user_vert_interp: Please unstagger the field") | 
						|
     exit | 
						|
  end if | 
						|
 | 
						|
; See what options we have | 
						|
  extrap_field    = get_res_value_keep(opts,"extrapolate",False) | 
						|
  field_type      = str_lower(get_res_value_keep(opts,"field_type","none")) | 
						|
  log_of_Pressure = get_res_value_keep(opts,"logP",False) | 
						|
  debug           = get_res_value_keep(opts,"debug",False) | 
						|
   | 
						|
  valid_field_types = (/"none","pressure","pres","p","z","t","ght"/) | 
						|
  if(.not.any(field_type.eq.valid_field_types)) then | 
						|
    print("wrf_user_vert_interp: Unrecognized field type.") | 
						|
    print("Valid field types are: " + str_join(valid_field_types,", ")) | 
						|
    exit | 
						|
  end if | 
						|
 | 
						|
  if(log_of_Pressure) then | 
						|
     logP = 1      ; this is for passing into Fortran | 
						|
  else | 
						|
     logP = 0 | 
						|
  end if | 
						|
 | 
						|
  icase  = 0 | 
						|
  extrap = 0   ; This is for passing into Fortran | 
						|
  if(extrap_field) then | 
						|
     extrap = 1 | 
						|
     if(any(field_type .eq. (/"p","pres","pressure"/))) then | 
						|
        icase = 1 | 
						|
     end if | 
						|
 | 
						|
     if(field_type .eq. "z") then | 
						|
        icase = 2 | 
						|
     end if | 
						|
 | 
						|
     if(field_type .eq. "ght") then | 
						|
        icase = 2 | 
						|
     end if | 
						|
; | 
						|
; For temperature we may have just temperature, potential temperature | 
						|
; or equivalent potential temperature.  Check the field description attribute  | 
						|
; to see which one we have. | 
						|
; | 
						|
     if(field_type .eq. "t") then | 
						|
        if(isatt(field,"description")) then | 
						|
 | 
						|
           if(field@description .eq. "Temperature") then | 
						|
              if(field@units .eq. "C") then | 
						|
                 icase = 3 | 
						|
              else | 
						|
                 icase = 4 | 
						|
              end if | 
						|
           end if | 
						|
 | 
						|
           if(field@description .eq. "Potential Temperature (theta) ") then | 
						|
              icase = 5 | 
						|
           end if | 
						|
 | 
						|
           if(field@description .eq. "Equivalent Potential Temperature") then | 
						|
              icase = 6 | 
						|
           end if | 
						|
        end if ;the endif for checking for the field description attribute | 
						|
 | 
						|
     end if;end if for the field_type being T or t | 
						|
 | 
						|
 | 
						|
  end if; the endif for extrap_field .eq. True | 
						|
 | 
						|
 | 
						|
  numlevels = dimsizes(interp_levels) | 
						|
 | 
						|
;We will need some basic fields for the interpolation | 
						|
;regardless of the field requested. Get all time periods | 
						|
;of the fields. | 
						|
  if(ISFILE) then | 
						|
      P     = nc_file->P + nc_file->PB | 
						|
      Pdims = dimsizes(P) | 
						|
      ght   = wrf_user_getvar(nc_file,"height",-1) | 
						|
      tk    = wrf_user_getvar(nc_file,"tk",-1) | 
						|
      qvp   = nc_file->QVAPOR | 
						|
      terht = nc_file->HGT | 
						|
      sfp   = nc_file->PSFC * 0.01 | 
						|
    else | 
						|
      P     = file_handle[:]->P + file_handle[:]->PB | 
						|
      Pdims = dimsizes(P) | 
						|
      tmpz  = file_handle[:]->PH | 
						|
      PHB   = file_handle[:]->PHB | 
						|
      tmpz  = (tmpz + PHB)/9.81 | 
						|
      ght   = wrf_user_unstagger(tmpz,"Z") | 
						|
      T     = file_handle[:]->T | 
						|
      T     = T + 300. | 
						|
      tk    = wrf_tk( P , T ) | 
						|
      qvp   = file_handle[:]->QVAPOR | 
						|
      terht = file_handle[:] ->HGT | 
						|
      sfp   = file_handle[:] ->PSFC * 0.01 | 
						|
    end if | 
						|
    smsfp = sfp | 
						|
    wrf_smooth_2d(smsfp,3)   | 
						|
 | 
						|
       | 
						|
;Initialize an array for the vertical coordinate | 
						|
 ntimes  = Pdims(0) | 
						|
 | 
						|
;Get the vertical coordinate type | 
						|
  vcor  = 0 | 
						|
  logp  = 0 | 
						|
  if(any(vert_coordinate .eq. (/"pressure","pres"/))) then | 
						|
     vcor = 1 | 
						|
     vcord_array = P * 0.01 | 
						|
  end if | 
						|
 | 
						|
  if(vert_coordinate .eq. "ght_msl") then | 
						|
    vcor = 2 | 
						|
    vcord_array = exp(-ght/sclht) | 
						|
  end if | 
						|
 | 
						|
  if(vert_coordinate .eq. "ght_agl") then | 
						|
    vcor = 3 | 
						|
    rtemp       = new( (/nz,ns,ew/),float) | 
						|
    vcord_array = new((/ntimes,nz,ns,ew/),float) | 
						|
    do it = 0, ntimes - 1 | 
						|
       do ilev = 0,nz-1 | 
						|
          rtemp(ilev,:,:) = ght(it,ilev,:,:) - terht(0,:,:) | 
						|
       end do | 
						|
       vcord_array(it,:,:,:) = exp(-rtemp/sclht) | 
						|
    end do | 
						|
    delete(rtemp) | 
						|
  end if | 
						|
 | 
						|
  if(vert_coordinate .eq. "theta")   then | 
						|
     vcor = 4 | 
						|
     idir   = 1        | 
						|
     icorsw = 0        | 
						|
     delta  = 0.01     | 
						|
     if(ISFILE) then         | 
						|
        coriolis   = nc_file->F(0,:,:)    | 
						|
        theta      = wrf_user_getvar(nc_file,"theta",-1) | 
						|
     else | 
						|
        coriolis   =  file_handle[0]->F(0,:,:)    | 
						|
        theta      = T | 
						|
     end if         | 
						|
     preshPa    = P * 0.01 | 
						|
     vcord_array = wrf_monotonic(theta,preshPa,coriolis,idir,delta,icorsw)       | 
						|
; | 
						|
;  We only extrapolate temperature fields below ground if we are interpolating | 
						|
;  to pressure or height vertical surfaces. | 
						|
; | 
						|
     icase = 0        | 
						|
  end if | 
						|
 | 
						|
  if(vert_coordinate .eq. "theta-e") then | 
						|
     vcor   = 5 | 
						|
     icorsw = 0 | 
						|
     idir   = 1  | 
						|
     delta  = 0.01  | 
						|
     if(ISFILE) then   | 
						|
        coriolis = nc_file->F(0,:,:)  | 
						|
        eqpot    = wrf_user_getvar(nc_file,"eth",-1) | 
						|
     else  | 
						|
        coriolis =  file_handle[0]->F(0,:,:) | 
						|
        eqpot    = wrf_eth ( qvp, tk, P ) | 
						|
     end if | 
						|
     preshPa    = P * 0.01 | 
						|
 | 
						|
     vcord_array = wrf_monotonic(eqpot,preshPa,coriolis,idir,delta,icorsw) | 
						|
;  We only extrapolate temperature fields below ground if we are interpolating | 
						|
;  to pressure or height vertical surfaces. | 
						|
     icase = 0 | 
						|
  end if | 
						|
 | 
						|
  if(debug) then | 
						|
    print("icase = " + icase + " extrap = " + extrap + " vcor = " + vcor + " logP = " + logP) | 
						|
  end if | 
						|
 | 
						|
  field_out = wrf_vintrp(field,P,tk,qvp,ght,terht(0,:,:),sfp,smsfp,\ | 
						|
                         vcord_array,interp_levels,icase,extrap,vcor,logP) | 
						|
 | 
						|
; Add metadata to return array | 
						|
  copy_VarMeta(field,field_out) | 
						|
 | 
						|
; Add new levels as a coordinate array | 
						|
  lev_field           = num_field_dims-3 | 
						|
  field_out!lev_field = "interp_levels" | 
						|
  field_out&$field_out!lev_field$ = interp_levels(::-1)    | 
						|
  field_out@vert_interp_type = vert_coordinate | 
						|
 | 
						|
  return(field_out) | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("write_wrf_debug_info") | 
						|
procedure write_wrf_debug_info(wks[1]:graphic,data1,data2, \ | 
						|
                               debug_file[1]:string, \ | 
						|
                               wrf_opts,wrf_func_name[1]:string) | 
						|
; | 
						|
; This procedure writes resources and data variables used to | 
						|
; create a WRF plot to a NetCDF file. This file can be read | 
						|
; in later to recreate the NCL script that created that plot, | 
						|
; using gsn_xxx functions. This is for debug purposes. You can't | 
						|
; tell what resources a WRF script is using, so this is a way | 
						|
; of seeing them all in a NetCDF file. | 
						|
; | 
						|
begin | 
						|
  if(.not.isatt(wks,"WRFDebug")) then | 
						|
    first_time = True | 
						|
    wks@WRFDebug = True | 
						|
  else | 
						|
    first_time = False | 
						|
  end if | 
						|
; | 
						|
; The default will be "wrfdebug.ncl" and "wrfdebug.nc"  | 
						|
; unless otherwise specified. | 
						|
; | 
						|
  cdf_debug_file = debug_file +  ".nc" | 
						|
  ncl_debug_file = debug_file +  ".ncl" | 
						|
  res_debug_file = debug_file +  ".res" | 
						|
 | 
						|
; | 
						|
; If this is the first time writing debug information to the file, | 
						|
; then create the file and add the first set of information. | 
						|
; | 
						|
; Make sure the files don't already exist. | 
						|
; | 
						|
  if(first_time) then | 
						|
    if(fileexists(cdf_debug_file).or.fileexists(ncl_debug_file).or.\ | 
						|
       fileexists(res_debug_file)) then | 
						|
      print("write_wrf_debug_info: error: debug files '" + cdf_debug_file + "',") | 
						|
      print("'" + ncl_debug_file + "' and/or " + res_debug_file + " exist.") | 
						|
      print("Please remove file(s) and start script again.") | 
						|
      exit | 
						|
    end if | 
						|
    dbgfile = addfile(cdf_debug_file,"c") | 
						|
  else | 
						|
; | 
						|
; If this is not the first time, open the file as read/write. | 
						|
; | 
						|
    dbgfile = addfile(cdf_debug_file,"w") | 
						|
  end if | 
						|
 | 
						|
; | 
						|
; If this is not the first time, then we need to append the information. | 
						|
;   | 
						|
  if(.not.first_time) then | 
						|
; | 
						|
; The variables should be wrf_var_1, wrf_var_2, etc. We need to get the | 
						|
; highest one already in use, so we can create the next highest one. | 
						|
; | 
						|
    wrf_debug_vars = getfilevarnames(dbgfile) | 
						|
    max_num = max(stringtointeger(str_get_field(wrf_debug_vars,3,"_"))) + 1 | 
						|
  else | 
						|
    max_num = 1 | 
						|
  end if | 
						|
 | 
						|
; This will be name of the logical variable to hold all the resources | 
						|
; for this dataset. | 
						|
  wrf_res_name  = "wrf_res_" + max_num | 
						|
 | 
						|
; | 
						|
; Write the plot data to the netCDF file.  If the data contains the | 
						|
; special 2D lat2d/lon2d arrays, we have to write these as 1D arrays | 
						|
; and reconstruct them as 2D later. | 
						|
; | 
						|
  if(typeof(data1).ne."logical".and.typeof(data2).eq."logical") then | 
						|
; For non u,v data | 
						|
    wrf_data_name = "wrf_data_" + max_num | 
						|
    add_latlon2d_debug_info(data1) | 
						|
    dbgfile->$wrf_data_name$ = (/data1/)           ; Write the data | 
						|
  end if | 
						|
  if(typeof(data1).ne."logical".and.typeof(data2).ne."logical") then | 
						|
; For u,v data | 
						|
    add_latlon2d_debug_info(data1) | 
						|
    add_latlon2d_debug_info(data2) | 
						|
    wrf_data_name = "wrf_udata_" + max_num | 
						|
    dbgfile->$wrf_data_name$ = (/data1/)           ; Write the U data | 
						|
    wrf_data_name = "wrf_vdata_" + max_num | 
						|
    dbgfile->$wrf_data_name$ = (/data2/)           ; Write the V data | 
						|
  end if | 
						|
 | 
						|
; Retain the name of the wrf function that called this routine. | 
						|
  tmp = "wrf_func_name_" + max_num | 
						|
  dbgfile@$tmp$ = wrf_func_name | 
						|
 | 
						|
; | 
						|
; Get plot resources, if any. | 
						|
; | 
						|
  wattnames = getvaratts(wrf_opts) | 
						|
  if(.not.any(ismissing(wattnames))) then | 
						|
    natt = dimsizes(wattnames) | 
						|
  else | 
						|
    natt = 0 | 
						|
  end if | 
						|
 | 
						|
; | 
						|
; Check if any of the plot attributes are ones that can contain | 
						|
; big data arrays, like sfXArray, vfYArray, etc. | 
						|
; | 
						|
; If so, then write these to the netCDF file. Otherwise, write them | 
						|
; to the file as attributes. | 
						|
; | 
						|
  array_resources = (/"sfXArray","sfYArray","vfXArray","vfYArray"/) | 
						|
 | 
						|
  if(natt.gt.0) then | 
						|
    tmp_opts = 1 | 
						|
    do i=0,natt-1 | 
						|
      if(any(wattnames(i).eq.array_resources)) then | 
						|
        tmp = "wrf_data_coord_name_" + wattnames(i) + "_" + max_num | 
						|
        dbgfile->$tmp$ = wrf_opts@$wattnames(i)$ | 
						|
      else | 
						|
; Can't write "logical" to a NetCDF file. | 
						|
        if(typeof(wrf_opts@$wattnames(i)$).eq."logical") then | 
						|
          if(wrf_opts@$wattnames(i)$) then | 
						|
            tmp_opts@$wattnames(i)$ = 1 | 
						|
          else | 
						|
            tmp_opts@$wattnames(i)$ = 0 | 
						|
          end if | 
						|
        else | 
						|
; Just write the resource. | 
						|
          tmp_opts@$wattnames(i)$ = wrf_opts@$wattnames(i)$ | 
						|
        end if | 
						|
      end if | 
						|
    end do | 
						|
    dbgfile->$wrf_res_name$ = tmp_opts | 
						|
  end if | 
						|
 | 
						|
; Close the NetCDF file | 
						|
  delete(dbgfile) | 
						|
end | 
						|
 | 
						|
undef("write_wrf_debug_script") | 
						|
procedure write_wrf_debug_script(wks,debug_file,wrf_func_name) | 
						|
begin | 
						|
  dbgfile = addfile(debug_file+".nc","r") | 
						|
  print(getvaratts(dbgfile)) | 
						|
end | 
						|
 | 
						|
undef("delete_attrs") | 
						|
procedure delete_attrs(opts:logical) | 
						|
 | 
						|
; This procedure does some cleanup by removing unneeded attributes | 
						|
; so they don't get passed to other routines by accident. | 
						|
 | 
						|
begin | 
						|
  list_attrs = (/"MainTitle","MainTitlePos","MainTitlePosF", \ | 
						|
                 "InitTime","ValidTime","TimePos","TimePosF", \ | 
						|
                 "NoHeaderFooter","TimeLabel","LevelLabel", \ | 
						|
                 "FieldTitle","UnitLabel","NumVectors","AspectRatio", \ | 
						|
                 "SubFieldTitle","PlotOrientation","PlotLevelID", \ | 
						|
                 "mpNestTime","ContourParameters","FontHeightF","Footer", \ | 
						|
                 "start_lat","start_lon","end_lat","end_lon", \ | 
						|
                 "proj","map_proj","stand_lon","truelat1","truelat2","cenlat", \ | 
						|
                 "pole_lat","pole_lon","ref_lat","ref_lon","ref_x","ref_y", \ | 
						|
                 "e_we","e_sn","parent_id","parent_grid_ratio", \ | 
						|
                 "i_parent_start","j_parent_start", \ | 
						|
                 "dx","dy","max_dom" \ | 
						|
                 /) | 
						|
 | 
						|
  do i=0,dimsizes(list_attrs)-1 | 
						|
    if(isatt(opts,list_attrs(i))) then | 
						|
      delete(opts@$list_attrs(i)$) | 
						|
    end if | 
						|
  end do | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("set_cn_resources") | 
						|
function set_cn_resources (data[*][*]:numeric, res:logical) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  opts = res | 
						|
 | 
						|
; The ContourParameters resource can either be a scalar that | 
						|
; represents the contour level spacing, or it can be an array | 
						|
; of three elements that represent the minimum level, the maximum | 
						|
; level, and the level spacing. | 
						|
; | 
						|
  mx = max(data) | 
						|
  mn = min(data) | 
						|
 | 
						|
  if(mn.ne.mx.and.opts.and.isatt(opts,"ContourParameters")) then | 
						|
    if(dimsizes(opts@ContourParameters) .eq. 1) then | 
						|
 | 
						|
; Only the contour interval is specified. | 
						|
      nlev   = tointeger((mx-mn)/opts@ContourParameters)+1 | 
						|
      levels = nice_mnmxintvl(mn,mx,nlev,True) | 
						|
      if(levels(0) .lt. 0.) then | 
						|
        ; Set a zero contour. | 
						|
        nlev = tointeger(levels(0)/opts@ContourParameters) - 1 | 
						|
        levels(0) = nlev*opts@ContourParameters | 
						|
      end if | 
						|
      nlev = tointeger((levels(1)-levels(0))/opts@ContourParameters)+1 | 
						|
      levels(1) = levels(0) + nlev*opts@ContourParameters | 
						|
      levels(2) = opts@ContourParameters | 
						|
 | 
						|
; Min level, max level, and level spacing are specified by user. | 
						|
    else | 
						|
      if(dimsizes(opts@ContourParameters) .eq. 3) then | 
						|
        levels = opts@ContourParameters | 
						|
      else | 
						|
        print("wrf_contour: Warning: illegal setting for ContourParameters attribute") | 
						|
      end if | 
						|
    end if | 
						|
 | 
						|
  end if | 
						|
 | 
						|
; Contour levels | 
						|
  if(isvar("levels")) then | 
						|
    opts@cnLevelSelectionMode = get_res_value_keep(opts, "cnLevelSelectionMode", "ManualLevels") | 
						|
    opts@cnMinLevelValF       = get_res_value_keep(opts, "cnMinLevelValF", levels(0)) | 
						|
    opts@cnMaxLevelValF       = get_res_value_keep(opts, "cnMaxLevelValF", levels(1)) | 
						|
    opts@cnLevelSpacingF      = get_res_value_keep(opts, "cnLevelSpacingF",levels(2)) | 
						|
    delete(levels) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
; Set the default zero line thickness to 2, and the negative contour | 
						|
; line dash pattern to 1 (0 is solid). | 
						|
  opts@gsnContourZeroLineThicknessF = get_res_value_keep(opts, "gsnContourZeroLineThicknessF",2.0) | 
						|
  opts@gsnContourNegLineDashPattern = get_res_value_keep(opts, "gsnContourNegLineDashPattern",1) | 
						|
 | 
						|
 | 
						|
; Set resources that apply for both filled and line contour plots. | 
						|
  opts@cnFillDrawOrder            = get_res_value_keep(opts,"cnFillDrawOrder", "PreDraw") | 
						|
 | 
						|
 | 
						|
  opts@cnLineLabelAngleF          = get_res_value_keep(opts,"cnLineLabelAngleF", 0.0) | 
						|
  opts@cnLineLabelFontHeightF     = get_res_value_keep(opts,"cnLineLabelFontHeightF", 0.015) | 
						|
  opts@cnInfoLabelFontHeightF     = get_res_value_keep(opts,"cnInfoLabelFontHeightF", 0.015) | 
						|
  opts@cnLineLabelPerimOn         = get_res_value_keep(opts,"cnLineLabelPerimOn", True) | 
						|
  opts@cnInfoLabelPerimOn         = get_res_value_keep(opts,"cnInfoLabelPerimOn", False) | 
						|
  opts@cnLineLabelBackgroundColor = get_res_value_keep(opts,"cnLineLabelBackgroundColor", -1) | 
						|
  opts@cnHighLabelBackgroundColor = get_res_value_keep(opts,"cnHighLabelBackgroundColor", -1) | 
						|
  opts@cnLowLabelBackgroundColor  = get_res_value_keep(opts,"cnLowLabelBackgroundColor", -1) | 
						|
  opts@cnLineColor                = get_res_value_keep(opts,"cnLineColor", "Black") | 
						|
  opts@cnLineLabelFontColor       = opts@cnLineColor | 
						|
  opts@cnLineLabelPerimColor      = opts@cnLineColor | 
						|
  opts@cnInfoLabelFontColor       = opts@cnLineColor | 
						|
  opts@cnHighLabelFontColor       = opts@cnLineColor | 
						|
  opts@cnLowLabelFontColor        = opts@cnLineColor | 
						|
 | 
						|
 | 
						|
; Set field Title and levels if available | 
						|
  if(.not.isatt(opts,"cnInfoLabelString")) then | 
						|
    info_string = " Contours: $CMN$ to $CMX$ by $CIU$" | 
						|
    if(isatt(opts,"FieldTitle")) then | 
						|
        opts@cnInfoLabelString = opts@FieldTitle + info_string | 
						|
    else if(isatt(data,"description")) then | 
						|
        opts@cnInfoLabelString = data@description + info_string | 
						|
    else | 
						|
        opts@cnInfoLabelString = info_string | 
						|
    end if | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  return(opts) | 
						|
end | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("set_lb_resources") | 
						|
function set_lb_resources (data[*][*]:numeric, res:logical) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  opts = res | 
						|
 | 
						|
 | 
						|
; Somewhat convoluted way to see if a labelbar is not desired. | 
						|
  if(check_attr(opts,"pmTickMarkDisplayMode","Never",True).or.\ | 
						|
     check_attr(opts,"pmTickMarkDisplayMode",-1,False).or.\ | 
						|
     check_attr(opts,"pmTickMarkDisplayMode",0,False).or. \ | 
						|
     check_attr(opts,"lbLabelBarOn",False,False).or.\ | 
						|
     check_attr(opts,"lbLabelBarOn",0,False)) then | 
						|
    lbar_on = False | 
						|
  else | 
						|
    lbar_on = True | 
						|
  end if | 
						|
  atmp = get_res_value(opts,"lbLabelBarOn",True) ; Remove this resource | 
						|
  delete(atmp)                                   ; just in case. | 
						|
 | 
						|
 | 
						|
; Possible title for the labelbar | 
						|
  if(isatt(opts,"FieldTitle")) then | 
						|
    lb_desc = opts@FieldTitle  | 
						|
  else | 
						|
    if(isatt(data,"description")) then | 
						|
      lb_desc = data@description  | 
						|
    else | 
						|
      lb_desc = ""   | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  if(isatt(opts,"UnitLabel") ) then | 
						|
    lb_desc = lb_desc + "  (" + opts@UnitLabel + ")" | 
						|
  else | 
						|
    if(isatt(data,"units") .and. .not.(data@units.eq."")) then | 
						|
      lb_desc = lb_desc + "  (" + data@units + ")" | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  if(.not.isatt(opts,"cnFillColors")) then | 
						|
    opts@gsnSpreadColors = get_res_value_keep(opts, "gsnSpreadColors", True) | 
						|
  end if | 
						|
  opts@cnInfoLabelOn   = get_res_value_keep(opts,"cnInfoLabelOn", False) | 
						|
  opts@cnLinesOn       = get_res_value_keep(opts,"cnLinesOn", False) | 
						|
  opts@cnLineLabelsOn  = get_res_value_keep(opts,"cnLineLabelsOn", False) | 
						|
 | 
						|
; Labelbar resources | 
						|
  if(lbar_on) then | 
						|
    opts@pmLabelBarDisplayMode    = get_res_value_keep(opts,"pmLabelBarDisplayMode", "Always") | 
						|
    opts@pmLabelBarSide           = get_res_value_keep(opts,"pmLabelBarSide", "Bottom") | 
						|
    opts@lbAutoManage             = get_res_value_keep(opts,"lbAutoManage",False) | 
						|
    opts@lbOrientation            = get_res_value_keep(opts,"lbOrientation", "Horizontal") | 
						|
    opts@lbPerimOn                = get_res_value_keep(opts,"lbPerimOn", False) | 
						|
    opts@lbLabelJust              = get_res_value_keep(opts,"lbLabelJust", "BottomCenter") | 
						|
    opts@lbLabelAutoStride        = get_res_value_keep(opts,"lbLabelAutoStride",True) | 
						|
    opts@lbBoxMinorExtentF        = get_res_value_keep(opts,"lbBoxMinorExtentF", 0.13) | 
						|
    opts@lbTitleFontHeightF       = get_res_value_keep(opts,"lbTitleFontHeightF", 0.015) | 
						|
    opts@lbLabelFontHeightF       = get_res_value_keep(opts,"lbLabelFontHeightF", 0.015) | 
						|
    opts@pmLabelBarOrthogonalPosF = get_res_value_keep(opts,"pmLabelBarOrthogonalPosF", -0.1) | 
						|
 | 
						|
    opts@lbTitleOn                = get_res_value_keep(opts,"lbTitleOn", True) | 
						|
    if(lb_desc.ne."" .and. opts@lbTitleOn) then | 
						|
      opts@lbTitleOn              = get_res_value_keep(opts,"lbTitleOn", True) | 
						|
      opts@lbTitleString          = get_res_value_keep(opts,"lbTitleString", lb_desc) | 
						|
      opts@lbTitleJust            = get_res_value_keep(opts,"lbTitleJust", "BottomCenter") | 
						|
      opts@lbTitleOffsetF         = get_res_value_keep(opts,"lbTitleOffsetF", -0.5) | 
						|
    else | 
						|
      opts@lbTitleOn = False | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  return(opts) | 
						|
end | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("set_title_resources") | 
						|
function set_title_resources (data[*][*]:numeric, res:logical) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  opts = res | 
						|
 | 
						|
; Set field Title and levels if available | 
						|
  if(isatt(opts,"FieldTitle")) then | 
						|
    SubTitles = opts@FieldTitle | 
						|
  else | 
						|
    if(isatt(data,"description")) then | 
						|
      SubTitles = data@description | 
						|
    else | 
						|
      SubTitles = "UnKnown" | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  if(isatt(opts,"SubFieldTitle")) then | 
						|
    SubTitles = SubTitles + " " +  opts@SubFieldTitle | 
						|
  end if | 
						|
  if(isatt(opts,"UnitLabel")) then | 
						|
    SubTitles = SubTitles + "   (" +  opts@UnitLabel + ")" | 
						|
  else | 
						|
     if(isatt(data,"units") .and. .not.(data@units.eq."")) then | 
						|
      SubTitles = SubTitles + "   (" +  data@units + ")" | 
						|
    end if | 
						|
  end if | 
						|
  if (isatt(opts,"PlotLevelID")) then | 
						|
    SubTitles = SubTitles + "     at   " +  opts@PlotLevelID  | 
						|
  else | 
						|
    if (isatt(data,"PlotLevelID")) then | 
						|
       SubTitles = SubTitles + "     at   " +  data@PlotLevelID  | 
						|
    end if | 
						|
  end if | 
						|
  opts@tiMainString = SubTitles       | 
						|
 | 
						|
  return(opts) | 
						|
end | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("set_vc_resources") | 
						|
function set_vc_resources (res:logical) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  opts = res | 
						|
 | 
						|
  if ( isatt(opts,"vpWidthF") ) then | 
						|
  ; num_vectors is used for vcMinDistanceF and vcRefLengthF | 
						|
    width = opts@vpWidthF | 
						|
    num_vectors = get_res_value(opts,"NumVectors",25.0) | 
						|
    opts@vcMinDistanceF   = get_res_value_keep(opts,"vcMinDistanceF", width/num_vectors) | 
						|
    opts@vcRefLengthF     = get_res_value_keep(opts,"vcRefLengthF", width/num_vectors) | 
						|
  else | 
						|
    opts@vcMinDistanceF   = get_res_value_keep(opts,"vcMinDistanceF", 0.02) | 
						|
    opts@vcRefLengthF     = get_res_value_keep(opts,"vcRefLengthF", 0.02) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  opts@vcGlyphStyle     = get_res_value_keep(opts,"vcGlyphStyle", "WindBarb") | 
						|
  opts@vcWindBarbColor  = get_res_value_keep(opts,"vcWindBarbColor", "Black") | 
						|
  opts@vcRefAnnoOn      = get_res_value_keep(opts,"vcRefAnnoOn", False) | 
						|
  opts@vcMinFracLengthF = get_res_value_keep(opts,"vcMinFracLengthF", .2) | 
						|
  | 
						|
  return(opts) | 
						|
end | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("set_mp_resources") | 
						|
function set_mp_resources (res:logical) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  opts = res | 
						|
 | 
						|
; "LowRes" is the default that NCL uses, so you don't need to | 
						|
; set it here. However, if you want a higher resolution, use  | 
						|
; "MediumRes". If you want higher resolution for the coastlines, | 
						|
; then set it to "HighRes", but then you also need to download | 
						|
; the RANGS-GSHHS database.  Higher resolutions take longer to | 
						|
; draw. | 
						|
 | 
						|
      opts@mpDataBaseVersion     = get_res_value_keep(opts, "mpDataBaseVersion","MediumRes") | 
						|
     ;opts@mpOutlineBoundarySets = get_res_value_keep(opts, "mpOutlineBoundarySets", "AllBoundaries") | 
						|
      opts@mpOutlineBoundarySets = get_res_value_keep(opts, "mpOutlineBoundarySets", "GeophysicalAndUSStates") | 
						|
      opts@mpPerimLineThicknessF = get_res_value_keep(opts, "mpPerimLineThicknessF", 1.0) | 
						|
      opts@tmXBLabelFontHeightF  = get_res_value_keep(opts, "tmXBLabelFontHeightF", 0.01) | 
						|
      opts@tmYLLabelFontHeightF  = get_res_value_keep(opts, "tmYLLabelFontHeightF", 0.01) | 
						|
 | 
						|
; Select portion of the map to view. | 
						|
      opts@mpLimitMode           = get_res_value_keep(opts, "mpLimitMode","Corners") | 
						|
      opts@mpLeftCornerLatF      = get_res_value_keep(opts, "mpLeftCornerLatF", opts@start_lat) | 
						|
      opts@mpLeftCornerLonF      = get_res_value_keep(opts, "mpLeftCornerLonF", opts@start_lon) | 
						|
      opts@mpRightCornerLatF     = get_res_value_keep(opts, "mpRightCornerLatF",opts@end_lat) | 
						|
      opts@mpRightCornerLonF     = get_res_value_keep(opts, "mpRightCornerLonF",opts@end_lon) | 
						|
 | 
						|
      if ( opts@mpRightCornerLonF .lt. 0.0 ) then | 
						|
        opts@mpRightCornerLonF  = opts@mpRightCornerLonF + 360.0 | 
						|
      end if  | 
						|
 | 
						|
; Set some other resources for line colors and grid spacing. | 
						|
 | 
						|
      opts@mpGeophysicalLineColor      = get_res_value_keep(opts, "mpGeophysicalLineColor","Gray") | 
						|
      opts@mpGeophysicalLineThicknessF = get_res_value_keep(opts, "mpGeophysicalLineThicknessF",0.5) | 
						|
      opts@mpGridLineColor             = get_res_value_keep(opts, "mpGridLineColor","Gray") | 
						|
      opts@mpGridLineThicknessF        = get_res_value_keep(opts, "mpGridLineThicknessF",0.5) | 
						|
     ;opts@mpGridMaskMode              = get_res_value_keep(opts, "mpGridMaskMode",3) | 
						|
      opts@mpGridSpacingF              = get_res_value_keep(opts, "mpGridSpacingF",5) | 
						|
      opts@mpLimbLineColor             = get_res_value_keep(opts, "mpLimbLineColor","Gray") | 
						|
      opts@mpLimbLineThicknessF        = get_res_value_keep(opts, "mpLimbLineThicknessF",0.5) | 
						|
      opts@mpNationalLineColor         = get_res_value_keep(opts, "mpNationalLineColor","Gray") | 
						|
      opts@mpNationalLineThicknessF    = get_res_value_keep(opts, "mpNationalLineThicknessF",0.5) | 
						|
      opts@mpPerimLineColor            = get_res_value_keep(opts, "mpPerimLineColor","Gray") | 
						|
      opts@mpPerimOn                   = get_res_value_keep(opts, "mpPerimOn",True) | 
						|
      opts@mpUSStateLineColor          = get_res_value_keep(opts, "mpUSStateLineColor","Gray") | 
						|
      opts@mpUSStateLineThicknessF     = get_res_value_keep(opts, "mpUSStateLineThicknessF",0.5) | 
						|
      opts@pmTickMarkDisplayMode       = get_res_value_keep(opts, "pmTickMarkDisplayMode","Always") | 
						|
 | 
						|
; Tick mark resources | 
						|
 | 
						|
     ;opts@tmXBMajorLengthF      = get_res_value(opts, "tmXBMajorLengthF",-0.03) | 
						|
     ;opts@tmYLMajorLengthF      = get_res_value(opts, "tmYLMajorLengthF",-0.03) | 
						|
      opts@tmXTOn                = get_res_value(opts,"tmXTOn",False) | 
						|
      opts@tmYROn                = get_res_value(opts,"tmYROn",False) | 
						|
      opts@tmYRLabelsOn          = get_res_value(opts,"tmYRLabelsOn",True) | 
						|
      opts@tmXBBorderOn          = get_res_value(opts,"tmXBBorderOn",True) | 
						|
      opts@tmXTBorderOn          = get_res_value(opts,"tmXTBorderOn",True) | 
						|
      opts@tmYLBorderOn          = get_res_value(opts,"tmYLBorderOn",True) | 
						|
      opts@tmYRBorderOn          = get_res_value(opts,"tmYRBorderOn",True) | 
						|
 | 
						|
  return(opts) | 
						|
end | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("_SetMainTitle") | 
						|
procedure _SetMainTitle(nc_file:file,wks[1]:graphic,cn[1]:graphic,opts) | 
						|
  | 
						|
; This procedure checks the input data for certain attributes, and | 
						|
; based on those, sets MainTitle, InitTime and ValidTime | 
						|
; | 
						|
;  Attributes recognized by this procedure: | 
						|
;     MainTitle                 (main title - top left) | 
						|
;                               (with Init time top right) | 
						|
;     TimeLabel                 (valid time  - right  under init time) | 
						|
;     NoHeaderFooter            (switch all headers and footers off - mainly for panels) | 
						|
; | 
						|
; If the "NoHeaderFooter" attribute exists and is set True, then | 
						|
; don't create any titles. | 
						|
 | 
						|
begin | 
						|
; | 
						|
  if(opts.and.isatt(opts,"NoHeaderFooter").and.opts@NoHeaderFooter) then | 
						|
    return | 
						|
  end if | 
						|
 | 
						|
; | 
						|
; Set basic plot font | 
						|
; | 
						|
  font_height = get_res_value_keep(opts,"FontHeightF",0.01) | 
						|
; | 
						|
; | 
						|
; If a MainTitle attribute hasn't been set, then set to "WRF" | 
						|
; Also set an Initial time | 
						|
; | 
						|
; MAIN Header of plot | 
						|
  opts@MainTitle    = get_res_value_keep(opts,"MainTitle", " ")  | 
						|
  opts@MainTitlePos = get_res_value_keep(opts,"MainTitlePos", "Left")  | 
						|
  opts@InitTime     = get_res_value_keep(opts,"InitTime", True)  | 
						|
  opts@ValidTime    = get_res_value_keep(opts,"ValidTime", True)  | 
						|
  opts@TimePos      = get_res_value_keep(opts,"TimePos", "Right")  | 
						|
  opts@Footer       = get_res_value_keep(opts,"Footer", True)  | 
						|
 | 
						|
 | 
						|
  if (opts@MainTitlePos .eq. "Left") | 
						|
    opts@MainTitlePos  = "CenterLeft" | 
						|
    opts@MainTitlePosF = 0.0 | 
						|
  end if | 
						|
  if (opts@MainTitlePos .eq. "Center") | 
						|
    opts@MainTitlePos  = "CenterCenter" | 
						|
    opts@MainTitlePosF = 0.5 | 
						|
  end if | 
						|
  if (opts@MainTitlePos .eq. "Right") | 
						|
    opts@MainTitlePos  = "CenterRight" | 
						|
    opts@MainTitlePosF = 1.0 | 
						|
  end if | 
						|
 | 
						|
  if (opts@TimePos .eq. "Left") | 
						|
    MTOPosF = 0.30 | 
						|
  else | 
						|
    MTOPosF = 0.20 | 
						|
  end if | 
						|
 | 
						|
  txt0 = create "MainPlotTitle" textItemClass wks | 
						|
    "txString"      : opts@MainTitle | 
						|
    "txFontHeightF" : font_height*1.5 | 
						|
  end create | 
						|
  anno = NhlAddAnnotation(cn,txt0) | 
						|
  setvalues anno | 
						|
    "amZone"           : 3 | 
						|
    "amSide"           : "Top" | 
						|
    "amJust"           : opts@MainTitlePos | 
						|
    "amParallelPosF"   : opts@MainTitlePosF | 
						|
    "amOrthogonalPosF" : MTOPosF | 
						|
    "amResizeNotify"   : False | 
						|
  end setvalues | 
						|
 | 
						|
; Time information on plot | 
						|
  if (opts@TimePos .eq. "Left") | 
						|
    opts@TimePos  = "CenterLeft" | 
						|
    opts@TimePosF = 0.0 | 
						|
    if (opts@MainTitlePos .eq. "CenterLeft") | 
						|
     MTOPosF = MTOPosF - 0.05 | 
						|
    end if | 
						|
  end if | 
						|
  if (opts@TimePos .eq. "Right") | 
						|
    opts@TimePos  = "CenterRight" | 
						|
    opts@TimePosF = 1.0 | 
						|
    if (opts@MainTitlePos .eq. "CenterRight") | 
						|
     MTOPosF = MTOPosF - 0.05 | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  if( isatt(nc_file,"START_DATE") ) then | 
						|
     model_start_time = nc_file@START_DATE | 
						|
  else | 
						|
     if( isatt(nc_file,"SIMULATION_START_DATE") ) then | 
						|
       model_start_time = nc_file@SIMULATION_START_DATE | 
						|
     else | 
						|
       opts@InitTime = False | 
						|
     end if | 
						|
  end if    | 
						|
  if( opts@InitTime ) then | 
						|
    InitTime = "Init: " + model_start_time | 
						|
    txt1 = create "InitTime" textItemClass wks | 
						|
      "txString"      : InitTime | 
						|
      "txFontHeightF" : font_height | 
						|
    end create | 
						|
    anno = NhlAddAnnotation(cn,txt1) | 
						|
    setvalues anno | 
						|
      "amZone"           : 3 | 
						|
      "amSide"           : "Top" | 
						|
      "amJust"           : opts@TimePos | 
						|
      "amParallelPosF"   : opts@TimePosF         | 
						|
      "amOrthogonalPosF" : MTOPosF | 
						|
      "amResizeNotify"   : False | 
						|
    end setvalues | 
						|
  end if | 
						|
 | 
						|
  plot_narrow = False | 
						|
  if((opts).and.(isatt(opts,"vpWidthF")).and.(isatt(opts,"vpHeightF"))) then | 
						|
     ph = opts@vpHeightF   | 
						|
     pw = opts@vpWidthF   | 
						|
     phw = ph/pw | 
						|
     if ( phw .gt. 1.8 ) then | 
						|
       plot_narrow = True | 
						|
     end if | 
						|
  end if | 
						|
 | 
						|
  if( opts@ValidTime .and. isatt(opts,"TimeLabel") ) then | 
						|
 | 
						|
    ValidTime = "Valid: " + opts@TimeLabel | 
						|
 | 
						|
    MTOPosF = MTOPosF - 0.03 | 
						|
    txt2 = create "ValidTime" textItemClass wks | 
						|
      "txString"      : ValidTime | 
						|
      "txFontHeightF" : font_height | 
						|
    end create | 
						|
    anno = NhlAddAnnotation(cn,txt2) | 
						|
    setvalues anno | 
						|
      "amZone"           : 3 | 
						|
      "amSide"           : "Top" | 
						|
      "amJust"           : opts@TimePos | 
						|
      "amParallelPosF"   : opts@TimePosF         | 
						|
      "amOrthogonalPosF" : MTOPosF            | 
						|
      "amResizeNotify"   : False | 
						|
    end setvalues | 
						|
  end if | 
						|
 | 
						|
 | 
						|
; Add Footer if called for | 
						|
  if( opts@Footer ) then | 
						|
    footer1 = nc_file@TITLE | 
						|
    dis =  nc_file@DX / 1000.0 | 
						|
    WE = "WEST-EAST_GRID_DIMENSION" | 
						|
    SN = "SOUTH-NORTH_GRID_DIMENSION" | 
						|
    BT = "BOTTOM-TOP_GRID_DIMENSION" | 
						|
    footer2 =  " WE = " + nc_file@$WE$ + \ | 
						|
               " ; SN = " + nc_file@$SN$ + \ | 
						|
               " ; Levels = " + nc_file@$BT$ + \ | 
						|
               " ; Dis = " + dis + "km" | 
						|
    if ( isatt(nc_file,"MP_PHYSICS")) then | 
						|
      footer2 = footer2 +  " ; Phys Opt = " + nc_file@MP_PHYSICS  | 
						|
    end if | 
						|
    if ( isatt(nc_file,"BL_PBL_PHYSICS")) then | 
						|
      footer2 = footer2 +  " ; PBL Opt = " + nc_file@BL_PBL_PHYSICS  | 
						|
    end if | 
						|
    if ( isatt(nc_file,"CU_PHYSICS")) then | 
						|
      footer2 = footer2 +  " ; Cu Opt = " + nc_file@CU_PHYSICS  | 
						|
    end if | 
						|
    Footer = footer1 + "~C~" + footer2 | 
						|
   else | 
						|
     Footer = " " | 
						|
   end if | 
						|
    txt3 = create "Footer" textItemClass wks | 
						|
      "txString"      : Footer  | 
						|
      "txFontHeightF" : font_height*.9 | 
						|
    end create | 
						|
    anno = NhlAddAnnotation(cn,txt3) | 
						|
    setvalues anno | 
						|
      "amZone"           : 1 | 
						|
;      "amZone"           : 7 | 
						|
      "amJust"           : "TopLeft" | 
						|
      "amSide"           : "Bottom" | 
						|
      "amParallelPosF"   : 0.0 | 
						|
      "amOrthogonalPosF" : -0.55 | 
						|
      "amResizeNotify"   : False | 
						|
    end setvalues | 
						|
 | 
						|
 | 
						|
; Add X-setion information if needed | 
						|
  if(opts.and.isatt(opts,"PlotOrientation")) then | 
						|
    ;Xsection = "Cross-Section Orientation : " + opts@PlotOrientation | 
						|
    Xsection =  opts@PlotOrientation | 
						|
    txt4 = create "Xsection" textItemClass wks | 
						|
      "txString"      : Xsection  | 
						|
      "txFontHeightF" : font_height*.9 | 
						|
    end create | 
						|
    anno = NhlAddAnnotation(cn,txt4) | 
						|
    setvalues anno | 
						|
      "amZone"           : 3 | 
						|
      "amSide"           : "Top" | 
						|
      "amJust"           : "CenterRight" | 
						|
      "amParallelPosF"   : 1.0 | 
						|
      "amOrthogonalPosF" : 0.005 | 
						|
      "amResizeNotify"   : False | 
						|
    end setvalues | 
						|
  end if | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("set_mp_wrf_map_resources") | 
						|
function set_mp_wrf_map_resources(in_file[1]:file,opt_args[1]:logical)    | 
						|
 | 
						|
begin | 
						|
; | 
						|
    opts = opt_args      ; Make a copy of the resource list | 
						|
 | 
						|
; Set some resources depending on what kind of map projection is  | 
						|
; chosen. | 
						|
; | 
						|
;   MAP_PROJ = 0 : "CylindricalEquidistant" | 
						|
;   MAP_PROJ = 1 : "LambertConformal" | 
						|
;   MAP_PROJ = 2 : "Stereographic" | 
						|
;   MAP_PROJ = 3 : "Mercator" | 
						|
;   MAP_PROJ = 6 : "Lat/Lon" | 
						|
 | 
						|
    if(isatt(in_file,"MAP_PROJ")) | 
						|
 | 
						|
;   CylindricalEquidistant | 
						|
      if(in_file@MAP_PROJ .eq. 0) | 
						|
        projection          = "CylindricalEquidistant" | 
						|
        opts@mpProjection = projection | 
						|
        opts@mpGridSpacingF = 45 | 
						|
        opts@mpCenterLatF   = get_res_value_keep(opts, "mpCenterLatF", 0.0) | 
						|
        if(isatt(in_file,"STAND_LON")) | 
						|
          opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",in_file@STAND_LON) | 
						|
        else | 
						|
          if(isatt(in_file,"CEN_LON")) | 
						|
            opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",in_file@CEN_LON) | 
						|
          else | 
						|
           print("ERROR: Found neither STAND_LON or CEN_LON in file") | 
						|
          end if | 
						|
        end if | 
						|
      end if | 
						|
 | 
						|
;   LambertConformal projection | 
						|
      if(in_file@MAP_PROJ .eq. 1) | 
						|
        projection               = "LambertConformal" | 
						|
        opts@mpProjection = projection | 
						|
        opts@mpLambertParallel1F = get_res_value_keep(opts, "mpLambertParallel1F",in_file@TRUELAT1) | 
						|
        opts@mpLambertParallel2F = get_res_value_keep(opts, "mpLambertParallel2F",in_file@TRUELAT2) | 
						|
        if(isatt(in_file,"STAND_LON")) | 
						|
          opts@mpLambertMeridianF  = get_res_value_keep(opts, "mpLambertMeridianF",in_file@STAND_LON) | 
						|
        else | 
						|
          if(isatt(in_file,"CEN_LON")) | 
						|
            opts@mpLambertMeridianF  = get_res_value_keep(opts, "mpLambertMeridianF",in_file@CEN_LON) | 
						|
          else | 
						|
           print("ERROR: Found neither STAND_LON or CEN_LON in file") | 
						|
          end if | 
						|
        end if | 
						|
      end if | 
						|
   | 
						|
;   Stereographic projection | 
						|
      if(in_file@MAP_PROJ .eq. 2) | 
						|
        projection          = "Stereographic" | 
						|
        opts@mpProjection = projection | 
						|
        opts@mpCenterLatF   = get_res_value_keep(opts, "mpCenterLatF", in_file@CEN_LAT) | 
						|
        if(isatt(in_file,"STAND_LON")) | 
						|
          opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",in_file@STAND_LON) | 
						|
        else | 
						|
          if(isatt(in_file,"CEN_LON")) | 
						|
            opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",in_file@CEN_LON) | 
						|
          else | 
						|
           print("ERROR: Found neither STAND_LON or CEN_LON in file") | 
						|
          end if | 
						|
        end if | 
						|
      end if | 
						|
   | 
						|
;   Mercator projection | 
						|
      if(in_file@MAP_PROJ .eq. 3) | 
						|
        projection          = "Mercator" | 
						|
        opts@mpProjection = projection | 
						|
        opts@mpCenterLatF   = get_res_value_keep(opts, "mpCenterLatF", 0.0) | 
						|
        if(isatt(in_file,"STAND_LON")) | 
						|
          opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",in_file@STAND_LON) | 
						|
        else | 
						|
          if(isatt(in_file,"CEN_LON")) | 
						|
            opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",in_file@CEN_LON) | 
						|
          else | 
						|
           print("ERROR: Found neither STAND_LON or CEN_LON in file") | 
						|
          end if | 
						|
        end if | 
						|
      end if | 
						|
   | 
						|
;    global WRF CylindricalEquidistant | 
						|
      if(in_file@MAP_PROJ .eq. 6) | 
						|
        projection          = "CylindricalEquidistant" | 
						|
        opts@mpProjection = projection | 
						|
        opts@mpGridSpacingF = 45 | 
						|
        opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",in_file@CEN_LON) | 
						|
        if( isatt(in_file,"POLE_LAT") ) then | 
						|
          opts@mpCenterRotF = get_res_value_keep(opts, "mpCenterRotF", 90.0 - in_file@POLE_LAT)  | 
						|
          delete(opts@mpCenterLonF) | 
						|
          calcen = -190. | 
						|
          opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF", calcen ) | 
						|
        end if | 
						|
      end if | 
						|
   | 
						|
    end if | 
						|
 | 
						|
  return(opts)                                     ; Return. | 
						|
 | 
						|
end | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_contour_ps") | 
						|
function wrf_contour_ps(nc_file:file,wks[1]: graphic, data[*][*]:numeric, \ | 
						|
                     opt_args[1]:logical) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  callFrame = True | 
						|
  if ( isatt(opt_args,"FrameIT") ) then | 
						|
    if ( .not.opt_args@FrameIT ) then | 
						|
      callFrame = False | 
						|
    end if | 
						|
    delete (opt_args@FrameIT) | 
						|
  end if | 
						|
 | 
						|
  lat2U = nc_file->XLAT_U(0,:,:) | 
						|
  lon2U = nc_file->XLONG_U(0,:,:) | 
						|
 | 
						|
  opts = opt_args | 
						|
  opts@sfXArray = lon2U | 
						|
  opts@sfYArray = lat2U | 
						|
  opts@sfDataArray = data | 
						|
  opts@mpProjection         = "Stereographic" | 
						|
  opts@mpEllipticalBoundary = True | 
						|
  opts@mpFillOn = False | 
						|
  | 
						|
  opts@mpGeophysicalLineColor      = get_res_value_keep(opts, "mpGeophysicalLineColor","Gray") | 
						|
  opts@mpGeophysicalLineThicknessF = get_res_value_keep(opts, "mpGeophysicalLineThicknessF",2.0) | 
						|
 | 
						|
 | 
						|
  ; Set the contour resources | 
						|
  opts = set_cn_resources(data,opts) | 
						|
  opts@cnInfoLabelFontHeightF = 0.012 | 
						|
  opts@cnLineLabelPerimOn = False | 
						|
  opts@cnInfoLabelPerimOn = True | 
						|
 | 
						|
 | 
						|
  ; Find out if we are working with a contour or a shaded plot | 
						|
  ; fill_on = False : line contour plot | 
						|
  ; fill_on = True  : filled contour plot | 
						|
  fill_on = get_res_value_keep(opts,"cnFillOn",False) | 
						|
  if(fill_on) then      ; set lb resources if needed | 
						|
    opts@pmLabelBarDisplayMode    = get_res_value_keep(opts,"pmLabelBarDisplayMode", "Never") | 
						|
    opts = set_lb_resources(data,opts) | 
						|
    opts@pmLabelBarOrthogonalPosF = 0.0 | 
						|
    opts@lbTitleJust = "BottomLeft" | 
						|
  end if | 
						|
   | 
						|
 | 
						|
 | 
						|
  opts@gsnDraw = False    | 
						|
  opts@gsnFrame = False | 
						|
  opts@gsnMaximize = False | 
						|
  delete_attrs(opts) | 
						|
  cn = gsn_csm_contour_map_polar(wks,data,opts)          ; Create the plot. | 
						|
 | 
						|
  draw(cn) | 
						|
 | 
						|
 | 
						|
  if ( callFrame ) then | 
						|
    frame(wks) | 
						|
  end if | 
						|
 | 
						|
return (cn) | 
						|
end | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("wrf_vector_ps") | 
						|
function wrf_vector_ps(nc_file:file,wks[1]: graphic, \ | 
						|
                       data_u[*][*]:numeric, data_v[*][*]:numeric, \ | 
						|
                       opt_args[1]:logical) | 
						|
 | 
						|
begin | 
						|
 | 
						|
  callFrame = True | 
						|
  if ( isatt(opt_args,"FrameIT") ) then | 
						|
    if ( .not.opt_args@FrameIT ) then | 
						|
      callFrame = False | 
						|
    end if | 
						|
    delete (opt_args@FrameIT) | 
						|
  end if | 
						|
 | 
						|
  if(isfilevar(nc_file,"XLAT")) | 
						|
    lat2T = nc_file->XLAT(0,:,:) | 
						|
    lon2T = nc_file->XLONG(0,:,:) | 
						|
  else | 
						|
    lat2T = nc_file->XLAT_M(0,:,:) | 
						|
    lon2T = nc_file->XLONG_M(0,:,:) | 
						|
  end if | 
						|
 | 
						|
  opts = opt_args | 
						|
  opts@vfXArray = lon2T | 
						|
  opts@vfYArray = lat2T | 
						|
  opts@vfUDataArray = data_u | 
						|
  opts@vfVDataArray = data_v | 
						|
  opts@mpProjection         = "Stereographic" | 
						|
  opts@mpEllipticalBoundary = True | 
						|
  opts@mpFillOn = False | 
						|
 | 
						|
  opts@mpGeophysicalLineColor      = get_res_value_keep(opts, "mpGeophysicalLineColor","Gray") | 
						|
  opts@mpGeophysicalLineThicknessF = get_res_value_keep(opts, "mpGeophysicalLineThicknessF",2.0) | 
						|
 | 
						|
 | 
						|
; Set vector resources | 
						|
  opts = set_vc_resources(opts)  | 
						|
 | 
						|
 | 
						|
 opts@gsnDraw = False    | 
						|
 opts@gsnFrame = False | 
						|
 opts@gsnMaximize = False | 
						|
 delete_attrs(opts) | 
						|
 cn = gsn_csm_vector_map_polar(wks,data_u,data_v,opts)          ; Create the plot. | 
						|
 | 
						|
  draw(cn) | 
						|
 | 
						|
 | 
						|
  if ( callFrame ) then | 
						|
    frame(wks) | 
						|
  end if | 
						|
 | 
						|
return (cn) | 
						|
end | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_contour") | 
						|
function wrf_contour(nc_file:file,wks[1]: graphic, data[*][*]:numeric, \ | 
						|
                     opt_args[1]:logical) | 
						|
  | 
						|
; This function creates a contour plot and adds some titles to it. | 
						|
; | 
						|
;   1. Determine width to height ratio of plot. | 
						|
; | 
						|
;   2. First determine if this is to be a filled or line | 
						|
;      contour plot (fill_on) | 
						|
; | 
						|
;   3. If the ContourParameters attribute is set, then calculate | 
						|
;      the contour levels. | 
						|
; | 
						|
;   4. Set two resources for setting the zero contour line to  | 
						|
;      a larger thickness, and for changing the negative contour | 
						|
;      lines to a dashed pattern. | 
						|
; | 
						|
;   5. If doing a filled contour plot, set a title for the labelbar | 
						|
;      based on whether a units attribute is set. | 
						|
; | 
						|
;   6. Make a copy of the resource list, and set some additional | 
						|
;      resources for filled contour plots. | 
						|
; | 
						|
;   7. Create the contour plot, attach the titles, and draw | 
						|
;      and advance the frame (if requested). | 
						|
  | 
						|
local dims | 
						|
begin | 
						|
  opts = opt_args      ; Make a copy of the resource list. | 
						|
 | 
						|
  if(opts.and.isatt(opts,"gsnDebugWriteFileName")) then | 
						|
    wrf_debug_file = get_res_value(opts,"gsnDebugWriteFileName",  "")     | 
						|
  end if | 
						|
     | 
						|
  if(opts.and.isatt(opts,"mpOutlineBoundarySets")) then | 
						|
    delete(opts@mpOutlineBoundarySets) | 
						|
  end if | 
						|
 | 
						|
 | 
						|
; Calculate ratio of plot width and height. Note that this doesn't | 
						|
; affect the setting of gsnMaximize to True, because gsnMaximize will | 
						|
; retain the aspect ratio of the plot. | 
						|
 | 
						|
  if(opts.and.isatt(opts,"AspectRatio")) then | 
						|
    ratio = opts@AspectRatio | 
						|
  else | 
						|
    dims  = dimsizes(data) | 
						|
    ratio = 1.*dims(0)/dims(1) | 
						|
    if(ratio .gt. 1.2) then | 
						|
      ratio = 1.2 | 
						|
    end if | 
						|
    if(ratio .lt. 0.6667) then | 
						|
      ratio = 0.6667 | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  if(ratio .gt. 1)  | 
						|
    width  = 0.65 * 1.0/ratio | 
						|
    height = 0.65 | 
						|
  else | 
						|
    width  = 0.85  | 
						|
    height = 0.85 * ratio | 
						|
  end if | 
						|
 | 
						|
  opts@vpWidthF = get_res_value_keep(opts,"vpWidthF",  width) | 
						|
  opts@vpHeightF = get_res_value_keep(opts,"vpHeightF", height) | 
						|
 | 
						|
 | 
						|
; Set some basic contour resources  | 
						|
  opts = set_cn_resources(data,opts) | 
						|
 | 
						|
 | 
						|
; Find out if we are working with a contour or a shaded plot | 
						|
; fill_on = False : line contour plot | 
						|
; fill_on = True  : filled contour plot | 
						|
  fill_on = get_res_value_keep(opts,"cnFillOn",False) | 
						|
  if(fill_on) then      ; set lb resources if needed | 
						|
    opts = set_lb_resources(data,opts) | 
						|
    atmp = get_res_value(opts,"lbLabelBarOn",True) ; Remove this resource | 
						|
    delete(atmp)                                   ; just in case. | 
						|
  end if | 
						|
 | 
						|
 | 
						|
; Set Title resources | 
						|
  opts = set_title_resources(data,opts) | 
						|
 | 
						|
 | 
						|
; Setting gsnScale to True ensures that the tickmark lengths and labels | 
						|
; will be the same size on both axes. | 
						|
  opts@gsnScale    = get_res_value_keep(opts,"gsnScale",    True) | 
						|
 | 
						|
 | 
						|
; The default is not to draw the plot or advance the frame, and | 
						|
; to maximize the plot in the frame. | 
						|
  opts@gsnDraw          = False    ; Make sure don't draw or frame or, | 
						|
  opts@gsnFrame         = False    ; maximize, b/c we'll do this later. | 
						|
  opts@gsnMaximize      = False | 
						|
 | 
						|
 | 
						|
  opts2 = opts | 
						|
  delete_attrs(opts2)                       ; Clean up. | 
						|
  cn = gsn_contour(wks,data,opts2)          ; Create the plot. | 
						|
  _SetMainTitle(nc_file,wks,cn,opts)        ; Set some titles | 
						|
 | 
						|
  if(isvar("wrf_debug_file")) then | 
						|
    write_wrf_debug_info(wks,data,False,wrf_debug_file,opts2,"wrf_contour") | 
						|
  end if | 
						|
 | 
						|
  opts2@gsnDraw     = get_res_value_keep(opts2,"gsnDraw",     False) | 
						|
  opts2@gsnFrame    = get_res_value_keep(opts2,"gsnFrame",    False) | 
						|
  opts2@gsnMaximize = get_res_value_keep(opts2,"gsnMaximize", True) | 
						|
  draw_and_frame(wks,cn,opts2@gsnDraw,opts2@gsnFrame,False,opts2@gsnMaximize) | 
						|
 | 
						|
  return(cn)                                ; Return | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_vector") | 
						|
function wrf_vector(nc_file:file,wks[1]: graphic, data_u[*][*]:numeric, \ | 
						|
                    data_v[*][*]:numeric, opt_args[1]:logical) | 
						|
; | 
						|
; This function creates a vector plot and adds some titles to it. | 
						|
; | 
						|
;   1. Determine width to height ratio of plot. Will also be use | 
						|
;      to calculate values for vector resources later. | 
						|
; | 
						|
;   2. Make a copy of the resource list, and set some additional | 
						|
;      resources. | 
						|
; | 
						|
;   3. Create the vector plot, attach the titles, and draw | 
						|
;      and advance the frame (if requested). | 
						|
  | 
						|
local dims | 
						|
begin | 
						|
  opts = opt_args      ; Make a copy of the resource list. | 
						|
 | 
						|
  if(opts.and.isatt(opts,"gsnDebugWriteFileName")) then | 
						|
    wrf_debug_file = get_res_value(opts,"gsnDebugWriteFileName",  "")     | 
						|
  end if | 
						|
 | 
						|
  if(opts.and.isatt(opts,"mpOutlineBoundarySets")) then | 
						|
    delete(opts@mpOutlineBoundarySets) | 
						|
  end if | 
						|
; | 
						|
; The ratio is used to determine the width and height of the | 
						|
; plot, and also to determine the value for the vcMinDistanceF | 
						|
; resource. | 
						|
; | 
						|
  if(opts.and.isatt(opts,"AspectRatio")) then | 
						|
    ratio = get_res_value(opts,"AspectRatio",0.) | 
						|
  else | 
						|
    dims  = dimsizes(data_u) | 
						|
    ratio = 1.*dims(0)/dims(1) | 
						|
    if(ratio .gt. 1.2) then | 
						|
      ratio = 1.2 | 
						|
    end if | 
						|
    if(ratio .lt. 0.6667) then | 
						|
      ratio = 0.6667 | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  if(ratio .gt. 1)  | 
						|
    width  = 0.65/ratio | 
						|
    height = 0.65 | 
						|
  else | 
						|
    width  = 0.95  | 
						|
    height = 0.95 * ratio | 
						|
  end if | 
						|
 | 
						|
  opts@vpWidthF  = get_res_value_keep(opts,"vpWidthF",  width) | 
						|
  opts@vpHeightF = get_res_value_keep(opts,"vpHeightF", height) | 
						|
 | 
						|
 | 
						|
; Set Title resources | 
						|
  opts = set_title_resources(data_u,opts) | 
						|
 | 
						|
 | 
						|
; Set vector resources | 
						|
  opts = set_vc_resources(opts) | 
						|
 | 
						|
 | 
						|
; Setting gsnScale to True ensures that the tickmark lengths and labels | 
						|
; will be the same size on both axes. | 
						|
  opts@gsnScale = get_res_value_keep(opts,"gsnScale",    True) | 
						|
 | 
						|
 | 
						|
; The default is not to draw the plot or advance the frame, and | 
						|
; to maximize the plot in the frame. | 
						|
  opts@gsnDraw          = False    ; Make sure don't draw or frame or, | 
						|
  opts@gsnFrame         = False    ; maximize, b/c we'll do this later. | 
						|
  opts@gsnMaximize      = False | 
						|
 | 
						|
  opts2 = opts | 
						|
  delete_attrs(opts2)                             ; Clean up. | 
						|
  vct = gsn_vector(wks,data_u,data_v,opts2)       ; Create vector plot. | 
						|
  _SetMainTitle(nc_file,wks,vct,opts)  | 
						|
 | 
						|
  if(isvar("wrf_debug_file")) then | 
						|
    write_wrf_debug_info(wks,data_u,data_v,wrf_debug_file,opts2,"wrf_vector") | 
						|
  end if | 
						|
 | 
						|
  opts2@gsnDraw     = get_res_value_keep(opts2,"gsnDraw",     False) | 
						|
  opts2@gsnFrame    = get_res_value_keep(opts2,"gsnFrame",    False) | 
						|
  opts2@gsnMaximize = get_res_value_keep(opts2,"gsnMaximize", True) | 
						|
  draw_and_frame(wks,vct,opts2@gsnDraw,opts2@gsnFrame,False, \ | 
						|
                 opts2@gsnMaximize) | 
						|
 | 
						|
  return(vct)                                     ; Return. | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("wrf_wps_map") | 
						|
function wrf_wps_map(wks[1]:graphic,opt_args[1]:logical)    | 
						|
 | 
						|
begin | 
						|
; | 
						|
;   1. Make a copy of the resource list, and set some resources | 
						|
;      common to all map projections. | 
						|
; | 
						|
;   2. Determine the projection being used, and set resources based | 
						|
;      on that projection. | 
						|
; | 
						|
;   3. Create the map plot, and draw and advance the frame | 
						|
;      (if requested). | 
						|
 | 
						|
    opts = opt_args      ; Make a copy of the resource list | 
						|
    opts  = True | 
						|
 | 
						|
; Set some resources depending on what kind of map projection is  | 
						|
; chosen. | 
						|
; | 
						|
;   MAP_PROJ = 0 : "CylindricalEquidistant" | 
						|
;   MAP_PROJ = 1 : "LambertConformal" | 
						|
;   MAP_PROJ = 2 : "Stereographic" | 
						|
;   MAP_PROJ = 3 : "Mercator" | 
						|
;   MAP_PROJ = 6 : "Lat/Lon" | 
						|
 | 
						|
;   CylindricalEquidistant | 
						|
      if(opts@map_proj .eq. 0) | 
						|
        projection          = "CylindricalEquidistant" | 
						|
        opts@mpGridSpacingF = 45 | 
						|
        opts@mpCenterLatF   = get_res_value_keep(opts, "mpCenterLatF", 0.0) | 
						|
        opts@mpCenterLonF   = get_res_value_keep(opts, "mpCenterLonF",opts@stand_lon) | 
						|
      end if | 
						|
 | 
						|
;   LambertConformal projection | 
						|
      if(opts@map_proj .eq. 1) | 
						|
        projection               = "LambertConformal" | 
						|
        opts@mpLambertParallel1F = get_res_value_keep(opts, "mpLambertParallel1F",opts@truelat1) | 
						|
        opts@mpLambertParallel2F = get_res_value_keep(opts, "mpLambertParallel2F",opts@truelat2) | 
						|
        opts@mpLambertMeridianF  = get_res_value_keep(opts, "mpLambertMeridianF",opts@stand_lon) | 
						|
      end if | 
						|
   | 
						|
;   Stereographic projection | 
						|
      if(opts@map_proj .eq. 2) | 
						|
        projection          = "Stereographic" | 
						|
        if( isatt(opts,"cenlat") ) then | 
						|
          opts@mpCenterLatF  = get_res_value_keep(opts, "mpCenterLatF",opts@cenlat) | 
						|
        else | 
						|
          opts@mpCenterLatF  = get_res_value_keep(opts, "mpCenterLatF",opts@ref_lat) | 
						|
        end if | 
						|
        opts@mpCenterLonF   = get_res_value_keep(opts, "mpCenterLonF",opts@stand_lon) | 
						|
      end if | 
						|
   | 
						|
;   Mercator projection | 
						|
      if(opts@map_proj .eq. 3) | 
						|
        projection          = "Mercator" | 
						|
        opts@mpCenterLatF   = get_res_value_keep(opts, "mpCenterLatF", 0.0) | 
						|
        opts@mpCenterLonF   = get_res_value_keep(opts, "mpCenterLonF",opts@stand_lon) | 
						|
      end if | 
						|
   | 
						|
;    global WRF CylindricalEquidistant | 
						|
      if(opts@map_proj .eq. 6) | 
						|
        projection          = "CylindricalEquidistant" | 
						|
        opts@mpGridSpacingF = 45 | 
						|
        if( isatt(opts,"cenlon") ) then | 
						|
          opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",opts@cenlon) | 
						|
        else | 
						|
          opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF",opts@ref_lon) | 
						|
        end if | 
						|
        if( isatt(opts,"pole_lat") ) then | 
						|
          delete(opts@mpCenterLonF) | 
						|
          opts@mpCenterLonF  = get_res_value_keep(opts, "mpCenterLonF", - 190. ) | 
						|
          opts@mpCenterRotF = get_res_value_keep(opts, "mpCenterRotF", 90.0 - opts@pole_lat)  | 
						|
        else | 
						|
          opts@mpCenterRotF = get_res_value_keep(opts, "mpCenterRotF", 0.0)  | 
						|
        end if | 
						|
      end if | 
						|
 | 
						|
; Set some resources common to all map projections. | 
						|
  opts = set_mp_resources(opts) | 
						|
 | 
						|
; The default is not to draw the plot or advance the frame, and | 
						|
; to maximize the plot in the frame. | 
						|
 | 
						|
  opts@gsnDraw       = get_res_value_keep(opts,"gsnDraw",     False) | 
						|
  opts@gsnFrame      = get_res_value_keep(opts,"gsnFrame",    False) | 
						|
  opts@gsnMaximize   = get_res_value_keep(opts,"gsnMaximize", True) | 
						|
 | 
						|
  delete_attrs(opts)                             ; Clean up. | 
						|
  mp = gsn_map(wks,projection,opts)              ; Create map plot. | 
						|
  return(mp)                                     ; Return. | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("wrf_wps_dom") | 
						|
function wrf_wps_dom(wks[1]:graphic,opt_args[1]:logical,lnres[1]:logical,txres[1]:logical)  | 
						|
 | 
						|
begin | 
						|
 | 
						|
  mpres = opt_args | 
						|
  ;BPR BEGIN | 
						|
  ;grid_to_plot = 0 => plot using the corner mass grid points | 
						|
  ;grid_to_plot = 1 => plot using the edges of the corner grid cells | 
						|
  ;  This uses the locations of the corner mass grid points +/- 0.5 grid cells | 
						|
  ;  to get from the mass grid point to the edge of the grid cell | 
						|
  grid_to_plot = 1 | 
						|
  ;grid_to_plot = mpres@grid_to_plot | 
						|
  if(grid_to_plot.eq.0) then | 
						|
  ; print("Plotting using corner mass grid points") | 
						|
  else if(grid_to_plot.eq.1) then | 
						|
  ; print("Plotting using edges of the corner grid cells") | 
						|
  else | 
						|
   print("ERROR: Invalid value for grid_to_plot = "+grid_to_plot) | 
						|
  end if | 
						|
  end if | 
						|
  ;BPR END | 
						|
 | 
						|
  res = True | 
						|
  res@DX = mpres@dx | 
						|
  res@DY = mpres@dy | 
						|
  res@LATINC = 0.0 | 
						|
  res@LONINC = 0.0 | 
						|
  if ( mpres@map_proj .eq. "lambert") then | 
						|
    mpres@map_proj = 1 | 
						|
    res@MAP_PROJ = 1 | 
						|
  end if | 
						|
  if ( mpres@map_proj .eq. "polar") then | 
						|
    mpres@map_proj = 2 | 
						|
    res@MAP_PROJ = 2 | 
						|
  end if | 
						|
  if ( mpres@map_proj .eq. "mercator") then | 
						|
    mpres@map_proj = 3 | 
						|
    res@MAP_PROJ = 3 | 
						|
  end if | 
						|
  if ( mpres@map_proj .eq. "lat-lon") then | 
						|
    mpres@map_proj = 6 | 
						|
    res@MAP_PROJ = 6 | 
						|
    res@LATINC = mpres@dy | 
						|
    res@LONINC = mpres@dx | 
						|
  end if | 
						|
  res@TRUELAT1 = mpres@truelat1 | 
						|
  res@TRUELAT2 = mpres@truelat2 | 
						|
  res@STAND_LON = mpres@stand_lon | 
						|
 | 
						|
  res@REF_LAT = mpres@ref_lat | 
						|
  res@REF_LON = mpres@ref_lon | 
						|
  if ( isatt(mpres,"ref_x") ) then | 
						|
    res@KNOWNI = mpres@ref_x | 
						|
  else | 
						|
    res@KNOWNI = int2flt(mpres@e_we(0))/2. | 
						|
  end if | 
						|
  if ( isatt(mpres,"ref_y") ) then | 
						|
    res@KNOWNJ = mpres@ref_y | 
						|
  else | 
						|
    res@KNOWNJ = int2flt(mpres@e_sn(0))/2. | 
						|
  end if | 
						|
 | 
						|
  if ( isatt(mpres,"pole_lat") ) then | 
						|
    res@POLE_LAT = mpres@pole_lat | 
						|
  else | 
						|
    res@POLE_LAT = 90.0 | 
						|
  end if | 
						|
  if ( isatt(mpres,"pole_lon") ) then | 
						|
    res@POLE_LON = mpres@pole_lon | 
						|
  else | 
						|
    res@POLE_LON = 0.0 | 
						|
  end if | 
						|
 | 
						|
  ;BPR BEGIN | 
						|
  ;Determine adjustment needed to convert from mass grid to chosen grid | 
						|
  if(grid_to_plot.eq.0) then | 
						|
   adjust_grid = 0.0  | 
						|
  else if(grid_to_plot.eq.1) then | 
						|
   adjust_grid = 0.5  | 
						|
  else  | 
						|
   print("ERROR: Invalid value for grid_to_plot = "+grid_to_plot) | 
						|
   adjust_grid = 0.0  | 
						|
  end if | 
						|
  end if | 
						|
 | 
						|
  xx = 1.0 - adjust_grid | 
						|
  yy = 1.0 - adjust_grid | 
						|
  ;xx = 1.0 | 
						|
  ;yy = 1.0 | 
						|
  ;BPR END | 
						|
  loc = wrf_ij_to_ll (xx,yy,res) | 
						|
  start_lon = loc(0) | 
						|
  start_lat = loc(1) | 
						|
  ;BPR BEGIN | 
						|
  ;e_we is the largest U grid point and e_sn the largest V gridpoint | 
						|
  ;xx = int2flt(mpres@e_we(0)) | 
						|
  ;yy = int2flt(mpres@e_sn(0)) | 
						|
  ;Change it so it is in terms of mass grid points since wrf_ij_to_ll is | 
						|
  ;in terms of mass grid points  | 
						|
  xx = int2flt(mpres@e_we(0)-1) + adjust_grid | 
						|
  yy = int2flt(mpres@e_sn(0)-1) + adjust_grid | 
						|
  ;BPR END | 
						|
  loc = wrf_ij_to_ll (xx,yy,res) | 
						|
  end_lon = loc(0) | 
						|
  end_lat = loc(1) | 
						|
 | 
						|
  mpres@start_lat   = start_lat | 
						|
  mpres@start_lon   = start_lon | 
						|
  mpres@end_lat     = end_lat | 
						|
  mpres@end_lon     = end_lon | 
						|
 | 
						|
 | 
						|
  mp = wrf_wps_map(wks,mpres) | 
						|
  draw(mp) | 
						|
 | 
						|
 | 
						|
  if ( mpres@max_dom .gt. 1 ) then | 
						|
 | 
						|
    numLineColors = 0 | 
						|
    if ( isatt(lnres,"domLineColors") ) then | 
						|
       numLineColors = dimsizes(lnres@domLineColors) | 
						|
    end if | 
						|
 | 
						|
    do idom = 1,mpres@max_dom-1 | 
						|
 | 
						|
      if ( numLineColors .gt. 0 ) then | 
						|
        if ( numLineColors .ge. idom ) then | 
						|
          lnres@gsLineColor = lnres@domLineColors(idom-1) | 
						|
          txres@txFontColor = lnres@domLineColors(idom-1) | 
						|
        else | 
						|
          lnres@gsLineColor = lnres@domLineColors(numLineColors-1) | 
						|
          txres@txFontColor = lnres@domLineColors(numLineColors-1) | 
						|
        end if | 
						|
      end if | 
						|
 | 
						|
 | 
						|
      ; nest start and end points in large domain space | 
						|
      if ( mpres@parent_id(idom) .eq. 1) then | 
						|
        ; corner value | 
						|
        ;BPR BEGIN | 
						|
        ;Due to the alignment of nests we need goffset in order to | 
						|
        ;find the location of (1,1) in the fine domain in coarse domain | 
						|
        ;coordinates | 
						|
        ;i_start = mpres@i_parent_start(idom) | 
						|
        ;j_start = mpres@j_parent_start(idom) | 
						|
        goffset = 0.5*(1-(1.0/mpres@parent_grid_ratio(idom))) | 
						|
        i_start = mpres@i_parent_start(idom)-goffset | 
						|
        j_start = mpres@j_parent_start(idom)-goffset | 
						|
        ; end point | 
						|
        ;Change to mass point | 
						|
        ;i_end = (mpres@e_we(idom)-1)/mpres@parent_grid_ratio(idom) + i_start | 
						|
        ;j_end = (mpres@e_sn(idom)-1)/mpres@parent_grid_ratio(idom) + j_start | 
						|
        i_end = (mpres@e_we(idom)-2)/(1.0*mpres@parent_grid_ratio(idom)) + i_start | 
						|
        j_end = (mpres@e_sn(idom)-2)/(1.0*mpres@parent_grid_ratio(idom)) + j_start | 
						|
         | 
						|
        if(grid_to_plot.eq.0) then | 
						|
         adjust_grid = 0.0  | 
						|
        else if(grid_to_plot.eq.1) then | 
						|
         adjust_grid = 0.5/(1.0*mpres@parent_grid_ratio(idom)) | 
						|
        else  | 
						|
         print("ERROR: Invalid value for grid_to_plot = "+grid_to_plot) | 
						|
         adjust_grid = 0.0  | 
						|
        end if | 
						|
        end if | 
						|
         | 
						|
        ;BPR END | 
						|
      end if | 
						|
      if ( mpres@parent_id(idom) .ge. 2) then | 
						|
        ; corner value | 
						|
        nd = mpres@parent_id(idom) | 
						|
        ;BPR BEGIN | 
						|
        ;i_points = ((mpres@e_we(idom)-1)/mpres@parent_grid_ratio(idom)) | 
						|
        ;j_points = ((mpres@e_sn(idom)-1)/mpres@parent_grid_ratio(idom)) | 
						|
        i_points = ((mpres@e_we(idom)-2)/(1.0*mpres@parent_grid_ratio(idom))) | 
						|
        j_points = ((mpres@e_sn(idom)-2)/(1.0*mpres@parent_grid_ratio(idom))) | 
						|
        goffset = 0.5*(1-(1.0/(1.0*mpres@parent_grid_ratio(idom)))) | 
						|
        ai_start = mpres@i_parent_start(idom)*1.0-goffset | 
						|
        aj_start = mpres@j_parent_start(idom)*1.0-goffset | 
						|
        ;ai_start = mpres@i_parent_start(idom)*1.0 | 
						|
        ;aj_start = mpres@j_parent_start(idom)*1.0 | 
						|
 | 
						|
        if(grid_to_plot.eq.0) then | 
						|
         adjust_grid = 0.0  | 
						|
        else if(grid_to_plot.eq.1) then | 
						|
         adjust_grid = 0.5/(1.0*mpres@parent_grid_ratio(idom))  | 
						|
        else  | 
						|
         print("ERROR: Invalid value for grid_to_plot = "+grid_to_plot) | 
						|
         adjust_grid = 0.0  | 
						|
        end if | 
						|
        end if | 
						|
 | 
						|
        do while ( nd .gt. 1) | 
						|
          ;Note that nd-1 is used in the following because the WPS namelist is | 
						|
          ;one-based but arrays in NCL are zero-based | 
						|
          goffset = 0.5*(1-(1.0/(1.0*mpres@parent_grid_ratio(nd-1)))) | 
						|
          ;ai_start = ai_start/mpres@parent_grid_ratio(nd-1) + mpres@i_parent_start(nd-1) | 
						|
          ;aj_start = aj_start/mpres@parent_grid_ratio(nd-1) + mpres@j_parent_start(nd-1) | 
						|
          ai_start = (ai_start-1)/(1.0*mpres@parent_grid_ratio(nd-1)) + mpres@i_parent_start(nd-1)-goffset | 
						|
          aj_start = (aj_start-1)/(1.0*mpres@parent_grid_ratio(nd-1)) + mpres@j_parent_start(nd-1)-goffset | 
						|
          ;i_points = (i_points/mpres@parent_grid_ratio(nd-1)) | 
						|
          ;j_points = (j_points/mpres@parent_grid_ratio(nd-1)) | 
						|
          i_points = (i_points/(1.0*mpres@parent_grid_ratio(nd-1))) | 
						|
          j_points = (j_points/(1.0*mpres@parent_grid_ratio(nd-1))) | 
						|
          if(grid_to_plot.eq.0) then | 
						|
           adjust_grid = 0.0  | 
						|
          else if(grid_to_plot.eq.1) then | 
						|
           adjust_grid = adjust_grid/(1.0*mpres@parent_grid_ratio(nd-1)) | 
						|
          else  | 
						|
           print("ERROR: Invalid value for grid_to_plot = "+grid_to_plot) | 
						|
           adjust_grid = 0.0  | 
						|
          end if | 
						|
          end if | 
						|
 | 
						|
          ;nd = nd - 1 | 
						|
          nd = mpres@parent_id(nd-1) | 
						|
        end do | 
						|
        ;i_start = tointeger(ai_start + .5 ) | 
						|
        ;j_start = tointeger(aj_start + .5 ) | 
						|
        i_start = ai_start | 
						|
        j_start = aj_start | 
						|
        ; end point | 
						|
        ;i_end = i_points + i_start + 1 | 
						|
        ;j_end = j_points + j_start + 1 | 
						|
        i_end = i_points + i_start | 
						|
        j_end = j_points + j_start | 
						|
        ;BPR END | 
						|
      end if | 
						|
 | 
						|
      ; get the four corners | 
						|
 | 
						|
      xx = i_start - adjust_grid | 
						|
      yy = j_start - adjust_grid | 
						|
      ;xx = int2flt(i_start) | 
						|
      ;yy = int2flt(j_start) | 
						|
      loc = wrf_ij_to_ll (xx,yy,res) | 
						|
      lon_SW = loc(0) | 
						|
      lat_SW = loc(1) | 
						|
 | 
						|
      xx = i_end + adjust_grid | 
						|
      yy = j_start - adjust_grid | 
						|
      ;xx = int2flt(i_end) | 
						|
      ;yy = int2flt(j_start) | 
						|
      loc = wrf_ij_to_ll (xx,yy,res) | 
						|
      lon_SE = loc(0) | 
						|
      lat_SE = loc(1) | 
						|
 | 
						|
      xx = i_start - adjust_grid | 
						|
      yy = j_end + adjust_grid | 
						|
      ;xx = int2flt(i_start) | 
						|
      ;yy = int2flt(j_end) | 
						|
      loc = wrf_ij_to_ll (xx,yy,res) | 
						|
      lon_NW = loc(0) | 
						|
      lat_NW = loc(1) | 
						|
 | 
						|
      ;xx = int2flt(i_end) | 
						|
      ;yy = int2flt(j_end) | 
						|
      xx = i_end + adjust_grid | 
						|
      yy = j_end + adjust_grid | 
						|
      ;BPR END | 
						|
      loc = wrf_ij_to_ll (xx,yy,res) | 
						|
      lon_NE = loc(0) | 
						|
      lat_NE = loc(1) | 
						|
 | 
						|
      xbox = (/lon_SW, lon_SE, lon_NE, lon_NW, lon_SW /) | 
						|
      ybox = (/lat_SW, lat_SE, lat_NE, lat_NW, lat_SW /) | 
						|
      x_out = new(dimsizes(xbox),typeof(xbox)) | 
						|
      y_out = new(dimsizes(ybox),typeof(ybox)) | 
						|
      datatondc(mp, xbox, ybox, x_out, y_out) | 
						|
      gsn_polyline_ndc(wks, x_out, y_out, lnres) | 
						|
 | 
						|
      idd = idom + 1 | 
						|
      dom_text = "d0"+idd | 
						|
      if ( txres@txJust .eq. "BottomLeft" ) then | 
						|
        gsn_text(wks,mp,dom_text,lon_NW,lat_NW,txres) | 
						|
      else | 
						|
        gsn_text_ndc(wks,dom_text,x_out(3)+0.01,y_out(3)-0.01,txres) | 
						|
      end if | 
						|
 | 
						|
    end do | 
						|
 | 
						|
  end if | 
						|
 | 
						|
  return(mp) | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("wrf_map_resources") | 
						|
function wrf_map_resources(in_file[1]:file,map_args[1]:logical)    | 
						|
local lat, lon, x1, x2, y1, y2, dims, ii, jj | 
						|
begin | 
						|
; | 
						|
; This function sets resources for a WRF map plot, basing the projection on | 
						|
; the MAP_PROJ attribute in the given file. It's intended to be callable | 
						|
; by users who need to set mpXXXX resources for other plotting scripts. | 
						|
; | 
						|
 | 
						|
; Set some resources depending on what kind of map projection is  | 
						|
; chosen. | 
						|
; | 
						|
;   MAP_PROJ = 0 : "CylindricalEquidistant" | 
						|
;   MAP_PROJ = 1 : "LambertConformal" | 
						|
;   MAP_PROJ = 2 : "Stereographic" | 
						|
;   MAP_PROJ = 3 : "Mercator" | 
						|
;   MAP_PROJ = 6 : "Lat/Lon" | 
						|
 | 
						|
    if(isatt(in_file,"MAP_PROJ")) | 
						|
 | 
						|
;   CylindricalEquidistant | 
						|
      if(in_file@MAP_PROJ .eq. 0) | 
						|
        map_args@mpProjection          = "CylindricalEquidistant" | 
						|
        map_args@mpGridSpacingF = 45 | 
						|
        map_args@mpCenterLatF   = get_res_value_keep(map_args, "mpCenterLatF", 0.0) | 
						|
        if(isatt(in_file,"STAND_LON")) | 
						|
          map_args@mpCenterLonF  = get_res_value_keep(map_args, "mpCenterLonF",in_file@STAND_LON) | 
						|
        else | 
						|
          if(isatt(in_file,"CEN_LON")) | 
						|
            map_args@mpCenterLonF  = get_res_value_keep(map_args, "mpCenterLonF",in_file@CEN_LON) | 
						|
          else | 
						|
           print("ERROR: Found neither STAND_LON or CEN_LON in file") | 
						|
          end if | 
						|
        end if | 
						|
      end if | 
						|
 | 
						|
;   LambertConformal projection | 
						|
      if(in_file@MAP_PROJ .eq. 1) | 
						|
        map_args@mpProjection               = "LambertConformal" | 
						|
        map_args@mpLambertParallel1F = get_res_value_keep(map_args, "mpLambertParallel1F",in_file@TRUELAT1) | 
						|
        map_args@mpLambertParallel2F = get_res_value_keep(map_args, "mpLambertParallel2F",in_file@TRUELAT2) | 
						|
        if(isatt(in_file,"STAND_LON")) | 
						|
          map_args@mpLambertMeridianF  = get_res_value_keep(map_args, "mpLambertMeridianF",in_file@STAND_LON) | 
						|
        else | 
						|
          if(isatt(in_file,"CEN_LON")) | 
						|
            map_args@mpLambertMeridianF  = get_res_value_keep(map_args, "mpLambertMeridianF",in_file@CEN_LON) | 
						|
          else | 
						|
           print("ERROR: Found neither STAND_LON or CEN_LON in file") | 
						|
          end if | 
						|
        end if | 
						|
      end if | 
						|
   | 
						|
;   Stereographic projection | 
						|
      if(in_file@MAP_PROJ .eq. 2) | 
						|
        map_args@mpProjection          = "Stereographic" | 
						|
        map_args@mpCenterLatF   = get_res_value_keep(map_args, "mpCenterLatF", in_file@CEN_LAT) | 
						|
        if(isatt(in_file,"STAND_LON")) | 
						|
          map_args@mpCenterLonF  = get_res_value_keep(map_args, "mpCenterLonF",in_file@STAND_LON) | 
						|
        else | 
						|
          if(isatt(in_file,"CEN_LON")) | 
						|
            map_args@mpCenterLonF  = get_res_value_keep(map_args, "mpCenterLonF",in_file@CEN_LON) | 
						|
          else | 
						|
           print("ERROR: Found neither STAND_LON or CEN_LON in file") | 
						|
          end if | 
						|
        end if | 
						|
      end if | 
						|
   | 
						|
;   Mercator projection | 
						|
      if(in_file@MAP_PROJ .eq. 3) | 
						|
        map_args@mpProjection          = "Mercator" | 
						|
        map_args@mpCenterLatF   = get_res_value_keep(map_args, "mpCenterLatF", 0.0) | 
						|
        if(isatt(in_file,"STAND_LON")) | 
						|
          map_args@mpCenterLonF  = get_res_value_keep(map_args, "mpCenterLonF",in_file@STAND_LON) | 
						|
        else | 
						|
          if(isatt(in_file,"CEN_LON")) | 
						|
            map_args@mpCenterLonF  = get_res_value_keep(map_args, "mpCenterLonF",in_file@CEN_LON) | 
						|
          else | 
						|
           print("ERROR: Found neither STAND_LON or CEN_LON in file") | 
						|
          end if | 
						|
        end if | 
						|
      end if | 
						|
   | 
						|
;    global WRF CylindricalEquidistant | 
						|
      if(in_file@MAP_PROJ .eq. 6) | 
						|
        map_args@mpProjection          = "CylindricalEquidistant" | 
						|
        map_args@mpGridSpacingF = 45 | 
						|
        map_args@mpCenterLonF  = get_res_value_keep(map_args, "mpCenterLonF",in_file@CEN_LON) | 
						|
        if( isatt(in_file,"POLE_LAT") ) then | 
						|
          map_args@mpCenterRotF = get_res_value_keep(map_args, "mpCenterRotF", 90.0 - in_file@POLE_LAT)  | 
						|
          delete(map_args@mpCenterLonF) | 
						|
          calcen = -190. | 
						|
          map_args@mpCenterLonF  = get_res_value_keep(map_args, "mpCenterLonF", calcen ) | 
						|
        end if | 
						|
      end if | 
						|
   | 
						|
    else | 
						|
   | 
						|
      return(map_args) | 
						|
   | 
						|
    end if | 
						|
 | 
						|
    map_args@mpNestTime = get_res_value_keep(map_args, "mpNestTime",0) | 
						|
 | 
						|
      if(isfilevar(in_file,"XLAT")) | 
						|
        lat = in_file->XLAT(map_args@mpNestTime,:,:) | 
						|
        lon = in_file->XLONG(map_args@mpNestTime,:,:) | 
						|
      else | 
						|
        lat = in_file->XLAT_M(map_args@mpNestTime,:,:) | 
						|
        lon = in_file->XLONG_M(map_args@mpNestTime,:,:) | 
						|
      end if | 
						|
      dims = dimsizes(lat) | 
						|
 | 
						|
      do ii = 0, dims(0)-1 | 
						|
      do jj = 0, dims(1)-1 | 
						|
        if ( lon(ii,jj) .lt. 0.0) then | 
						|
          lon(ii,jj) = lon(ii,jj) + 360. | 
						|
        end if | 
						|
      end do | 
						|
      end do | 
						|
 | 
						|
      map_args@start_lat = lat(0,0) | 
						|
      map_args@start_lon = lon(0,0) | 
						|
      map_args@end_lat   = lat(dims(0)-1,dims(1)-1) | 
						|
      map_args@end_lon   = lon(dims(0)-1,dims(1)-1) | 
						|
 | 
						|
 | 
						|
; Set some resources common to all map projections. | 
						|
      map_args = set_mp_resources(map_args) | 
						|
 | 
						|
      if ( isatt(map_args,"ZoomIn") .and. map_args@ZoomIn ) then | 
						|
        y1 = 0 | 
						|
        x1 = 0 | 
						|
        y2 = dims(0)-1 | 
						|
        x2 = dims(1)-1 | 
						|
        if ( isatt(map_args,"Ystart") ) then | 
						|
          y1 = map_args@Ystart | 
						|
          delete(map_args@Ystart) | 
						|
        end if | 
						|
        if ( isatt(map_args,"Xstart") ) then | 
						|
          x1 = map_args@Xstart | 
						|
          delete(map_args@Xstart) | 
						|
        end if | 
						|
        if ( isatt(map_args,"Yend") ) then | 
						|
          if ( map_args@Yend .le. y2 ) then | 
						|
            y2 = map_args@Yend | 
						|
          end if | 
						|
          delete(map_args@Yend) | 
						|
        end if | 
						|
        if ( isatt(map_args,"Xend") ) then | 
						|
          if ( map_args@Xend .le. x2 ) then | 
						|
            x2 = map_args@Xend | 
						|
          end if | 
						|
          delete(map_args@Xend) | 
						|
        end if | 
						|
 | 
						|
        map_args@mpLeftCornerLatF      = lat(y1,x1) | 
						|
        map_args@mpLeftCornerLonF      = lon(y1,x1) | 
						|
        map_args@mpRightCornerLatF     = lat(y2,x2) | 
						|
        map_args@mpRightCornerLonF     = lon(y2,x2) | 
						|
 | 
						|
        if ( map_args@mpRightCornerLonF .lt. 0.0 ) then | 
						|
          map_args@mpRightCornerLonF  = map_args@mpRightCornerLonF + 360.0 | 
						|
        end if  | 
						|
 | 
						|
        delete(map_args@ZoomIn) | 
						|
      end if | 
						|
 | 
						|
      return(map_args) | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
undef("wrf_map") | 
						|
function wrf_map(wks[1]:graphic,in_file[1]:file,opt_args[1]:logical)    | 
						|
 | 
						|
begin | 
						|
; | 
						|
; This function creates a map plot, and bases the projection on | 
						|
; the MAP_PROJ attribute in the given file. | 
						|
; | 
						|
;   1. Make a copy of the resource list, and call a function to set | 
						|
;      some resources common to all map projections. | 
						|
; | 
						|
;   2. Determine the projection being used, and set resources based | 
						|
;      on that projection. | 
						|
; | 
						|
;   3. Create the map plot, and draw and advance the frame | 
						|
;      (if requested). | 
						|
 | 
						|
    if(opt_args.and.isatt(opt_args,"gsnDebugWriteFileName")) then | 
						|
      wrf_debug_file = get_res_value(opt_args,"gsnDebugWriteFileName",  "")     | 
						|
    end if | 
						|
 | 
						|
    opts = opt_args      ; Make a copy of the resource list | 
						|
    opts  = True | 
						|
 | 
						|
;---Set some map resources based on parameters and variables in input file. | 
						|
    opts = wrf_map_resources(in_file,opts) | 
						|
 | 
						|
    if(.not.isatt(opts,"mpProjection")) then | 
						|
      print("wrf_map: Error: no MAP_PROJ attribute in input file") | 
						|
      return(new(1,graphic)) | 
						|
    else | 
						|
      projection = opts@mpProjection | 
						|
    end if | 
						|
 | 
						|
; The default is not to draw the plot or advance the frame, and | 
						|
; to maximize the plot in the frame. | 
						|
 | 
						|
  opts@gsnDraw       = get_res_value_keep(opts,"gsnDraw",     False) | 
						|
  opts@gsnFrame      = get_res_value_keep(opts,"gsnFrame",    False) | 
						|
  opts@gsnMaximize   = get_res_value_keep(opts,"gsnMaximize", True) | 
						|
 | 
						|
  delete_attrs(opts)                             ; Clean up. | 
						|
  mp = gsn_map(wks,projection,opts)              ; Create map plot. | 
						|
 | 
						|
  if(isvar("wrf_debug_file")) then | 
						|
    opts@mpProjection = projection | 
						|
    write_wrf_debug_info(wks,False,False,wrf_debug_file,opts,"wrf_map") | 
						|
  end if | 
						|
 | 
						|
  return(mp)                                     ; Return. | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_map_overlays") | 
						|
function wrf_map_overlays(in_file[1]:file, \ | 
						|
                          wks:graphic, \ | 
						|
                          plots[*]:graphic, \ | 
						|
                          opt_arg[1]:logical, \ | 
						|
                          opt_mp[1]:logical)  | 
						|
  | 
						|
; This procedure takes an array of plots and overlays them on a | 
						|
; base plot - map background. | 
						|
; | 
						|
; It will advance the plot and cleanup, unless you set the | 
						|
; PanelPlot resource to True. | 
						|
; | 
						|
;  Attributes recognized by this procedure: | 
						|
;     FramePlot | 
						|
;     PanelPlot | 
						|
;     NoTitles                  (don't do any titles)  | 
						|
;     CommonTitle & PlotTitle is used to overwrite field titles | 
						|
;        CommonTitle will supercede NoTitles | 
						|
;     LatLonOverlay | 
						|
; | 
						|
; If FramePlot False, then Draw the plot but do not Frame. | 
						|
; In this case a user want to add to the drawing, and will | 
						|
; have to advance the Frame manually in the script. | 
						|
; | 
						|
; If the "NoTitles" attribute exists and is set True, then | 
						|
; don't create the top-left titles, and leave the main titles alone. | 
						|
; This resource can be useful if you are planning to panel | 
						|
; the plots. | 
						|
; | 
						|
; If PanelPlot is set to True, then this flags to wrf_map_overlays | 
						|
; that these plots are going to be eventually paneled (likely | 
						|
; by gsn_panel), and hence 1) draw and frame should not be called | 
						|
; (unless gsnDraw and/or gsnFrame are explicitly set to True), | 
						|
; and 2) the overlays and titles should not be removed with | 
						|
; NhlRemoveOverlay and NhlRemoveAnnotation. | 
						|
; | 
						|
; If LatLonOverlay is set to True, then this means the user is | 
						|
; using the 2D lat/lon coordinates to do the overlay, and hence | 
						|
; tfDoNDCOverlay should not be set to True. (The default is False.) | 
						|
; | 
						|
begin | 
						|
 | 
						|
  opts     = opt_arg         ; Make a copy of the resource lists | 
						|
  opt_mp_2 = opt_mp       | 
						|
 | 
						|
  if(opts.and.isatt(opts,"gsnDebugWriteFileName")) then | 
						|
    opt_mp_2@gsnDebugWriteFileName = get_res_value(opts, \ | 
						|
                                            "gsnDebugWriteFileName",  "")     | 
						|
    wrf_debug_file = opt_mp_2@gsnDebugWriteFileName | 
						|
  end if | 
						|
 | 
						|
  ; Let's make the map first | 
						|
  base = wrf_map(wks,in_file,opt_mp_2) | 
						|
 | 
						|
  no_titles  = get_res_value(opts,"NoTitles",False)     ; Do we want field titles? | 
						|
  com_title  = get_res_value(opts,"CommonTitle",False)     ; Do we have a common title? | 
						|
  if ( com_title ) then | 
						|
    plot_title = get_res_value(opts,"PlotTitle","  ") | 
						|
    no_titles = True | 
						|
  end if | 
						|
   | 
						|
  call_draw  = True | 
						|
  call_frame = get_res_value(opts,"FramePlot",True)     ; Do we want to frame the plot? | 
						|
  panel_plot = get_res_value(opts,"PanelPlot",False)    ; Are we paneling? | 
						|
  latlon_overlay = get_res_value(opts,"LatLonOverlay",False) ; Lat/lon Overlay? | 
						|
  opts@gsnMaximize = get_res_value_keep(opts,"gsnMaximize", True) | 
						|
 | 
						|
  nplots = dimsizes(plots) | 
						|
;  font_color = "Black" | 
						|
 | 
						|
  do i=0,nplots-1 | 
						|
    if(.not.ismissing(plots(i))) then | 
						|
;      class_name = NhlClassName(plots(i)) | 
						|
;      print(class_name) | 
						|
;      if(class_name.eq."contourPlotClass") then | 
						|
;        getvalues plots(i) | 
						|
;          "cnFillOn"    : fill_on | 
						|
;          "cnLineColor" : line_color | 
						|
;        end getvalues | 
						|
;        if (.not.fill_on) then | 
						|
;          font_color = line_color       | 
						|
;        end if        | 
						|
;      end if | 
						|
      if(.not.no_titles) then | 
						|
        getvalues plots(i) | 
						|
          "tiMainString" : SubTitle | 
						|
        end getvalues | 
						|
        if(i.eq.0) then | 
						|
          SubTitles = SubTitle | 
						|
        else | 
						|
          SubTitles = SubTitles + "~C~" + SubTitle | 
						|
        end if | 
						|
      end if | 
						|
      if(com_title .and. i .eq. nplots-1) then | 
						|
        getvalues plots(i) | 
						|
          "tiMainString" : SubTitle | 
						|
        end getvalues | 
						|
        SubTitles = plot_title | 
						|
      end if | 
						|
      if(.not.latlon_overlay) then | 
						|
        setvalues plots(i) | 
						|
          "tfDoNDCOverlay" : True | 
						|
          "tiMainOn"       : False | 
						|
        end setvalues | 
						|
      else | 
						|
        setvalues plots(i) | 
						|
          "tiMainOn"       : False | 
						|
        end setvalues | 
						|
      end if | 
						|
      overlay(base,plots(i)) | 
						|
    else | 
						|
      print("wrf_map_overlays: Warning: overlay plot #" + i + " is not valid.") | 
						|
    end if | 
						|
  end do | 
						|
 | 
						|
  if(.not.no_titles .or. com_title) then | 
						|
    font_height = get_res_value_keep(opts,"FontHeightF",0.01) | 
						|
    txt = create "map_titles" textItemClass wks | 
						|
      "txString"      : SubTitles | 
						|
      "txFontHeightF" : font_height | 
						|
     ;"txFontColor"   : font_color | 
						|
    end create | 
						|
    anno = NhlAddAnnotation(base,txt) | 
						|
    setvalues anno | 
						|
      "amZone"           : 3 | 
						|
      "amJust"           : "BottomLeft" | 
						|
      "amSide"           : "Top" | 
						|
      "amParallelPosF"   : 0.005 | 
						|
      "amOrthogonalPosF" : 0.03 | 
						|
      "amResizeNotify"   : False | 
						|
    end setvalues | 
						|
    base@map_titles = anno | 
						|
  end if | 
						|
; | 
						|
; gsnDraw and gsnFrame default to False if panel plot. | 
						|
; | 
						|
  if(panel_plot) then | 
						|
    call_draw = False | 
						|
    call_frame= False | 
						|
  end if | 
						|
 | 
						|
 | 
						|
  opts@gsnDraw     = get_res_value_keep(opts,"gsnDraw",     call_draw) | 
						|
  opts@gsnFrame    = get_res_value_keep(opts,"gsnFrame",    call_frame) | 
						|
 | 
						|
  draw_and_frame(wks,base,opts@gsnDraw,opts@gsnFrame,False, \ | 
						|
                 opts@gsnMaximize) | 
						|
 | 
						|
  if(.not.panel_plot) then | 
						|
    do i=0,nplots-1 | 
						|
      if(.not.ismissing(plots(i))) then | 
						|
        NhlRemoveOverlay(base,plots(i),False) | 
						|
      else | 
						|
        print("wrf_remove_map_overlays: Warning: overlay plot #" + i + " is not valid.") | 
						|
        print("                        Nothing to remove.") | 
						|
      end if | 
						|
    end do | 
						|
  end if | 
						|
 | 
						|
  if(isvar("wrf_debug_file")) then | 
						|
    write_wrf_debug_script(wks,wrf_debug_file,"wrf_map_overlays") | 
						|
  end if | 
						|
 | 
						|
  if(.not.no_titles.and..not.panel_plot) then | 
						|
    if(isatt(base,"map_titles")) then | 
						|
      NhlRemoveAnnotation(base,base@map_titles) | 
						|
      delete(base@map_titles) | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
return(base) | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_overlays") | 
						|
function wrf_overlays(in_file[1]:file, \ | 
						|
                     wks:graphic, plots[*]:graphic, \ | 
						|
                     opt_arg[1]:logical) | 
						|
  | 
						|
; This procedure takes an array of plots and overlays them. | 
						|
; | 
						|
; It will advance the plot and cleanup, unless you set the | 
						|
; PanelPlot resource to True. | 
						|
;  | 
						|
;  Attributes recognized by this procedure: | 
						|
;     FramePlot | 
						|
;     PanelPlot | 
						|
;     NoTitles                  (don't do any titles)  | 
						|
;     CommonTitle & PlotTile is used to overwrite field titles | 
						|
;        CommonTitle will super-seed NoTitles | 
						|
; | 
						|
; If FramePlot False, then Draw the plot but do not Frame. | 
						|
; In this case a user want to add to the drawing, and will | 
						|
; have to advance the Frame manually in the script. | 
						|
; | 
						|
; If the "NoTitles" attribute exists and is set True, then | 
						|
; don't create the top-left titles, and leave the main titles alone. | 
						|
; This resource can be useful if you are planning to panel | 
						|
; the plots. | 
						|
; | 
						|
; If PanelPlot is set to True, then this flags to wrf_overlays | 
						|
; that these plots are going to be eventually paneled (likely | 
						|
; by gsn_panel), and hence 1) draw and frame should not be called | 
						|
; (unless gsnDraw and/or gsnFrame are explicitly set to True), | 
						|
; and 2) the overlays and titles should not be removed with | 
						|
; NhlRemoveOverlay and NhlRemoveAnnotation. | 
						|
; | 
						|
; If LatLonOverlay is set to True, then this means the user is | 
						|
; using the 2D lat/lon coordinates to do the overlay, and hence | 
						|
; tfDoNDCOverlay should not be set to True. (The default is False.) | 
						|
; | 
						|
begin | 
						|
  opts = opt_arg      ; Make a copy of the resource list. | 
						|
 | 
						|
  no_titles  = get_res_value(opts,"NoTitles",False)     ; Do we want field titles? | 
						|
  com_title  = get_res_value(opts,"CommonTitle",False)     ; Do we have a common title? | 
						|
  latlon_overlay = get_res_value(opts,"LatLonOverlay",False) ; Lat/lon Overlay? | 
						|
  if ( com_title ) then | 
						|
    plot_title = get_res_value(opts,"PlotTitle","  ") | 
						|
    no_titles = True | 
						|
  end if | 
						|
 | 
						|
  call_draw  = True | 
						|
  call_frame = get_res_value(opts,"FramePlot",True)     ; Do we want to frame the plot? | 
						|
  panel_plot = get_res_value(opts,"PanelPlot",False)    ; Are we paneling? | 
						|
  opts@gsnMaximize = get_res_value_keep(opts,"gsnMaximize", True) | 
						|
 | 
						|
  nplots = dimsizes(plots) | 
						|
     | 
						|
  base = plots(0) | 
						|
  if(.not.no_titles) then | 
						|
    getvalues plots(0) | 
						|
      "tiMainString" : SubTitle | 
						|
    end getvalues | 
						|
    SubTitles = SubTitle | 
						|
    if(.not.latlon_overlay) then | 
						|
      setvalues plots(0) | 
						|
        "tfDoNDCOverlay" : True | 
						|
        "tiMainOn"       : False | 
						|
      end setvalues | 
						|
    else | 
						|
      setvalues plots(0) | 
						|
        "tiMainOn"       : False | 
						|
      end setvalues | 
						|
    end if | 
						|
  else | 
						|
    if(.not.latlon_overlay) then | 
						|
      setvalues plots(0) | 
						|
        "tfDoNDCOverlay" : True | 
						|
      end setvalues | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
  if (nplots.eq.1) then  | 
						|
    blank = create "BlankPlot" logLinPlotClass wks | 
						|
      ;"cnConstFLabelOn" : False | 
						|
    end create | 
						|
    overlay(base,blank) | 
						|
  end if | 
						|
 | 
						|
  do i=1,nplots-1 | 
						|
    if(.not.ismissing(plots(i))) then | 
						|
      if(.not.no_titles) then | 
						|
        getvalues plots(i) | 
						|
          "tiMainString" : SubTitle | 
						|
        end getvalues | 
						|
        if(i.eq.0) then | 
						|
          SubTitles = SubTitle | 
						|
        else | 
						|
          SubTitles = SubTitles + "~C~" + SubTitle | 
						|
        end if | 
						|
      end if | 
						|
      if(com_title .and. i .eq. nplots-1) then | 
						|
        getvalues plots(i) | 
						|
          "tiMainString" : SubTitle | 
						|
        end getvalues | 
						|
        SubTitles = plot_title | 
						|
      end if | 
						|
      if(.not.latlon_overlay) then | 
						|
        setvalues plots(i) | 
						|
          "tfDoNDCOverlay" : True | 
						|
          "tiMainOn"       : False | 
						|
        end setvalues | 
						|
      else | 
						|
        setvalues plots(i) | 
						|
          "tiMainOn"       : False | 
						|
        end setvalues | 
						|
      end if | 
						|
      overlay(base,plots(i)) | 
						|
    else | 
						|
      print("wrf_overlays: Warning: overlay plot #" + i + " is not valid.") | 
						|
    end if | 
						|
  end do | 
						|
 | 
						|
  if(.not.no_titles .or. com_title) then | 
						|
    font_height = get_res_value_keep(opts,"FontHeightF",0.01) | 
						|
 | 
						|
    txt = create "map_titles" textItemClass wks | 
						|
      "txString"      : SubTitles | 
						|
      "txFontHeightF" : font_height | 
						|
    end create | 
						|
    anno = NhlAddAnnotation(base,txt) | 
						|
    setvalues anno | 
						|
      "amZone"           : 3 | 
						|
      "amJust"           : "BottomLeft" | 
						|
      "amSide"           : "Top" | 
						|
      "amParallelPosF"   : 0.005 | 
						|
      "amOrthogonalPosF" : 0.03 | 
						|
      "amResizeNotify"   : False | 
						|
    end setvalues | 
						|
    base@map_titles = anno | 
						|
  end if | 
						|
 | 
						|
; | 
						|
; gsnDraw and gsnFrame should default to True if not a panel plot. | 
						|
;   | 
						|
  if(panel_plot) then | 
						|
    call_draw = False | 
						|
    call_frame= False | 
						|
  end if | 
						|
 | 
						|
  opts@gsnDraw     = get_res_value_keep(opts,"gsnDraw",     call_draw) | 
						|
  opts@gsnFrame    = get_res_value_keep(opts,"gsnFrame",    call_frame) | 
						|
  opts@gsnMaximize = get_res_value_keep(opts,"gsnMaximize", True) | 
						|
 | 
						|
  draw_and_frame(wks,base,opts@gsnDraw,opts@gsnFrame,False, \ | 
						|
                 opts@gsnMaximize) | 
						|
 | 
						|
  if(.not.no_titles.and..not.panel_plot) then | 
						|
    NhlRemoveAnnotation(base,base@map_titles) | 
						|
    delete(base@map_titles) | 
						|
  end if | 
						|
 | 
						|
  if(.not.panel_plot) then | 
						|
    if ( nplots .ge. 2 ) then | 
						|
      do i=1,nplots-1 | 
						|
        if(.not.ismissing(plots(i))) then | 
						|
          NhlRemoveOverlay(base,plots(i),False) | 
						|
        else | 
						|
          print("wrf_remove_overlays: Warning: overlay plot #" + i + " is not valid.") | 
						|
          print("                        Nothing to remove.") | 
						|
        end if | 
						|
      end do | 
						|
    end if | 
						|
  end if | 
						|
 | 
						|
return(base) | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_map_zoom") | 
						|
function wrf_map_zoom(wks[1]:graphic,in_file[1]:file,opt_args[1]:logical, \ | 
						|
                      y1:integer,y2:integer,x1:integer,x2:integer) | 
						|
 | 
						|
; As of version 5.0.1, this routine is redundant. Use the special "ZoomIn" | 
						|
; resource in wrf_map to accomplish the same thing. This function is | 
						|
; being kept for backwards capability. There should be no need for it | 
						|
; except to run old WRF-NCL codes.  Do not make any changes to it except | 
						|
; possibly to fix bugs. | 
						|
; | 
						|
begin | 
						|
      print("wrf_map_zoom: Warning: This function is obsolete. Consider using") | 
						|
      print("                       the 'ZoomIn' resource in wrf_map instead.") | 
						|
      if(isfilevar(in_file,"XLAT")) | 
						|
        lat = in_file->XLAT(0,:,:) | 
						|
        lon = in_file->XLONG(0,:,:) | 
						|
      else | 
						|
        lat = in_file->XLAT_M(0,:,:) | 
						|
        lon = in_file->XLONG_M(0,:,:) | 
						|
      end if | 
						|
      opts  = opt_args      ; Make a copy of the resource list | 
						|
      opts  = True | 
						|
      opts@mpLeftCornerLatF      = lat(y1,x1) | 
						|
      opts@mpLeftCornerLonF      = lon(y1,x1) | 
						|
      opts@mpRightCornerLatF     = lat(y2,x2) | 
						|
      opts@mpRightCornerLonF     = lon(y2,x2) | 
						|
      mz = wrf_map(wks,in_file,opts) | 
						|
      return(mz) | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_map_overlay") | 
						|
procedure wrf_map_overlay(wks:graphic,base[1]:graphic, \ | 
						|
                          plots[*]:graphic, \ | 
						|
                          opt_arg[1]:logical) | 
						|
  | 
						|
; As of version 5.0.1, this procedure is obsolete. Use wrf_map_overlays | 
						|
; instead. It is being kept for backwards capability. Do not make any | 
						|
; changes to it except possibly to fix bugs. | 
						|
; | 
						|
; This procedure takes an array of plots and overlays them on a | 
						|
; base plot - map background. | 
						|
; | 
						|
; It will advance the plot and cleanup, unless you set the | 
						|
; PanelPlot resource to True. | 
						|
; | 
						|
;  Attributes recognized by this procedure: | 
						|
;     NoTitles                  (don't do any titles)  | 
						|
;     PanelPlot | 
						|
; | 
						|
; If the "NoTitles" attribute exists and is set True, then | 
						|
; don't create the top-left titles, and leave the main titles alone. | 
						|
; This resource can be useful if you are planning to panel | 
						|
; the plots. | 
						|
; | 
						|
; If PanelPlot is set to True, then this flags to wrf_map_overlay | 
						|
; that these plots are going to be eventually paneled (likely | 
						|
; by gsn_panel), and hence 1) draw and frame should not be called | 
						|
; (unless gsnDraw and/or gsnFrame are explicitly set to True), | 
						|
; and 2) the overlays and titles should not be removed with | 
						|
; NhlRemoveOverlay and NhlRemoveAnnotation. | 
						|
; | 
						|
begin | 
						|
  print("wrf_map_overlay: Warning: This procedure is obsolete. Consider" ) | 
						|
  print("                          using wrf_map_overlays instead.") | 
						|
 | 
						|
  opts = opt_arg      ; Make a copy of the resource list | 
						|
  opts = True | 
						|
 | 
						|
  if(opts.and.isatt(opts,"NoTitles").and.opts@NoTitles) then | 
						|
    no_titles = True | 
						|
  else | 
						|
    no_titles = False | 
						|
  end if | 
						|
 | 
						|
  panel_plot = get_res_value(opts,"PanelPlot",False)    ; Are we paneling? | 
						|
  latlon_overlay = get_res_value(opts,"LatLonOverlay",False) ; Lat/lon Overlay? | 
						|
 | 
						|
  nplots = dimsizes(plots) | 
						|
;  font_color = "Black" | 
						|
 | 
						|
  do i=0,nplots-1 | 
						|
    if(.not.ismissing(plots(i))) then | 
						|
;      class_name = NhlClassName(plots(i)) | 
						|
;      print(class_name) | 
						|
;      if(class_name.eq."contourPlotClass") then | 
						|
;        getvalues plots(i) | 
						|
;          "cnFillOn"    : fill_on | 
						|
;          "cnLineColor" : line_color | 
						|
;        end getvalues | 
						|
;        if (.not.fill_on) then | 
						|
;          font_color = line_color       | 
						|
;        end if        | 
						|
;      end if | 
						|
      if(.not.no_titles) then | 
						|
        getvalues plots(i) | 
						|
          "tiMainString" : SubTitle | 
						|
        end getvalues | 
						|
        if(i.eq.0) then | 
						|
          SubTitles = SubTitle | 
						|
        else | 
						|
          SubTitles = SubTitles + "~C~" + SubTitle | 
						|
        end if | 
						|
        if(.not.latlon_overlay) then | 
						|
    	  setvalues plots(i) | 
						|
            "tfDoNDCOverlay" : True | 
						|
            "tiMainOn"       : False | 
						|
          end setvalues | 
						|
        else | 
						|
    	  setvalues plots(i) | 
						|
            "tiMainOn"       : False | 
						|
          end setvalues | 
						|
        end if | 
						|
      else | 
						|
        if(.not.latlon_overlay) then | 
						|
  	  setvalues plots(i) | 
						|
            "tfDoNDCOverlay" : True | 
						|
          end setvalues | 
						|
        end if | 
						|
      end if | 
						|
      overlay(base,plots(i)) | 
						|
    else | 
						|
      print("wrf_map_overlay: Warning: overlay plot #" + i + " is not valid.") | 
						|
    end if | 
						|
  end do | 
						|
 | 
						|
  if(.not.no_titles) then | 
						|
    font_height = get_res_value_keep(opts,"FontHeightF",0.01) | 
						|
    txt = create "map_titles" textItemClass wks | 
						|
      "txString"      : SubTitles | 
						|
      "txFontHeightF" : font_height | 
						|
     ;"txFontColor"   : font_color | 
						|
    end create | 
						|
    anno = NhlAddAnnotation(base,txt) | 
						|
    setvalues anno | 
						|
      "amZone"           : 3 | 
						|
      "amJust"           : "BottomLeft" | 
						|
      "amSide"           : "Top" | 
						|
      "amParallelPosF"   : 0.005 | 
						|
      "amOrthogonalPosF" : 0.03 | 
						|
      "amResizeNotify"   : False | 
						|
    end setvalues | 
						|
    base@map_titles = anno | 
						|
  end if | 
						|
; | 
						|
; gsnDraw and gsnFrame should default to True if not a panel plot. | 
						|
; gsnFrame will default to False if opt_arg is False. | 
						|
; | 
						|
  if(panel_plot.or..not.opt_arg) then | 
						|
    call_frame = False | 
						|
  else | 
						|
    call_frame = True | 
						|
  end if | 
						|
  if(panel_plot) then | 
						|
    call_draw = False | 
						|
  else | 
						|
    call_draw = True | 
						|
  end if | 
						|
  opts@gsnDraw     = get_res_value_keep(opts,"gsnDraw",     call_draw) | 
						|
  opts@gsnFrame    = get_res_value_keep(opts,"gsnFrame",    call_frame) | 
						|
  opts@gsnMaximize = get_res_value_keep(opts,"gsnMaximize", True) | 
						|
 | 
						|
  draw_and_frame(wks,base,opts@gsnDraw,opts@gsnFrame,False, \ | 
						|
                 opts@gsnMaximize) | 
						|
 | 
						|
  if(.not.panel_plot) then | 
						|
    do i=0,nplots-1 | 
						|
      if(.not.ismissing(plots(i))) then | 
						|
        NhlRemoveOverlay(base,plots(i),False) | 
						|
      else | 
						|
        print("wrf_remove_map_overlay: Warning: overlay plot #" + i + " is not valid.") | 
						|
        print("                        Nothing to remove.") | 
						|
      end if | 
						|
    end do | 
						|
  end if | 
						|
 | 
						|
  if(.not.no_titles.and..not.panel_plot) then | 
						|
    if(isatt(base,"map_titles")) then | 
						|
      NhlRemoveAnnotation(base,base@map_titles) | 
						|
      delete(base@map_titles) | 
						|
    end if | 
						|
  end if | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("wrf_overlay") | 
						|
procedure wrf_overlay(wks:graphic, plots[*]:graphic, \ | 
						|
                          opt_arg[1]:logical) | 
						|
  | 
						|
; As of version 5.0.1, this procedure is obsolete. Use wrf_overlays | 
						|
; instead. It is being kept for backwards capability. Do not make any | 
						|
; changes to it except possibly to fix bugs. | 
						|
; | 
						|
; This procedure takes an array of plots and overlays them. | 
						|
; | 
						|
; It will advance the plot and cleanup, unless you set the | 
						|
; PanelPlot resource to True. | 
						|
; | 
						|
;  Attributes recognized by this procedure: | 
						|
;     NoTitles                  (don't do any titles)  | 
						|
;     PanelPlot | 
						|
; | 
						|
; If the "NoTitles" attribute exists and is set True, then | 
						|
; don't create the top-left titles, and leave the main titles alone. | 
						|
; This resource can be useful if you are planning to panel | 
						|
; the plots. | 
						|
; | 
						|
; If PanelPlot is set to True, then this flags to wrf_overlay | 
						|
; that these plots are going to be eventually paneled (likely | 
						|
; by gsn_panel), and hence 1) draw and frame should not be called | 
						|
; (unless gsnDraw and/or gsnFrame are explicitly set to True), | 
						|
; and 2) the overlays and titles should not be removed with | 
						|
; NhlRemoveOverlay and NhlRemoveAnnotation. | 
						|
; | 
						|
; If LatLonOverlay is set to True, then this means the user is | 
						|
; using the 2D lat/lon coordinates to do the overlay, and hence | 
						|
; tfDoNDCOverlay should not be set to True. (The default is False.) | 
						|
; | 
						|
begin | 
						|
  print("wrf_overlay: Warning: This procedure is obsolete. Consider using") | 
						|
  print("                      wrf_overlays instead.") | 
						|
 | 
						|
  opts = opt_arg      ; Make a copy of the resource list. | 
						|
  opts = True | 
						|
 | 
						|
  if(opts.and.isatt(opts,"NoTitles").and.opts@NoTitles) then | 
						|
    no_titles = True | 
						|
  else | 
						|
    no_titles = False | 
						|
  end if | 
						|
 | 
						|
  panel_plot = get_res_value(opts,"PanelPlot",False)    ; Are we paneling? | 
						|
  latlon_overlay = get_res_value(opts,"LatLonOverlay",False)  ; lat/lon overlay? | 
						|
 | 
						|
  nplots = dimsizes(plots) | 
						|
     | 
						|
  base = plots(0) | 
						|
  if(.not.no_titles) then | 
						|
    getvalues plots(0) | 
						|
      "tiMainString" : SubTitle | 
						|
    end getvalues | 
						|
    SubTitles = SubTitle | 
						|
    if(.not.latlon_overlay) then | 
						|
      setvalues plots(0) | 
						|
        "tfDoNDCOverlay" : True | 
						|
        "tiMainOn"       : False | 
						|
      end setvalues | 
						|
    else | 
						|
      setvalues plots(0) | 
						|
        "tiMainOn"       : False | 
						|
      end setvalues | 
						|
    end if | 
						|
  else | 
						|
    setvalues plots(0) | 
						|
      "tfDoNDCOverlay" : True | 
						|
    end setvalues | 
						|
  end if | 
						|
 | 
						|
  if (nplots.eq.1) then  | 
						|
    blank = create "BlankPlot" logLinPlotClass wks | 
						|
      ;"cnConstFLabelOn" : False | 
						|
    end create | 
						|
    overlay(base,blank) | 
						|
  end if | 
						|
 | 
						|
  do i=1,nplots-1 | 
						|
    if(.not.ismissing(plots(i))) then | 
						|
      if(.not.no_titles) then | 
						|
        getvalues plots(i) | 
						|
          "tiMainString" : SubTitle | 
						|
        end getvalues | 
						|
        SubTitles = SubTitles + "~C~" + SubTitle | 
						|
        if(.not.latlon_overlay) then | 
						|
          setvalues plots(i) | 
						|
            "tfDoNDCOverlay" : True | 
						|
            "tiMainOn"       : False | 
						|
          end setvalues | 
						|
        else | 
						|
          setvalues plots(i) | 
						|
            "tiMainOn"       : False | 
						|
          end setvalues | 
						|
        end if | 
						|
      else | 
						|
        if(.not.latlon_overlay) then | 
						|
          setvalues plots(i) | 
						|
            "tfDoNDCOverlay" : True | 
						|
          end setvalues | 
						|
        end if | 
						|
      end if | 
						|
      overlay(base,plots(i)) | 
						|
    else | 
						|
      print("wrf_overlay: Warning: overlay plot #" + i + " is not valid.") | 
						|
    end if | 
						|
  end do | 
						|
 | 
						|
  if(.not.no_titles) then | 
						|
    font_height = get_res_value_keep(opts,"FontHeightF",0.01) | 
						|
 | 
						|
    txt = create "map_titles" textItemClass wks | 
						|
      "txString"      : SubTitles | 
						|
      "txFontHeightF" : font_height | 
						|
    end create | 
						|
    anno = NhlAddAnnotation(base,txt) | 
						|
    setvalues anno | 
						|
      "amZone"           : 3 | 
						|
      "amJust"           : "BottomLeft" | 
						|
      "amSide"           : "Top" | 
						|
      "amParallelPosF"   : 0.005 | 
						|
      "amOrthogonalPosF" : 0.03 | 
						|
      "amResizeNotify"   : False | 
						|
    end setvalues | 
						|
    base@map_titles = anno | 
						|
  end if | 
						|
 | 
						|
; | 
						|
; gsnDraw and gsnFrame should default to True if not a panel plot. | 
						|
; gsnFrame will default to False if opt_arg is False. | 
						|
; | 
						|
  if(panel_plot.or..not.opt_arg) then | 
						|
    call_frame = False | 
						|
  else | 
						|
    call_frame = True | 
						|
  end if | 
						|
  if(panel_plot) then | 
						|
    call_draw = False | 
						|
  else | 
						|
    call_draw = True | 
						|
  end if | 
						|
  opts@gsnDraw     = get_res_value_keep(opts,"gsnDraw",     call_draw) | 
						|
  opts@gsnFrame    = get_res_value_keep(opts,"gsnFrame",    call_frame) | 
						|
  opts@gsnMaximize = get_res_value_keep(opts,"gsnMaximize", True) | 
						|
 | 
						|
  draw_and_frame(wks,base,opts@gsnDraw,opts@gsnFrame,False, \ | 
						|
                 opts@gsnMaximize) | 
						|
 | 
						|
  if(.not.no_titles.and..not.panel_plot) then | 
						|
    NhlRemoveAnnotation(base,base@map_titles) | 
						|
    delete(base@map_titles) | 
						|
  end if | 
						|
 | 
						|
  if(.not.panel_plot) then | 
						|
    if ( nplots .ge. 2 ) then | 
						|
      do i=1,nplots-1 | 
						|
        if(.not.ismissing(plots(i))) then | 
						|
          NhlRemoveOverlay(base,plots(i),False) | 
						|
        else | 
						|
          print("wrf_remove_overlay: Warning: overlay plot #" + i + " is not valid.") | 
						|
          print("                        Nothing to remove.") | 
						|
        end if | 
						|
      end do | 
						|
    end if | 
						|
  end if | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("add_white_space") | 
						|
function add_white_space(str:string,maxlen:integer) | 
						|
 | 
						|
begin | 
						|
  cstr = stringtochar(str) | 
						|
  len  = dimsizes(cstr)-1 | 
						|
  ws   = "" | 
						|
  if(len.lt.maxlen) then | 
						|
    do i=1,maxlen-len | 
						|
      ws = ws + " " | 
						|
    end do | 
						|
  end if | 
						|
  return(ws) | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("print_opts") | 
						|
procedure print_opts(opts_name,opts,debug) | 
						|
 | 
						|
begin | 
						|
  if(.not.debug) then | 
						|
    return | 
						|
  end if | 
						|
  varatts = getvaratts(opts) | 
						|
; | 
						|
; Sort attributes alphabetically/ | 
						|
; | 
						|
  sqsort(varatts) | 
						|
; | 
						|
; Get length of longest attribute name. | 
						|
; | 
						|
  cvaratts = stringtochar(varatts) | 
						|
  cmaxlen  = dimsizes(cvaratts(0,:))-1 | 
						|
 | 
						|
  print("------------------------------------------------------------") | 
						|
  print(opts_name + "...")    ; Print name of option variable. | 
						|
; | 
						|
; Loop through each attribute in the list. If its value is an array, | 
						|
; then print out the array with '(/' and '/)' around it. | 
						|
; | 
						|
; If the value is a string, then put ticks (') around each string. | 
						|
; | 
						|
  do i=0,dimsizes(varatts)-1 | 
						|
    x = opts@$varatts(i)$ | 
						|
; | 
						|
; Use add_white_space to make sure all the equal signs line up. | 
						|
; | 
						|
    tmp_str = "    " + varatts(i) + \ | 
						|
              add_white_space(varatts(i),cmaxlen) + " = " | 
						|
; | 
						|
; Check if attribute is an array. | 
						|
;     | 
						|
    if(dimsizes(x).gt.1) then | 
						|
      tmp_str = tmp_str + "(/" | 
						|
      do j=0,dimsizes(x)-1 | 
						|
        if(typeof(x(j)).eq."string") then | 
						|
          tmp_str = tmp_str + "'" + x(j) + "'" | 
						|
        else | 
						|
          tmp_str = tmp_str + x(j) | 
						|
        end if | 
						|
        if(j.lt.dimsizes(x)-1) then | 
						|
          tmp_str = tmp_str + "," | 
						|
        else | 
						|
          tmp_str = tmp_str + "/)" | 
						|
        end if | 
						|
      end do | 
						|
    else      if(typeof(x).eq."string") then | 
						|
        tmp_str = tmp_str + "'" + x + "'" | 
						|
      else | 
						|
        tmp_str = tmp_str + x | 
						|
      end if | 
						|
    end if | 
						|
    print("" + tmp_str) | 
						|
    delete(x) | 
						|
  end do | 
						|
 | 
						|
end | 
						|
 | 
						|
;-------------------------------------------------------------------------------- | 
						|
 | 
						|
undef("print_header") | 
						|
procedure print_header(icount:integer,debug) | 
						|
begin | 
						|
  icount = icount + 1 | 
						|
  if(.not.debug) then | 
						|
    return | 
						|
  end if | 
						|
  print("END plot #" + icount) | 
						|
  print("------------------------------------------------------------") | 
						|
 | 
						|
end | 
						|
 | 
						|
;--------------------------------------------------------------------------------
 | 
						|
 |