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