Skip to content

Commit

Permalink
feature/geo_ref This commit references ufs-community#22.
Browse files Browse the repository at this point in the history
Add geo-referencing information to sfc_climo_gen output
files.
  • Loading branch information
GeorgeGayno-NOAA committed May 26, 2020
1 parent c7ea352 commit ff45e5f
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 19 deletions.
20 changes: 18 additions & 2 deletions sorc/sfc_climo_gen.fd/interp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ subroutine interp(localpet, method, input_file)
real(esmf_kind_r4), allocatable :: data_src_global(:,:)
real(esmf_kind_r4), allocatable :: data_mdl_one_tile(:,:)
real(esmf_kind_r4), allocatable :: vegt_mdl_one_tile(:,:)
real(esmf_kind_r4), allocatable :: lat_mdl_one_tile(:,:)
real(esmf_kind_r4), allocatable :: lon_mdl_one_tile(:,:)

type(esmf_regridmethod_flag),intent(in) :: method
type(esmf_field) :: data_field_src
Expand Down Expand Up @@ -93,9 +95,13 @@ subroutine interp(localpet, method, input_file)
if (localpet == 0) then
allocate(data_mdl_one_tile(i_mdl,j_mdl))
allocate(mask_mdl_one_tile(i_mdl,j_mdl))
allocate(lat_mdl_one_tile(i_mdl,j_mdl))
allocate(lon_mdl_one_tile(i_mdl,j_mdl))
else
allocate(data_mdl_one_tile(0,0))
allocate(mask_mdl_one_tile(0,0))
allocate(lat_mdl_one_tile(0,0))
allocate(lon_mdl_one_tile(0,0))
endif

record = 0
Expand Down Expand Up @@ -199,6 +205,16 @@ subroutine interp(localpet, method, input_file)

OUTPUT_LOOP : do tile = 1, num_tiles

print*,"- CALL FieldGather FOR MODEL LATITUDE."
call ESMF_FieldGather(latitude_field_mdl, lat_mdl_one_tile, rootPet=0, tile=tile, rc=rc)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
call error_handler("IN FieldGather.", rc)

print*,"- CALL FieldGather FOR MODEL LONGITUDE."
call ESMF_FieldGather(longitude_field_mdl, lon_mdl_one_tile, rootPet=0, tile=tile, rc=rc)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
call error_handler("IN FieldGather.", rc)

print*,"- CALL FieldGather FOR MODEL GRID DATA."
call ESMF_FieldGather(data_field_mdl, data_mdl_one_tile, rootPet=0, tile=tile, rc=rc)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
Expand All @@ -225,7 +241,7 @@ subroutine interp(localpet, method, input_file)
call adjust_for_landice (data_mdl_one_tile, vegt_mdl_one_tile, i_mdl, j_mdl, field_names(n))
end select
where(mask_mdl_one_tile == 0) data_mdl_one_tile = missing
call output (data_mdl_one_tile, i_mdl, j_mdl, tile, record, t, n)
call output (data_mdl_one_tile, lat_mdl_one_tile, lon_mdl_one_tile, i_mdl, j_mdl, tile, record, t, n)
endif

if (field_names(n) == 'vegetation_type') then
Expand All @@ -245,7 +261,7 @@ subroutine interp(localpet, method, input_file)
status=nf90_close(ncid)

deallocate(data_mdl_one_tile, mask_mdl_one_tile)
deallocate(data_src_global)
deallocate(data_src_global, lat_mdl_one_tile, lon_mdl_one_tile)

print*,"- CALL FieldRegridRelease."
call ESMF_FieldRegridRelease(routehandle=regrid_data, rc=rc)
Expand Down
93 changes: 80 additions & 13 deletions sorc/sfc_climo_gen.fd/model_grid.F90
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ module model_grid
! grid_mdl ESMF grid object for the model grid.
! grid_tiles Array of model grid tile names.
! i/j_mdl i/j dimensions of model tile.
! latitude_field_mdl ESMF field object that holds the
! model grid latitude
! longitude_field_mdl ESMF field object that holds the
! model grid longitude
! mdl_field_mdl ESMF field object that holds the
! model land mask.
! missing Value assigned to undefined points
Expand All @@ -51,6 +55,7 @@ module model_grid

