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