|
libsim Versione 8.0.0
|
◆ v7d_rounding()
Reduce some dimensions (level and timerage) for semplification (rounding). You can use this for simplify and use variables in computation like alchimia where fields have to be on the same coordinate It return real or character data only: if input is charcter data only it return character otherwise il return all the data converted to real. examples: means in time for short periods and istantaneous values 2 meter and surface levels If there are data on more then one almost equal levels or timeranges, the first var present (at least one point) will be taken (order is by icreasing var index). You can use predefined values for classic semplification almost_equal_levels and almost_equal_timeranges The level or timerange in output will be defined by the first element of level and timerange list
Definizione alla linea 9368 del file vol7d_class.F90. 9369! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
9370! authors:
9371! Davide Cesari <dcesari@arpa.emr.it>
9372! Paolo Patruno <ppatruno@arpa.emr.it>
9373
9374! This program is free software; you can redistribute it and/or
9375! modify it under the terms of the GNU General Public License as
9376! published by the Free Software Foundation; either version 2 of
9377! the License, or (at your option) any later version.
9378
9379! This program is distributed in the hope that it will be useful,
9380! but WITHOUT ANY WARRANTY; without even the implied warranty of
9381! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9382! GNU General Public License for more details.
9383
9384! You should have received a copy of the GNU General Public License
9385! along with this program. If not, see <http://www.gnu.org/licenses/>.
9386#include "config.h"
9387
9388!> \defgroup vol7d Libsim package, vol7d library.
9389!! The libsim vol7d library contains classes for managing pointwise
9390!! data, tipically weather observations, and for their import from a
9391!! Db-All.e database or from a WMO BUFR file. In order to compile and
9392!! link programs using this library, you have to insert the required
9393!! \c USE statements in the program units involved, specify the
9394!! location of module files when compiling (tipically \c
9395!! -I/usr/lib/gfortran/modules or \c -I/usr/lib64/gfortran/modules or
9396!! \c -I/usr/include) and indicate the library name \c -lsim_vol7d
9397!! when linking, assuming that the library has been installed in a
9398!! default location.
9399
9400!> Classe per la gestione di un volume completo di dati osservati.
9401!! Questo modulo definisce gli oggetti e i metodi per gestire
9402!! volumi di dati meteorologici sparsi.
9403!! I volumi definiti sono principalmente di 4 categorie:
9404!! - volumi di anagrafica (vol7d::volanar & c.), hanno 3 dimensioni:
9405!! - anagrafica
9406!! - variabile di anagrafica
9407!! - rete
9408!! - volumi di attributi di anagrafica (vol7d::volanaattrr & c.), hanno 4 dimensioni:
9409!! - anagrafica
9410!! - variabile di anagrafica
9411!! - rete
9412!! - variabile di attributi delle variabili di anagrafica
9413!! - volumi di dati (vol7d::voldatir & c.), hanno 6 dimensioni:
9414!! - anagrafica
9415!! - tempo
9416!! - livello verticale
9417!! - intervallo temporale (timerange)
9418!! - variabile di dati
9419!! - rete
9420!! - volumi di attributi di dati (vol7d::voldatiattrr & c.), hanno 7 dimensioni:
9421!! - anagrafica
9422!! - tempo
9423!! - livello verticale
9424!! - intervallo temporale (timerange)
9425!! - variabile di dati
9426!! - rete
9427!! - variabile di attributi delle variabili di dati
9428!!
9429!! Tutte le variabili sono inoltre disponibil1 in 5 tipi diversi:
9430!! - reale (abbreviato r)
9431!! - doppia precisione (abbreviato d)
9432!! - intero (abbreviato i)
9433!! - byte (abbreviato b)
9434!! - carattere (abbreviato c)
9435!!
9436!! Per ognuna delle dimensioni possibili, incluse le variabili e gli
9437!! attributi con i loro diversi tipi,
9438!! è definito un cosiddetto "vettore di descrittori", con un
9439!! numero di elementi pari all'estensione della dimensione stessa,
9440!! che contiene le informazioni necessarie a descrivere
9441!! gli elementi di quella dimensione.
9442!! In realtà l'utente non dovrà generalmente occuparsi di costruire
9443!! un oggetto vol7d con le proprie mani ma utilizzerà nella maggior parte
9444!! dei casi i metodi di importazione preconfezionati che importano dati da
9445!! DB-All.e (vol7d_dballe_class) o dal DB Oracle del SIM (vol7d_oraclesim_class).
9446!!
9447!!
9448!! Il programma esempio_v7d.f90 contiene un esempio elementare di uso
9449!! della classe vol7d:
9450!! \include esempio_v7d.f90
9451!!
9452!! \ingroup vol7d
9460USE io_units
9467IMPLICIT NONE
9468
9469
9470INTEGER, PARAMETER :: vol7d_maxdim_a = 3, vol7d_maxdim_aa = 4, &
9471 vol7d_maxdim_d = 6, vol7d_maxdim_ad = 7
9472
9473INTEGER, PARAMETER :: vol7d_ana_a=1 !< indice della dimensione "anagrafica" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
9474INTEGER, PARAMETER :: vol7d_var_a=2 !< indice della dimensione "variabile" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
9475INTEGER, PARAMETER :: vol7d_network_a=3 !< indice della dimensione "rete" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
9476INTEGER, PARAMETER :: vol7d_attr_a=4 !< indice della dimensione "attributo" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
9477INTEGER, PARAMETER :: vol7d_ana_d=1 !< indice della dimensione "anagrafica" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
9478INTEGER, PARAMETER :: vol7d_time_d=2 !< indice della dimensione "tempo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
9479INTEGER, PARAMETER :: vol7d_level_d=3 !< indice della dimensione "livello verticale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
9480INTEGER, PARAMETER :: vol7d_timerange_d=4 !< indice della dimensione "intervallo temporale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
9481INTEGER, PARAMETER :: vol7d_var_d=5 !< indice della dimensione "variabile" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
9482INTEGER, PARAMETER :: vol7d_network_d=6 !< indice della dimensione "rete" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
9483INTEGER, PARAMETER :: vol7d_attr_d=7 !< indice della dimensione "attributo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
9484INTEGER, PARAMETER :: vol7d_cdatalen=32
9485
9486TYPE vol7d_varmap
9487 INTEGER :: r, d, i, b, c
9488END TYPE vol7d_varmap
9489
9490!> Definisce un oggetto contenente i volumi anagrafica e dati e tutti
9491!! i descrittori delle loro dimensioni.
9493!> vettore descrittore della dimensione anagrafica
9494 TYPE(vol7d_ana),POINTER :: ana(:)
9495!> vettore descrittore della dimensione tempo
9496 TYPE(datetime),POINTER :: time(:)
9497!> vettore descrittore della dimensione livello verticale
9498 TYPE(vol7d_level),POINTER :: level(:)
9499!> vettore descrittore della dimensione intervallo temporale (timerange)
9500 TYPE(vol7d_timerange),POINTER :: timerange(:)
9501!> vettore descrittore della dimensione rete
9502 TYPE(vol7d_network),POINTER :: network(:)
9503!> vettore descrittore della dimensione variabile di anagrafica
9504 TYPE(vol7d_varvect) :: anavar
9505!> vettore descrittore della dimensione attributo delle variabili di anagrafica
9506 TYPE(vol7d_varvect) :: anaattr
9507!> vettore descrittore della dimensione variabile di anagrafica che ha tali attributi
9508 TYPE(vol7d_varvect) :: anavarattr
9509!> vettore descrittore della dimensione variabile di dati
9510 TYPE(vol7d_varvect) :: dativar
9511!> vettore descrittore della dimensione attributo delle variabili di dati
9512 TYPE(vol7d_varvect) :: datiattr
9513!> vettore descrittore della dimensione variabile di dati che ha tali attributi
9514 TYPE(vol7d_varvect) :: dativarattr
9515
9516!> volume di anagrafica a valori reali
9517 REAL,POINTER :: volanar(:,:,:)
9518!> volume di anagrafica a valori a doppia precisione
9519 DOUBLE PRECISION,POINTER :: volanad(:,:,:)
9520!> volume di anagrafica a valori interi
9521 INTEGER,POINTER :: volanai(:,:,:)
9522!> volume di anagrafica a valori byte
9523 INTEGER(kind=int_b),POINTER :: volanab(:,:,:)
9524!> volume di anagrafica a valori carattere
9525 CHARACTER(len=vol7d_cdatalen),POINTER :: volanac(:,:,:)
9526
9527!> volume di attributi di anagrafica a valori reali
9528 REAL,POINTER :: volanaattrr(:,:,:,:)
9529!> volume di attributi di anagrafica a valori a doppia precisione
9530 DOUBLE PRECISION,POINTER :: volanaattrd(:,:,:,:)
9531!> volume di attributi di anagrafica a valori interi
9532 INTEGER,POINTER :: volanaattri(:,:,:,:)
9533!> volume di attributi di anagrafica a valori byte
9534 INTEGER(kind=int_b),POINTER :: volanaattrb(:,:,:,:)
9535!> volume di attributi di anagrafica a valori carattere
9536 CHARACTER(len=vol7d_cdatalen),POINTER :: volanaattrc(:,:,:,:)
9537
9538!> volume di dati a valori reali
9539 REAL,POINTER :: voldatir(:,:,:,:,:,:) ! sono i dati
9540!> volume di dati a valori a doppia precisione
9541 DOUBLE PRECISION,POINTER :: voldatid(:,:,:,:,:,:)
9542!> volume di dati a valori interi
9543 INTEGER,POINTER :: voldatii(:,:,:,:,:,:)
9544!> volume di dati a valori byte
9545 INTEGER(kind=int_b),POINTER :: voldatib(:,:,:,:,:,:)
9546!> volume di dati a valori carattere
9547 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatic(:,:,:,:,:,:)
9548
9549!> volume di attributi di dati a valori reali
9550 REAL,POINTER :: voldatiattrr(:,:,:,:,:,:,:)
9551!> volume di attributi di dati a valori a doppia precisione
9552 DOUBLE PRECISION,POINTER :: voldatiattrd(:,:,:,:,:,:,:)
9553!> volume di attributi di dati a valori interi
9554 INTEGER,POINTER :: voldatiattri(:,:,:,:,:,:,:)
9555!> volume di attributi di dati a valori byte
9556 INTEGER(kind=int_b),POINTER :: voldatiattrb(:,:,:,:,:,:,:)
9557!> volume di attributi di dati a valori carattere
9558 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatiattrc(:,:,:,:,:,:,:)
9559
9560!> time definition; 0=time is reference time, 1=time is validity time
9561 integer :: time_definition
9562
9564
9565!> Costruttore per la classe vol7d.
9566!! Deve essere richiamato
9567!! per tutti gli oggetti di questo tipo definiti in un programma.
9569 MODULE PROCEDURE vol7d_init
9570END INTERFACE
9571
9572!> Distruttore per la classe vol7d.
9574 MODULE PROCEDURE vol7d_delete
9575END INTERFACE
9576
9577!> Scrittura su file.
9579 MODULE PROCEDURE vol7d_write_on_file
9580END INTERFACE
9581
9582!> Lettura da file.
9583INTERFACE import
9584 MODULE PROCEDURE vol7d_read_from_file
9585END INTERFACE
9586
9587!>Print object
9589 MODULE PROCEDURE vol7d_display, dat_display, dat_vect_display
9590END INTERFACE
9591
9592!>Represent data in a pretty string
9594 MODULE PROCEDURE to_char_dat
9595END INTERFACE
9596
9597!>doubleprecision data conversion
9599 MODULE PROCEDURE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
9600END INTERFACE
9601
9602!>real data conversion
9604 MODULE PROCEDURE realdatd,realdatr,realdati,realdatb,realdatc
9605END INTERFACE
9606
9607!>integer data conversion
9609 MODULE PROCEDURE integerdatd,integerdatr,integerdati,integerdatb,integerdatc
9610END INTERFACE
9611
9612!>copy object
9614 MODULE PROCEDURE vol7d_copy
9615END INTERFACE
9616
9617!> Test for a missing volume
9619 MODULE PROCEDURE vol7d_c_e
9620END INTERFACE
9621
9622!> Check for problems
9623!! return 0 if all check passed
9624!! print diagnostics with log4f
9626 MODULE PROCEDURE vol7d_check
9627END INTERFACE
9628
9629!> Reduce some dimensions (level and timerage) for semplification (rounding).
9630!! You can use this for simplify and use variables in computation like alchimia
9631!! where fields have to be on the same coordinate
9632!! It return real or character data only: if input is charcter data only it return character otherwise il return
9633!! all the data converted to real.
9634!! examples:
9635!! means in time for short periods and istantaneous values
9636!! 2 meter and surface levels
9637!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
9638!! will be taken (order is by icreasing var index).
9639!! You can use predefined values for classic semplification
9640!! almost_equal_levels and almost_equal_timeranges
9641!! The level or timerange in output will be defined by the first element of level and timerange list
9643 MODULE PROCEDURE v7d_rounding
9644END INTERFACE
9645
9646!!$INTERFACE get_volana
9647!!$ MODULE PROCEDURE vol7d_get_volanar, vol7d_get_volanad, vol7d_get_volanai, &
9648!!$ vol7d_get_volanab, vol7d_get_volanac
9649!!$END INTERFACE
9650!!$
9651!!$INTERFACE get_voldati
9652!!$ MODULE PROCEDURE vol7d_get_voldatir, vol7d_get_voldatid, vol7d_get_voldatii, &
9653!!$ vol7d_get_voldatib, vol7d_get_voldatic
9654!!$END INTERFACE
9655!!$
9656!!$INTERFACE get_volanaattr
9657!!$ MODULE PROCEDURE vol7d_get_volanaattrr, vol7d_get_volanaattrd, &
9658!!$ vol7d_get_volanaattri, vol7d_get_volanaattrb, vol7d_get_volanaattrc
9659!!$END INTERFACE
9660!!$
9661!!$INTERFACE get_voldatiattr
9662!!$ MODULE PROCEDURE vol7d_get_voldatiattrr, vol7d_get_voldatiattrd, &
9663!!$ vol7d_get_voldatiattri, vol7d_get_voldatiattrb, vol7d_get_voldatiattrc
9664!!$END INTERFACE
9665
9666PRIVATE vol7d_get_volr, vol7d_get_vold, vol7d_get_voli, vol7d_get_volb, &
9667 vol7d_get_volc, &
9668 volptr1dr, volptr2dr, volptr3dr, volptr4dr, volptr5dr, volptr6dr, volptr7dr, &
9669 volptr1dd, volptr2dd, volptr3dd, volptr4dd, volptr5dd, volptr6dd, volptr7dd, &
9670 volptr1di, volptr2di, volptr3di, volptr4di, volptr5di, volptr6di, volptr7di, &
9671 volptr1db, volptr2db, volptr3db, volptr4db, volptr5db, volptr6db, volptr7db, &
9672 volptr1dc, volptr2dc, volptr3dc, volptr4dc, volptr5dc, volptr6dc, volptr7dc, &
9673 vol7d_nullifyr, vol7d_nullifyd, vol7d_nullifyi, vol7d_nullifyb, vol7d_nullifyc, &
9674 vol7d_init, vol7d_delete, vol7d_write_on_file, vol7d_read_from_file, &
9675 vol7d_check_alloc_ana, vol7d_force_alloc_ana, &
9676 vol7d_check_alloc_dati, vol7d_force_alloc_dati, vol7d_force_alloc, &
9677 vol7d_display, dat_display, dat_vect_display, &
9678 to_char_dat, vol7d_check
9679
9680PRIVATE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
9681
9682PRIVATE vol7d_c_e
9683
9684CONTAINS
9685
9686
9687!> Inizializza un oggetto di tipo vol7d.
9688!! Non riceve alcun parametro tranne l'oggetto stesso. Attenzione, è necessario
9689!! comunque chiamare sempre il costruttore per evitare di avere dei puntatori in
9690!! uno stato indefinito.
9691SUBROUTINE vol7d_init(this,time_definition)
9692TYPE(vol7d),intent(out) :: this !< oggetto da inizializzare
9693INTEGER,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)
9694
9701
9702NULLIFY(this%ana, this%time, this%level, this%timerange, this%network)
9703
9704NULLIFY(this%volanar, this%volanaattrr, this%voldatir, this%voldatiattrr)
9705NULLIFY(this%volanad, this%volanaattrd, this%voldatid, this%voldatiattrd)
9706NULLIFY(this%volanai, this%volanaattri, this%voldatii, this%voldatiattri)
9707NULLIFY(this%volanab, this%volanaattrb, this%voldatib, this%voldatiattrb)
9708NULLIFY(this%volanac, this%volanaattrc, this%voldatic, this%voldatiattrc)
9709
9710if(present(time_definition)) then
9711 this%time_definition=time_definition
9712else
9713 this%time_definition=1 !default to validity time
9714end if
9715
9716END SUBROUTINE vol7d_init
9717
9718
9719!> Distrugge l'oggetto in maniera pulita, liberando l'eventuale memoria
9720!! dinamicamente allocata. Permette di distruggere la sola parte di dati
9721!! mantenendo l'anagrafica.
9722ELEMENTAL SUBROUTINE vol7d_delete(this, dataonly)
9723TYPE(vol7d),intent(inout) :: this !< oggetto da distruggere
9724LOGICAL, INTENT(in), OPTIONAL :: dataonly !< dealloca solo i dati, tenendo l'anagrafica, (default \c .FALSE.)
9725
9726
9727IF (.NOT. optio_log(dataonly)) THEN
9728 IF (ASSOCIATED(this%volanar)) DEALLOCATE(this%volanar)
9729 IF (ASSOCIATED(this%volanad)) DEALLOCATE(this%volanad)
9730 IF (ASSOCIATED(this%volanai)) DEALLOCATE(this%volanai)
9731 IF (ASSOCIATED(this%volanab)) DEALLOCATE(this%volanab)
9732 IF (ASSOCIATED(this%volanac)) DEALLOCATE(this%volanac)
9733 IF (ASSOCIATED(this%volanaattrr)) DEALLOCATE(this%volanaattrr)
9734 IF (ASSOCIATED(this%volanaattrd)) DEALLOCATE(this%volanaattrd)
9735 IF (ASSOCIATED(this%volanaattri)) DEALLOCATE(this%volanaattri)
9736 IF (ASSOCIATED(this%volanaattrb)) DEALLOCATE(this%volanaattrb)
9737 IF (ASSOCIATED(this%volanaattrc)) DEALLOCATE(this%volanaattrc)
9738ENDIF
9739IF (ASSOCIATED(this%voldatir)) DEALLOCATE(this%voldatir)
9740IF (ASSOCIATED(this%voldatid)) DEALLOCATE(this%voldatid)
9741IF (ASSOCIATED(this%voldatii)) DEALLOCATE(this%voldatii)
9742IF (ASSOCIATED(this%voldatib)) DEALLOCATE(this%voldatib)
9743IF (ASSOCIATED(this%voldatic)) DEALLOCATE(this%voldatic)
9744IF (ASSOCIATED(this%voldatiattrr)) DEALLOCATE(this%voldatiattrr)
9745IF (ASSOCIATED(this%voldatiattrd)) DEALLOCATE(this%voldatiattrd)
9746IF (ASSOCIATED(this%voldatiattri)) DEALLOCATE(this%voldatiattri)
9747IF (ASSOCIATED(this%voldatiattrb)) DEALLOCATE(this%voldatiattrb)
9748IF (ASSOCIATED(this%voldatiattrc)) DEALLOCATE(this%voldatiattrc)
9749
9750IF (.NOT. optio_log(dataonly)) THEN
9751 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
9752 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
9753ENDIF
9754IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
9755IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
9756IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
9757
9758IF (.NOT. optio_log(dataonly)) THEN
9762ENDIF
9766
9767END SUBROUTINE vol7d_delete
9768
9769
9770
9771integer function vol7d_check(this)
9772TYPE(vol7d),intent(in) :: this !< object to check
9773integer :: i,j,k,l,m,n
9774
9775vol7d_check=0
9776
9777if (associated(this%voldatii)) then
9778do i = 1,size(this%voldatii,1)
9779 do j = 1,size(this%voldatii,2)
9780 do k = 1,size(this%voldatii,3)
9781 do l = 1,size(this%voldatii,4)
9782 do m = 1,size(this%voldatii,5)
9783 do n = 1,size(this%voldatii,6)
9784 if (this%voldatii(i,j,k,l,m,n) /= this%voldatii(i,j,k,l,m,n) ) then
9785 CALL l4f_log(l4f_warn,"check: abnormal value at voldatii("&
9787 vol7d_check=1
9788 end if
9789 end do
9790 end do
9791 end do
9792 end do
9793 end do
9794end do
9795end if
9796
9797
9798if (associated(this%voldatir)) then
9799do i = 1,size(this%voldatir,1)
9800 do j = 1,size(this%voldatir,2)
9801 do k = 1,size(this%voldatir,3)
9802 do l = 1,size(this%voldatir,4)
9803 do m = 1,size(this%voldatir,5)
9804 do n = 1,size(this%voldatir,6)
9805 if (this%voldatir(i,j,k,l,m,n) /= this%voldatir(i,j,k,l,m,n) ) then
9806 CALL l4f_log(l4f_warn,"check: abnormal value at voldatir("&
9808 vol7d_check=2
9809 end if
9810 end do
9811 end do
9812 end do
9813 end do
9814 end do
9815end do
9816end if
9817
9818if (associated(this%voldatid)) then
9819do i = 1,size(this%voldatid,1)
9820 do j = 1,size(this%voldatid,2)
9821 do k = 1,size(this%voldatid,3)
9822 do l = 1,size(this%voldatid,4)
9823 do m = 1,size(this%voldatid,5)
9824 do n = 1,size(this%voldatid,6)
9825 if (this%voldatid(i,j,k,l,m,n) /= this%voldatid(i,j,k,l,m,n) ) then
9826 CALL l4f_log(l4f_warn,"check: abnormal value at voldatid("&
9828 vol7d_check=3
9829 end if
9830 end do
9831 end do
9832 end do
9833 end do
9834 end do
9835end do
9836end if
9837
9838if (associated(this%voldatib)) then
9839do i = 1,size(this%voldatib,1)
9840 do j = 1,size(this%voldatib,2)
9841 do k = 1,size(this%voldatib,3)
9842 do l = 1,size(this%voldatib,4)
9843 do m = 1,size(this%voldatib,5)
9844 do n = 1,size(this%voldatib,6)
9845 if (this%voldatib(i,j,k,l,m,n) /= this%voldatib(i,j,k,l,m,n) ) then
9846 CALL l4f_log(l4f_warn,"check: abnormal value at voldatib("&
9848 vol7d_check=4
9849 end if
9850 end do
9851 end do
9852 end do
9853 end do
9854 end do
9855end do
9856end if
9857
9858end function vol7d_check
9859
9860
9861
9862!TODO da completare ! aborta se i volumi sono allocati a dimensione 0
9863!> stampa a video una sintesi del contenuto
9864SUBROUTINE vol7d_display(this)
9865TYPE(vol7d),intent(in) :: this !< oggetto da visualizzare
9866integer :: i
9867
9868REAL :: rdat
9869DOUBLE PRECISION :: ddat
9870INTEGER :: idat
9871INTEGER(kind=int_b) :: bdat
9872CHARACTER(len=vol7d_cdatalen) :: cdat
9873
9874
9875print*,"<<<<<<<<<<<<<<<<<<< vol7d object >>>>>>>>>>>>>>>>>>>>"
9876if (this%time_definition == 0) then
9877 print*,"TIME DEFINITION: time is reference time"
9878else if (this%time_definition == 1) then
9879 print*,"TIME DEFINITION: time is validity time"
9880else if (this%time_definition == 2) then
9881 print*,"TIME DEFINITION: time is validity time, forecast range forced to 0"
9882else
9883 print*,"Time definition has a wrong walue:", this%time_definition
9884end if
9885
9886IF (ASSOCIATED(this%network))then
9887 print*,"---- network vector ----"
9888 print*,"elements=",size(this%network)
9889 do i=1, size(this%network)
9891 end do
9892end IF
9893
9894IF (ASSOCIATED(this%ana))then
9895 print*,"---- ana vector ----"
9896 print*,"elements=",size(this%ana)
9897 do i=1, size(this%ana)
9899 end do
9900end IF
9901
9902IF (ASSOCIATED(this%time))then
9903 print*,"---- time vector ----"
9904 print*,"elements=",size(this%time)
9905 do i=1, size(this%time)
9907 end do
9908end if
9909
9910IF (ASSOCIATED(this%level)) then
9911 print*,"---- level vector ----"
9912 print*,"elements=",size(this%level)
9913 do i =1,size(this%level)
9915 end do
9916end if
9917
9918IF (ASSOCIATED(this%timerange))then
9919 print*,"---- timerange vector ----"
9920 print*,"elements=",size(this%timerange)
9921 do i =1,size(this%timerange)
9923 end do
9924end if
9925
9926
9927print*,"---- ana vector ----"
9928print*,""
9929print*,"->>>>>>>>> anavar -"
9931print*,""
9932print*,"->>>>>>>>> anaattr -"
9934print*,""
9935print*,"->>>>>>>>> anavarattr -"
9937
9938print*,"-- ana data section (first point) --"
9939
9940idat=imiss
9941rdat=rmiss
9942ddat=dmiss
9943bdat=ibmiss
9944cdat=cmiss
9945
9946!ntime = MIN(SIZE(this%time),nprint)
9947!ntimerange = MIN(SIZE(this%timerange),nprint)
9948!nlevel = MIN(SIZE(this%level),nprint)
9949!nnetwork = MIN(SIZE(this%network),nprint)
9950!nana = MIN(SIZE(this%ana),nprint)
9951
9952IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0) THEN
9953if (associated(this%volanai)) then
9954 do i=1,size(this%anavar%i)
9955 idat=this%volanai(1,i,1)
9957 end do
9958end if
9959idat=imiss
9960
9961if (associated(this%volanar)) then
9962 do i=1,size(this%anavar%r)
9963 rdat=this%volanar(1,i,1)
9965 end do
9966end if
9967rdat=rmiss
9968
9969if (associated(this%volanad)) then
9970 do i=1,size(this%anavar%d)
9971 ddat=this%volanad(1,i,1)
9973 end do
9974end if
9975ddat=dmiss
9976
9977if (associated(this%volanab)) then
9978 do i=1,size(this%anavar%b)
9979 bdat=this%volanab(1,i,1)
9981 end do
9982end if
9983bdat=ibmiss
9984
9985if (associated(this%volanac)) then
9986 do i=1,size(this%anavar%c)
9987 cdat=this%volanac(1,i,1)
9989 end do
9990end if
9991cdat=cmiss
9992ENDIF
9993
9994print*,"---- data vector ----"
9995print*,""
9996print*,"->>>>>>>>> dativar -"
9998print*,""
9999print*,"->>>>>>>>> datiattr -"
10001print*,""
10002print*,"->>>>>>>>> dativarattr -"
10004
10005print*,"-- data data section (first point) --"
10006
10007idat=imiss
10008rdat=rmiss
10009ddat=dmiss
10010bdat=ibmiss
10011cdat=cmiss
10012
10013IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0 .AND. size(this%time) > 0 &
10014 .AND. size(this%level) > 0 .AND. size(this%timerange) > 0) THEN
10015if (associated(this%voldatii)) then
10016 do i=1,size(this%dativar%i)
10017 idat=this%voldatii(1,1,1,1,i,1)
10019 end do
10020end if
10021idat=imiss
10022
10023if (associated(this%voldatir)) then
10024 do i=1,size(this%dativar%r)
10025 rdat=this%voldatir(1,1,1,1,i,1)
10027 end do
10028end if
10029rdat=rmiss
10030
10031if (associated(this%voldatid)) then
10032 do i=1,size(this%dativar%d)
10033 ddat=this%voldatid(1,1,1,1,i,1)
10035 end do
10036end if
10037ddat=dmiss
10038
10039if (associated(this%voldatib)) then
10040 do i=1,size(this%dativar%b)
10041 bdat=this%voldatib(1,1,1,1,i,1)
10043 end do
10044end if
10045bdat=ibmiss
10046
10047if (associated(this%voldatic)) then
10048 do i=1,size(this%dativar%c)
10049 cdat=this%voldatic(1,1,1,1,i,1)
10051 end do
10052end if
10053cdat=cmiss
10054ENDIF
10055
10056print*,"<<<<<<<<<<<<<<<<<<< END vol7d object >>>>>>>>>>>>>>>>>>>>"
10057
10058END SUBROUTINE vol7d_display
10059
10060
10061!> stampa a video una sintesi del contenuto
10062SUBROUTINE dat_display(this,idat,rdat,ddat,bdat,cdat)
10063TYPE(vol7d_var),intent(in) :: this !< oggetto da visualizzare
10064!> real
10065REAL :: rdat
10066!> double precision
10067DOUBLE PRECISION :: ddat
10068!> integer
10069INTEGER :: idat
10070!> byte
10071INTEGER(kind=int_b) :: bdat
10072!> character
10073CHARACTER(len=*) :: cdat
10074
10075print *, to_char_dat(this,idat,rdat,ddat,bdat,cdat)
10076
10077end SUBROUTINE dat_display
10078
10079!> stampa a video una sintesi del contenuto
10080SUBROUTINE dat_vect_display(this,idat,rdat,ddat,bdat,cdat)
10081
10082TYPE(vol7d_var),intent(in) :: this(:) !< oggetto da visualizzare
10083!> real
10084REAL :: rdat(:)
10085!> double precision
10086DOUBLE PRECISION :: ddat(:)
10087!> integer
10088INTEGER :: idat(:)
10089!> byte
10090INTEGER(kind=int_b) :: bdat(:)
10091!> character
10092CHARACTER(len=*):: cdat(:)
10093
10094integer :: i
10095
10096do i =1,size(this)
10098end do
10099
10100end SUBROUTINE dat_vect_display
10101
10102
10103FUNCTION to_char_dat(this,idat,rdat,ddat,bdat,cdat)
10104#ifdef HAVE_DBALLE
10105USE dballef
10106#endif
10107TYPE(vol7d_var),INTENT(in) :: this
10108!> real
10109REAL :: rdat
10110!> double precision
10111DOUBLE PRECISION :: ddat
10112!> integer
10113INTEGER :: idat
10114!> byte
10115INTEGER(kind=int_b) :: bdat
10116!> character
10117CHARACTER(len=*) :: cdat
10118CHARACTER(len=80) :: to_char_dat
10119
10120CHARACTER(len=LEN(to_char_dat)) :: to_char_tmp
10121
10122
10123#ifdef HAVE_DBALLE
10124INTEGER :: handle, ier
10125
10126handle = 0
10127to_char_dat="VALUE: "
10128
10133
10135 ier = idba_messaggi(handle,"/dev/null", "w", "BUFR")
10136 ier = idba_spiegab(handle,this%btable,cdat,to_char_tmp)
10137 ier = idba_fatto(handle)
10138 to_char_dat=trim(to_char_dat)//" ;char> "//trim(to_char_tmp)
10139endif
10140
10141#else
10142
10143to_char_dat="VALUE: "
10149
10150#endif
10151
10152END FUNCTION to_char_dat
10153
10154
10155!> Tests whether anything has ever been assigned to a vol7d object
10156!! (.TRUE.) or it is as clean as after an init (.FALSE.).
10157FUNCTION vol7d_c_e(this) RESULT(c_e)
10158TYPE(vol7d), INTENT(in) :: this
10159
10160LOGICAL :: c_e
10161
10163 ASSOCIATED(this%level) .OR. ASSOCIATED(this%timerange) .OR. &
10164 ASSOCIATED(this%network) .OR. &
10165 ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
10166 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
10167 ASSOCIATED(this%anavar%c) .OR. &
10168 ASSOCIATED(this%anaattr%r) .OR. ASSOCIATED(this%anaattr%d) .OR. &
10169 ASSOCIATED(this%anaattr%i) .OR. ASSOCIATED(this%anaattr%b) .OR. &
10170 ASSOCIATED(this%anaattr%c) .OR. &
10171 ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
10172 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
10173 ASSOCIATED(this%dativar%c) .OR. &
10174 ASSOCIATED(this%datiattr%r) .OR. ASSOCIATED(this%datiattr%d) .OR. &
10175 ASSOCIATED(this%datiattr%i) .OR. ASSOCIATED(this%datiattr%b) .OR. &
10176 ASSOCIATED(this%datiattr%c)
10177
10178END FUNCTION vol7d_c_e
10179
10180
10181!> Metodo per allocare i descrittori delle 7 dimensioni.
10182!! Riceve un grande numero di parametri opzionali che
10183!! indicano quali descrittori allocare e con quale estensione;
10184!! i descrittori non specificati non vengono toccati.
10185!! Può essere quindi chiamato più volte allocando via via
10186!! descrittori relativi a dimensioni diverse.
10187!! Se un descrittore richiesto è già allocato, viene deallocato
10188!! (perdendone l'eventuale contenuto) e riallocato con l'estensione
10189!! richiesta.
10190!! Per i descrittori relativi a dimensioni che non siano variabili o attributi,
10191!! è possibile specificare l'estensione di una dimensione a 0,
10192!! in tal caso il descrittore viene comunque allocato con lunghezza nulla,
10193!! che è diverso da non allocarlo. Per i descrittori di variabili e attributi
10194!! passare un'estensione 0 equivale a non fornire il parametro.
10195!! Avere uno o più descrittori dimensionati con estensione nulla fa sì
10196!! che anche il volume dati successivamente allocato abbia estensione nulla;
10197!! sebbene ciò appaia inutile, un volume del genere può in realtà servire,
10198!! in associazione ai metodi ::vol7d_merge o ::vol7d_append per estendere
10199!! un volume esistente aggiungendo elementi in alcune dimensioni (quelle
10200!! a estensione non nulla, ovviamente) e mantenendo invariato tutto il resto.
10201!! Per quanto riguarda i descrittori delle dimensioni relative alle
10202!! variabili, la relativa estensione è specificata con la nomenclatura
10203!! \a n<x><y><z> dove <x> può valere:
10204!! - \a ana per variabili relative a voumi di anagrafica
10205!! - \a dati per variabili relative a voumi di dati
10206!!
10207!! <y> può valere:
10208!! - \a var per variabili
10209!! - \a attr per attributi
10210!! - \a varattr variabili aventi attributi nei volumi di attributi
10211!!
10212!! <z> può valere:
10213!! - \a r per variabili o attributi a valori reali
10214!! - \a d per variabili o attributi a valori a doppia precisione
10215!! - \a i per variabili o attributi a valori interi
10216!! - \a b per variabili o attributi a valori byte
10217!! - \a c per variabili o attributi a valori carattere
10218!!
10219SUBROUTINE vol7d_alloc(this, nana, ntime, nlevel, ntimerange, nnetwork, &
10220 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
10221 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
10222 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
10223 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
10224 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
10225 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc, &
10226 ini)
10227TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i descrittori
10228INTEGER,INTENT(in),OPTIONAL :: nana !< estensione della dimensione anagrafica
10229INTEGER,INTENT(in),OPTIONAL :: ntime !< estensione della dimensione tempo
10230INTEGER,INTENT(in),OPTIONAL :: nlevel !< estensione della dimensione livello varticale
10231INTEGER,INTENT(in),OPTIONAL :: ntimerange !< estensione della dimensione intervallo temporale (timerange)
10232INTEGER,INTENT(in),OPTIONAL :: nnetwork !< estensione della dimensione rete
10233!> estensione delle possibili dimensioni variabile
10234INTEGER,INTENT(in),OPTIONAL :: &
10235 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
10236 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
10237 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
10238 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
10239 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
10240 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc
10241LOGICAL,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
10242
10243INTEGER :: i
10244LOGICAL :: linit
10245
10246IF (PRESENT(ini)) THEN
10247 linit = ini
10248ELSE
10249 linit = .false.
10250ENDIF
10251
10252! Dimensioni principali
10253IF (PRESENT(nana)) THEN
10254 IF (nana >= 0) THEN
10255 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
10256 ALLOCATE(this%ana(nana))
10257 IF (linit) THEN
10258 DO i = 1, nana
10260 ENDDO
10261 ENDIF
10262 ENDIF
10263ENDIF
10264IF (PRESENT(ntime)) THEN
10265 IF (ntime >= 0) THEN
10266 IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
10267 ALLOCATE(this%time(ntime))
10268 IF (linit) THEN
10269 DO i = 1, ntime
10271 ENDDO
10272 ENDIF
10273 ENDIF
10274ENDIF
10275IF (PRESENT(nlevel)) THEN
10276 IF (nlevel >= 0) THEN
10277 IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
10278 ALLOCATE(this%level(nlevel))
10279 IF (linit) THEN
10280 DO i = 1, nlevel
10282 ENDDO
10283 ENDIF
10284 ENDIF
10285ENDIF
10286IF (PRESENT(ntimerange)) THEN
10287 IF (ntimerange >= 0) THEN
10288 IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
10289 ALLOCATE(this%timerange(ntimerange))
10290 IF (linit) THEN
10291 DO i = 1, ntimerange
10293 ENDDO
10294 ENDIF
10295 ENDIF
10296ENDIF
10297IF (PRESENT(nnetwork)) THEN
10298 IF (nnetwork >= 0) THEN
10299 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
10300 ALLOCATE(this%network(nnetwork))
10301 IF (linit) THEN
10302 DO i = 1, nnetwork
10304 ENDDO
10305 ENDIF
10306 ENDIF
10307ENDIF
10308! Dimensioni dei tipi delle variabili
10309CALL vol7d_varvect_alloc(this%anavar, nanavarr, nanavard, &
10310 nanavari, nanavarb, nanavarc, ini)
10311CALL vol7d_varvect_alloc(this%anaattr, nanaattrr, nanaattrd, &
10312 nanaattri, nanaattrb, nanaattrc, ini)
10313CALL vol7d_varvect_alloc(this%anavarattr, nanavarattrr, nanavarattrd, &
10314 nanavarattri, nanavarattrb, nanavarattrc, ini)
10315CALL vol7d_varvect_alloc(this%dativar, ndativarr, ndativard, &
10316 ndativari, ndativarb, ndativarc, ini)
10317CALL vol7d_varvect_alloc(this%datiattr, ndatiattrr, ndatiattrd, &
10318 ndatiattri, ndatiattrb, ndatiattrc, ini)
10319CALL vol7d_varvect_alloc(this%dativarattr, ndativarattrr, ndativarattrd, &
10320 ndativarattri, ndativarattrb, ndativarattrc, ini)
10321
10322END SUBROUTINE vol7d_alloc
10323
10324
10325FUNCTION vol7d_check_alloc_ana(this)
10326TYPE(vol7d),INTENT(in) :: this
10327LOGICAL :: vol7d_check_alloc_ana
10328
10329vol7d_check_alloc_ana = ASSOCIATED(this%ana) .AND. ASSOCIATED(this%network)
10330
10331END FUNCTION vol7d_check_alloc_ana
10332
10333SUBROUTINE vol7d_force_alloc_ana(this, ini)
10334TYPE(vol7d),INTENT(inout) :: this
10335LOGICAL,INTENT(in),OPTIONAL :: ini
10336
10337! Alloco i descrittori minimi per avere un volume di anagrafica
10338IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=1, ini=ini)
10339IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=1, ini=ini)
10340
10341END SUBROUTINE vol7d_force_alloc_ana
10342
10343
10344FUNCTION vol7d_check_alloc_dati(this)
10345TYPE(vol7d),INTENT(in) :: this
10346LOGICAL :: vol7d_check_alloc_dati
10347
10348vol7d_check_alloc_dati = vol7d_check_alloc_ana(this) .AND. &
10349 ASSOCIATED(this%time) .AND. ASSOCIATED(this%level) .AND. &
10350 ASSOCIATED(this%timerange)
10351
10352END FUNCTION vol7d_check_alloc_dati
10353
10354SUBROUTINE vol7d_force_alloc_dati(this, ini)
10355TYPE(vol7d),INTENT(inout) :: this
10356LOGICAL,INTENT(in),OPTIONAL :: ini
10357
10358! Alloco i descrittori minimi per avere un volume di dati
10359CALL vol7d_force_alloc_ana(this, ini)
10360IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=1, ini=ini)
10361IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=1, ini=ini)
10362IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=1, ini=ini)
10363
10364END SUBROUTINE vol7d_force_alloc_dati
10365
10366
10367SUBROUTINE vol7d_force_alloc(this)
10368TYPE(vol7d),INTENT(inout) :: this
10369
10370! If anything really not allocated yet, allocate with size 0
10371IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=0)
10372IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=0)
10373IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=0)
10374IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=0)
10375IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=0)
10376
10377END SUBROUTINE vol7d_force_alloc
10378
10379
10380FUNCTION vol7d_check_vol(this)
10381TYPE(vol7d),INTENT(in) :: this !< oggetto da controllare
10382LOGICAL :: vol7d_check_vol
10383
10384vol7d_check_vol = c_e(this)
10385
10386! Anagrafica
10387IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
10388 vol7d_check_vol = .false.
10389ENDIF
10390
10391IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
10392 vol7d_check_vol = .false.
10393ENDIF
10394
10395IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
10396 vol7d_check_vol = .false.
10397ENDIF
10398
10399IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
10400 vol7d_check_vol = .false.
10401ENDIF
10402
10403IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
10404 vol7d_check_vol = .false.
10405ENDIF
10406IF (ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
10407 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
10408 ASSOCIATED(this%anavar%c)) THEN
10409 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_ana(this)
10410ENDIF
10411
10412! Attributi dell'anagrafica
10413IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
10414 .NOT.ASSOCIATED(this%volanaattrr)) THEN
10415 vol7d_check_vol = .false.
10416ENDIF
10417
10418IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
10419 .NOT.ASSOCIATED(this%volanaattrd)) THEN
10420 vol7d_check_vol = .false.
10421ENDIF
10422
10423IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
10424 .NOT.ASSOCIATED(this%volanaattri)) THEN
10425 vol7d_check_vol = .false.
10426ENDIF
10427
10428IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
10429 .NOT.ASSOCIATED(this%volanaattrb)) THEN
10430 vol7d_check_vol = .false.
10431ENDIF
10432
10433IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
10434 .NOT.ASSOCIATED(this%volanaattrc)) THEN
10435 vol7d_check_vol = .false.
10436ENDIF
10437
10438! Dati
10439IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
10440 vol7d_check_vol = .false.
10441ENDIF
10442
10443IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
10444 vol7d_check_vol = .false.
10445ENDIF
10446
10447IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
10448 vol7d_check_vol = .false.
10449ENDIF
10450
10451IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
10452 vol7d_check_vol = .false.
10453ENDIF
10454
10455IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
10456 vol7d_check_vol = .false.
10457ENDIF
10458
10459! Attributi dei dati
10460IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
10461 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
10462 vol7d_check_vol = .false.
10463ENDIF
10464
10465IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
10466 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
10467 vol7d_check_vol = .false.
10468ENDIF
10469
10470IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
10471 .NOT.ASSOCIATED(this%voldatiattri)) THEN
10472 vol7d_check_vol = .false.
10473ENDIF
10474
10475IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
10476 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
10477 vol7d_check_vol = .false.
10478ENDIF
10479
10480IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
10481 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
10482 vol7d_check_vol = .false.
10483ENDIF
10484IF (ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
10485 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
10486 ASSOCIATED(this%dativar%c)) THEN
10487 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_dati(this)
10488ENDIF
10489
10490END FUNCTION vol7d_check_vol
10491
10492
10493!> Metodo per allocare i volumi richiesti di variabili e attributi per
10494!! anagrafica e dati.
10495!! Se alcuni dei descrittori relativi alle dimensioni anagrafica,
10496!! livello verticale, tempo, intervallo temporale (timerange), rete non sono
10497!! stati richiesti preventivamente con la ::vol7d_alloc, essi vengono allocati
10498!! automaticamente da questo metodo
10499!! con estensione di default pari a 1 (non 0!), questo significa, ad esempio,
10500!! che se prevedo di avere soli dati superficiali, cioè ad un solo livello
10501!! verticale, o una sola rete di stazioni, non devo preoccuparmi di
10502!! specificare questa informazione.
10503!! Tra i 20 possibili volumi allocabili
10504!! ((variabili,attributi)*(anagrafica,dati)*(r,d,i,b,c)=20)
10505!! saranno allocati solo quelli per cui è stato precedentemente richiesto il
10506!! corrispondente descrittore variabili/attributi con la ::vol7d_alloc.
10507SUBROUTINE vol7d_alloc_vol(this, ini, inivol)
10508TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i volumi
10509LOGICAL,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
10510LOGICAL,INTENT(in),OPTIONAL :: inivol !< se fornito e vale \c .TRUE., i volumi allocati saranno inizializzati a valore mancante
10511
10512LOGICAL :: linivol
10513
10514IF (PRESENT(inivol)) THEN
10515 linivol = inivol
10516ELSE
10517 linivol = .true.
10518ENDIF
10519
10520! Anagrafica
10521IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
10522 CALL vol7d_force_alloc_ana(this, ini)
10523 ALLOCATE(this%volanar(SIZE(this%ana), SIZE(this%anavar%r), SIZE(this%network)))
10524 IF (linivol) this%volanar(:,:,:) = rmiss
10525ENDIF
10526
10527IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
10528 CALL vol7d_force_alloc_ana(this, ini)
10529 ALLOCATE(this%volanad(SIZE(this%ana), SIZE(this%anavar%d), SIZE(this%network)))
10530 IF (linivol) this%volanad(:,:,:) = rdmiss
10531ENDIF
10532
10533IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
10534 CALL vol7d_force_alloc_ana(this, ini)
10535 ALLOCATE(this%volanai(SIZE(this%ana), SIZE(this%anavar%i), SIZE(this%network)))
10536 IF (linivol) this%volanai(:,:,:) = imiss
10537ENDIF
10538
10539IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
10540 CALL vol7d_force_alloc_ana(this, ini)
10541 ALLOCATE(this%volanab(SIZE(this%ana), SIZE(this%anavar%b), SIZE(this%network)))
10542 IF (linivol) this%volanab(:,:,:) = ibmiss
10543ENDIF
10544
10545IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
10546 CALL vol7d_force_alloc_ana(this, ini)
10547 ALLOCATE(this%volanac(SIZE(this%ana), SIZE(this%anavar%c), SIZE(this%network)))
10548 IF (linivol) this%volanac(:,:,:) = cmiss
10549ENDIF
10550
10551! Attributi dell'anagrafica
10552IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
10553 .NOT.ASSOCIATED(this%volanaattrr)) THEN
10554 CALL vol7d_force_alloc_ana(this, ini)
10555 ALLOCATE(this%volanaattrr(SIZE(this%ana), SIZE(this%anavarattr%r), &
10556 SIZE(this%network), SIZE(this%anaattr%r)))
10557 IF (linivol) this%volanaattrr(:,:,:,:) = rmiss
10558ENDIF
10559
10560IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
10561 .NOT.ASSOCIATED(this%volanaattrd)) THEN
10562 CALL vol7d_force_alloc_ana(this, ini)
10563 ALLOCATE(this%volanaattrd(SIZE(this%ana), SIZE(this%anavarattr%d), &
10564 SIZE(this%network), SIZE(this%anaattr%d)))
10565 IF (linivol) this%volanaattrd(:,:,:,:) = rdmiss
10566ENDIF
10567
10568IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
10569 .NOT.ASSOCIATED(this%volanaattri)) THEN
10570 CALL vol7d_force_alloc_ana(this, ini)
10571 ALLOCATE(this%volanaattri(SIZE(this%ana), SIZE(this%anavarattr%i), &
10572 SIZE(this%network), SIZE(this%anaattr%i)))
10573 IF (linivol) this%volanaattri(:,:,:,:) = imiss
10574ENDIF
10575
10576IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
10577 .NOT.ASSOCIATED(this%volanaattrb)) THEN
10578 CALL vol7d_force_alloc_ana(this, ini)
10579 ALLOCATE(this%volanaattrb(SIZE(this%ana), SIZE(this%anavarattr%b), &
10580 SIZE(this%network), SIZE(this%anaattr%b)))
10581 IF (linivol) this%volanaattrb(:,:,:,:) = ibmiss
10582ENDIF
10583
10584IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
10585 .NOT.ASSOCIATED(this%volanaattrc)) THEN
10586 CALL vol7d_force_alloc_ana(this, ini)
10587 ALLOCATE(this%volanaattrc(SIZE(this%ana), SIZE(this%anavarattr%c), &
10588 SIZE(this%network), SIZE(this%anaattr%c)))
10589 IF (linivol) this%volanaattrc(:,:,:,:) = cmiss
10590ENDIF
10591
10592! Dati
10593IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
10594 CALL vol7d_force_alloc_dati(this, ini)
10595 ALLOCATE(this%voldatir(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10596 SIZE(this%timerange), SIZE(this%dativar%r), SIZE(this%network)))
10597 IF (linivol) this%voldatir(:,:,:,:,:,:) = rmiss
10598ENDIF
10599
10600IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
10601 CALL vol7d_force_alloc_dati(this, ini)
10602 ALLOCATE(this%voldatid(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10603 SIZE(this%timerange), SIZE(this%dativar%d), SIZE(this%network)))
10604 IF (linivol) this%voldatid(:,:,:,:,:,:) = rdmiss
10605ENDIF
10606
10607IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
10608 CALL vol7d_force_alloc_dati(this, ini)
10609 ALLOCATE(this%voldatii(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10610 SIZE(this%timerange), SIZE(this%dativar%i), SIZE(this%network)))
10611 IF (linivol) this%voldatii(:,:,:,:,:,:) = imiss
10612ENDIF
10613
10614IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
10615 CALL vol7d_force_alloc_dati(this, ini)
10616 ALLOCATE(this%voldatib(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10617 SIZE(this%timerange), SIZE(this%dativar%b), SIZE(this%network)))
10618 IF (linivol) this%voldatib(:,:,:,:,:,:) = ibmiss
10619ENDIF
10620
10621IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
10622 CALL vol7d_force_alloc_dati(this, ini)
10623 ALLOCATE(this%voldatic(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10624 SIZE(this%timerange), SIZE(this%dativar%c), SIZE(this%network)))
10625 IF (linivol) this%voldatic(:,:,:,:,:,:) = cmiss
10626ENDIF
10627
10628! Attributi dei dati
10629IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
10630 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
10631 CALL vol7d_force_alloc_dati(this, ini)
10632 ALLOCATE(this%voldatiattrr(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10633 SIZE(this%timerange), SIZE(this%dativarattr%r), SIZE(this%network), &
10634 SIZE(this%datiattr%r)))
10635 IF (linivol) this%voldatiattrr(:,:,:,:,:,:,:) = rmiss
10636ENDIF
10637
10638IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
10639 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
10640 CALL vol7d_force_alloc_dati(this, ini)
10641 ALLOCATE(this%voldatiattrd(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10642 SIZE(this%timerange), SIZE(this%dativarattr%d), SIZE(this%network), &
10643 SIZE(this%datiattr%d)))
10644 IF (linivol) this%voldatiattrd(:,:,:,:,:,:,:) = rdmiss
10645ENDIF
10646
10647IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
10648 .NOT.ASSOCIATED(this%voldatiattri)) THEN
10649 CALL vol7d_force_alloc_dati(this, ini)
10650 ALLOCATE(this%voldatiattri(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10651 SIZE(this%timerange), SIZE(this%dativarattr%i), SIZE(this%network), &
10652 SIZE(this%datiattr%i)))
10653 IF (linivol) this%voldatiattri(:,:,:,:,:,:,:) = imiss
10654ENDIF
10655
10656IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
10657 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
10658 CALL vol7d_force_alloc_dati(this, ini)
10659 ALLOCATE(this%voldatiattrb(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10660 SIZE(this%timerange), SIZE(this%dativarattr%b), SIZE(this%network), &
10661 SIZE(this%datiattr%b)))
10662 IF (linivol) this%voldatiattrb(:,:,:,:,:,:,:) = ibmiss
10663ENDIF
10664
10665IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
10666 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
10667 CALL vol7d_force_alloc_dati(this, ini)
10668 ALLOCATE(this%voldatiattrc(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10669 SIZE(this%timerange), SIZE(this%dativarattr%c), SIZE(this%network), &
10670 SIZE(this%datiattr%c)))
10671 IF (linivol) this%voldatiattrc(:,:,:,:,:,:,:) = cmiss
10672ENDIF
10673
10674! Catch-all method
10675CALL vol7d_force_alloc(this)
10676
10677! Creo gli indici var-attr
10678
10679#ifdef DEBUG
10680CALL l4f_log(l4f_debug,"calling: vol7d_set_attr_ind")
10681#endif
10682
10683CALL vol7d_set_attr_ind(this)
10684
10685
10686
10687END SUBROUTINE vol7d_alloc_vol
10688
10689
10690!> Metodo per creare gli indici che associano le variabili aventi attributo
10691!! alle variabili nei relativi descrittori.
10692!! Ha senso chiamare questo metodo solo dopo che i descrittori delle variabili
10693!! e degli attributi desiderati sono stati allocati ed è stato assegnato un
10694!! valore ai relativi membri btable (vedi vol7d_var_class::vol7d_var), se
10695!! i descrittori non sono stati allocati o assegnati, il metodo non fa niente.
10696SUBROUTINE vol7d_set_attr_ind(this)
10697TYPE(vol7d),INTENT(inout) :: this !< oggetto in cui creare gli indici
10698
10699INTEGER :: i
10700
10701! real
10702IF (ASSOCIATED(this%dativar%r)) THEN
10703 IF (ASSOCIATED(this%dativarattr%r)) THEN
10704 DO i = 1, SIZE(this%dativar%r)
10705 this%dativar%r(i)%r = &
10706 firsttrue(this%dativar%r(i)%btable == this%dativarattr%r(:)%btable)
10707 ENDDO
10708 ENDIF
10709
10710 IF (ASSOCIATED(this%dativarattr%d)) THEN
10711 DO i = 1, SIZE(this%dativar%r)
10712 this%dativar%r(i)%d = &
10713 firsttrue(this%dativar%r(i)%btable == this%dativarattr%d(:)%btable)
10714 ENDDO
10715 ENDIF
10716
10717 IF (ASSOCIATED(this%dativarattr%i)) THEN
10718 DO i = 1, SIZE(this%dativar%r)
10719 this%dativar%r(i)%i = &
10720 firsttrue(this%dativar%r(i)%btable == this%dativarattr%i(:)%btable)
10721 ENDDO
10722 ENDIF
10723
10724 IF (ASSOCIATED(this%dativarattr%b)) THEN
10725 DO i = 1, SIZE(this%dativar%r)
10726 this%dativar%r(i)%b = &
10727 firsttrue(this%dativar%r(i)%btable == this%dativarattr%b(:)%btable)
10728 ENDDO
10729 ENDIF
10730
10731 IF (ASSOCIATED(this%dativarattr%c)) THEN
10732 DO i = 1, SIZE(this%dativar%r)
10733 this%dativar%r(i)%c = &
10734 firsttrue(this%dativar%r(i)%btable == this%dativarattr%c(:)%btable)
10735 ENDDO
10736 ENDIF
10737ENDIF
10738! double
10739IF (ASSOCIATED(this%dativar%d)) THEN
10740 IF (ASSOCIATED(this%dativarattr%r)) THEN
10741 DO i = 1, SIZE(this%dativar%d)
10742 this%dativar%d(i)%r = &
10743 firsttrue(this%dativar%d(i)%btable == this%dativarattr%r(:)%btable)
10744 ENDDO
10745 ENDIF
10746
10747 IF (ASSOCIATED(this%dativarattr%d)) THEN
10748 DO i = 1, SIZE(this%dativar%d)
10749 this%dativar%d(i)%d = &
10750 firsttrue(this%dativar%d(i)%btable == this%dativarattr%d(:)%btable)
10751 ENDDO
10752 ENDIF
10753
10754 IF (ASSOCIATED(this%dativarattr%i)) THEN
10755 DO i = 1, SIZE(this%dativar%d)
10756 this%dativar%d(i)%i = &
10757 firsttrue(this%dativar%d(i)%btable == this%dativarattr%i(:)%btable)
10758 ENDDO
10759 ENDIF
10760
10761 IF (ASSOCIATED(this%dativarattr%b)) THEN
10762 DO i = 1, SIZE(this%dativar%d)
10763 this%dativar%d(i)%b = &
10764 firsttrue(this%dativar%d(i)%btable == this%dativarattr%b(:)%btable)
10765 ENDDO
10766 ENDIF
10767
10768 IF (ASSOCIATED(this%dativarattr%c)) THEN
10769 DO i = 1, SIZE(this%dativar%d)
10770 this%dativar%d(i)%c = &
10771 firsttrue(this%dativar%d(i)%btable == this%dativarattr%c(:)%btable)
10772 ENDDO
10773 ENDIF
10774ENDIF
10775! integer
10776IF (ASSOCIATED(this%dativar%i)) THEN
10777 IF (ASSOCIATED(this%dativarattr%r)) THEN
10778 DO i = 1, SIZE(this%dativar%i)
10779 this%dativar%i(i)%r = &
10780 firsttrue(this%dativar%i(i)%btable == this%dativarattr%r(:)%btable)
10781 ENDDO
10782 ENDIF
10783
10784 IF (ASSOCIATED(this%dativarattr%d)) THEN
10785 DO i = 1, SIZE(this%dativar%i)
10786 this%dativar%i(i)%d = &
10787 firsttrue(this%dativar%i(i)%btable == this%dativarattr%d(:)%btable)
10788 ENDDO
10789 ENDIF
10790
10791 IF (ASSOCIATED(this%dativarattr%i)) THEN
10792 DO i = 1, SIZE(this%dativar%i)
10793 this%dativar%i(i)%i = &
10794 firsttrue(this%dativar%i(i)%btable == this%dativarattr%i(:)%btable)
10795 ENDDO
10796 ENDIF
10797
10798 IF (ASSOCIATED(this%dativarattr%b)) THEN
10799 DO i = 1, SIZE(this%dativar%i)
10800 this%dativar%i(i)%b = &
10801 firsttrue(this%dativar%i(i)%btable == this%dativarattr%b(:)%btable)
10802 ENDDO
10803 ENDIF
10804
10805 IF (ASSOCIATED(this%dativarattr%c)) THEN
10806 DO i = 1, SIZE(this%dativar%i)
10807 this%dativar%i(i)%c = &
10808 firsttrue(this%dativar%i(i)%btable == this%dativarattr%c(:)%btable)
10809 ENDDO
10810 ENDIF
10811ENDIF
10812! byte
10813IF (ASSOCIATED(this%dativar%b)) THEN
10814 IF (ASSOCIATED(this%dativarattr%r)) THEN
10815 DO i = 1, SIZE(this%dativar%b)
10816 this%dativar%b(i)%r = &
10817 firsttrue(this%dativar%b(i)%btable == this%dativarattr%r(:)%btable)
10818 ENDDO
10819 ENDIF
10820
10821 IF (ASSOCIATED(this%dativarattr%d)) THEN
10822 DO i = 1, SIZE(this%dativar%b)
10823 this%dativar%b(i)%d = &
10824 firsttrue(this%dativar%b(i)%btable == this%dativarattr%d(:)%btable)
10825 ENDDO
10826 ENDIF
10827
10828 IF (ASSOCIATED(this%dativarattr%i)) THEN
10829 DO i = 1, SIZE(this%dativar%b)
10830 this%dativar%b(i)%i = &
10831 firsttrue(this%dativar%b(i)%btable == this%dativarattr%i(:)%btable)
10832 ENDDO
10833 ENDIF
10834
10835 IF (ASSOCIATED(this%dativarattr%b)) THEN
10836 DO i = 1, SIZE(this%dativar%b)
10837 this%dativar%b(i)%b = &
10838 firsttrue(this%dativar%b(i)%btable == this%dativarattr%b(:)%btable)
10839 ENDDO
10840 ENDIF
10841
10842 IF (ASSOCIATED(this%dativarattr%c)) THEN
10843 DO i = 1, SIZE(this%dativar%b)
10844 this%dativar%b(i)%c = &
10845 firsttrue(this%dativar%b(i)%btable == this%dativarattr%c(:)%btable)
10846 ENDDO
10847 ENDIF
10848ENDIF
10849! character
10850IF (ASSOCIATED(this%dativar%c)) THEN
10851 IF (ASSOCIATED(this%dativarattr%r)) THEN
10852 DO i = 1, SIZE(this%dativar%c)
10853 this%dativar%c(i)%r = &
10854 firsttrue(this%dativar%c(i)%btable == this%dativarattr%r(:)%btable)
10855 ENDDO
10856 ENDIF
10857
10858 IF (ASSOCIATED(this%dativarattr%d)) THEN
10859 DO i = 1, SIZE(this%dativar%c)
10860 this%dativar%c(i)%d = &
10861 firsttrue(this%dativar%c(i)%btable == this%dativarattr%d(:)%btable)
10862 ENDDO
10863 ENDIF
10864
10865 IF (ASSOCIATED(this%dativarattr%i)) THEN
10866 DO i = 1, SIZE(this%dativar%c)
10867 this%dativar%c(i)%i = &
10868 firsttrue(this%dativar%c(i)%btable == this%dativarattr%i(:)%btable)
10869 ENDDO
10870 ENDIF
10871
10872 IF (ASSOCIATED(this%dativarattr%b)) THEN
10873 DO i = 1, SIZE(this%dativar%c)
10874 this%dativar%c(i)%b = &
10875 firsttrue(this%dativar%c(i)%btable == this%dativarattr%b(:)%btable)
10876 ENDDO
10877 ENDIF
10878
10879 IF (ASSOCIATED(this%dativarattr%c)) THEN
10880 DO i = 1, SIZE(this%dativar%c)
10881 this%dativar%c(i)%c = &
10882 firsttrue(this%dativar%c(i)%btable == this%dativarattr%c(:)%btable)
10883 ENDDO
10884 ENDIF
10885ENDIF
10886
10887END SUBROUTINE vol7d_set_attr_ind
10888
10889
10890!> Metodo per fondere 2 oggetti vol7d.
10891!! Il secondo volume viene accodato al primo e poi distrutto, si veda
10892!! quindi la descrizione di ::vol7d_append. Se uno degli oggetti \a
10893!! this o \a that sono vuoti non perde tempo inutile,
10894SUBROUTINE vol7d_merge(this, that, sort, bestdata, &
10895 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
10896TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, alla fine conterrà il risultato della fusione
10897TYPE(vol7d),INTENT(INOUT) :: that !< secondo oggetto in ingresso, alla fine sarà distrutto
10898LOGICAL,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
10899LOGICAL,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
10900LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple ! experimental, please do not use outside the library now
10901
10902TYPE(vol7d) :: v7d_clean
10903
10904
10906 this = that
10908 that = v7d_clean ! destroy that without deallocating
10909ELSE ! Append that to this and destroy that
10911 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
10913ENDIF
10914
10915END SUBROUTINE vol7d_merge
10916
10917
10918!> Metodo per accodare un oggetto vol7d ad un altro.
10919!! Si tratta di un metodo molto potente e versatile;
10920!! i descrittori delle dimensioni del volume finale conterranno i valori
10921!! dei corrispondenti descrittori del primo e del secondo volume
10922!! e i volumi di anagrafica e dati conterranno i valori dei due volumi
10923!! ai posti giusti, e valori mancanti per le nuove combinazioni che
10924!! eventualmente si verranno a creare.
10925!! Se i volumi multidimensionali di anagrafica e/o dati dei 2 oggetti
10926!! hanno un'intersezione non nulla, negli elementi comuni il volume finale
10927!! conterrà il corrispondente elemento del \b secondo volume.
10928!! Attenzione che, durante l'esecuzione del metodo, la memoria richiesta è
10929!! pari alla memoria complessiva occupata dai 2 volumi iniziali più
10930!! la memoria complessiva del volume finale, per cui, nel caso di volumi grandi,
10931!! ci potrebbero essere problemi di esaurimento della memoria centrale.
10932!! Se l'oggetto \a that è vuoto non perde tempo inutile,
10933!!
10934!! \todo nel caso di elementi comuni inserire la possibiità (opzionale per
10935!! non penalizzare le prestazioni quando ciò non serve) di effettuare una scelta
10936!! più ragionata dell'elemento da tenere, almeno controllando i dati mancanti
10937!! se non le flag di qualità
10938!!
10939!! \todo "rateizzare" l'allocazione dei volumi per ridurre l'occupazione di
10940!! memoria nel caso siano allocati contemporaneamente volumi di variabili e
10941!! di attributi o più volumi di tipi diversi
10942!!
10943!! \todo il parametro \a that è dichiarato \a INOUT perché la vol7d_alloc_vol
10944!! può modificarlo, bisognerebbe implementare una vol7d_check_vol che restituisca
10945!! errore anziché usare la vol7d_alloc_vol.
10946SUBROUTINE vol7d_append(this, that, sort, bestdata, &
10947 ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple)
10948TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, a cui sarà accodato il secondo
10949TYPE(vol7d),INTENT(IN) :: that !< secondo oggetto in ingresso, non viene modificato dal metodo
10950LOGICAL,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
10951! experimental, please do not use outside the library now, they force the use
10952! of a simplified mapping algorithm which is valid only whene the dimension
10953! content is the same in both volumes , or when one of them is empty
10954LOGICAL,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
10955LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple
10956
10957
10958TYPE(vol7d) :: v7dtmp
10959LOGICAL :: lsort, lbestdata
10960INTEGER,POINTER :: remapt1(:), remapt2(:), remaptr1(:), remaptr2(:), &
10961 remapl1(:), remapl2(:), remapa1(:), remapa2(:), remapn1(:), remapn2(:)
10962
10964IF (.NOT.vol7d_check_vol(that)) RETURN ! be safe
10967 RETURN
10968ENDIF
10969
10970IF (this%time_definition /= that%time_definition) THEN
10971 CALL l4f_log(l4f_fatal, &
10972 'in vol7d_append, cannot append volumes with different &
10973 &time definition')
10974 CALL raise_fatal_error()
10975ENDIF
10976
10977! Completo l'allocazione per avere volumi a norma
10978CALL vol7d_alloc_vol(this)
10979
10983
10984! Calcolo le mappature tra volumi vecchi e volume nuovo
10985! I puntatori remap* vengono tutti o allocati o nullificati
10986IF (optio_log(ltimesimple)) THEN
10987 CALL vol7d_remap2simple_datetime(this%time, that%time, v7dtmp%time, &
10988 lsort, remapt1, remapt2)
10989ELSE
10990 CALL vol7d_remap2_datetime(this%time, that%time, v7dtmp%time, &
10991 lsort, remapt1, remapt2)
10992ENDIF
10993IF (optio_log(ltimerangesimple)) THEN
10994 CALL vol7d_remap2simple_vol7d_timerange(this%timerange, that%timerange, &
10995 v7dtmp%timerange, lsort, remaptr1, remaptr2)
10996ELSE
10997 CALL vol7d_remap2_vol7d_timerange(this%timerange, that%timerange, &
10998 v7dtmp%timerange, lsort, remaptr1, remaptr2)
10999ENDIF
11000IF (optio_log(llevelsimple)) THEN
11001 CALL vol7d_remap2simple_vol7d_level(this%level, that%level, v7dtmp%level, &
11002 lsort, remapl1, remapl2)
11003ELSE
11004 CALL vol7d_remap2_vol7d_level(this%level, that%level, v7dtmp%level, &
11005 lsort, remapl1, remapl2)
11006ENDIF
11007IF (optio_log(lanasimple)) THEN
11008 CALL vol7d_remap2simple_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
11009 .false., remapa1, remapa2)
11010ELSE
11011 CALL vol7d_remap2_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
11012 .false., remapa1, remapa2)
11013ENDIF
11014IF (optio_log(lnetworksimple)) THEN
11015 CALL vol7d_remap2simple_vol7d_network(this%network, that%network, v7dtmp%network, &
11016 .false., remapn1, remapn2)
11017ELSE
11018 CALL vol7d_remap2_vol7d_network(this%network, that%network, v7dtmp%network, &
11019 .false., remapn1, remapn2)
11020ENDIF
11021
11022! Faccio la fusione fisica dei volumi
11023CALL vol7d_merge_finalr(this, that, v7dtmp, &
11024 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
11025 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
11026CALL vol7d_merge_finald(this, that, v7dtmp, &
11027 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
11028 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
11029CALL vol7d_merge_finali(this, that, v7dtmp, &
11030 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
11031 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
11032CALL vol7d_merge_finalb(this, that, v7dtmp, &
11033 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
11034 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
11035CALL vol7d_merge_finalc(this, that, v7dtmp, &
11036 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
11037 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
11038
11039! Dealloco i vettori di rimappatura
11040IF (ASSOCIATED(remapt1)) DEALLOCATE(remapt1)
11041IF (ASSOCIATED(remapt2)) DEALLOCATE(remapt2)
11042IF (ASSOCIATED(remaptr1)) DEALLOCATE(remaptr1)
11043IF (ASSOCIATED(remaptr2)) DEALLOCATE(remaptr2)
11044IF (ASSOCIATED(remapl1)) DEALLOCATE(remapl1)
11045IF (ASSOCIATED(remapl2)) DEALLOCATE(remapl2)
11046IF (ASSOCIATED(remapa1)) DEALLOCATE(remapa1)
11047IF (ASSOCIATED(remapa2)) DEALLOCATE(remapa2)
11048IF (ASSOCIATED(remapn1)) DEALLOCATE(remapn1)
11049IF (ASSOCIATED(remapn2)) DEALLOCATE(remapn2)
11050
11051! Distruggo il vecchio volume e assegno il nuovo a this
11053this = v7dtmp
11054! Ricreo gli indici var-attr
11055CALL vol7d_set_attr_ind(this)
11056
11057END SUBROUTINE vol7d_append
11058
11059
11060!> Metodo per creare una copia completa e indipendente di un oggetto vol7d.
11061!! Questo metodo crea un duplicato di tutti i membri di un oggetto vol7d,
11062!! con la possibilità di rielaborarlo durante la copia. Se l'oggetto da copiare
11063!! è vuoto non perde tempo inutile.
11064!! Attenzione, il codice:
11065!! \code
11066!! USE vol7d_class
11067!! TYPE(vol7d) :: vol1, vol2
11068!! CALL init(vol1)
11069!! CALL init(vol2)
11070!! ... ! riempio vol1
11071!! vol2 = vol1
11072!! \endcode
11073!! fa una cosa diversa rispetto a:
11074!! \code
11075!! USE vol7d_class
11076!! TYPE(vol7d) :: vol1, vol2
11077!! CALL init(vol1)
11078!! CALL init(vol2)
11079!! ... ! riempio vol1
11080!! CALL vol7d_copy(vol1, vol2)
11081!! \endcode
11082!! nel primo caso, infatti, l'operatore di assegnazione copia solo i componenti
11083!! statici di \a vol1 nei corrispondenti elementi di \a vol2, mentre i componenti che
11084!! sono allocati dinamicamente (cioè quelli che in ::vol7d hanno l'attributo
11085!! \c POINTER, in pratica quasi tutti) non vengono duplicati, ma per essi vol2
11086!! conterrà un puntatore al corrispondente elemento a cui già punta vol1, e quindi
11087!! eventuali cambiamenti al contenuto di uno dei due oggetti influenzerà il
11088!! contenuto dell'altro; nel secondo caso, invece, vol1 e vol2 sono, dopo la
11089!! vol7d_copy, 2 istanze
11090!! completamente indipendenti, ma uguali tra loro per contenuto, della classe
11091!! vol7d, e quindi hanno vita indipendente.
11092SUBROUTINE vol7d_copy(this, that, sort, unique, miss, &
11093 lsort_time, lsort_timerange, lsort_level, &
11094 ltime, ltimerange, llevel, lana, lnetwork, &
11095 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
11096 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
11097 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
11098 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
11099 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
11100 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
11101TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
11102TYPE(vol7d),INTENT(INOUT) :: that !< oggetto destinazione
11103LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
11104LOGICAL,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)
11105LOGICAL,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
11106LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
11107LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
11108LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
11109!> se fornito, deve essere un vettore logico della stessa lunghezza di
11110!! this%time indicante quali elementi della dimensione \a time
11111!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
11112!! nel volume copiato; in alternativa può essere un vettore di
11113!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
11114!! gli elementi (utile principalmente per le variabili); è compatibile
11115!! col parametro \a miss
11116LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
11117!> come il precedente per la dimensione \a timerange
11118LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:)
11119!> come il precedente per la dimensione \a level
11120LOGICAL,INTENT(IN),OPTIONAL :: llevel(:)
11121!> come il precedente per la dimensione \a ana
11122LOGICAL,INTENT(IN),OPTIONAL :: lana(:)
11123!> come il precedente per la dimensione \a network
11124LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:)
11125!> come il precedente per tutte le possibili dimensioni variabile
11126LOGICAL,INTENT(in),OPTIONAL :: &
11127 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
11128 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
11129 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
11130 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
11131 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
11132 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
11133
11134LOGICAL :: lsort, lunique, lmiss
11135INTEGER,POINTER :: remapt(:), remaptr(:), remapl(:), remapa(:), remapn(:)
11136
11139IF (.NOT.vol7d_check_vol(this)) RETURN ! be safe
11140
11144
11145! Calcolo le mappature tra volume vecchio e volume nuovo
11146! I puntatori remap* vengono tutti o allocati o nullificati
11147CALL vol7d_remap1_datetime(this%time, that%time, &
11148 lsort.OR.optio_log(lsort_time), lunique, lmiss, remapt, ltime)
11149CALL vol7d_remap1_vol7d_timerange(this%timerange, that%timerange, &
11150 lsort.OR.optio_log(lsort_timerange), lunique, lmiss, remaptr, ltimerange)
11151CALL vol7d_remap1_vol7d_level(this%level, that%level, &
11152 lsort.OR.optio_log(lsort_level), lunique, lmiss, remapl, llevel)
11153CALL vol7d_remap1_vol7d_ana(this%ana, that%ana, &
11154 lsort, lunique, lmiss, remapa, lana)
11155CALL vol7d_remap1_vol7d_network(this%network, that%network, &
11156 lsort, lunique, lmiss, remapn, lnetwork)
11157
11158! lanavari, lanavarb, lanavarc, &
11159! lanaattri, lanaattrb, lanaattrc, &
11160! lanavarattri, lanavarattrb, lanavarattrc, &
11161! ldativari, ldativarb, ldativarc, &
11162! ldatiattri, ldatiattrb, ldatiattrc, &
11163! ldativarattri, ldativarattrb, ldativarattrc
11164! Faccio la riforma fisica dei volumi
11165CALL vol7d_reform_finalr(this, that, &
11166 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
11167 lanavarr, lanaattrr, lanavarattrr, ldativarr, ldatiattrr, ldativarattrr)
11168CALL vol7d_reform_finald(this, that, &
11169 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
11170 lanavard, lanaattrd, lanavarattrd, ldativard, ldatiattrd, ldativarattrd)
11171CALL vol7d_reform_finali(this, that, &
11172 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
11173 lanavari, lanaattri, lanavarattri, ldativari, ldatiattri, ldativarattri)
11174CALL vol7d_reform_finalb(this, that, &
11175 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
11176 lanavarb, lanaattrb, lanavarattrb, ldativarb, ldatiattrb, ldativarattrb)
11177CALL vol7d_reform_finalc(this, that, &
11178 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
11179 lanavarc, lanaattrc, lanavarattrc, ldativarc, ldatiattrc, ldativarattrc)
11180
11181! Dealloco i vettori di rimappatura
11182IF (ASSOCIATED(remapt)) DEALLOCATE(remapt)
11183IF (ASSOCIATED(remaptr)) DEALLOCATE(remaptr)
11184IF (ASSOCIATED(remapl)) DEALLOCATE(remapl)
11185IF (ASSOCIATED(remapa)) DEALLOCATE(remapa)
11186IF (ASSOCIATED(remapn)) DEALLOCATE(remapn)
11187
11188! Ricreo gli indici var-attr
11189CALL vol7d_set_attr_ind(that)
11190that%time_definition = this%time_definition
11191
11192END SUBROUTINE vol7d_copy
11193
11194
11195!> Metodo per riformare in varie maniere un oggetto vol7d.
11196!! Equivale ad una copia (vedi ::vol7d_copy)
11197!! seguita dalla distruzione del volume iniziale e alla
11198!! sua riassegnazione al volume copiato. Ha senso se almeno uno dei parametri
11199!! \a sort, \a uniq o \a miss è fornito uguale a \c .TRUE., altrimenti
11200!! è solo una perdita di tempo.
11201!! Può essere utile, ad esempio, per eliminare stazioni
11202!! o istanti temporali indesiderati, basta assegnare il loro corrispondente
11203!! elemento del descrittore a valore mancante e chiamare vol7d_reform
11204!! con miss=.TRUE. .
11205SUBROUTINE vol7d_reform(this, sort, unique, miss, &
11206 lsort_time, lsort_timerange, lsort_level, &
11207 ltime, ltimerange, llevel, lana, lnetwork, &
11208 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
11209 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
11210 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
11211 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
11212 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
11213 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc&
11214 ,purgeana)
11215TYPE(vol7d),INTENT(INOUT) :: this !< oggetto da riformare
11216LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
11217LOGICAL,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)
11218LOGICAL,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
11219LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
11220LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
11221LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
11222!> se fornito, deve essere un vettore logico della stessa lunghezza di
11223!! this%time indicante quali elementi della dimensione \a time
11224!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
11225!! nel volume copiato; in alternativa può essere un vettore di
11226!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
11227!! gli elementi (utile principalmente per le variabili); è compatibile
11228!! col parametro \a miss
11229LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
11230LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:) !< come il precedente per la dimensione \a timerange
11231LOGICAL,INTENT(IN),OPTIONAL :: llevel(:) !< come il precedente per la dimensione \a level
11232LOGICAL,INTENT(IN),OPTIONAL :: lana(:) !< come il precedente per la dimensione \a ana
11233LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:) !< come il precedente per la dimensione \a network
11234!> come il precedente per tutte le possibili dimensioni variabile
11235LOGICAL,INTENT(in),OPTIONAL :: &
11236 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
11237 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
11238 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
11239 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
11240 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
11241 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
11242LOGICAL,INTENT(IN),OPTIONAL :: purgeana !< if true remove ana with all data missing
11243
11244TYPE(vol7d) :: v7dtmp
11245logical,allocatable :: llana(:)
11246integer :: i
11247
11249 lsort_time, lsort_timerange, lsort_level, &
11250 ltime, ltimerange, llevel, lana, lnetwork, &
11251 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
11252 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
11253 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
11254 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
11255 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
11256 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
11257
11258! destroy old volume
11260
11261if (optio_log(purgeana)) then
11262 allocate(llana(size(v7dtmp%ana)))
11263 llana =.false.
11264 do i =1,size(v7dtmp%ana)
11265 if (associated(v7dtmp%voldatii)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatii(i,:,:,:,:,:)))
11266 if (associated(v7dtmp%voldatir)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatir(i,:,:,:,:,:)))
11267 if (associated(v7dtmp%voldatid)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatid(i,:,:,:,:,:)))
11268 if (associated(v7dtmp%voldatib)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatib(i,:,:,:,:,:)))
11269 if (associated(v7dtmp%voldatic)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatic(i,:,:,:,:,:)))
11270 end do
11271 CALL vol7d_copy(v7dtmp, this,lana=llana)
11273 deallocate(llana)
11274else
11275 this=v7dtmp
11276end if
11277
11278END SUBROUTINE vol7d_reform
11279
11280
11281!> Sorts the sortable dimensions in the volume \a this only when necessary.
11282!! Most of the times, the time, timerange and level dimensions in a
11283!! vol7d object are correctly sorted; on the other side many methods
11284!! strictly rely on this fact in order to work correctly. This method
11285!! performs a quick check and sorts the required dimensions only if
11286!! they are not sorted in ascending order yet, improving safety
11287!! without impairing much performance.
11288SUBROUTINE vol7d_smart_sort(this, lsort_time, lsort_timerange, lsort_level)
11289TYPE(vol7d),INTENT(INOUT) :: this !< object to be sorted
11290LOGICAL,OPTIONAL,INTENT(in) :: lsort_time !< if present and \a .TRUE., sort time dimension if it is not sorted in ascending order
11291LOGICAL,OPTIONAL,INTENT(in) :: lsort_timerange !< if present and \a .TRUE., sort timerange dimension if it is not sorted in ascending order
11292LOGICAL,OPTIONAL,INTENT(in) :: lsort_level !< if present and \a .TRUE., sort vertical level dimension if it is not sorted in ascending order
11293
11294INTEGER :: i
11295LOGICAL :: to_be_sorted
11296
11297to_be_sorted = .false.
11298CALL vol7d_alloc_vol(this) ! usual safety check
11299
11300IF (optio_log(lsort_time)) THEN
11301 DO i = 2, SIZE(this%time)
11302 IF (this%time(i) < this%time(i-1)) THEN
11303 to_be_sorted = .true.
11304 EXIT
11305 ENDIF
11306 ENDDO
11307ENDIF
11308IF (optio_log(lsort_timerange)) THEN
11309 DO i = 2, SIZE(this%timerange)
11310 IF (this%timerange(i) < this%timerange(i-1)) THEN
11311 to_be_sorted = .true.
11312 EXIT
11313 ENDIF
11314 ENDDO
11315ENDIF
11316IF (optio_log(lsort_level)) THEN
11317 DO i = 2, SIZE(this%level)
11318 IF (this%level(i) < this%level(i-1)) THEN
11319 to_be_sorted = .true.
11320 EXIT
11321 ENDIF
11322 ENDDO
11323ENDIF
11324
11325IF (to_be_sorted) CALL vol7d_reform(this, &
11326 lsort_time=lsort_time, lsort_timerange=lsort_timerange, lsort_level=lsort_level )
11327
11328END SUBROUTINE vol7d_smart_sort
11329
11330!> Filter the contents of a volume keeping only desired data.
11331!! This subroutine filters a vol7d object by keeping only a subset of
11332!! the data contained. It can keep only times within a specified
11333!! interval, only station networks contained in a list and only
11334!! specified station or data variables. If a filter parameter is not
11335!! provided, no filtering will take place according to that criterion.
11336!! The volume is reallocated keeping only the desired data.
11337SUBROUTINE vol7d_filter(this, avl, vl, nl, s_d, e_d)
11338TYPE(vol7d),INTENT(inout) :: this !< volume to be filtered
11339CHARACTER(len=*),INTENT(in),OPTIONAL :: avl(:) !< list of station variables to be kept, if not provided or of zero length, all variables are kept
11340CHARACTER(len=*),INTENT(in),OPTIONAL :: vl(:) !< list of data variables to be kept, if not provided or of zero length, all variables are kept
11341TYPE(vol7d_network),OPTIONAL :: nl(:) !< list of station networks to be kept, if not provided or of zero length, all networks are kept
11342TYPE(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
11343TYPE(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
11344
11345INTEGER :: i
11346
11347IF (PRESENT(avl)) THEN
11348 IF (SIZE(avl) > 0) THEN
11349
11350 IF (ASSOCIATED(this%anavar%r)) THEN
11351 DO i = 1, SIZE(this%anavar%r)
11352 IF (all(this%anavar%r(i)%btable /= avl)) this%anavar%r(i) = vol7d_var_miss
11353 ENDDO
11354 ENDIF
11355
11356 IF (ASSOCIATED(this%anavar%i)) THEN
11357 DO i = 1, SIZE(this%anavar%i)
11358 IF (all(this%anavar%i(i)%btable /= avl)) this%anavar%i(i) = vol7d_var_miss
11359 ENDDO
11360 ENDIF
11361
11362 IF (ASSOCIATED(this%anavar%b)) THEN
11363 DO i = 1, SIZE(this%anavar%b)
11364 IF (all(this%anavar%b(i)%btable /= avl)) this%anavar%b(i) = vol7d_var_miss
11365 ENDDO
11366 ENDIF
11367
11368 IF (ASSOCIATED(this%anavar%d)) THEN
11369 DO i = 1, SIZE(this%anavar%d)
11370 IF (all(this%anavar%d(i)%btable /= avl)) this%anavar%d(i) = vol7d_var_miss
11371 ENDDO
11372 ENDIF
11373
11374 IF (ASSOCIATED(this%anavar%c)) THEN
11375 DO i = 1, SIZE(this%anavar%c)
11376 IF (all(this%anavar%c(i)%btable /= avl)) this%anavar%c(i) = vol7d_var_miss
11377 ENDDO
11378 ENDIF
11379
11380 ENDIF
11381ENDIF
11382
11383
11384IF (PRESENT(vl)) THEN
11385 IF (size(vl) > 0) THEN
11386 IF (ASSOCIATED(this%dativar%r)) THEN
11387 DO i = 1, SIZE(this%dativar%r)
11388 IF (all(this%dativar%r(i)%btable /= vl)) this%dativar%r(i) = vol7d_var_miss
11389 ENDDO
11390 ENDIF
11391
11392 IF (ASSOCIATED(this%dativar%i)) THEN
11393 DO i = 1, SIZE(this%dativar%i)
11394 IF (all(this%dativar%i(i)%btable /= vl)) this%dativar%i(i) = vol7d_var_miss
11395 ENDDO
11396 ENDIF
11397
11398 IF (ASSOCIATED(this%dativar%b)) THEN
11399 DO i = 1, SIZE(this%dativar%b)
11400 IF (all(this%dativar%b(i)%btable /= vl)) this%dativar%b(i) = vol7d_var_miss
11401 ENDDO
11402 ENDIF
11403
11404 IF (ASSOCIATED(this%dativar%d)) THEN
11405 DO i = 1, SIZE(this%dativar%d)
11406 IF (all(this%dativar%d(i)%btable /= vl)) this%dativar%d(i) = vol7d_var_miss
11407 ENDDO
11408 ENDIF
11409
11410 IF (ASSOCIATED(this%dativar%c)) THEN
11411 DO i = 1, SIZE(this%dativar%c)
11412 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
11413 ENDDO
11414 ENDIF
11415
11416 IF (ASSOCIATED(this%dativar%c)) THEN
11417 DO i = 1, SIZE(this%dativar%c)
11418 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
11419 ENDDO
11420 ENDIF
11421
11422 ENDIF
11423ENDIF
11424
11425IF (PRESENT(nl)) THEN
11426 IF (SIZE(nl) > 0) THEN
11427 DO i = 1, SIZE(this%network)
11428 IF (all(this%network(i) /= nl)) this%network(i) = vol7d_network_miss
11429 ENDDO
11430 ENDIF
11431ENDIF
11432
11433IF (PRESENT(s_d)) THEN
11435 WHERE (this%time < s_d)
11436 this%time = datetime_miss
11437 END WHERE
11438 ENDIF
11439ENDIF
11440
11441IF (PRESENT(e_d)) THEN
11443 WHERE (this%time > e_d)
11444 this%time = datetime_miss
11445 END WHERE
11446 ENDIF
11447ENDIF
11448
11449CALL vol7d_reform(this, miss=.true.)
11450
11451END SUBROUTINE vol7d_filter
11452
11453
11454!> Metodo per convertire i volumi di dati di un oggetto vol7d in dati
11455!! reali dove possibile. L'oggetto convertito è una copia completa
11456!! dell'originale che può essere quindi distrutto dopo la chiamata.
11457!! Per i dati di anagrafica, al momento sono convertiti solo
11458!! i dati CHARACTER se è passato \a anaconv=.TRUE.
11459!! Gli attributi non sono toccati.
11460SUBROUTINE vol7d_convr(this, that, anaconv)
11461TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
11462TYPE(vol7d),INTENT(INOUT) :: that !< oggetto convertito
11463LOGICAL,OPTIONAL,INTENT(in) :: anaconv !< converti anche anagrafica
11464INTEGER :: i
11465LOGICAL :: fv(1)=(/.false./), tv(1)=(/.true./), acp(1), acn(1)
11466TYPE(vol7d) :: v7d_tmp
11467
11468IF (optio_log(anaconv)) THEN
11469 acp=fv
11470 acn=tv
11471ELSE
11472 acp=tv
11473 acn=fv
11474ENDIF
11475
11476! Volume con solo i dati reali e tutti gli attributi
11477! l'anagrafica e` copiata interamente se necessario
11478CALL vol7d_copy(this, that, &
11479 lanavarr=tv, lanavard=acp, lanavari=acp, lanavarb=acp, lanavarc=acp, &
11480 ldativarr=tv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=fv)
11481
11482! Volume solo di dati double
11483CALL vol7d_copy(this, v7d_tmp, &
11484 lanavarr=fv, lanavard=acn, lanavari=fv, lanavarb=fv, lanavarc=fv, &
11485 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
11486 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
11487 ldativarr=fv, ldativard=tv, ldativari=fv, ldativarb=fv, ldativarc=fv, &
11488 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
11489 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
11490
11491! converto a dati reali
11492IF (ASSOCIATED(v7d_tmp%anavar%d) .OR. ASSOCIATED(v7d_tmp%dativar%d)) THEN
11493
11494 IF (ASSOCIATED(v7d_tmp%anavar%d)) THEN
11495! alloco i dati reali e vi trasferisco i double
11496 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanad, 1), SIZE(v7d_tmp%volanad, 2), &
11497 SIZE(v7d_tmp%volanad, 3)))
11498 DO i = 1, SIZE(v7d_tmp%anavar%d)
11499 v7d_tmp%volanar(:,i,:) = &
11500 realdat(v7d_tmp%volanad(:,i,:), v7d_tmp%anavar%d(i))
11501 ENDDO
11502 DEALLOCATE(v7d_tmp%volanad)
11503! trasferisco le variabili
11504 v7d_tmp%anavar%r => v7d_tmp%anavar%d
11505 NULLIFY(v7d_tmp%anavar%d)
11506 ENDIF
11507
11508 IF (ASSOCIATED(v7d_tmp%dativar%d)) THEN
11509! alloco i dati reali e vi trasferisco i double
11510 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatid, 1), SIZE(v7d_tmp%voldatid, 2), &
11511 SIZE(v7d_tmp%voldatid, 3), SIZE(v7d_tmp%voldatid, 4), SIZE(v7d_tmp%voldatid, 5), &
11512 SIZE(v7d_tmp%voldatid, 6)))
11513 DO i = 1, SIZE(v7d_tmp%dativar%d)
11514 v7d_tmp%voldatir(:,:,:,:,i,:) = &
11515 realdat(v7d_tmp%voldatid(:,:,:,:,i,:), v7d_tmp%dativar%d(i))
11516 ENDDO
11517 DEALLOCATE(v7d_tmp%voldatid)
11518! trasferisco le variabili
11519 v7d_tmp%dativar%r => v7d_tmp%dativar%d
11520 NULLIFY(v7d_tmp%dativar%d)
11521 ENDIF
11522
11523! fondo con il volume definitivo
11524 CALL vol7d_merge(that, v7d_tmp)
11525ELSE
11527ENDIF
11528
11529
11530! Volume solo di dati interi
11531CALL vol7d_copy(this, v7d_tmp, &
11532 lanavarr=fv, lanavard=fv, lanavari=acn, lanavarb=fv, lanavarc=fv, &
11533 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
11534 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
11535 ldativarr=fv, ldativard=fv, ldativari=tv, ldativarb=fv, ldativarc=fv, &
11536 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
11537 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
11538
11539! converto a dati reali
11540IF (ASSOCIATED(v7d_tmp%anavar%i) .OR. ASSOCIATED(v7d_tmp%dativar%i)) THEN
11541
11542 IF (ASSOCIATED(v7d_tmp%anavar%i)) THEN
11543! alloco i dati reali e vi trasferisco gli interi
11544 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanai, 1), SIZE(v7d_tmp%volanai, 2), &
11545 SIZE(v7d_tmp%volanai, 3)))
11546 DO i = 1, SIZE(v7d_tmp%anavar%i)
11547 v7d_tmp%volanar(:,i,:) = &
11548 realdat(v7d_tmp%volanai(:,i,:), v7d_tmp%anavar%i(i))
11549 ENDDO
11550 DEALLOCATE(v7d_tmp%volanai)
11551! trasferisco le variabili
11552 v7d_tmp%anavar%r => v7d_tmp%anavar%i
11553 NULLIFY(v7d_tmp%anavar%i)
11554 ENDIF
11555
11556 IF (ASSOCIATED(v7d_tmp%dativar%i)) THEN
11557! alloco i dati reali e vi trasferisco gli interi
11558 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatii, 1), SIZE(v7d_tmp%voldatii, 2), &
11559 SIZE(v7d_tmp%voldatii, 3), SIZE(v7d_tmp%voldatii, 4), SIZE(v7d_tmp%voldatii, 5), &
11560 SIZE(v7d_tmp%voldatii, 6)))
11561 DO i = 1, SIZE(v7d_tmp%dativar%i)
11562 v7d_tmp%voldatir(:,:,:,:,i,:) = &
11563 realdat(v7d_tmp%voldatii(:,:,:,:,i,:), v7d_tmp%dativar%i(i))
11564 ENDDO
11565 DEALLOCATE(v7d_tmp%voldatii)
11566! trasferisco le variabili
11567 v7d_tmp%dativar%r => v7d_tmp%dativar%i
11568 NULLIFY(v7d_tmp%dativar%i)
11569 ENDIF
11570
11571! fondo con il volume definitivo
11572 CALL vol7d_merge(that, v7d_tmp)
11573ELSE
11575ENDIF
11576
11577
11578! Volume solo di dati byte
11579CALL vol7d_copy(this, v7d_tmp, &
11580 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=acn, lanavarc=fv, &
11581 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
11582 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
11583 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=tv, ldativarc=fv, &
11584 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
11585 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
11586
11587! converto a dati reali
11588IF (ASSOCIATED(v7d_tmp%anavar%b) .OR. ASSOCIATED(v7d_tmp%dativar%b)) THEN
11589
11590 IF (ASSOCIATED(v7d_tmp%anavar%b)) THEN
11591! alloco i dati reali e vi trasferisco i byte
11592 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanab, 1), SIZE(v7d_tmp%volanab, 2), &
11593 SIZE(v7d_tmp%volanab, 3)))
11594 DO i = 1, SIZE(v7d_tmp%anavar%b)
11595 v7d_tmp%volanar(:,i,:) = &
11596 realdat(v7d_tmp%volanab(:,i,:), v7d_tmp%anavar%b(i))
11597 ENDDO
11598 DEALLOCATE(v7d_tmp%volanab)
11599! trasferisco le variabili
11600 v7d_tmp%anavar%r => v7d_tmp%anavar%b
11601 NULLIFY(v7d_tmp%anavar%b)
11602 ENDIF
11603
11604 IF (ASSOCIATED(v7d_tmp%dativar%b)) THEN
11605! alloco i dati reali e vi trasferisco i byte
11606 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatib, 1), SIZE(v7d_tmp%voldatib, 2), &
11607 SIZE(v7d_tmp%voldatib, 3), SIZE(v7d_tmp%voldatib, 4), SIZE(v7d_tmp%voldatib, 5), &
11608 SIZE(v7d_tmp%voldatib, 6)))
11609 DO i = 1, SIZE(v7d_tmp%dativar%b)
11610 v7d_tmp%voldatir(:,:,:,:,i,:) = &
11611 realdat(v7d_tmp%voldatib(:,:,:,:,i,:), v7d_tmp%dativar%b(i))
11612 ENDDO
11613 DEALLOCATE(v7d_tmp%voldatib)
11614! trasferisco le variabili
11615 v7d_tmp%dativar%r => v7d_tmp%dativar%b
11616 NULLIFY(v7d_tmp%dativar%b)
11617 ENDIF
11618
11619! fondo con il volume definitivo
11620 CALL vol7d_merge(that, v7d_tmp)
11621ELSE
11623ENDIF
11624
11625
11626! Volume solo di dati character
11627CALL vol7d_copy(this, v7d_tmp, &
11628 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=fv, lanavarc=acn, &
11629 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
11630 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
11631 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=tv, &
11632 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
11633 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
11634
11635! converto a dati reali
11636IF (ASSOCIATED(v7d_tmp%anavar%c) .OR. ASSOCIATED(v7d_tmp%dativar%c)) THEN
11637
11638 IF (ASSOCIATED(v7d_tmp%anavar%c)) THEN
11639! alloco i dati reali e vi trasferisco i character
11640 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanac, 1), SIZE(v7d_tmp%volanac, 2), &
11641 SIZE(v7d_tmp%volanac, 3)))
11642 DO i = 1, SIZE(v7d_tmp%anavar%c)
11643 v7d_tmp%volanar(:,i,:) = &
11644 realdat(v7d_tmp%volanac(:,i,:), v7d_tmp%anavar%c(i))
11645 ENDDO
11646 DEALLOCATE(v7d_tmp%volanac)
11647! trasferisco le variabili
11648 v7d_tmp%anavar%r => v7d_tmp%anavar%c
11649 NULLIFY(v7d_tmp%anavar%c)
11650 ENDIF
11651
11652 IF (ASSOCIATED(v7d_tmp%dativar%c)) THEN
11653! alloco i dati reali e vi trasferisco i character
11654 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatic, 1), SIZE(v7d_tmp%voldatic, 2), &
11655 SIZE(v7d_tmp%voldatic, 3), SIZE(v7d_tmp%voldatic, 4), SIZE(v7d_tmp%voldatic, 5), &
11656 SIZE(v7d_tmp%voldatic, 6)))
11657 DO i = 1, SIZE(v7d_tmp%dativar%c)
11658 v7d_tmp%voldatir(:,:,:,:,i,:) = &
11659 realdat(v7d_tmp%voldatic(:,:,:,:,i,:), v7d_tmp%dativar%c(i))
11660 ENDDO
11661 DEALLOCATE(v7d_tmp%voldatic)
11662! trasferisco le variabili
11663 v7d_tmp%dativar%r => v7d_tmp%dativar%c
11664 NULLIFY(v7d_tmp%dativar%c)
11665 ENDIF
11666
11667! fondo con il volume definitivo
11668 CALL vol7d_merge(that, v7d_tmp)
11669ELSE
11671ENDIF
11672
11673END SUBROUTINE vol7d_convr
11674
11675
11676!> Metodo per ottenere solo le differenze tra due oggetti vol7d.
11677!! Il primo volume viene confrontato col secondo; nel secondo volume ovunque
11678!! i dati confrontati siano coincidenti viene impostato valore mancante.
11679SUBROUTINE vol7d_diff_only (this, that, data_only,ana)
11680TYPE(vol7d),INTENT(IN) :: this !< primo volume da confrontare
11681TYPE(vol7d),INTENT(OUT) :: that !< secondo volume da confrontare in cui eliminare i dati coincidenti
11682logical , optional, intent(in) :: data_only !< attiva l'elaborazione dei soli dati e non dell'anagrafica (default: .false.)
11683logical , optional, intent(in) :: ana !< attiva l'elaborazione dell'anagrafica (coordinate e ident) (default: .false.)
11684logical :: ldata_only,lana
11685
11686IF (PRESENT(data_only)) THEN
11687 ldata_only = data_only
11688ELSE
11689 ldata_only = .false.
11690ENDIF
11691
11692IF (PRESENT(ana)) THEN
11693 lana = ana
11694ELSE
11695 lana = .false.
11696ENDIF
11697
11698
11699#undef VOL7D_POLY_ARRAY
11700#define VOL7D_POLY_ARRAY voldati
11701#include "vol7d_class_diff.F90"
11702#undef VOL7D_POLY_ARRAY
11703#define VOL7D_POLY_ARRAY voldatiattr
11704#include "vol7d_class_diff.F90"
11705#undef VOL7D_POLY_ARRAY
11706
11707if ( .not. ldata_only) then
11708
11709#define VOL7D_POLY_ARRAY volana
11710#include "vol7d_class_diff.F90"
11711#undef VOL7D_POLY_ARRAY
11712#define VOL7D_POLY_ARRAY volanaattr
11713#include "vol7d_class_diff.F90"
11714#undef VOL7D_POLY_ARRAY
11715
11716 if(lana)then
11717 where ( this%ana == that%ana )
11718 that%ana = vol7d_ana_miss
11719 end where
11720 end if
11721
11722end if
11723
11724
11725
11726END SUBROUTINE vol7d_diff_only
11727
11728
11729
11730! Creo le routine da ripetere per i vari tipi di dati di v7d
11731! tramite un template e il preprocessore
11732#undef VOL7D_POLY_TYPE
11733#undef VOL7D_POLY_TYPES
11734#define VOL7D_POLY_TYPE REAL
11735#define VOL7D_POLY_TYPES r
11736#include "vol7d_class_type_templ.F90"
11737#undef VOL7D_POLY_TYPE
11738#undef VOL7D_POLY_TYPES
11739#define VOL7D_POLY_TYPE DOUBLE PRECISION
11740#define VOL7D_POLY_TYPES d
11741#include "vol7d_class_type_templ.F90"
11742#undef VOL7D_POLY_TYPE
11743#undef VOL7D_POLY_TYPES
11744#define VOL7D_POLY_TYPE INTEGER
11745#define VOL7D_POLY_TYPES i
11746#include "vol7d_class_type_templ.F90"
11747#undef VOL7D_POLY_TYPE
11748#undef VOL7D_POLY_TYPES
11749#define VOL7D_POLY_TYPE INTEGER(kind=int_b)
11750#define VOL7D_POLY_TYPES b
11751#include "vol7d_class_type_templ.F90"
11752#undef VOL7D_POLY_TYPE
11753#undef VOL7D_POLY_TYPES
11754#define VOL7D_POLY_TYPE CHARACTER(len=vol7d_cdatalen)
11755#define VOL7D_POLY_TYPES c
11756#include "vol7d_class_type_templ.F90"
11757
11758! Creo le routine da ripetere per i vari descrittori di dimensioni di v7d
11759! tramite un template e il preprocessore
11760#define VOL7D_SORT
11761#undef VOL7D_NO_ZERO_ALLOC
11762#undef VOL7D_POLY_TYPE
11763#define VOL7D_POLY_TYPE datetime
11764#include "vol7d_class_desc_templ.F90"
11765#undef VOL7D_POLY_TYPE
11766#define VOL7D_POLY_TYPE vol7d_timerange
11767#include "vol7d_class_desc_templ.F90"
11768#undef VOL7D_POLY_TYPE
11769#define VOL7D_POLY_TYPE vol7d_level
11770#include "vol7d_class_desc_templ.F90"
11771#undef VOL7D_SORT
11772#undef VOL7D_POLY_TYPE
11773#define VOL7D_POLY_TYPE vol7d_network
11774#include "vol7d_class_desc_templ.F90"
11775#undef VOL7D_POLY_TYPE
11776#define VOL7D_POLY_TYPE vol7d_ana
11777#include "vol7d_class_desc_templ.F90"
11778#define VOL7D_NO_ZERO_ALLOC
11779#undef VOL7D_POLY_TYPE
11780#define VOL7D_POLY_TYPE vol7d_var
11781#include "vol7d_class_desc_templ.F90"
11782
11783!>\brief Scrittura su file di un volume Vol7d.
11784!! Scrittura su file unformatted di un intero volume Vol7d.
11785!! Il volume viene serializzato e scritto su file.
11786!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
11787!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
11788!! tali parametri saranno in output.
11789!! Se non viene fornito il nome file viene utilizzato un file di default con nome pari al nome del programma in
11790!! esecuzione con postfisso ".v7d".
11791!! Come parametro opzionale c'è la description che insieme alla data corrente viene inserita nell'header del file.
11792subroutine vol7d_write_on_file (this,unit,description,filename,filename_auto)
11793
11794TYPE(vol7d),INTENT(IN) :: this !< volume vol7d da scrivere
11795integer,optional,intent(inout) :: unit !< unità su cui scrivere; se passata =0 ritorna il valore rielaborato (default =rielaborato internamente con getlun )
11796character(len=*),intent(in),optional :: filename !< nome del file su cui scrivere
11797character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
11798character(len=*),INTENT(IN),optional :: description !< descrizione del volume
11799
11800integer :: lunit
11801character(len=254) :: ldescription,arg,lfilename
11802integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
11803 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
11804 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
11805 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
11806 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
11807 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
11808 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
11809!integer :: im,id,iy
11810integer :: tarray(8)
11811logical :: opened,exist
11812
11813 nana=0
11814 ntime=0
11815 ntimerange=0
11816 nlevel=0
11817 nnetwork=0
11818 ndativarr=0
11819 ndativari=0
11820 ndativarb=0
11821 ndativard=0
11822 ndativarc=0
11823 ndatiattrr=0
11824 ndatiattri=0
11825 ndatiattrb=0
11826 ndatiattrd=0
11827 ndatiattrc=0
11828 ndativarattrr=0
11829 ndativarattri=0
11830 ndativarattrb=0
11831 ndativarattrd=0
11832 ndativarattrc=0
11833 nanavarr=0
11834 nanavari=0
11835 nanavarb=0
11836 nanavard=0
11837 nanavarc=0
11838 nanaattrr=0
11839 nanaattri=0
11840 nanaattrb=0
11841 nanaattrd=0
11842 nanaattrc=0
11843 nanavarattrr=0
11844 nanavarattri=0
11845 nanavarattrb=0
11846 nanavarattrd=0
11847 nanavarattrc=0
11848
11849
11850!call idate(im,id,iy)
11851call date_and_time(values=tarray)
11852call getarg(0,arg)
11853
11854if (present(description))then
11855 ldescription=description
11856else
11857 ldescription="Vol7d generated by: "//trim(arg)
11858end if
11859
11860if (.not. present(unit))then
11861 lunit=getunit()
11862else
11863 if (unit==0)then
11864 lunit=getunit()
11865 unit=lunit
11866 else
11867 lunit=unit
11868 end if
11869end if
11870
11871lfilename=trim(arg)//".v7d"
11873
11874if (present(filename))then
11875 if (filename /= "")then
11876 lfilename=filename
11877 end if
11878end if
11879
11880if (present(filename_auto))filename_auto=lfilename
11881
11882
11883inquire(unit=lunit,opened=opened)
11884if (.not. opened) then
11885! inquire(file=lfilename, EXIST=exist)
11886! IF (exist) THEN
11887! CALL l4f_log(L4F_FATAL, &
11888! 'in vol7d_write_on_file, file exists, cannot open file '//TRIM(lfilename))
11889! CALL raise_fatal_error()
11890! ENDIF
11891 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM')
11892 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
11893end if
11894
11895if (associated(this%ana)) nana=size(this%ana)
11896if (associated(this%time)) ntime=size(this%time)
11897if (associated(this%timerange)) ntimerange=size(this%timerange)
11898if (associated(this%level)) nlevel=size(this%level)
11899if (associated(this%network)) nnetwork=size(this%network)
11900
11901if (associated(this%dativar%r)) ndativarr=size(this%dativar%r)
11902if (associated(this%dativar%i)) ndativari=size(this%dativar%i)
11903if (associated(this%dativar%b)) ndativarb=size(this%dativar%b)
11904if (associated(this%dativar%d)) ndativard=size(this%dativar%d)
11905if (associated(this%dativar%c)) ndativarc=size(this%dativar%c)
11906
11907if (associated(this%datiattr%r)) ndatiattrr=size(this%datiattr%r)
11908if (associated(this%datiattr%i)) ndatiattri=size(this%datiattr%i)
11909if (associated(this%datiattr%b)) ndatiattrb=size(this%datiattr%b)
11910if (associated(this%datiattr%d)) ndatiattrd=size(this%datiattr%d)
11911if (associated(this%datiattr%c)) ndatiattrc=size(this%datiattr%c)
11912
11913if (associated(this%dativarattr%r)) ndativarattrr=size(this%dativarattr%r)
11914if (associated(this%dativarattr%i)) ndativarattri=size(this%dativarattr%i)
11915if (associated(this%dativarattr%b)) ndativarattrb=size(this%dativarattr%b)
11916if (associated(this%dativarattr%d)) ndativarattrd=size(this%dativarattr%d)
11917if (associated(this%dativarattr%c)) ndativarattrc=size(this%dativarattr%c)
11918
11919if (associated(this%anavar%r)) nanavarr=size(this%anavar%r)
11920if (associated(this%anavar%i)) nanavari=size(this%anavar%i)
11921if (associated(this%anavar%b)) nanavarb=size(this%anavar%b)
11922if (associated(this%anavar%d)) nanavard=size(this%anavar%d)
11923if (associated(this%anavar%c)) nanavarc=size(this%anavar%c)
11924
11925if (associated(this%anaattr%r)) nanaattrr=size(this%anaattr%r)
11926if (associated(this%anaattr%i)) nanaattri=size(this%anaattr%i)
11927if (associated(this%anaattr%b)) nanaattrb=size(this%anaattr%b)
11928if (associated(this%anaattr%d)) nanaattrd=size(this%anaattr%d)
11929if (associated(this%anaattr%c)) nanaattrc=size(this%anaattr%c)
11930
11931if (associated(this%anavarattr%r)) nanavarattrr=size(this%anavarattr%r)
11932if (associated(this%anavarattr%i)) nanavarattri=size(this%anavarattr%i)
11933if (associated(this%anavarattr%b)) nanavarattrb=size(this%anavarattr%b)
11934if (associated(this%anavarattr%d)) nanavarattrd=size(this%anavarattr%d)
11935if (associated(this%anavarattr%c)) nanavarattrc=size(this%anavarattr%c)
11936
11937write(unit=lunit)ldescription
11938write(unit=lunit)tarray
11939
11940write(unit=lunit)&
11941 nana, ntime, ntimerange, nlevel, nnetwork, &
11942 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
11943 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
11944 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
11945 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
11946 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
11947 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
11948 this%time_definition
11949
11950
11951!write(unit=lunit)this
11952
11953
11954!! prime 5 dimensioni
11957if (associated(this%level)) write(unit=lunit)this%level
11958if (associated(this%timerange)) write(unit=lunit)this%timerange
11959if (associated(this%network)) write(unit=lunit)this%network
11960
11961 !! 6a dimensione: variabile dell'anagrafica e dei dati
11962 !! con relativi attributi e in 5 tipi diversi
11963
11964if (associated(this%anavar%r)) write(unit=lunit)this%anavar%r
11965if (associated(this%anavar%i)) write(unit=lunit)this%anavar%i
11966if (associated(this%anavar%b)) write(unit=lunit)this%anavar%b
11967if (associated(this%anavar%d)) write(unit=lunit)this%anavar%d
11968if (associated(this%anavar%c)) write(unit=lunit)this%anavar%c
11969
11970if (associated(this%anaattr%r)) write(unit=lunit)this%anaattr%r
11971if (associated(this%anaattr%i)) write(unit=lunit)this%anaattr%i
11972if (associated(this%anaattr%b)) write(unit=lunit)this%anaattr%b
11973if (associated(this%anaattr%d)) write(unit=lunit)this%anaattr%d
11974if (associated(this%anaattr%c)) write(unit=lunit)this%anaattr%c
11975
11976if (associated(this%anavarattr%r)) write(unit=lunit)this%anavarattr%r
11977if (associated(this%anavarattr%i)) write(unit=lunit)this%anavarattr%i
11978if (associated(this%anavarattr%b)) write(unit=lunit)this%anavarattr%b
11979if (associated(this%anavarattr%d)) write(unit=lunit)this%anavarattr%d
11980if (associated(this%anavarattr%c)) write(unit=lunit)this%anavarattr%c
11981
11982if (associated(this%dativar%r)) write(unit=lunit)this%dativar%r
11983if (associated(this%dativar%i)) write(unit=lunit)this%dativar%i
11984if (associated(this%dativar%b)) write(unit=lunit)this%dativar%b
11985if (associated(this%dativar%d)) write(unit=lunit)this%dativar%d
11986if (associated(this%dativar%c)) write(unit=lunit)this%dativar%c
11987
11988if (associated(this%datiattr%r)) write(unit=lunit)this%datiattr%r
11989if (associated(this%datiattr%i)) write(unit=lunit)this%datiattr%i
11990if (associated(this%datiattr%b)) write(unit=lunit)this%datiattr%b
11991if (associated(this%datiattr%d)) write(unit=lunit)this%datiattr%d
11992if (associated(this%datiattr%c)) write(unit=lunit)this%datiattr%c
11993
11994if (associated(this%dativarattr%r)) write(unit=lunit)this%dativarattr%r
11995if (associated(this%dativarattr%i)) write(unit=lunit)this%dativarattr%i
11996if (associated(this%dativarattr%b)) write(unit=lunit)this%dativarattr%b
11997if (associated(this%dativarattr%d)) write(unit=lunit)this%dativarattr%d
11998if (associated(this%dativarattr%c)) write(unit=lunit)this%dativarattr%c
11999
12000!! Volumi di valori e attributi per anagrafica e dati
12001
12002if (associated(this%volanar)) write(unit=lunit)this%volanar
12003if (associated(this%volanaattrr)) write(unit=lunit)this%volanaattrr
12004if (associated(this%voldatir)) write(unit=lunit)this%voldatir
12005if (associated(this%voldatiattrr)) write(unit=lunit)this%voldatiattrr
12006
12007if (associated(this%volanai)) write(unit=lunit)this%volanai
12008if (associated(this%volanaattri)) write(unit=lunit)this%volanaattri
12009if (associated(this%voldatii)) write(unit=lunit)this%voldatii
12010if (associated(this%voldatiattri)) write(unit=lunit)this%voldatiattri
12011
12012if (associated(this%volanab)) write(unit=lunit)this%volanab
12013if (associated(this%volanaattrb)) write(unit=lunit)this%volanaattrb
12014if (associated(this%voldatib)) write(unit=lunit)this%voldatib
12015if (associated(this%voldatiattrb)) write(unit=lunit)this%voldatiattrb
12016
12017if (associated(this%volanad)) write(unit=lunit)this%volanad
12018if (associated(this%volanaattrd)) write(unit=lunit)this%volanaattrd
12019if (associated(this%voldatid)) write(unit=lunit)this%voldatid
12020if (associated(this%voldatiattrd)) write(unit=lunit)this%voldatiattrd
12021
12022if (associated(this%volanac)) write(unit=lunit)this%volanac
12023if (associated(this%volanaattrc)) write(unit=lunit)this%volanaattrc
12024if (associated(this%voldatic)) write(unit=lunit)this%voldatic
12025if (associated(this%voldatiattrc)) write(unit=lunit)this%voldatiattrc
12026
12027if (.not. present(unit)) close(unit=lunit)
12028
12029end subroutine vol7d_write_on_file
12030
12031
12032!>\brief Lettura da file di un volume Vol7d.
12033!! Lettura da file unformatted di un intero volume Vol7d.
12034!! Questa subroutine comprende vol7d_alloc e vol7d_alloc_vol.
12035!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
12036!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
12037!! tali parametri saranno in output.
12038
12039
12040subroutine vol7d_read_from_file (this,unit,filename,description,tarray,filename_auto)
12041
12042TYPE(vol7d),INTENT(OUT) :: this !< Volume vol7d da leggere
12043integer,intent(inout),optional :: unit !< unità su cui è stato aperto un file; se =0 rielaborato internamente (default = elaborato internamente con getunit)
12044character(len=*),INTENT(in),optional :: filename !< nome del file eventualmente da aprire (default = (nome dell'eseguibile)//.v7d )
12045character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
12046character(len=*),INTENT(out),optional :: description !< descrizione del volume letto
12047integer,intent(out),optional :: tarray(8) !< vettore come definito da "date_and_time" della data di scrittura del volume
12048
12049
12050integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
12051 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
12052 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
12053 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
12054 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
12055 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
12056 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
12057
12058character(len=254) :: ldescription,lfilename,arg
12059integer :: ltarray(8),lunit,ios
12060logical :: opened,exist
12061
12062
12063call getarg(0,arg)
12064
12065if (.not. present(unit))then
12066 lunit=getunit()
12067else
12068 if (unit==0)then
12069 lunit=getunit()
12070 unit=lunit
12071 else
12072 lunit=unit
12073 end if
12074end if
12075
12076lfilename=trim(arg)//".v7d"
12078
12079if (present(filename))then
12080 if (filename /= "")then
12081 lfilename=filename
12082 end if
12083end if
12084
12085if (present(filename_auto))filename_auto=lfilename
12086
12087
12088inquire(unit=lunit,opened=opened)
12089IF (.NOT. opened) THEN
12090 inquire(file=lfilename,exist=exist)
12091 IF (.NOT.exist) THEN
12092 CALL l4f_log(l4f_fatal, &
12093 'in vol7d_read_from_file, file does not exists, cannot open')
12094 CALL raise_fatal_error()
12095 ENDIF
12096 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM', &
12097 status='OLD', action='READ')
12098 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
12099end if
12100
12101
12103read(unit=lunit,iostat=ios)ldescription
12104
12105if (ios < 0) then ! A negative value indicates that the End of File or End of Record
12106 call vol7d_alloc (this)
12107 call vol7d_alloc_vol (this)
12108 if (present(description))description=ldescription
12109 if (present(tarray))tarray=ltarray
12110 if (.not. present(unit)) close(unit=lunit)
12111end if
12112
12113read(unit=lunit)ltarray
12114
12115CALL l4f_log(l4f_info, 'Reading vol7d from file')
12116CALL l4f_log(l4f_info, 'description: '//trim(ldescription))
12119
12120if (present(description))description=ldescription
12121if (present(tarray))tarray=ltarray
12122
12123read(unit=lunit)&
12124 nana, ntime, ntimerange, nlevel, nnetwork, &
12125 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
12126 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
12127 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
12128 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
12129 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
12130 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
12131 this%time_definition
12132
12133call vol7d_alloc (this, &
12134 nana=nana, ntime=ntime, ntimerange=ntimerange, nlevel=nlevel, nnetwork=nnetwork,&
12135 ndativarr=ndativarr, ndativari=ndativari, ndativarb=ndativarb,&
12136 ndativard=ndativard, ndativarc=ndativarc,&
12137 ndatiattrr=ndatiattrr, ndatiattri=ndatiattri, ndatiattrb=ndatiattrb,&
12138 ndatiattrd=ndatiattrd, ndatiattrc=ndatiattrc,&
12139 ndativarattrr=ndativarattrr, ndativarattri=ndativarattri, ndativarattrb=ndativarattrb, &
12140 ndativarattrd=ndativarattrd, ndativarattrc=ndativarattrc,&
12141 nanavarr=nanavarr, nanavari=nanavari, nanavarb=nanavarb, &
12142 nanavard=nanavard, nanavarc=nanavarc,&
12143 nanaattrr=nanaattrr, nanaattri=nanaattri, nanaattrb=nanaattrb,&
12144 nanaattrd=nanaattrd, nanaattrc=nanaattrc,&
12145 nanavarattrr=nanavarattrr, nanavarattri=nanavarattri, nanavarattrb=nanavarattrb, &
12146 nanavarattrd=nanavarattrd, nanavarattrc=nanavarattrc)
12147
12148
12151if (associated(this%level)) read(unit=lunit)this%level
12152if (associated(this%timerange)) read(unit=lunit)this%timerange
12153if (associated(this%network)) read(unit=lunit)this%network
12154
12155if (associated(this%anavar%r)) read(unit=lunit)this%anavar%r
12156if (associated(this%anavar%i)) read(unit=lunit)this%anavar%i
12157if (associated(this%anavar%b)) read(unit=lunit)this%anavar%b
12158if (associated(this%anavar%d)) read(unit=lunit)this%anavar%d
12159if (associated(this%anavar%c)) read(unit=lunit)this%anavar%c
12160
12161if (associated(this%anaattr%r)) read(unit=lunit)this%anaattr%r
12162if (associated(this%anaattr%i)) read(unit=lunit)this%anaattr%i
12163if (associated(this%anaattr%b)) read(unit=lunit)this%anaattr%b
12164if (associated(this%anaattr%d)) read(unit=lunit)this%anaattr%d
12165if (associated(this%anaattr%c)) read(unit=lunit)this%anaattr%c
12166
12167if (associated(this%anavarattr%r)) read(unit=lunit)this%anavarattr%r
12168if (associated(this%anavarattr%i)) read(unit=lunit)this%anavarattr%i
12169if (associated(this%anavarattr%b)) read(unit=lunit)this%anavarattr%b
12170if (associated(this%anavarattr%d)) read(unit=lunit)this%anavarattr%d
12171if (associated(this%anavarattr%c)) read(unit=lunit)this%anavarattr%c
12172
12173if (associated(this%dativar%r)) read(unit=lunit)this%dativar%r
12174if (associated(this%dativar%i)) read(unit=lunit)this%dativar%i
12175if (associated(this%dativar%b)) read(unit=lunit)this%dativar%b
12176if (associated(this%dativar%d)) read(unit=lunit)this%dativar%d
12177if (associated(this%dativar%c)) read(unit=lunit)this%dativar%c
12178
12179if (associated(this%datiattr%r)) read(unit=lunit)this%datiattr%r
12180if (associated(this%datiattr%i)) read(unit=lunit)this%datiattr%i
12181if (associated(this%datiattr%b)) read(unit=lunit)this%datiattr%b
12182if (associated(this%datiattr%d)) read(unit=lunit)this%datiattr%d
12183if (associated(this%datiattr%c)) read(unit=lunit)this%datiattr%c
12184
12185if (associated(this%dativarattr%r)) read(unit=lunit)this%dativarattr%r
12186if (associated(this%dativarattr%i)) read(unit=lunit)this%dativarattr%i
12187if (associated(this%dativarattr%b)) read(unit=lunit)this%dativarattr%b
12188if (associated(this%dativarattr%d)) read(unit=lunit)this%dativarattr%d
12189if (associated(this%dativarattr%c)) read(unit=lunit)this%dativarattr%c
12190
12191call vol7d_alloc_vol (this)
12192
12193!! Volumi di valori e attributi per anagrafica e dati
12194
12195if (associated(this%volanar)) read(unit=lunit)this%volanar
12196if (associated(this%volanaattrr)) read(unit=lunit)this%volanaattrr
12197if (associated(this%voldatir)) read(unit=lunit)this%voldatir
12198if (associated(this%voldatiattrr)) read(unit=lunit)this%voldatiattrr
12199
12200if (associated(this%volanai)) read(unit=lunit)this%volanai
12201if (associated(this%volanaattri)) read(unit=lunit)this%volanaattri
12202if (associated(this%voldatii)) read(unit=lunit)this%voldatii
12203if (associated(this%voldatiattri)) read(unit=lunit)this%voldatiattri
12204
12205if (associated(this%volanab)) read(unit=lunit)this%volanab
12206if (associated(this%volanaattrb)) read(unit=lunit)this%volanaattrb
12207if (associated(this%voldatib)) read(unit=lunit)this%voldatib
12208if (associated(this%voldatiattrb)) read(unit=lunit)this%voldatiattrb
12209
12210if (associated(this%volanad)) read(unit=lunit)this%volanad
12211if (associated(this%volanaattrd)) read(unit=lunit)this%volanaattrd
12212if (associated(this%voldatid)) read(unit=lunit)this%voldatid
12213if (associated(this%voldatiattrd)) read(unit=lunit)this%voldatiattrd
12214
12215if (associated(this%volanac)) read(unit=lunit)this%volanac
12216if (associated(this%volanaattrc)) read(unit=lunit)this%volanaattrc
12217if (associated(this%voldatic)) read(unit=lunit)this%voldatic
12218if (associated(this%voldatiattrc)) read(unit=lunit)this%voldatiattrc
12219
12220if (.not. present(unit)) close(unit=lunit)
12221
12222end subroutine vol7d_read_from_file
12223
12224
12225! to double precision
12226elemental doubleprecision function doubledatd(voldat,var)
12227doubleprecision,intent(in) :: voldat
12228type(vol7d_var),intent(in) :: var
12229
12230doubledatd=voldat
12231
12232end function doubledatd
12233
12234
12235elemental doubleprecision function doubledatr(voldat,var)
12236real,intent(in) :: voldat
12237type(vol7d_var),intent(in) :: var
12238
12240 doubledatr=dble(voldat)
12241else
12242 doubledatr=dmiss
12243end if
12244
12245end function doubledatr
12246
12247
12248elemental doubleprecision function doubledati(voldat,var)
12249integer,intent(in) :: voldat
12250type(vol7d_var),intent(in) :: var
12251
12254 doubledati=dble(voldat)/10.d0**var%scalefactor
12255 else
12256 doubledati=dble(voldat)
12257 endif
12258else
12259 doubledati=dmiss
12260end if
12261
12262end function doubledati
12263
12264
12265elemental doubleprecision function doubledatb(voldat,var)
12266integer(kind=int_b),intent(in) :: voldat
12267type(vol7d_var),intent(in) :: var
12268
12271 doubledatb=dble(voldat)/10.d0**var%scalefactor
12272 else
12273 doubledatb=dble(voldat)
12274 endif
12275else
12276 doubledatb=dmiss
12277end if
12278
12279end function doubledatb
12280
12281
12282elemental doubleprecision function doubledatc(voldat,var)
12283CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
12284type(vol7d_var),intent(in) :: var
12285
12286doubledatc = c2d(voldat)
12288 doubledatc=doubledatc/10.d0**var%scalefactor
12289end if
12290
12291end function doubledatc
12292
12293
12294! to integer
12295elemental integer function integerdatd(voldat,var)
12296doubleprecision,intent(in) :: voldat
12297type(vol7d_var),intent(in) :: var
12298
12301 integerdatd=nint(voldat*10d0**var%scalefactor)
12302 else
12303 integerdatd=nint(voldat)
12304 endif
12305else
12306 integerdatd=imiss
12307end if
12308
12309end function integerdatd
12310
12311
12312elemental integer function integerdatr(voldat,var)
12313real,intent(in) :: voldat
12314type(vol7d_var),intent(in) :: var
12315
12318 integerdatr=nint(voldat*10d0**var%scalefactor)
12319 else
12320 integerdatr=nint(voldat)
12321 endif
12322else
12323 integerdatr=imiss
12324end if
12325
12326end function integerdatr
12327
12328
12329elemental integer function integerdati(voldat,var)
12330integer,intent(in) :: voldat
12331type(vol7d_var),intent(in) :: var
12332
12333integerdati=voldat
12334
12335end function integerdati
12336
12337
12338elemental integer function integerdatb(voldat,var)
12339integer(kind=int_b),intent(in) :: voldat
12340type(vol7d_var),intent(in) :: var
12341
12343 integerdatb=voldat
12344else
12345 integerdatb=imiss
12346end if
12347
12348end function integerdatb
12349
12350
12351elemental integer function integerdatc(voldat,var)
12352CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
12353type(vol7d_var),intent(in) :: var
12354
12355integerdatc=c2i(voldat)
12356
12357end function integerdatc
12358
12359
12360! to real
12361elemental real function realdatd(voldat,var)
12362doubleprecision,intent(in) :: voldat
12363type(vol7d_var),intent(in) :: var
12364
12366 realdatd=real(voldat)
12367else
12368 realdatd=rmiss
12369end if
12370
12371end function realdatd
12372
12373
12374elemental real function realdatr(voldat,var)
12375real,intent(in) :: voldat
12376type(vol7d_var),intent(in) :: var
12377
12378realdatr=voldat
12379
12380end function realdatr
12381
12382
12383elemental real function realdati(voldat,var)
12384integer,intent(in) :: voldat
12385type(vol7d_var),intent(in) :: var
12386
12389 realdati=float(voldat)/10.**var%scalefactor
12390 else
12391 realdati=float(voldat)
12392 endif
12393else
12394 realdati=rmiss
12395end if
12396
12397end function realdati
12398
12399
12400elemental real function realdatb(voldat,var)
12401integer(kind=int_b),intent(in) :: voldat
12402type(vol7d_var),intent(in) :: var
12403
12406 realdatb=float(voldat)/10**var%scalefactor
12407 else
12408 realdatb=float(voldat)
12409 endif
12410else
12411 realdatb=rmiss
12412end if
12413
12414end function realdatb
12415
12416
12417elemental real function realdatc(voldat,var)
12418CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
12419type(vol7d_var),intent(in) :: var
12420
12421realdatc=c2r(voldat)
12423 realdatc=realdatc/10.**var%scalefactor
12424end if
12425
12426end function realdatc
12427
12428
12429!> Return an ana volume of a requested variable as real data.
12430!! It returns a 2-d array of the proper shape (ana x network) for the
12431!! ana variable requested, converted to real type. If the conversion
12432!! fails or if the variable is not contained in the ana volume,
12433!! missing data are returned.
12434FUNCTION realanavol(this, var) RESULT(vol)
12435TYPE(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
12436TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
12437REAL :: vol(SIZE(this%ana),size(this%network))
12438
12439CHARACTER(len=1) :: dtype
12440INTEGER :: indvar
12441
12442dtype = cmiss
12443indvar = index(this%anavar, var, type=dtype)
12444
12445IF (indvar > 0) THEN
12446 SELECT CASE (dtype)
12447 CASE("d")
12448 vol = realdat(this%volanad(:,indvar,:), var)
12449 CASE("r")
12450 vol = this%volanar(:,indvar,:)
12451 CASE("i")
12452 vol = realdat(this%volanai(:,indvar,:), var)
12453 CASE("b")
12454 vol = realdat(this%volanab(:,indvar,:), var)
12455 CASE("c")
12456 vol = realdat(this%volanac(:,indvar,:), var)
12457 CASE default
12458 vol = rmiss
12459 END SELECT
12460ELSE
12461 vol = rmiss
12462ENDIF
12463
12464END FUNCTION realanavol
12465
12466
12467!> Return an ana volume of a requested variable as integer data.
12468!! It returns a 2-d array of the proper shape (ana x network) for the
12469!! ana variable requested, converted to integer type. If the conversion
12470!! fails or if the variable is not contained in the ana volume,
12471!! missing data are returned.
12472FUNCTION integeranavol(this, var) RESULT(vol)
12473TYPE(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
12474TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
12475INTEGER :: vol(SIZE(this%ana),size(this%network))
12476
12477CHARACTER(len=1) :: dtype
12478INTEGER :: indvar
12479
12480dtype = cmiss
12481indvar = index(this%anavar, var, type=dtype)
12482
12483IF (indvar > 0) THEN
12484 SELECT CASE (dtype)
12485 CASE("d")
12486 vol = integerdat(this%volanad(:,indvar,:), var)
12487 CASE("r")
12488 vol = integerdat(this%volanar(:,indvar,:), var)
12489 CASE("i")
12490 vol = this%volanai(:,indvar,:)
12491 CASE("b")
12492 vol = integerdat(this%volanab(:,indvar,:), var)
12493 CASE("c")
12494 vol = integerdat(this%volanac(:,indvar,:), var)
12495 CASE default
12496 vol = imiss
12497 END SELECT
12498ELSE
12499 vol = imiss
12500ENDIF
12501
12502END FUNCTION integeranavol
12503
12504
12505!> Move data for all variables from one coordinate in the character volume to other.
12506!! Only not missing data will be copyed and all attributes will be moved together.
12507!! Usefull to colapse data spread in more indices (level or time or ....).
12508!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
12509!! to obtain a new vol7d with less data shape.
12510subroutine move_datac (v7d,&
12511 indana,indtime,indlevel,indtimerange,indnetwork,&
12512 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
12513
12514TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
12515
12516integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
12517integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
12518integer :: inddativar,inddativarattr
12519
12520
12521do inddativar=1,size(v7d%dativar%c)
12522
12524 .not. c_e(v7d%voldatic(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
12525 ) then
12526
12527 ! dati
12528 v7d%voldatic &
12529 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
12530 v7d%voldatic &
12531 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
12532
12533
12534 ! attributi
12535 if (associated (v7d%dativarattr%i)) then
12536 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%c(inddativar))
12537 if (inddativarattr > 0 ) then
12538 v7d%voldatiattri &
12539 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12540 v7d%voldatiattri &
12541 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12542 end if
12543 end if
12544
12545 if (associated (v7d%dativarattr%r)) then
12546 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%c(inddativar))
12547 if (inddativarattr > 0 ) then
12548 v7d%voldatiattrr &
12549 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12550 v7d%voldatiattrr &
12551 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12552 end if
12553 end if
12554
12555 if (associated (v7d%dativarattr%d)) then
12556 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%c(inddativar))
12557 if (inddativarattr > 0 ) then
12558 v7d%voldatiattrd &
12559 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12560 v7d%voldatiattrd &
12561 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12562 end if
12563 end if
12564
12565 if (associated (v7d%dativarattr%b)) then
12566 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%c(inddativar))
12567 if (inddativarattr > 0 ) then
12568 v7d%voldatiattrb &
12569 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12570 v7d%voldatiattrb &
12571 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12572 end if
12573 end if
12574
12575 if (associated (v7d%dativarattr%c)) then
12576 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%c(inddativar))
12577 if (inddativarattr > 0 ) then
12578 v7d%voldatiattrc &
12579 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12580 v7d%voldatiattrc &
12581 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12582 end if
12583 end if
12584
12585 end if
12586
12587end do
12588
12589end subroutine move_datac
12590
12591!> Move data for all variables from one coordinate in the real volume to other.
12592!! Only not missing data will be copyed and all attributes will be moved together.
12593!! Usefull to colapse data spread in more indices (level or time or ....).
12594!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
12595!! to obtain a new vol7d with less data shape.
12596subroutine move_datar (v7d,&
12597 indana,indtime,indlevel,indtimerange,indnetwork,&
12598 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
12599
12600TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
12601
12602integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
12603integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
12604integer :: inddativar,inddativarattr
12605
12606
12607do inddativar=1,size(v7d%dativar%r)
12608
12610 .not. c_e(v7d%voldatir(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
12611 ) then
12612
12613 ! dati
12614 v7d%voldatir &
12615 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
12616 v7d%voldatir &
12617 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
12618
12619
12620 ! attributi
12621 if (associated (v7d%dativarattr%i)) then
12622 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%r(inddativar))
12623 if (inddativarattr > 0 ) then
12624 v7d%voldatiattri &
12625 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12626 v7d%voldatiattri &
12627 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12628 end if
12629 end if
12630
12631 if (associated (v7d%dativarattr%r)) then
12632 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%r(inddativar))
12633 if (inddativarattr > 0 ) then
12634 v7d%voldatiattrr &
12635 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12636 v7d%voldatiattrr &
12637 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12638 end if
12639 end if
12640
12641 if (associated (v7d%dativarattr%d)) then
12642 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%r(inddativar))
12643 if (inddativarattr > 0 ) then
12644 v7d%voldatiattrd &
12645 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12646 v7d%voldatiattrd &
12647 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12648 end if
12649 end if
12650
12651 if (associated (v7d%dativarattr%b)) then
12652 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%r(inddativar))
12653 if (inddativarattr > 0 ) then
12654 v7d%voldatiattrb &
12655 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12656 v7d%voldatiattrb &
12657 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12658 end if
12659 end if
12660
12661 if (associated (v7d%dativarattr%c)) then
12662 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%r(inddativar))
12663 if (inddativarattr > 0 ) then
12664 v7d%voldatiattrc &
12665 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12666 v7d%voldatiattrc &
12667 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12668 end if
12669 end if
12670
12671 end if
12672
12673end do
12674
12675end subroutine move_datar
12676
12677
12678!> Reduce some dimensions (level and timerage) for semplification (rounding).
12679!! You can use this for simplify and use variables in computation like alchimia
12680!! where fields have to be on the same coordinate
12681!! It return real or character data only: if input is charcter data only it return character otherwise il return
12682!! all the data converted to real.
12683!! examples:
12684!! means in time for short periods and istantaneous values
12685!! 2 meter and surface levels
12686!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
12687!! will be taken (order is by icreasing var index).
12688!! You can use predefined values for classic semplification
12689!! almost_equal_levels and almost_equal_timeranges
12690!! The level or timerange in output will be defined by the first element of level and timerange list
12691subroutine v7d_rounding(v7din,v7dout,level,timerange,nostatproc)
12692type(vol7d),intent(inout) :: v7din !< input volume
12693type(vol7d),intent(out) :: v7dout !> output volume
12694type(vol7d_level),intent(in),optional :: level(:) !< almost equal level list
12695type(vol7d_timerange),intent(in),optional :: timerange(:) !< almost equal timerange list
12696!logical,intent(in),optional :: merge !< if there are data on more then one almost equal levels or timeranges
12697!! will be merged POINT BY POINT with priority for the fird data found ordered by icreasing var index
12698logical,intent(in),optional :: nostatproc !< do not take in account statistical processing code in timerange and P2
12699
12700integer :: nana,nlevel,ntime,ntimerange,nnetwork,nbin
12701integer :: iana,ilevel,itimerange,indl,indt,itime,inetwork
12702type(vol7d_level) :: roundlevel(size(v7din%level))
12703type(vol7d_timerange) :: roundtimerange(size(v7din%timerange))
12704type(vol7d) :: v7d_tmp
12705
12706
12707nbin=0
12708
12709if (associated(v7din%dativar%r)) nbin = nbin + size(v7din%dativar%r)
12710if (associated(v7din%dativar%i)) nbin = nbin + size(v7din%dativar%i)
12711if (associated(v7din%dativar%d)) nbin = nbin + size(v7din%dativar%d)
12712if (associated(v7din%dativar%b)) nbin = nbin + size(v7din%dativar%b)
12713
12715
12716roundlevel=v7din%level
12717
12718if (present(level))then
12719 do ilevel = 1, size(v7din%level)
12720 if ((any(v7din%level(ilevel) .almosteq. level))) then
12721 roundlevel(ilevel)=level(1)
12722 end if
12723 end do
12724end if
12725
12726roundtimerange=v7din%timerange
12727
12728if (present(timerange))then
12729 do itimerange = 1, size(v7din%timerange)
12730 if ((any(v7din%timerange(itimerange) .almosteq. timerange))) then
12731 roundtimerange(itimerange)=timerange(1)
12732 end if
12733 end do
12734end if
12735
12736!set istantaneous values everywere
12737!preserve p1 for forecast time
12738if (optio_log(nostatproc)) then
12739 roundtimerange(:)%timerange=254
12740 roundtimerange(:)%p2=0
12741end if
12742
12743
12744nana=size(v7din%ana)
12745nlevel=count_distinct(roundlevel,back=.true.)
12746ntime=size(v7din%time)
12747ntimerange=count_distinct(roundtimerange,back=.true.)
12748nnetwork=size(v7din%network)
12749
12751
12752if (nbin == 0) then
12754else
12755 call vol7d_convr(v7din,v7d_tmp)
12756end if
12757
12758v7d_tmp%level=roundlevel
12759v7d_tmp%timerange=roundtimerange
12760
12761do ilevel=1, size(v7d_tmp%level)
12762 indl=index(v7d_tmp%level,roundlevel(ilevel))
12763 do itimerange=1,size(v7d_tmp%timerange)
12764 indt=index(v7d_tmp%timerange,roundtimerange(itimerange))
12765
12766 if (indl /= ilevel .or. indt /= itimerange) then
12767
12768 do iana=1, nana
12769 do itime=1,ntime
12770 do inetwork=1,nnetwork
12771
12772 if (nbin > 0) then
12773 call move_datar (v7d_tmp,&
12774 iana,itime,ilevel,itimerange,inetwork,&
12775 iana,itime,indl,indt,inetwork)
12776 else
12777 call move_datac (v7d_tmp,&
12778 iana,itime,ilevel,itimerange,inetwork,&
12779 iana,itime,indl,indt,inetwork)
12780 end if
12781
12782 end do
12783 end do
12784 end do
12785
12786 end if
12787
12788 end do
12789end do
12790
12791! set to missing level and time > nlevel
12792do ilevel=nlevel+1,size(v7d_tmp%level)
12794end do
12795
12796do itimerange=ntimerange+1,size(v7d_tmp%timerange)
12798end do
12799
12800!copy with remove
12803
12804!call display(v7dout)
12805
12806end subroutine v7d_rounding
12807
12808
12810
12811!>\example esempio_qc_convert.f90
12812!!\brief Programma esempio semplice per la scrittura su file di un volume vol7d
12813!!
12814!!Programma che scrive su file un volume vol7d letto da una serie di file ASCII.
12815!!Questo programma scrive i dati del clima che poi verranno letti da modqccli
12816
12817
12818!>\example esempio_v7ddballe_move_and_collapse.f90
12819!!\brief ! Example program to reduce to one the dimensions of levels and time without loss of data
Set of functions that return a trimmed CHARACTER representation of the input variable. Definition char_utilities.F90:278 Legge un oggetto datetime/timedelta o un vettore di oggetti datetime/timedelta da un file FORMATTED o... Definition datetime_class.F90:478 Scrive un oggetto datetime/timedelta o un vettore di oggetti datetime/timedelta su un file FORMATTED ... Definition datetime_class.F90:485 Generic subroutine for checking OPTIONAL parameters. Definition optional_values.f90:36 Check for problems return 0 if all check passed print diagnostics with log4f. Definition vol7d_class.F90:445 Reduce some dimensions (level and timerage) for semplification (rounding). Definition vol7d_class.F90:462 This module defines usefull general purpose function and subroutine. Definition array_utilities.F90:212 Definition of constants to be used for declaring variables of a desired type. Definition kinds.F90:245 Module for quickly interpreting the OPTIONAL parameters passed to a subprogram. Definition optional_values.f90:28 Classe per la gestione dell'anagrafica di stazioni meteo e affini. Definition vol7d_ana_class.F90:212 Classe per la gestione di un volume completo di dati osservati. Definition vol7d_class.F90:273 Classe per la gestione dei livelli verticali in osservazioni meteo e affini. Definition vol7d_level_class.F90:213 Classe per la gestione delle reti di stazioni per osservazioni meteo e affini. Definition vol7d_network_class.F90:214 Classe per la gestione degli intervalli temporali di osservazioni meteo e affini. Definition vol7d_timerange_class.F90:215 Classe per gestire un vettore di oggetti di tipo vol7d_var_class::vol7d_var. Definition vol7d_varvect_class.f90:22 Definisce un oggetto contenente i volumi anagrafica e dati e tutti i descrittori delle loro dimension... Definition vol7d_class.F90:312 |