libsim Versione 8.0.0

◆ vol7d_get_volanar()

subroutine vol7d_get_volanar ( type(vol7d), intent(in) this,
integer, dimension(:), intent(in) dimlist,
real, dimension(:), optional, pointer vol1dp,
real, dimension(:,:), optional, pointer vol2dp,
real, dimension(:,:,:), optional, pointer vol3dp )

Crea una vista a dimensione ridotta di un volume 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_volanar(v7d1, (/vol7d_ana_d/), vol1d)
IF (ASSOCIATED(vol1d)) THEN
print*,vol1d
...
ENDIF
return
Parametri
[in]thisoggetto di cui creare la vista
[in]dimlistlista delle dimensioni da includere nella vista, attenzione tutte le dimensioni non degeneri (cioè con estensione >1) devono essere incluse nella lista; utilizzare le costanti vol7d_ana_a ... vol7d_attr_a, ecc.
vol1dparray che in uscita conterrà la vista 1d
vol2dparray che in uscita conterrà la vista 2d
vol3dparray che in uscita conterrà la vista 3d

Definizione alla linea 3541 del file vol7d_class.F90.

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

Generated with Doxygen.