|
libsim Versione 8.0.0
|
◆ vol7d_get_voldatir()
Crea una vista a dimensione ridotta di un volume di dati di tipo REAL. È necessario fornire uno solo dei parametri opzionali vol*dp corrispondente al numero di dimensioni richieste. L'ordine delle dimensioni nella vista è quello prefissato in vol7d indipendentemente dall'ordine delle dimensioni fornito in dimlist. In caso di fallimento, in particolare se dimlist non contiene tutte le dimensioni non degeneri del volume richiesto oppure se una delle dimensioni è =0, il puntatore vol*dp è restituito in uno stato disassociato, per cui è opportuno controllare sempre in uscita, lo stato del puntatore per evitare che il programma abortisca con un errore di sistema, ad esempio: REAL, POINTER :: vol2d(:,:)
...
CALL vol7d_get_voldatir(v7d1, (/vol7d_ana_d, vol7d_time_d/), vol2d)
IF (ASSOCIATED(vol2d)) THEN
print*,vol2d
...
ENDIF
return
Definizione alla linea 3646 del file vol7d_class.F90. 3648! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
3649! authors:
3650! Davide Cesari <dcesari@arpa.emr.it>
3651! Paolo Patruno <ppatruno@arpa.emr.it>
3652
3653! This program is free software; you can redistribute it and/or
3654! modify it under the terms of the GNU General Public License as
3655! published by the Free Software Foundation; either version 2 of
3656! the License, or (at your option) any later version.
3657
3658! This program is distributed in the hope that it will be useful,
3659! but WITHOUT ANY WARRANTY; without even the implied warranty of
3660! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3661! GNU General Public License for more details.
3662
3663! You should have received a copy of the GNU General Public License
3664! along with this program. If not, see <http://www.gnu.org/licenses/>.
3665#include "config.h"
3666
3667!> \defgroup vol7d Libsim package, vol7d library.
3668!! The libsim vol7d library contains classes for managing pointwise
3669!! data, tipically weather observations, and for their import from a
3670!! Db-All.e database or from a WMO BUFR file. In order to compile and
3671!! link programs using this library, you have to insert the required
3672!! \c USE statements in the program units involved, specify the
3673!! location of module files when compiling (tipically \c
3674!! -I/usr/lib/gfortran/modules or \c -I/usr/lib64/gfortran/modules or
3675!! \c -I/usr/include) and indicate the library name \c -lsim_vol7d
3676!! when linking, assuming that the library has been installed in a
3677!! default location.
3678
3679!> Classe per la gestione di un volume completo di dati osservati.
3680!! Questo modulo definisce gli oggetti e i metodi per gestire
3681!! volumi di dati meteorologici sparsi.
3682!! I volumi definiti sono principalmente di 4 categorie:
3683!! - volumi di anagrafica (vol7d::volanar & c.), hanno 3 dimensioni:
3684!! - anagrafica
3685!! - variabile di anagrafica
3686!! - rete
3687!! - volumi di attributi di anagrafica (vol7d::volanaattrr & c.), hanno 4 dimensioni:
3688!! - anagrafica
3689!! - variabile di anagrafica
3690!! - rete
3691!! - variabile di attributi delle variabili di anagrafica
3692!! - volumi di dati (vol7d::voldatir & c.), hanno 6 dimensioni:
3693!! - anagrafica
3694!! - tempo
3695!! - livello verticale
3696!! - intervallo temporale (timerange)
3697!! - variabile di dati
3698!! - rete
3699!! - volumi di attributi di dati (vol7d::voldatiattrr & c.), hanno 7 dimensioni:
3700!! - anagrafica
3701!! - tempo
3702!! - livello verticale
3703!! - intervallo temporale (timerange)
3704!! - variabile di dati
3705!! - rete
3706!! - variabile di attributi delle variabili di dati
3707!!
3708!! Tutte le variabili sono inoltre disponibil1 in 5 tipi diversi:
3709!! - reale (abbreviato r)
3710!! - doppia precisione (abbreviato d)
3711!! - intero (abbreviato i)
3712!! - byte (abbreviato b)
3713!! - carattere (abbreviato c)
3714!!
3715!! Per ognuna delle dimensioni possibili, incluse le variabili e gli
3716!! attributi con i loro diversi tipi,
3717!! è definito un cosiddetto "vettore di descrittori", con un
3718!! numero di elementi pari all'estensione della dimensione stessa,
3719!! che contiene le informazioni necessarie a descrivere
3720!! gli elementi di quella dimensione.
3721!! In realtà l'utente non dovrà generalmente occuparsi di costruire
3722!! un oggetto vol7d con le proprie mani ma utilizzerà nella maggior parte
3723!! dei casi i metodi di importazione preconfezionati che importano dati da
3724!! DB-All.e (vol7d_dballe_class) o dal DB Oracle del SIM (vol7d_oraclesim_class).
3725!!
3726!!
3727!! Il programma esempio_v7d.f90 contiene un esempio elementare di uso
3728!! della classe vol7d:
3729!! \include esempio_v7d.f90
3730!!
3731!! \ingroup vol7d
3739USE io_units
3746IMPLICIT NONE
3747
3748
3749INTEGER, PARAMETER :: vol7d_maxdim_a = 3, vol7d_maxdim_aa = 4, &
3750 vol7d_maxdim_d = 6, vol7d_maxdim_ad = 7
3751
3752INTEGER, PARAMETER :: vol7d_ana_a=1 !< indice della dimensione "anagrafica" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
3753INTEGER, PARAMETER :: vol7d_var_a=2 !< indice della dimensione "variabile" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
3754INTEGER, PARAMETER :: vol7d_network_a=3 !< indice della dimensione "rete" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
3755INTEGER, PARAMETER :: vol7d_attr_a=4 !< indice della dimensione "attributo" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
3756INTEGER, PARAMETER :: vol7d_ana_d=1 !< indice della dimensione "anagrafica" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
3757INTEGER, PARAMETER :: vol7d_time_d=2 !< indice della dimensione "tempo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
3758INTEGER, PARAMETER :: vol7d_level_d=3 !< indice della dimensione "livello verticale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
3759INTEGER, PARAMETER :: vol7d_timerange_d=4 !< indice della dimensione "intervallo temporale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
3760INTEGER, PARAMETER :: vol7d_var_d=5 !< indice della dimensione "variabile" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
3761INTEGER, PARAMETER :: vol7d_network_d=6 !< indice della dimensione "rete" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
3762INTEGER, PARAMETER :: vol7d_attr_d=7 !< indice della dimensione "attributo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
3763INTEGER, PARAMETER :: vol7d_cdatalen=32
3764
3765TYPE vol7d_varmap
3766 INTEGER :: r, d, i, b, c
3767END TYPE vol7d_varmap
3768
3769!> Definisce un oggetto contenente i volumi anagrafica e dati e tutti
3770!! i descrittori delle loro dimensioni.
3772!> vettore descrittore della dimensione anagrafica
3773 TYPE(vol7d_ana),POINTER :: ana(:)
3774!> vettore descrittore della dimensione tempo
3775 TYPE(datetime),POINTER :: time(:)
3776!> vettore descrittore della dimensione livello verticale
3777 TYPE(vol7d_level),POINTER :: level(:)
3778!> vettore descrittore della dimensione intervallo temporale (timerange)
3779 TYPE(vol7d_timerange),POINTER :: timerange(:)
3780!> vettore descrittore della dimensione rete
3781 TYPE(vol7d_network),POINTER :: network(:)
3782!> vettore descrittore della dimensione variabile di anagrafica
3783 TYPE(vol7d_varvect) :: anavar
3784!> vettore descrittore della dimensione attributo delle variabili di anagrafica
3785 TYPE(vol7d_varvect) :: anaattr
3786!> vettore descrittore della dimensione variabile di anagrafica che ha tali attributi
3787 TYPE(vol7d_varvect) :: anavarattr
3788!> vettore descrittore della dimensione variabile di dati
3789 TYPE(vol7d_varvect) :: dativar
3790!> vettore descrittore della dimensione attributo delle variabili di dati
3791 TYPE(vol7d_varvect) :: datiattr
3792!> vettore descrittore della dimensione variabile di dati che ha tali attributi
3793 TYPE(vol7d_varvect) :: dativarattr
3794
3795!> volume di anagrafica a valori reali
3796 REAL,POINTER :: volanar(:,:,:)
3797!> volume di anagrafica a valori a doppia precisione
3798 DOUBLE PRECISION,POINTER :: volanad(:,:,:)
3799!> volume di anagrafica a valori interi
3800 INTEGER,POINTER :: volanai(:,:,:)
3801!> volume di anagrafica a valori byte
3802 INTEGER(kind=int_b),POINTER :: volanab(:,:,:)
3803!> volume di anagrafica a valori carattere
3804 CHARACTER(len=vol7d_cdatalen),POINTER :: volanac(:,:,:)
3805
3806!> volume di attributi di anagrafica a valori reali
3807 REAL,POINTER :: volanaattrr(:,:,:,:)
3808!> volume di attributi di anagrafica a valori a doppia precisione
3809 DOUBLE PRECISION,POINTER :: volanaattrd(:,:,:,:)
3810!> volume di attributi di anagrafica a valori interi
3811 INTEGER,POINTER :: volanaattri(:,:,:,:)
3812!> volume di attributi di anagrafica a valori byte
3813 INTEGER(kind=int_b),POINTER :: volanaattrb(:,:,:,:)
3814!> volume di attributi di anagrafica a valori carattere
3815 CHARACTER(len=vol7d_cdatalen),POINTER :: volanaattrc(:,:,:,:)
3816
3817!> volume di dati a valori reali
3818 REAL,POINTER :: voldatir(:,:,:,:,:,:) ! sono i dati
3819!> volume di dati a valori a doppia precisione
3820 DOUBLE PRECISION,POINTER :: voldatid(:,:,:,:,:,:)
3821!> volume di dati a valori interi
3822 INTEGER,POINTER :: voldatii(:,:,:,:,:,:)
3823!> volume di dati a valori byte
3824 INTEGER(kind=int_b),POINTER :: voldatib(:,:,:,:,:,:)
3825!> volume di dati a valori carattere
3826 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatic(:,:,:,:,:,:)
3827
3828!> volume di attributi di dati a valori reali
3829 REAL,POINTER :: voldatiattrr(:,:,:,:,:,:,:)
3830!> volume di attributi di dati a valori a doppia precisione
3831 DOUBLE PRECISION,POINTER :: voldatiattrd(:,:,:,:,:,:,:)
3832!> volume di attributi di dati a valori interi
3833 INTEGER,POINTER :: voldatiattri(:,:,:,:,:,:,:)
3834!> volume di attributi di dati a valori byte
3835 INTEGER(kind=int_b),POINTER :: voldatiattrb(:,:,:,:,:,:,:)
3836!> volume di attributi di dati a valori carattere
3837 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatiattrc(:,:,:,:,:,:,:)
3838
3839!> time definition; 0=time is reference time, 1=time is validity time
3840 integer :: time_definition
3841
3843
3844!> Costruttore per la classe vol7d.
3845!! Deve essere richiamato
3846!! per tutti gli oggetti di questo tipo definiti in un programma.
3848 MODULE PROCEDURE vol7d_init
3849END INTERFACE
3850
3851!> Distruttore per la classe vol7d.
3853 MODULE PROCEDURE vol7d_delete
3854END INTERFACE
3855
3856!> Scrittura su file.
3858 MODULE PROCEDURE vol7d_write_on_file
3859END INTERFACE
3860
3861!> Lettura da file.
3862INTERFACE import
3863 MODULE PROCEDURE vol7d_read_from_file
3864END INTERFACE
3865
3866!>Print object
3868 MODULE PROCEDURE vol7d_display, dat_display, dat_vect_display
3869END INTERFACE
3870
3871!>Represent data in a pretty string
3873 MODULE PROCEDURE to_char_dat
3874END INTERFACE
3875
3876!>doubleprecision data conversion
3878 MODULE PROCEDURE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
3879END INTERFACE
3880
3881!>real data conversion
3883 MODULE PROCEDURE realdatd,realdatr,realdati,realdatb,realdatc
3884END INTERFACE
3885
3886!>integer data conversion
3888 MODULE PROCEDURE integerdatd,integerdatr,integerdati,integerdatb,integerdatc
3889END INTERFACE
3890
3891!>copy object
3893 MODULE PROCEDURE vol7d_copy
3894END INTERFACE
3895
3896!> Test for a missing volume
3898 MODULE PROCEDURE vol7d_c_e
3899END INTERFACE
3900
3901!> Check for problems
3902!! return 0 if all check passed
3903!! print diagnostics with log4f
3905 MODULE PROCEDURE vol7d_check
3906END INTERFACE
3907
3908!> Reduce some dimensions (level and timerage) for semplification (rounding).
3909!! You can use this for simplify and use variables in computation like alchimia
3910!! where fields have to be on the same coordinate
3911!! It return real or character data only: if input is charcter data only it return character otherwise il return
3912!! all the data converted to real.
3913!! examples:
3914!! means in time for short periods and istantaneous values
3915!! 2 meter and surface levels
3916!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
3917!! will be taken (order is by icreasing var index).
3918!! You can use predefined values for classic semplification
3919!! almost_equal_levels and almost_equal_timeranges
3920!! The level or timerange in output will be defined by the first element of level and timerange list
3922 MODULE PROCEDURE v7d_rounding
3923END INTERFACE
3924
3925!!$INTERFACE get_volana
3926!!$ MODULE PROCEDURE vol7d_get_volanar, vol7d_get_volanad, vol7d_get_volanai, &
3927!!$ vol7d_get_volanab, vol7d_get_volanac
3928!!$END INTERFACE
3929!!$
3930!!$INTERFACE get_voldati
3931!!$ MODULE PROCEDURE vol7d_get_voldatir, vol7d_get_voldatid, vol7d_get_voldatii, &
3932!!$ vol7d_get_voldatib, vol7d_get_voldatic
3933!!$END INTERFACE
3934!!$
3935!!$INTERFACE get_volanaattr
3936!!$ MODULE PROCEDURE vol7d_get_volanaattrr, vol7d_get_volanaattrd, &
3937!!$ vol7d_get_volanaattri, vol7d_get_volanaattrb, vol7d_get_volanaattrc
3938!!$END INTERFACE
3939!!$
3940!!$INTERFACE get_voldatiattr
3941!!$ MODULE PROCEDURE vol7d_get_voldatiattrr, vol7d_get_voldatiattrd, &
3942!!$ vol7d_get_voldatiattri, vol7d_get_voldatiattrb, vol7d_get_voldatiattrc
3943!!$END INTERFACE
3944
3945PRIVATE vol7d_get_volr, vol7d_get_vold, vol7d_get_voli, vol7d_get_volb, &
3946 vol7d_get_volc, &
3947 volptr1dr, volptr2dr, volptr3dr, volptr4dr, volptr5dr, volptr6dr, volptr7dr, &
3948 volptr1dd, volptr2dd, volptr3dd, volptr4dd, volptr5dd, volptr6dd, volptr7dd, &
3949 volptr1di, volptr2di, volptr3di, volptr4di, volptr5di, volptr6di, volptr7di, &
3950 volptr1db, volptr2db, volptr3db, volptr4db, volptr5db, volptr6db, volptr7db, &
3951 volptr1dc, volptr2dc, volptr3dc, volptr4dc, volptr5dc, volptr6dc, volptr7dc, &
3952 vol7d_nullifyr, vol7d_nullifyd, vol7d_nullifyi, vol7d_nullifyb, vol7d_nullifyc, &
3953 vol7d_init, vol7d_delete, vol7d_write_on_file, vol7d_read_from_file, &
3954 vol7d_check_alloc_ana, vol7d_force_alloc_ana, &
3955 vol7d_check_alloc_dati, vol7d_force_alloc_dati, vol7d_force_alloc, &
3956 vol7d_display, dat_display, dat_vect_display, &
3957 to_char_dat, vol7d_check
3958
3959PRIVATE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
3960
3961PRIVATE vol7d_c_e
3962
3963CONTAINS
3964
3965
3966!> Inizializza un oggetto di tipo vol7d.
3967!! Non riceve alcun parametro tranne l'oggetto stesso. Attenzione, è necessario
3968!! comunque chiamare sempre il costruttore per evitare di avere dei puntatori in
3969!! uno stato indefinito.
3970SUBROUTINE vol7d_init(this,time_definition)
3971TYPE(vol7d),intent(out) :: this !< oggetto da inizializzare
3972INTEGER,INTENT(IN),OPTIONAL :: time_definition !< 0=time is reference time; 1=time is validity time; 2=time is validity time, forecast range forced to 0 (default=1)
3973
3980
3981NULLIFY(this%ana, this%time, this%level, this%timerange, this%network)
3982
3983NULLIFY(this%volanar, this%volanaattrr, this%voldatir, this%voldatiattrr)
3984NULLIFY(this%volanad, this%volanaattrd, this%voldatid, this%voldatiattrd)
3985NULLIFY(this%volanai, this%volanaattri, this%voldatii, this%voldatiattri)
3986NULLIFY(this%volanab, this%volanaattrb, this%voldatib, this%voldatiattrb)
3987NULLIFY(this%volanac, this%volanaattrc, this%voldatic, this%voldatiattrc)
3988
3989if(present(time_definition)) then
3990 this%time_definition=time_definition
3991else
3992 this%time_definition=1 !default to validity time
3993end if
3994
3995END SUBROUTINE vol7d_init
3996
3997
3998!> Distrugge l'oggetto in maniera pulita, liberando l'eventuale memoria
3999!! dinamicamente allocata. Permette di distruggere la sola parte di dati
4000!! mantenendo l'anagrafica.
4001ELEMENTAL SUBROUTINE vol7d_delete(this, dataonly)
4002TYPE(vol7d),intent(inout) :: this !< oggetto da distruggere
4003LOGICAL, INTENT(in), OPTIONAL :: dataonly !< dealloca solo i dati, tenendo l'anagrafica, (default \c .FALSE.)
4004
4005
4006IF (.NOT. optio_log(dataonly)) THEN
4007 IF (ASSOCIATED(this%volanar)) DEALLOCATE(this%volanar)
4008 IF (ASSOCIATED(this%volanad)) DEALLOCATE(this%volanad)
4009 IF (ASSOCIATED(this%volanai)) DEALLOCATE(this%volanai)
4010 IF (ASSOCIATED(this%volanab)) DEALLOCATE(this%volanab)
4011 IF (ASSOCIATED(this%volanac)) DEALLOCATE(this%volanac)
4012 IF (ASSOCIATED(this%volanaattrr)) DEALLOCATE(this%volanaattrr)
4013 IF (ASSOCIATED(this%volanaattrd)) DEALLOCATE(this%volanaattrd)
4014 IF (ASSOCIATED(this%volanaattri)) DEALLOCATE(this%volanaattri)
4015 IF (ASSOCIATED(this%volanaattrb)) DEALLOCATE(this%volanaattrb)
4016 IF (ASSOCIATED(this%volanaattrc)) DEALLOCATE(this%volanaattrc)
4017ENDIF
4018IF (ASSOCIATED(this%voldatir)) DEALLOCATE(this%voldatir)
4019IF (ASSOCIATED(this%voldatid)) DEALLOCATE(this%voldatid)
4020IF (ASSOCIATED(this%voldatii)) DEALLOCATE(this%voldatii)
4021IF (ASSOCIATED(this%voldatib)) DEALLOCATE(this%voldatib)
4022IF (ASSOCIATED(this%voldatic)) DEALLOCATE(this%voldatic)
4023IF (ASSOCIATED(this%voldatiattrr)) DEALLOCATE(this%voldatiattrr)
4024IF (ASSOCIATED(this%voldatiattrd)) DEALLOCATE(this%voldatiattrd)
4025IF (ASSOCIATED(this%voldatiattri)) DEALLOCATE(this%voldatiattri)
4026IF (ASSOCIATED(this%voldatiattrb)) DEALLOCATE(this%voldatiattrb)
4027IF (ASSOCIATED(this%voldatiattrc)) DEALLOCATE(this%voldatiattrc)
4028
4029IF (.NOT. optio_log(dataonly)) THEN
4030 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
4031 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
4032ENDIF
4033IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
4034IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
4035IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
4036
4037IF (.NOT. optio_log(dataonly)) THEN
4041ENDIF
4045
4046END SUBROUTINE vol7d_delete
4047
4048
4049
4050integer function vol7d_check(this)
4051TYPE(vol7d),intent(in) :: this !< object to check
4052integer :: i,j,k,l,m,n
4053
4054vol7d_check=0
4055
4056if (associated(this%voldatii)) then
4057do i = 1,size(this%voldatii,1)
4058 do j = 1,size(this%voldatii,2)
4059 do k = 1,size(this%voldatii,3)
4060 do l = 1,size(this%voldatii,4)
4061 do m = 1,size(this%voldatii,5)
4062 do n = 1,size(this%voldatii,6)
4063 if (this%voldatii(i,j,k,l,m,n) /= this%voldatii(i,j,k,l,m,n) ) then
4064 CALL l4f_log(l4f_warn,"check: abnormal value at voldatii("&
4066 vol7d_check=1
4067 end if
4068 end do
4069 end do
4070 end do
4071 end do
4072 end do
4073end do
4074end if
4075
4076
4077if (associated(this%voldatir)) then
4078do i = 1,size(this%voldatir,1)
4079 do j = 1,size(this%voldatir,2)
4080 do k = 1,size(this%voldatir,3)
4081 do l = 1,size(this%voldatir,4)
4082 do m = 1,size(this%voldatir,5)
4083 do n = 1,size(this%voldatir,6)
4084 if (this%voldatir(i,j,k,l,m,n) /= this%voldatir(i,j,k,l,m,n) ) then
4085 CALL l4f_log(l4f_warn,"check: abnormal value at voldatir("&
4087 vol7d_check=2
4088 end if
4089 end do
4090 end do
4091 end do
4092 end do
4093 end do
4094end do
4095end if
4096
4097if (associated(this%voldatid)) then
4098do i = 1,size(this%voldatid,1)
4099 do j = 1,size(this%voldatid,2)
4100 do k = 1,size(this%voldatid,3)
4101 do l = 1,size(this%voldatid,4)
4102 do m = 1,size(this%voldatid,5)
4103 do n = 1,size(this%voldatid,6)
4104 if (this%voldatid(i,j,k,l,m,n) /= this%voldatid(i,j,k,l,m,n) ) then
4105 CALL l4f_log(l4f_warn,"check: abnormal value at voldatid("&
4107 vol7d_check=3
4108 end if
4109 end do
4110 end do
4111 end do
4112 end do
4113 end do
4114end do
4115end if
4116
4117if (associated(this%voldatib)) then
4118do i = 1,size(this%voldatib,1)
4119 do j = 1,size(this%voldatib,2)
4120 do k = 1,size(this%voldatib,3)
4121 do l = 1,size(this%voldatib,4)
4122 do m = 1,size(this%voldatib,5)
4123 do n = 1,size(this%voldatib,6)
4124 if (this%voldatib(i,j,k,l,m,n) /= this%voldatib(i,j,k,l,m,n) ) then
4125 CALL l4f_log(l4f_warn,"check: abnormal value at voldatib("&
4127 vol7d_check=4
4128 end if
4129 end do
4130 end do
4131 end do
4132 end do
4133 end do
4134end do
4135end if
4136
4137end function vol7d_check
4138
4139
4140
4141!TODO da completare ! aborta se i volumi sono allocati a dimensione 0
4142!> stampa a video una sintesi del contenuto
4143SUBROUTINE vol7d_display(this)
4144TYPE(vol7d),intent(in) :: this !< oggetto da visualizzare
4145integer :: i
4146
4147REAL :: rdat
4148DOUBLE PRECISION :: ddat
4149INTEGER :: idat
4150INTEGER(kind=int_b) :: bdat
4151CHARACTER(len=vol7d_cdatalen) :: cdat
4152
4153
4154print*,"<<<<<<<<<<<<<<<<<<< vol7d object >>>>>>>>>>>>>>>>>>>>"
4155if (this%time_definition == 0) then
4156 print*,"TIME DEFINITION: time is reference time"
4157else if (this%time_definition == 1) then
4158 print*,"TIME DEFINITION: time is validity time"
4159else if (this%time_definition == 2) then
4160 print*,"TIME DEFINITION: time is validity time, forecast range forced to 0"
4161else
4162 print*,"Time definition has a wrong walue:", this%time_definition
4163end if
4164
4165IF (ASSOCIATED(this%network))then
4166 print*,"---- network vector ----"
4167 print*,"elements=",size(this%network)
4168 do i=1, size(this%network)
4170 end do
4171end IF
4172
4173IF (ASSOCIATED(this%ana))then
4174 print*,"---- ana vector ----"
4175 print*,"elements=",size(this%ana)
4176 do i=1, size(this%ana)
4178 end do
4179end IF
4180
4181IF (ASSOCIATED(this%time))then
4182 print*,"---- time vector ----"
4183 print*,"elements=",size(this%time)
4184 do i=1, size(this%time)
4186 end do
4187end if
4188
4189IF (ASSOCIATED(this%level)) then
4190 print*,"---- level vector ----"
4191 print*,"elements=",size(this%level)
4192 do i =1,size(this%level)
4194 end do
4195end if
4196
4197IF (ASSOCIATED(this%timerange))then
4198 print*,"---- timerange vector ----"
4199 print*,"elements=",size(this%timerange)
4200 do i =1,size(this%timerange)
4202 end do
4203end if
4204
4205
4206print*,"---- ana vector ----"
4207print*,""
4208print*,"->>>>>>>>> anavar -"
4210print*,""
4211print*,"->>>>>>>>> anaattr -"
4213print*,""
4214print*,"->>>>>>>>> anavarattr -"
4216
4217print*,"-- ana data section (first point) --"
4218
4219idat=imiss
4220rdat=rmiss
4221ddat=dmiss
4222bdat=ibmiss
4223cdat=cmiss
4224
4225!ntime = MIN(SIZE(this%time),nprint)
4226!ntimerange = MIN(SIZE(this%timerange),nprint)
4227!nlevel = MIN(SIZE(this%level),nprint)
4228!nnetwork = MIN(SIZE(this%network),nprint)
4229!nana = MIN(SIZE(this%ana),nprint)
4230
4231IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0) THEN
4232if (associated(this%volanai)) then
4233 do i=1,size(this%anavar%i)
4234 idat=this%volanai(1,i,1)
4236 end do
4237end if
4238idat=imiss
4239
4240if (associated(this%volanar)) then
4241 do i=1,size(this%anavar%r)
4242 rdat=this%volanar(1,i,1)
4244 end do
4245end if
4246rdat=rmiss
4247
4248if (associated(this%volanad)) then
4249 do i=1,size(this%anavar%d)
4250 ddat=this%volanad(1,i,1)
4252 end do
4253end if
4254ddat=dmiss
4255
4256if (associated(this%volanab)) then
4257 do i=1,size(this%anavar%b)
4258 bdat=this%volanab(1,i,1)
4260 end do
4261end if
4262bdat=ibmiss
4263
4264if (associated(this%volanac)) then
4265 do i=1,size(this%anavar%c)
4266 cdat=this%volanac(1,i,1)
4268 end do
4269end if
4270cdat=cmiss
4271ENDIF
4272
4273print*,"---- data vector ----"
4274print*,""
4275print*,"->>>>>>>>> dativar -"
4277print*,""
4278print*,"->>>>>>>>> datiattr -"
4280print*,""
4281print*,"->>>>>>>>> dativarattr -"
4283
4284print*,"-- data data section (first point) --"
4285
4286idat=imiss
4287rdat=rmiss
4288ddat=dmiss
4289bdat=ibmiss
4290cdat=cmiss
4291
4292IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0 .AND. size(this%time) > 0 &
4293 .AND. size(this%level) > 0 .AND. size(this%timerange) > 0) THEN
4294if (associated(this%voldatii)) then
4295 do i=1,size(this%dativar%i)
4296 idat=this%voldatii(1,1,1,1,i,1)
4298 end do
4299end if
4300idat=imiss
4301
4302if (associated(this%voldatir)) then
4303 do i=1,size(this%dativar%r)
4304 rdat=this%voldatir(1,1,1,1,i,1)
4306 end do
4307end if
4308rdat=rmiss
4309
4310if (associated(this%voldatid)) then
4311 do i=1,size(this%dativar%d)
4312 ddat=this%voldatid(1,1,1,1,i,1)
4314 end do
4315end if
4316ddat=dmiss
4317
4318if (associated(this%voldatib)) then
4319 do i=1,size(this%dativar%b)
4320 bdat=this%voldatib(1,1,1,1,i,1)
4322 end do
4323end if
4324bdat=ibmiss
4325
4326if (associated(this%voldatic)) then
4327 do i=1,size(this%dativar%c)
4328 cdat=this%voldatic(1,1,1,1,i,1)
4330 end do
4331end if
4332cdat=cmiss
4333ENDIF
4334
4335print*,"<<<<<<<<<<<<<<<<<<< END vol7d object >>>>>>>>>>>>>>>>>>>>"
4336
4337END SUBROUTINE vol7d_display
4338
4339
4340!> stampa a video una sintesi del contenuto
4341SUBROUTINE dat_display(this,idat,rdat,ddat,bdat,cdat)
4342TYPE(vol7d_var),intent(in) :: this !< oggetto da visualizzare
4343!> real
4344REAL :: rdat
4345!> double precision
4346DOUBLE PRECISION :: ddat
4347!> integer
4348INTEGER :: idat
4349!> byte
4350INTEGER(kind=int_b) :: bdat
4351!> character
4352CHARACTER(len=*) :: cdat
4353
4354print *, to_char_dat(this,idat,rdat,ddat,bdat,cdat)
4355
4356end SUBROUTINE dat_display
4357
4358!> stampa a video una sintesi del contenuto
4359SUBROUTINE dat_vect_display(this,idat,rdat,ddat,bdat,cdat)
4360
4361TYPE(vol7d_var),intent(in) :: this(:) !< oggetto da visualizzare
4362!> real
4363REAL :: rdat(:)
4364!> double precision
4365DOUBLE PRECISION :: ddat(:)
4366!> integer
4367INTEGER :: idat(:)
4368!> byte
4369INTEGER(kind=int_b) :: bdat(:)
4370!> character
4371CHARACTER(len=*):: cdat(:)
4372
4373integer :: i
4374
4375do i =1,size(this)
4377end do
4378
4379end SUBROUTINE dat_vect_display
4380
4381
4382FUNCTION to_char_dat(this,idat,rdat,ddat,bdat,cdat)
4383#ifdef HAVE_DBALLE
4384USE dballef
4385#endif
4386TYPE(vol7d_var),INTENT(in) :: this
4387!> real
4388REAL :: rdat
4389!> double precision
4390DOUBLE PRECISION :: ddat
4391!> integer
4392INTEGER :: idat
4393!> byte
4394INTEGER(kind=int_b) :: bdat
4395!> character
4396CHARACTER(len=*) :: cdat
4397CHARACTER(len=80) :: to_char_dat
4398
4399CHARACTER(len=LEN(to_char_dat)) :: to_char_tmp
4400
4401
4402#ifdef HAVE_DBALLE
4403INTEGER :: handle, ier
4404
4405handle = 0
4406to_char_dat="VALUE: "
4407
4412
4414 ier = idba_messaggi(handle,"/dev/null", "w", "BUFR")
4415 ier = idba_spiegab(handle,this%btable,cdat,to_char_tmp)
4416 ier = idba_fatto(handle)
4417 to_char_dat=trim(to_char_dat)//" ;char> "//trim(to_char_tmp)
4418endif
4419
4420#else
4421
4422to_char_dat="VALUE: "
4428
4429#endif
4430
4431END FUNCTION to_char_dat
4432
4433
4434!> Tests whether anything has ever been assigned to a vol7d object
4435!! (.TRUE.) or it is as clean as after an init (.FALSE.).
4436FUNCTION vol7d_c_e(this) RESULT(c_e)
4437TYPE(vol7d), INTENT(in) :: this
4438
4439LOGICAL :: c_e
4440
4442 ASSOCIATED(this%level) .OR. ASSOCIATED(this%timerange) .OR. &
4443 ASSOCIATED(this%network) .OR. &
4444 ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
4445 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
4446 ASSOCIATED(this%anavar%c) .OR. &
4447 ASSOCIATED(this%anaattr%r) .OR. ASSOCIATED(this%anaattr%d) .OR. &
4448 ASSOCIATED(this%anaattr%i) .OR. ASSOCIATED(this%anaattr%b) .OR. &
4449 ASSOCIATED(this%anaattr%c) .OR. &
4450 ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
4451 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
4452 ASSOCIATED(this%dativar%c) .OR. &
4453 ASSOCIATED(this%datiattr%r) .OR. ASSOCIATED(this%datiattr%d) .OR. &
4454 ASSOCIATED(this%datiattr%i) .OR. ASSOCIATED(this%datiattr%b) .OR. &
4455 ASSOCIATED(this%datiattr%c)
4456
4457END FUNCTION vol7d_c_e
4458
4459
4460!> Metodo per allocare i descrittori delle 7 dimensioni.
4461!! Riceve un grande numero di parametri opzionali che
4462!! indicano quali descrittori allocare e con quale estensione;
4463!! i descrittori non specificati non vengono toccati.
4464!! Può essere quindi chiamato più volte allocando via via
4465!! descrittori relativi a dimensioni diverse.
4466!! Se un descrittore richiesto è già allocato, viene deallocato
4467!! (perdendone l'eventuale contenuto) e riallocato con l'estensione
4468!! richiesta.
4469!! Per i descrittori relativi a dimensioni che non siano variabili o attributi,
4470!! è possibile specificare l'estensione di una dimensione a 0,
4471!! in tal caso il descrittore viene comunque allocato con lunghezza nulla,
4472!! che è diverso da non allocarlo. Per i descrittori di variabili e attributi
4473!! passare un'estensione 0 equivale a non fornire il parametro.
4474!! Avere uno o più descrittori dimensionati con estensione nulla fa sì
4475!! che anche il volume dati successivamente allocato abbia estensione nulla;
4476!! sebbene ciò appaia inutile, un volume del genere può in realtà servire,
4477!! in associazione ai metodi ::vol7d_merge o ::vol7d_append per estendere
4478!! un volume esistente aggiungendo elementi in alcune dimensioni (quelle
4479!! a estensione non nulla, ovviamente) e mantenendo invariato tutto il resto.
4480!! Per quanto riguarda i descrittori delle dimensioni relative alle
4481!! variabili, la relativa estensione è specificata con la nomenclatura
4482!! \a n<x><y><z> dove <x> può valere:
4483!! - \a ana per variabili relative a voumi di anagrafica
4484!! - \a dati per variabili relative a voumi di dati
4485!!
4486!! <y> può valere:
4487!! - \a var per variabili
4488!! - \a attr per attributi
4489!! - \a varattr variabili aventi attributi nei volumi di attributi
4490!!
4491!! <z> può valere:
4492!! - \a r per variabili o attributi a valori reali
4493!! - \a d per variabili o attributi a valori a doppia precisione
4494!! - \a i per variabili o attributi a valori interi
4495!! - \a b per variabili o attributi a valori byte
4496!! - \a c per variabili o attributi a valori carattere
4497!!
4498SUBROUTINE vol7d_alloc(this, nana, ntime, nlevel, ntimerange, nnetwork, &
4499 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
4500 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
4501 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
4502 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
4503 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
4504 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc, &
4505 ini)
4506TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i descrittori
4507INTEGER,INTENT(in),OPTIONAL :: nana !< estensione della dimensione anagrafica
4508INTEGER,INTENT(in),OPTIONAL :: ntime !< estensione della dimensione tempo
4509INTEGER,INTENT(in),OPTIONAL :: nlevel !< estensione della dimensione livello varticale
4510INTEGER,INTENT(in),OPTIONAL :: ntimerange !< estensione della dimensione intervallo temporale (timerange)
4511INTEGER,INTENT(in),OPTIONAL :: nnetwork !< estensione della dimensione rete
4512!> estensione delle possibili dimensioni variabile
4513INTEGER,INTENT(in),OPTIONAL :: &
4514 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
4515 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
4516 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
4517 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
4518 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
4519 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc
4520LOGICAL,INTENT(in),OPTIONAL :: ini !< se fornito e vale \c .TRUE., viene chiamato il costruttore, senza parametri opzionali, per ogni elemento di tutti i descrittori allocati, inizializzandolo quindi a valore mancante
4521
4522INTEGER :: i
4523LOGICAL :: linit
4524
4525IF (PRESENT(ini)) THEN
4526 linit = ini
4527ELSE
4528 linit = .false.
4529ENDIF
4530
4531! Dimensioni principali
4532IF (PRESENT(nana)) THEN
4533 IF (nana >= 0) THEN
4534 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
4535 ALLOCATE(this%ana(nana))
4536 IF (linit) THEN
4537 DO i = 1, nana
4539 ENDDO
4540 ENDIF
4541 ENDIF
4542ENDIF
4543IF (PRESENT(ntime)) THEN
4544 IF (ntime >= 0) THEN
4545 IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
4546 ALLOCATE(this%time(ntime))
4547 IF (linit) THEN
4548 DO i = 1, ntime
4550 ENDDO
4551 ENDIF
4552 ENDIF
4553ENDIF
4554IF (PRESENT(nlevel)) THEN
4555 IF (nlevel >= 0) THEN
4556 IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
4557 ALLOCATE(this%level(nlevel))
4558 IF (linit) THEN
4559 DO i = 1, nlevel
4561 ENDDO
4562 ENDIF
4563 ENDIF
4564ENDIF
4565IF (PRESENT(ntimerange)) THEN
4566 IF (ntimerange >= 0) THEN
4567 IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
4568 ALLOCATE(this%timerange(ntimerange))
4569 IF (linit) THEN
4570 DO i = 1, ntimerange
4572 ENDDO
4573 ENDIF
4574 ENDIF
4575ENDIF
4576IF (PRESENT(nnetwork)) THEN
4577 IF (nnetwork >= 0) THEN
4578 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
4579 ALLOCATE(this%network(nnetwork))
4580 IF (linit) THEN
4581 DO i = 1, nnetwork
4583 ENDDO
4584 ENDIF
4585 ENDIF
4586ENDIF
4587! Dimensioni dei tipi delle variabili
4588CALL vol7d_varvect_alloc(this%anavar, nanavarr, nanavard, &
4589 nanavari, nanavarb, nanavarc, ini)
4590CALL vol7d_varvect_alloc(this%anaattr, nanaattrr, nanaattrd, &
4591 nanaattri, nanaattrb, nanaattrc, ini)
4592CALL vol7d_varvect_alloc(this%anavarattr, nanavarattrr, nanavarattrd, &
4593 nanavarattri, nanavarattrb, nanavarattrc, ini)
4594CALL vol7d_varvect_alloc(this%dativar, ndativarr, ndativard, &
4595 ndativari, ndativarb, ndativarc, ini)
4596CALL vol7d_varvect_alloc(this%datiattr, ndatiattrr, ndatiattrd, &
4597 ndatiattri, ndatiattrb, ndatiattrc, ini)
4598CALL vol7d_varvect_alloc(this%dativarattr, ndativarattrr, ndativarattrd, &
4599 ndativarattri, ndativarattrb, ndativarattrc, ini)
4600
4601END SUBROUTINE vol7d_alloc
4602
4603
4604FUNCTION vol7d_check_alloc_ana(this)
4605TYPE(vol7d),INTENT(in) :: this
4606LOGICAL :: vol7d_check_alloc_ana
4607
4608vol7d_check_alloc_ana = ASSOCIATED(this%ana) .AND. ASSOCIATED(this%network)
4609
4610END FUNCTION vol7d_check_alloc_ana
4611
4612SUBROUTINE vol7d_force_alloc_ana(this, ini)
4613TYPE(vol7d),INTENT(inout) :: this
4614LOGICAL,INTENT(in),OPTIONAL :: ini
4615
4616! Alloco i descrittori minimi per avere un volume di anagrafica
4617IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=1, ini=ini)
4618IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=1, ini=ini)
4619
4620END SUBROUTINE vol7d_force_alloc_ana
4621
4622
4623FUNCTION vol7d_check_alloc_dati(this)
4624TYPE(vol7d),INTENT(in) :: this
4625LOGICAL :: vol7d_check_alloc_dati
4626
4627vol7d_check_alloc_dati = vol7d_check_alloc_ana(this) .AND. &
4628 ASSOCIATED(this%time) .AND. ASSOCIATED(this%level) .AND. &
4629 ASSOCIATED(this%timerange)
4630
4631END FUNCTION vol7d_check_alloc_dati
4632
4633SUBROUTINE vol7d_force_alloc_dati(this, ini)
4634TYPE(vol7d),INTENT(inout) :: this
4635LOGICAL,INTENT(in),OPTIONAL :: ini
4636
4637! Alloco i descrittori minimi per avere un volume di dati
4638CALL vol7d_force_alloc_ana(this, ini)
4639IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=1, ini=ini)
4640IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=1, ini=ini)
4641IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=1, ini=ini)
4642
4643END SUBROUTINE vol7d_force_alloc_dati
4644
4645
4646SUBROUTINE vol7d_force_alloc(this)
4647TYPE(vol7d),INTENT(inout) :: this
4648
4649! If anything really not allocated yet, allocate with size 0
4650IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=0)
4651IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=0)
4652IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=0)
4653IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=0)
4654IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=0)
4655
4656END SUBROUTINE vol7d_force_alloc
4657
4658
4659FUNCTION vol7d_check_vol(this)
4660TYPE(vol7d),INTENT(in) :: this !< oggetto da controllare
4661LOGICAL :: vol7d_check_vol
4662
4663vol7d_check_vol = c_e(this)
4664
4665! Anagrafica
4666IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
4667 vol7d_check_vol = .false.
4668ENDIF
4669
4670IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
4671 vol7d_check_vol = .false.
4672ENDIF
4673
4674IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
4675 vol7d_check_vol = .false.
4676ENDIF
4677
4678IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
4679 vol7d_check_vol = .false.
4680ENDIF
4681
4682IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
4683 vol7d_check_vol = .false.
4684ENDIF
4685IF (ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
4686 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
4687 ASSOCIATED(this%anavar%c)) THEN
4688 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_ana(this)
4689ENDIF
4690
4691! Attributi dell'anagrafica
4692IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
4693 .NOT.ASSOCIATED(this%volanaattrr)) THEN
4694 vol7d_check_vol = .false.
4695ENDIF
4696
4697IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
4698 .NOT.ASSOCIATED(this%volanaattrd)) THEN
4699 vol7d_check_vol = .false.
4700ENDIF
4701
4702IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
4703 .NOT.ASSOCIATED(this%volanaattri)) THEN
4704 vol7d_check_vol = .false.
4705ENDIF
4706
4707IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
4708 .NOT.ASSOCIATED(this%volanaattrb)) THEN
4709 vol7d_check_vol = .false.
4710ENDIF
4711
4712IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
4713 .NOT.ASSOCIATED(this%volanaattrc)) THEN
4714 vol7d_check_vol = .false.
4715ENDIF
4716
4717! Dati
4718IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
4719 vol7d_check_vol = .false.
4720ENDIF
4721
4722IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
4723 vol7d_check_vol = .false.
4724ENDIF
4725
4726IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
4727 vol7d_check_vol = .false.
4728ENDIF
4729
4730IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
4731 vol7d_check_vol = .false.
4732ENDIF
4733
4734IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
4735 vol7d_check_vol = .false.
4736ENDIF
4737
4738! Attributi dei dati
4739IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
4740 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
4741 vol7d_check_vol = .false.
4742ENDIF
4743
4744IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
4745 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
4746 vol7d_check_vol = .false.
4747ENDIF
4748
4749IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
4750 .NOT.ASSOCIATED(this%voldatiattri)) THEN
4751 vol7d_check_vol = .false.
4752ENDIF
4753
4754IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
4755 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
4756 vol7d_check_vol = .false.
4757ENDIF
4758
4759IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
4760 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
4761 vol7d_check_vol = .false.
4762ENDIF
4763IF (ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
4764 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
4765 ASSOCIATED(this%dativar%c)) THEN
4766 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_dati(this)
4767ENDIF
4768
4769END FUNCTION vol7d_check_vol
4770
4771
4772!> Metodo per allocare i volumi richiesti di variabili e attributi per
4773!! anagrafica e dati.
4774!! Se alcuni dei descrittori relativi alle dimensioni anagrafica,
4775!! livello verticale, tempo, intervallo temporale (timerange), rete non sono
4776!! stati richiesti preventivamente con la ::vol7d_alloc, essi vengono allocati
4777!! automaticamente da questo metodo
4778!! con estensione di default pari a 1 (non 0!), questo significa, ad esempio,
4779!! che se prevedo di avere soli dati superficiali, cioè ad un solo livello
4780!! verticale, o una sola rete di stazioni, non devo preoccuparmi di
4781!! specificare questa informazione.
4782!! Tra i 20 possibili volumi allocabili
4783!! ((variabili,attributi)*(anagrafica,dati)*(r,d,i,b,c)=20)
4784!! saranno allocati solo quelli per cui è stato precedentemente richiesto il
4785!! corrispondente descrittore variabili/attributi con la ::vol7d_alloc.
4786SUBROUTINE vol7d_alloc_vol(this, ini, inivol)
4787TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i volumi
4788LOGICAL,INTENT(in),OPTIONAL :: ini !< se fornito e vale \c .TRUE., viene chiamato il costruttore, senza parametri opzionali, per ogni elemento di tutti i descrittori allocati
4789LOGICAL,INTENT(in),OPTIONAL :: inivol !< se fornito e vale \c .TRUE., i volumi allocati saranno inizializzati a valore mancante
4790
4791LOGICAL :: linivol
4792
4793IF (PRESENT(inivol)) THEN
4794 linivol = inivol
4795ELSE
4796 linivol = .true.
4797ENDIF
4798
4799! Anagrafica
4800IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
4801 CALL vol7d_force_alloc_ana(this, ini)
4802 ALLOCATE(this%volanar(SIZE(this%ana), SIZE(this%anavar%r), SIZE(this%network)))
4803 IF (linivol) this%volanar(:,:,:) = rmiss
4804ENDIF
4805
4806IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
4807 CALL vol7d_force_alloc_ana(this, ini)
4808 ALLOCATE(this%volanad(SIZE(this%ana), SIZE(this%anavar%d), SIZE(this%network)))
4809 IF (linivol) this%volanad(:,:,:) = rdmiss
4810ENDIF
4811
4812IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
4813 CALL vol7d_force_alloc_ana(this, ini)
4814 ALLOCATE(this%volanai(SIZE(this%ana), SIZE(this%anavar%i), SIZE(this%network)))
4815 IF (linivol) this%volanai(:,:,:) = imiss
4816ENDIF
4817
4818IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
4819 CALL vol7d_force_alloc_ana(this, ini)
4820 ALLOCATE(this%volanab(SIZE(this%ana), SIZE(this%anavar%b), SIZE(this%network)))
4821 IF (linivol) this%volanab(:,:,:) = ibmiss
4822ENDIF
4823
4824IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
4825 CALL vol7d_force_alloc_ana(this, ini)
4826 ALLOCATE(this%volanac(SIZE(this%ana), SIZE(this%anavar%c), SIZE(this%network)))
4827 IF (linivol) this%volanac(:,:,:) = cmiss
4828ENDIF
4829
4830! Attributi dell'anagrafica
4831IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
4832 .NOT.ASSOCIATED(this%volanaattrr)) THEN
4833 CALL vol7d_force_alloc_ana(this, ini)
4834 ALLOCATE(this%volanaattrr(SIZE(this%ana), SIZE(this%anavarattr%r), &
4835 SIZE(this%network), SIZE(this%anaattr%r)))
4836 IF (linivol) this%volanaattrr(:,:,:,:) = rmiss
4837ENDIF
4838
4839IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
4840 .NOT.ASSOCIATED(this%volanaattrd)) THEN
4841 CALL vol7d_force_alloc_ana(this, ini)
4842 ALLOCATE(this%volanaattrd(SIZE(this%ana), SIZE(this%anavarattr%d), &
4843 SIZE(this%network), SIZE(this%anaattr%d)))
4844 IF (linivol) this%volanaattrd(:,:,:,:) = rdmiss
4845ENDIF
4846
4847IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
4848 .NOT.ASSOCIATED(this%volanaattri)) THEN
4849 CALL vol7d_force_alloc_ana(this, ini)
4850 ALLOCATE(this%volanaattri(SIZE(this%ana), SIZE(this%anavarattr%i), &
4851 SIZE(this%network), SIZE(this%anaattr%i)))
4852 IF (linivol) this%volanaattri(:,:,:,:) = imiss
4853ENDIF
4854
4855IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
4856 .NOT.ASSOCIATED(this%volanaattrb)) THEN
4857 CALL vol7d_force_alloc_ana(this, ini)
4858 ALLOCATE(this%volanaattrb(SIZE(this%ana), SIZE(this%anavarattr%b), &
4859 SIZE(this%network), SIZE(this%anaattr%b)))
4860 IF (linivol) this%volanaattrb(:,:,:,:) = ibmiss
4861ENDIF
4862
4863IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
4864 .NOT.ASSOCIATED(this%volanaattrc)) THEN
4865 CALL vol7d_force_alloc_ana(this, ini)
4866 ALLOCATE(this%volanaattrc(SIZE(this%ana), SIZE(this%anavarattr%c), &
4867 SIZE(this%network), SIZE(this%anaattr%c)))
4868 IF (linivol) this%volanaattrc(:,:,:,:) = cmiss
4869ENDIF
4870
4871! Dati
4872IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
4873 CALL vol7d_force_alloc_dati(this, ini)
4874 ALLOCATE(this%voldatir(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4875 SIZE(this%timerange), SIZE(this%dativar%r), SIZE(this%network)))
4876 IF (linivol) this%voldatir(:,:,:,:,:,:) = rmiss
4877ENDIF
4878
4879IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
4880 CALL vol7d_force_alloc_dati(this, ini)
4881 ALLOCATE(this%voldatid(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4882 SIZE(this%timerange), SIZE(this%dativar%d), SIZE(this%network)))
4883 IF (linivol) this%voldatid(:,:,:,:,:,:) = rdmiss
4884ENDIF
4885
4886IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
4887 CALL vol7d_force_alloc_dati(this, ini)
4888 ALLOCATE(this%voldatii(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4889 SIZE(this%timerange), SIZE(this%dativar%i), SIZE(this%network)))
4890 IF (linivol) this%voldatii(:,:,:,:,:,:) = imiss
4891ENDIF
4892
4893IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
4894 CALL vol7d_force_alloc_dati(this, ini)
4895 ALLOCATE(this%voldatib(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4896 SIZE(this%timerange), SIZE(this%dativar%b), SIZE(this%network)))
4897 IF (linivol) this%voldatib(:,:,:,:,:,:) = ibmiss
4898ENDIF
4899
4900IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
4901 CALL vol7d_force_alloc_dati(this, ini)
4902 ALLOCATE(this%voldatic(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4903 SIZE(this%timerange), SIZE(this%dativar%c), SIZE(this%network)))
4904 IF (linivol) this%voldatic(:,:,:,:,:,:) = cmiss
4905ENDIF
4906
4907! Attributi dei dati
4908IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
4909 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
4910 CALL vol7d_force_alloc_dati(this, ini)
4911 ALLOCATE(this%voldatiattrr(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4912 SIZE(this%timerange), SIZE(this%dativarattr%r), SIZE(this%network), &
4913 SIZE(this%datiattr%r)))
4914 IF (linivol) this%voldatiattrr(:,:,:,:,:,:,:) = rmiss
4915ENDIF
4916
4917IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
4918 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
4919 CALL vol7d_force_alloc_dati(this, ini)
4920 ALLOCATE(this%voldatiattrd(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4921 SIZE(this%timerange), SIZE(this%dativarattr%d), SIZE(this%network), &
4922 SIZE(this%datiattr%d)))
4923 IF (linivol) this%voldatiattrd(:,:,:,:,:,:,:) = rdmiss
4924ENDIF
4925
4926IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
4927 .NOT.ASSOCIATED(this%voldatiattri)) THEN
4928 CALL vol7d_force_alloc_dati(this, ini)
4929 ALLOCATE(this%voldatiattri(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4930 SIZE(this%timerange), SIZE(this%dativarattr%i), SIZE(this%network), &
4931 SIZE(this%datiattr%i)))
4932 IF (linivol) this%voldatiattri(:,:,:,:,:,:,:) = imiss
4933ENDIF
4934
4935IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
4936 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
4937 CALL vol7d_force_alloc_dati(this, ini)
4938 ALLOCATE(this%voldatiattrb(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4939 SIZE(this%timerange), SIZE(this%dativarattr%b), SIZE(this%network), &
4940 SIZE(this%datiattr%b)))
4941 IF (linivol) this%voldatiattrb(:,:,:,:,:,:,:) = ibmiss
4942ENDIF
4943
4944IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
4945 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
4946 CALL vol7d_force_alloc_dati(this, ini)
4947 ALLOCATE(this%voldatiattrc(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
4948 SIZE(this%timerange), SIZE(this%dativarattr%c), SIZE(this%network), &
4949 SIZE(this%datiattr%c)))
4950 IF (linivol) this%voldatiattrc(:,:,:,:,:,:,:) = cmiss
4951ENDIF
4952
4953! Catch-all method
4954CALL vol7d_force_alloc(this)
4955
4956! Creo gli indici var-attr
4957
4958#ifdef DEBUG
4959CALL l4f_log(l4f_debug,"calling: vol7d_set_attr_ind")
4960#endif
4961
4962CALL vol7d_set_attr_ind(this)
4963
4964
4965
4966END SUBROUTINE vol7d_alloc_vol
4967
4968
4969!> Metodo per creare gli indici che associano le variabili aventi attributo
4970!! alle variabili nei relativi descrittori.
4971!! Ha senso chiamare questo metodo solo dopo che i descrittori delle variabili
4972!! e degli attributi desiderati sono stati allocati ed è stato assegnato un
4973!! valore ai relativi membri btable (vedi vol7d_var_class::vol7d_var), se
4974!! i descrittori non sono stati allocati o assegnati, il metodo non fa niente.
4975SUBROUTINE vol7d_set_attr_ind(this)
4976TYPE(vol7d),INTENT(inout) :: this !< oggetto in cui creare gli indici
4977
4978INTEGER :: i
4979
4980! real
4981IF (ASSOCIATED(this%dativar%r)) THEN
4982 IF (ASSOCIATED(this%dativarattr%r)) THEN
4983 DO i = 1, SIZE(this%dativar%r)
4984 this%dativar%r(i)%r = &
4985 firsttrue(this%dativar%r(i)%btable == this%dativarattr%r(:)%btable)
4986 ENDDO
4987 ENDIF
4988
4989 IF (ASSOCIATED(this%dativarattr%d)) THEN
4990 DO i = 1, SIZE(this%dativar%r)
4991 this%dativar%r(i)%d = &
4992 firsttrue(this%dativar%r(i)%btable == this%dativarattr%d(:)%btable)
4993 ENDDO
4994 ENDIF
4995
4996 IF (ASSOCIATED(this%dativarattr%i)) THEN
4997 DO i = 1, SIZE(this%dativar%r)
4998 this%dativar%r(i)%i = &
4999 firsttrue(this%dativar%r(i)%btable == this%dativarattr%i(:)%btable)
5000 ENDDO
5001 ENDIF
5002
5003 IF (ASSOCIATED(this%dativarattr%b)) THEN
5004 DO i = 1, SIZE(this%dativar%r)
5005 this%dativar%r(i)%b = &
5006 firsttrue(this%dativar%r(i)%btable == this%dativarattr%b(:)%btable)
5007 ENDDO
5008 ENDIF
5009
5010 IF (ASSOCIATED(this%dativarattr%c)) THEN
5011 DO i = 1, SIZE(this%dativar%r)
5012 this%dativar%r(i)%c = &
5013 firsttrue(this%dativar%r(i)%btable == this%dativarattr%c(:)%btable)
5014 ENDDO
5015 ENDIF
5016ENDIF
5017! double
5018IF (ASSOCIATED(this%dativar%d)) THEN
5019 IF (ASSOCIATED(this%dativarattr%r)) THEN
5020 DO i = 1, SIZE(this%dativar%d)
5021 this%dativar%d(i)%r = &
5022 firsttrue(this%dativar%d(i)%btable == this%dativarattr%r(:)%btable)
5023 ENDDO
5024 ENDIF
5025
5026 IF (ASSOCIATED(this%dativarattr%d)) THEN
5027 DO i = 1, SIZE(this%dativar%d)
5028 this%dativar%d(i)%d = &
5029 firsttrue(this%dativar%d(i)%btable == this%dativarattr%d(:)%btable)
5030 ENDDO
5031 ENDIF
5032
5033 IF (ASSOCIATED(this%dativarattr%i)) THEN
5034 DO i = 1, SIZE(this%dativar%d)
5035 this%dativar%d(i)%i = &
5036 firsttrue(this%dativar%d(i)%btable == this%dativarattr%i(:)%btable)
5037 ENDDO
5038 ENDIF
5039
5040 IF (ASSOCIATED(this%dativarattr%b)) THEN
5041 DO i = 1, SIZE(this%dativar%d)
5042 this%dativar%d(i)%b = &
5043 firsttrue(this%dativar%d(i)%btable == this%dativarattr%b(:)%btable)
5044 ENDDO
5045 ENDIF
5046
5047 IF (ASSOCIATED(this%dativarattr%c)) THEN
5048 DO i = 1, SIZE(this%dativar%d)
5049 this%dativar%d(i)%c = &
5050 firsttrue(this%dativar%d(i)%btable == this%dativarattr%c(:)%btable)
5051 ENDDO
5052 ENDIF
5053ENDIF
5054! integer
5055IF (ASSOCIATED(this%dativar%i)) THEN
5056 IF (ASSOCIATED(this%dativarattr%r)) THEN
5057 DO i = 1, SIZE(this%dativar%i)
5058 this%dativar%i(i)%r = &
5059 firsttrue(this%dativar%i(i)%btable == this%dativarattr%r(:)%btable)
5060 ENDDO
5061 ENDIF
5062
5063 IF (ASSOCIATED(this%dativarattr%d)) THEN
5064 DO i = 1, SIZE(this%dativar%i)
5065 this%dativar%i(i)%d = &
5066 firsttrue(this%dativar%i(i)%btable == this%dativarattr%d(:)%btable)
5067 ENDDO
5068 ENDIF
5069
5070 IF (ASSOCIATED(this%dativarattr%i)) THEN
5071 DO i = 1, SIZE(this%dativar%i)
5072 this%dativar%i(i)%i = &
5073 firsttrue(this%dativar%i(i)%btable == this%dativarattr%i(:)%btable)
5074 ENDDO
5075 ENDIF
5076
5077 IF (ASSOCIATED(this%dativarattr%b)) THEN
5078 DO i = 1, SIZE(this%dativar%i)
5079 this%dativar%i(i)%b = &
5080 firsttrue(this%dativar%i(i)%btable == this%dativarattr%b(:)%btable)
5081 ENDDO
5082 ENDIF
5083
5084 IF (ASSOCIATED(this%dativarattr%c)) THEN
5085 DO i = 1, SIZE(this%dativar%i)
5086 this%dativar%i(i)%c = &
5087 firsttrue(this%dativar%i(i)%btable == this%dativarattr%c(:)%btable)
5088 ENDDO
5089 ENDIF
5090ENDIF
5091! byte
5092IF (ASSOCIATED(this%dativar%b)) THEN
5093 IF (ASSOCIATED(this%dativarattr%r)) THEN
5094 DO i = 1, SIZE(this%dativar%b)
5095 this%dativar%b(i)%r = &
5096 firsttrue(this%dativar%b(i)%btable == this%dativarattr%r(:)%btable)
5097 ENDDO
5098 ENDIF
5099
5100 IF (ASSOCIATED(this%dativarattr%d)) THEN
5101 DO i = 1, SIZE(this%dativar%b)
5102 this%dativar%b(i)%d = &
5103 firsttrue(this%dativar%b(i)%btable == this%dativarattr%d(:)%btable)
5104 ENDDO
5105 ENDIF
5106
5107 IF (ASSOCIATED(this%dativarattr%i)) THEN
5108 DO i = 1, SIZE(this%dativar%b)
5109 this%dativar%b(i)%i = &
5110 firsttrue(this%dativar%b(i)%btable == this%dativarattr%i(:)%btable)
5111 ENDDO
5112 ENDIF
5113
5114 IF (ASSOCIATED(this%dativarattr%b)) THEN
5115 DO i = 1, SIZE(this%dativar%b)
5116 this%dativar%b(i)%b = &
5117 firsttrue(this%dativar%b(i)%btable == this%dativarattr%b(:)%btable)
5118 ENDDO
5119 ENDIF
5120
5121 IF (ASSOCIATED(this%dativarattr%c)) THEN
5122 DO i = 1, SIZE(this%dativar%b)
5123 this%dativar%b(i)%c = &
5124 firsttrue(this%dativar%b(i)%btable == this%dativarattr%c(:)%btable)
5125 ENDDO
5126 ENDIF
5127ENDIF
5128! character
5129IF (ASSOCIATED(this%dativar%c)) THEN
5130 IF (ASSOCIATED(this%dativarattr%r)) THEN
5131 DO i = 1, SIZE(this%dativar%c)
5132 this%dativar%c(i)%r = &
5133 firsttrue(this%dativar%c(i)%btable == this%dativarattr%r(:)%btable)
5134 ENDDO
5135 ENDIF
5136
5137 IF (ASSOCIATED(this%dativarattr%d)) THEN
5138 DO i = 1, SIZE(this%dativar%c)
5139 this%dativar%c(i)%d = &
5140 firsttrue(this%dativar%c(i)%btable == this%dativarattr%d(:)%btable)
5141 ENDDO
5142 ENDIF
5143
5144 IF (ASSOCIATED(this%dativarattr%i)) THEN
5145 DO i = 1, SIZE(this%dativar%c)
5146 this%dativar%c(i)%i = &
5147 firsttrue(this%dativar%c(i)%btable == this%dativarattr%i(:)%btable)
5148 ENDDO
5149 ENDIF
5150
5151 IF (ASSOCIATED(this%dativarattr%b)) THEN
5152 DO i = 1, SIZE(this%dativar%c)
5153 this%dativar%c(i)%b = &
5154 firsttrue(this%dativar%c(i)%btable == this%dativarattr%b(:)%btable)
5155 ENDDO
5156 ENDIF
5157
5158 IF (ASSOCIATED(this%dativarattr%c)) THEN
5159 DO i = 1, SIZE(this%dativar%c)
5160 this%dativar%c(i)%c = &
5161 firsttrue(this%dativar%c(i)%btable == this%dativarattr%c(:)%btable)
5162 ENDDO
5163 ENDIF
5164ENDIF
5165
5166END SUBROUTINE vol7d_set_attr_ind
5167
5168
5169!> Metodo per fondere 2 oggetti vol7d.
5170!! Il secondo volume viene accodato al primo e poi distrutto, si veda
5171!! quindi la descrizione di ::vol7d_append. Se uno degli oggetti \a
5172!! this o \a that sono vuoti non perde tempo inutile,
5173SUBROUTINE vol7d_merge(this, that, sort, bestdata, &
5174 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
5175TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, alla fine conterrà il risultato della fusione
5176TYPE(vol7d),INTENT(INOUT) :: that !< secondo oggetto in ingresso, alla fine sarà distrutto
5177LOGICAL,INTENT(IN),OPTIONAL :: sort !< se fornito e uguale a \c .TRUE., i descrittori che supportano un ordinamento (operatori > e/o <) risulteranno ordinati in ordine crescente nell'oggetto finale
5178LOGICAL,INTENT(in),OPTIONAL :: bestdata !< if provided and \a .TRUE. in case of overlapping volumes keep valid data where available, or data from the second volume if both valid
5179LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple ! experimental, please do not use outside the library now
5180
5181TYPE(vol7d) :: v7d_clean
5182
5183
5185 this = that
5187 that = v7d_clean ! destroy that without deallocating
5188ELSE ! Append that to this and destroy that
5190 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
5192ENDIF
5193
5194END SUBROUTINE vol7d_merge
5195
5196
5197!> Metodo per accodare un oggetto vol7d ad un altro.
5198!! Si tratta di un metodo molto potente e versatile;
5199!! i descrittori delle dimensioni del volume finale conterranno i valori
5200!! dei corrispondenti descrittori del primo e del secondo volume
5201!! e i volumi di anagrafica e dati conterranno i valori dei due volumi
5202!! ai posti giusti, e valori mancanti per le nuove combinazioni che
5203!! eventualmente si verranno a creare.
5204!! Se i volumi multidimensionali di anagrafica e/o dati dei 2 oggetti
5205!! hanno un'intersezione non nulla, negli elementi comuni il volume finale
5206!! conterrà il corrispondente elemento del \b secondo volume.
5207!! Attenzione che, durante l'esecuzione del metodo, la memoria richiesta è
5208!! pari alla memoria complessiva occupata dai 2 volumi iniziali più
5209!! la memoria complessiva del volume finale, per cui, nel caso di volumi grandi,
5210!! ci potrebbero essere problemi di esaurimento della memoria centrale.
5211!! Se l'oggetto \a that è vuoto non perde tempo inutile,
5212!!
5213!! \todo nel caso di elementi comuni inserire la possibiità (opzionale per
5214!! non penalizzare le prestazioni quando ciò non serve) di effettuare una scelta
5215!! più ragionata dell'elemento da tenere, almeno controllando i dati mancanti
5216!! se non le flag di qualità
5217!!
5218!! \todo "rateizzare" l'allocazione dei volumi per ridurre l'occupazione di
5219!! memoria nel caso siano allocati contemporaneamente volumi di variabili e
5220!! di attributi o più volumi di tipi diversi
5221!!
5222!! \todo il parametro \a that è dichiarato \a INOUT perché la vol7d_alloc_vol
5223!! può modificarlo, bisognerebbe implementare una vol7d_check_vol che restituisca
5224!! errore anziché usare la vol7d_alloc_vol.
5225SUBROUTINE vol7d_append(this, that, sort, bestdata, &
5226 ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple)
5227TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, a cui sarà accodato il secondo
5228TYPE(vol7d),INTENT(IN) :: that !< secondo oggetto in ingresso, non viene modificato dal metodo
5229LOGICAL,INTENT(IN),OPTIONAL :: sort !< se fornito e uguale a \c .TRUE., i descrittori che supportano un ordinamento (operatori > e/o <) risulteranno ordinati in ordine crescente nell'oggetto finale
5230! experimental, please do not use outside the library now, they force the use
5231! of a simplified mapping algorithm which is valid only whene the dimension
5232! content is the same in both volumes , or when one of them is empty
5233LOGICAL,INTENT(in),OPTIONAL :: bestdata !< if provided and \a .TRUE. in case of overlapping volumes keep valid data where available, or data from the second volume if both valid
5234LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple
5235
5236
5237TYPE(vol7d) :: v7dtmp
5238LOGICAL :: lsort, lbestdata
5239INTEGER,POINTER :: remapt1(:), remapt2(:), remaptr1(:), remaptr2(:), &
5240 remapl1(:), remapl2(:), remapa1(:), remapa2(:), remapn1(:), remapn2(:)
5241
5243IF (.NOT.vol7d_check_vol(that)) RETURN ! be safe
5246 RETURN
5247ENDIF
5248
5249IF (this%time_definition /= that%time_definition) THEN
5250 CALL l4f_log(l4f_fatal, &
5251 'in vol7d_append, cannot append volumes with different &
5252 &time definition')
5253 CALL raise_fatal_error()
5254ENDIF
5255
5256! Completo l'allocazione per avere volumi a norma
5257CALL vol7d_alloc_vol(this)
5258
5262
5263! Calcolo le mappature tra volumi vecchi e volume nuovo
5264! I puntatori remap* vengono tutti o allocati o nullificati
5265IF (optio_log(ltimesimple)) THEN
5266 CALL vol7d_remap2simple_datetime(this%time, that%time, v7dtmp%time, &
5267 lsort, remapt1, remapt2)
5268ELSE
5269 CALL vol7d_remap2_datetime(this%time, that%time, v7dtmp%time, &
5270 lsort, remapt1, remapt2)
5271ENDIF
5272IF (optio_log(ltimerangesimple)) THEN
5273 CALL vol7d_remap2simple_vol7d_timerange(this%timerange, that%timerange, &
5274 v7dtmp%timerange, lsort, remaptr1, remaptr2)
5275ELSE
5276 CALL vol7d_remap2_vol7d_timerange(this%timerange, that%timerange, &
5277 v7dtmp%timerange, lsort, remaptr1, remaptr2)
5278ENDIF
5279IF (optio_log(llevelsimple)) THEN
5280 CALL vol7d_remap2simple_vol7d_level(this%level, that%level, v7dtmp%level, &
5281 lsort, remapl1, remapl2)
5282ELSE
5283 CALL vol7d_remap2_vol7d_level(this%level, that%level, v7dtmp%level, &
5284 lsort, remapl1, remapl2)
5285ENDIF
5286IF (optio_log(lanasimple)) THEN
5287 CALL vol7d_remap2simple_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
5288 .false., remapa1, remapa2)
5289ELSE
5290 CALL vol7d_remap2_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
5291 .false., remapa1, remapa2)
5292ENDIF
5293IF (optio_log(lnetworksimple)) THEN
5294 CALL vol7d_remap2simple_vol7d_network(this%network, that%network, v7dtmp%network, &
5295 .false., remapn1, remapn2)
5296ELSE
5297 CALL vol7d_remap2_vol7d_network(this%network, that%network, v7dtmp%network, &
5298 .false., remapn1, remapn2)
5299ENDIF
5300
5301! Faccio la fusione fisica dei volumi
5302CALL vol7d_merge_finalr(this, that, v7dtmp, &
5303 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
5304 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
5305CALL vol7d_merge_finald(this, that, v7dtmp, &
5306 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
5307 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
5308CALL vol7d_merge_finali(this, that, v7dtmp, &
5309 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
5310 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
5311CALL vol7d_merge_finalb(this, that, v7dtmp, &
5312 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
5313 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
5314CALL vol7d_merge_finalc(this, that, v7dtmp, &
5315 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
5316 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
5317
5318! Dealloco i vettori di rimappatura
5319IF (ASSOCIATED(remapt1)) DEALLOCATE(remapt1)
5320IF (ASSOCIATED(remapt2)) DEALLOCATE(remapt2)
5321IF (ASSOCIATED(remaptr1)) DEALLOCATE(remaptr1)
5322IF (ASSOCIATED(remaptr2)) DEALLOCATE(remaptr2)
5323IF (ASSOCIATED(remapl1)) DEALLOCATE(remapl1)
5324IF (ASSOCIATED(remapl2)) DEALLOCATE(remapl2)
5325IF (ASSOCIATED(remapa1)) DEALLOCATE(remapa1)
5326IF (ASSOCIATED(remapa2)) DEALLOCATE(remapa2)
5327IF (ASSOCIATED(remapn1)) DEALLOCATE(remapn1)
5328IF (ASSOCIATED(remapn2)) DEALLOCATE(remapn2)
5329
5330! Distruggo il vecchio volume e assegno il nuovo a this
5332this = v7dtmp
5333! Ricreo gli indici var-attr
5334CALL vol7d_set_attr_ind(this)
5335
5336END SUBROUTINE vol7d_append
5337
5338
5339!> Metodo per creare una copia completa e indipendente di un oggetto vol7d.
5340!! Questo metodo crea un duplicato di tutti i membri di un oggetto vol7d,
5341!! con la possibilità di rielaborarlo durante la copia. Se l'oggetto da copiare
5342!! è vuoto non perde tempo inutile.
5343!! Attenzione, il codice:
5344!! \code
5345!! USE vol7d_class
5346!! TYPE(vol7d) :: vol1, vol2
5347!! CALL init(vol1)
5348!! CALL init(vol2)
5349!! ... ! riempio vol1
5350!! vol2 = vol1
5351!! \endcode
5352!! fa una cosa diversa rispetto a:
5353!! \code
5354!! USE vol7d_class
5355!! TYPE(vol7d) :: vol1, vol2
5356!! CALL init(vol1)
5357!! CALL init(vol2)
5358!! ... ! riempio vol1
5359!! CALL vol7d_copy(vol1, vol2)
5360!! \endcode
5361!! nel primo caso, infatti, l'operatore di assegnazione copia solo i componenti
5362!! statici di \a vol1 nei corrispondenti elementi di \a vol2, mentre i componenti che
5363!! sono allocati dinamicamente (cioè quelli che in ::vol7d hanno l'attributo
5364!! \c POINTER, in pratica quasi tutti) non vengono duplicati, ma per essi vol2
5365!! conterrà un puntatore al corrispondente elemento a cui già punta vol1, e quindi
5366!! eventuali cambiamenti al contenuto di uno dei due oggetti influenzerà il
5367!! contenuto dell'altro; nel secondo caso, invece, vol1 e vol2 sono, dopo la
5368!! vol7d_copy, 2 istanze
5369!! completamente indipendenti, ma uguali tra loro per contenuto, della classe
5370!! vol7d, e quindi hanno vita indipendente.
5371SUBROUTINE vol7d_copy(this, that, sort, unique, miss, &
5372 lsort_time, lsort_timerange, lsort_level, &
5373 ltime, ltimerange, llevel, lana, lnetwork, &
5374 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
5375 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
5376 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
5377 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
5378 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
5379 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
5380TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
5381TYPE(vol7d),INTENT(INOUT) :: that !< oggetto destinazione
5382LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
5383LOGICAL,INTENT(IN),OPTIONAL :: unique !< se fornito e uguale a \c .TRUE., gli eventuali elementi duplicati nei descrittori dell'oggetto iniziale verranno collassati in un unico elemento (con eventuale perdita dei dati relativi agli elementi duplicati)
5384LOGICAL,INTENT(IN),OPTIONAL :: miss !< se fornito e uguale a \c .TRUE., gli eventuali elementi dei descrittori uguali al corrispondente valore mancante verranno eliminati dall'oggetto riformato
5385LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
5386LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
5387LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
5388!> se fornito, deve essere un vettore logico della stessa lunghezza di
5389!! this%time indicante quali elementi della dimensione \a time
5390!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
5391!! nel volume copiato; in alternativa può essere un vettore di
5392!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
5393!! gli elementi (utile principalmente per le variabili); è compatibile
5394!! col parametro \a miss
5395LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
5396!> come il precedente per la dimensione \a timerange
5397LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:)
5398!> come il precedente per la dimensione \a level
5399LOGICAL,INTENT(IN),OPTIONAL :: llevel(:)
5400!> come il precedente per la dimensione \a ana
5401LOGICAL,INTENT(IN),OPTIONAL :: lana(:)
5402!> come il precedente per la dimensione \a network
5403LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:)
5404!> come il precedente per tutte le possibili dimensioni variabile
5405LOGICAL,INTENT(in),OPTIONAL :: &
5406 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
5407 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
5408 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
5409 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
5410 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
5411 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
5412
5413LOGICAL :: lsort, lunique, lmiss
5414INTEGER,POINTER :: remapt(:), remaptr(:), remapl(:), remapa(:), remapn(:)
5415
5418IF (.NOT.vol7d_check_vol(this)) RETURN ! be safe
5419
5423
5424! Calcolo le mappature tra volume vecchio e volume nuovo
5425! I puntatori remap* vengono tutti o allocati o nullificati
5426CALL vol7d_remap1_datetime(this%time, that%time, &
5427 lsort.OR.optio_log(lsort_time), lunique, lmiss, remapt, ltime)
5428CALL vol7d_remap1_vol7d_timerange(this%timerange, that%timerange, &
5429 lsort.OR.optio_log(lsort_timerange), lunique, lmiss, remaptr, ltimerange)
5430CALL vol7d_remap1_vol7d_level(this%level, that%level, &
5431 lsort.OR.optio_log(lsort_level), lunique, lmiss, remapl, llevel)
5432CALL vol7d_remap1_vol7d_ana(this%ana, that%ana, &
5433 lsort, lunique, lmiss, remapa, lana)
5434CALL vol7d_remap1_vol7d_network(this%network, that%network, &
5435 lsort, lunique, lmiss, remapn, lnetwork)
5436
5437! lanavari, lanavarb, lanavarc, &
5438! lanaattri, lanaattrb, lanaattrc, &
5439! lanavarattri, lanavarattrb, lanavarattrc, &
5440! ldativari, ldativarb, ldativarc, &
5441! ldatiattri, ldatiattrb, ldatiattrc, &
5442! ldativarattri, ldativarattrb, ldativarattrc
5443! Faccio la riforma fisica dei volumi
5444CALL vol7d_reform_finalr(this, that, &
5445 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
5446 lanavarr, lanaattrr, lanavarattrr, ldativarr, ldatiattrr, ldativarattrr)
5447CALL vol7d_reform_finald(this, that, &
5448 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
5449 lanavard, lanaattrd, lanavarattrd, ldativard, ldatiattrd, ldativarattrd)
5450CALL vol7d_reform_finali(this, that, &
5451 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
5452 lanavari, lanaattri, lanavarattri, ldativari, ldatiattri, ldativarattri)
5453CALL vol7d_reform_finalb(this, that, &
5454 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
5455 lanavarb, lanaattrb, lanavarattrb, ldativarb, ldatiattrb, ldativarattrb)
5456CALL vol7d_reform_finalc(this, that, &
5457 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
5458 lanavarc, lanaattrc, lanavarattrc, ldativarc, ldatiattrc, ldativarattrc)
5459
5460! Dealloco i vettori di rimappatura
5461IF (ASSOCIATED(remapt)) DEALLOCATE(remapt)
5462IF (ASSOCIATED(remaptr)) DEALLOCATE(remaptr)
5463IF (ASSOCIATED(remapl)) DEALLOCATE(remapl)
5464IF (ASSOCIATED(remapa)) DEALLOCATE(remapa)
5465IF (ASSOCIATED(remapn)) DEALLOCATE(remapn)
5466
5467! Ricreo gli indici var-attr
5468CALL vol7d_set_attr_ind(that)
5469that%time_definition = this%time_definition
5470
5471END SUBROUTINE vol7d_copy
5472
5473
5474!> Metodo per riformare in varie maniere un oggetto vol7d.
5475!! Equivale ad una copia (vedi ::vol7d_copy)
5476!! seguita dalla distruzione del volume iniziale e alla
5477!! sua riassegnazione al volume copiato. Ha senso se almeno uno dei parametri
5478!! \a sort, \a uniq o \a miss è fornito uguale a \c .TRUE., altrimenti
5479!! è solo una perdita di tempo.
5480!! Può essere utile, ad esempio, per eliminare stazioni
5481!! o istanti temporali indesiderati, basta assegnare il loro corrispondente
5482!! elemento del descrittore a valore mancante e chiamare vol7d_reform
5483!! con miss=.TRUE. .
5484SUBROUTINE vol7d_reform(this, sort, unique, miss, &
5485 lsort_time, lsort_timerange, lsort_level, &
5486 ltime, ltimerange, llevel, lana, lnetwork, &
5487 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
5488 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
5489 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
5490 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
5491 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
5492 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc&
5493 ,purgeana)
5494TYPE(vol7d),INTENT(INOUT) :: this !< oggetto da riformare
5495LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
5496LOGICAL,INTENT(IN),OPTIONAL :: unique !< se fornito e uguale a \c .TRUE., gli eventuali elementi duplicati nei descrittori dell'oggetto iniziale verranno collassati in un unico elemento (con eventuale perdita dei dati relativi agli elementi duplicati)
5497LOGICAL,INTENT(IN),OPTIONAL :: miss !< se fornito e uguale a \c .TRUE., gli eventuali elementi dei descrittori uguali al corrispondente valore mancante verranno eliminati dall'oggetto riformato
5498LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
5499LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
5500LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
5501!> se fornito, deve essere un vettore logico della stessa lunghezza di
5502!! this%time indicante quali elementi della dimensione \a time
5503!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
5504!! nel volume copiato; in alternativa può essere un vettore di
5505!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
5506!! gli elementi (utile principalmente per le variabili); è compatibile
5507!! col parametro \a miss
5508LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
5509LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:) !< come il precedente per la dimensione \a timerange
5510LOGICAL,INTENT(IN),OPTIONAL :: llevel(:) !< come il precedente per la dimensione \a level
5511LOGICAL,INTENT(IN),OPTIONAL :: lana(:) !< come il precedente per la dimensione \a ana
5512LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:) !< come il precedente per la dimensione \a network
5513!> come il precedente per tutte le possibili dimensioni variabile
5514LOGICAL,INTENT(in),OPTIONAL :: &
5515 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
5516 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
5517 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
5518 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
5519 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
5520 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
5521LOGICAL,INTENT(IN),OPTIONAL :: purgeana !< if true remove ana with all data missing
5522
5523TYPE(vol7d) :: v7dtmp
5524logical,allocatable :: llana(:)
5525integer :: i
5526
5528 lsort_time, lsort_timerange, lsort_level, &
5529 ltime, ltimerange, llevel, lana, lnetwork, &
5530 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
5531 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
5532 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
5533 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
5534 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
5535 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
5536
5537! destroy old volume
5539
5540if (optio_log(purgeana)) then
5541 allocate(llana(size(v7dtmp%ana)))
5542 llana =.false.
5543 do i =1,size(v7dtmp%ana)
5544 if (associated(v7dtmp%voldatii)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatii(i,:,:,:,:,:)))
5545 if (associated(v7dtmp%voldatir)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatir(i,:,:,:,:,:)))
5546 if (associated(v7dtmp%voldatid)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatid(i,:,:,:,:,:)))
5547 if (associated(v7dtmp%voldatib)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatib(i,:,:,:,:,:)))
5548 if (associated(v7dtmp%voldatic)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatic(i,:,:,:,:,:)))
5549 end do
5550 CALL vol7d_copy(v7dtmp, this,lana=llana)
5552 deallocate(llana)
5553else
5554 this=v7dtmp
5555end if
5556
5557END SUBROUTINE vol7d_reform
5558
5559
5560!> Sorts the sortable dimensions in the volume \a this only when necessary.
5561!! Most of the times, the time, timerange and level dimensions in a
5562!! vol7d object are correctly sorted; on the other side many methods
5563!! strictly rely on this fact in order to work correctly. This method
5564!! performs a quick check and sorts the required dimensions only if
5565!! they are not sorted in ascending order yet, improving safety
5566!! without impairing much performance.
5567SUBROUTINE vol7d_smart_sort(this, lsort_time, lsort_timerange, lsort_level)
5568TYPE(vol7d),INTENT(INOUT) :: this !< object to be sorted
5569LOGICAL,OPTIONAL,INTENT(in) :: lsort_time !< if present and \a .TRUE., sort time dimension if it is not sorted in ascending order
5570LOGICAL,OPTIONAL,INTENT(in) :: lsort_timerange !< if present and \a .TRUE., sort timerange dimension if it is not sorted in ascending order
5571LOGICAL,OPTIONAL,INTENT(in) :: lsort_level !< if present and \a .TRUE., sort vertical level dimension if it is not sorted in ascending order
5572
5573INTEGER :: i
5574LOGICAL :: to_be_sorted
5575
5576to_be_sorted = .false.
5577CALL vol7d_alloc_vol(this) ! usual safety check
5578
5579IF (optio_log(lsort_time)) THEN
5580 DO i = 2, SIZE(this%time)
5581 IF (this%time(i) < this%time(i-1)) THEN
5582 to_be_sorted = .true.
5583 EXIT
5584 ENDIF
5585 ENDDO
5586ENDIF
5587IF (optio_log(lsort_timerange)) THEN
5588 DO i = 2, SIZE(this%timerange)
5589 IF (this%timerange(i) < this%timerange(i-1)) THEN
5590 to_be_sorted = .true.
5591 EXIT
5592 ENDIF
5593 ENDDO
5594ENDIF
5595IF (optio_log(lsort_level)) THEN
5596 DO i = 2, SIZE(this%level)
5597 IF (this%level(i) < this%level(i-1)) THEN
5598 to_be_sorted = .true.
5599 EXIT
5600 ENDIF
5601 ENDDO
5602ENDIF
5603
5604IF (to_be_sorted) CALL vol7d_reform(this, &
5605 lsort_time=lsort_time, lsort_timerange=lsort_timerange, lsort_level=lsort_level )
5606
5607END SUBROUTINE vol7d_smart_sort
5608
5609!> Filter the contents of a volume keeping only desired data.
5610!! This subroutine filters a vol7d object by keeping only a subset of
5611!! the data contained. It can keep only times within a specified
5612!! interval, only station networks contained in a list and only
5613!! specified station or data variables. If a filter parameter is not
5614!! provided, no filtering will take place according to that criterion.
5615!! The volume is reallocated keeping only the desired data.
5616SUBROUTINE vol7d_filter(this, avl, vl, nl, s_d, e_d)
5617TYPE(vol7d),INTENT(inout) :: this !< volume to be filtered
5618CHARACTER(len=*),INTENT(in),OPTIONAL :: avl(:) !< list of station variables to be kept, if not provided or of zero length, all variables are kept
5619CHARACTER(len=*),INTENT(in),OPTIONAL :: vl(:) !< list of data variables to be kept, if not provided or of zero length, all variables are kept
5620TYPE(vol7d_network),OPTIONAL :: nl(:) !< list of station networks to be kept, if not provided or of zero length, all networks are kept
5621TYPE(datetime),INTENT(in),OPTIONAL :: s_d !< initial time interval for time filtering, if not provided or equal to missing data no lower limit is imposed
5622TYPE(datetime),INTENT(in),OPTIONAL :: e_d !< final time interval for time filtering, if not provided or equal to missing data no upper limit is imposed
5623
5624INTEGER :: i
5625
5626IF (PRESENT(avl)) THEN
5627 IF (SIZE(avl) > 0) THEN
5628
5629 IF (ASSOCIATED(this%anavar%r)) THEN
5630 DO i = 1, SIZE(this%anavar%r)
5631 IF (all(this%anavar%r(i)%btable /= avl)) this%anavar%r(i) = vol7d_var_miss
5632 ENDDO
5633 ENDIF
5634
5635 IF (ASSOCIATED(this%anavar%i)) THEN
5636 DO i = 1, SIZE(this%anavar%i)
5637 IF (all(this%anavar%i(i)%btable /= avl)) this%anavar%i(i) = vol7d_var_miss
5638 ENDDO
5639 ENDIF
5640
5641 IF (ASSOCIATED(this%anavar%b)) THEN
5642 DO i = 1, SIZE(this%anavar%b)
5643 IF (all(this%anavar%b(i)%btable /= avl)) this%anavar%b(i) = vol7d_var_miss
5644 ENDDO
5645 ENDIF
5646
5647 IF (ASSOCIATED(this%anavar%d)) THEN
5648 DO i = 1, SIZE(this%anavar%d)
5649 IF (all(this%anavar%d(i)%btable /= avl)) this%anavar%d(i) = vol7d_var_miss
5650 ENDDO
5651 ENDIF
5652
5653 IF (ASSOCIATED(this%anavar%c)) THEN
5654 DO i = 1, SIZE(this%anavar%c)
5655 IF (all(this%anavar%c(i)%btable /= avl)) this%anavar%c(i) = vol7d_var_miss
5656 ENDDO
5657 ENDIF
5658
5659 ENDIF
5660ENDIF
5661
5662
5663IF (PRESENT(vl)) THEN
5664 IF (size(vl) > 0) THEN
5665 IF (ASSOCIATED(this%dativar%r)) THEN
5666 DO i = 1, SIZE(this%dativar%r)
5667 IF (all(this%dativar%r(i)%btable /= vl)) this%dativar%r(i) = vol7d_var_miss
5668 ENDDO
5669 ENDIF
5670
5671 IF (ASSOCIATED(this%dativar%i)) THEN
5672 DO i = 1, SIZE(this%dativar%i)
5673 IF (all(this%dativar%i(i)%btable /= vl)) this%dativar%i(i) = vol7d_var_miss
5674 ENDDO
5675 ENDIF
5676
5677 IF (ASSOCIATED(this%dativar%b)) THEN
5678 DO i = 1, SIZE(this%dativar%b)
5679 IF (all(this%dativar%b(i)%btable /= vl)) this%dativar%b(i) = vol7d_var_miss
5680 ENDDO
5681 ENDIF
5682
5683 IF (ASSOCIATED(this%dativar%d)) THEN
5684 DO i = 1, SIZE(this%dativar%d)
5685 IF (all(this%dativar%d(i)%btable /= vl)) this%dativar%d(i) = vol7d_var_miss
5686 ENDDO
5687 ENDIF
5688
5689 IF (ASSOCIATED(this%dativar%c)) THEN
5690 DO i = 1, SIZE(this%dativar%c)
5691 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
5692 ENDDO
5693 ENDIF
5694
5695 IF (ASSOCIATED(this%dativar%c)) THEN
5696 DO i = 1, SIZE(this%dativar%c)
5697 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
5698 ENDDO
5699 ENDIF
5700
5701 ENDIF
5702ENDIF
5703
5704IF (PRESENT(nl)) THEN
5705 IF (SIZE(nl) > 0) THEN
5706 DO i = 1, SIZE(this%network)
5707 IF (all(this%network(i) /= nl)) this%network(i) = vol7d_network_miss
5708 ENDDO
5709 ENDIF
5710ENDIF
5711
5712IF (PRESENT(s_d)) THEN
5714 WHERE (this%time < s_d)
5715 this%time = datetime_miss
5716 END WHERE
5717 ENDIF
5718ENDIF
5719
5720IF (PRESENT(e_d)) THEN
5722 WHERE (this%time > e_d)
5723 this%time = datetime_miss
5724 END WHERE
5725 ENDIF
5726ENDIF
5727
5728CALL vol7d_reform(this, miss=.true.)
5729
5730END SUBROUTINE vol7d_filter
5731
5732
5733!> Metodo per convertire i volumi di dati di un oggetto vol7d in dati
5734!! reali dove possibile. L'oggetto convertito è una copia completa
5735!! dell'originale che può essere quindi distrutto dopo la chiamata.
5736!! Per i dati di anagrafica, al momento sono convertiti solo
5737!! i dati CHARACTER se è passato \a anaconv=.TRUE.
5738!! Gli attributi non sono toccati.
5739SUBROUTINE vol7d_convr(this, that, anaconv)
5740TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
5741TYPE(vol7d),INTENT(INOUT) :: that !< oggetto convertito
5742LOGICAL,OPTIONAL,INTENT(in) :: anaconv !< converti anche anagrafica
5743INTEGER :: i
5744LOGICAL :: fv(1)=(/.false./), tv(1)=(/.true./), acp(1), acn(1)
5745TYPE(vol7d) :: v7d_tmp
5746
5747IF (optio_log(anaconv)) THEN
5748 acp=fv
5749 acn=tv
5750ELSE
5751 acp=tv
5752 acn=fv
5753ENDIF
5754
5755! Volume con solo i dati reali e tutti gli attributi
5756! l'anagrafica e` copiata interamente se necessario
5757CALL vol7d_copy(this, that, &
5758 lanavarr=tv, lanavard=acp, lanavari=acp, lanavarb=acp, lanavarc=acp, &
5759 ldativarr=tv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=fv)
5760
5761! Volume solo di dati double
5762CALL vol7d_copy(this, v7d_tmp, &
5763 lanavarr=fv, lanavard=acn, lanavari=fv, lanavarb=fv, lanavarc=fv, &
5764 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
5765 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
5766 ldativarr=fv, ldativard=tv, ldativari=fv, ldativarb=fv, ldativarc=fv, &
5767 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
5768 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
5769
5770! converto a dati reali
5771IF (ASSOCIATED(v7d_tmp%anavar%d) .OR. ASSOCIATED(v7d_tmp%dativar%d)) THEN
5772
5773 IF (ASSOCIATED(v7d_tmp%anavar%d)) THEN
5774! alloco i dati reali e vi trasferisco i double
5775 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanad, 1), SIZE(v7d_tmp%volanad, 2), &
5776 SIZE(v7d_tmp%volanad, 3)))
5777 DO i = 1, SIZE(v7d_tmp%anavar%d)
5778 v7d_tmp%volanar(:,i,:) = &
5779 realdat(v7d_tmp%volanad(:,i,:), v7d_tmp%anavar%d(i))
5780 ENDDO
5781 DEALLOCATE(v7d_tmp%volanad)
5782! trasferisco le variabili
5783 v7d_tmp%anavar%r => v7d_tmp%anavar%d
5784 NULLIFY(v7d_tmp%anavar%d)
5785 ENDIF
5786
5787 IF (ASSOCIATED(v7d_tmp%dativar%d)) THEN
5788! alloco i dati reali e vi trasferisco i double
5789 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatid, 1), SIZE(v7d_tmp%voldatid, 2), &
5790 SIZE(v7d_tmp%voldatid, 3), SIZE(v7d_tmp%voldatid, 4), SIZE(v7d_tmp%voldatid, 5), &
5791 SIZE(v7d_tmp%voldatid, 6)))
5792 DO i = 1, SIZE(v7d_tmp%dativar%d)
5793 v7d_tmp%voldatir(:,:,:,:,i,:) = &
5794 realdat(v7d_tmp%voldatid(:,:,:,:,i,:), v7d_tmp%dativar%d(i))
5795 ENDDO
5796 DEALLOCATE(v7d_tmp%voldatid)
5797! trasferisco le variabili
5798 v7d_tmp%dativar%r => v7d_tmp%dativar%d
5799 NULLIFY(v7d_tmp%dativar%d)
5800 ENDIF
5801
5802! fondo con il volume definitivo
5803 CALL vol7d_merge(that, v7d_tmp)
5804ELSE
5806ENDIF
5807
5808
5809! Volume solo di dati interi
5810CALL vol7d_copy(this, v7d_tmp, &
5811 lanavarr=fv, lanavard=fv, lanavari=acn, lanavarb=fv, lanavarc=fv, &
5812 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
5813 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
5814 ldativarr=fv, ldativard=fv, ldativari=tv, ldativarb=fv, ldativarc=fv, &
5815 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
5816 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
5817
5818! converto a dati reali
5819IF (ASSOCIATED(v7d_tmp%anavar%i) .OR. ASSOCIATED(v7d_tmp%dativar%i)) THEN
5820
5821 IF (ASSOCIATED(v7d_tmp%anavar%i)) THEN
5822! alloco i dati reali e vi trasferisco gli interi
5823 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanai, 1), SIZE(v7d_tmp%volanai, 2), &
5824 SIZE(v7d_tmp%volanai, 3)))
5825 DO i = 1, SIZE(v7d_tmp%anavar%i)
5826 v7d_tmp%volanar(:,i,:) = &
5827 realdat(v7d_tmp%volanai(:,i,:), v7d_tmp%anavar%i(i))
5828 ENDDO
5829 DEALLOCATE(v7d_tmp%volanai)
5830! trasferisco le variabili
5831 v7d_tmp%anavar%r => v7d_tmp%anavar%i
5832 NULLIFY(v7d_tmp%anavar%i)
5833 ENDIF
5834
5835 IF (ASSOCIATED(v7d_tmp%dativar%i)) THEN
5836! alloco i dati reali e vi trasferisco gli interi
5837 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatii, 1), SIZE(v7d_tmp%voldatii, 2), &
5838 SIZE(v7d_tmp%voldatii, 3), SIZE(v7d_tmp%voldatii, 4), SIZE(v7d_tmp%voldatii, 5), &
5839 SIZE(v7d_tmp%voldatii, 6)))
5840 DO i = 1, SIZE(v7d_tmp%dativar%i)
5841 v7d_tmp%voldatir(:,:,:,:,i,:) = &
5842 realdat(v7d_tmp%voldatii(:,:,:,:,i,:), v7d_tmp%dativar%i(i))
5843 ENDDO
5844 DEALLOCATE(v7d_tmp%voldatii)
5845! trasferisco le variabili
5846 v7d_tmp%dativar%r => v7d_tmp%dativar%i
5847 NULLIFY(v7d_tmp%dativar%i)
5848 ENDIF
5849
5850! fondo con il volume definitivo
5851 CALL vol7d_merge(that, v7d_tmp)
5852ELSE
5854ENDIF
5855
5856
5857! Volume solo di dati byte
5858CALL vol7d_copy(this, v7d_tmp, &
5859 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=acn, lanavarc=fv, &
5860 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
5861 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
5862 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=tv, ldativarc=fv, &
5863 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
5864 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
5865
5866! converto a dati reali
5867IF (ASSOCIATED(v7d_tmp%anavar%b) .OR. ASSOCIATED(v7d_tmp%dativar%b)) THEN
5868
5869 IF (ASSOCIATED(v7d_tmp%anavar%b)) THEN
5870! alloco i dati reali e vi trasferisco i byte
5871 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanab, 1), SIZE(v7d_tmp%volanab, 2), &
5872 SIZE(v7d_tmp%volanab, 3)))
5873 DO i = 1, SIZE(v7d_tmp%anavar%b)
5874 v7d_tmp%volanar(:,i,:) = &
5875 realdat(v7d_tmp%volanab(:,i,:), v7d_tmp%anavar%b(i))
5876 ENDDO
5877 DEALLOCATE(v7d_tmp%volanab)
5878! trasferisco le variabili
5879 v7d_tmp%anavar%r => v7d_tmp%anavar%b
5880 NULLIFY(v7d_tmp%anavar%b)
5881 ENDIF
5882
5883 IF (ASSOCIATED(v7d_tmp%dativar%b)) THEN
5884! alloco i dati reali e vi trasferisco i byte
5885 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatib, 1), SIZE(v7d_tmp%voldatib, 2), &
5886 SIZE(v7d_tmp%voldatib, 3), SIZE(v7d_tmp%voldatib, 4), SIZE(v7d_tmp%voldatib, 5), &
5887 SIZE(v7d_tmp%voldatib, 6)))
5888 DO i = 1, SIZE(v7d_tmp%dativar%b)
5889 v7d_tmp%voldatir(:,:,:,:,i,:) = &
5890 realdat(v7d_tmp%voldatib(:,:,:,:,i,:), v7d_tmp%dativar%b(i))
5891 ENDDO
5892 DEALLOCATE(v7d_tmp%voldatib)
5893! trasferisco le variabili
5894 v7d_tmp%dativar%r => v7d_tmp%dativar%b
5895 NULLIFY(v7d_tmp%dativar%b)
5896 ENDIF
5897
5898! fondo con il volume definitivo
5899 CALL vol7d_merge(that, v7d_tmp)
5900ELSE
5902ENDIF
5903
5904
5905! Volume solo di dati character
5906CALL vol7d_copy(this, v7d_tmp, &
5907 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=fv, lanavarc=acn, &
5908 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
5909 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
5910 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=tv, &
5911 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
5912 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
5913
5914! converto a dati reali
5915IF (ASSOCIATED(v7d_tmp%anavar%c) .OR. ASSOCIATED(v7d_tmp%dativar%c)) THEN
5916
5917 IF (ASSOCIATED(v7d_tmp%anavar%c)) THEN
5918! alloco i dati reali e vi trasferisco i character
5919 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanac, 1), SIZE(v7d_tmp%volanac, 2), &
5920 SIZE(v7d_tmp%volanac, 3)))
5921 DO i = 1, SIZE(v7d_tmp%anavar%c)
5922 v7d_tmp%volanar(:,i,:) = &
5923 realdat(v7d_tmp%volanac(:,i,:), v7d_tmp%anavar%c(i))
5924 ENDDO
5925 DEALLOCATE(v7d_tmp%volanac)
5926! trasferisco le variabili
5927 v7d_tmp%anavar%r => v7d_tmp%anavar%c
5928 NULLIFY(v7d_tmp%anavar%c)
5929 ENDIF
5930
5931 IF (ASSOCIATED(v7d_tmp%dativar%c)) THEN
5932! alloco i dati reali e vi trasferisco i character
5933 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatic, 1), SIZE(v7d_tmp%voldatic, 2), &
5934 SIZE(v7d_tmp%voldatic, 3), SIZE(v7d_tmp%voldatic, 4), SIZE(v7d_tmp%voldatic, 5), &
5935 SIZE(v7d_tmp%voldatic, 6)))
5936 DO i = 1, SIZE(v7d_tmp%dativar%c)
5937 v7d_tmp%voldatir(:,:,:,:,i,:) = &
5938 realdat(v7d_tmp%voldatic(:,:,:,:,i,:), v7d_tmp%dativar%c(i))
5939 ENDDO
5940 DEALLOCATE(v7d_tmp%voldatic)
5941! trasferisco le variabili
5942 v7d_tmp%dativar%r => v7d_tmp%dativar%c
5943 NULLIFY(v7d_tmp%dativar%c)
5944 ENDIF
5945
5946! fondo con il volume definitivo
5947 CALL vol7d_merge(that, v7d_tmp)
5948ELSE
5950ENDIF
5951
5952END SUBROUTINE vol7d_convr
5953
5954
5955!> Metodo per ottenere solo le differenze tra due oggetti vol7d.
5956!! Il primo volume viene confrontato col secondo; nel secondo volume ovunque
5957!! i dati confrontati siano coincidenti viene impostato valore mancante.
5958SUBROUTINE vol7d_diff_only (this, that, data_only,ana)
5959TYPE(vol7d),INTENT(IN) :: this !< primo volume da confrontare
5960TYPE(vol7d),INTENT(OUT) :: that !< secondo volume da confrontare in cui eliminare i dati coincidenti
5961logical , optional, intent(in) :: data_only !< attiva l'elaborazione dei soli dati e non dell'anagrafica (default: .false.)
5962logical , optional, intent(in) :: ana !< attiva l'elaborazione dell'anagrafica (coordinate e ident) (default: .false.)
5963logical :: ldata_only,lana
5964
5965IF (PRESENT(data_only)) THEN
5966 ldata_only = data_only
5967ELSE
5968 ldata_only = .false.
5969ENDIF
5970
5971IF (PRESENT(ana)) THEN
5972 lana = ana
5973ELSE
5974 lana = .false.
5975ENDIF
5976
5977
5978#undef VOL7D_POLY_ARRAY
5979#define VOL7D_POLY_ARRAY voldati
5980#include "vol7d_class_diff.F90"
5981#undef VOL7D_POLY_ARRAY
5982#define VOL7D_POLY_ARRAY voldatiattr
5983#include "vol7d_class_diff.F90"
5984#undef VOL7D_POLY_ARRAY
5985
5986if ( .not. ldata_only) then
5987
5988#define VOL7D_POLY_ARRAY volana
5989#include "vol7d_class_diff.F90"
5990#undef VOL7D_POLY_ARRAY
5991#define VOL7D_POLY_ARRAY volanaattr
5992#include "vol7d_class_diff.F90"
5993#undef VOL7D_POLY_ARRAY
5994
5995 if(lana)then
5996 where ( this%ana == that%ana )
5997 that%ana = vol7d_ana_miss
5998 end where
5999 end if
6000
6001end if
6002
6003
6004
6005END SUBROUTINE vol7d_diff_only
6006
6007
6008
6009! Creo le routine da ripetere per i vari tipi di dati di v7d
6010! tramite un template e il preprocessore
6011#undef VOL7D_POLY_TYPE
6012#undef VOL7D_POLY_TYPES
6013#define VOL7D_POLY_TYPE REAL
6014#define VOL7D_POLY_TYPES r
6015#include "vol7d_class_type_templ.F90"
6016#undef VOL7D_POLY_TYPE
6017#undef VOL7D_POLY_TYPES
6018#define VOL7D_POLY_TYPE DOUBLE PRECISION
6019#define VOL7D_POLY_TYPES d
6020#include "vol7d_class_type_templ.F90"
6021#undef VOL7D_POLY_TYPE
6022#undef VOL7D_POLY_TYPES
6023#define VOL7D_POLY_TYPE INTEGER
6024#define VOL7D_POLY_TYPES i
6025#include "vol7d_class_type_templ.F90"
6026#undef VOL7D_POLY_TYPE
6027#undef VOL7D_POLY_TYPES
6028#define VOL7D_POLY_TYPE INTEGER(kind=int_b)
6029#define VOL7D_POLY_TYPES b
6030#include "vol7d_class_type_templ.F90"
6031#undef VOL7D_POLY_TYPE
6032#undef VOL7D_POLY_TYPES
6033#define VOL7D_POLY_TYPE CHARACTER(len=vol7d_cdatalen)
6034#define VOL7D_POLY_TYPES c
6035#include "vol7d_class_type_templ.F90"
6036
6037! Creo le routine da ripetere per i vari descrittori di dimensioni di v7d
6038! tramite un template e il preprocessore
6039#define VOL7D_SORT
6040#undef VOL7D_NO_ZERO_ALLOC
6041#undef VOL7D_POLY_TYPE
6042#define VOL7D_POLY_TYPE datetime
6043#include "vol7d_class_desc_templ.F90"
6044#undef VOL7D_POLY_TYPE
6045#define VOL7D_POLY_TYPE vol7d_timerange
6046#include "vol7d_class_desc_templ.F90"
6047#undef VOL7D_POLY_TYPE
6048#define VOL7D_POLY_TYPE vol7d_level
6049#include "vol7d_class_desc_templ.F90"
6050#undef VOL7D_SORT
6051#undef VOL7D_POLY_TYPE
6052#define VOL7D_POLY_TYPE vol7d_network
6053#include "vol7d_class_desc_templ.F90"
6054#undef VOL7D_POLY_TYPE
6055#define VOL7D_POLY_TYPE vol7d_ana
6056#include "vol7d_class_desc_templ.F90"
6057#define VOL7D_NO_ZERO_ALLOC
6058#undef VOL7D_POLY_TYPE
6059#define VOL7D_POLY_TYPE vol7d_var
6060#include "vol7d_class_desc_templ.F90"
6061
6062!>\brief Scrittura su file di un volume Vol7d.
6063!! Scrittura su file unformatted di un intero volume Vol7d.
6064!! Il volume viene serializzato e scritto su file.
6065!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
6066!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
6067!! tali parametri saranno in output.
6068!! Se non viene fornito il nome file viene utilizzato un file di default con nome pari al nome del programma in
6069!! esecuzione con postfisso ".v7d".
6070!! Come parametro opzionale c'è la description che insieme alla data corrente viene inserita nell'header del file.
6071subroutine vol7d_write_on_file (this,unit,description,filename,filename_auto)
6072
6073TYPE(vol7d),INTENT(IN) :: this !< volume vol7d da scrivere
6074integer,optional,intent(inout) :: unit !< unità su cui scrivere; se passata =0 ritorna il valore rielaborato (default =rielaborato internamente con getlun )
6075character(len=*),intent(in),optional :: filename !< nome del file su cui scrivere
6076character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
6077character(len=*),INTENT(IN),optional :: description !< descrizione del volume
6078
6079integer :: lunit
6080character(len=254) :: ldescription,arg,lfilename
6081integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
6082 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
6083 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
6084 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
6085 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
6086 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
6087 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
6088!integer :: im,id,iy
6089integer :: tarray(8)
6090logical :: opened,exist
6091
6092 nana=0
6093 ntime=0
6094 ntimerange=0
6095 nlevel=0
6096 nnetwork=0
6097 ndativarr=0
6098 ndativari=0
6099 ndativarb=0
6100 ndativard=0
6101 ndativarc=0
6102 ndatiattrr=0
6103 ndatiattri=0
6104 ndatiattrb=0
6105 ndatiattrd=0
6106 ndatiattrc=0
6107 ndativarattrr=0
6108 ndativarattri=0
6109 ndativarattrb=0
6110 ndativarattrd=0
6111 ndativarattrc=0
6112 nanavarr=0
6113 nanavari=0
6114 nanavarb=0
6115 nanavard=0
6116 nanavarc=0
6117 nanaattrr=0
6118 nanaattri=0
6119 nanaattrb=0
6120 nanaattrd=0
6121 nanaattrc=0
6122 nanavarattrr=0
6123 nanavarattri=0
6124 nanavarattrb=0
6125 nanavarattrd=0
6126 nanavarattrc=0
6127
6128
6129!call idate(im,id,iy)
6130call date_and_time(values=tarray)
6131call getarg(0,arg)
6132
6133if (present(description))then
6134 ldescription=description
6135else
6136 ldescription="Vol7d generated by: "//trim(arg)
6137end if
6138
6139if (.not. present(unit))then
6140 lunit=getunit()
6141else
6142 if (unit==0)then
6143 lunit=getunit()
6144 unit=lunit
6145 else
6146 lunit=unit
6147 end if
6148end if
6149
6150lfilename=trim(arg)//".v7d"
6152
6153if (present(filename))then
6154 if (filename /= "")then
6155 lfilename=filename
6156 end if
6157end if
6158
6159if (present(filename_auto))filename_auto=lfilename
6160
6161
6162inquire(unit=lunit,opened=opened)
6163if (.not. opened) then
6164! inquire(file=lfilename, EXIST=exist)
6165! IF (exist) THEN
6166! CALL l4f_log(L4F_FATAL, &
6167! 'in vol7d_write_on_file, file exists, cannot open file '//TRIM(lfilename))
6168! CALL raise_fatal_error()
6169! ENDIF
6170 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM')
6171 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
6172end if
6173
6174if (associated(this%ana)) nana=size(this%ana)
6175if (associated(this%time)) ntime=size(this%time)
6176if (associated(this%timerange)) ntimerange=size(this%timerange)
6177if (associated(this%level)) nlevel=size(this%level)
6178if (associated(this%network)) nnetwork=size(this%network)
6179
6180if (associated(this%dativar%r)) ndativarr=size(this%dativar%r)
6181if (associated(this%dativar%i)) ndativari=size(this%dativar%i)
6182if (associated(this%dativar%b)) ndativarb=size(this%dativar%b)
6183if (associated(this%dativar%d)) ndativard=size(this%dativar%d)
6184if (associated(this%dativar%c)) ndativarc=size(this%dativar%c)
6185
6186if (associated(this%datiattr%r)) ndatiattrr=size(this%datiattr%r)
6187if (associated(this%datiattr%i)) ndatiattri=size(this%datiattr%i)
6188if (associated(this%datiattr%b)) ndatiattrb=size(this%datiattr%b)
6189if (associated(this%datiattr%d)) ndatiattrd=size(this%datiattr%d)
6190if (associated(this%datiattr%c)) ndatiattrc=size(this%datiattr%c)
6191
6192if (associated(this%dativarattr%r)) ndativarattrr=size(this%dativarattr%r)
6193if (associated(this%dativarattr%i)) ndativarattri=size(this%dativarattr%i)
6194if (associated(this%dativarattr%b)) ndativarattrb=size(this%dativarattr%b)
6195if (associated(this%dativarattr%d)) ndativarattrd=size(this%dativarattr%d)
6196if (associated(this%dativarattr%c)) ndativarattrc=size(this%dativarattr%c)
6197
6198if (associated(this%anavar%r)) nanavarr=size(this%anavar%r)
6199if (associated(this%anavar%i)) nanavari=size(this%anavar%i)
6200if (associated(this%anavar%b)) nanavarb=size(this%anavar%b)
6201if (associated(this%anavar%d)) nanavard=size(this%anavar%d)
6202if (associated(this%anavar%c)) nanavarc=size(this%anavar%c)
6203
6204if (associated(this%anaattr%r)) nanaattrr=size(this%anaattr%r)
6205if (associated(this%anaattr%i)) nanaattri=size(this%anaattr%i)
6206if (associated(this%anaattr%b)) nanaattrb=size(this%anaattr%b)
6207if (associated(this%anaattr%d)) nanaattrd=size(this%anaattr%d)
6208if (associated(this%anaattr%c)) nanaattrc=size(this%anaattr%c)
6209
6210if (associated(this%anavarattr%r)) nanavarattrr=size(this%anavarattr%r)
6211if (associated(this%anavarattr%i)) nanavarattri=size(this%anavarattr%i)
6212if (associated(this%anavarattr%b)) nanavarattrb=size(this%anavarattr%b)
6213if (associated(this%anavarattr%d)) nanavarattrd=size(this%anavarattr%d)
6214if (associated(this%anavarattr%c)) nanavarattrc=size(this%anavarattr%c)
6215
6216write(unit=lunit)ldescription
6217write(unit=lunit)tarray
6218
6219write(unit=lunit)&
6220 nana, ntime, ntimerange, nlevel, nnetwork, &
6221 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
6222 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
6223 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
6224 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
6225 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
6226 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
6227 this%time_definition
6228
6229
6230!write(unit=lunit)this
6231
6232
6233!! prime 5 dimensioni
6236if (associated(this%level)) write(unit=lunit)this%level
6237if (associated(this%timerange)) write(unit=lunit)this%timerange
6238if (associated(this%network)) write(unit=lunit)this%network
6239
6240 !! 6a dimensione: variabile dell'anagrafica e dei dati
6241 !! con relativi attributi e in 5 tipi diversi
6242
6243if (associated(this%anavar%r)) write(unit=lunit)this%anavar%r
6244if (associated(this%anavar%i)) write(unit=lunit)this%anavar%i
6245if (associated(this%anavar%b)) write(unit=lunit)this%anavar%b
6246if (associated(this%anavar%d)) write(unit=lunit)this%anavar%d
6247if (associated(this%anavar%c)) write(unit=lunit)this%anavar%c
6248
6249if (associated(this%anaattr%r)) write(unit=lunit)this%anaattr%r
6250if (associated(this%anaattr%i)) write(unit=lunit)this%anaattr%i
6251if (associated(this%anaattr%b)) write(unit=lunit)this%anaattr%b
6252if (associated(this%anaattr%d)) write(unit=lunit)this%anaattr%d
6253if (associated(this%anaattr%c)) write(unit=lunit)this%anaattr%c
6254
6255if (associated(this%anavarattr%r)) write(unit=lunit)this%anavarattr%r
6256if (associated(this%anavarattr%i)) write(unit=lunit)this%anavarattr%i
6257if (associated(this%anavarattr%b)) write(unit=lunit)this%anavarattr%b
6258if (associated(this%anavarattr%d)) write(unit=lunit)this%anavarattr%d
6259if (associated(this%anavarattr%c)) write(unit=lunit)this%anavarattr%c
6260
6261if (associated(this%dativar%r)) write(unit=lunit)this%dativar%r
6262if (associated(this%dativar%i)) write(unit=lunit)this%dativar%i
6263if (associated(this%dativar%b)) write(unit=lunit)this%dativar%b
6264if (associated(this%dativar%d)) write(unit=lunit)this%dativar%d
6265if (associated(this%dativar%c)) write(unit=lunit)this%dativar%c
6266
6267if (associated(this%datiattr%r)) write(unit=lunit)this%datiattr%r
6268if (associated(this%datiattr%i)) write(unit=lunit)this%datiattr%i
6269if (associated(this%datiattr%b)) write(unit=lunit)this%datiattr%b
6270if (associated(this%datiattr%d)) write(unit=lunit)this%datiattr%d
6271if (associated(this%datiattr%c)) write(unit=lunit)this%datiattr%c
6272
6273if (associated(this%dativarattr%r)) write(unit=lunit)this%dativarattr%r
6274if (associated(this%dativarattr%i)) write(unit=lunit)this%dativarattr%i
6275if (associated(this%dativarattr%b)) write(unit=lunit)this%dativarattr%b
6276if (associated(this%dativarattr%d)) write(unit=lunit)this%dativarattr%d
6277if (associated(this%dativarattr%c)) write(unit=lunit)this%dativarattr%c
6278
6279!! Volumi di valori e attributi per anagrafica e dati
6280
6281if (associated(this%volanar)) write(unit=lunit)this%volanar
6282if (associated(this%volanaattrr)) write(unit=lunit)this%volanaattrr
6283if (associated(this%voldatir)) write(unit=lunit)this%voldatir
6284if (associated(this%voldatiattrr)) write(unit=lunit)this%voldatiattrr
6285
6286if (associated(this%volanai)) write(unit=lunit)this%volanai
6287if (associated(this%volanaattri)) write(unit=lunit)this%volanaattri
6288if (associated(this%voldatii)) write(unit=lunit)this%voldatii
6289if (associated(this%voldatiattri)) write(unit=lunit)this%voldatiattri
6290
6291if (associated(this%volanab)) write(unit=lunit)this%volanab
6292if (associated(this%volanaattrb)) write(unit=lunit)this%volanaattrb
6293if (associated(this%voldatib)) write(unit=lunit)this%voldatib
6294if (associated(this%voldatiattrb)) write(unit=lunit)this%voldatiattrb
6295
6296if (associated(this%volanad)) write(unit=lunit)this%volanad
6297if (associated(this%volanaattrd)) write(unit=lunit)this%volanaattrd
6298if (associated(this%voldatid)) write(unit=lunit)this%voldatid
6299if (associated(this%voldatiattrd)) write(unit=lunit)this%voldatiattrd
6300
6301if (associated(this%volanac)) write(unit=lunit)this%volanac
6302if (associated(this%volanaattrc)) write(unit=lunit)this%volanaattrc
6303if (associated(this%voldatic)) write(unit=lunit)this%voldatic
6304if (associated(this%voldatiattrc)) write(unit=lunit)this%voldatiattrc
6305
6306if (.not. present(unit)) close(unit=lunit)
6307
6308end subroutine vol7d_write_on_file
6309
6310
6311!>\brief Lettura da file di un volume Vol7d.
6312!! Lettura da file unformatted di un intero volume Vol7d.
6313!! Questa subroutine comprende vol7d_alloc e vol7d_alloc_vol.
6314!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
6315!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
6316!! tali parametri saranno in output.
6317
6318
6319subroutine vol7d_read_from_file (this,unit,filename,description,tarray,filename_auto)
6320
6321TYPE(vol7d),INTENT(OUT) :: this !< Volume vol7d da leggere
6322integer,intent(inout),optional :: unit !< unità su cui è stato aperto un file; se =0 rielaborato internamente (default = elaborato internamente con getunit)
6323character(len=*),INTENT(in),optional :: filename !< nome del file eventualmente da aprire (default = (nome dell'eseguibile)//.v7d )
6324character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
6325character(len=*),INTENT(out),optional :: description !< descrizione del volume letto
6326integer,intent(out),optional :: tarray(8) !< vettore come definito da "date_and_time" della data di scrittura del volume
6327
6328
6329integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
6330 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
6331 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
6332 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
6333 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
6334 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
6335 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
6336
6337character(len=254) :: ldescription,lfilename,arg
6338integer :: ltarray(8),lunit,ios
6339logical :: opened,exist
6340
6341
6342call getarg(0,arg)
6343
6344if (.not. present(unit))then
6345 lunit=getunit()
6346else
6347 if (unit==0)then
6348 lunit=getunit()
6349 unit=lunit
6350 else
6351 lunit=unit
6352 end if
6353end if
6354
6355lfilename=trim(arg)//".v7d"
6357
6358if (present(filename))then
6359 if (filename /= "")then
6360 lfilename=filename
6361 end if
6362end if
6363
6364if (present(filename_auto))filename_auto=lfilename
6365
6366
6367inquire(unit=lunit,opened=opened)
6368IF (.NOT. opened) THEN
6369 inquire(file=lfilename,exist=exist)
6370 IF (.NOT.exist) THEN
6371 CALL l4f_log(l4f_fatal, &
6372 'in vol7d_read_from_file, file does not exists, cannot open')
6373 CALL raise_fatal_error()
6374 ENDIF
6375 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM', &
6376 status='OLD', action='READ')
6377 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
6378end if
6379
6380
6382read(unit=lunit,iostat=ios)ldescription
6383
6384if (ios < 0) then ! A negative value indicates that the End of File or End of Record
6385 call vol7d_alloc (this)
6386 call vol7d_alloc_vol (this)
6387 if (present(description))description=ldescription
6388 if (present(tarray))tarray=ltarray
6389 if (.not. present(unit)) close(unit=lunit)
6390end if
6391
6392read(unit=lunit)ltarray
6393
6394CALL l4f_log(l4f_info, 'Reading vol7d from file')
6395CALL l4f_log(l4f_info, 'description: '//trim(ldescription))
6398
6399if (present(description))description=ldescription
6400if (present(tarray))tarray=ltarray
6401
6402read(unit=lunit)&
6403 nana, ntime, ntimerange, nlevel, nnetwork, &
6404 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
6405 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
6406 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
6407 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
6408 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
6409 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
6410 this%time_definition
6411
6412call vol7d_alloc (this, &
6413 nana=nana, ntime=ntime, ntimerange=ntimerange, nlevel=nlevel, nnetwork=nnetwork,&
6414 ndativarr=ndativarr, ndativari=ndativari, ndativarb=ndativarb,&
6415 ndativard=ndativard, ndativarc=ndativarc,&
6416 ndatiattrr=ndatiattrr, ndatiattri=ndatiattri, ndatiattrb=ndatiattrb,&
6417 ndatiattrd=ndatiattrd, ndatiattrc=ndatiattrc,&
6418 ndativarattrr=ndativarattrr, ndativarattri=ndativarattri, ndativarattrb=ndativarattrb, &
6419 ndativarattrd=ndativarattrd, ndativarattrc=ndativarattrc,&
6420 nanavarr=nanavarr, nanavari=nanavari, nanavarb=nanavarb, &
6421 nanavard=nanavard, nanavarc=nanavarc,&
6422 nanaattrr=nanaattrr, nanaattri=nanaattri, nanaattrb=nanaattrb,&
6423 nanaattrd=nanaattrd, nanaattrc=nanaattrc,&
6424 nanavarattrr=nanavarattrr, nanavarattri=nanavarattri, nanavarattrb=nanavarattrb, &
6425 nanavarattrd=nanavarattrd, nanavarattrc=nanavarattrc)
6426
6427
6430if (associated(this%level)) read(unit=lunit)this%level
6431if (associated(this%timerange)) read(unit=lunit)this%timerange
6432if (associated(this%network)) read(unit=lunit)this%network
6433
6434if (associated(this%anavar%r)) read(unit=lunit)this%anavar%r
6435if (associated(this%anavar%i)) read(unit=lunit)this%anavar%i
6436if (associated(this%anavar%b)) read(unit=lunit)this%anavar%b
6437if (associated(this%anavar%d)) read(unit=lunit)this%anavar%d
6438if (associated(this%anavar%c)) read(unit=lunit)this%anavar%c
6439
6440if (associated(this%anaattr%r)) read(unit=lunit)this%anaattr%r
6441if (associated(this%anaattr%i)) read(unit=lunit)this%anaattr%i
6442if (associated(this%anaattr%b)) read(unit=lunit)this%anaattr%b
6443if (associated(this%anaattr%d)) read(unit=lunit)this%anaattr%d
6444if (associated(this%anaattr%c)) read(unit=lunit)this%anaattr%c
6445
6446if (associated(this%anavarattr%r)) read(unit=lunit)this%anavarattr%r
6447if (associated(this%anavarattr%i)) read(unit=lunit)this%anavarattr%i
6448if (associated(this%anavarattr%b)) read(unit=lunit)this%anavarattr%b
6449if (associated(this%anavarattr%d)) read(unit=lunit)this%anavarattr%d
6450if (associated(this%anavarattr%c)) read(unit=lunit)this%anavarattr%c
6451
6452if (associated(this%dativar%r)) read(unit=lunit)this%dativar%r
6453if (associated(this%dativar%i)) read(unit=lunit)this%dativar%i
6454if (associated(this%dativar%b)) read(unit=lunit)this%dativar%b
6455if (associated(this%dativar%d)) read(unit=lunit)this%dativar%d
6456if (associated(this%dativar%c)) read(unit=lunit)this%dativar%c
6457
6458if (associated(this%datiattr%r)) read(unit=lunit)this%datiattr%r
6459if (associated(this%datiattr%i)) read(unit=lunit)this%datiattr%i
6460if (associated(this%datiattr%b)) read(unit=lunit)this%datiattr%b
6461if (associated(this%datiattr%d)) read(unit=lunit)this%datiattr%d
6462if (associated(this%datiattr%c)) read(unit=lunit)this%datiattr%c
6463
6464if (associated(this%dativarattr%r)) read(unit=lunit)this%dativarattr%r
6465if (associated(this%dativarattr%i)) read(unit=lunit)this%dativarattr%i
6466if (associated(this%dativarattr%b)) read(unit=lunit)this%dativarattr%b
6467if (associated(this%dativarattr%d)) read(unit=lunit)this%dativarattr%d
6468if (associated(this%dativarattr%c)) read(unit=lunit)this%dativarattr%c
6469
6470call vol7d_alloc_vol (this)
6471
6472!! Volumi di valori e attributi per anagrafica e dati
6473
6474if (associated(this%volanar)) read(unit=lunit)this%volanar
6475if (associated(this%volanaattrr)) read(unit=lunit)this%volanaattrr
6476if (associated(this%voldatir)) read(unit=lunit)this%voldatir
6477if (associated(this%voldatiattrr)) read(unit=lunit)this%voldatiattrr
6478
6479if (associated(this%volanai)) read(unit=lunit)this%volanai
6480if (associated(this%volanaattri)) read(unit=lunit)this%volanaattri
6481if (associated(this%voldatii)) read(unit=lunit)this%voldatii
6482if (associated(this%voldatiattri)) read(unit=lunit)this%voldatiattri
6483
6484if (associated(this%volanab)) read(unit=lunit)this%volanab
6485if (associated(this%volanaattrb)) read(unit=lunit)this%volanaattrb
6486if (associated(this%voldatib)) read(unit=lunit)this%voldatib
6487if (associated(this%voldatiattrb)) read(unit=lunit)this%voldatiattrb
6488
6489if (associated(this%volanad)) read(unit=lunit)this%volanad
6490if (associated(this%volanaattrd)) read(unit=lunit)this%volanaattrd
6491if (associated(this%voldatid)) read(unit=lunit)this%voldatid
6492if (associated(this%voldatiattrd)) read(unit=lunit)this%voldatiattrd
6493
6494if (associated(this%volanac)) read(unit=lunit)this%volanac
6495if (associated(this%volanaattrc)) read(unit=lunit)this%volanaattrc
6496if (associated(this%voldatic)) read(unit=lunit)this%voldatic
6497if (associated(this%voldatiattrc)) read(unit=lunit)this%voldatiattrc
6498
6499if (.not. present(unit)) close(unit=lunit)
6500
6501end subroutine vol7d_read_from_file
6502
6503
6504! to double precision
6505elemental doubleprecision function doubledatd(voldat,var)
6506doubleprecision,intent(in) :: voldat
6507type(vol7d_var),intent(in) :: var
6508
6509doubledatd=voldat
6510
6511end function doubledatd
6512
6513
6514elemental doubleprecision function doubledatr(voldat,var)
6515real,intent(in) :: voldat
6516type(vol7d_var),intent(in) :: var
6517
6519 doubledatr=dble(voldat)
6520else
6521 doubledatr=dmiss
6522end if
6523
6524end function doubledatr
6525
6526
6527elemental doubleprecision function doubledati(voldat,var)
6528integer,intent(in) :: voldat
6529type(vol7d_var),intent(in) :: var
6530
6533 doubledati=dble(voldat)/10.d0**var%scalefactor
6534 else
6535 doubledati=dble(voldat)
6536 endif
6537else
6538 doubledati=dmiss
6539end if
6540
6541end function doubledati
6542
6543
6544elemental doubleprecision function doubledatb(voldat,var)
6545integer(kind=int_b),intent(in) :: voldat
6546type(vol7d_var),intent(in) :: var
6547
6550 doubledatb=dble(voldat)/10.d0**var%scalefactor
6551 else
6552 doubledatb=dble(voldat)
6553 endif
6554else
6555 doubledatb=dmiss
6556end if
6557
6558end function doubledatb
6559
6560
6561elemental doubleprecision function doubledatc(voldat,var)
6562CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
6563type(vol7d_var),intent(in) :: var
6564
6565doubledatc = c2d(voldat)
6567 doubledatc=doubledatc/10.d0**var%scalefactor
6568end if
6569
6570end function doubledatc
6571
6572
6573! to integer
6574elemental integer function integerdatd(voldat,var)
6575doubleprecision,intent(in) :: voldat
6576type(vol7d_var),intent(in) :: var
6577
6580 integerdatd=nint(voldat*10d0**var%scalefactor)
6581 else
6582 integerdatd=nint(voldat)
6583 endif
6584else
6585 integerdatd=imiss
6586end if
6587
6588end function integerdatd
6589
6590
6591elemental integer function integerdatr(voldat,var)
6592real,intent(in) :: voldat
6593type(vol7d_var),intent(in) :: var
6594
6597 integerdatr=nint(voldat*10d0**var%scalefactor)
6598 else
6599 integerdatr=nint(voldat)
6600 endif
6601else
6602 integerdatr=imiss
6603end if
6604
6605end function integerdatr
6606
6607
6608elemental integer function integerdati(voldat,var)
6609integer,intent(in) :: voldat
6610type(vol7d_var),intent(in) :: var
6611
6612integerdati=voldat
6613
6614end function integerdati
6615
6616
6617elemental integer function integerdatb(voldat,var)
6618integer(kind=int_b),intent(in) :: voldat
6619type(vol7d_var),intent(in) :: var
6620
6622 integerdatb=voldat
6623else
6624 integerdatb=imiss
6625end if
6626
6627end function integerdatb
6628
6629
6630elemental integer function integerdatc(voldat,var)
6631CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
6632type(vol7d_var),intent(in) :: var
6633
6634integerdatc=c2i(voldat)
6635
6636end function integerdatc
6637
6638
6639! to real
6640elemental real function realdatd(voldat,var)
6641doubleprecision,intent(in) :: voldat
6642type(vol7d_var),intent(in) :: var
6643
6645 realdatd=real(voldat)
6646else
6647 realdatd=rmiss
6648end if
6649
6650end function realdatd
6651
6652
6653elemental real function realdatr(voldat,var)
6654real,intent(in) :: voldat
6655type(vol7d_var),intent(in) :: var
6656
6657realdatr=voldat
6658
6659end function realdatr
6660
6661
6662elemental real function realdati(voldat,var)
6663integer,intent(in) :: voldat
6664type(vol7d_var),intent(in) :: var
6665
6668 realdati=float(voldat)/10.**var%scalefactor
6669 else
6670 realdati=float(voldat)
6671 endif
6672else
6673 realdati=rmiss
6674end if
6675
6676end function realdati
6677
6678
6679elemental real function realdatb(voldat,var)
6680integer(kind=int_b),intent(in) :: voldat
6681type(vol7d_var),intent(in) :: var
6682
6685 realdatb=float(voldat)/10**var%scalefactor
6686 else
6687 realdatb=float(voldat)
6688 endif
6689else
6690 realdatb=rmiss
6691end if
6692
6693end function realdatb
6694
6695
6696elemental real function realdatc(voldat,var)
6697CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
6698type(vol7d_var),intent(in) :: var
6699
6700realdatc=c2r(voldat)
6702 realdatc=realdatc/10.**var%scalefactor
6703end if
6704
6705end function realdatc
6706
6707
6708!> Return an ana volume of a requested variable as real data.
6709!! It returns a 2-d array of the proper shape (ana x network) for the
6710!! ana variable requested, converted to real type. If the conversion
6711!! fails or if the variable is not contained in the ana volume,
6712!! missing data are returned.
6713FUNCTION realanavol(this, var) RESULT(vol)
6714TYPE(vol7d),INTENT(in) :: this !< the \a vol7d object to query, the method \a vol7d_alloc_vol must have been called for it otherwise progam may abort
6715TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
6716REAL :: vol(SIZE(this%ana),size(this%network))
6717
6718CHARACTER(len=1) :: dtype
6719INTEGER :: indvar
6720
6721dtype = cmiss
6722indvar = index(this%anavar, var, type=dtype)
6723
6724IF (indvar > 0) THEN
6725 SELECT CASE (dtype)
6726 CASE("d")
6727 vol = realdat(this%volanad(:,indvar,:), var)
6728 CASE("r")
6729 vol = this%volanar(:,indvar,:)
6730 CASE("i")
6731 vol = realdat(this%volanai(:,indvar,:), var)
6732 CASE("b")
6733 vol = realdat(this%volanab(:,indvar,:), var)
6734 CASE("c")
6735 vol = realdat(this%volanac(:,indvar,:), var)
6736 CASE default
6737 vol = rmiss
6738 END SELECT
6739ELSE
6740 vol = rmiss
6741ENDIF
6742
6743END FUNCTION realanavol
6744
6745
6746!> Return an ana volume of a requested variable as integer data.
6747!! It returns a 2-d array of the proper shape (ana x network) for the
6748!! ana variable requested, converted to integer type. If the conversion
6749!! fails or if the variable is not contained in the ana volume,
6750!! missing data are returned.
6751FUNCTION integeranavol(this, var) RESULT(vol)
6752TYPE(vol7d),INTENT(in) :: this !< the \a vol7d object to query, the method \a vol7d_alloc_vol must have been called for it otherwise progam may abort
6753TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
6754INTEGER :: vol(SIZE(this%ana),size(this%network))
6755
6756CHARACTER(len=1) :: dtype
6757INTEGER :: indvar
6758
6759dtype = cmiss
6760indvar = index(this%anavar, var, type=dtype)
6761
6762IF (indvar > 0) THEN
6763 SELECT CASE (dtype)
6764 CASE("d")
6765 vol = integerdat(this%volanad(:,indvar,:), var)
6766 CASE("r")
6767 vol = integerdat(this%volanar(:,indvar,:), var)
6768 CASE("i")
6769 vol = this%volanai(:,indvar,:)
6770 CASE("b")
6771 vol = integerdat(this%volanab(:,indvar,:), var)
6772 CASE("c")
6773 vol = integerdat(this%volanac(:,indvar,:), var)
6774 CASE default
6775 vol = imiss
6776 END SELECT
6777ELSE
6778 vol = imiss
6779ENDIF
6780
6781END FUNCTION integeranavol
6782
6783
6784!> Move data for all variables from one coordinate in the character volume to other.
6785!! Only not missing data will be copyed and all attributes will be moved together.
6786!! Usefull to colapse data spread in more indices (level or time or ....).
6787!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
6788!! to obtain a new vol7d with less data shape.
6789subroutine move_datac (v7d,&
6790 indana,indtime,indlevel,indtimerange,indnetwork,&
6791 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
6792
6793TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
6794
6795integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
6796integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
6797integer :: inddativar,inddativarattr
6798
6799
6800do inddativar=1,size(v7d%dativar%c)
6801
6803 .not. c_e(v7d%voldatic(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
6804 ) then
6805
6806 ! dati
6807 v7d%voldatic &
6808 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
6809 v7d%voldatic &
6810 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
6811
6812
6813 ! attributi
6814 if (associated (v7d%dativarattr%i)) then
6815 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%c(inddativar))
6816 if (inddativarattr > 0 ) then
6817 v7d%voldatiattri &
6818 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6819 v7d%voldatiattri &
6820 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6821 end if
6822 end if
6823
6824 if (associated (v7d%dativarattr%r)) then
6825 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%c(inddativar))
6826 if (inddativarattr > 0 ) then
6827 v7d%voldatiattrr &
6828 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6829 v7d%voldatiattrr &
6830 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6831 end if
6832 end if
6833
6834 if (associated (v7d%dativarattr%d)) then
6835 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%c(inddativar))
6836 if (inddativarattr > 0 ) then
6837 v7d%voldatiattrd &
6838 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6839 v7d%voldatiattrd &
6840 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6841 end if
6842 end if
6843
6844 if (associated (v7d%dativarattr%b)) then
6845 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%c(inddativar))
6846 if (inddativarattr > 0 ) then
6847 v7d%voldatiattrb &
6848 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6849 v7d%voldatiattrb &
6850 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6851 end if
6852 end if
6853
6854 if (associated (v7d%dativarattr%c)) then
6855 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%c(inddativar))
6856 if (inddativarattr > 0 ) then
6857 v7d%voldatiattrc &
6858 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6859 v7d%voldatiattrc &
6860 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6861 end if
6862 end if
6863
6864 end if
6865
6866end do
6867
6868end subroutine move_datac
6869
6870!> Move data for all variables from one coordinate in the real volume to other.
6871!! Only not missing data will be copyed and all attributes will be moved together.
6872!! Usefull to colapse data spread in more indices (level or time or ....).
6873!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
6874!! to obtain a new vol7d with less data shape.
6875subroutine move_datar (v7d,&
6876 indana,indtime,indlevel,indtimerange,indnetwork,&
6877 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
6878
6879TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
6880
6881integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
6882integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
6883integer :: inddativar,inddativarattr
6884
6885
6886do inddativar=1,size(v7d%dativar%r)
6887
6889 .not. c_e(v7d%voldatir(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
6890 ) then
6891
6892 ! dati
6893 v7d%voldatir &
6894 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
6895 v7d%voldatir &
6896 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
6897
6898
6899 ! attributi
6900 if (associated (v7d%dativarattr%i)) then
6901 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%r(inddativar))
6902 if (inddativarattr > 0 ) then
6903 v7d%voldatiattri &
6904 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6905 v7d%voldatiattri &
6906 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6907 end if
6908 end if
6909
6910 if (associated (v7d%dativarattr%r)) then
6911 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%r(inddativar))
6912 if (inddativarattr > 0 ) then
6913 v7d%voldatiattrr &
6914 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6915 v7d%voldatiattrr &
6916 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6917 end if
6918 end if
6919
6920 if (associated (v7d%dativarattr%d)) then
6921 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%r(inddativar))
6922 if (inddativarattr > 0 ) then
6923 v7d%voldatiattrd &
6924 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6925 v7d%voldatiattrd &
6926 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6927 end if
6928 end if
6929
6930 if (associated (v7d%dativarattr%b)) then
6931 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%r(inddativar))
6932 if (inddativarattr > 0 ) then
6933 v7d%voldatiattrb &
6934 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6935 v7d%voldatiattrb &
6936 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6937 end if
6938 end if
6939
6940 if (associated (v7d%dativarattr%c)) then
6941 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%r(inddativar))
6942 if (inddativarattr > 0 ) then
6943 v7d%voldatiattrc &
6944 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
6945 v7d%voldatiattrc &
6946 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
6947 end if
6948 end if
6949
6950 end if
6951
6952end do
6953
6954end subroutine move_datar
6955
6956
6957!> Reduce some dimensions (level and timerage) for semplification (rounding).
6958!! You can use this for simplify and use variables in computation like alchimia
6959!! where fields have to be on the same coordinate
6960!! It return real or character data only: if input is charcter data only it return character otherwise il return
6961!! all the data converted to real.
6962!! examples:
6963!! means in time for short periods and istantaneous values
6964!! 2 meter and surface levels
6965!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
6966!! will be taken (order is by icreasing var index).
6967!! You can use predefined values for classic semplification
6968!! almost_equal_levels and almost_equal_timeranges
6969!! The level or timerange in output will be defined by the first element of level and timerange list
6970subroutine v7d_rounding(v7din,v7dout,level,timerange,nostatproc)
6971type(vol7d),intent(inout) :: v7din !< input volume
6972type(vol7d),intent(out) :: v7dout !> output volume
6973type(vol7d_level),intent(in),optional :: level(:) !< almost equal level list
6974type(vol7d_timerange),intent(in),optional :: timerange(:) !< almost equal timerange list
6975!logical,intent(in),optional :: merge !< if there are data on more then one almost equal levels or timeranges
6976!! will be merged POINT BY POINT with priority for the fird data found ordered by icreasing var index
6977logical,intent(in),optional :: nostatproc !< do not take in account statistical processing code in timerange and P2
6978
6979integer :: nana,nlevel,ntime,ntimerange,nnetwork,nbin
6980integer :: iana,ilevel,itimerange,indl,indt,itime,inetwork
6981type(vol7d_level) :: roundlevel(size(v7din%level))
6982type(vol7d_timerange) :: roundtimerange(size(v7din%timerange))
6983type(vol7d) :: v7d_tmp
6984
6985
6986nbin=0
6987
6988if (associated(v7din%dativar%r)) nbin = nbin + size(v7din%dativar%r)
6989if (associated(v7din%dativar%i)) nbin = nbin + size(v7din%dativar%i)
6990if (associated(v7din%dativar%d)) nbin = nbin + size(v7din%dativar%d)
6991if (associated(v7din%dativar%b)) nbin = nbin + size(v7din%dativar%b)
6992
6994
6995roundlevel=v7din%level
6996
6997if (present(level))then
6998 do ilevel = 1, size(v7din%level)
6999 if ((any(v7din%level(ilevel) .almosteq. level))) then
7000 roundlevel(ilevel)=level(1)
7001 end if
7002 end do
7003end if
7004
7005roundtimerange=v7din%timerange
7006
7007if (present(timerange))then
7008 do itimerange = 1, size(v7din%timerange)
7009 if ((any(v7din%timerange(itimerange) .almosteq. timerange))) then
7010 roundtimerange(itimerange)=timerange(1)
7011 end if
7012 end do
7013end if
7014
7015!set istantaneous values everywere
7016!preserve p1 for forecast time
7017if (optio_log(nostatproc)) then
7018 roundtimerange(:)%timerange=254
7019 roundtimerange(:)%p2=0
7020end if
7021
7022
7023nana=size(v7din%ana)
7024nlevel=count_distinct(roundlevel,back=.true.)
7025ntime=size(v7din%time)
7026ntimerange=count_distinct(roundtimerange,back=.true.)
7027nnetwork=size(v7din%network)
7028
7030
7031if (nbin == 0) then
7033else
7034 call vol7d_convr(v7din,v7d_tmp)
7035end if
7036
7037v7d_tmp%level=roundlevel
7038v7d_tmp%timerange=roundtimerange
7039
7040do ilevel=1, size(v7d_tmp%level)
7041 indl=index(v7d_tmp%level,roundlevel(ilevel))
7042 do itimerange=1,size(v7d_tmp%timerange)
7043 indt=index(v7d_tmp%timerange,roundtimerange(itimerange))
7044
7045 if (indl /= ilevel .or. indt /= itimerange) then
7046
7047 do iana=1, nana
7048 do itime=1,ntime
7049 do inetwork=1,nnetwork
7050
7051 if (nbin > 0) then
7052 call move_datar (v7d_tmp,&
7053 iana,itime,ilevel,itimerange,inetwork,&
7054 iana,itime,indl,indt,inetwork)
7055 else
7056 call move_datac (v7d_tmp,&
7057 iana,itime,ilevel,itimerange,inetwork,&
7058 iana,itime,indl,indt,inetwork)
7059 end if
7060
7061 end do
7062 end do
7063 end do
7064
7065 end if
7066
7067 end do
7068end do
7069
7070! set to missing level and time > nlevel
7071do ilevel=nlevel+1,size(v7d_tmp%level)
7073end do
7074
7075do itimerange=ntimerange+1,size(v7d_tmp%timerange)
7077end do
7078
7079!copy with remove
7082
7083!call display(v7dout)
7084
7085end subroutine v7d_rounding
7086
7087
7089
7090!>\example esempio_qc_convert.f90
7091!!\brief Programma esempio semplice per la scrittura su file di un volume vol7d
7092!!
7093!!Programma che scrive su file un volume vol7d letto da una serie di file ASCII.
7094!!Questo programma scrive i dati del clima che poi verranno letti da modqccli
7095
7096
7097!>\example esempio_v7ddballe_move_and_collapse.f90
7098!!\brief ! Example program to reduce to one the dimensions of levels and time without loss of data
Set of functions that return a trimmed CHARACTER representation of the input variable. Definition char_utilities.F90:278 Legge un oggetto datetime/timedelta o un vettore di oggetti datetime/timedelta da un file FORMATTED o... Definition datetime_class.F90:478 Scrive un oggetto datetime/timedelta o un vettore di oggetti datetime/timedelta su un file FORMATTED ... Definition datetime_class.F90:485 Generic subroutine for checking OPTIONAL parameters. Definition optional_values.f90:36 Check for problems return 0 if all check passed print diagnostics with log4f. Definition vol7d_class.F90:445 Reduce some dimensions (level and timerage) for semplification (rounding). Definition vol7d_class.F90:462 This module defines usefull general purpose function and subroutine. Definition array_utilities.F90:212 Definition of constants to be used for declaring variables of a desired type. Definition kinds.F90:245 Module for quickly interpreting the OPTIONAL parameters passed to a subprogram. Definition optional_values.f90:28 Classe per la gestione dell'anagrafica di stazioni meteo e affini. Definition vol7d_ana_class.F90:212 Classe per la gestione di un volume completo di dati osservati. Definition vol7d_class.F90:273 Classe per la gestione dei livelli verticali in osservazioni meteo e affini. Definition vol7d_level_class.F90:213 Classe per la gestione delle reti di stazioni per osservazioni meteo e affini. Definition vol7d_network_class.F90:214 Classe per la gestione degli intervalli temporali di osservazioni meteo e affini. Definition vol7d_timerange_class.F90:215 Classe per gestire un vettore di oggetti di tipo vol7d_var_class::vol7d_var. Definition vol7d_varvect_class.f90:22 Definisce un oggetto contenente i volumi anagrafica e dati e tutti i descrittori delle loro dimension... Definition vol7d_class.F90:312 |