49 CHARACTER(len=65) :: description
50 CHARACTER(len=24) :: unit
53TYPE(volgrid6d_var),
PARAMETER :: volgrid6d_var_miss= &
56TYPE(vol7d_var),
PARAMETER :: vol7d_var_horstag(2) = (/ &
57 vol7d_var(
'B11003',
'',
'', 0, 0, 0, 0, 0, 0), &
58 vol7d_var(
'B11004',
'',
'', 0, 0, 0, 0, 0, 0) &
61TYPE(vol7d_var),
PARAMETER :: vol7d_var_horcomp(4) = (/ &
62 vol7d_var(
'B11003',
'',
'', 0, 0, 0, 0, 0, 0), &
63 vol7d_var(
'B11004',
'',
'', 0, 0, 0, 0, 0, 0), &
64 vol7d_var(
'B11200',
'',
'', 0, 0, 0, 0, 0, 0), &
65 vol7d_var(
'B11201',
'',
'', 0, 0, 0, 0, 0, 0) &
82TYPE(conv_func),
PARAMETER :: conv_func_miss=
conv_func(rmiss,rmiss)
83TYPE(conv_func),
PARAMETER :: conv_func_identity=
conv_func(1.0,0.0)
86 TYPE(volgrid6d_var) :: vg6d_var
87 TYPE(vol7d_var) :: v7d_var
88 TYPE(conv_func) :: c_func
90END TYPE vg6d_v7d_var_conv
92TYPE(vg6d_v7d_var_conv),
PARAMETER :: vg6d_v7d_var_conv_miss= &
93 vg6d_v7d_var_conv(volgrid6d_var_miss, vol7d_var_miss, conv_func_miss)
95TYPE(vg6d_v7d_var_conv),
ALLOCATABLE :: conv_fwd(:), conv_bwd(:)
111 MODULE PROCEDURE volgrid6d_var_init
117 MODULE PROCEDURE volgrid6d_var_delete
121 MODULE PROCEDURE volgrid6d_var_c_e
129INTERFACE OPERATOR (==)
130 MODULE PROCEDURE volgrid6d_var_eq, conv_func_eq
137INTERFACE OPERATOR (/=)
138 MODULE PROCEDURE volgrid6d_var_ne, conv_func_ne
141#define VOL7D_POLY_TYPE TYPE(volgrid6d_var)
142#define VOL7D_POLY_TYPES _var6d
143#include "array_utilities_pre.F90"
147 MODULE PROCEDURE display_volgrid6d_var
154INTERFACE OPERATOR (*)
155 MODULE PROCEDURE conv_func_mult
156END INTERFACE OPERATOR (*)
161 MODULE PROCEDURE conv_func_compute
167 MODULE PROCEDURE varbufr2vargrib_convert, vargrib2varbufr_convert
172 c_e, volgrid6d_var_normalize, &
173 OPERATOR(==),
OPERATOR(/=),
OPERATOR(*), &
174 count_distinct, pack_distinct, count_and_pack_distinct, &
175 map_distinct, map_inv_distinct, &
177 vargrib2varbufr, varbufr2vargrib, &
179 volgrid6d_var_hor_comp_index, volgrid6d_var_is_hor_comp
185ELEMENTAL FUNCTION volgrid6d_var_new(centre, category, number, &
186 discipline, description, unit)
RESULT(this)
187integer,
INTENT(in),
OPTIONAL :: centre
188integer,
INTENT(in),
OPTIONAL :: category
189integer,
INTENT(in),
OPTIONAL :: number
190integer,
INTENT(in),
OPTIONAL :: discipline
191CHARACTER(len=*),
INTENT(in),
OPTIONAL :: description
192CHARACTER(len=*),
INTENT(in),
OPTIONAL :: unit
194TYPE(volgrid6d_var) :: this
196CALL init(this, centre, category, number, discipline, description, unit)
198END FUNCTION volgrid6d_var_new
202ELEMENTAL SUBROUTINE volgrid6d_var_init(this, centre, category, number, discipline,description,unit)
203TYPE(volgrid6d_var),
INTENT(INOUT) :: this
204INTEGER,
INTENT(in),
OPTIONAL :: centre
205INTEGER,
INTENT(in),
OPTIONAL :: category
206INTEGER,
INTENT(in),
OPTIONAL :: number
207INTEGER,
INTENT(in),
OPTIONAL :: discipline
208CHARACTER(len=*),
INTENT(in),
OPTIONAL :: description
209CHARACTER(len=*),
INTENT(in),
OPTIONAL :: unit
211IF (
PRESENT(centre))
THEN
215 this%category = imiss
217 this%discipline = imiss
221IF (
PRESENT(category))
THEN
222 this%category = category
224 this%category = imiss
226 this%discipline = imiss
231IF (
PRESENT(number))
THEN
235 this%discipline = imiss
242IF (
PRESENT(discipline))
THEN
243 this%discipline = discipline
245 this%discipline = 255
248IF (
PRESENT(description))
THEN
249 this%description = description
251 this%description = cmiss
254IF (
PRESENT(unit))
THEN
262END SUBROUTINE volgrid6d_var_init
266SUBROUTINE volgrid6d_var_delete(this)
267TYPE(volgrid6d_var),
INTENT(INOUT) :: this
272this%discipline = imiss
273this%description = cmiss
276END SUBROUTINE volgrid6d_var_delete
279ELEMENTAL FUNCTION volgrid6d_var_c_e(this)
RESULT(c_e)
280TYPE(volgrid6d_var),
INTENT(IN) :: this
282c_e = this /= volgrid6d_var_miss
283END FUNCTION volgrid6d_var_c_e
286ELEMENTAL FUNCTION volgrid6d_var_eq(this, that)
RESULT(res)
287TYPE(volgrid6d_var),
INTENT(IN) :: this, that
290IF (this%discipline == that%discipline)
THEN
292 IF (this%discipline == 255)
THEN
293 res = ((this%category == that%category) .OR. &
294 (this%category >= 1 .AND. this%category <=3 .AND. &
295 that%category >= 1 .AND. that%category <=3)) .AND. &
296 this%number == that%number
298 IF ((this%category >= 128 .AND. this%category <= 254) .OR. &
299 (this%number >= 128 .AND. this%number <= 254))
THEN
300 res = res .AND. this%centre == that%centre
304 res = this%category == that%category .AND. &
305 this%number == that%number
307 IF ((this%discipline >= 192 .AND. this%discipline <= 254) .OR. &
308 (this%category >= 192 .AND. this%category <= 254) .OR. &
309 (this%number >= 192 .AND. this%number <= 254))
THEN
310 res = res .AND. this%centre == that%centre
318END FUNCTION volgrid6d_var_eq
321ELEMENTAL FUNCTION volgrid6d_var_ne(this, that)
RESULT(res)
322TYPE(volgrid6d_var),
INTENT(IN) :: this, that
325res = .NOT.(this == that)
327END FUNCTION volgrid6d_var_ne
330#include "array_utilities_inc.F90"
334SUBROUTINE display_volgrid6d_var(this)
335TYPE(volgrid6d_var),
INTENT(in) :: this
337print*,
"GRIDVAR: ",this%centre,this%discipline,this%category,this%number
339END SUBROUTINE display_volgrid6d_var
354SUBROUTINE vargrib2varbufr(vargrib, varbufr, c_func)
355TYPE(volgrid6d_var),
INTENT(in) :: vargrib(:)
356TYPE(vol7d_var),
INTENT(out) :: varbufr(:)
357TYPE(conv_func),
POINTER :: c_func(:)
359INTEGER :: i, n, stallo
361n = min(
SIZE(varbufr),
SIZE(vargrib))
362ALLOCATE(c_func(n),stat=stallo)
364 call l4f_log(l4f_fatal,
"allocating memory")
365 call raise_fatal_error()
372END SUBROUTINE vargrib2varbufr
385FUNCTION vargrib2varbufr_convert(vargrib, c_func)
RESULT(convert)
386TYPE(volgrid6d_var),
INTENT(in) :: vargrib
387TYPE(conv_func),
INTENT(out),
OPTIONAL :: c_func
388TYPE(vol7d_var) :: convert
392IF (.NOT.
ALLOCATED(conv_fwd))
CALL vg6d_v7d_var_conv_setup()
394DO i = 1,
SIZE(conv_fwd)
395 IF (vargrib == conv_fwd(i)%vg6d_var)
THEN
397 IF (
PRESENT(c_func)) c_func = conv_fwd(i)%c_func
403IF (
PRESENT(c_func)) c_func = conv_func_miss
406convert%gribhint(:) = (/vargrib%centre, vargrib%category, vargrib%number, &
409CALL l4f_log(l4f_warn,
'vargrib2varbufr: variable '// &
410 trim(to_char(vargrib%centre))//
':'//trim(to_char(vargrib%category))//
':'// &
411 trim(to_char(vargrib%number))//
':'//trim(to_char(vargrib%discipline))// &
412 ' not found in table')
414END FUNCTION vargrib2varbufr_convert
432SUBROUTINE varbufr2vargrib(varbufr, vargrib, c_func, grid_id_template)
436TYPE(
grid_id),
INTENT(in),
OPTIONAL :: grid_id_template
438INTEGER :: i, n, stallo
440n = min(
SIZE(varbufr),
SIZE(vargrib))
441ALLOCATE(c_func(n),stat=stallo)
443 CALL l4f_log(l4f_fatal,
"allocating memory")
444 CALL raise_fatal_error()
448 vargrib(i) =
convert(varbufr(i), c_func(i), grid_id_template)
451END SUBROUTINE varbufr2vargrib
467FUNCTION varbufr2vargrib_convert(varbufr, c_func, grid_id_template)
RESULT(convert)
469TYPE(
conv_func),
INTENT(out),
OPTIONAL :: c_func
470TYPE(
grid_id),
INTENT(in),
OPTIONAL :: grid_id_template
474#ifdef HAVE_LIBGRIBAPI
475INTEGER :: gaid, editionnumber, category, centre
478IF (.NOT.
ALLOCATED(conv_bwd))
CALL vg6d_v7d_var_conv_setup()
480#ifdef HAVE_LIBGRIBAPI
481editionnumber=255; category=255; centre=255
483IF (
PRESENT(grid_id_template))
THEN
484#ifdef HAVE_LIBGRIBAPI
485 gaid = grid_id_get_gaid(grid_id_template)
487 CALL grib_get(gaid,
'GRIBEditionNumber', editionnumber)
488 IF (editionnumber == 1)
THEN
489 CALL grib_get(gaid,
'gribTablesVersionNo',category)
491 CALL grib_get(gaid,
'centre',centre)
496DO i = 1,
SIZE(conv_bwd)
497 IF (varbufr == conv_bwd(i)%v7d_var)
THEN
498#ifdef HAVE_LIBGRIBAPI
499 IF (editionnumber /= 255)
THEN
500 IF (editionnumber == 1)
THEN
501 IF (conv_bwd(i)%vg6d_var%discipline /= 255) cycle
502 ELSE IF (editionnumber == 2)
THEN
503 IF (conv_bwd(i)%vg6d_var%discipline == 255) cycle
505 IF (conv_bwd(i)%vg6d_var%centre /= 255 .AND. &
506 conv_bwd(i)%vg6d_var%centre /= centre) cycle
510 IF (
PRESENT(c_func)) c_func = conv_bwd(i)%c_func
516IF (
PRESENT(c_func)) c_func = conv_func_miss
519IF (any(varbufr%gribhint /= imiss))
THEN
520 convert%centre = varbufr%gribhint(1)
521 convert%category = varbufr%gribhint(2)
522 convert%number = varbufr%gribhint(3)
523 convert%discipline = varbufr%gribhint(4)
526CALL l4f_log(l4f_warn,
'varbufr2vargrib: variable '// &
527 trim(varbufr%btable)//
" : "//trim(varbufr%description)//
" : "//trim(varbufr%unit)// &
528 ' not found in table')
530END FUNCTION varbufr2vargrib_convert
540SUBROUTINE volgrid6d_var_normalize(this, c_func, grid_id_template)
543TYPE(
grid_id),
INTENT(in) :: grid_id_template
545LOGICAL :: eqed, eqcentre
546INTEGER :: gaid, editionnumber, centre
553c_func = conv_func_miss
555#ifdef HAVE_LIBGRIBAPI
556gaid = grid_id_get_gaid(grid_id_template)
558 CALL grib_get(gaid,
'GRIBEditionNumber', editionnumber)
559 CALL grib_get(gaid,
'centre', centre)
560 eqed = editionnumber == 1 .EQV. this%discipline == 255
561 eqcentre = centre == this%centre
565IF (eqed .AND. eqcentre)
RETURN
567tmpbufr =
convert(this, tmpc_func1)
568tmpgrib =
convert(tmpbufr, tmpc_func2, grid_id_template)
570IF (tmpgrib /= volgrid6d_var_miss)
THEN
573 c_func = tmpc_func1 * tmpc_func2
575 IF (c_func == conv_func_identity) c_func = conv_func_miss
576ELSE IF (.NOT.eqed)
THEN
581END SUBROUTINE volgrid6d_var_normalize
586SUBROUTINE vg6d_v7d_var_conv_setup()
587INTEGER :: un, i, n, stallo
590un = open_package_file(
'vargrib2bufr.csv', filetype_data)
600ALLOCATE(conv_fwd(n),stat=stallo)
602 CALL l4f_log(l4f_fatal,
"allocating memory")
603 CALL raise_fatal_error()
606conv_fwd(:) = vg6d_v7d_var_conv_miss
607CALL import_var_conv(un, conv_fwd)
611un = open_package_file(
'vargrib2bufr.csv', filetype_data)
623ALLOCATE(conv_bwd(n),stat=stallo)
625 CALL l4f_log(l4f_fatal,
"allocating memory")
626 CALL raise_fatal_error()
629conv_bwd(:) = vg6d_v7d_var_conv_miss
630CALL import_var_conv(un, conv_bwd)
632 conv_bwd(i)%c_func%a = 1./conv_bwd(i)%c_func%a
633 conv_bwd(i)%c_func%b = - conv_bwd(i)%c_func%b
639SUBROUTINE import_var_conv(un, conv_type)
640INTEGER,
INTENT(in) :: un
641TYPE(vg6d_v7d_var_conv),
INTENT(out) :: conv_type(:)
644TYPE(csv_record) :: csv
645CHARACTER(len=1024) :: line
646CHARACTER(len=10) :: btable
647INTEGER :: centre, category, number, discipline
649DO i = 1,
SIZE(conv_type)
650 READ(un,
'(A)',
END=200)line
652 CALL csv_record_getfield(csv, btable)
653 CALL csv_record_getfield(csv)
654 CALL csv_record_getfield(csv)
655 CALL init(conv_type(i)%v7d_var, btable=btable)
657 CALL csv_record_getfield(csv, centre)
658 CALL csv_record_getfield(csv, category)
659 CALL csv_record_getfield(csv, number)
660 CALL csv_record_getfield(csv, discipline)
661 CALL init(conv_type(i)%vg6d_var, centre=centre, category=category, &
662 number=number, discipline=discipline)
664 CALL csv_record_getfield(csv, conv_type(i)%c_func%a)
665 CALL csv_record_getfield(csv, conv_type(i)%c_func%b)
671END SUBROUTINE import_var_conv
673END SUBROUTINE vg6d_v7d_var_conv_setup
676ELEMENTAL FUNCTION conv_func_eq(this, that)
RESULT(res)
680res = this%a == that%a .AND. this%b == that%b
682END FUNCTION conv_func_eq
685ELEMENTAL FUNCTION conv_func_ne(this, that)
RESULT(res)
689res = .NOT.(this == that)
691END FUNCTION conv_func_ne
694FUNCTION conv_func_mult(this, that)
RESULT(mult)
700IF (this == conv_func_miss .OR. that == conv_func_miss)
THEN
701 mult = conv_func_miss
703 mult%a = this%a*that%a
704 mult%b = this%a*that%b+this%b
707END FUNCTION conv_func_mult
716ELEMENTAL SUBROUTINE conv_func_compute(this, values)
718REAL,
INTENT(inout) :: values
720IF (this /= conv_func_miss)
THEN
721 IF (c_e(values)) values = values*this%a + this%b
726END SUBROUTINE conv_func_compute
742SUBROUTINE volgrid6d_var_hor_comp_index(this, xind, yind)
744INTEGER,
POINTER :: xind(:), yind(:)
746TYPE(vol7d_var) :: varbufr(size(this))
748INTEGER :: i, nv, counts(size(vol7d_var_horcomp))
753CALL vargrib2varbufr(this, varbufr, c_func)
755DO i = 1,
SIZE(vol7d_var_horcomp)
756 counts(i) = count(varbufr(:) == vol7d_var_horcomp(i))
759IF (any(counts(1::2) > 1))
THEN
760 CALL l4f_log(l4f_warn,
'> 1 variable refer to x component of the same field, (un)rotation impossible')
764IF (any(counts(2::2) > 1))
THEN
765 CALL l4f_log(l4f_warn,
'> 1 variable refer to y component of the same field, (un)rotation impossible')
772DO i = 1,
SIZE(vol7d_var_horcomp), 2
773 IF (counts(i) == 0 .AND. counts(i+1) > 0)
THEN
774 CALL l4f_log(l4f_warn,
'variable '//trim(vol7d_var_horcomp(i+1)%btable)// &
775 ' present but the corresponding x-component '// &
776 trim(vol7d_var_horcomp(i)%btable)//
' is missing, (un)rotation impossible')
778 ELSE IF (counts(i+1) == 0 .AND. counts(i) > 0)
THEN
779 CALL l4f_log(l4f_warn,
'variable '//trim(vol7d_var_horcomp(i)%btable)// &
780 ' present but the corresponding y-component '// &
781 trim(vol7d_var_horcomp(i+1)%btable)//
' is missing, (un)rotation impossible')
784 IF (counts(i) == 1 .AND. counts(i+1) == 1) nv = nv + 1
788ALLOCATE(xind(nv), yind(nv))
790DO i = 1,
SIZE(vol7d_var_horcomp), 2
791 IF (counts(i) == 1 .AND. counts(i+1) == 1)
THEN
793 xind(nv) =
index(varbufr(:), vol7d_var_horcomp(i))
794 yind(nv) =
index(varbufr(:), vol7d_var_horcomp(i+1))
799END SUBROUTINE volgrid6d_var_hor_comp_index
806FUNCTION volgrid6d_var_is_hor_comp(this)
RESULT(is_hor_comp)
808LOGICAL :: is_hor_comp
810TYPE(vol7d_var) :: varbufr
813is_hor_comp = any(varbufr == vol7d_var_horcomp(:))
815END FUNCTION volgrid6d_var_is_hor_comp
Apply the conversion function this to values.
Apply the conversion function this to values.
Destructor for the corresponding object, it assigns it to a missing value.
Display on the screen a brief content of object.
Initialize a volgrid6d_var object with the optional arguments provided.
Utilities for managing files.
This module defines an abstract interface to different drivers for access to files containing gridded...
Definition of constants to be used for declaring variables of a desired type.
Definitions of constants and functions for working with missing values.
Classe per la gestione delle variabili osservate da stazioni meteo e affini.
Class for managing physical variables in a grib 1/2 fashion.
Derived type associated to a block/message/record/band of gridded data coming from a file-like object...
Definisce una variabile meteorologica osservata o un suo attributo.
Class defining a real conversion function between units.
Definition of a physical variable in grib coding style.