type(esmf_grid), public :: grid_mdl
type(esmf_field), public :: data_field_mdl, mask_field_mdl
type(esmf_field), public :: latitude_field_mdl, longitude_field_mdl
type(esmf_field), public :: vegt_field_mdl

public :: define_model_grid
Expand Down Expand Up @@ -92,10 +97,13 @@ subroutine define_model_grid(localpet, npets)
integer :: extra, rc, tile
integer, allocatable :: decomptile(:,:)

integer, allocatable :: mask_mdl_one_tile(:,:)
integer(esmf_kind_i4), allocatable :: mask_mdl_one_tile(:,:)
integer(esmf_kind_i4), pointer :: mask_field_mdl_ptr(:,:)
integer(esmf_kind_i4), pointer :: mask_mdl_ptr(:,:)

real(esmf_kind_r4), allocatable :: latitude_one_tile(:,:)
real(esmf_kind_r4), allocatable :: longitude_one_tile(:,:)

!-----------------------------------------------------------------------
! Get the number of tiles from the mosaic file.
!-----------------------------------------------------------------------
Expand Down Expand Up @@ -193,6 +201,24 @@ subroutine define_model_grid(localpet, npets)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
call error_handler("IN FieldCreate", rc)

print*,"- CALL FieldCreate FOR MODEL GRID LATITUDE."
latitude_field_mdl = ESMF_FieldCreate(grid_mdl, &
typekind=ESMF_TYPEKIND_R4, &
staggerloc=ESMF_STAGGERLOC_CENTER, &
name="latitude on model grid", &
rc=rc)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
call error_handler("IN FieldCreate", rc)

print*,"- CALL FieldCreate FOR MODEL GRID LONGITUDE."
longitude_field_mdl = ESMF_FieldCreate(grid_mdl, &
typekind=ESMF_TYPEKIND_R4, &
staggerloc=ESMF_STAGGERLOC_CENTER, &
name="longitude on model grid", &
rc=rc)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
call error_handler("IN FieldCreate", rc)

!-----------------------------------------------------------------------
! Set model land mask.
!-----------------------------------------------------------------------
Expand All @@ -216,22 +242,39 @@ subroutine define_model_grid(localpet, npets)

if (localpet == 0) then
allocate(mask_mdl_one_tile(i_mdl,j_mdl))
allocate(latitude_one_tile(i_mdl,j_mdl))
allocate(longitude_one_tile(i_mdl,j_mdl))
else
allocate(mask_mdl_one_tile(0,0))
allocate(latitude_one_tile(0,0))
allocate(longitude_one_tile(0,0))
endif

do tile = 1, num_tiles
if (localpet == 0) then
the_file = trim(orog_dir_mdl) // trim(orog_files_mdl(tile))
call get_model_mask(trim(the_file), mask_mdl_one_tile, i_mdl, j_mdl)
call get_model_info(trim(the_file), mask_mdl_one_tile, &
latitude_one_tile, longitude_one_tile, i_mdl, j_mdl)
endif

print*,"- CALL FieldScatter FOR MODEL GRID MASK. TILE IS: ", tile
call ESMF_FieldScatter(mask_field_mdl, mask_mdl_one_tile, rootpet=0, tile=tile, rc=rc)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
call error_handler("IN FieldScatter", rc)

print*,"- CALL FieldScatter FOR MODEL LATITUDE. TILE IS: ", tile
call ESMF_FieldScatter(latitude_field_mdl, latitude_one_tile, rootpet=0, tile=tile, rc=rc)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
call error_handler("IN FieldScatter", rc)

print*,"- CALL FieldScatter FOR MODEL LONGITUDE. TILE IS: ", tile
call ESMF_FieldScatter(longitude_field_mdl, longitude_one_tile, rootpet=0, tile=tile, rc=rc)
if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) &
call error_handler("IN FieldScatter", rc)

enddo

