Recipe: Fortran program as OPeNDAP client: Difference between revisions
Move from http to https |
|||
(49 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
Back to [[G5NR Data Access Guide]]. | |||
== Problem == | |||
By accessing the collection <code>inst01hr_3d_T_Cv</code> via the OPeNDAP server | |||
https://opendap.nccs.nasa.gov/dods/OSSE/G5NR/Ganymed/7km | |||
we want to read the surface temperature data inside the box bound by latitudes 25<sup>o</sup>N, 50<sup>o</sup>N and longitudes -130<sup>o</sup>W, -65<sup>o</sup>W for 2006/Sep/18, 9z and compute its min/max. | |||
== Solution == | |||
First, we ensure that our NetCDF-4 library has been built with Fortran and OPeNDAP support. If both the queries | |||
> nc-config --has-f90 | > nc-config --has-f90 | ||
> nc-config --has-dap | > nc-config --has-dap | ||
return "yes", we have a compatible NetCDF-4 library. Here <code>nc-config</code> is a utility bundled with NetCDF-4 package. | |||
The metadata for the collection <code>inst01hr_3d_T_Cv</code> is available at | |||
https://opendap.nccs.nasa.gov/dods/OSSE/G5NR/Ganymed/7km/0.5000_deg/inst/inst01hr_3d_T_Cv.info | |||
==== Code ==== | |||
This code accesses the collection <code>inst01hr_3d_T_Cv</code> from the OPeNDAP server, reads a subset of the temperature data (all levels inside the bounding box specified above) and computes its max/min. | |||
NOTE: | |||
# Instead of reading a downloaded NetCDF-4 file, we read an OPeNDAP URL. | |||
# While in the downloaded file, the temperature variable appears in the uppercase (T), on the OPeNDAP server, this variable is in lowercase. This is reflected in the call to <code>nf90_inq_varid</code>. | |||
# Via the OPeNDAP URL, we now have access to all times for which data exists. The hourly <code>inst</code> files are available starting at 2005/15/15, 2200z. Our desired time, 2006/09/18, 0900z is then the 11772<sup>th</sup> step. | |||
<syntaxhighlight lang="fortran" line> | <syntaxhighlight lang="fortran" line> | ||
program | program g5nr_reader_dap | ||
use netcdf ! for reading the NR files | use netcdf ! for reading the NR files | ||
Line 32: | Line 39: | ||
! 4D array: (lon,lat,lev,time) | ! 4D array: (lon,lat,lev,time) | ||
! ------------------------------------ | ! ------------------------------------ | ||
real, allocatable :: T(:,:,:,:) | real, allocatable :: T(:,:,:,:) | ||
! Miscellaneous | ! Miscellaneous | ||
Line 39: | Line 45: | ||
integer :: ierr | integer :: ierr | ||
integer :: im, jm, lm | integer :: im, jm, lm | ||
integer :: ncid, varid | integer :: ncid, varid | ||
integer :: start(4), count(4) | integer :: start(4), count(4) | ||
integer :: imin, imax, jmin, jmax | |||
real :: minlat, minlon, maxlat, maxlon | |||
! file name and dimensions | ! We replace filename by opendal url | ||
! ------------------------ | ! ---------------------------------- | ||
im = | T_file = "https://opendap.nccs.nasa.gov:9090/dods/OSSE/G5NR/Ganymed/7km/0.5000_deg/inst/inst01hr_3d_T_Cv" | ||
jm = | |||
! file name and (subset) dimensions | |||
! bounding box: | |||
! lons = -130:0.5:-65 | |||
! lats = 25:0.5:50 | |||
! --------------------------------- | |||
! array indices from the | |||
! bounding lat/lon values | |||
imin = nint((-130. + 180.)/0.5) | |||
imax = nint(( -65. + 180.)/0.5) | |||
jmin = nint(( 25 + 90.)/0.5) | |||
jmax = nint(( 50 + 90.)/0.5) | |||
! array sizes | |||
im = imax-imin+1 | |||
jm = jmax-jmin+1 | |||
lm = 72 | lm = 72 | ||
! Open | ! Open url and get var id | ||
! | ! ----------------------- | ||
call check(nf90_open(T_file,NF90_NOWRITE,ncid), "opening T file") | call check(nf90_open(T_file,NF90_NOWRITE,ncid), "opening T file") | ||
call check(nf90_inq_varid(ncid," | call check(nf90_inq_varid(ncid,"t",varid), "getting T varid") | ||
! Read | ! Read temperature data | ||
! | ! --------------------- | ||
allocate(T(im,jm,lm,1)) | allocate(T(im,jm,lm,1)) ! global 4D array with 1 time level | ||
start = | start = [imin, jmin, 1, 11772] ! time level 11772 corresponds to 2006/09/18, 9z | ||
count = | count = [im, jm, lm, 1] ! 1 time level, 3D (lon,lat,lev) array | ||
write(*,*) 'Reading | write(*,*) 'Reading T...' | ||
call check(nf90_get_var(ncid,varid,T,start=start,count=count), "reading T") | call check(nf90_get_var(ncid,varid,T,start=start,count=count), "reading T") | ||
write(*,*)'T: ', maxval(T),minval(T) | write(*,*)'T: ', maxval(T),minval(T) | ||
! close file, release memory | ! close file, release memory | ||
call check(nf90_close(ncid), "closing T file") | call check(nf90_close(ncid), "closing T file") | ||
deallocate(T) | deallocate(T) | ||
! All done | ! All done | ||
Line 109: | Line 105: | ||
end subroutine check | end subroutine check | ||
end program | end program g5nr_reader_dap | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Compile and link ==== | ==== Compile and link ==== | ||
We use the utility <code>nf-config</code> (included in the NetCDF-4 installation) to identify the | We use the utility <code>nf-config</code> (included in the NetCDF-4 installation) to identify the linking rules | ||
For a typical NetCDF-4 installation, the above code, <code> | For a typical NetCDF-4 installation, the above code, <code>g5nr_reader_dap.f90</code> can be compiled and linked to the NetCDF-4 library via | ||
gfortran -o g5nr_reader_dap.x `nf-config --fflags` g5nr_reader_dap.f90 `nf-config --flibs` | |||
creating the executable <code>g5nr_reader_dap.x</code>. | |||
creating the executable <code> | |||
NOTE: | NOTE: | ||
Line 131: | Line 124: | ||
Running the executable, | Running the executable, | ||
./ | ./g5nr_reader_dap.x | ||
produces the output | produces the output | ||
Reading T | Reading T (subset)... | ||
T (subset): 305.6048 191.6956 | |||
== Discussion == | |||
== See Also == | |||
# File Spec: [[File:G5NR-Ganymed-7km FileSpec-ON6-V1.0.pdf]] | |||
# [[Recipe: Fortran program to read data from downloaded file]] | |||
== No Warranty == | |||
== Copyright == | |||
==== | |||