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