6 ! Return values for comparison functions primary_cmp() and secondary_cmp()
7 integer, parameter :: LESS = -1, &
16 character (len=32) :: date
17 logical :: time_dependent, mask_field
19 ! Set = 0 if this is an analysis.
22 ! AVN, GFS, ETA???, ARW, NMM, AGRMET, NAM, RUC, SST
23 character (len=32) :: fg_source
25 character (len=128) :: field
26 character (len=128) :: units
27 character (len=128) :: description
29 ! PRESSURE, SIGMA, NATIVE, HYBRID
30 character (len=32) :: vertical_coord
31 integer :: vertical_level
33 ! XY, YX - ENOUGH INFO?
34 character (len=32) :: array_order
35 integer, dimension(2) :: dim1, dim2
37 logical :: is_wind_grid_rel
38 logical :: array_has_missing_values
44 ! Mercator, Polar Stereographic, Lambert, Gaussian, Lat Lon
45 character (len=32) :: projection
47 integer :: projection_flag
49 ! For ARW: M, U, or V; for NMM: H or V
52 real :: knownlat, knownlon, deltalat, deltalon
53 real :: deltax, deltay, xlonc, truelat1, truelat2
57 ! This is the datatype that is understood by data_storage module
59 ! BEGIN any types we want to keep and use for sorting in storage module
60 type (header_info) :: header
61 type (map_info) :: map
62 ! END any types we want to keep and use for sorting in storage module
64 real, dimension(:,:), pointer :: r_arr !!!!! REQUIRED !!!!!
65 type (bitarray), pointer :: valid_mask, modified_mask
68 ! This type is used for the nodes of the secondary linked lists, the ones that
71 type (fg_input) :: fg_data
73 type (data_node), pointer :: next, prev
74 integer, dimension(2) :: field_shape
76 ! If non-zero, the array is actually stored in a Fortran unit
79 ! The following two are used by heaps
84 ! This type is used for the nodes in the primary linked lists, and thus has head
85 ! and tail pointers for secondary linked lists
87 type (fg_input) :: fg_data
88 type (head_node), pointer :: next, prev
89 type (data_node), pointer :: fieldlist_head, fieldlist_tail
96 ! Compares two fg_input types; returns EQUAL if the two should
97 ! belong to the same secondary linked list, and NOT_EQUAL otherwise
98 function primary_cmp(a, b)
103 type (fg_input), intent(in) :: a, b
106 integer :: primary_cmp
108 ! if ((a%header%date == b%header%date) .and. &
109 ! (a%header%forecast_hour == b%header%forecast_hour) .and. &
110 ! (a%header%fg_source == b%header%fg_source) .and. &
111 ! (a%header%field == b%header%field)) then
112 if (a%header%field == b%header%field) then
115 primary_cmp = NOT_EQUAL
118 end function primary_cmp
121 ! Compares two fg_input types; returns EQUAL if the two belong
122 ! at the same position in a secondary linked list, LESS if "a" belongs
123 ! after "b", and GREATER if "a" belongs before "b"
124 function secondary_cmp(a, b)
129 type (fg_input), intent(in) :: a, b
132 integer :: secondary_cmp
134 ! BUG: Eventually, we only want to sort pressure-level data this way, and
135 ! all others the opposite way, as in the else case below.
136 if (a%header%time_dependent) then
137 if (a%header%vertical_level > b%header%vertical_level) then
139 else if (a%header%vertical_level == b%header%vertical_level) then
140 secondary_cmp = EQUAL
142 secondary_cmp = GREATER
146 if (a%header%vertical_level < b%header%vertical_level) then
148 else if (a%header%vertical_level == b%header%vertical_level) then
149 secondary_cmp = EQUAL
151 secondary_cmp = GREATER
155 end function secondary_cmp
158 ! Duplicates an fg_input type
159 subroutine dup(src, dst)
164 type (fg_input), intent(in) :: src
165 type (fg_input), intent(out) :: dst
167 dst%header = src%header
169 dst%r_arr => src%r_arr
170 dst%valid_mask => src%valid_mask
171 dst%modified_mask => src%modified_mask
176 function is_time_dependent(a)
181 type (fg_input), intent(in) :: a
184 logical :: is_time_dependent
186 is_time_dependent = a%header%time_dependent
188 end function is_time_dependent
191 function is_mask_field(a)
196 type (fg_input), intent(in) :: a
199 logical :: is_mask_field
201 is_mask_field = a%header%mask_field
203 end function is_mask_field
206 ! Returns the vertical level of an fg_input type
207 function get_level(a)
212 type (fg_input), intent(in) :: a
217 get_level = a%header%vertical_level
219 end function get_level
222 ! Returns the description string of an fg_input type
223 function get_description(a)
228 type (fg_input), intent(in) :: a
231 character (len=128) :: get_description
233 get_description = a%header%description
235 end function get_description
238 ! Returns the units string of an fg_input type
239 function get_units(a)
244 type (fg_input), intent(in) :: a
247 character (len=128) :: get_units
249 get_units = a%header%units
251 end function get_units
254 ! Returns the field staggering an fg_input type
255 function get_staggering(a)
260 type (fg_input), intent(in) :: a
263 integer :: get_staggering
265 get_staggering = a%map%stagger
267 end function get_staggering
270 ! Returns the fieldname string of an fg_input type
271 function get_fieldname(a)
276 type (fg_input), intent(in) :: a
279 character (len=128) :: get_fieldname
281 get_fieldname = a%header%field
283 end function get_fieldname
286 ! Gives starting and ending indices for a field
287 subroutine get_dims(a, start_mem_1, end_mem_1, start_mem_2, end_mem_2)
292 type (fg_input), intent(in) :: a
293 integer, intent(out) :: start_mem_1, end_mem_1, start_mem_2, end_mem_2
295 start_mem_1 = a%header%dim1(1)
296 end_mem_1 = a%header%dim1(2)
297 start_mem_2 = a%header%dim2(1)
298 end_mem_2 = a%header%dim2(2)
300 end subroutine get_dims
303 ! Prints relevant information from the headers of an fg_input type; mainly
305 subroutine print_header(a)
310 type (fg_input), intent(in) :: a
312 call mprintf(.true.,DEBUG,'FIELD : %s',s1=trim(a%header%field))
313 call mprintf(.true.,DEBUG,'DATE : %s',s1=trim(a%header%date))
314 call mprintf(.true.,DEBUG,'SOURCE : %s',s1=trim(a%header%fg_source))
315 call mprintf(.true.,DEBUG,'FCST HR: %f',f1=a%header%forecast_hour)
317 end subroutine print_header
319 end module datatype_module