31 public :: file_grads_get_shape
32 public :: file_grads_read
35 interface file_grads_get_shape
38 end interface file_grads_get_shape
40 interface file_grads_read
41 module procedure file_grads_read_1d_name
43 module procedure file_grads_read_2d_name
45 module procedure file_grads_read_3d_name
47 end interface file_grads_read
60 integer,
parameter :: nmls_max = 10
61 integer,
parameter :: vars_max = 100
62 integer,
parameter :: lvars_max = 1000
64 character(len=H_SHORT) :: name
65 character(len=H_LONG) :: fname
66 character(len=H_SHORT) :: dtype
70 real(RP),
allocatable :: lvars(:)
79 character(len=H_SHORT) :: bintype
82 character(len=H_LONG) :: fname
84 type(t_var),
allocatable :: vars(:)
88 character(len=H_LONG) :: fname
89 character(len=H_SHORT) :: postfix
92 type(t_nml),
save :: nmls(nmls_max)
94 type(t_file) :: files(vars_max)
109 character(len=*),
intent(in) :: file_name
110 integer,
intent(out) :: file_id
112 character(len=H_SHORT) :: name
113 character(len=H_SHORT) :: dtype
114 character(len=H_LONG) :: fname
118 real(
rp) :: lvars(lvars_max)
125 character(len=H_SHORT) :: fendian
127 character(len=H_SHORT) :: bintype
129 namelist /grads_dims/ &
134 namelist /grads_item/ &
152 character(len=H_LONG) :: dirname
163 log_info(
"FILE_GrADS_open",*)
'open namelist file :', trim(fname)
167 if ( nmls(n)%fname == fname )
then
179 form =
'formatted', &
183 if ( ierr /= 0 )
then
184 log_error(
"FILE_GrADS_open",*)
'Input file is not found! ', trim(fname)
188 call check_oldnamelist( fid )
191 read(fid,nml=grads_dims,iostat=ierr)
193 log_error(
"FILE_GrADS_open",*)
'Not appropriate names in GrADS_DIMS in ', trim(fname),
'. Check!'
200 if ( nnmls > nmls_max )
then
201 log_error(
"FILE_GrADS_open",*)
'Number of GrADS file to be open is exceeded the maximum', nmls_max
206 nmls(file_id)%fname = file_name
207 nmls(file_id)%nx = nx
208 nmls(file_id)%ny = ny
209 nmls(file_id)%nz = nz
217 read(fid, nml=grads_item, iostat=ierr)
219 log_error(
"FILE_GrADS_open",*)
'Not appropriate names in GrADS_ITEM in ', trim(file_name),
'. Check!'
221 else if( ierr < 0 )
then
227 if ( nvars > vars_max )
then
228 log_error(
"FILE_GRADS_open",*)
'The number of grads vars exceeds the limit! ', &
229 nvars,
' > ', vars_max
233 nmls(file_id)%nvars = nvars
234 allocate( nmls(file_id)%vars(nvars) )
236 n = index( file_name,
'/', back=.true. )
238 dirname = file_name(1:n)
257 nx = nmls(file_id)%nx
258 ny = nmls(file_id)%ny
259 nz = nmls(file_id)%nz
266 read(fid, nml=grads_item, iostat=ierr)
269 nmls(file_id)%vars(n)%name =
upcase(name)
270 if ( fname(1:1) ==
"/" )
then
271 nmls(file_id)%vars(n)%fname = fname
273 nmls(file_id)%vars(n)%fname = trim(dirname) // fname
275 nmls(file_id)%vars(n)%dtype = dtype
276 nmls(file_id)%vars(n)%swpoint = swpoint
277 nmls(file_id)%vars(n)%dd = dd
278 nmls(file_id)%vars(n)%lnum = lnum
280 if ( lnum > lvars_max )
then
281 log_error(
"FILE_GrADS_open",*)
'lnum exceeds the limit', lvars_max
284 allocate( nmls(file_id)%vars(n)%lvars(lnum) )
285 nmls(file_id)%vars(n)%lvars(:) = lvars(1:lnum)
287 nmls(file_id)%vars(n)%startrec = startrec
288 nmls(file_id)%vars(n)%totalrec = totalrec
289 nmls(file_id)%vars(n)%missval = missval
290 nmls(file_id)%vars(n)%nx = nx
291 nmls(file_id)%vars(n)%ny = ny
292 nmls(file_id)%vars(n)%nz = nz
293 nmls(file_id)%vars(n)%yrev = yrev
294 if ( fendian ==
"big" )
then
295 nmls(file_id)%vars(n)%endian = 1
297 nmls(file_id)%vars(n)%endian = 0
299 nmls(file_id)%vars(n)%bintype = bintype
315 integer,
intent(in) :: file_id
316 character(len=*),
intent(in) :: var_name
317 integer,
intent(out) :: var_id
319 character(len=len(var_name)) :: vname
322 if ( file_id < 0 )
then
323 log_error(
"FILE_GrADS_varid",*)
'file_id is invalid: ', file_id
330 do n = 1, nmls(file_id)%nvars
331 if ( nmls(file_id)%vars(n)%name == vname )
then
347 integer,
intent(in) :: file_id
348 character(len=*),
intent(in) :: var_name
349 logical,
intent(out) :: exist
353 if ( file_id < 0 )
then
354 log_error(
"FILE_GrADS_varcheck",*)
'file_id is invalid: ', file_id
362 if ( var_id < 0 )
then
376 integer,
intent(in) :: file_id
377 integer,
intent(in) :: var_id
380 if ( file_id < 0 )
then
381 log_error(
"FILE_GrADS_isOneD",*)
'file_id is invalid: ', file_id
384 if ( var_id < 0 )
then
385 log_error(
"FILE_GrADS_isOneD",*)
'var_id is invalid: ', var_id
389 select case( nmls(file_id)%vars(var_id)%dtype )
390 case (
'linear',
'levels')
407 integer,
intent(in) :: file_id
408 character(len=*),
intent(in) :: var_name
409 integer,
intent(out) :: shape(:)
416 if ( var_id < 0 )
then
417 log_error(
"FILE_GrADS_get_shape",*)
'variable "', trim(var_name),
' is not founed in file "', trim(nmls(file_id)%fname),
'"'
432 integer,
intent(in) :: file_id
433 integer,
intent(in) :: var_id
434 integer,
intent(out) :: shape(:)
439 if ( nmls(file_id)%vars(var_id)%dtype ==
"levels" )
then
440 shape(1) = nmls(file_id)%vars(var_id)%lnum
444 else if (
size(shape) == 2 )
then
445 shape(1) = nmls(file_id)%vars(var_id)%nx
446 shape(2) = nmls(file_id)%vars(var_id)%ny
448 shape(1) = nmls(file_id)%vars(var_id)%nz
449 shape(2) = nmls(file_id)%vars(var_id)%nx
450 shape(3) = nmls(file_id)%vars(var_id)%ny
457 subroutine file_grads_read_1d_name( &
468 integer,
intent(in) :: file_id
469 character(len=*),
intent(in) :: var_name
470 real(RP),
intent(out) :: var(:)
471 integer,
intent(in),
optional :: step
472 integer,
intent(in),
optional :: start(1)
473 integer,
intent(in),
optional :: count(1)
474 character(len=*),
intent(in),
optional :: postfix
482 if ( var_id < 0 )
then
483 log_error(
"FILE_GrADS_read_1D_name",*)
'variable "', trim(var_name),
' is not founed in file "', trim(nmls(file_id)%fname),
'"'
496 end subroutine file_grads_read_1d_name
507 integer,
intent(in) :: file_id
508 integer,
intent(in) :: var_id
509 real(RP),
intent(out) :: var(:)
510 integer,
intent(in),
optional :: step
511 integer,
intent(in),
optional :: start(1)
512 integer,
intent(in),
optional :: count(1)
513 character(len=*),
intent(in),
optional :: postfix
521 if ( file_id < 0 )
then
522 log_error(
"FILE_GrADS_read_1D_vid",*)
'file_id is invalid: ', file_id
524 if ( var_id < 0 )
then
525 log_error(
"FILE_GrADS_read_1D_vid",*)
'var_id is invalid: ', var_id
528 call file_grads_read_data( nmls(file_id)%vars(var_id), &
529 1,
size(var), shape(var), &
540 subroutine file_grads_read_2d_name( &
551 integer,
intent(in) :: file_id
552 character(len=*),
intent(in) :: var_name
553 real(RP),
intent(out) :: var(:,:)
554 integer,
intent(in),
optional :: step
555 integer,
intent(in),
optional :: start(2)
556 integer,
intent(in),
optional :: count(2)
557 character(len=*),
intent(in),
optional :: postfix
565 if ( var_id < 0 )
then
566 log_error(
"FILE_GrADS_read_2D_name",*)
'variable "', trim(var_name),
' is not founed in file "', trim(nmls(file_id)%fname),
'"'
578 end subroutine file_grads_read_2d_name
589 integer,
intent(in) :: file_id
590 integer,
intent(in) :: var_id
591 real(RP),
intent(out) :: var(:,:)
592 integer,
intent(in),
optional :: step
593 integer,
intent(in),
optional :: start(2)
594 integer,
intent(in),
optional :: count(2)
595 character(len=*),
intent(in),
optional :: postfix
601 if ( file_id < 0 )
then
602 log_error(
"FILE_GrADS_read_2D_vid",*)
'file_id is invalid: ', file_id
604 if ( var_id < 0 )
then
605 log_error(
"FILE_GrADS_read_2D_vid",*)
'var_id is invalid: ', var_id
608 call file_grads_read_data( nmls(file_id)%vars(var_id), &
609 2,
size(var), shape(var), &
620 subroutine file_grads_read_3d_name( &
631 integer,
intent(in) :: file_id
632 character(len=*),
intent(in) :: var_name
633 real(RP),
intent(out) :: var(:,:,:)
634 integer,
intent(in),
optional :: step
635 integer,
intent(in),
optional :: start(3)
636 integer,
intent(in),
optional :: count(3)
637 character(len=*),
intent(in),
optional :: postfix
645 if ( var_id < 0 )
then
646 log_error(
"FILE_GrADS_read_3D_name",*)
'variable "', trim(var_name),
' is not founed in file "', trim(nmls(file_id)%fname),
'"'
658 end subroutine file_grads_read_3d_name
669 integer,
intent(in) :: file_id
670 integer,
intent(in) :: var_id
671 real(RP),
intent(out) :: var(:,:,:)
672 integer,
intent(in),
optional :: step
673 integer,
intent(in),
optional :: start(3)
674 integer,
intent(in),
optional :: count(3)
675 character(len=*),
intent(in),
optional :: postfix
681 if ( file_id < 0 )
then
682 log_error(
"FILE_GrADS_read_3D_vid",*)
'file_id is invalid: ', file_id
684 if ( var_id < 0 )
then
685 log_error(
"FILE_GrADS_read_3D_vid",*)
'var_id is invalid: ', var_id
688 call file_grads_read_data( nmls(file_id)%vars(var_id), &
689 3,
size(var), shape(var), &
714 integer,
intent(in) :: file_id
718 if ( file_id < 0 )
return
720 do n = 1, nmls(file_id)%nvars
722 if ( files(m)%fname == nmls(file_id)%vars(n)%fname )
then
723 if ( files(m)%fid > 0 )
then
724 close( files(m)%fid )
726 files(m)%postfix =
""
731 if ( nmls(file_id)%vars(n)%lnum > 0 )
deallocate( nmls(file_id)%vars(n)%lvars )
732 nmls(file_id)%vars(n)%lnum = -1
734 deallocate( nmls(file_id)%vars )
735 nmls(file_id)%fname =
""
736 nmls(file_id)%nvars = 0
745 subroutine file_grads_read_data( &
760 type(t_var),
intent(in) :: var_info
761 integer,
intent(in) :: ndims
762 integer,
intent(in) :: n
763 integer,
intent(in) :: shape(ndims)
764 real(
rp),
intent(out) :: var(n)
765 integer,
intent(in),
optional :: step
766 integer,
intent(in),
optional :: start(ndims)
767 integer,
intent(in),
optional :: count(ndims)
768 character(len=*),
intent(in),
optional :: postfix
771 character(len=H_LONG) :: gfile
772 real(
sp) :: buf(var_info%nx,var_info%ny)
777 character(len=H_SHORT) :: postfix_
779 integer :: nxy, nz, ka
780 integer :: pos, isize, ierr
781 integer :: i, j, k, ii, jj, kk
784 subroutine rd( fid, pos, nx, cz, k, sx, cx, cy, yrev, var, ierr )
786 integer,
intent(in) :: fid, pos
787 integer,
intent(in) :: nx, cz, k, sx, cx, cy
788 logical,
intent(in) :: yrev
789 real(
rp),
intent(out) :: var(:)
790 integer,
intent(out) :: ierr
793 procedure(rd),
pointer :: read_data
795 select case( var_info%dtype )
798 if ( ndims > 1 )
then
799 log_error(
"FILE_GrADS_read_data",*)
'"linear" is invalid for dtype of 2D or 2D var!'
802 if( var_info%swpoint == undef .or.var_info%dd == undef )
then
803 log_error(
"FILE_GrADS_read_data",*)
'"swpoint" and "dd" are required for linear data! ', var_info%swpoint
807 if (
present(start) )
then
812 if (
present(count) )
then
815 count_(1) = n - start_(1) + 1
819 ii = i + start_(1) - 2
820 var(i) = var_info%swpoint + ii * var_info%dd
825 if ( ndims > 1 )
then
826 log_error(
"FILE_GrADS_read_data",*)
'"levels" is invalid for dtype of 2D or 2D var!'
829 if ( var_info%lnum < 0 )
then
830 log_error(
"FILE_GrADS_read_data",*)
'"lnum" is required for levels data! '
833 if ( var_info%lnum .ne. n )
then
834 log_error(
"FILE_GrADS_read_data",*)
'"lnum" and size of var are not the same', var_info%lnum, n
838 if (
present(start) )
then
843 if (
present(count) )
then
846 count_(1) = var_info%lnum - start_(1) + 1
850 kk = k + start_(1) - 1
851 if ( kk > var_info%lnum )
exit
852 var(k) = var_info%lvars(kk)
853 if( var(k) == undef )
then
854 log_error(
"FILE_GrADS_read_data",*)
'"lvars" must be specified for levels data! '
861 if (
present(postfix) )
then
866 if (
present(step) )
then
872 if ( ndims == 1 )
then
873 log_error(
"FILE_GrADS_read_data",*)
'"map" is invalid for dtype of 1D var!'
876 if( var_info%startrec < 0 .or. var_info%totalrec < 0 )
then
877 log_error(
"FILE_GrADS_read_data",*)
'"startrec" and "totalrec" are required for map data! ', var_info%startrec, var_info%totalrec
880 if( var_info%fname ==
"" )
then
881 log_error(
"FILE_GrADS_read_data",*)
'"fname" is required for map data!'
888 if ( files(i)%fname == var_info%fname )
then
895 if ( nfiles > vars_max )
then
896 log_error(
"FILE_GrADS_read_data",*)
'The number of files exceeds the limit', vars_max
900 files(fid)%fname = var_info%fname
901 files(fid)%postfix =
""
905 call io_get_fname(gfile, trim(var_info%fname)//trim(postfix_)//
'.grd')
907 if ( files(fid)%postfix == postfix_ .and. files(fid)%fid > 0 )
then
910 if ( files(fid)%fid > 0 )
close( files(fid)%fid )
912 files(fid)%postfix = postfix_
916 form =
'unformatted', &
920 if ( ierr /= 0 )
then
921 log_error(
"FILE_GrADS_read_data",*)
'Failed to open the grads data file! ', trim(gfile)
926 if ( ndims == 2 )
then
930 if (
present(start) )
then
931 start_(2:3) = start(:)
936 if (
present(count) )
then
937 count_(2:3) = count(:)
939 count_(2:3) = (/ var_info%nx, var_info%ny /)
941 if ( shape(1) .ne. count_(2) .or. shape(2) .ne. count_(3) )
then
942 log_error(
"FILE_GrADS_read_data",*)
'nx or ny is different', shape(:), count_(2:3)
948 if (
present(start) )
then
953 if (
present(count) )
then
956 count_(:) = (/ nz, var_info%nx, var_info%ny /)
958 if ( ka < count_(1) )
then
959 log_error(
"FILE_GrADS_read_data",*)
'size is too small for the 1st dimension'
962 if ( shape(2) .ne. count_(2) .or. shape(3) .ne. count_(3) )
then
963 log_error(
"FILE_GrADS_read_data",*)
'nx or ny is different', shape(2:), count_(2:)
966 count_(1) = min( count_(1), nz )
968 nxy = count_(2) * count_(3)
971 if ( n .ne. nxy * ka )
then
972 log_error(
"FILE_GrADS_read_data",*)
'size of var is not consitent with namelist info! ', n, ka, count_(2:3)
976 select case ( var_info%bintype )
981 read_data => read_data_int2
984 read_data => read_data_int4
987 read_data => read_data_real4
990 read_data => read_data_int8
993 read_data => read_data_real8
996 log_error(
"FILE_GrADS_read_data",*)
'bintype is invalid for ', trim(var_info%name)
1000 kk = k + start_(1) - 2
1001 pos = ( var_info%totalrec * ( step_ - 1 ) + var_info%startrec - 1 + kk ) * var_info%ny
1002 if ( var_info%yrev )
then
1003 pos = pos + var_info%ny - ( start_(3) + count_(3) - 1 )
1005 pos = pos + start_(3) - 1
1007 pos = pos * var_info%nx * isize + 1
1008 call read_data( fid, pos, ka, var_info%nx, k, start_(2), count_(2), count_(3), var_info%yrev, var(:), ierr )
1009 if ( ierr /= 0 )
then
1010 log_error(
"FILE_GrADS_read_data",*)
'Failed to read data! ', trim(var_info%name),
', k=',k,
', step=',step_,
' in ', trim(gfile)
1011 log_error_cont(*)
'pos=', pos
1015 if ( var_info%missval .ne. undef )
then
1021 if ( abs( var(ii) - var_info%missval ) < eps ) var(ii) = undef
1028 do k = count_(1)+1, ka
1037 end subroutine file_grads_read_data
1039 subroutine read_data_int1( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1040 integer,
intent(in) :: fid, pos
1041 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1042 logical,
intent(in) :: yrev
1044 real(RP),
intent(out) :: var(:)
1045 integer,
intent(out) :: ierr
1047 integer(1) :: buf(nx,cy)
1050 read(fid, pos=pos, iostat=ierr) buf(:,:)
1051 if ( ierr /= 0 )
return
1057 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1064 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1072 subroutine read_data_int2( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1073 integer,
intent(in) :: fid, pos
1074 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1075 logical,
intent(in) :: yrev
1077 real(RP),
intent(out) :: var(:)
1078 integer,
intent(out) :: ierr
1080 integer(2) :: buf(nx,cy)
1083 read(fid, pos=pos, iostat=ierr) buf(:,:)
1084 if ( ierr /= 0 )
return
1090 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1097 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1103 end subroutine read_data_int2
1105 subroutine read_data_int4( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1106 integer,
intent(in) :: fid, pos
1107 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1108 logical,
intent(in) :: yrev
1110 real(RP),
intent(out) :: var(:)
1111 integer,
intent(out) :: ierr
1113 integer(4) :: buf(nx,cy)
1116 read(fid, pos=pos, iostat=ierr) buf(:,:)
1117 if ( ierr /= 0 )
return
1123 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1130 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1136 end subroutine read_data_int4
1138 subroutine read_data_real4( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1139 integer,
intent(in) :: fid, pos
1140 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1141 logical,
intent(in) :: yrev
1143 real(RP),
intent(out) :: var(:)
1144 integer,
intent(out) :: ierr
1146 real(4) :: buf(nx,cy)
1149 read(fid, pos=pos, iostat=ierr) buf(:,:)
1150 if ( ierr /= 0 )
return
1156 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1163 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1169 end subroutine read_data_real4
1171 subroutine read_data_int8( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1172 integer,
intent(in) :: fid, pos
1173 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1174 logical,
intent(in) :: yrev
1176 real(RP),
intent(out) :: var(:)
1177 integer,
intent(out) :: ierr
1179 integer(8) :: buf(nx,cy)
1182 read(fid, pos=pos, iostat=ierr) buf(:,:)
1183 if ( ierr /= 0 )
return
1189 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1196 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1202 end subroutine read_data_int8
1204 subroutine read_data_real8( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1205 integer,
intent(in) :: fid, pos
1206 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1207 logical,
intent(in) :: yrev
1209 real(RP),
intent(out) :: var(:)
1210 integer,
intent(out) :: ierr
1212 real(8) :: buf(nx,cy)
1215 read(fid, pos=pos, iostat=ierr) buf(:,:)
1216 if ( ierr /= 0 )
return
1222 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1229 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1235 end subroutine read_data_real8
1237 subroutine check_oldnamelist( fid )
1241 integer,
intent(in) :: fid
1246 namelist /nml_grads_grid/ dummy
1247 namelist /grdvar/ dummy
1249 read(fid, nml=nml_grads_grid, iostat=ierr)
1251 log_error(
"check_oldnamelist",*)
'The old namelist "nml_grads_grid" is found.'
1252 log_error_cont(*)
'Use "GrADS_DIMS" instead.'
1257 read(fid, nml=grdvar, iostat=ierr)
1259 log_error(
"check_oldnamelist",*)
'The old namelist "grdvar" is found.'
1260 log_error_cont(*)
'Use "GrADS_ITEM" instead.'
1266 end subroutine check_oldnamelist
1270 character(len=*),
intent(in) :: str
1271 character(len=len(str)) ::
upcase
1273 do i = 1, len_trim(str)
1274 if ( str(i:i) >=
'a' .and. str(i:i) <=
'z' )
then
1275 upcase(i:i) = char( ichar(str(i:i)) - 32 )
1280 do i = len_trim(str)+1, len(str)