34 integer,
intent(in) :: unit
35 integer,
intent(out) :: ndim, nvar, natt, ntime
38 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GET_INFO: must first call mpp_io_init.' )
39 if( .NOT.mpp_file(unit)%opened )&
40 call mpp_error(fatal,
'MPP_GET_INFO: invalid unit number, file '//trim(mpp_file(unit)%name))
42 ndim = mpp_file(unit)%ndim
43 nvar = mpp_file(unit)%nvar
44 natt = mpp_file(unit)%natt
45 ntime = mpp_file(unit)%time_level
54 integer,
intent(in) :: unit
55 type(atttype),
intent(inout) :: global_atts(:)
60 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GET_INFO: must first call mpp_io_init.' )
61 if( .NOT.mpp_file(unit)%opened )&
62 call mpp_error( fatal,
'MPP_GET_INFO: invalid unit number,file '//trim(mpp_file(unit)%name))
64 if (
size(global_atts(:)).lt.mpp_file(unit)%natt) &
65 call mpp_error(fatal,
'MPP_GET_ATTS: atttype not dimensioned properly in calling routine, file '// &
66 trim(mpp_file(unit)%name))
68 natt = mpp_file(unit)%natt
69 global_atts = default_att
72 global_atts(i) = mpp_file(unit)%Att(i)
79 subroutine mpp_get_field_atts(field, name, units, longname, min, max, missing, ndim, siz, axes, atts, &
80 valid, scale, add, checksum)
82 type(fieldtype),
intent(in) :: field
83 character(len=*),
intent(out),
optional :: name, units
84 character(len=*),
intent(out),
optional :: longname
85 real,
intent(out),
optional :: min,max,missing
86 integer,
intent(out),
optional :: ndim
87 integer,
intent(out),
dimension(:),
optional :: siz
88 type(validtype),
intent(out),
optional :: valid
89 real,
intent(out),
optional :: scale
90 real,
intent(out),
optional :: add
91 integer(i8_kind),
intent(out),
dimension(:),
optional :: checksum
93 type(atttype),
intent(inout),
dimension(:),
optional :: atts
94 type(axistype),
intent(inout),
dimension(:),
optional :: axes
96 integer :: n,m, check_exist
98 if (
PRESENT(name)) name = field%name
99 if (
PRESENT(units)) units = field%units
100 if (
PRESENT(longname)) longname = field%longname
101 if (
PRESENT(min)) min = field%min
102 if (
PRESENT(max)) max = field%max
103 if (
PRESENT(missing)) missing = field%missing
104 if (
PRESENT(ndim)) ndim = field%ndim
105 if (
PRESENT(atts))
then
107 n =
size(atts(:));m=
size(field%Att(:))
109 call mpp_error(fatal,
'attribute array not large enough in mpp_get_field_atts, field '//&
112 atts(n) = field%Att(n)
115 if (
PRESENT(axes))
then
117 n =
size(axes(:));m=field%ndim
119 call mpp_error(fatal,
'axis array not large enough in mpp_get_field_atts, field '//&
122 axes(n) = field%axes(n)
125 if (
PRESENT(siz))
then
127 n =
size(siz(:));m=field%ndim
129 call mpp_error(fatal,
'size array not large enough in mpp_get_field_atts, field '//&
132 siz(n) = field%size(n)
136 if(
PRESENT(valid))
then
140 if(
PRESENT(scale)) scale = field%scale
141 if(
present(add)) add = field%add
142 if(
present(checksum))
then
144 check_exist = mpp_find_att(field%Att(:),
"checksum")
145 if ( check_exist >= 0 )
then
146 if(
size(checksum(:)) >
size(field%checksum(:)))
call mpp_error(fatal, &
147 &
"size(checksum(:)) >size(field%checksum(:))")
148 checksum = field%checksum(1:
size(checksum(:)))
153 end subroutine mpp_get_field_atts
156 subroutine mpp_get_axis_atts( axis, name, units, longname, cartesian, &
157 calendar, sense, len, natts, atts, compressed )
159 type(axistype),
intent(in) :: axis
160 character(len=*),
intent(out) ,
optional :: name, units
161 character(len=*),
intent(out),
optional :: longname, cartesian
162 character(len=*),
intent(out),
optional :: compressed, calendar
163 integer,
intent(out),
optional :: sense, len , natts
164 type(atttype),
intent(inout),
optional,
dimension(:) :: atts
168 if (
PRESENT(name)) name = axis%name
169 if (
PRESENT(units)) units = axis%units
170 if (
PRESENT(longname)) longname = axis%longname
171 if (
PRESENT(cartesian)) cartesian = axis%cartesian
172 if (
PRESENT(compressed)) compressed = axis%compressed
173 if (
PRESENT(calendar)) calendar = axis%calendar
174 if (
PRESENT(sense)) sense = axis%sense
175 if (
PRESENT(len)) len = axis%len
176 if (
PRESENT(atts))
then
178 n =
size(atts(:));m=
size(axis%Att(:))
180 call mpp_error(fatal,
'attribute array not large enough in mpp_get_field_atts, axis '//&
183 atts(n) = axis%Att(n)
186 if (
PRESENT(natts)) natts =
size(axis%Att(:))
189 end subroutine mpp_get_axis_atts
195 integer,
intent(in) :: unit
196 type(fieldtype),
intent(inout) :: variables(:)
200 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GET_FIELDS: must first call mpp_io_init.' )
201 if( .NOT.mpp_file(unit)%opened )
call mpp_error( fatal,
'MPP_GET_FIELDS: invalid unit number.' )
203 if (
size(variables(:)).ne.mpp_file(unit)%nvar) &
204 call mpp_error(fatal,
'MPP_GET_FIELDS: fieldtype not dimensioned properly in calling routine, file '//&
205 trim(mpp_file(unit)%name))
207 nvar = mpp_file(unit)%nvar
210 variables(i) = mpp_file(unit)%Var(i)
221 integer,
intent(in) :: unit
222 type(axistype),
intent(inout) :: axes(:)
223 type(axistype),
intent(inout),
optional :: time_axis
226 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GET_AXES: must first call mpp_io_init.' )
227 if( .NOT.mpp_file(unit)%opened )&
228 call mpp_error( fatal,
'MPP_GET_AXES: invalid unit number, file '//trim(mpp_file(unit)%name))
230 if (
size(axes(:)).ne.mpp_file(unit)%ndim) &
231 call mpp_error(fatal,
'MPP_GET_AXES: axistype not dimensioned properly in calling routine, file '//&
232 trim(mpp_file(unit)%name))
235 if (
PRESENT(time_axis)) time_axis = default_axis
236 ndim = mpp_file(unit)%ndim
239 axes(i)=mpp_file(unit)%Axis(i)
241 if (
PRESENT(time_axis) &
242 .AND. .NOT.
ASSOCIATED(mpp_file(unit)%Axis(i)%data) &
243 .AND. mpp_file(unit)%Axis(i)%type /= -1)
then
244 time_axis = mpp_file(unit)%Axis(i)
254 integer,
intent(in) :: unit
255 character(len=*),
intent(in) :: dimname
256 logical,
optional,
intent(out) :: found
262 if( .NOT.module_is_initialized ) &
263 call mpp_error( fatal,
'mpp_get_dimension_length: must first call mpp_io_init.' )
264 if( .NOT.mpp_file(unit)%opened )&
265 call mpp_error( fatal,
'mpp_get_dimension_length: invalid unit number, file '//trim(mpp_file(unit)%name))
268 do i = 1, mpp_file(unit)%ndim
269 if(trim(dimname) == trim(mpp_file(unit)%Axis(i)%name))
then
276 if(
present(found)) found = found_dim
283 integer,
intent(in) :: unit
284 type(axistype),
intent(inout) :: time_axis
286 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GET_AXES: must first call mpp_io_init.' )
287 if( .NOT.mpp_file(unit)%opened )&
288 call mpp_error( fatal,
'MPP_GET_AXES: invalid unit number, file '//trim(mpp_file(unit)%name))
290 time_axis = mpp_file(unit)%Axis(mpp_file(unit)%recdimid)
312 integer,
intent(in) :: unit
313 real,
intent(inout) :: time_values(:)
317 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GET_TIMES: must first call mpp_io_init.' )
318 if( .NOT.mpp_file(unit)%opened )&
319 call mpp_error(fatal,
'MPP_GET_TIMES: invalid unit number, file '//trim(mpp_file(unit)%name))
324 if (mpp_file(unit)%time_level == -1)
then
329 if (
size(time_values(:)).ne.mpp_file(unit)%time_level) &
330 call mpp_error(fatal,
'MPP_GET_TIMES: time_values not dimensioned properly in calling routine, file '//&
331 trim(mpp_file(unit)%name))
333 ntime = mpp_file(unit)%time_level
336 time_values(i) = mpp_file(unit)%time_values(i)
343 function mpp_get_field_index(fields,fieldname)
345 type(fieldtype),
dimension(:) :: fields
346 character(len=*) :: fieldname
347 integer :: mpp_get_field_index
351 mpp_get_field_index = -1
353 do n=1,
size(fields(:))
354 if (lowercase(fields(n)%name) == lowercase(fieldname))
then
355 mpp_get_field_index = n
361 end function mpp_get_field_index
364 function mpp_get_axis_index(axes,axisname)
366 type(axistype),
dimension(:) :: axes
367 character(len=*) :: axisname
368 integer :: mpp_get_axis_index
372 mpp_get_axis_index = -1
375 if (lowercase(axes(n)%name) == lowercase(axisname))
then
376 mpp_get_axis_index = n
382 end function mpp_get_axis_index
385 function mpp_get_axis_by_name(unit,axisname)
388 character(len=*) :: axisname
389 type(axistype) :: mpp_get_axis_by_name
393 mpp_get_axis_by_name = default_axis
395 do n=1,
size(mpp_file(unit)%Axis(:))
396 if (lowercase(mpp_file(unit)%Axis(n)%name) == lowercase(axisname))
then
397 mpp_get_axis_by_name = mpp_file(unit)%Axis(n)
403 end function mpp_get_axis_by_name
406 function mpp_get_field_size(field)
408 type(fieldtype) :: field
409 integer :: mpp_get_field_size(4)
411 mpp_get_field_size = -1
413 mpp_get_field_size(1) = field%size(1)
414 mpp_get_field_size(2) = field%size(2)
415 mpp_get_field_size(3) = field%size(3)
416 mpp_get_field_size(4) = field%size(4)
419 end function mpp_get_field_size
423 function mpp_get_axis_length(axis)
425 type(axistype) :: axis
426 integer :: mpp_get_axis_length
428 mpp_get_axis_length = axis%len
431 end function mpp_get_axis_length
434 function mpp_get_axis_bounds(axis, data, name)
435 type(axistype),
intent(in) :: axis
436 real,
dimension(:),
intent(out) :: data
437 character(len=*),
optional,
intent(out) :: name
438 logical :: mpp_get_axis_bounds
440 if (
size(
data(:)).lt.axis%len+1)&
441 call mpp_error(fatal,
'MPP_GET_AXIS_BOUNDS: data array not large enough, axis '//trim(axis%name))
442 if (.NOT.
ASSOCIATED(axis%data_bounds))
then
443 mpp_get_axis_bounds = .false.
445 mpp_get_axis_bounds = .true.
446 data(1:axis%len+1) = axis%data_bounds(:)
448 if(
present(name)) name = trim(axis%name_bounds)
451 end function mpp_get_axis_bounds
454 subroutine mpp_get_axis_data( axis, data )
456 type(axistype),
intent(in) :: axis
457 real,
dimension(:),
intent(out) :: data
460 if (
size(
data(:)).lt.axis%len)&
461 call mpp_error(fatal,
'MPP_GET_AXIS_DATA: data array not large enough, axis '//trim(axis%name))
462 if (.NOT.
ASSOCIATED(axis%data))
then
463 call mpp_error(note,
'MPP_GET_AXIS_DATA: use mpp_get_times for record dims')
466 data(1:axis%len) = axis%data
470 end subroutine mpp_get_axis_data
474 function mpp_get_recdimid(unit)
476 integer,
intent(in) :: unit
477 integer :: mpp_get_recdimid
480 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_GET_RECDIMID: must first call mpp_io_init.' )
481 if( .NOT.mpp_file(unit)%opened )
call mpp_error( fatal,
'MPP_GET_RECDIMID: invalid unit number.' )
483 mpp_get_recdimid = mpp_file(unit)%recdimid
486 end function mpp_get_recdimid
513 integer,
intent(in) :: unit
520 function mpp_get_axis_id(axis)
521 integer mpp_get_axis_id
522 type(axistype),
intent(in) :: axis
523 mpp_get_axis_id = axis%id
525 end function mpp_get_axis_id
528 function mpp_get_field_id(field)
529 integer mpp_get_field_id
530 type(fieldtype),
intent(in) :: field
531 mpp_get_field_id = field%id
533 end function mpp_get_field_id
538 integer,
intent(in) :: n
539 character(len=10) :: text
541 if( n.GT.mpp_io_stack_size .AND.
allocated(mpp_io_stack) )
deallocate(mpp_io_stack)
542 if( .NOT.
allocated(mpp_io_stack) )
then
543 allocate( mpp_io_stack(n) )
544 mpp_io_stack_size = n
545 write( text,
'(i10)' )n
546 if( pe.EQ.mpp_root_pe() )
call mpp_error( note,
'MPP_IO_SET_STACK_SIZE: stack size set to '//text//
'.' )
556 type(fieldtype),
intent(in) :: f
557 type(validtype),
intent(out) :: v
559 integer :: irange,imin,imax,ifill,imissing,iscale
560 integer :: valid_T, scale_T
563 v%min = -huge(v%min); v%max = huge(v%max)
564 if (f%natt == 0)
return
566 irange = mpp_find_att(f%att,
'valid_range')
567 imin = mpp_find_att(f%att,
'valid_min')
568 imax = mpp_find_att(f%att,
'valid_max')
569 ifill = mpp_find_att(f%att,
'_FillValue')
570 imissing = mpp_find_att(f%att,
'missing_value')
576 iscale = mpp_find_att(f%att,
'scale_factor')
577 if(iscale>0) scale_t = f%att(iscale)%type
578 iscale = mpp_find_att(f%att,
'add_offset')
579 if(iscale>0) scale_t = max(scale_t,f%att(iscale)%type)
585 v%min = f%att(irange)%fatt(1)
586 v%max = f%att(irange)%fatt(2)
587 valid_t = f%att(irange)%type
588 else if (imax>0.or.imin>0)
then
590 v%max = f%att(imax)%fatt(1)
591 valid_t = max(valid_t,f%att(imax)%type)
594 v%min = f%att(imin)%fatt(1)
595 valid_t = max(valid_t,f%att(imin)%type)
597 else if (imissing > 0)
then
601 v%min = f%att(imissing)%fatt(1)*f%scale + f%add
602 else if (ifill>0)
then
606 if(f%att(ifill)%fatt(1)>0)
then
608 v%max = f%att(ifill)%fatt(1)
610 case (nf_byte,nf_short,nf_int)
613 v%max = nearest(nearest(real(v%max,4),-1.0),-1.0)
615 v%max = nearest(nearest(real(v%max,8),-1.0),-1.0)
619 v%max = v%max*f%scale + f%add
622 v%min = f%att(ifill)%fatt(1)
624 case (nf_byte,nf_short,nf_int)
627 v%min = nearest(nearest(real(v%min,4),+1.0),+1.0)
629 v%min = nearest(nearest(real(v%min,8),+1.0),+1.0)
633 v%min = v%min*f%scale + f%add
643 if(.not.((valid_t == scale_t).and.(scale_t>f%type)))
then
644 if(irange>0 .or. imin>0)
then
645 v%min = v%min*f%scale + f%add
647 if(irange>0 .or. imax>0)
then
648 v%max = v%max*f%scale + f%add
655 logical elemental function mpp_is_valid(x, v)
656 real ,
intent(in) :: x
657 type(validtype),
intent(in) :: v
660 mpp_is_valid = (v%min<=x).and.(x<=v%max)
662 mpp_is_valid = x/=v%min
664 end function mpp_is_valid
669 function mpp_find_att(atts, name)
670 integer :: mpp_find_att
671 type(atttype),
intent(in) :: atts(:)
672 character(len=*) :: name
678 if (trim(name)==trim(atts(i)%name))
then
683 end function mpp_find_att
688 type(atttype),
intent(in) :: att
700 type(atttype),
intent(in) :: att
712 type(atttype),
intent(in) :: att
725 type(atttype),
intent(in) :: att
737 type(atttype),
intent(in) :: att
749 type(atttype),
intent(in) :: att
760 type(fieldtype),
intent(in) :: field
770 integer,
intent(in) :: unit
781 integer,
intent(in) :: unit
792 integer,
intent(in) :: unit
793 character(len=*),
intent(in) :: fieldname, attname
794 character(len=*),
intent(out) :: attvalue
795 logical :: found_field, found_att
796 integer :: i, j, length
798 found_field = .false.
800 do i=1,mpp_file(unit)%nvar
801 if( trim(mpp_file(unit)%Var(i)%name) == trim(fieldname))
then
803 do j=1,
size(mpp_file(unit)%Var(i)%Att(:))
804 if( trim(mpp_file(unit)%Var(i)%Att(j)%name) == trim(attname) )
then
806 length = mpp_file(unit)%Var(i)%Att(j)%len
807 if(len(attvalue) .LE. length )
call mpp_error(fatal, &
808 'mpp_io_util.inc: length of attvalue is less than the length of catt')
809 attvalue = trim(mpp_file(unit)%Var(i)%Att(j)%catt(1:length))
817 if(.NOT. found_field)
call mpp_error(fatal,
"mpp_io_util.inc: field "//trim(fieldname)// &
818 " does not exist in the file "//trim(mpp_file(unit)%name) )
819 if(.NOT. found_att)
call mpp_error(fatal,
"mpp_io_util.inc: attribute "//trim(attname)//
" of field "&
820 //trim(fieldname)//
" does not exist in the file "//trim(mpp_file(unit)%name) )
838 function mpp_attribute_exist(field,name)
839 logical :: mpp_attribute_exist
840 type(fieldtype),
intent(in) :: field
841 character(len=*),
intent(in) :: name
843 if(field%natt > 0)
then
844 mpp_attribute_exist = ( mpp_find_att(field%Att(:),name) > 0 )
846 mpp_attribute_exist = .false.
849 end function mpp_attribute_exist
852 subroutine mpp_dist_io_pelist(ssize,pelist)
853 integer,
intent(in) :: ssize
854 integer,
allocatable,
intent(out) :: pelist(:)
855 integer :: i, lsize, ioroot
856 logical :: is_ioroot=.false.
859 if(ssize < 1)
call mpp_error(fatal,
'mpp_dist_io_pelist: I/O stripe size < 1')
861 is_ioroot = mpp_is_dist_ioroot(ssize,ioroot=ioroot,lsize=lsize)
864 if(lsize < 1)
call mpp_error(fatal,
'mpp_dist_io_pelist: size of pelist < 1')
866 allocate(pelist(lsize))
868 pelist(i) = ioroot + i - 1
870 end subroutine mpp_dist_io_pelist
873 logical function mpp_is_dist_ioroot(ssize,ioroot,lsize)
874 integer,
intent(in) :: ssize
875 integer,
intent(out),
optional :: ioroot, lsize
876 integer :: pe, npes, mypos, maxpe, d_ioroot, d_lsize, last_ioroot
879 if(ssize < 1)
call mpp_error(fatal,
'mpp_is_dist_ioroot: I/O stripe size < 1')
881 mpp_is_dist_ioroot = .false.
882 rootpe = mpp_root_pe()
885 mypos = modulo(pe-rootpe,ssize)
886 d_ioroot = pe - mypos
888 maxpe = min(d_ioroot+ssize,npes+rootpe) - 1
889 d_lsize = maxpe - d_ioroot + 1
890 if(mod(npes,ssize) == 1)
then
891 last_ioroot = (npes-1) - ssize
892 if(pe >= last_ioroot)
then
893 d_ioroot = last_ioroot
897 if(pe == d_ioroot) mpp_is_dist_ioroot = .true.
898 if(
PRESENT(ioroot)) ioroot = d_ioroot
899 if(
PRESENT(lsize)) lsize = d_lsize
900 end function mpp_is_dist_ioroot
character(len=len(mpp_file(1)%name)) function mpp_get_file_name(unit)
return the file name of corresponding unit
subroutine mpp_get_info(unit, ndim, nvar, natt, ntime)
Get some general information about a file.
subroutine mpp_get_global_atts(unit, global_atts)
Copy global file attributes for use by user.
subroutine mpp_io_set_stack_size(n)
Set the mpp_io_stack variable to be at least n LONG words long.
integer function mpp_get_ncid(unit)
Get netCDF ID of an open file.
integer function mpp_get_dimension_length(unit, dimname, found)
Copy variable information from file (excluding data)
subroutine mpp_get_times(unit, time_values)
Get file time data.
character(len=len(default_axis%calendar)) function mpp_get_default_calendar()
Copy variable information from file (excluding data)
real function mpp_get_att_real_scalar(att)
return the real array value of an attribute.
logical function mpp_file_is_opened(unit)
return if certain file with unit is opened or not
subroutine mpp_get_valid(f, v)
Based on presence/absence of attributes, defines valid range or missing.
subroutine mpp_get_fields(unit, variables)
Copy variable information from file (excluding data)
subroutine mpp_get_field_att_text(unit, fieldname, attname, attvalue)
return the attribute value of given field name
character(len=len(field%name)) function mpp_get_field_name(field)
return the name of an field
subroutine mpp_get_time_axis(unit, time_axis)
Copy variable information from file (excluding data)
integer function mpp_get_att_length(att)
return the length of an attribute.
subroutine mpp_get_axes(unit, axes, time_axis)
Copy variable information from file (excluding data)
character(len=len(att%name)) function mpp_get_att_name(att)
return the name of an attribute.
real function, dimension(size(att%fatt(:))) mpp_get_att_real(att)
return the real array value of an attribute.
logical function mpp_io_clock_on()
return mpp_io_nml variable io_clock_on
integer function mpp_get_att_type(att)
return the type of an attribute.
character(len=att%len) function mpp_get_att_char(att)
return the char value of an attribute.
integer function mpp_npes()
Returns processor count for current pelist.
integer function mpp_pe()
Returns processor ID.