FMS  2024.03
Flexible Modeling System
get_variable_attribute.inc
1 !***********************************************************************
2 !* GNU Lesser General Public License
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* FMS is free software: you can redistribute it and/or modify it under
7 !* the terms of the GNU Lesser General Public License as published by
8 !* the Free Software Foundation, either version 3 of the License, or (at
9 !* your option) any later version.
10 !*
11 !* FMS is distributed in the hope that it will be useful, but WITHOUT
12 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 !* for more details.
15 !*
16 !* You should have received a copy of the GNU Lesser General Public
17 !* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18 !***********************************************************************
19 !> @file
20 !> @brief Routines for retrieving variable attribute values from netcdf files with different
21 !! dimension sizes for the @ref get_variable_attribute interface
22 
23 !> @addtogroup netcdf_io_mod
24 !> @{
25 
26 !> @brief Get the value of a variable's attribute.
27 subroutine get_variable_attribute_0d(fileobj, variable_name, attribute_name, &
28  attribute_value, broadcast, reproduce_null_char_bug_flag)
29 
30  class(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
31  character(len=*), intent(in) :: variable_name !< Variable name.
32  character(len=*), intent(in) :: attribute_name !< Attribute name.
33  class(*), intent(inout) :: attribute_value !< Attribute value
34  logical, intent(in), optional :: broadcast !< Flag controlling whether or
35  !! not the data will be
36  !! broadcasted to non
37  !! "I/O root" ranks.
38  !! The broadcast will be done
39  !! by default.
40  logical, intent(in), optional :: reproduce_null_char_bug_flag !< Flag indicating to reproduce the mpp_io bug where
41  !! the null characters were not removed after reading
42  !! a string attribute
43 
44  integer :: varid
45  integer :: err
46  character(len=200) :: append_error_msg !< Msg to be appended to FATAL error message
47  character(len=1024), dimension(1) :: charbuf !< 1D Character buffer
48  logical :: reproduce_null_char_bug !< Local flag indicating to reproduce the mpp_io bug where
49  !! the null characters were not removed after reading a string attribute
50 
51  !! If the reproduce_null_char_bug flag is turned on fms2io will not remove the null character
52  reproduce_null_char_bug = .false.
53  if (present(reproduce_null_char_bug_flag)) reproduce_null_char_bug=reproduce_null_char_bug_flag
54 
55  append_error_msg = "get_variable_attribute_0d: file:"//trim(fileobj%path)//"- variable:"//&
56  &trim(variable_name)//" attribute: "//trim(attribute_name)
57 
58  if (fileobj%is_root) then
59  varid = get_variable_id(fileobj%ncid, trim(variable_name), msg=append_error_msg)
60  select type(attribute_value)
61  type is (character(len=*))
62  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), charbuf(1))
63  if (reproduce_null_char_bug) then
64  call string_copy(attribute_value, charbuf(1), check_for_null=.false.)
65  else
66  call string_copy(attribute_value, charbuf(1), check_for_null=.true.)
67  endif
68  type is (integer(kind=i4_kind))
69  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), attribute_value)
70  type is (integer(kind=i8_kind))
71  if ( .not. fileobj%is_netcdf4) call error(trim(fileobj%path)// &
72  & ": 64 bit integers are only supported with 'netcdf4' file format"//&
73  &". Set netcdf_default_format='netcdf4' in the fms2_io namelist OR "//&
74  &"add nc_format='netcdf4' to your open_file call")
75  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), attribute_value)
76  type is (real(kind=r4_kind))
77  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), attribute_value)
78  type is (real(kind=r8_kind))
79  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), attribute_value)
80  class default
81  call error("unsupported attribute type: "//trim(append_error_msg))
82  end select
83  call check_netcdf_code(err, append_error_msg)
84  endif
85  if (present(broadcast)) then
86  if (.not. broadcast) then
87  return
88  endif
89  endif
90  select type(attribute_value)
91  type is (character(len=*))
92  call mpp_broadcast(charbuf, len(charbuf), fileobj%io_root, pelist=fileobj%pelist)
93  if (reproduce_null_char_bug) then
94  call string_copy(attribute_value, charbuf(1), check_for_null=.false.)
95  else
96  call string_copy(attribute_value, charbuf(1), check_for_null=.true.)
97  endif
98  type is (integer(kind=i4_kind))
99  call mpp_broadcast(attribute_value, fileobj%io_root, pelist=fileobj%pelist)
100  type is (integer(kind=i8_kind))
101  call mpp_broadcast(attribute_value, fileobj%io_root, pelist=fileobj%pelist)
102  type is (real(kind=r4_kind))
103  call mpp_broadcast(attribute_value, fileobj%io_root, pelist=fileobj%pelist)
104  type is (real(kind=r8_kind))
105  call mpp_broadcast(attribute_value, fileobj%io_root, pelist=fileobj%pelist)
106  class default
107  call error("unsupported attribute type: "//trim(append_error_msg))
108  end select
109 end subroutine get_variable_attribute_0d
110 
111 
112 !> @brief Get the value of a variable's attribute.
113 subroutine get_variable_attribute_1d(fileobj, variable_name, attribute_name, &
114  attribute_value, broadcast)
115 
116  class(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
117  character(len=*), intent(in) :: variable_name !< Variable name.
118  character(len=*), intent(in) :: attribute_name !< Attribute name.
119  class(*), dimension(:), intent(inout) :: attribute_value !< Attribute value
120  logical, intent(in), optional :: broadcast !< Flag controlling whether or
121  !! not the data will be
122  !! broadcasted to non
123  !! "I/O root" ranks.
124  !! The broadcast will be done
125  !! by default.
126 
127  integer :: varid
128  integer :: err
129  character(len=200) :: append_error_msg !< Msg to be appended to FATAL error message
130 
131  append_error_msg = "get_variable_attribute_1d: file:"//trim(fileobj%path)//"- variable:"//&
132  &trim(variable_name)//" attribute: "//trim(attribute_name)
133 
134  if (fileobj%is_root) then
135  varid = get_variable_id(fileobj%ncid, trim(variable_name), msg=append_error_msg)
136  select type(attribute_value)
137  type is (integer(kind=i4_kind))
138  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), attribute_value)
139  type is (integer(kind=i8_kind))
140  if ( .not. fileobj%is_netcdf4) call error(trim(fileobj%path)// &
141  &": 64 bit integers are only supported with 'netcdf4' file format"//&
142  &". Set netcdf_default_format='netcdf4' in the fms2_io namelist OR "//&
143  &"add nc_format='netcdf4' to your open_file call")
144  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), attribute_value)
145  type is (real(kind=r4_kind))
146  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), attribute_value)
147  type is (real(kind=r8_kind))
148  err = nf90_get_att(fileobj%ncid, varid, trim(attribute_name), attribute_value)
149  class default
150  call error("unsupported attribute type: "//trim(append_error_msg))
151  end select
152  call check_netcdf_code(err, append_error_msg)
153  endif
154  if (present(broadcast)) then
155  if (.not. broadcast) then
156  return
157  endif
158  endif
159  select type(attribute_value)
160  type is (integer(kind=i4_kind))
161  call mpp_broadcast(attribute_value, size(attribute_value), fileobj%io_root, &
162  pelist=fileobj%pelist)
163  type is (integer(kind=i8_kind))
164  call mpp_broadcast(attribute_value, size(attribute_value), fileobj%io_root, &
165  pelist=fileobj%pelist)
166  type is (real(kind=r4_kind))
167  call mpp_broadcast(attribute_value, size(attribute_value), fileobj%io_root, &
168  pelist=fileobj%pelist)
169  type is (real(kind=r8_kind))
170  call mpp_broadcast(attribute_value, size(attribute_value), fileobj%io_root, &
171  pelist=fileobj%pelist)
172  class default
173  call error("unsupported attribute type: "//trim(append_error_msg))
174  end select
175 end subroutine get_variable_attribute_1d
176 !> @}
subroutine get_variable_attribute_1d(fileobj, variable_name, attribute_name, attribute_value, broadcast)
Get the value of a variable's attribute.
subroutine get_variable_attribute_0d(fileobj, variable_name, attribute_name, attribute_value, broadcast, reproduce_null_char_bug_flag)
Get the value of a variable's attribute.