deallocate(mask_mdl_one_tile)
deallocate(mask_mdl_one_tile, latitude_one_tile, longitude_one_tile)

print*,"- CALL GridAddItem FOR MODEL GRID."
call ESMF_GridAddItem(grid_mdl, &
Expand All @@ -254,24 +297,26 @@ subroutine define_model_grid(localpet, npets)

end subroutine define_model_grid

subroutine get_model_mask(orog_file, mask, idim, jdim)
subroutine get_model_info(orog_file, mask, lat2d, lon2d, idim, jdim)

!-----------------------------------------------------------------------
! subroutine documentation block
!
! Subroutine: get model mask
! Subroutine: get model information
! prgmmr: gayno org: w/np2 date: 2018
!
! Abstract: Read model land/sea mask from the orography file.
! Abstract: Read model land/sea mask and lat/lon from the orography file.
!
! Usage: call get_model_mask(orog_file, mask, idim, jdim)
! Usage: call get_model_info(orog_file, mask, lat2d, lon2d, idim, jdim)
!
! input argument list:
! orog_file the orography file
! i/jdim i/j dimension of the model tile
!
! output argument list:
! mask land/sea mask
! lat2d latitude
! lon2d longitude
!
!-----------------------------------------------------------------------

Expand All @@ -286,16 +331,19 @@ subroutine get_model_mask(orog_file, mask, idim, jdim)
integer, intent(in) :: idim, jdim
integer(esmf_kind_i4), intent(out) :: mask(idim,jdim)

real(esmf_kind_r4), intent(out) :: lat2d(idim,jdim)
real(esmf_kind_r4), intent(out) :: lon2d(idim,jdim)

integer :: error, lat, lon
integer :: ncid, id_dim, id_var

real(kind=4), allocatable :: dummy(:,:)

print*,"- READ MODEL LAND MASK FILE"
print*,"- READ MODEL OROGRAPHY FILE"

print*,'- OPEN LAND MASK FILE: ', orog_file
print*,'- OPEN FILE: ', orog_file
error=nf90_open(orog_file,nf90_nowrite,ncid)
call netcdf_err(error, "OPENING MODEL LAND MASK FILE")
call netcdf_err(error, "OPENING MODEL OROGRAPHY FILE")

print*,"- READ I-DIMENSION"
error=nf90_inq_dimid(ncid, 'lon', id_dim)
Expand All @@ -322,14 +370,27 @@ subroutine get_model_mask(orog_file, mask, idim, jdim)
call netcdf_err(error, "READING SLMSK ID")
error=nf90_get_var(ncid, id_var, dummy)
call netcdf_err(error, "READING SLMSK")
mask = nint(dummy)

error = nf90_close(ncid)
print*,"- READ LATITUDE"
error=nf90_inq_varid(ncid, 'geolat', id_var)
call netcdf_err(error, "READING GEOLAT ID")
error=nf90_get_var(ncid, id_var, dummy)
call netcdf_err(error, "READING GEOLAT")
lat2d=dummy

mask = nint(dummy)
print*,"- READ LONGITUDE"
error=nf90_inq_varid(ncid, 'geolon', id_var)
call netcdf_err(error, "READING GEOLON ID")
error=nf90_get_var(ncid, id_var, dummy)
call netcdf_err(error, "READING GEOLON")
lon2d=dummy

error = nf90_close(ncid)

deallocate (dummy)

end subroutine get_model_mask
end subroutine get_model_info

subroutine model_grid_cleanup

Expand Down Expand Up @@ -361,6 +422,12 @@ subroutine model_grid_cleanup
print*,"- CALL FieldDestroy FOR MODEL GRID VEGETATION TYPE."
call ESMF_FieldDestroy(vegt_field_mdl,rc=rc)

print*,"- CALL FieldDestroy FOR MODEL GRID LATITUDE."
call ESMF_FieldDestroy(latitude_field_mdl,rc=rc)

print*,"- CALL FieldDestroy FOR MODEL GRID LONGITUDE."
call ESMF_FieldDestroy(longitude_field_mdl,rc=rc)

end subroutine model_grid_cleanup

end module model_grid
60 changes: 56 additions & 4 deletions sorc/sfc_climo_gen.fd/output.f90
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
subroutine output(data_one_tile, i_mdl, j_mdl, tile, record, time, field_idx)
subroutine output(data_one_tile, lat_one_tile, lon_one_tile, i_mdl, j_mdl, &
tile, record, time, field_idx)

!--------------------------------------------------------------------------
! subroutine documentation block
!
! Subroutine: output
! prgmmr: gayno org: w/np2 date: 2018
!
! Abstract: Output model data for a single tile and a signle
! Abstract: Output model data for a single tile and a single
! record in netcdf format.
!
! Usage: call output(data_one_tile, i_mdl, j_mdl, tile, record, &
! Usage: call output(data_one_tile, lat_one_tile, lon_one_tile, &
! i_mdl, j_mdl, tile, record, &
! time, field_idx)
!
! input argument list:
! data_one_tile Data to be output (single tile).
! lat_one_tile Latitude of tile.
! lon_one_tile Longitude of tile.
! field_idx Index of field within field name
! array.
! i/j_mdl i/j dimensions of tile.
Expand All @@ -38,6 +42,8 @@ subroutine output(data_one_tile, i_mdl, j_mdl, tile, record, time, field_idx)
integer, intent(in) :: record, time, field_idx

real(esmf_kind_r4), intent(in) :: data_one_tile(i_mdl,j_mdl)
real(esmf_kind_r4), intent(in) :: lat_one_tile(i_mdl,j_mdl)
real(esmf_kind_r4), intent(in) :: lon_one_tile(i_mdl,j_mdl)

character(len=200) :: out_file
character(len=200) :: out_file_with_halo
Expand All @@ -46,7 +52,7 @@ subroutine output(data_one_tile, i_mdl, j_mdl, tile, record, time, field_idx)
integer :: dim_x, dim_y, id_data
integer :: dim_time, id_times
integer :: header_buffer_val = 16384
integer :: i_out, j_out
integer :: i_out, j_out, id_lat, id_lon
integer :: i_start, i_end, j_start, j_end
integer, save :: ncid(6), ncid_with_halo

Expand Down Expand Up @@ -126,11 +132,26 @@ subroutine output(data_one_tile, i_mdl, j_mdl, tile, record, time, field_idx)
call netcdf_err(error, 'DEFINING GLOBAL SOURCE ATTRIBUTE' )
endif

error = nf90_def_var(ncid(tile), 'geolat', NF90_FLOAT, (/dim_x,dim_y/), id_lat)
call netcdf_err(error, 'DEFINING GEOLAT FIELD' )
error = nf90_put_att(ncid(tile), id_lat, "long_name", "Latitude")
call netcdf_err(error, 'DEFINING GEOLAT NAME ATTRIBUTE' )
error = nf90_put_att(ncid(tile), id_lat, "units", "degrees_north")
call netcdf_err(error, 'DEFINING GEOLAT UNIT ATTRIBUTE' )
error = nf90_def_var(ncid(tile), 'geolon', NF90_FLOAT, (/dim_x,dim_y/), id_lon)
call netcdf_err(error, 'DEFINING GEOLON FIELD' )
error = nf90_put_att(ncid(tile), id_lon, "long_name", "Longitude")
call netcdf_err(error, 'DEFINING GEOLON NAME ATTRIBUTE' )
error = nf90_put_att(ncid(tile), id_lon, "units", "degrees_east")
call netcdf_err(error, 'DEFINING GEOLON UNIT ATTRIBUTE' )

do j = 1, num_fields
error = nf90_def_var(ncid(tile), trim(field_names(j)), NF90_FLOAT, (/dim_x,dim_y,dim_time/), id_data)
call netcdf_err(error, 'DEFINING FIELD' )
error = nf90_put_att(ncid(tile), id_data, "missing_value", missing)
call netcdf_err(error, 'DEFINING FIELD ATTRIBUTE' )
error = nf90_put_att(ncid(tile), id_data, "coordinates", "geolon geolat")
call netcdf_err(error, 'DEFINING COORD ATTRIBUTE' )
enddo

error = nf90_enddef(ncid(tile), header_buffer_val,4,0,4)
Expand All @@ -139,6 +160,14 @@ subroutine output(data_one_tile, i_mdl, j_mdl, tile, record, time, field_idx)
error = nf90_put_var( ncid(tile), id_times, day_of_rec)
call netcdf_err(error, 'WRITING TIME FIELD' )

error = nf90_put_var( ncid(tile), id_lat, lat_one_tile(i_start:i_end,j_start:j_end), &
start=(/1,1/), count=(/i_out,j_out/))
call netcdf_err(error, 'IN NF90_PUT_VAR FOR GEOLAT' )

error = nf90_put_var( ncid(tile), id_lon, lon_one_tile(i_start:i_end,j_start:j_end), &
start=(/1,1/), count=(/i_out,j_out/))
call netcdf_err(error, 'IN NF90_PUT_VAR FOR GEOLON' )

endif

print*,'- WRITE DATA FOR RECORD: ',record
Expand Down Expand Up @@ -182,11 +211,26 @@ subroutine output(data_one_tile, i_mdl, j_mdl, tile, record, time, field_idx)
call netcdf_err(error, 'DEFINING GLOBAL SOURCE ATTRIBUTE' )
endif

error = nf90_def_var(ncid_with_halo, 'geolat', NF90_FLOAT, (/dim_x,dim_y/), id_lat)
call netcdf_err(error, 'DEFINING GEOLAT FIELD' )
error = nf90_put_att(ncid_with_halo, id_lat, "long_name", "Latitude")
call netcdf_err(error, 'DEFINING GEOLAT NAME ATTRIBUTE' )
error = nf90_put_att(ncid_with_halo, id_lat, "units", "degrees_north")
call netcdf_err(error, 'DEFINING GEOLAT UNIT ATTRIBUTE' )
error = nf90_def_var(ncid_with_halo, 'geolon', NF90_FLOAT, (/dim_x,dim_y/), id_lon)
call netcdf_err(error, 'DEFINING GEOLON FIELD' )
error = nf90_put_att(ncid_with_halo, id_lon, "long_name", "Longitude")
call netcdf_err(error, 'DEFINING GEOLON NAME ATTRIBUTE' )
error = nf90_put_att(ncid_with_halo, id_lon, "units", "degrees_east")
call netcdf_err(error, 'DEFINING GEOLON UNIT ATTRIBUTE' )

do j = 1, num_fields
error = nf90_def_var(ncid_with_halo, field_names(j), NF90_FLOAT, (/dim_x,dim_y,dim_time/), id_data)
call netcdf_err(error, 'DEFINING FIELD VARIABLE' )
error = nf90_put_att(ncid_with_halo, id_data, "missing_value", missing)
call netcdf_err(error, 'DEFINING FIELD ATTRIBUTE' )
error = nf90_put_att(ncid_with_halo, id_data, "coordinates", "geolon geolat")
call netcdf_err(error, 'DEFINING COORD ATTRIBUTE' )
enddo

error = nf90_enddef(ncid_with_halo, header_buffer_val,4,0,4)
Expand All @@ -195,6 +239,14 @@ subroutine output(data_one_tile, i_mdl, j_mdl, tile, record, time, field_idx)
error = nf90_put_var(ncid_with_halo, id_times, day_of_rec)
call netcdf_err(error, 'WRITING TIME VARIABLE' )

error = nf90_put_var( ncid_with_halo, id_lat, lat_one_tile, &
start=(/1,1/), count=(/i_mdl,j_mdl/))
call netcdf_err(error, 'IN NF90_PUT_VAR FOR GEOLAT' )

error = nf90_put_var( ncid_with_halo, id_lon, lon_one_tile, &
start=(/1,1/), count=(/i_mdl,j_mdl/))
call netcdf_err(error, 'IN NF90_PUT_VAR FOR GEOLON' )

endif

print*,'- WRITE DATA FOR RECORD: ',record
Expand Down

0 comments on commit ff45e5f

Please sign in to comment.