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_
781 integer :: nxy, nz, ka
782 integer :: isize, ierr
783 integer :: i, j, k, ii, jj, kk
786 subroutine rd( fid, pos, nx, cz, k, sx, cx, cy, yrev, var, ierr )
788 integer,
intent(in) :: fid
789 integer(8),
intent(in) :: pos
790 integer,
intent(in) :: nx, cz, k, sx, cx, cy
791 logical,
intent(in) :: yrev
792 real(
rp),
intent(out) :: var(:)
793 integer,
intent(out) :: ierr
796 procedure(rd),
pointer :: read_data
798 select case( var_info%dtype )
801 if ( ndims > 1 )
then
802 log_error(
"FILE_GrADS_read_data",*)
'"linear" is invalid for dtype of 2D or 2D var!'
805 if( var_info%swpoint == undef .or.var_info%dd == undef )
then
806 log_error(
"FILE_GrADS_read_data",*)
'"swpoint" and "dd" are required for linear data! ', var_info%swpoint
810 if (
present(start) )
then
815 if (
present(count) )
then
818 count_(1) = n - start_(1) + 1
822 ii = i + start_(1) - 2
823 var(i) = var_info%swpoint + ii * var_info%dd
828 if ( ndims > 1 )
then
829 log_error(
"FILE_GrADS_read_data",*)
'"levels" is invalid for dtype of 2D or 2D var!'
832 if ( var_info%lnum < 0 )
then
833 log_error(
"FILE_GrADS_read_data",*)
'"lnum" is required for levels data! '
836 if ( var_info%lnum .ne. n )
then
837 log_error(
"FILE_GrADS_read_data",*)
'"lnum" and size of var are not the same', var_info%lnum, n
841 if (
present(start) )
then
846 if (
present(count) )
then
849 count_(1) = var_info%lnum - start_(1) + 1
853 kk = k + start_(1) - 1
854 if ( kk > var_info%lnum )
exit
855 var(k) = var_info%lvars(kk)
856 if( var(k) == undef )
then
857 log_error(
"FILE_GrADS_read_data",*)
'"lvars" must be specified for levels data! '
864 if (
present(postfix) )
then
869 if (
present(step) )
then
875 if ( ndims == 1 )
then
876 log_error(
"FILE_GrADS_read_data",*)
'"map" is invalid for dtype of 1D var!'
879 if( var_info%startrec < 0 .or. var_info%totalrec < 0 )
then
880 log_error(
"FILE_GrADS_read_data",*)
'"startrec" and "totalrec" are required for map data! ', var_info%startrec, var_info%totalrec
883 if( var_info%fname ==
"" )
then
884 log_error(
"FILE_GrADS_read_data",*)
'"fname" is required for map data!'
891 if ( files(i)%fname == var_info%fname )
then
898 if ( nfiles > vars_max )
then
899 log_error(
"FILE_GrADS_read_data",*)
'The number of files exceeds the limit', vars_max
903 files(fid)%fname = var_info%fname
904 files(fid)%postfix =
""
908 call io_get_fname(gfile, trim(var_info%fname)//trim(postfix_)//
'.grd')
910 if ( files(fid)%postfix == postfix_ .and. files(fid)%fid > 0 )
then
913 if ( files(fid)%fid > 0 )
close( files(fid)%fid )
915 files(fid)%postfix = postfix_
919 form =
'unformatted', &
923 if ( ierr /= 0 )
then
924 log_error(
"FILE_GrADS_read_data",*)
'Failed to open the grads data file! ', trim(gfile)
929 if ( ndims == 2 )
then
933 if (
present(start) )
then
934 start_(2:3) = start(:)
939 if (
present(count) )
then
940 count_(2:3) = count(:)
942 count_(2:3) = (/ var_info%nx, var_info%ny /)
944 if ( shape(1) .ne. count_(2) .or. shape(2) .ne. count_(3) )
then
945 log_error(
"FILE_GrADS_read_data",*)
'nx or ny is different', shape(:), count_(2:3)
951 if (
present(start) )
then
956 if (
present(count) )
then
959 count_(:) = (/ nz, var_info%nx, var_info%ny /)
961 if ( ka < count_(1) )
then
962 log_error(
"FILE_GrADS_read_data",*)
'size is too small for the 1st dimension'
965 if ( shape(2) .ne. count_(2) .or. shape(3) .ne. count_(3) )
then
966 log_error(
"FILE_GrADS_read_data",*)
'nx or ny is different', shape(2:), count_(2:)
969 count_(1) = min( count_(1), nz )
971 nxy = count_(2) * count_(3)
974 if ( n .ne. nxy * ka )
then
975 log_error(
"FILE_GrADS_read_data",*)
'size of var is not consitent with namelist info! ', n, ka, count_(2:3)
979 select case ( var_info%bintype )
984 read_data => read_data_int2
987 read_data => read_data_int4
990 read_data => read_data_real4
993 read_data => read_data_int8
996 read_data => read_data_real8
999 log_error(
"FILE_GrADS_read_data",*)
'bintype is invalid for ', trim(var_info%name)
1003 kk = k + start_(1) - 2
1004 pos = ( var_info%totalrec * ( step_ - 1 ) + var_info%startrec - 1 + kk ) * var_info%ny
1005 if ( var_info%yrev )
then
1006 pos = pos + var_info%ny - ( start_(3) + count_(3) - 1 )
1008 pos = pos + start_(3) - 1
1010 pos = pos * var_info%nx * isize + 1
1011 call read_data( fid, pos, ka, var_info%nx, k, start_(2), count_(2), count_(3), var_info%yrev, var(:), ierr )
1012 if ( ierr /= 0 )
then
1013 log_error(
"FILE_GrADS_read_data",*)
'Failed to read data! ', trim(var_info%name),
', k=',k,
', step=',step_,
' in ', trim(gfile)
1014 log_error_cont(*)
'pos=', pos
1018 if ( var_info%missval .ne. undef )
then
1024 if ( abs( var(ii) - var_info%missval ) < eps ) var(ii) = undef
1031 do k = count_(1)+1, ka
1040 end subroutine file_grads_read_data
1042 subroutine read_data_int1( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1043 integer,
intent(in) :: fid
1044 integer(8),
intent(in) :: pos
1045 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1046 logical,
intent(in) :: yrev
1048 real(RP),
intent(out) :: var(:)
1049 integer,
intent(out) :: ierr
1051 integer(1) :: buf(nx,cy)
1054 read(fid, pos=pos, iostat=ierr) buf(:,:)
1055 if ( ierr /= 0 )
return
1061 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1068 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1076 subroutine read_data_int2( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1077 integer,
intent(in) :: fid
1078 integer(8),
intent(in) :: pos
1079 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1080 logical,
intent(in) :: yrev
1082 real(RP),
intent(out) :: var(:)
1083 integer,
intent(out) :: ierr
1085 integer(2) :: buf(nx,cy)
1088 read(fid, pos=pos, iostat=ierr) buf(:,:)
1089 if ( ierr /= 0 )
return
1095 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1102 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1108 end subroutine read_data_int2
1110 subroutine read_data_int4( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1111 integer,
intent(in) :: fid
1112 integer(8),
intent(in) :: pos
1113 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1114 logical,
intent(in) :: yrev
1116 real(RP),
intent(out) :: var(:)
1117 integer,
intent(out) :: ierr
1119 integer(4) :: buf(nx,cy)
1122 read(fid, pos=pos, iostat=ierr) buf(:,:)
1123 if ( ierr /= 0 )
return
1129 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1136 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1142 end subroutine read_data_int4
1144 subroutine read_data_real4( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1145 integer,
intent(in) :: fid
1146 integer(8),
intent(in) :: pos
1147 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1148 logical,
intent(in) :: yrev
1150 real(RP),
intent(out) :: var(:)
1151 integer,
intent(out) :: ierr
1153 real(4) :: buf(nx,cy)
1156 read(fid, pos=pos, iostat=ierr) buf(:,:)
1157 if ( ierr /= 0 )
return
1163 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1170 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1176 end subroutine read_data_real4
1178 subroutine read_data_int8( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1179 integer,
intent(in) :: fid
1180 integer(8),
intent(in) :: pos
1181 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1182 logical,
intent(in) :: yrev
1184 real(RP),
intent(out) :: var(:)
1185 integer,
intent(out) :: ierr
1187 integer(8) :: buf(nx,cy)
1190 read(fid, pos=pos, iostat=ierr) buf(:,:)
1191 if ( ierr /= 0 )
return
1197 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1204 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1210 end subroutine read_data_int8
1212 subroutine read_data_real8( fid, pos, ka, nx, k, sx, cx, cy, yrev, var, ierr )
1213 integer,
intent(in) :: fid
1214 integer(8),
intent(in) :: pos
1215 integer,
intent(in) :: ka, nx, k, sx, cx, cy
1216 logical,
intent(in) :: yrev
1218 real(RP),
intent(out) :: var(:)
1219 integer,
intent(out) :: ierr
1221 real(8) :: buf(nx,cy)
1224 read(fid, pos=pos, iostat=ierr) buf(:,:)
1225 if ( ierr /= 0 )
return
1231 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,cy-j+1)
1238 var(k+(i-1)*ka+(j-1)*cx*ka) = buf(sx+i-1,j)
1244 end subroutine read_data_real8
1246 subroutine check_oldnamelist( fid )
1250 integer,
intent(in) :: fid
1255 namelist /nml_grads_grid/ dummy
1256 namelist /grdvar/ dummy
1258 read(fid, nml=nml_grads_grid, iostat=ierr)
1260 log_error(
"check_oldnamelist",*)
'The old namelist "nml_grads_grid" is found.'
1261 log_error_cont(*)
'Use "GrADS_DIMS" instead.'
1266 read(fid, nml=grdvar, iostat=ierr)
1268 log_error(
"check_oldnamelist",*)
'The old namelist "grdvar" is found.'
1269 log_error_cont(*)
'Use "GrADS_ITEM" instead.'
1275 end subroutine check_oldnamelist
1279 character(len=*),
intent(in) :: str
1280 character(len=len(str)) ::
upcase
1282 do i = 1, len_trim(str)
1283 if ( str(i:i) >=
'a' .and. str(i:i) <=
'z' )
then
1284 upcase(i:i) = char( ichar(str(i:i)) - 32 )
1289 do i = len_trim(str)+1, len(str)