NCEPLIBS-g2 4.0.0
Loading...
Searching...
No Matches
g2cf.F90
Go to the documentation of this file.
1
4
8module g2cf
9 use g2c_interface
10
12 integer, parameter :: g2_noerr = 0
13
15 integer, parameter :: g2_max_name = 1024
16
18 integer, parameter :: g2_max_pds_template_len = 50
19
21 integer, parameter :: g2_max_gds_template_len = 50
22
24 integer, parameter :: g2_max_drs_template_len = 55
25
26contains
42 function addcnullchar(string, nlen) result(cstring)
43 use iso_c_binding
44 implicit none
45
46 character(len=*), intent(in) :: string
47 integer, intent(inout) :: nlen
48 character(len = (len(string) + 1)) :: cstring
49
50 integer :: inull
51
52 ! First check to see if we already have a C NULL char attached
53 ! to string and strip trailing blanks. We will use it if its present
54 ! otherwise we add one. The length of the trimmed string plus the
55 ! C_NULL_CHAR is returned in nlen.
56 nlen = len_trim(string)
57 inull = scan(string, c_null_char)
58 cstring = repeat(" ", len(cstring)) ! init to blanks
59 if (inull > 0) then ! string has a NULL char
60 nlen = inull
61 cstring = string(1:nlen)
62 else ! append null char to trimmed string
63 cstring = string(1:nlen)//c_null_char
64 nlen = nlen + 1
65 endif
66 end function addcnullchar
67
81 function stripcnullchar(cstring, nlen) result(string)
82 use iso_c_binding
83 implicit none
84
85 character(len=*), intent(in) :: cstring
86 integer, intent(in) :: nlen
87 character(len=nlen) :: string
88 integer :: ie, inull
89
90 ie = len_trim(cstring)
91 inull = scan(cstring, c_null_char)
92
93 if (inull > 1) ie = inull-1
94 ie = max(1, min(ie, nlen)) ! limit ie to 1 or nlen
95 string = repeat(" ", nlen)
96 string(1:ie) = cstring(1:ie)
97
98 end function stripcnullchar
99
109 function g2cf_open(path, mode, g2id) result (status)
110 use iso_c_binding
111 use g2c_interface
112 implicit none
113
114 character(len = *), intent(in) :: path
115 integer, intent(in) :: mode
116 integer, intent(inout) :: g2id
117 integer :: status
118
119 integer(c_int) :: cmode, cg2id, cstatus
120 character(len = (len(path) + 1)) :: cpath
121 integer :: ie
122
123 cmode = mode
124 cg2id = 0
125
126 ! Check for C null character on path and add one if not present.
127 cpath = addcnullchar(path, ie)
128
129 ! Call g2c_open to open GRIB2 file.
130 cstatus = g2c_open(cpath(1:ie), cmode, cg2id)
131
132 ! Return results to caller.
133 if (cstatus .eq. 0) then
134 g2id = cg2id
135 endif
136 status = cstatus
137
138 end function g2cf_open
139
152 function g2cf_open_index(data_file, index_file, mode, g2cid) result (status)
153 use iso_c_binding
154 implicit none
155
156 character(len=*), intent(in) :: data_file, index_file
157 integer, intent(in) :: mode
158 integer, intent(inout) :: g2cid
159 integer :: status
160
161 integer(c_int) :: cmode, cg2cid, cstatus
162 character(len = (len(data_file) + 1)) :: cdata_file
163 character(len = (len(index_file) + 1)) :: cindex_file
164 integer :: ie1, ie2
165
166 cmode = mode
167 cg2cid = 0
168
169 ! Check for c null character on path and add one if not present.
170 cdata_file = addcnullchar(data_file, ie1)
171 cindex_file = addcnullchar(index_file, ie2)
172
173 ! Call g2c_open_index to open the file.
174 cstatus = g2c_open_index(cdata_file(1:ie1), cindex_file(1:ie2), cmode, cg2cid)
175
176 if (cstatus == 0) then
177 g2cid = cg2cid
178 endif
179 status = cstatus
180 end function g2cf_open_index
181
190 function g2cf_inq(g2id, num_msg) result(status)
191 use iso_c_binding
192 use g2c_interface
193 implicit none
194
195 integer, intent(in) :: g2id
196 integer, intent(out) :: num_msg
197 integer :: status
198
199 integer(c_int) :: cg2id, cnum_msg, cstatus
200
201 cg2id = g2id
202 cstatus = g2c_inq(cg2id, cnum_msg)
203 num_msg = cnum_msg
204 status = cstatus
205 end function g2cf_inq
206
223 function g2cf_inq_msg(g2id, msg_num, discipline, num_fields, &
224 num_local, center, subcenter, master_version, local_version) result(status)
225 use iso_c_binding
226 use g2c_interface
227 implicit none
228
229 integer, intent(in) :: g2id, msg_num
230 integer(kind = 1), intent(out) :: discipline
231 integer, intent(out) :: num_fields, num_local
232 integer(kind = 2), intent(out) :: center, subcenter
233 integer(kind = 1), intent(out) :: master_version, local_version
234 integer :: status
235
236 integer(c_int) :: cg2id, cmsg_num, cstatus
237 integer(c_signed_char) :: cdiscipline
238 integer(c_int) :: cnum_fields, cnum_local
239 integer(c_short) :: ccenter, csubcenter
240 integer(c_signed_char) :: cmaster_version, clocal_version
241
242 cg2id = g2id
243 ! Subtract 1 because C is zero-based.
244 cmsg_num = msg_num - 1
245 cstatus = g2c_inq_msg(cg2id, cmsg_num, cdiscipline, cnum_fields, &
246 cnum_local, ccenter, csubcenter, cmaster_version, clocal_version)
247 discipline = cdiscipline
248 num_fields = cnum_fields
249 num_local = cnum_local
250 center = ccenter
251 subcenter = csubcenter
252 master_version = cmaster_version
253 local_version = clocal_version
254 status = cstatus
255 end function g2cf_inq_msg
256
272 function g2cf_inq_msg_time(g2id, msg_num, sig_ref_time, year, &
273 month, day, hour, minute, second) result(status)
274 use iso_c_binding
275 use g2c_interface
276 implicit none
277
278 integer, intent(in) :: g2id
279 integer, intent(in) :: msg_num
280 integer(kind = 1), intent(out) :: sig_ref_time
281 integer(kind = 2), intent(out) :: year
282 integer(kind = 1), intent(out) :: month, day, hour, minute, second
283
284 integer(c_int) :: g2cid, cmsg_num
285 integer(c_signed_char) :: csig_ref_time
286 integer(c_short) :: cyear
287 integer(c_signed_char) :: cmonth, cday, chour, cminute, csecond
288
289 integer(c_int) :: cstatus
290 integer :: status
291
292 g2cid = g2id
293 cmsg_num = msg_num - 1 ! C is 0-based.
294 cstatus = g2c_inq_msg_time(g2id, cmsg_num, csig_ref_time, cyear, &
295 cmonth, cday, chour, cminute, csecond)
296 sig_ref_time = csig_ref_time
297 year = cyear
298 month = cmonth
299 day = cday
300 hour = chour
301 minute = cminute
302 second = csecond
303 status = cstatus
304
305 end function g2cf_inq_msg_time
306
322 function g2cf_inq_prod(g2id, msg_num, prod_num, pds_template_len, pds_template, gds_template_len, &
323 gds_template, drs_template_len, drs_template) result(status)
324 use iso_c_binding
325 use g2c_interface
326 implicit none
327
328 integer, intent(in) :: g2id, msg_num, prod_num
329 integer, intent(out) :: pds_template_len
330 integer(kind = 8), intent(out) :: pds_template(*)
331 integer, intent(out) :: gds_template_len
332 integer(kind = 8), intent(out) :: gds_template(*)
333 integer, intent(out) :: drs_template_len
334 integer(kind = 8), intent(out) :: drs_template(*)
335
336 integer(c_int) :: g2cid, cmsg_num
337 integer(c_int) :: cprod_num, cpds_template_len
338 integer(c_long_long) :: cpds_template(g2_max_pds_template_len)
339 integer(c_int) :: cgds_template_len
340 integer(c_long_long) :: cgds_template(g2_max_gds_template_len)
341 integer(c_int) :: cdrs_template_len
342 integer(c_long_long) :: cdrs_template(g2_max_drs_template_len)
343
344 integer(c_int) :: cstatus
345 integer :: status, i
346
347 ! Copy input params to C types.
348 g2cid = g2id
349 cmsg_num = msg_num - 1 ! C is 0-based.
350 cprod_num = prod_num - 1 ! C is 0-based.
351
352 ! Call the C function.
353 cstatus = g2c_inq_prod(g2cid, cmsg_num, cprod_num, cpds_template_len, cpds_template, &
354 cgds_template_len, cgds_template, cdrs_template_len, cdrs_template)
355
356 ! Copy output params to Fortran types.
357 pds_template_len = cpds_template_len
358 if (pds_template_len .gt. 0) then
359 do i = 1, pds_template_len
360 pds_template(i) = cpds_template(i)
361 end do
362 endif
363 gds_template_len = cgds_template_len
364 if (gds_template_len .gt. 0) then
365 do i = 1, gds_template_len
366 gds_template(i) = cgds_template(i)
367 end do
368 endif
369 drs_template_len = cdrs_template_len
370 if (drs_template_len .gt. 0) then
371 do i = 1, drs_template_len
372 drs_template(i) = cdrs_template(i)
373 end do
374 endif
375 status = cstatus
376
377 end function g2cf_inq_prod
378
392 function g2cf_inq_dim(g2id, msg_num, prod_num, dim_num, dimlen, name, val) result(status)
393 use iso_c_binding
394 use g2c_interface
395 implicit none
396
397 integer, intent(in) :: g2id, msg_num, prod_num, dim_num
398 integer(kind = 8), intent(out) :: dimlen
399 character, intent(out) :: name(*)
400 real, intent(out), optional :: val(*)
401
402 integer(c_int) :: g2cid, cmsg_num, cprod_num, cdim_num
403 integer(c_size_t) :: cdimlen
404 real(c_float) :: cval(10)
405
406 character(len = G2_MAX_NAME) :: tmpname
407 integer(kind = 8) :: i
408 integer :: nlen
409 integer(c_int) :: cstatus
410 integer :: status
411
412 ! Copy input params to C types.
413 g2cid = g2id
414 cmsg_num = msg_num - 1 ! C is 0-based.
415 cprod_num = prod_num - 1 ! C is 0-based.
416 cdim_num = dim_num - 1 ! C is 0-based.
417 nlen = len(name)
418
419 ! Call the C function.
420 if (present(val)) then
421 cstatus = g2c_inq_dim(g2cid, cmsg_num, cprod_num, cdim_num, cdimlen, &
422 tmpname, cval)
423 else
424 cstatus = g2c_inq_dim_info(g2cid, cmsg_num, cprod_num, cdim_num, cdimlen, &
425 tmpname)
426 endif
427
428 ! Copy output params to Fortran types.
429 if (cstatus == g2_noerr) then
430 dimlen = cdimlen
431 ! Strip c null char from tmpname if present and set end of string.
432 name(:nlen) = stripcnullchar(tmpname, nlen)
433
434 ! Copy values.
435 if (present(val)) then
436 do i = 1, dimlen
437 val(i) = cval(i)
438 end do
439 endif
440 endif
441
442 ! Copy exit status.
443 status = cstatus
444
445 end function g2cf_inq_dim
446
447 ! /* Getting data. */
448 ! int g2c_get_prod(int g2cid, int msg_num, int prod_num, int *num_data_points,
449 ! float *data);
450 ! function g2c_get_prod(g2id, msg_num, prod_num, num_data_points, data) bind(c)
451 ! use iso_c_binding
452 ! integer(c_int), value :: g2id
453 ! integer(c_int), value :: msg_num
454 ! integer(c_int), value :: prod_num
455 ! integer(c_int), intent(out) :: num_data_points
456 ! real(c_float), intent(out) :: data
457 ! integer(c_int) :: g2c_get_prod
458 ! end function g2c_get_prod
466 function g2cf_close(g2id) result(status)
467 use iso_c_binding
468 use g2c_interface
469 implicit none
470
471 integer, intent(in) :: g2id
472 integer :: status
473
474 integer(c_int) :: cg2id, cstatus
475
476 cg2id = g2id
477 cstatus = g2c_close(cg2id)
478 status = cstatus
479 end function g2cf_close
480
488 function g2cf_set_log_level(log_level) result(status)
489 use iso_c_binding
490 use g2c_interface
491 implicit none
492
493 integer, intent(in) :: log_level
494 integer :: status
495
496 integer(c_int) :: clog_level, cstatus
497
498 clog_level = log_level
499 cstatus = g2c_set_log_level(clog_level)
500 status = cstatus
501 end function g2cf_set_log_level
502
503end module g2cf
Module for the NCEPLIBS-g2 file-based GRIB2 API.
Definition g2cf.F90:8
integer function g2cf_close(g2id)
Close a GRIB2 file.
Definition g2cf.F90:467
integer, parameter g2_max_drs_template_len
Maximum number of entries in a DRS template.
Definition g2cf.F90:24
integer, parameter g2_max_pds_template_len
Maximum number of entries in a PDS template.
Definition g2cf.F90:18
integer function g2cf_inq_dim(g2id, msg_num, prod_num, dim_num, dimlen, name, val)
Learn about a dimension.
Definition g2cf.F90:393
character(len=(len(string)+1)) function addcnullchar(string, nlen)
Add a C_NULL_CHAR to a string to create a C compatible string.
Definition g2cf.F90:43
integer, parameter g2_max_gds_template_len
Maximum number of entries in a GDS template.
Definition g2cf.F90:21
integer function g2cf_open_index(data_file, index_file, mode, g2cid)
Open a GRIB2 file using an exsiting index file (generated by the grb2index utility).
Definition g2cf.F90:153
integer function g2cf_set_log_level(log_level)
Turn internal logging on.
Definition g2cf.F90:489
integer, parameter g2_max_name
Maximum name length.
Definition g2cf.F90:15
integer function g2cf_inq_prod(g2id, msg_num, prod_num, pds_template_len, pds_template, gds_template_len, gds_template, drs_template_len, drs_template)
Learn about a product.
Definition g2cf.F90:324
integer function g2cf_inq_msg(g2id, msg_num, discipline, num_fields, num_local, center, subcenter, master_version, local_version)
Learn about a message are in a GRIB2 file.
Definition g2cf.F90:225
integer, parameter g2_noerr
Return value from functions when there is no error.
Definition g2cf.F90:12
integer function g2cf_open(path, mode, g2id)
Open a GRIB2 file.
Definition g2cf.F90:110
character(len=nlen) function stripcnullchar(cstring, nlen)
Check cstring for a c null char, strip it off and return regular string.
Definition g2cf.F90:82
integer function g2cf_inq_msg_time(g2id, msg_num, sig_ref_time, year, month, day, hour, minute, second)
Learn about message date/time.
Definition g2cf.F90:274
integer function g2cf_inq(g2id, num_msg)
Learn how many messages are in a GRIB2 file.
Definition g2cf.F90:191