libsim Versione 8.0.0

◆ vol7d_read_from_file()

subroutine vol7d_read_from_file ( type(vol7d), intent(out) this,
integer, intent(inout), optional unit,
character(len=*), intent(in), optional filename,
character(len=*), intent(out), optional description,
integer, dimension(8), intent(out), optional tarray,
character(len=*), intent(out), optional filename_auto )

Lettura da file di un volume Vol7d.

Lettura da file unformatted di un intero volume Vol7d. Questa subroutine comprende vol7d_alloc e vol7d_alloc_vol. Il file puo' essere aperto opzionalmente dall'utente. Si possono passare opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente tali parametri saranno in output.

Parametri
[out]thisVolume vol7d da leggere
[in,out]unitunità su cui è stato aperto un file; se =0 rielaborato internamente (default = elaborato internamente con getunit)
[in]filenamenome del file eventualmente da aprire (default = (nome dell'eseguibile)//.v7d )
[out]filename_autonome del file generato se "filename" è omesso
[out]descriptiondescrizione del volume letto
[out]tarrayvettore come definito da "date_and_time" della data di scrittura del volume

Definizione alla linea 8717 del file vol7d_class.F90.

8718! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
8719! authors:
8720! Davide Cesari <dcesari@arpa.emr.it>
8721! Paolo Patruno <ppatruno@arpa.emr.it>
8722
8723! This program is free software; you can redistribute it and/or
8724! modify it under the terms of the GNU General Public License as
8725! published by the Free Software Foundation; either version 2 of
8726! the License, or (at your option) any later version.
8727
8728! This program is distributed in the hope that it will be useful,
8729! but WITHOUT ANY WARRANTY; without even the implied warranty of
8730! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8731! GNU General Public License for more details.
8732
8733! You should have received a copy of the GNU General Public License
8734! along with this program. If not, see <http://www.gnu.org/licenses/>.
8735#include "config.h"
8736
8737!> \defgroup vol7d Libsim package, vol7d library.
8738!! The libsim vol7d library contains classes for managing pointwise
8739!! data, tipically weather observations, and for their import from a
8740!! Db-All.e database or from a WMO BUFR file. In order to compile and
8741!! link programs using this library, you have to insert the required
8742!! \c USE statements in the program units involved, specify the
8743!! location of module files when compiling (tipically \c
8744!! -I/usr/lib/gfortran/modules or \c -I/usr/lib64/gfortran/modules or
8745!! \c -I/usr/include) and indicate the library name \c -lsim_vol7d
8746!! when linking, assuming that the library has been installed in a
8747!! default location.
8748
8749!> Classe per la gestione di un volume completo di dati osservati.
8750!! Questo modulo definisce gli oggetti e i metodi per gestire
8751!! volumi di dati meteorologici sparsi.
8752!! I volumi definiti sono principalmente di 4 categorie:
8753!! - volumi di anagrafica (vol7d::volanar & c.), hanno 3 dimensioni:
8754!! - anagrafica
8755!! - variabile di anagrafica
8756!! - rete
8757!! - volumi di attributi di anagrafica (vol7d::volanaattrr & c.), hanno 4 dimensioni:
8758!! - anagrafica
8759!! - variabile di anagrafica
8760!! - rete
8761!! - variabile di attributi delle variabili di anagrafica
8762!! - volumi di dati (vol7d::voldatir & c.), hanno 6 dimensioni:
8763!! - anagrafica
8764!! - tempo
8765!! - livello verticale
8766!! - intervallo temporale (timerange)
8767!! - variabile di dati
8768!! - rete
8769!! - volumi di attributi di dati (vol7d::voldatiattrr & c.), hanno 7 dimensioni:
8770!! - anagrafica
8771!! - tempo
8772!! - livello verticale
8773!! - intervallo temporale (timerange)
8774!! - variabile di dati
8775!! - rete
8776!! - variabile di attributi delle variabili di dati
8777!!
8778!! Tutte le variabili sono inoltre disponibil1 in 5 tipi diversi:
8779!! - reale (abbreviato r)
8780!! - doppia precisione (abbreviato d)
8781!! - intero (abbreviato i)
8782!! - byte (abbreviato b)
8783!! - carattere (abbreviato c)
8784!!
8785!! Per ognuna delle dimensioni possibili, incluse le variabili e gli
8786!! attributi con i loro diversi tipi,
8787!! è definito un cosiddetto "vettore di descrittori", con un
8788!! numero di elementi pari all'estensione della dimensione stessa,
8789!! che contiene le informazioni necessarie a descrivere
8790!! gli elementi di quella dimensione.
8791!! In realtà l'utente non dovrà generalmente occuparsi di costruire
8792!! un oggetto vol7d con le proprie mani ma utilizzerà nella maggior parte
8793!! dei casi i metodi di importazione preconfezionati che importano dati da
8794!! DB-All.e (vol7d_dballe_class) o dal DB Oracle del SIM (vol7d_oraclesim_class).
8795!!
8796!!
8797!! Il programma esempio_v7d.f90 contiene un esempio elementare di uso
8798!! della classe vol7d:
8799!! \include esempio_v7d.f90
8800!!
8801!! \ingroup vol7d
8802MODULE vol7d_class
8803USE kinds
8807USE log4fortran
8808USE err_handling
8809USE io_units
8816IMPLICIT NONE
8817
8818
8819INTEGER, PARAMETER :: vol7d_maxdim_a = 3, vol7d_maxdim_aa = 4, &
8820 vol7d_maxdim_d = 6, vol7d_maxdim_ad = 7
8821
8822INTEGER, PARAMETER :: vol7d_ana_a=1 !< indice della dimensione "anagrafica" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
8823INTEGER, PARAMETER :: vol7d_var_a=2 !< indice della dimensione "variabile" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
8824INTEGER, PARAMETER :: vol7d_network_a=3 !< indice della dimensione "rete" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
8825INTEGER, PARAMETER :: vol7d_attr_a=4 !< indice della dimensione "attributo" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
8826INTEGER, PARAMETER :: vol7d_ana_d=1 !< indice della dimensione "anagrafica" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
8827INTEGER, PARAMETER :: vol7d_time_d=2 !< indice della dimensione "tempo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
8828INTEGER, PARAMETER :: vol7d_level_d=3 !< indice della dimensione "livello verticale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
8829INTEGER, PARAMETER :: vol7d_timerange_d=4 !< indice della dimensione "intervallo temporale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
8830INTEGER, PARAMETER :: vol7d_var_d=5 !< indice della dimensione "variabile" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
8831INTEGER, PARAMETER :: vol7d_network_d=6 !< indice della dimensione "rete" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
8832INTEGER, PARAMETER :: vol7d_attr_d=7 !< indice della dimensione "attributo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
8833INTEGER, PARAMETER :: vol7d_cdatalen=32
8834
8835TYPE vol7d_varmap
8836 INTEGER :: r, d, i, b, c
8837END TYPE vol7d_varmap
8838
8839!> Definisce un oggetto contenente i volumi anagrafica e dati e tutti
8840!! i descrittori delle loro dimensioni.
8841TYPE vol7d
8842!> vettore descrittore della dimensione anagrafica
8843 TYPE(vol7d_ana),POINTER :: ana(:)
8844!> vettore descrittore della dimensione tempo
8845 TYPE(datetime),POINTER :: time(:)
8846!> vettore descrittore della dimensione livello verticale
8847 TYPE(vol7d_level),POINTER :: level(:)
8848!> vettore descrittore della dimensione intervallo temporale (timerange)
8849 TYPE(vol7d_timerange),POINTER :: timerange(:)
8850!> vettore descrittore della dimensione rete
8851 TYPE(vol7d_network),POINTER :: network(:)
8852!> vettore descrittore della dimensione variabile di anagrafica
8853 TYPE(vol7d_varvect) :: anavar
8854!> vettore descrittore della dimensione attributo delle variabili di anagrafica
8855 TYPE(vol7d_varvect) :: anaattr
8856!> vettore descrittore della dimensione variabile di anagrafica che ha tali attributi
8857 TYPE(vol7d_varvect) :: anavarattr
8858!> vettore descrittore della dimensione variabile di dati
8859 TYPE(vol7d_varvect) :: dativar
8860!> vettore descrittore della dimensione attributo delle variabili di dati
8861 TYPE(vol7d_varvect) :: datiattr
8862!> vettore descrittore della dimensione variabile di dati che ha tali attributi
8863 TYPE(vol7d_varvect) :: dativarattr
8864
8865!> volume di anagrafica a valori reali
8866 REAL,POINTER :: volanar(:,:,:)
8867!> volume di anagrafica a valori a doppia precisione
8868 DOUBLE PRECISION,POINTER :: volanad(:,:,:)
8869!> volume di anagrafica a valori interi
8870 INTEGER,POINTER :: volanai(:,:,:)
8871!> volume di anagrafica a valori byte
8872 INTEGER(kind=int_b),POINTER :: volanab(:,:,:)
8873!> volume di anagrafica a valori carattere
8874 CHARACTER(len=vol7d_cdatalen),POINTER :: volanac(:,:,:)
8875
8876!> volume di attributi di anagrafica a valori reali
8877 REAL,POINTER :: volanaattrr(:,:,:,:)
8878!> volume di attributi di anagrafica a valori a doppia precisione
8879 DOUBLE PRECISION,POINTER :: volanaattrd(:,:,:,:)
8880!> volume di attributi di anagrafica a valori interi
8881 INTEGER,POINTER :: volanaattri(:,:,:,:)
8882!> volume di attributi di anagrafica a valori byte
8883 INTEGER(kind=int_b),POINTER :: volanaattrb(:,:,:,:)
8884!> volume di attributi di anagrafica a valori carattere
8885 CHARACTER(len=vol7d_cdatalen),POINTER :: volanaattrc(:,:,:,:)
8886
8887!> volume di dati a valori reali
8888 REAL,POINTER :: voldatir(:,:,:,:,:,:) ! sono i dati
8889!> volume di dati a valori a doppia precisione
8890 DOUBLE PRECISION,POINTER :: voldatid(:,:,:,:,:,:)
8891!> volume di dati a valori interi
8892 INTEGER,POINTER :: voldatii(:,:,:,:,:,:)
8893!> volume di dati a valori byte
8894 INTEGER(kind=int_b),POINTER :: voldatib(:,:,:,:,:,:)
8895!> volume di dati a valori carattere
8896 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatic(:,:,:,:,:,:)
8897
8898!> volume di attributi di dati a valori reali
8899 REAL,POINTER :: voldatiattrr(:,:,:,:,:,:,:)
8900!> volume di attributi di dati a valori a doppia precisione
8901 DOUBLE PRECISION,POINTER :: voldatiattrd(:,:,:,:,:,:,:)
8902!> volume di attributi di dati a valori interi
8903 INTEGER,POINTER :: voldatiattri(:,:,:,:,:,:,:)
8904!> volume di attributi di dati a valori byte
8905 INTEGER(kind=int_b),POINTER :: voldatiattrb(:,:,:,:,:,:,:)
8906!> volume di attributi di dati a valori carattere
8907 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatiattrc(:,:,:,:,:,:,:)
8908
8909!> time definition; 0=time is reference time, 1=time is validity time
8910 integer :: time_definition
8911
8912END TYPE vol7d
8913
8914!> Costruttore per la classe vol7d.
8915!! Deve essere richiamato
8916!! per tutti gli oggetti di questo tipo definiti in un programma.
8917INTERFACE init
8918 MODULE PROCEDURE vol7d_init
8919END INTERFACE
8920
8921!> Distruttore per la classe vol7d.
8922INTERFACE delete
8923 MODULE PROCEDURE vol7d_delete
8924END INTERFACE
8925
8926!> Scrittura su file.
8927INTERFACE export
8928 MODULE PROCEDURE vol7d_write_on_file
8929END INTERFACE
8930
8931!> Lettura da file.
8932INTERFACE import
8933 MODULE PROCEDURE vol7d_read_from_file
8934END INTERFACE
8935
8936!>Print object
8937INTERFACE display
8938 MODULE PROCEDURE vol7d_display, dat_display, dat_vect_display
8939END INTERFACE
8940
8941!>Represent data in a pretty string
8942INTERFACE to_char
8943 MODULE PROCEDURE to_char_dat
8944END INTERFACE
8945
8946!>doubleprecision data conversion
8947INTERFACE doubledat
8948 MODULE PROCEDURE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
8949END INTERFACE
8950
8951!>real data conversion
8952INTERFACE realdat
8953 MODULE PROCEDURE realdatd,realdatr,realdati,realdatb,realdatc
8954END INTERFACE
8955
8956!>integer data conversion
8957INTERFACE integerdat
8958 MODULE PROCEDURE integerdatd,integerdatr,integerdati,integerdatb,integerdatc
8959END INTERFACE
8960
8961!>copy object
8962INTERFACE copy
8963 MODULE PROCEDURE vol7d_copy
8964END INTERFACE
8965
8966!> Test for a missing volume
8967INTERFACE c_e
8968 MODULE PROCEDURE vol7d_c_e
8969END INTERFACE
8970
8971!> Check for problems
8972!! return 0 if all check passed
8973!! print diagnostics with log4f
8974INTERFACE check
8975 MODULE PROCEDURE vol7d_check
8976END INTERFACE
8977
8978!> Reduce some dimensions (level and timerage) for semplification (rounding).
8979!! You can use this for simplify and use variables in computation like alchimia
8980!! where fields have to be on the same coordinate
8981!! It return real or character data only: if input is charcter data only it return character otherwise il return
8982!! all the data converted to real.
8983!! examples:
8984!! means in time for short periods and istantaneous values
8985!! 2 meter and surface levels
8986!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
8987!! will be taken (order is by icreasing var index).
8988!! You can use predefined values for classic semplification
8989!! almost_equal_levels and almost_equal_timeranges
8990!! The level or timerange in output will be defined by the first element of level and timerange list
8991INTERFACE rounding
8992 MODULE PROCEDURE v7d_rounding
8993END INTERFACE
8994
8995!!$INTERFACE get_volana
8996!!$ MODULE PROCEDURE vol7d_get_volanar, vol7d_get_volanad, vol7d_get_volanai, &
8997!!$ vol7d_get_volanab, vol7d_get_volanac
8998!!$END INTERFACE
8999!!$
9000!!$INTERFACE get_voldati
9001!!$ MODULE PROCEDURE vol7d_get_voldatir, vol7d_get_voldatid, vol7d_get_voldatii, &
9002!!$ vol7d_get_voldatib, vol7d_get_voldatic
9003!!$END INTERFACE
9004!!$
9005!!$INTERFACE get_volanaattr
9006!!$ MODULE PROCEDURE vol7d_get_volanaattrr, vol7d_get_volanaattrd, &
9007!!$ vol7d_get_volanaattri, vol7d_get_volanaattrb, vol7d_get_volanaattrc
9008!!$END INTERFACE
9009!!$
9010!!$INTERFACE get_voldatiattr
9011!!$ MODULE PROCEDURE vol7d_get_voldatiattrr, vol7d_get_voldatiattrd, &
9012!!$ vol7d_get_voldatiattri, vol7d_get_voldatiattrb, vol7d_get_voldatiattrc
9013!!$END INTERFACE
9014
9015PRIVATE vol7d_get_volr, vol7d_get_vold, vol7d_get_voli, vol7d_get_volb, &
9016 vol7d_get_volc, &
9017 volptr1dr, volptr2dr, volptr3dr, volptr4dr, volptr5dr, volptr6dr, volptr7dr, &
9018 volptr1dd, volptr2dd, volptr3dd, volptr4dd, volptr5dd, volptr6dd, volptr7dd, &
9019 volptr1di, volptr2di, volptr3di, volptr4di, volptr5di, volptr6di, volptr7di, &
9020 volptr1db, volptr2db, volptr3db, volptr4db, volptr5db, volptr6db, volptr7db, &
9021 volptr1dc, volptr2dc, volptr3dc, volptr4dc, volptr5dc, volptr6dc, volptr7dc, &
9022 vol7d_nullifyr, vol7d_nullifyd, vol7d_nullifyi, vol7d_nullifyb, vol7d_nullifyc, &
9023 vol7d_init, vol7d_delete, vol7d_write_on_file, vol7d_read_from_file, &
9024 vol7d_check_alloc_ana, vol7d_force_alloc_ana, &
9025 vol7d_check_alloc_dati, vol7d_force_alloc_dati, vol7d_force_alloc, &
9026 vol7d_display, dat_display, dat_vect_display, &
9027 to_char_dat, vol7d_check
9028
9029PRIVATE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
9030
9031PRIVATE vol7d_c_e
9032
9033CONTAINS
9034
9035
9036!> Inizializza un oggetto di tipo vol7d.
9037!! Non riceve alcun parametro tranne l'oggetto stesso. Attenzione, è necessario
9038!! comunque chiamare sempre il costruttore per evitare di avere dei puntatori in
9039!! uno stato indefinito.
9040SUBROUTINE vol7d_init(this,time_definition)
9041TYPE(vol7d),intent(out) :: this !< oggetto da inizializzare
9042INTEGER,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)
9043
9044CALL init(this%anavar)
9045CALL init(this%anaattr)
9046CALL init(this%anavarattr)
9047CALL init(this%dativar)
9048CALL init(this%datiattr)
9049CALL init(this%dativarattr)
9050
9051NULLIFY(this%ana, this%time, this%level, this%timerange, this%network)
9052
9053NULLIFY(this%volanar, this%volanaattrr, this%voldatir, this%voldatiattrr)
9054NULLIFY(this%volanad, this%volanaattrd, this%voldatid, this%voldatiattrd)
9055NULLIFY(this%volanai, this%volanaattri, this%voldatii, this%voldatiattri)
9056NULLIFY(this%volanab, this%volanaattrb, this%voldatib, this%voldatiattrb)
9057NULLIFY(this%volanac, this%volanaattrc, this%voldatic, this%voldatiattrc)
9058
9059if(present(time_definition)) then
9060 this%time_definition=time_definition
9061else
9062 this%time_definition=1 !default to validity time
9063end if
9064
9065END SUBROUTINE vol7d_init
9066
9067
9068!> Distrugge l'oggetto in maniera pulita, liberando l'eventuale memoria
9069!! dinamicamente allocata. Permette di distruggere la sola parte di dati
9070!! mantenendo l'anagrafica.
9071ELEMENTAL SUBROUTINE vol7d_delete(this, dataonly)
9072TYPE(vol7d),intent(inout) :: this !< oggetto da distruggere
9073LOGICAL, INTENT(in), OPTIONAL :: dataonly !< dealloca solo i dati, tenendo l'anagrafica, (default \c .FALSE.)
9074
9075
9076IF (.NOT. optio_log(dataonly)) THEN
9077 IF (ASSOCIATED(this%volanar)) DEALLOCATE(this%volanar)
9078 IF (ASSOCIATED(this%volanad)) DEALLOCATE(this%volanad)
9079 IF (ASSOCIATED(this%volanai)) DEALLOCATE(this%volanai)
9080 IF (ASSOCIATED(this%volanab)) DEALLOCATE(this%volanab)
9081 IF (ASSOCIATED(this%volanac)) DEALLOCATE(this%volanac)
9082 IF (ASSOCIATED(this%volanaattrr)) DEALLOCATE(this%volanaattrr)
9083 IF (ASSOCIATED(this%volanaattrd)) DEALLOCATE(this%volanaattrd)
9084 IF (ASSOCIATED(this%volanaattri)) DEALLOCATE(this%volanaattri)
9085 IF (ASSOCIATED(this%volanaattrb)) DEALLOCATE(this%volanaattrb)
9086 IF (ASSOCIATED(this%volanaattrc)) DEALLOCATE(this%volanaattrc)
9087ENDIF
9088IF (ASSOCIATED(this%voldatir)) DEALLOCATE(this%voldatir)
9089IF (ASSOCIATED(this%voldatid)) DEALLOCATE(this%voldatid)
9090IF (ASSOCIATED(this%voldatii)) DEALLOCATE(this%voldatii)
9091IF (ASSOCIATED(this%voldatib)) DEALLOCATE(this%voldatib)
9092IF (ASSOCIATED(this%voldatic)) DEALLOCATE(this%voldatic)
9093IF (ASSOCIATED(this%voldatiattrr)) DEALLOCATE(this%voldatiattrr)
9094IF (ASSOCIATED(this%voldatiattrd)) DEALLOCATE(this%voldatiattrd)
9095IF (ASSOCIATED(this%voldatiattri)) DEALLOCATE(this%voldatiattri)
9096IF (ASSOCIATED(this%voldatiattrb)) DEALLOCATE(this%voldatiattrb)
9097IF (ASSOCIATED(this%voldatiattrc)) DEALLOCATE(this%voldatiattrc)
9098
9099IF (.NOT. optio_log(dataonly)) THEN
9100 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
9101 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
9102ENDIF
9103IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
9104IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
9105IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
9106
9107IF (.NOT. optio_log(dataonly)) THEN
9108 CALL delete(this%anavar)
9109 CALL delete(this%anaattr)
9110 CALL delete(this%anavarattr)
9111ENDIF
9112CALL delete(this%dativar)
9113CALL delete(this%datiattr)
9114CALL delete(this%dativarattr)
9115
9116END SUBROUTINE vol7d_delete
9117
9118
9119
9120integer function vol7d_check(this)
9121TYPE(vol7d),intent(in) :: this !< object to check
9122integer :: i,j,k,l,m,n
9123
9124vol7d_check=0
9125
9126if (associated(this%voldatii)) then
9127do i = 1,size(this%voldatii,1)
9128 do j = 1,size(this%voldatii,2)
9129 do k = 1,size(this%voldatii,3)
9130 do l = 1,size(this%voldatii,4)
9131 do m = 1,size(this%voldatii,5)
9132 do n = 1,size(this%voldatii,6)
9133 if (this%voldatii(i,j,k,l,m,n) /= this%voldatii(i,j,k,l,m,n) ) then
9134 CALL l4f_log(l4f_warn,"check: abnormal value at voldatii("&
9135 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
9136 vol7d_check=1
9137 end if
9138 end do
9139 end do
9140 end do
9141 end do
9142 end do
9143end do
9144end if
9145
9146
9147if (associated(this%voldatir)) then
9148do i = 1,size(this%voldatir,1)
9149 do j = 1,size(this%voldatir,2)
9150 do k = 1,size(this%voldatir,3)
9151 do l = 1,size(this%voldatir,4)
9152 do m = 1,size(this%voldatir,5)
9153 do n = 1,size(this%voldatir,6)
9154 if (this%voldatir(i,j,k,l,m,n) /= this%voldatir(i,j,k,l,m,n) ) then
9155 CALL l4f_log(l4f_warn,"check: abnormal value at voldatir("&
9156 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
9157 vol7d_check=2
9158 end if
9159 end do
9160 end do
9161 end do
9162 end do
9163 end do
9164end do
9165end if
9166
9167if (associated(this%voldatid)) then
9168do i = 1,size(this%voldatid,1)
9169 do j = 1,size(this%voldatid,2)
9170 do k = 1,size(this%voldatid,3)
9171 do l = 1,size(this%voldatid,4)
9172 do m = 1,size(this%voldatid,5)
9173 do n = 1,size(this%voldatid,6)
9174 if (this%voldatid(i,j,k,l,m,n) /= this%voldatid(i,j,k,l,m,n) ) then
9175 CALL l4f_log(l4f_warn,"check: abnormal value at voldatid("&
9176 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
9177 vol7d_check=3
9178 end if
9179 end do
9180 end do
9181 end do
9182 end do
9183 end do
9184end do
9185end if
9186
9187if (associated(this%voldatib)) then
9188do i = 1,size(this%voldatib,1)
9189 do j = 1,size(this%voldatib,2)
9190 do k = 1,size(this%voldatib,3)
9191 do l = 1,size(this%voldatib,4)
9192 do m = 1,size(this%voldatib,5)
9193 do n = 1,size(this%voldatib,6)
9194 if (this%voldatib(i,j,k,l,m,n) /= this%voldatib(i,j,k,l,m,n) ) then
9195 CALL l4f_log(l4f_warn,"check: abnormal value at voldatib("&
9196 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
9197 vol7d_check=4
9198 end if
9199 end do
9200 end do
9201 end do
9202 end do
9203 end do
9204end do
9205end if
9206
9207end function vol7d_check
9208
9209
9210
9211!TODO da completare ! aborta se i volumi sono allocati a dimensione 0
9212!> stampa a video una sintesi del contenuto
9213SUBROUTINE vol7d_display(this)
9214TYPE(vol7d),intent(in) :: this !< oggetto da visualizzare
9215integer :: i
9216
9217REAL :: rdat
9218DOUBLE PRECISION :: ddat
9219INTEGER :: idat
9220INTEGER(kind=int_b) :: bdat
9221CHARACTER(len=vol7d_cdatalen) :: cdat
9222
9223
9224print*,"<<<<<<<<<<<<<<<<<<< vol7d object >>>>>>>>>>>>>>>>>>>>"
9225if (this%time_definition == 0) then
9226 print*,"TIME DEFINITION: time is reference time"
9227else if (this%time_definition == 1) then
9228 print*,"TIME DEFINITION: time is validity time"
9229else if (this%time_definition == 2) then
9230 print*,"TIME DEFINITION: time is validity time, forecast range forced to 0"
9231else
9232 print*,"Time definition has a wrong walue:", this%time_definition
9233end if
9234
9235IF (ASSOCIATED(this%network))then
9236 print*,"---- network vector ----"
9237 print*,"elements=",size(this%network)
9238 do i=1, size(this%network)
9239 call display(this%network(i))
9240 end do
9241end IF
9242
9243IF (ASSOCIATED(this%ana))then
9244 print*,"---- ana vector ----"
9245 print*,"elements=",size(this%ana)
9246 do i=1, size(this%ana)
9247 call display(this%ana(i))
9248 end do
9249end IF
9250
9251IF (ASSOCIATED(this%time))then
9252 print*,"---- time vector ----"
9253 print*,"elements=",size(this%time)
9254 do i=1, size(this%time)
9255 call display(this%time(i))
9256 end do
9257end if
9258
9259IF (ASSOCIATED(this%level)) then
9260 print*,"---- level vector ----"
9261 print*,"elements=",size(this%level)
9262 do i =1,size(this%level)
9263 call display(this%level(i))
9264 end do
9265end if
9266
9267IF (ASSOCIATED(this%timerange))then
9268 print*,"---- timerange vector ----"
9269 print*,"elements=",size(this%timerange)
9270 do i =1,size(this%timerange)
9271 call display(this%timerange(i))
9272 end do
9273end if
9274
9275
9276print*,"---- ana vector ----"
9277print*,""
9278print*,"->>>>>>>>> anavar -"
9279call display(this%anavar)
9280print*,""
9281print*,"->>>>>>>>> anaattr -"
9282call display(this%anaattr)
9283print*,""
9284print*,"->>>>>>>>> anavarattr -"
9285call display(this%anavarattr)
9286
9287print*,"-- ana data section (first point) --"
9288
9289idat=imiss
9290rdat=rmiss
9291ddat=dmiss
9292bdat=ibmiss
9293cdat=cmiss
9294
9295!ntime = MIN(SIZE(this%time),nprint)
9296!ntimerange = MIN(SIZE(this%timerange),nprint)
9297!nlevel = MIN(SIZE(this%level),nprint)
9298!nnetwork = MIN(SIZE(this%network),nprint)
9299!nana = MIN(SIZE(this%ana),nprint)
9300
9301IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0) THEN
9302if (associated(this%volanai)) then
9303 do i=1,size(this%anavar%i)
9304 idat=this%volanai(1,i,1)
9305 if (associated(this%anavar%i)) call display(this%anavar%i(i),idat,rdat,ddat,bdat,cdat)
9306 end do
9307end if
9308idat=imiss
9309
9310if (associated(this%volanar)) then
9311 do i=1,size(this%anavar%r)
9312 rdat=this%volanar(1,i,1)
9313 if (associated(this%anavar%r)) call display(this%anavar%r(i),idat,rdat,ddat,bdat,cdat)
9314 end do
9315end if
9316rdat=rmiss
9317
9318if (associated(this%volanad)) then
9319 do i=1,size(this%anavar%d)
9320 ddat=this%volanad(1,i,1)
9321 if (associated(this%anavar%d)) call display(this%anavar%d(i),idat,rdat,ddat,bdat,cdat)
9322 end do
9323end if
9324ddat=dmiss
9325
9326if (associated(this%volanab)) then
9327 do i=1,size(this%anavar%b)
9328 bdat=this%volanab(1,i,1)
9329 if (associated(this%anavar%b)) call display(this%anavar%b(i),idat,rdat,ddat,bdat,cdat)
9330 end do
9331end if
9332bdat=ibmiss
9333
9334if (associated(this%volanac)) then
9335 do i=1,size(this%anavar%c)
9336 cdat=this%volanac(1,i,1)
9337 if (associated(this%anavar%c)) call display(this%anavar%c(i),idat,rdat,ddat,bdat,cdat)
9338 end do
9339end if
9340cdat=cmiss
9341ENDIF
9342
9343print*,"---- data vector ----"
9344print*,""
9345print*,"->>>>>>>>> dativar -"
9346call display(this%dativar)
9347print*,""
9348print*,"->>>>>>>>> datiattr -"
9349call display(this%datiattr)
9350print*,""
9351print*,"->>>>>>>>> dativarattr -"
9352call display(this%dativarattr)
9353
9354print*,"-- data data section (first point) --"
9355
9356idat=imiss
9357rdat=rmiss
9358ddat=dmiss
9359bdat=ibmiss
9360cdat=cmiss
9361
9362IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0 .AND. size(this%time) > 0 &
9363 .AND. size(this%level) > 0 .AND. size(this%timerange) > 0) THEN
9364if (associated(this%voldatii)) then
9365 do i=1,size(this%dativar%i)
9366 idat=this%voldatii(1,1,1,1,i,1)
9367 if (associated(this%dativar%i)) call display(this%dativar%i(i),idat,rdat,ddat,bdat,cdat)
9368 end do
9369end if
9370idat=imiss
9371
9372if (associated(this%voldatir)) then
9373 do i=1,size(this%dativar%r)
9374 rdat=this%voldatir(1,1,1,1,i,1)
9375 if (associated(this%dativar%r)) call display(this%dativar%r(i),idat,rdat,ddat,bdat,cdat)
9376 end do
9377end if
9378rdat=rmiss
9379
9380if (associated(this%voldatid)) then
9381 do i=1,size(this%dativar%d)
9382 ddat=this%voldatid(1,1,1,1,i,1)
9383 if (associated(this%dativar%d)) call display(this%dativar%d(i),idat,rdat,ddat,bdat,cdat)
9384 end do
9385end if
9386ddat=dmiss
9387
9388if (associated(this%voldatib)) then
9389 do i=1,size(this%dativar%b)
9390 bdat=this%voldatib(1,1,1,1,i,1)
9391 if (associated(this%dativar%b)) call display(this%dativar%b(i),idat,rdat,ddat,bdat,cdat)
9392 end do
9393end if
9394bdat=ibmiss
9395
9396if (associated(this%voldatic)) then
9397 do i=1,size(this%dativar%c)
9398 cdat=this%voldatic(1,1,1,1,i,1)
9399 if (associated(this%dativar%c)) call display(this%dativar%c(i),idat,rdat,ddat,bdat,cdat)
9400 end do
9401end if
9402cdat=cmiss
9403ENDIF
9404
9405print*,"<<<<<<<<<<<<<<<<<<< END vol7d object >>>>>>>>>>>>>>>>>>>>"
9406
9407END SUBROUTINE vol7d_display
9408
9409
9410!> stampa a video una sintesi del contenuto
9411SUBROUTINE dat_display(this,idat,rdat,ddat,bdat,cdat)
9412TYPE(vol7d_var),intent(in) :: this !< oggetto da visualizzare
9413!> real
9414REAL :: rdat
9415!> double precision
9416DOUBLE PRECISION :: ddat
9417!> integer
9418INTEGER :: idat
9419!> byte
9420INTEGER(kind=int_b) :: bdat
9421!> character
9422CHARACTER(len=*) :: cdat
9423
9424print *, to_char_dat(this,idat,rdat,ddat,bdat,cdat)
9425
9426end SUBROUTINE dat_display
9427
9428!> stampa a video una sintesi del contenuto
9429SUBROUTINE dat_vect_display(this,idat,rdat,ddat,bdat,cdat)
9430
9431TYPE(vol7d_var),intent(in) :: this(:) !< oggetto da visualizzare
9432!> real
9433REAL :: rdat(:)
9434!> double precision
9435DOUBLE PRECISION :: ddat(:)
9436!> integer
9437INTEGER :: idat(:)
9438!> byte
9439INTEGER(kind=int_b) :: bdat(:)
9440!> character
9441CHARACTER(len=*):: cdat(:)
9442
9443integer :: i
9444
9445do i =1,size(this)
9446 call display(this(i),idat(i),rdat(i),ddat(i),bdat(i),cdat(i))
9447end do
9448
9449end SUBROUTINE dat_vect_display
9450
9451
9452FUNCTION to_char_dat(this,idat,rdat,ddat,bdat,cdat)
9453#ifdef HAVE_DBALLE
9454USE dballef
9455#endif
9456TYPE(vol7d_var),INTENT(in) :: this
9457!> real
9458REAL :: rdat
9459!> double precision
9460DOUBLE PRECISION :: ddat
9461!> integer
9462INTEGER :: idat
9463!> byte
9464INTEGER(kind=int_b) :: bdat
9465!> character
9466CHARACTER(len=*) :: cdat
9467CHARACTER(len=80) :: to_char_dat
9468
9469CHARACTER(len=LEN(to_char_dat)) :: to_char_tmp
9470
9471
9472#ifdef HAVE_DBALLE
9473INTEGER :: handle, ier
9474
9475handle = 0
9476to_char_dat="VALUE: "
9477
9478if (c_e(idat)) to_char_dat=trim(to_char_dat)//" ;int> "//trim(to_char(idat))
9479if (c_e(rdat)) to_char_dat=trim(to_char_dat)//" ;real> "//trim(to_char(rdat))
9480if (c_e(ddat)) to_char_dat=trim(to_char_dat)//" ;double> "//trim(to_char(ddat))
9481if (c_e(bdat)) to_char_dat=trim(to_char_dat)//" ;byte> "//trim(to_char(bdat))
9482
9483if ( c_e(cdat))then
9484 ier = idba_messaggi(handle,"/dev/null", "w", "BUFR")
9485 ier = idba_spiegab(handle,this%btable,cdat,to_char_tmp)
9486 ier = idba_fatto(handle)
9487 to_char_dat=trim(to_char_dat)//" ;char> "//trim(to_char_tmp)
9488endif
9489
9490#else
9491
9492to_char_dat="VALUE: "
9493if (c_e(idat)) to_char_dat=trim(to_char_dat)//" ;int> "//trim(to_char(idat))
9494if (c_e(rdat)) to_char_dat=trim(to_char_dat)//" ;real> "//trim(to_char(rdat))
9495if (c_e(ddat)) to_char_dat=trim(to_char_dat)//" ;double> "//trim(to_char(ddat))
9496if (c_e(bdat)) to_char_dat=trim(to_char_dat)//" ;byte> "//trim(to_char(bdat))
9497if (c_e(cdat)) to_char_dat=trim(to_char_dat)//" ;char> "//trim(cdat)
9498
9499#endif
9500
9501END FUNCTION to_char_dat
9502
9503
9504!> Tests whether anything has ever been assigned to a vol7d object
9505!! (.TRUE.) or it is as clean as after an init (.FALSE.).
9506FUNCTION vol7d_c_e(this) RESULT(c_e)
9507TYPE(vol7d), INTENT(in) :: this
9508
9509LOGICAL :: c_e
9510
9511c_e = ASSOCIATED(this%ana) .OR. ASSOCIATED(this%time) .OR. &
9512 ASSOCIATED(this%level) .OR. ASSOCIATED(this%timerange) .OR. &
9513 ASSOCIATED(this%network) .OR. &
9514 ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
9515 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
9516 ASSOCIATED(this%anavar%c) .OR. &
9517 ASSOCIATED(this%anaattr%r) .OR. ASSOCIATED(this%anaattr%d) .OR. &
9518 ASSOCIATED(this%anaattr%i) .OR. ASSOCIATED(this%anaattr%b) .OR. &
9519 ASSOCIATED(this%anaattr%c) .OR. &
9520 ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
9521 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
9522 ASSOCIATED(this%dativar%c) .OR. &
9523 ASSOCIATED(this%datiattr%r) .OR. ASSOCIATED(this%datiattr%d) .OR. &
9524 ASSOCIATED(this%datiattr%i) .OR. ASSOCIATED(this%datiattr%b) .OR. &
9525 ASSOCIATED(this%datiattr%c)
9526
9527END FUNCTION vol7d_c_e
9528
9529
9530!> Metodo per allocare i descrittori delle 7 dimensioni.
9531!! Riceve un grande numero di parametri opzionali che
9532!! indicano quali descrittori allocare e con quale estensione;
9533!! i descrittori non specificati non vengono toccati.
9534!! Può essere quindi chiamato più volte allocando via via
9535!! descrittori relativi a dimensioni diverse.
9536!! Se un descrittore richiesto è già allocato, viene deallocato
9537!! (perdendone l'eventuale contenuto) e riallocato con l'estensione
9538!! richiesta.
9539!! Per i descrittori relativi a dimensioni che non siano variabili o attributi,
9540!! è possibile specificare l'estensione di una dimensione a 0,
9541!! in tal caso il descrittore viene comunque allocato con lunghezza nulla,
9542!! che è diverso da non allocarlo. Per i descrittori di variabili e attributi
9543!! passare un'estensione 0 equivale a non fornire il parametro.
9544!! Avere uno o più descrittori dimensionati con estensione nulla fa sì
9545!! che anche il volume dati successivamente allocato abbia estensione nulla;
9546!! sebbene ciò appaia inutile, un volume del genere può in realtà servire,
9547!! in associazione ai metodi ::vol7d_merge o ::vol7d_append per estendere
9548!! un volume esistente aggiungendo elementi in alcune dimensioni (quelle
9549!! a estensione non nulla, ovviamente) e mantenendo invariato tutto il resto.
9550!! Per quanto riguarda i descrittori delle dimensioni relative alle
9551!! variabili, la relativa estensione è specificata con la nomenclatura
9552!! \a n&lt;x&gt;&lt;y&gt;&lt;z&gt; dove &lt;x&gt; può valere:
9553!! - \a ana per variabili relative a voumi di anagrafica
9554!! - \a dati per variabili relative a voumi di dati
9555!!
9556!! &lt;y&gt; può valere:
9557!! - \a var per variabili
9558!! - \a attr per attributi
9559!! - \a varattr variabili aventi attributi nei volumi di attributi
9560!!
9561!! &lt;z&gt; può valere:
9562!! - \a r per variabili o attributi a valori reali
9563!! - \a d per variabili o attributi a valori a doppia precisione
9564!! - \a i per variabili o attributi a valori interi
9565!! - \a b per variabili o attributi a valori byte
9566!! - \a c per variabili o attributi a valori carattere
9567!!
9568SUBROUTINE vol7d_alloc(this, nana, ntime, nlevel, ntimerange, nnetwork, &
9569 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
9570 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
9571 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
9572 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
9573 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
9574 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc, &
9575 ini)
9576TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i descrittori
9577INTEGER,INTENT(in),OPTIONAL :: nana !< estensione della dimensione anagrafica
9578INTEGER,INTENT(in),OPTIONAL :: ntime !< estensione della dimensione tempo
9579INTEGER,INTENT(in),OPTIONAL :: nlevel !< estensione della dimensione livello varticale
9580INTEGER,INTENT(in),OPTIONAL :: ntimerange !< estensione della dimensione intervallo temporale (timerange)
9581INTEGER,INTENT(in),OPTIONAL :: nnetwork !< estensione della dimensione rete
9582!> estensione delle possibili dimensioni variabile
9583INTEGER,INTENT(in),OPTIONAL :: &
9584 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
9585 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
9586 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
9587 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
9588 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
9589 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc
9590LOGICAL,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
9591
9592INTEGER :: i
9593LOGICAL :: linit
9594
9595IF (PRESENT(ini)) THEN
9596 linit = ini
9597ELSE
9598 linit = .false.
9599ENDIF
9600
9601! Dimensioni principali
9602IF (PRESENT(nana)) THEN
9603 IF (nana >= 0) THEN
9604 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
9605 ALLOCATE(this%ana(nana))
9606 IF (linit) THEN
9607 DO i = 1, nana
9608 CALL init(this%ana(i))
9609 ENDDO
9610 ENDIF
9611 ENDIF
9612ENDIF
9613IF (PRESENT(ntime)) THEN
9614 IF (ntime >= 0) THEN
9615 IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
9616 ALLOCATE(this%time(ntime))
9617 IF (linit) THEN
9618 DO i = 1, ntime
9619 CALL init(this%time(i))
9620 ENDDO
9621 ENDIF
9622 ENDIF
9623ENDIF
9624IF (PRESENT(nlevel)) THEN
9625 IF (nlevel >= 0) THEN
9626 IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
9627 ALLOCATE(this%level(nlevel))
9628 IF (linit) THEN
9629 DO i = 1, nlevel
9630 CALL init(this%level(i))
9631 ENDDO
9632 ENDIF
9633 ENDIF
9634ENDIF
9635IF (PRESENT(ntimerange)) THEN
9636 IF (ntimerange >= 0) THEN
9637 IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
9638 ALLOCATE(this%timerange(ntimerange))
9639 IF (linit) THEN
9640 DO i = 1, ntimerange
9641 CALL init(this%timerange(i))
9642 ENDDO
9643 ENDIF
9644 ENDIF
9645ENDIF
9646IF (PRESENT(nnetwork)) THEN
9647 IF (nnetwork >= 0) THEN
9648 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
9649 ALLOCATE(this%network(nnetwork))
9650 IF (linit) THEN
9651 DO i = 1, nnetwork
9652 CALL init(this%network(i))
9653 ENDDO
9654 ENDIF
9655 ENDIF
9656ENDIF
9657! Dimensioni dei tipi delle variabili
9658CALL vol7d_varvect_alloc(this%anavar, nanavarr, nanavard, &
9659 nanavari, nanavarb, nanavarc, ini)
9660CALL vol7d_varvect_alloc(this%anaattr, nanaattrr, nanaattrd, &
9661 nanaattri, nanaattrb, nanaattrc, ini)
9662CALL vol7d_varvect_alloc(this%anavarattr, nanavarattrr, nanavarattrd, &
9663 nanavarattri, nanavarattrb, nanavarattrc, ini)
9664CALL vol7d_varvect_alloc(this%dativar, ndativarr, ndativard, &
9665 ndativari, ndativarb, ndativarc, ini)
9666CALL vol7d_varvect_alloc(this%datiattr, ndatiattrr, ndatiattrd, &
9667 ndatiattri, ndatiattrb, ndatiattrc, ini)
9668CALL vol7d_varvect_alloc(this%dativarattr, ndativarattrr, ndativarattrd, &
9669 ndativarattri, ndativarattrb, ndativarattrc, ini)
9670
9671END SUBROUTINE vol7d_alloc
9672
9673
9674FUNCTION vol7d_check_alloc_ana(this)
9675TYPE(vol7d),INTENT(in) :: this
9676LOGICAL :: vol7d_check_alloc_ana
9677
9678vol7d_check_alloc_ana = ASSOCIATED(this%ana) .AND. ASSOCIATED(this%network)
9679
9680END FUNCTION vol7d_check_alloc_ana
9681
9682SUBROUTINE vol7d_force_alloc_ana(this, ini)
9683TYPE(vol7d),INTENT(inout) :: this
9684LOGICAL,INTENT(in),OPTIONAL :: ini
9685
9686! Alloco i descrittori minimi per avere un volume di anagrafica
9687IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=1, ini=ini)
9688IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=1, ini=ini)
9689
9690END SUBROUTINE vol7d_force_alloc_ana
9691
9692
9693FUNCTION vol7d_check_alloc_dati(this)
9694TYPE(vol7d),INTENT(in) :: this
9695LOGICAL :: vol7d_check_alloc_dati
9696
9697vol7d_check_alloc_dati = vol7d_check_alloc_ana(this) .AND. &
9698 ASSOCIATED(this%time) .AND. ASSOCIATED(this%level) .AND. &
9699 ASSOCIATED(this%timerange)
9700
9701END FUNCTION vol7d_check_alloc_dati
9702
9703SUBROUTINE vol7d_force_alloc_dati(this, ini)
9704TYPE(vol7d),INTENT(inout) :: this
9705LOGICAL,INTENT(in),OPTIONAL :: ini
9706
9707! Alloco i descrittori minimi per avere un volume di dati
9708CALL vol7d_force_alloc_ana(this, ini)
9709IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=1, ini=ini)
9710IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=1, ini=ini)
9711IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=1, ini=ini)
9712
9713END SUBROUTINE vol7d_force_alloc_dati
9714
9715
9716SUBROUTINE vol7d_force_alloc(this)
9717TYPE(vol7d),INTENT(inout) :: this
9718
9719! If anything really not allocated yet, allocate with size 0
9720IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=0)
9721IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=0)
9722IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=0)
9723IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=0)
9724IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=0)
9725
9726END SUBROUTINE vol7d_force_alloc
9727
9728
9729FUNCTION vol7d_check_vol(this)
9730TYPE(vol7d),INTENT(in) :: this !< oggetto da controllare
9731LOGICAL :: vol7d_check_vol
9732
9733vol7d_check_vol = c_e(this)
9734
9735! Anagrafica
9736IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
9737 vol7d_check_vol = .false.
9738ENDIF
9739
9740IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
9741 vol7d_check_vol = .false.
9742ENDIF
9743
9744IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
9745 vol7d_check_vol = .false.
9746ENDIF
9747
9748IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
9749 vol7d_check_vol = .false.
9750ENDIF
9751
9752IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
9753 vol7d_check_vol = .false.
9754ENDIF
9755IF (ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
9756 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
9757 ASSOCIATED(this%anavar%c)) THEN
9758 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_ana(this)
9759ENDIF
9760
9761! Attributi dell'anagrafica
9762IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
9763 .NOT.ASSOCIATED(this%volanaattrr)) THEN
9764 vol7d_check_vol = .false.
9765ENDIF
9766
9767IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
9768 .NOT.ASSOCIATED(this%volanaattrd)) THEN
9769 vol7d_check_vol = .false.
9770ENDIF
9771
9772IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
9773 .NOT.ASSOCIATED(this%volanaattri)) THEN
9774 vol7d_check_vol = .false.
9775ENDIF
9776
9777IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
9778 .NOT.ASSOCIATED(this%volanaattrb)) THEN
9779 vol7d_check_vol = .false.
9780ENDIF
9781
9782IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
9783 .NOT.ASSOCIATED(this%volanaattrc)) THEN
9784 vol7d_check_vol = .false.
9785ENDIF
9786
9787! Dati
9788IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
9789 vol7d_check_vol = .false.
9790ENDIF
9791
9792IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
9793 vol7d_check_vol = .false.
9794ENDIF
9795
9796IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
9797 vol7d_check_vol = .false.
9798ENDIF
9799
9800IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
9801 vol7d_check_vol = .false.
9802ENDIF
9803
9804IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
9805 vol7d_check_vol = .false.
9806ENDIF
9807
9808! Attributi dei dati
9809IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
9810 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
9811 vol7d_check_vol = .false.
9812ENDIF
9813
9814IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
9815 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
9816 vol7d_check_vol = .false.
9817ENDIF
9818
9819IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
9820 .NOT.ASSOCIATED(this%voldatiattri)) THEN
9821 vol7d_check_vol = .false.
9822ENDIF
9823
9824IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
9825 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
9826 vol7d_check_vol = .false.
9827ENDIF
9828
9829IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
9830 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
9831 vol7d_check_vol = .false.
9832ENDIF
9833IF (ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
9834 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
9835 ASSOCIATED(this%dativar%c)) THEN
9836 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_dati(this)
9837ENDIF
9838
9839END FUNCTION vol7d_check_vol
9840
9841
9842!> Metodo per allocare i volumi richiesti di variabili e attributi per
9843!! anagrafica e dati.
9844!! Se alcuni dei descrittori relativi alle dimensioni anagrafica,
9845!! livello verticale, tempo, intervallo temporale (timerange), rete non sono
9846!! stati richiesti preventivamente con la ::vol7d_alloc, essi vengono allocati
9847!! automaticamente da questo metodo
9848!! con estensione di default pari a 1 (non 0!), questo significa, ad esempio,
9849!! che se prevedo di avere soli dati superficiali, cioè ad un solo livello
9850!! verticale, o una sola rete di stazioni, non devo preoccuparmi di
9851!! specificare questa informazione.
9852!! Tra i 20 possibili volumi allocabili
9853!! ((variabili,attributi)*(anagrafica,dati)*(r,d,i,b,c)=20)
9854!! saranno allocati solo quelli per cui è stato precedentemente richiesto il
9855!! corrispondente descrittore variabili/attributi con la ::vol7d_alloc.
9856SUBROUTINE vol7d_alloc_vol(this, ini, inivol)
9857TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i volumi
9858LOGICAL,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
9859LOGICAL,INTENT(in),OPTIONAL :: inivol !< se fornito e vale \c .TRUE., i volumi allocati saranno inizializzati a valore mancante
9860
9861LOGICAL :: linivol
9862
9863IF (PRESENT(inivol)) THEN
9864 linivol = inivol
9865ELSE
9866 linivol = .true.
9867ENDIF
9868
9869! Anagrafica
9870IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
9871 CALL vol7d_force_alloc_ana(this, ini)
9872 ALLOCATE(this%volanar(SIZE(this%ana), SIZE(this%anavar%r), SIZE(this%network)))
9873 IF (linivol) this%volanar(:,:,:) = rmiss
9874ENDIF
9875
9876IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
9877 CALL vol7d_force_alloc_ana(this, ini)
9878 ALLOCATE(this%volanad(SIZE(this%ana), SIZE(this%anavar%d), SIZE(this%network)))
9879 IF (linivol) this%volanad(:,:,:) = rdmiss
9880ENDIF
9881
9882IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
9883 CALL vol7d_force_alloc_ana(this, ini)
9884 ALLOCATE(this%volanai(SIZE(this%ana), SIZE(this%anavar%i), SIZE(this%network)))
9885 IF (linivol) this%volanai(:,:,:) = imiss
9886ENDIF
9887
9888IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
9889 CALL vol7d_force_alloc_ana(this, ini)
9890 ALLOCATE(this%volanab(SIZE(this%ana), SIZE(this%anavar%b), SIZE(this%network)))
9891 IF (linivol) this%volanab(:,:,:) = ibmiss
9892ENDIF
9893
9894IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
9895 CALL vol7d_force_alloc_ana(this, ini)
9896 ALLOCATE(this%volanac(SIZE(this%ana), SIZE(this%anavar%c), SIZE(this%network)))
9897 IF (linivol) this%volanac(:,:,:) = cmiss
9898ENDIF
9899
9900! Attributi dell'anagrafica
9901IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
9902 .NOT.ASSOCIATED(this%volanaattrr)) THEN
9903 CALL vol7d_force_alloc_ana(this, ini)
9904 ALLOCATE(this%volanaattrr(SIZE(this%ana), SIZE(this%anavarattr%r), &
9905 SIZE(this%network), SIZE(this%anaattr%r)))
9906 IF (linivol) this%volanaattrr(:,:,:,:) = rmiss
9907ENDIF
9908
9909IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
9910 .NOT.ASSOCIATED(this%volanaattrd)) THEN
9911 CALL vol7d_force_alloc_ana(this, ini)
9912 ALLOCATE(this%volanaattrd(SIZE(this%ana), SIZE(this%anavarattr%d), &
9913 SIZE(this%network), SIZE(this%anaattr%d)))
9914 IF (linivol) this%volanaattrd(:,:,:,:) = rdmiss
9915ENDIF
9916
9917IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
9918 .NOT.ASSOCIATED(this%volanaattri)) THEN
9919 CALL vol7d_force_alloc_ana(this, ini)
9920 ALLOCATE(this%volanaattri(SIZE(this%ana), SIZE(this%anavarattr%i), &
9921 SIZE(this%network), SIZE(this%anaattr%i)))
9922 IF (linivol) this%volanaattri(:,:,:,:) = imiss
9923ENDIF
9924
9925IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
9926 .NOT.ASSOCIATED(this%volanaattrb)) THEN
9927 CALL vol7d_force_alloc_ana(this, ini)
9928 ALLOCATE(this%volanaattrb(SIZE(this%ana), SIZE(this%anavarattr%b), &
9929 SIZE(this%network), SIZE(this%anaattr%b)))
9930 IF (linivol) this%volanaattrb(:,:,:,:) = ibmiss
9931ENDIF
9932
9933IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
9934 .NOT.ASSOCIATED(this%volanaattrc)) THEN
9935 CALL vol7d_force_alloc_ana(this, ini)
9936 ALLOCATE(this%volanaattrc(SIZE(this%ana), SIZE(this%anavarattr%c), &
9937 SIZE(this%network), SIZE(this%anaattr%c)))
9938 IF (linivol) this%volanaattrc(:,:,:,:) = cmiss
9939ENDIF
9940
9941! Dati
9942IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
9943 CALL vol7d_force_alloc_dati(this, ini)
9944 ALLOCATE(this%voldatir(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
9945 SIZE(this%timerange), SIZE(this%dativar%r), SIZE(this%network)))
9946 IF (linivol) this%voldatir(:,:,:,:,:,:) = rmiss
9947ENDIF
9948
9949IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
9950 CALL vol7d_force_alloc_dati(this, ini)
9951 ALLOCATE(this%voldatid(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
9952 SIZE(this%timerange), SIZE(this%dativar%d), SIZE(this%network)))
9953 IF (linivol) this%voldatid(:,:,:,:,:,:) = rdmiss
9954ENDIF
9955
9956IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
9957 CALL vol7d_force_alloc_dati(this, ini)
9958 ALLOCATE(this%voldatii(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
9959 SIZE(this%timerange), SIZE(this%dativar%i), SIZE(this%network)))
9960 IF (linivol) this%voldatii(:,:,:,:,:,:) = imiss
9961ENDIF
9962
9963IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
9964 CALL vol7d_force_alloc_dati(this, ini)
9965 ALLOCATE(this%voldatib(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
9966 SIZE(this%timerange), SIZE(this%dativar%b), SIZE(this%network)))
9967 IF (linivol) this%voldatib(:,:,:,:,:,:) = ibmiss
9968ENDIF
9969
9970IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
9971 CALL vol7d_force_alloc_dati(this, ini)
9972 ALLOCATE(this%voldatic(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
9973 SIZE(this%timerange), SIZE(this%dativar%c), SIZE(this%network)))
9974 IF (linivol) this%voldatic(:,:,:,:,:,:) = cmiss
9975ENDIF
9976
9977! Attributi dei dati
9978IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
9979 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
9980 CALL vol7d_force_alloc_dati(this, ini)
9981 ALLOCATE(this%voldatiattrr(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
9982 SIZE(this%timerange), SIZE(this%dativarattr%r), SIZE(this%network), &
9983 SIZE(this%datiattr%r)))
9984 IF (linivol) this%voldatiattrr(:,:,:,:,:,:,:) = rmiss
9985ENDIF
9986
9987IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
9988 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
9989 CALL vol7d_force_alloc_dati(this, ini)
9990 ALLOCATE(this%voldatiattrd(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
9991 SIZE(this%timerange), SIZE(this%dativarattr%d), SIZE(this%network), &
9992 SIZE(this%datiattr%d)))
9993 IF (linivol) this%voldatiattrd(:,:,:,:,:,:,:) = rdmiss
9994ENDIF
9995
9996IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
9997 .NOT.ASSOCIATED(this%voldatiattri)) THEN
9998 CALL vol7d_force_alloc_dati(this, ini)
9999 ALLOCATE(this%voldatiattri(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10000 SIZE(this%timerange), SIZE(this%dativarattr%i), SIZE(this%network), &
10001 SIZE(this%datiattr%i)))
10002 IF (linivol) this%voldatiattri(:,:,:,:,:,:,:) = imiss
10003ENDIF
10004
10005IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
10006 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
10007 CALL vol7d_force_alloc_dati(this, ini)
10008 ALLOCATE(this%voldatiattrb(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10009 SIZE(this%timerange), SIZE(this%dativarattr%b), SIZE(this%network), &
10010 SIZE(this%datiattr%b)))
10011 IF (linivol) this%voldatiattrb(:,:,:,:,:,:,:) = ibmiss
10012ENDIF
10013
10014IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
10015 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
10016 CALL vol7d_force_alloc_dati(this, ini)
10017 ALLOCATE(this%voldatiattrc(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
10018 SIZE(this%timerange), SIZE(this%dativarattr%c), SIZE(this%network), &
10019 SIZE(this%datiattr%c)))
10020 IF (linivol) this%voldatiattrc(:,:,:,:,:,:,:) = cmiss
10021ENDIF
10022
10023! Catch-all method
10024CALL vol7d_force_alloc(this)
10025
10026! Creo gli indici var-attr
10027
10028#ifdef DEBUG
10029CALL l4f_log(l4f_debug,"calling: vol7d_set_attr_ind")
10030#endif
10031
10032CALL vol7d_set_attr_ind(this)
10033
10034
10035
10036END SUBROUTINE vol7d_alloc_vol
10037
10038
10039!> Metodo per creare gli indici che associano le variabili aventi attributo
10040!! alle variabili nei relativi descrittori.
10041!! Ha senso chiamare questo metodo solo dopo che i descrittori delle variabili
10042!! e degli attributi desiderati sono stati allocati ed è stato assegnato un
10043!! valore ai relativi membri btable (vedi vol7d_var_class::vol7d_var), se
10044!! i descrittori non sono stati allocati o assegnati, il metodo non fa niente.
10045SUBROUTINE vol7d_set_attr_ind(this)
10046TYPE(vol7d),INTENT(inout) :: this !< oggetto in cui creare gli indici
10047
10048INTEGER :: i
10049
10050! real
10051IF (ASSOCIATED(this%dativar%r)) THEN
10052 IF (ASSOCIATED(this%dativarattr%r)) THEN
10053 DO i = 1, SIZE(this%dativar%r)
10054 this%dativar%r(i)%r = &
10055 firsttrue(this%dativar%r(i)%btable == this%dativarattr%r(:)%btable)
10056 ENDDO
10057 ENDIF
10058
10059 IF (ASSOCIATED(this%dativarattr%d)) THEN
10060 DO i = 1, SIZE(this%dativar%r)
10061 this%dativar%r(i)%d = &
10062 firsttrue(this%dativar%r(i)%btable == this%dativarattr%d(:)%btable)
10063 ENDDO
10064 ENDIF
10065
10066 IF (ASSOCIATED(this%dativarattr%i)) THEN
10067 DO i = 1, SIZE(this%dativar%r)
10068 this%dativar%r(i)%i = &
10069 firsttrue(this%dativar%r(i)%btable == this%dativarattr%i(:)%btable)
10070 ENDDO
10071 ENDIF
10072
10073 IF (ASSOCIATED(this%dativarattr%b)) THEN
10074 DO i = 1, SIZE(this%dativar%r)
10075 this%dativar%r(i)%b = &
10076 firsttrue(this%dativar%r(i)%btable == this%dativarattr%b(:)%btable)
10077 ENDDO
10078 ENDIF
10079
10080 IF (ASSOCIATED(this%dativarattr%c)) THEN
10081 DO i = 1, SIZE(this%dativar%r)
10082 this%dativar%r(i)%c = &
10083 firsttrue(this%dativar%r(i)%btable == this%dativarattr%c(:)%btable)
10084 ENDDO
10085 ENDIF
10086ENDIF
10087! double
10088IF (ASSOCIATED(this%dativar%d)) THEN
10089 IF (ASSOCIATED(this%dativarattr%r)) THEN
10090 DO i = 1, SIZE(this%dativar%d)
10091 this%dativar%d(i)%r = &
10092 firsttrue(this%dativar%d(i)%btable == this%dativarattr%r(:)%btable)
10093 ENDDO
10094 ENDIF
10095
10096 IF (ASSOCIATED(this%dativarattr%d)) THEN
10097 DO i = 1, SIZE(this%dativar%d)
10098 this%dativar%d(i)%d = &
10099 firsttrue(this%dativar%d(i)%btable == this%dativarattr%d(:)%btable)
10100 ENDDO
10101 ENDIF
10102
10103 IF (ASSOCIATED(this%dativarattr%i)) THEN
10104 DO i = 1, SIZE(this%dativar%d)
10105 this%dativar%d(i)%i = &
10106 firsttrue(this%dativar%d(i)%btable == this%dativarattr%i(:)%btable)
10107 ENDDO
10108 ENDIF
10109
10110 IF (ASSOCIATED(this%dativarattr%b)) THEN
10111 DO i = 1, SIZE(this%dativar%d)
10112 this%dativar%d(i)%b = &
10113 firsttrue(this%dativar%d(i)%btable == this%dativarattr%b(:)%btable)
10114 ENDDO
10115 ENDIF
10116
10117 IF (ASSOCIATED(this%dativarattr%c)) THEN
10118 DO i = 1, SIZE(this%dativar%d)
10119 this%dativar%d(i)%c = &
10120 firsttrue(this%dativar%d(i)%btable == this%dativarattr%c(:)%btable)
10121 ENDDO
10122 ENDIF
10123ENDIF
10124! integer
10125IF (ASSOCIATED(this%dativar%i)) THEN
10126 IF (ASSOCIATED(this%dativarattr%r)) THEN
10127 DO i = 1, SIZE(this%dativar%i)
10128 this%dativar%i(i)%r = &
10129 firsttrue(this%dativar%i(i)%btable == this%dativarattr%r(:)%btable)
10130 ENDDO
10131 ENDIF
10132
10133 IF (ASSOCIATED(this%dativarattr%d)) THEN
10134 DO i = 1, SIZE(this%dativar%i)
10135 this%dativar%i(i)%d = &
10136 firsttrue(this%dativar%i(i)%btable == this%dativarattr%d(:)%btable)
10137 ENDDO
10138 ENDIF
10139
10140 IF (ASSOCIATED(this%dativarattr%i)) THEN
10141 DO i = 1, SIZE(this%dativar%i)
10142 this%dativar%i(i)%i = &
10143 firsttrue(this%dativar%i(i)%btable == this%dativarattr%i(:)%btable)
10144 ENDDO
10145 ENDIF
10146
10147 IF (ASSOCIATED(this%dativarattr%b)) THEN
10148 DO i = 1, SIZE(this%dativar%i)
10149 this%dativar%i(i)%b = &
10150 firsttrue(this%dativar%i(i)%btable == this%dativarattr%b(:)%btable)
10151 ENDDO
10152 ENDIF
10153
10154 IF (ASSOCIATED(this%dativarattr%c)) THEN
10155 DO i = 1, SIZE(this%dativar%i)
10156 this%dativar%i(i)%c = &
10157 firsttrue(this%dativar%i(i)%btable == this%dativarattr%c(:)%btable)
10158 ENDDO
10159 ENDIF
10160ENDIF
10161! byte
10162IF (ASSOCIATED(this%dativar%b)) THEN
10163 IF (ASSOCIATED(this%dativarattr%r)) THEN
10164 DO i = 1, SIZE(this%dativar%b)
10165 this%dativar%b(i)%r = &
10166 firsttrue(this%dativar%b(i)%btable == this%dativarattr%r(:)%btable)
10167 ENDDO
10168 ENDIF
10169
10170 IF (ASSOCIATED(this%dativarattr%d)) THEN
10171 DO i = 1, SIZE(this%dativar%b)
10172 this%dativar%b(i)%d = &
10173 firsttrue(this%dativar%b(i)%btable == this%dativarattr%d(:)%btable)
10174 ENDDO
10175 ENDIF
10176
10177 IF (ASSOCIATED(this%dativarattr%i)) THEN
10178 DO i = 1, SIZE(this%dativar%b)
10179 this%dativar%b(i)%i = &
10180 firsttrue(this%dativar%b(i)%btable == this%dativarattr%i(:)%btable)
10181 ENDDO
10182 ENDIF
10183
10184 IF (ASSOCIATED(this%dativarattr%b)) THEN
10185 DO i = 1, SIZE(this%dativar%b)
10186 this%dativar%b(i)%b = &
10187 firsttrue(this%dativar%b(i)%btable == this%dativarattr%b(:)%btable)
10188 ENDDO
10189 ENDIF
10190
10191 IF (ASSOCIATED(this%dativarattr%c)) THEN
10192 DO i = 1, SIZE(this%dativar%b)
10193 this%dativar%b(i)%c = &
10194 firsttrue(this%dativar%b(i)%btable == this%dativarattr%c(:)%btable)
10195 ENDDO
10196 ENDIF
10197ENDIF
10198! character
10199IF (ASSOCIATED(this%dativar%c)) THEN
10200 IF (ASSOCIATED(this%dativarattr%r)) THEN
10201 DO i = 1, SIZE(this%dativar%c)
10202 this%dativar%c(i)%r = &
10203 firsttrue(this%dativar%c(i)%btable == this%dativarattr%r(:)%btable)
10204 ENDDO
10205 ENDIF
10206
10207 IF (ASSOCIATED(this%dativarattr%d)) THEN
10208 DO i = 1, SIZE(this%dativar%c)
10209 this%dativar%c(i)%d = &
10210 firsttrue(this%dativar%c(i)%btable == this%dativarattr%d(:)%btable)
10211 ENDDO
10212 ENDIF
10213
10214 IF (ASSOCIATED(this%dativarattr%i)) THEN
10215 DO i = 1, SIZE(this%dativar%c)
10216 this%dativar%c(i)%i = &
10217 firsttrue(this%dativar%c(i)%btable == this%dativarattr%i(:)%btable)
10218 ENDDO
10219 ENDIF
10220
10221 IF (ASSOCIATED(this%dativarattr%b)) THEN
10222 DO i = 1, SIZE(this%dativar%c)
10223 this%dativar%c(i)%b = &
10224 firsttrue(this%dativar%c(i)%btable == this%dativarattr%b(:)%btable)
10225 ENDDO
10226 ENDIF
10227
10228 IF (ASSOCIATED(this%dativarattr%c)) THEN
10229 DO i = 1, SIZE(this%dativar%c)
10230 this%dativar%c(i)%c = &
10231 firsttrue(this%dativar%c(i)%btable == this%dativarattr%c(:)%btable)
10232 ENDDO
10233 ENDIF
10234ENDIF
10235
10236END SUBROUTINE vol7d_set_attr_ind
10237
10238
10239!> Metodo per fondere 2 oggetti vol7d.
10240!! Il secondo volume viene accodato al primo e poi distrutto, si veda
10241!! quindi la descrizione di ::vol7d_append. Se uno degli oggetti \a
10242!! this o \a that sono vuoti non perde tempo inutile,
10243SUBROUTINE vol7d_merge(this, that, sort, bestdata, &
10244 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
10245TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, alla fine conterrà il risultato della fusione
10246TYPE(vol7d),INTENT(INOUT) :: that !< secondo oggetto in ingresso, alla fine sarà distrutto
10247LOGICAL,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
10248LOGICAL,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
10249LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple ! experimental, please do not use outside the library now
10250
10251TYPE(vol7d) :: v7d_clean
10252
10253
10254IF (.NOT.c_e(this)) THEN ! speedup
10255 this = that
10256 CALL init(v7d_clean)
10257 that = v7d_clean ! destroy that without deallocating
10258ELSE ! Append that to this and destroy that
10259 CALL vol7d_append(this, that, sort, bestdata, &
10260 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
10261 CALL delete(that)
10262ENDIF
10263
10264END SUBROUTINE vol7d_merge
10265
10266
10267!> Metodo per accodare un oggetto vol7d ad un altro.
10268!! Si tratta di un metodo molto potente e versatile;
10269!! i descrittori delle dimensioni del volume finale conterranno i valori
10270!! dei corrispondenti descrittori del primo e del secondo volume
10271!! e i volumi di anagrafica e dati conterranno i valori dei due volumi
10272!! ai posti giusti, e valori mancanti per le nuove combinazioni che
10273!! eventualmente si verranno a creare.
10274!! Se i volumi multidimensionali di anagrafica e/o dati dei 2 oggetti
10275!! hanno un'intersezione non nulla, negli elementi comuni il volume finale
10276!! conterrà il corrispondente elemento del \b secondo volume.
10277!! Attenzione che, durante l'esecuzione del metodo, la memoria richiesta è
10278!! pari alla memoria complessiva occupata dai 2 volumi iniziali più
10279!! la memoria complessiva del volume finale, per cui, nel caso di volumi grandi,
10280!! ci potrebbero essere problemi di esaurimento della memoria centrale.
10281!! Se l'oggetto \a that è vuoto non perde tempo inutile,
10282!!
10283!! \todo nel caso di elementi comuni inserire la possibiità (opzionale per
10284!! non penalizzare le prestazioni quando ciò non serve) di effettuare una scelta
10285!! più ragionata dell'elemento da tenere, almeno controllando i dati mancanti
10286!! se non le flag di qualità
10287!!
10288!! \todo "rateizzare" l'allocazione dei volumi per ridurre l'occupazione di
10289!! memoria nel caso siano allocati contemporaneamente volumi di variabili e
10290!! di attributi o più volumi di tipi diversi
10291!!
10292!! \todo il parametro \a that è dichiarato \a INOUT perché la vol7d_alloc_vol
10293!! può modificarlo, bisognerebbe implementare una vol7d_check_vol che restituisca
10294!! errore anziché usare la vol7d_alloc_vol.
10295SUBROUTINE vol7d_append(this, that, sort, bestdata, &
10296 ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple)
10297TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, a cui sarà accodato il secondo
10298TYPE(vol7d),INTENT(IN) :: that !< secondo oggetto in ingresso, non viene modificato dal metodo
10299LOGICAL,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
10300! experimental, please do not use outside the library now, they force the use
10301! of a simplified mapping algorithm which is valid only whene the dimension
10302! content is the same in both volumes , or when one of them is empty
10303LOGICAL,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
10304LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple
10305
10306
10307TYPE(vol7d) :: v7dtmp
10308LOGICAL :: lsort, lbestdata
10309INTEGER,POINTER :: remapt1(:), remapt2(:), remaptr1(:), remaptr2(:), &
10310 remapl1(:), remapl2(:), remapa1(:), remapa2(:), remapn1(:), remapn2(:)
10311
10312IF (.NOT.c_e(that)) RETURN ! speedup, nothing to do
10313IF (.NOT.vol7d_check_vol(that)) RETURN ! be safe
10314IF (.NOT.c_e(this)) THEN ! this case is like a vol7d_copy, more efficient to copy?
10315 CALL vol7d_copy(that, this, sort=sort)
10316 RETURN
10317ENDIF
10318
10319IF (this%time_definition /= that%time_definition) THEN
10320 CALL l4f_log(l4f_fatal, &
10321 'in vol7d_append, cannot append volumes with different &
10322 &time definition')
10323 CALL raise_fatal_error()
10324ENDIF
10325
10326! Completo l'allocazione per avere volumi a norma
10327CALL vol7d_alloc_vol(this)
10328
10329CALL init(v7dtmp, time_definition=this%time_definition)
10330CALL optio(sort, lsort)
10331CALL optio(bestdata, lbestdata)
10332
10333! Calcolo le mappature tra volumi vecchi e volume nuovo
10334! I puntatori remap* vengono tutti o allocati o nullificati
10335IF (optio_log(ltimesimple)) THEN
10336 CALL vol7d_remap2simple_datetime(this%time, that%time, v7dtmp%time, &
10337 lsort, remapt1, remapt2)
10338ELSE
10339 CALL vol7d_remap2_datetime(this%time, that%time, v7dtmp%time, &
10340 lsort, remapt1, remapt2)
10341ENDIF
10342IF (optio_log(ltimerangesimple)) THEN
10343 CALL vol7d_remap2simple_vol7d_timerange(this%timerange, that%timerange, &
10344 v7dtmp%timerange, lsort, remaptr1, remaptr2)
10345ELSE
10346 CALL vol7d_remap2_vol7d_timerange(this%timerange, that%timerange, &
10347 v7dtmp%timerange, lsort, remaptr1, remaptr2)
10348ENDIF
10349IF (optio_log(llevelsimple)) THEN
10350 CALL vol7d_remap2simple_vol7d_level(this%level, that%level, v7dtmp%level, &
10351 lsort, remapl1, remapl2)
10352ELSE
10353 CALL vol7d_remap2_vol7d_level(this%level, that%level, v7dtmp%level, &
10354 lsort, remapl1, remapl2)
10355ENDIF
10356IF (optio_log(lanasimple)) THEN
10357 CALL vol7d_remap2simple_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
10358 .false., remapa1, remapa2)
10359ELSE
10360 CALL vol7d_remap2_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
10361 .false., remapa1, remapa2)
10362ENDIF
10363IF (optio_log(lnetworksimple)) THEN
10364 CALL vol7d_remap2simple_vol7d_network(this%network, that%network, v7dtmp%network, &
10365 .false., remapn1, remapn2)
10366ELSE
10367 CALL vol7d_remap2_vol7d_network(this%network, that%network, v7dtmp%network, &
10368 .false., remapn1, remapn2)
10369ENDIF
10370
10371! Faccio la fusione fisica dei volumi
10372CALL vol7d_merge_finalr(this, that, v7dtmp, &
10373 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
10374 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
10375CALL vol7d_merge_finald(this, that, v7dtmp, &
10376 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
10377 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
10378CALL vol7d_merge_finali(this, that, v7dtmp, &
10379 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
10380 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
10381CALL vol7d_merge_finalb(this, that, v7dtmp, &
10382 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
10383 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
10384CALL vol7d_merge_finalc(this, that, v7dtmp, &
10385 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
10386 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
10387
10388! Dealloco i vettori di rimappatura
10389IF (ASSOCIATED(remapt1)) DEALLOCATE(remapt1)
10390IF (ASSOCIATED(remapt2)) DEALLOCATE(remapt2)
10391IF (ASSOCIATED(remaptr1)) DEALLOCATE(remaptr1)
10392IF (ASSOCIATED(remaptr2)) DEALLOCATE(remaptr2)
10393IF (ASSOCIATED(remapl1)) DEALLOCATE(remapl1)
10394IF (ASSOCIATED(remapl2)) DEALLOCATE(remapl2)
10395IF (ASSOCIATED(remapa1)) DEALLOCATE(remapa1)
10396IF (ASSOCIATED(remapa2)) DEALLOCATE(remapa2)
10397IF (ASSOCIATED(remapn1)) DEALLOCATE(remapn1)
10398IF (ASSOCIATED(remapn2)) DEALLOCATE(remapn2)
10399
10400! Distruggo il vecchio volume e assegno il nuovo a this
10401CALL delete(this)
10402this = v7dtmp
10403! Ricreo gli indici var-attr
10404CALL vol7d_set_attr_ind(this)
10405
10406END SUBROUTINE vol7d_append
10407
10408
10409!> Metodo per creare una copia completa e indipendente di un oggetto vol7d.
10410!! Questo metodo crea un duplicato di tutti i membri di un oggetto vol7d,
10411!! con la possibilità di rielaborarlo durante la copia. Se l'oggetto da copiare
10412!! è vuoto non perde tempo inutile.
10413!! Attenzione, il codice:
10414!! \code
10415!! USE vol7d_class
10416!! TYPE(vol7d) :: vol1, vol2
10417!! CALL init(vol1)
10418!! CALL init(vol2)
10419!! ... ! riempio vol1
10420!! vol2 = vol1
10421!! \endcode
10422!! fa una cosa diversa rispetto a:
10423!! \code
10424!! USE vol7d_class
10425!! TYPE(vol7d) :: vol1, vol2
10426!! CALL init(vol1)
10427!! CALL init(vol2)
10428!! ... ! riempio vol1
10429!! CALL vol7d_copy(vol1, vol2)
10430!! \endcode
10431!! nel primo caso, infatti, l'operatore di assegnazione copia solo i componenti
10432!! statici di \a vol1 nei corrispondenti elementi di \a vol2, mentre i componenti che
10433!! sono allocati dinamicamente (cioè quelli che in ::vol7d hanno l'attributo
10434!! \c POINTER, in pratica quasi tutti) non vengono duplicati, ma per essi vol2
10435!! conterrà un puntatore al corrispondente elemento a cui già punta vol1, e quindi
10436!! eventuali cambiamenti al contenuto di uno dei due oggetti influenzerà il
10437!! contenuto dell'altro; nel secondo caso, invece, vol1 e vol2 sono, dopo la
10438!! vol7d_copy, 2 istanze
10439!! completamente indipendenti, ma uguali tra loro per contenuto, della classe
10440!! vol7d, e quindi hanno vita indipendente.
10441SUBROUTINE vol7d_copy(this, that, sort, unique, miss, &
10442 lsort_time, lsort_timerange, lsort_level, &
10443 ltime, ltimerange, llevel, lana, lnetwork, &
10444 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
10445 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
10446 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
10447 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
10448 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
10449 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
10450TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
10451TYPE(vol7d),INTENT(INOUT) :: that !< oggetto destinazione
10452LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
10453LOGICAL,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)
10454LOGICAL,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
10455LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
10456LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
10457LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
10458!> se fornito, deve essere un vettore logico della stessa lunghezza di
10459!! this%time indicante quali elementi della dimensione \a time
10460!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
10461!! nel volume copiato; in alternativa può essere un vettore di
10462!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
10463!! gli elementi (utile principalmente per le variabili); è compatibile
10464!! col parametro \a miss
10465LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
10466!> come il precedente per la dimensione \a timerange
10467LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:)
10468!> come il precedente per la dimensione \a level
10469LOGICAL,INTENT(IN),OPTIONAL :: llevel(:)
10470!> come il precedente per la dimensione \a ana
10471LOGICAL,INTENT(IN),OPTIONAL :: lana(:)
10472!> come il precedente per la dimensione \a network
10473LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:)
10474!> come il precedente per tutte le possibili dimensioni variabile
10475LOGICAL,INTENT(in),OPTIONAL :: &
10476 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
10477 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
10478 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
10479 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
10480 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
10481 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
10482
10483LOGICAL :: lsort, lunique, lmiss
10484INTEGER,POINTER :: remapt(:), remaptr(:), remapl(:), remapa(:), remapn(:)
10485
10486CALL init(that)
10487IF (.NOT.c_e(this)) RETURN ! speedup, nothing to do
10488IF (.NOT.vol7d_check_vol(this)) RETURN ! be safe
10489
10490CALL optio(sort, lsort)
10491CALL optio(unique, lunique)
10492CALL optio(miss, lmiss)
10493
10494! Calcolo le mappature tra volume vecchio e volume nuovo
10495! I puntatori remap* vengono tutti o allocati o nullificati
10496CALL vol7d_remap1_datetime(this%time, that%time, &
10497 lsort.OR.optio_log(lsort_time), lunique, lmiss, remapt, ltime)
10498CALL vol7d_remap1_vol7d_timerange(this%timerange, that%timerange, &
10499 lsort.OR.optio_log(lsort_timerange), lunique, lmiss, remaptr, ltimerange)
10500CALL vol7d_remap1_vol7d_level(this%level, that%level, &
10501 lsort.OR.optio_log(lsort_level), lunique, lmiss, remapl, llevel)
10502CALL vol7d_remap1_vol7d_ana(this%ana, that%ana, &
10503 lsort, lunique, lmiss, remapa, lana)
10504CALL vol7d_remap1_vol7d_network(this%network, that%network, &
10505 lsort, lunique, lmiss, remapn, lnetwork)
10506
10507! lanavari, lanavarb, lanavarc, &
10508! lanaattri, lanaattrb, lanaattrc, &
10509! lanavarattri, lanavarattrb, lanavarattrc, &
10510! ldativari, ldativarb, ldativarc, &
10511! ldatiattri, ldatiattrb, ldatiattrc, &
10512! ldativarattri, ldativarattrb, ldativarattrc
10513! Faccio la riforma fisica dei volumi
10514CALL vol7d_reform_finalr(this, that, &
10515 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
10516 lanavarr, lanaattrr, lanavarattrr, ldativarr, ldatiattrr, ldativarattrr)
10517CALL vol7d_reform_finald(this, that, &
10518 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
10519 lanavard, lanaattrd, lanavarattrd, ldativard, ldatiattrd, ldativarattrd)
10520CALL vol7d_reform_finali(this, that, &
10521 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
10522 lanavari, lanaattri, lanavarattri, ldativari, ldatiattri, ldativarattri)
10523CALL vol7d_reform_finalb(this, that, &
10524 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
10525 lanavarb, lanaattrb, lanavarattrb, ldativarb, ldatiattrb, ldativarattrb)
10526CALL vol7d_reform_finalc(this, that, &
10527 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
10528 lanavarc, lanaattrc, lanavarattrc, ldativarc, ldatiattrc, ldativarattrc)
10529
10530! Dealloco i vettori di rimappatura
10531IF (ASSOCIATED(remapt)) DEALLOCATE(remapt)
10532IF (ASSOCIATED(remaptr)) DEALLOCATE(remaptr)
10533IF (ASSOCIATED(remapl)) DEALLOCATE(remapl)
10534IF (ASSOCIATED(remapa)) DEALLOCATE(remapa)
10535IF (ASSOCIATED(remapn)) DEALLOCATE(remapn)
10536
10537! Ricreo gli indici var-attr
10538CALL vol7d_set_attr_ind(that)
10539that%time_definition = this%time_definition
10540
10541END SUBROUTINE vol7d_copy
10542
10543
10544!> Metodo per riformare in varie maniere un oggetto vol7d.
10545!! Equivale ad una copia (vedi ::vol7d_copy)
10546!! seguita dalla distruzione del volume iniziale e alla
10547!! sua riassegnazione al volume copiato. Ha senso se almeno uno dei parametri
10548!! \a sort, \a uniq o \a miss è fornito uguale a \c .TRUE., altrimenti
10549!! è solo una perdita di tempo.
10550!! Può essere utile, ad esempio, per eliminare stazioni
10551!! o istanti temporali indesiderati, basta assegnare il loro corrispondente
10552!! elemento del descrittore a valore mancante e chiamare vol7d_reform
10553!! con miss=.TRUE. .
10554SUBROUTINE vol7d_reform(this, sort, unique, miss, &
10555 lsort_time, lsort_timerange, lsort_level, &
10556 ltime, ltimerange, llevel, lana, lnetwork, &
10557 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
10558 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
10559 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
10560 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
10561 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
10562 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc&
10563 ,purgeana)
10564TYPE(vol7d),INTENT(INOUT) :: this !< oggetto da riformare
10565LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
10566LOGICAL,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)
10567LOGICAL,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
10568LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
10569LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
10570LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
10571!> se fornito, deve essere un vettore logico della stessa lunghezza di
10572!! this%time indicante quali elementi della dimensione \a time
10573!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
10574!! nel volume copiato; in alternativa può essere un vettore di
10575!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
10576!! gli elementi (utile principalmente per le variabili); è compatibile
10577!! col parametro \a miss
10578LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
10579LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:) !< come il precedente per la dimensione \a timerange
10580LOGICAL,INTENT(IN),OPTIONAL :: llevel(:) !< come il precedente per la dimensione \a level
10581LOGICAL,INTENT(IN),OPTIONAL :: lana(:) !< come il precedente per la dimensione \a ana
10582LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:) !< come il precedente per la dimensione \a network
10583!> come il precedente per tutte le possibili dimensioni variabile
10584LOGICAL,INTENT(in),OPTIONAL :: &
10585 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
10586 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
10587 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
10588 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
10589 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
10590 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
10591LOGICAL,INTENT(IN),OPTIONAL :: purgeana !< if true remove ana with all data missing
10592
10593TYPE(vol7d) :: v7dtmp
10594logical,allocatable :: llana(:)
10595integer :: i
10596
10597CALL vol7d_copy(this, v7dtmp, sort, unique, miss, &
10598 lsort_time, lsort_timerange, lsort_level, &
10599 ltime, ltimerange, llevel, lana, lnetwork, &
10600 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
10601 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
10602 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
10603 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
10604 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
10605 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
10606
10607! destroy old volume
10608CALL delete(this)
10609
10610if (optio_log(purgeana)) then
10611 allocate(llana(size(v7dtmp%ana)))
10612 llana =.false.
10613 do i =1,size(v7dtmp%ana)
10614 if (associated(v7dtmp%voldatii)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatii(i,:,:,:,:,:)))
10615 if (associated(v7dtmp%voldatir)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatir(i,:,:,:,:,:)))
10616 if (associated(v7dtmp%voldatid)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatid(i,:,:,:,:,:)))
10617 if (associated(v7dtmp%voldatib)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatib(i,:,:,:,:,:)))
10618 if (associated(v7dtmp%voldatic)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatic(i,:,:,:,:,:)))
10619 end do
10620 CALL vol7d_copy(v7dtmp, this,lana=llana)
10621 CALL delete(v7dtmp)
10622 deallocate(llana)
10623else
10624 this=v7dtmp
10625end if
10626
10627END SUBROUTINE vol7d_reform
10628
10629
10630!> Sorts the sortable dimensions in the volume \a this only when necessary.
10631!! Most of the times, the time, timerange and level dimensions in a
10632!! vol7d object are correctly sorted; on the other side many methods
10633!! strictly rely on this fact in order to work correctly. This method
10634!! performs a quick check and sorts the required dimensions only if
10635!! they are not sorted in ascending order yet, improving safety
10636!! without impairing much performance.
10637SUBROUTINE vol7d_smart_sort(this, lsort_time, lsort_timerange, lsort_level)
10638TYPE(vol7d),INTENT(INOUT) :: this !< object to be sorted
10639LOGICAL,OPTIONAL,INTENT(in) :: lsort_time !< if present and \a .TRUE., sort time dimension if it is not sorted in ascending order
10640LOGICAL,OPTIONAL,INTENT(in) :: lsort_timerange !< if present and \a .TRUE., sort timerange dimension if it is not sorted in ascending order
10641LOGICAL,OPTIONAL,INTENT(in) :: lsort_level !< if present and \a .TRUE., sort vertical level dimension if it is not sorted in ascending order
10642
10643INTEGER :: i
10644LOGICAL :: to_be_sorted
10645
10646to_be_sorted = .false.
10647CALL vol7d_alloc_vol(this) ! usual safety check
10648
10649IF (optio_log(lsort_time)) THEN
10650 DO i = 2, SIZE(this%time)
10651 IF (this%time(i) < this%time(i-1)) THEN
10652 to_be_sorted = .true.
10653 EXIT
10654 ENDIF
10655 ENDDO
10656ENDIF
10657IF (optio_log(lsort_timerange)) THEN
10658 DO i = 2, SIZE(this%timerange)
10659 IF (this%timerange(i) < this%timerange(i-1)) THEN
10660 to_be_sorted = .true.
10661 EXIT
10662 ENDIF
10663 ENDDO
10664ENDIF
10665IF (optio_log(lsort_level)) THEN
10666 DO i = 2, SIZE(this%level)
10667 IF (this%level(i) < this%level(i-1)) THEN
10668 to_be_sorted = .true.
10669 EXIT
10670 ENDIF
10671 ENDDO
10672ENDIF
10673
10674IF (to_be_sorted) CALL vol7d_reform(this, &
10675 lsort_time=lsort_time, lsort_timerange=lsort_timerange, lsort_level=lsort_level )
10676
10677END SUBROUTINE vol7d_smart_sort
10678
10679!> Filter the contents of a volume keeping only desired data.
10680!! This subroutine filters a vol7d object by keeping only a subset of
10681!! the data contained. It can keep only times within a specified
10682!! interval, only station networks contained in a list and only
10683!! specified station or data variables. If a filter parameter is not
10684!! provided, no filtering will take place according to that criterion.
10685!! The volume is reallocated keeping only the desired data.
10686SUBROUTINE vol7d_filter(this, avl, vl, nl, s_d, e_d)
10687TYPE(vol7d),INTENT(inout) :: this !< volume to be filtered
10688CHARACTER(len=*),INTENT(in),OPTIONAL :: avl(:) !< list of station variables to be kept, if not provided or of zero length, all variables are kept
10689CHARACTER(len=*),INTENT(in),OPTIONAL :: vl(:) !< list of data variables to be kept, if not provided or of zero length, all variables are kept
10690TYPE(vol7d_network),OPTIONAL :: nl(:) !< list of station networks to be kept, if not provided or of zero length, all networks are kept
10691TYPE(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
10692TYPE(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
10693
10694INTEGER :: i
10695
10696IF (PRESENT(avl)) THEN
10697 IF (SIZE(avl) > 0) THEN
10698
10699 IF (ASSOCIATED(this%anavar%r)) THEN
10700 DO i = 1, SIZE(this%anavar%r)
10701 IF (all(this%anavar%r(i)%btable /= avl)) this%anavar%r(i) = vol7d_var_miss
10702 ENDDO
10703 ENDIF
10704
10705 IF (ASSOCIATED(this%anavar%i)) THEN
10706 DO i = 1, SIZE(this%anavar%i)
10707 IF (all(this%anavar%i(i)%btable /= avl)) this%anavar%i(i) = vol7d_var_miss
10708 ENDDO
10709 ENDIF
10710
10711 IF (ASSOCIATED(this%anavar%b)) THEN
10712 DO i = 1, SIZE(this%anavar%b)
10713 IF (all(this%anavar%b(i)%btable /= avl)) this%anavar%b(i) = vol7d_var_miss
10714 ENDDO
10715 ENDIF
10716
10717 IF (ASSOCIATED(this%anavar%d)) THEN
10718 DO i = 1, SIZE(this%anavar%d)
10719 IF (all(this%anavar%d(i)%btable /= avl)) this%anavar%d(i) = vol7d_var_miss
10720 ENDDO
10721 ENDIF
10722
10723 IF (ASSOCIATED(this%anavar%c)) THEN
10724 DO i = 1, SIZE(this%anavar%c)
10725 IF (all(this%anavar%c(i)%btable /= avl)) this%anavar%c(i) = vol7d_var_miss
10726 ENDDO
10727 ENDIF
10728
10729 ENDIF
10730ENDIF
10731
10732
10733IF (PRESENT(vl)) THEN
10734 IF (size(vl) > 0) THEN
10735 IF (ASSOCIATED(this%dativar%r)) THEN
10736 DO i = 1, SIZE(this%dativar%r)
10737 IF (all(this%dativar%r(i)%btable /= vl)) this%dativar%r(i) = vol7d_var_miss
10738 ENDDO
10739 ENDIF
10740
10741 IF (ASSOCIATED(this%dativar%i)) THEN
10742 DO i = 1, SIZE(this%dativar%i)
10743 IF (all(this%dativar%i(i)%btable /= vl)) this%dativar%i(i) = vol7d_var_miss
10744 ENDDO
10745 ENDIF
10746
10747 IF (ASSOCIATED(this%dativar%b)) THEN
10748 DO i = 1, SIZE(this%dativar%b)
10749 IF (all(this%dativar%b(i)%btable /= vl)) this%dativar%b(i) = vol7d_var_miss
10750 ENDDO
10751 ENDIF
10752
10753 IF (ASSOCIATED(this%dativar%d)) THEN
10754 DO i = 1, SIZE(this%dativar%d)
10755 IF (all(this%dativar%d(i)%btable /= vl)) this%dativar%d(i) = vol7d_var_miss
10756 ENDDO
10757 ENDIF
10758
10759 IF (ASSOCIATED(this%dativar%c)) THEN
10760 DO i = 1, SIZE(this%dativar%c)
10761 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
10762 ENDDO
10763 ENDIF
10764
10765 IF (ASSOCIATED(this%dativar%c)) THEN
10766 DO i = 1, SIZE(this%dativar%c)
10767 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
10768 ENDDO
10769 ENDIF
10770
10771 ENDIF
10772ENDIF
10773
10774IF (PRESENT(nl)) THEN
10775 IF (SIZE(nl) > 0) THEN
10776 DO i = 1, SIZE(this%network)
10777 IF (all(this%network(i) /= nl)) this%network(i) = vol7d_network_miss
10778 ENDDO
10779 ENDIF
10780ENDIF
10781
10782IF (PRESENT(s_d)) THEN
10783 IF (c_e(s_d)) THEN
10784 WHERE (this%time < s_d)
10785 this%time = datetime_miss
10786 END WHERE
10787 ENDIF
10788ENDIF
10789
10790IF (PRESENT(e_d)) THEN
10791 IF (c_e(e_d)) THEN
10792 WHERE (this%time > e_d)
10793 this%time = datetime_miss
10794 END WHERE
10795 ENDIF
10796ENDIF
10797
10798CALL vol7d_reform(this, miss=.true.)
10799
10800END SUBROUTINE vol7d_filter
10801
10802
10803!> Metodo per convertire i volumi di dati di un oggetto vol7d in dati
10804!! reali dove possibile. L'oggetto convertito è una copia completa
10805!! dell'originale che può essere quindi distrutto dopo la chiamata.
10806!! Per i dati di anagrafica, al momento sono convertiti solo
10807!! i dati CHARACTER se è passato \a anaconv=.TRUE.
10808!! Gli attributi non sono toccati.
10809SUBROUTINE vol7d_convr(this, that, anaconv)
10810TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
10811TYPE(vol7d),INTENT(INOUT) :: that !< oggetto convertito
10812LOGICAL,OPTIONAL,INTENT(in) :: anaconv !< converti anche anagrafica
10813INTEGER :: i
10814LOGICAL :: fv(1)=(/.false./), tv(1)=(/.true./), acp(1), acn(1)
10815TYPE(vol7d) :: v7d_tmp
10816
10817IF (optio_log(anaconv)) THEN
10818 acp=fv
10819 acn=tv
10820ELSE
10821 acp=tv
10822 acn=fv
10823ENDIF
10824
10825! Volume con solo i dati reali e tutti gli attributi
10826! l'anagrafica e` copiata interamente se necessario
10827CALL vol7d_copy(this, that, &
10828 lanavarr=tv, lanavard=acp, lanavari=acp, lanavarb=acp, lanavarc=acp, &
10829 ldativarr=tv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=fv)
10830
10831! Volume solo di dati double
10832CALL vol7d_copy(this, v7d_tmp, &
10833 lanavarr=fv, lanavard=acn, lanavari=fv, lanavarb=fv, lanavarc=fv, &
10834 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
10835 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
10836 ldativarr=fv, ldativard=tv, ldativari=fv, ldativarb=fv, ldativarc=fv, &
10837 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
10838 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
10839
10840! converto a dati reali
10841IF (ASSOCIATED(v7d_tmp%anavar%d) .OR. ASSOCIATED(v7d_tmp%dativar%d)) THEN
10842
10843 IF (ASSOCIATED(v7d_tmp%anavar%d)) THEN
10844! alloco i dati reali e vi trasferisco i double
10845 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanad, 1), SIZE(v7d_tmp%volanad, 2), &
10846 SIZE(v7d_tmp%volanad, 3)))
10847 DO i = 1, SIZE(v7d_tmp%anavar%d)
10848 v7d_tmp%volanar(:,i,:) = &
10849 realdat(v7d_tmp%volanad(:,i,:), v7d_tmp%anavar%d(i))
10850 ENDDO
10851 DEALLOCATE(v7d_tmp%volanad)
10852! trasferisco le variabili
10853 v7d_tmp%anavar%r => v7d_tmp%anavar%d
10854 NULLIFY(v7d_tmp%anavar%d)
10855 ENDIF
10856
10857 IF (ASSOCIATED(v7d_tmp%dativar%d)) THEN
10858! alloco i dati reali e vi trasferisco i double
10859 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatid, 1), SIZE(v7d_tmp%voldatid, 2), &
10860 SIZE(v7d_tmp%voldatid, 3), SIZE(v7d_tmp%voldatid, 4), SIZE(v7d_tmp%voldatid, 5), &
10861 SIZE(v7d_tmp%voldatid, 6)))
10862 DO i = 1, SIZE(v7d_tmp%dativar%d)
10863 v7d_tmp%voldatir(:,:,:,:,i,:) = &
10864 realdat(v7d_tmp%voldatid(:,:,:,:,i,:), v7d_tmp%dativar%d(i))
10865 ENDDO
10866 DEALLOCATE(v7d_tmp%voldatid)
10867! trasferisco le variabili
10868 v7d_tmp%dativar%r => v7d_tmp%dativar%d
10869 NULLIFY(v7d_tmp%dativar%d)
10870 ENDIF
10871
10872! fondo con il volume definitivo
10873 CALL vol7d_merge(that, v7d_tmp)
10874ELSE
10875 CALL delete(v7d_tmp)
10876ENDIF
10877
10878
10879! Volume solo di dati interi
10880CALL vol7d_copy(this, v7d_tmp, &
10881 lanavarr=fv, lanavard=fv, lanavari=acn, lanavarb=fv, lanavarc=fv, &
10882 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
10883 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
10884 ldativarr=fv, ldativard=fv, ldativari=tv, ldativarb=fv, ldativarc=fv, &
10885 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
10886 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
10887
10888! converto a dati reali
10889IF (ASSOCIATED(v7d_tmp%anavar%i) .OR. ASSOCIATED(v7d_tmp%dativar%i)) THEN
10890
10891 IF (ASSOCIATED(v7d_tmp%anavar%i)) THEN
10892! alloco i dati reali e vi trasferisco gli interi
10893 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanai, 1), SIZE(v7d_tmp%volanai, 2), &
10894 SIZE(v7d_tmp%volanai, 3)))
10895 DO i = 1, SIZE(v7d_tmp%anavar%i)
10896 v7d_tmp%volanar(:,i,:) = &
10897 realdat(v7d_tmp%volanai(:,i,:), v7d_tmp%anavar%i(i))
10898 ENDDO
10899 DEALLOCATE(v7d_tmp%volanai)
10900! trasferisco le variabili
10901 v7d_tmp%anavar%r => v7d_tmp%anavar%i
10902 NULLIFY(v7d_tmp%anavar%i)
10903 ENDIF
10904
10905 IF (ASSOCIATED(v7d_tmp%dativar%i)) THEN
10906! alloco i dati reali e vi trasferisco gli interi
10907 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatii, 1), SIZE(v7d_tmp%voldatii, 2), &
10908 SIZE(v7d_tmp%voldatii, 3), SIZE(v7d_tmp%voldatii, 4), SIZE(v7d_tmp%voldatii, 5), &
10909 SIZE(v7d_tmp%voldatii, 6)))
10910 DO i = 1, SIZE(v7d_tmp%dativar%i)
10911 v7d_tmp%voldatir(:,:,:,:,i,:) = &
10912 realdat(v7d_tmp%voldatii(:,:,:,:,i,:), v7d_tmp%dativar%i(i))
10913 ENDDO
10914 DEALLOCATE(v7d_tmp%voldatii)
10915! trasferisco le variabili
10916 v7d_tmp%dativar%r => v7d_tmp%dativar%i
10917 NULLIFY(v7d_tmp%dativar%i)
10918 ENDIF
10919
10920! fondo con il volume definitivo
10921 CALL vol7d_merge(that, v7d_tmp)
10922ELSE
10923 CALL delete(v7d_tmp)
10924ENDIF
10925
10926
10927! Volume solo di dati byte
10928CALL vol7d_copy(this, v7d_tmp, &
10929 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=acn, lanavarc=fv, &
10930 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
10931 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
10932 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=tv, ldativarc=fv, &
10933 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
10934 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
10935
10936! converto a dati reali
10937IF (ASSOCIATED(v7d_tmp%anavar%b) .OR. ASSOCIATED(v7d_tmp%dativar%b)) THEN
10938
10939 IF (ASSOCIATED(v7d_tmp%anavar%b)) THEN
10940! alloco i dati reali e vi trasferisco i byte
10941 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanab, 1), SIZE(v7d_tmp%volanab, 2), &
10942 SIZE(v7d_tmp%volanab, 3)))
10943 DO i = 1, SIZE(v7d_tmp%anavar%b)
10944 v7d_tmp%volanar(:,i,:) = &
10945 realdat(v7d_tmp%volanab(:,i,:), v7d_tmp%anavar%b(i))
10946 ENDDO
10947 DEALLOCATE(v7d_tmp%volanab)
10948! trasferisco le variabili
10949 v7d_tmp%anavar%r => v7d_tmp%anavar%b
10950 NULLIFY(v7d_tmp%anavar%b)
10951 ENDIF
10952
10953 IF (ASSOCIATED(v7d_tmp%dativar%b)) THEN
10954! alloco i dati reali e vi trasferisco i byte
10955 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatib, 1), SIZE(v7d_tmp%voldatib, 2), &
10956 SIZE(v7d_tmp%voldatib, 3), SIZE(v7d_tmp%voldatib, 4), SIZE(v7d_tmp%voldatib, 5), &
10957 SIZE(v7d_tmp%voldatib, 6)))
10958 DO i = 1, SIZE(v7d_tmp%dativar%b)
10959 v7d_tmp%voldatir(:,:,:,:,i,:) = &
10960 realdat(v7d_tmp%voldatib(:,:,:,:,i,:), v7d_tmp%dativar%b(i))
10961 ENDDO
10962 DEALLOCATE(v7d_tmp%voldatib)
10963! trasferisco le variabili
10964 v7d_tmp%dativar%r => v7d_tmp%dativar%b
10965 NULLIFY(v7d_tmp%dativar%b)
10966 ENDIF
10967
10968! fondo con il volume definitivo
10969 CALL vol7d_merge(that, v7d_tmp)
10970ELSE
10971 CALL delete(v7d_tmp)
10972ENDIF
10973
10974
10975! Volume solo di dati character
10976CALL vol7d_copy(this, v7d_tmp, &
10977 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=fv, lanavarc=acn, &
10978 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
10979 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
10980 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=tv, &
10981 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
10982 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
10983
10984! converto a dati reali
10985IF (ASSOCIATED(v7d_tmp%anavar%c) .OR. ASSOCIATED(v7d_tmp%dativar%c)) THEN
10986
10987 IF (ASSOCIATED(v7d_tmp%anavar%c)) THEN
10988! alloco i dati reali e vi trasferisco i character
10989 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanac, 1), SIZE(v7d_tmp%volanac, 2), &
10990 SIZE(v7d_tmp%volanac, 3)))
10991 DO i = 1, SIZE(v7d_tmp%anavar%c)
10992 v7d_tmp%volanar(:,i,:) = &
10993 realdat(v7d_tmp%volanac(:,i,:), v7d_tmp%anavar%c(i))
10994 ENDDO
10995 DEALLOCATE(v7d_tmp%volanac)
10996! trasferisco le variabili
10997 v7d_tmp%anavar%r => v7d_tmp%anavar%c
10998 NULLIFY(v7d_tmp%anavar%c)
10999 ENDIF
11000
11001 IF (ASSOCIATED(v7d_tmp%dativar%c)) THEN
11002! alloco i dati reali e vi trasferisco i character
11003 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatic, 1), SIZE(v7d_tmp%voldatic, 2), &
11004 SIZE(v7d_tmp%voldatic, 3), SIZE(v7d_tmp%voldatic, 4), SIZE(v7d_tmp%voldatic, 5), &
11005 SIZE(v7d_tmp%voldatic, 6)))
11006 DO i = 1, SIZE(v7d_tmp%dativar%c)
11007 v7d_tmp%voldatir(:,:,:,:,i,:) = &
11008 realdat(v7d_tmp%voldatic(:,:,:,:,i,:), v7d_tmp%dativar%c(i))
11009 ENDDO
11010 DEALLOCATE(v7d_tmp%voldatic)
11011! trasferisco le variabili
11012 v7d_tmp%dativar%r => v7d_tmp%dativar%c
11013 NULLIFY(v7d_tmp%dativar%c)
11014 ENDIF
11015
11016! fondo con il volume definitivo
11017 CALL vol7d_merge(that, v7d_tmp)
11018ELSE
11019 CALL delete(v7d_tmp)
11020ENDIF
11021
11022END SUBROUTINE vol7d_convr
11023
11024
11025!> Metodo per ottenere solo le differenze tra due oggetti vol7d.
11026!! Il primo volume viene confrontato col secondo; nel secondo volume ovunque
11027!! i dati confrontati siano coincidenti viene impostato valore mancante.
11028SUBROUTINE vol7d_diff_only (this, that, data_only,ana)
11029TYPE(vol7d),INTENT(IN) :: this !< primo volume da confrontare
11030TYPE(vol7d),INTENT(OUT) :: that !< secondo volume da confrontare in cui eliminare i dati coincidenti
11031logical , optional, intent(in) :: data_only !< attiva l'elaborazione dei soli dati e non dell'anagrafica (default: .false.)
11032logical , optional, intent(in) :: ana !< attiva l'elaborazione dell'anagrafica (coordinate e ident) (default: .false.)
11033logical :: ldata_only,lana
11034
11035IF (PRESENT(data_only)) THEN
11036 ldata_only = data_only
11037ELSE
11038 ldata_only = .false.
11039ENDIF
11040
11041IF (PRESENT(ana)) THEN
11042 lana = ana
11043ELSE
11044 lana = .false.
11045ENDIF
11046
11047
11048#undef VOL7D_POLY_ARRAY
11049#define VOL7D_POLY_ARRAY voldati
11050#include "vol7d_class_diff.F90"
11051#undef VOL7D_POLY_ARRAY
11052#define VOL7D_POLY_ARRAY voldatiattr
11053#include "vol7d_class_diff.F90"
11054#undef VOL7D_POLY_ARRAY
11055
11056if ( .not. ldata_only) then
11057
11058#define VOL7D_POLY_ARRAY volana
11059#include "vol7d_class_diff.F90"
11060#undef VOL7D_POLY_ARRAY
11061#define VOL7D_POLY_ARRAY volanaattr
11062#include "vol7d_class_diff.F90"
11063#undef VOL7D_POLY_ARRAY
11064
11065 if(lana)then
11066 where ( this%ana == that%ana )
11067 that%ana = vol7d_ana_miss
11068 end where
11069 end if
11070
11071end if
11072
11073
11074
11075END SUBROUTINE vol7d_diff_only
11076
11077
11078
11079! Creo le routine da ripetere per i vari tipi di dati di v7d
11080! tramite un template e il preprocessore
11081#undef VOL7D_POLY_TYPE
11082#undef VOL7D_POLY_TYPES
11083#define VOL7D_POLY_TYPE REAL
11084#define VOL7D_POLY_TYPES r
11085#include "vol7d_class_type_templ.F90"
11086#undef VOL7D_POLY_TYPE
11087#undef VOL7D_POLY_TYPES
11088#define VOL7D_POLY_TYPE DOUBLE PRECISION
11089#define VOL7D_POLY_TYPES d
11090#include "vol7d_class_type_templ.F90"
11091#undef VOL7D_POLY_TYPE
11092#undef VOL7D_POLY_TYPES
11093#define VOL7D_POLY_TYPE INTEGER
11094#define VOL7D_POLY_TYPES i
11095#include "vol7d_class_type_templ.F90"
11096#undef VOL7D_POLY_TYPE
11097#undef VOL7D_POLY_TYPES
11098#define VOL7D_POLY_TYPE INTEGER(kind=int_b)
11099#define VOL7D_POLY_TYPES b
11100#include "vol7d_class_type_templ.F90"
11101#undef VOL7D_POLY_TYPE
11102#undef VOL7D_POLY_TYPES
11103#define VOL7D_POLY_TYPE CHARACTER(len=vol7d_cdatalen)
11104#define VOL7D_POLY_TYPES c
11105#include "vol7d_class_type_templ.F90"
11106
11107! Creo le routine da ripetere per i vari descrittori di dimensioni di v7d
11108! tramite un template e il preprocessore
11109#define VOL7D_SORT
11110#undef VOL7D_NO_ZERO_ALLOC
11111#undef VOL7D_POLY_TYPE
11112#define VOL7D_POLY_TYPE datetime
11113#include "vol7d_class_desc_templ.F90"
11114#undef VOL7D_POLY_TYPE
11115#define VOL7D_POLY_TYPE vol7d_timerange
11116#include "vol7d_class_desc_templ.F90"
11117#undef VOL7D_POLY_TYPE
11118#define VOL7D_POLY_TYPE vol7d_level
11119#include "vol7d_class_desc_templ.F90"
11120#undef VOL7D_SORT
11121#undef VOL7D_POLY_TYPE
11122#define VOL7D_POLY_TYPE vol7d_network
11123#include "vol7d_class_desc_templ.F90"
11124#undef VOL7D_POLY_TYPE
11125#define VOL7D_POLY_TYPE vol7d_ana
11126#include "vol7d_class_desc_templ.F90"
11127#define VOL7D_NO_ZERO_ALLOC
11128#undef VOL7D_POLY_TYPE
11129#define VOL7D_POLY_TYPE vol7d_var
11130#include "vol7d_class_desc_templ.F90"
11131
11132!>\brief Scrittura su file di un volume Vol7d.
11133!! Scrittura su file unformatted di un intero volume Vol7d.
11134!! Il volume viene serializzato e scritto su file.
11135!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
11136!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
11137!! tali parametri saranno in output.
11138!! Se non viene fornito il nome file viene utilizzato un file di default con nome pari al nome del programma in
11139!! esecuzione con postfisso ".v7d".
11140!! Come parametro opzionale c'è la description che insieme alla data corrente viene inserita nell'header del file.
11141subroutine vol7d_write_on_file (this,unit,description,filename,filename_auto)
11142
11143TYPE(vol7d),INTENT(IN) :: this !< volume vol7d da scrivere
11144integer,optional,intent(inout) :: unit !< unità su cui scrivere; se passata =0 ritorna il valore rielaborato (default =rielaborato internamente con getlun )
11145character(len=*),intent(in),optional :: filename !< nome del file su cui scrivere
11146character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
11147character(len=*),INTENT(IN),optional :: description !< descrizione del volume
11148
11149integer :: lunit
11150character(len=254) :: ldescription,arg,lfilename
11151integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
11152 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
11153 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
11154 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
11155 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
11156 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
11157 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
11158!integer :: im,id,iy
11159integer :: tarray(8)
11160logical :: opened,exist
11161
11162 nana=0
11163 ntime=0
11164 ntimerange=0
11165 nlevel=0
11166 nnetwork=0
11167 ndativarr=0
11168 ndativari=0
11169 ndativarb=0
11170 ndativard=0
11171 ndativarc=0
11172 ndatiattrr=0
11173 ndatiattri=0
11174 ndatiattrb=0
11175 ndatiattrd=0
11176 ndatiattrc=0
11177 ndativarattrr=0
11178 ndativarattri=0
11179 ndativarattrb=0
11180 ndativarattrd=0
11181 ndativarattrc=0
11182 nanavarr=0
11183 nanavari=0
11184 nanavarb=0
11185 nanavard=0
11186 nanavarc=0
11187 nanaattrr=0
11188 nanaattri=0
11189 nanaattrb=0
11190 nanaattrd=0
11191 nanaattrc=0
11192 nanavarattrr=0
11193 nanavarattri=0
11194 nanavarattrb=0
11195 nanavarattrd=0
11196 nanavarattrc=0
11197
11198
11199!call idate(im,id,iy)
11200call date_and_time(values=tarray)
11201call getarg(0,arg)
11202
11203if (present(description))then
11204 ldescription=description
11205else
11206 ldescription="Vol7d generated by: "//trim(arg)
11207end if
11208
11209if (.not. present(unit))then
11210 lunit=getunit()
11211else
11212 if (unit==0)then
11213 lunit=getunit()
11214 unit=lunit
11215 else
11216 lunit=unit
11217 end if
11218end if
11219
11220lfilename=trim(arg)//".v7d"
11221if (index(arg,'/',back=.true.) > 0) lfilename=lfilename(index(arg,'/',back=.true.)+1 : )
11222
11223if (present(filename))then
11224 if (filename /= "")then
11225 lfilename=filename
11226 end if
11227end if
11228
11229if (present(filename_auto))filename_auto=lfilename
11230
11231
11232inquire(unit=lunit,opened=opened)
11233if (.not. opened) then
11234! inquire(file=lfilename, EXIST=exist)
11235! IF (exist) THEN
11236! CALL l4f_log(L4F_FATAL, &
11237! 'in vol7d_write_on_file, file exists, cannot open file '//TRIM(lfilename))
11238! CALL raise_fatal_error()
11239! ENDIF
11240 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM')
11241 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
11242end if
11243
11244if (associated(this%ana)) nana=size(this%ana)
11245if (associated(this%time)) ntime=size(this%time)
11246if (associated(this%timerange)) ntimerange=size(this%timerange)
11247if (associated(this%level)) nlevel=size(this%level)
11248if (associated(this%network)) nnetwork=size(this%network)
11249
11250if (associated(this%dativar%r)) ndativarr=size(this%dativar%r)
11251if (associated(this%dativar%i)) ndativari=size(this%dativar%i)
11252if (associated(this%dativar%b)) ndativarb=size(this%dativar%b)
11253if (associated(this%dativar%d)) ndativard=size(this%dativar%d)
11254if (associated(this%dativar%c)) ndativarc=size(this%dativar%c)
11255
11256if (associated(this%datiattr%r)) ndatiattrr=size(this%datiattr%r)
11257if (associated(this%datiattr%i)) ndatiattri=size(this%datiattr%i)
11258if (associated(this%datiattr%b)) ndatiattrb=size(this%datiattr%b)
11259if (associated(this%datiattr%d)) ndatiattrd=size(this%datiattr%d)
11260if (associated(this%datiattr%c)) ndatiattrc=size(this%datiattr%c)
11261
11262if (associated(this%dativarattr%r)) ndativarattrr=size(this%dativarattr%r)
11263if (associated(this%dativarattr%i)) ndativarattri=size(this%dativarattr%i)
11264if (associated(this%dativarattr%b)) ndativarattrb=size(this%dativarattr%b)
11265if (associated(this%dativarattr%d)) ndativarattrd=size(this%dativarattr%d)
11266if (associated(this%dativarattr%c)) ndativarattrc=size(this%dativarattr%c)
11267
11268if (associated(this%anavar%r)) nanavarr=size(this%anavar%r)
11269if (associated(this%anavar%i)) nanavari=size(this%anavar%i)
11270if (associated(this%anavar%b)) nanavarb=size(this%anavar%b)
11271if (associated(this%anavar%d)) nanavard=size(this%anavar%d)
11272if (associated(this%anavar%c)) nanavarc=size(this%anavar%c)
11273
11274if (associated(this%anaattr%r)) nanaattrr=size(this%anaattr%r)
11275if (associated(this%anaattr%i)) nanaattri=size(this%anaattr%i)
11276if (associated(this%anaattr%b)) nanaattrb=size(this%anaattr%b)
11277if (associated(this%anaattr%d)) nanaattrd=size(this%anaattr%d)
11278if (associated(this%anaattr%c)) nanaattrc=size(this%anaattr%c)
11279
11280if (associated(this%anavarattr%r)) nanavarattrr=size(this%anavarattr%r)
11281if (associated(this%anavarattr%i)) nanavarattri=size(this%anavarattr%i)
11282if (associated(this%anavarattr%b)) nanavarattrb=size(this%anavarattr%b)
11283if (associated(this%anavarattr%d)) nanavarattrd=size(this%anavarattr%d)
11284if (associated(this%anavarattr%c)) nanavarattrc=size(this%anavarattr%c)
11285
11286write(unit=lunit)ldescription
11287write(unit=lunit)tarray
11288
11289write(unit=lunit)&
11290 nana, ntime, ntimerange, nlevel, nnetwork, &
11291 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
11292 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
11293 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
11294 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
11295 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
11296 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
11297 this%time_definition
11298
11299
11300!write(unit=lunit)this
11301
11302
11303!! prime 5 dimensioni
11304if (associated(this%ana)) call write_unit(this%ana, lunit)
11305if (associated(this%time)) call write_unit(this%time, lunit)
11306if (associated(this%level)) write(unit=lunit)this%level
11307if (associated(this%timerange)) write(unit=lunit)this%timerange
11308if (associated(this%network)) write(unit=lunit)this%network
11309
11310 !! 6a dimensione: variabile dell'anagrafica e dei dati
11311 !! con relativi attributi e in 5 tipi diversi
11312
11313if (associated(this%anavar%r)) write(unit=lunit)this%anavar%r
11314if (associated(this%anavar%i)) write(unit=lunit)this%anavar%i
11315if (associated(this%anavar%b)) write(unit=lunit)this%anavar%b
11316if (associated(this%anavar%d)) write(unit=lunit)this%anavar%d
11317if (associated(this%anavar%c)) write(unit=lunit)this%anavar%c
11318
11319if (associated(this%anaattr%r)) write(unit=lunit)this%anaattr%r
11320if (associated(this%anaattr%i)) write(unit=lunit)this%anaattr%i
11321if (associated(this%anaattr%b)) write(unit=lunit)this%anaattr%b
11322if (associated(this%anaattr%d)) write(unit=lunit)this%anaattr%d
11323if (associated(this%anaattr%c)) write(unit=lunit)this%anaattr%c
11324
11325if (associated(this%anavarattr%r)) write(unit=lunit)this%anavarattr%r
11326if (associated(this%anavarattr%i)) write(unit=lunit)this%anavarattr%i
11327if (associated(this%anavarattr%b)) write(unit=lunit)this%anavarattr%b
11328if (associated(this%anavarattr%d)) write(unit=lunit)this%anavarattr%d
11329if (associated(this%anavarattr%c)) write(unit=lunit)this%anavarattr%c
11330
11331if (associated(this%dativar%r)) write(unit=lunit)this%dativar%r
11332if (associated(this%dativar%i)) write(unit=lunit)this%dativar%i
11333if (associated(this%dativar%b)) write(unit=lunit)this%dativar%b
11334if (associated(this%dativar%d)) write(unit=lunit)this%dativar%d
11335if (associated(this%dativar%c)) write(unit=lunit)this%dativar%c
11336
11337if (associated(this%datiattr%r)) write(unit=lunit)this%datiattr%r
11338if (associated(this%datiattr%i)) write(unit=lunit)this%datiattr%i
11339if (associated(this%datiattr%b)) write(unit=lunit)this%datiattr%b
11340if (associated(this%datiattr%d)) write(unit=lunit)this%datiattr%d
11341if (associated(this%datiattr%c)) write(unit=lunit)this%datiattr%c
11342
11343if (associated(this%dativarattr%r)) write(unit=lunit)this%dativarattr%r
11344if (associated(this%dativarattr%i)) write(unit=lunit)this%dativarattr%i
11345if (associated(this%dativarattr%b)) write(unit=lunit)this%dativarattr%b
11346if (associated(this%dativarattr%d)) write(unit=lunit)this%dativarattr%d
11347if (associated(this%dativarattr%c)) write(unit=lunit)this%dativarattr%c
11348
11349!! Volumi di valori e attributi per anagrafica e dati
11350
11351if (associated(this%volanar)) write(unit=lunit)this%volanar
11352if (associated(this%volanaattrr)) write(unit=lunit)this%volanaattrr
11353if (associated(this%voldatir)) write(unit=lunit)this%voldatir
11354if (associated(this%voldatiattrr)) write(unit=lunit)this%voldatiattrr
11355
11356if (associated(this%volanai)) write(unit=lunit)this%volanai
11357if (associated(this%volanaattri)) write(unit=lunit)this%volanaattri
11358if (associated(this%voldatii)) write(unit=lunit)this%voldatii
11359if (associated(this%voldatiattri)) write(unit=lunit)this%voldatiattri
11360
11361if (associated(this%volanab)) write(unit=lunit)this%volanab
11362if (associated(this%volanaattrb)) write(unit=lunit)this%volanaattrb
11363if (associated(this%voldatib)) write(unit=lunit)this%voldatib
11364if (associated(this%voldatiattrb)) write(unit=lunit)this%voldatiattrb
11365
11366if (associated(this%volanad)) write(unit=lunit)this%volanad
11367if (associated(this%volanaattrd)) write(unit=lunit)this%volanaattrd
11368if (associated(this%voldatid)) write(unit=lunit)this%voldatid
11369if (associated(this%voldatiattrd)) write(unit=lunit)this%voldatiattrd
11370
11371if (associated(this%volanac)) write(unit=lunit)this%volanac
11372if (associated(this%volanaattrc)) write(unit=lunit)this%volanaattrc
11373if (associated(this%voldatic)) write(unit=lunit)this%voldatic
11374if (associated(this%voldatiattrc)) write(unit=lunit)this%voldatiattrc
11375
11376if (.not. present(unit)) close(unit=lunit)
11377
11378end subroutine vol7d_write_on_file
11379
11380
11381!>\brief Lettura da file di un volume Vol7d.
11382!! Lettura da file unformatted di un intero volume Vol7d.
11383!! Questa subroutine comprende vol7d_alloc e vol7d_alloc_vol.
11384!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
11385!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
11386!! tali parametri saranno in output.
11387
11388
11389subroutine vol7d_read_from_file (this,unit,filename,description,tarray,filename_auto)
11390
11391TYPE(vol7d),INTENT(OUT) :: this !< Volume vol7d da leggere
11392integer,intent(inout),optional :: unit !< unità su cui è stato aperto un file; se =0 rielaborato internamente (default = elaborato internamente con getunit)
11393character(len=*),INTENT(in),optional :: filename !< nome del file eventualmente da aprire (default = (nome dell'eseguibile)//.v7d )
11394character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
11395character(len=*),INTENT(out),optional :: description !< descrizione del volume letto
11396integer,intent(out),optional :: tarray(8) !< vettore come definito da "date_and_time" della data di scrittura del volume
11397
11398
11399integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
11400 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
11401 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
11402 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
11403 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
11404 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
11405 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
11406
11407character(len=254) :: ldescription,lfilename,arg
11408integer :: ltarray(8),lunit,ios
11409logical :: opened,exist
11410
11411
11412call getarg(0,arg)
11413
11414if (.not. present(unit))then
11415 lunit=getunit()
11416else
11417 if (unit==0)then
11418 lunit=getunit()
11419 unit=lunit
11420 else
11421 lunit=unit
11422 end if
11423end if
11424
11425lfilename=trim(arg)//".v7d"
11426if (index(arg,'/',back=.true.) > 0) lfilename=lfilename(index(arg,'/',back=.true.)+1 : )
11427
11428if (present(filename))then
11429 if (filename /= "")then
11430 lfilename=filename
11431 end if
11432end if
11433
11434if (present(filename_auto))filename_auto=lfilename
11435
11436
11437inquire(unit=lunit,opened=opened)
11438IF (.NOT. opened) THEN
11439 inquire(file=lfilename,exist=exist)
11440 IF (.NOT.exist) THEN
11441 CALL l4f_log(l4f_fatal, &
11442 'in vol7d_read_from_file, file does not exists, cannot open')
11443 CALL raise_fatal_error()
11444 ENDIF
11445 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM', &
11446 status='OLD', action='READ')
11447 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
11448end if
11449
11450
11451call init(this)
11452read(unit=lunit,iostat=ios)ldescription
11453
11454if (ios < 0) then ! A negative value indicates that the End of File or End of Record
11455 call vol7d_alloc (this)
11456 call vol7d_alloc_vol (this)
11457 if (present(description))description=ldescription
11458 if (present(tarray))tarray=ltarray
11459 if (.not. present(unit)) close(unit=lunit)
11460end if
11461
11462read(unit=lunit)ltarray
11463
11464CALL l4f_log(l4f_info, 'Reading vol7d from file')
11465CALL l4f_log(l4f_info, 'description: '//trim(ldescription))
11466CALL l4f_log(l4f_info, 'written on '//trim(to_char(ltarray(1)))//' '// &
11467 trim(to_char(ltarray(2)))//' '//trim(to_char(ltarray(3))))
11468
11469if (present(description))description=ldescription
11470if (present(tarray))tarray=ltarray
11471
11472read(unit=lunit)&
11473 nana, ntime, ntimerange, nlevel, nnetwork, &
11474 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
11475 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
11476 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
11477 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
11478 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
11479 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
11480 this%time_definition
11481
11482call vol7d_alloc (this, &
11483 nana=nana, ntime=ntime, ntimerange=ntimerange, nlevel=nlevel, nnetwork=nnetwork,&
11484 ndativarr=ndativarr, ndativari=ndativari, ndativarb=ndativarb,&
11485 ndativard=ndativard, ndativarc=ndativarc,&
11486 ndatiattrr=ndatiattrr, ndatiattri=ndatiattri, ndatiattrb=ndatiattrb,&
11487 ndatiattrd=ndatiattrd, ndatiattrc=ndatiattrc,&
11488 ndativarattrr=ndativarattrr, ndativarattri=ndativarattri, ndativarattrb=ndativarattrb, &
11489 ndativarattrd=ndativarattrd, ndativarattrc=ndativarattrc,&
11490 nanavarr=nanavarr, nanavari=nanavari, nanavarb=nanavarb, &
11491 nanavard=nanavard, nanavarc=nanavarc,&
11492 nanaattrr=nanaattrr, nanaattri=nanaattri, nanaattrb=nanaattrb,&
11493 nanaattrd=nanaattrd, nanaattrc=nanaattrc,&
11494 nanavarattrr=nanavarattrr, nanavarattri=nanavarattri, nanavarattrb=nanavarattrb, &
11495 nanavarattrd=nanavarattrd, nanavarattrc=nanavarattrc)
11496
11497
11498if (associated(this%ana)) call read_unit(this%ana, lunit)
11499if (associated(this%time)) call read_unit(this%time, lunit)
11500if (associated(this%level)) read(unit=lunit)this%level
11501if (associated(this%timerange)) read(unit=lunit)this%timerange
11502if (associated(this%network)) read(unit=lunit)this%network
11503
11504if (associated(this%anavar%r)) read(unit=lunit)this%anavar%r
11505if (associated(this%anavar%i)) read(unit=lunit)this%anavar%i
11506if (associated(this%anavar%b)) read(unit=lunit)this%anavar%b
11507if (associated(this%anavar%d)) read(unit=lunit)this%anavar%d
11508if (associated(this%anavar%c)) read(unit=lunit)this%anavar%c
11509
11510if (associated(this%anaattr%r)) read(unit=lunit)this%anaattr%r
11511if (associated(this%anaattr%i)) read(unit=lunit)this%anaattr%i
11512if (associated(this%anaattr%b)) read(unit=lunit)this%anaattr%b
11513if (associated(this%anaattr%d)) read(unit=lunit)this%anaattr%d
11514if (associated(this%anaattr%c)) read(unit=lunit)this%anaattr%c
11515
11516if (associated(this%anavarattr%r)) read(unit=lunit)this%anavarattr%r
11517if (associated(this%anavarattr%i)) read(unit=lunit)this%anavarattr%i
11518if (associated(this%anavarattr%b)) read(unit=lunit)this%anavarattr%b
11519if (associated(this%anavarattr%d)) read(unit=lunit)this%anavarattr%d
11520if (associated(this%anavarattr%c)) read(unit=lunit)this%anavarattr%c
11521
11522if (associated(this%dativar%r)) read(unit=lunit)this%dativar%r
11523if (associated(this%dativar%i)) read(unit=lunit)this%dativar%i
11524if (associated(this%dativar%b)) read(unit=lunit)this%dativar%b
11525if (associated(this%dativar%d)) read(unit=lunit)this%dativar%d
11526if (associated(this%dativar%c)) read(unit=lunit)this%dativar%c
11527
11528if (associated(this%datiattr%r)) read(unit=lunit)this%datiattr%r
11529if (associated(this%datiattr%i)) read(unit=lunit)this%datiattr%i
11530if (associated(this%datiattr%b)) read(unit=lunit)this%datiattr%b
11531if (associated(this%datiattr%d)) read(unit=lunit)this%datiattr%d
11532if (associated(this%datiattr%c)) read(unit=lunit)this%datiattr%c
11533
11534if (associated(this%dativarattr%r)) read(unit=lunit)this%dativarattr%r
11535if (associated(this%dativarattr%i)) read(unit=lunit)this%dativarattr%i
11536if (associated(this%dativarattr%b)) read(unit=lunit)this%dativarattr%b
11537if (associated(this%dativarattr%d)) read(unit=lunit)this%dativarattr%d
11538if (associated(this%dativarattr%c)) read(unit=lunit)this%dativarattr%c
11539
11540call vol7d_alloc_vol (this)
11541
11542!! Volumi di valori e attributi per anagrafica e dati
11543
11544if (associated(this%volanar)) read(unit=lunit)this%volanar
11545if (associated(this%volanaattrr)) read(unit=lunit)this%volanaattrr
11546if (associated(this%voldatir)) read(unit=lunit)this%voldatir
11547if (associated(this%voldatiattrr)) read(unit=lunit)this%voldatiattrr
11548
11549if (associated(this%volanai)) read(unit=lunit)this%volanai
11550if (associated(this%volanaattri)) read(unit=lunit)this%volanaattri
11551if (associated(this%voldatii)) read(unit=lunit)this%voldatii
11552if (associated(this%voldatiattri)) read(unit=lunit)this%voldatiattri
11553
11554if (associated(this%volanab)) read(unit=lunit)this%volanab
11555if (associated(this%volanaattrb)) read(unit=lunit)this%volanaattrb
11556if (associated(this%voldatib)) read(unit=lunit)this%voldatib
11557if (associated(this%voldatiattrb)) read(unit=lunit)this%voldatiattrb
11558
11559if (associated(this%volanad)) read(unit=lunit)this%volanad
11560if (associated(this%volanaattrd)) read(unit=lunit)this%volanaattrd
11561if (associated(this%voldatid)) read(unit=lunit)this%voldatid
11562if (associated(this%voldatiattrd)) read(unit=lunit)this%voldatiattrd
11563
11564if (associated(this%volanac)) read(unit=lunit)this%volanac
11565if (associated(this%volanaattrc)) read(unit=lunit)this%volanaattrc
11566if (associated(this%voldatic)) read(unit=lunit)this%voldatic
11567if (associated(this%voldatiattrc)) read(unit=lunit)this%voldatiattrc
11568
11569if (.not. present(unit)) close(unit=lunit)
11570
11571end subroutine vol7d_read_from_file
11572
11573
11574! to double precision
11575elemental doubleprecision function doubledatd(voldat,var)
11576doubleprecision,intent(in) :: voldat
11577type(vol7d_var),intent(in) :: var
11578
11579doubledatd=voldat
11580
11581end function doubledatd
11582
11583
11584elemental doubleprecision function doubledatr(voldat,var)
11585real,intent(in) :: voldat
11586type(vol7d_var),intent(in) :: var
11587
11588if (c_e(voldat))then
11589 doubledatr=dble(voldat)
11590else
11591 doubledatr=dmiss
11592end if
11593
11594end function doubledatr
11595
11596
11597elemental doubleprecision function doubledati(voldat,var)
11598integer,intent(in) :: voldat
11599type(vol7d_var),intent(in) :: var
11600
11601if (c_e(voldat)) then
11602 if (c_e(var%scalefactor))then
11603 doubledati=dble(voldat)/10.d0**var%scalefactor
11604 else
11605 doubledati=dble(voldat)
11606 endif
11607else
11608 doubledati=dmiss
11609end if
11610
11611end function doubledati
11612
11613
11614elemental doubleprecision function doubledatb(voldat,var)
11615integer(kind=int_b),intent(in) :: voldat
11616type(vol7d_var),intent(in) :: var
11617
11618if (c_e(voldat)) then
11619 if (c_e(var%scalefactor))then
11620 doubledatb=dble(voldat)/10.d0**var%scalefactor
11621 else
11622 doubledatb=dble(voldat)
11623 endif
11624else
11625 doubledatb=dmiss
11626end if
11627
11628end function doubledatb
11629
11630
11631elemental doubleprecision function doubledatc(voldat,var)
11632CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
11633type(vol7d_var),intent(in) :: var
11634
11635doubledatc = c2d(voldat)
11636if (c_e(doubledatc) .and. c_e(var%scalefactor))then
11637 doubledatc=doubledatc/10.d0**var%scalefactor
11638end if
11639
11640end function doubledatc
11641
11642
11643! to integer
11644elemental integer function integerdatd(voldat,var)
11645doubleprecision,intent(in) :: voldat
11646type(vol7d_var),intent(in) :: var
11647
11648if (c_e(voldat))then
11649 if (c_e(var%scalefactor)) then
11650 integerdatd=nint(voldat*10d0**var%scalefactor)
11651 else
11652 integerdatd=nint(voldat)
11653 endif
11654else
11655 integerdatd=imiss
11656end if
11657
11658end function integerdatd
11659
11660
11661elemental integer function integerdatr(voldat,var)
11662real,intent(in) :: voldat
11663type(vol7d_var),intent(in) :: var
11664
11665if (c_e(voldat))then
11666 if (c_e(var%scalefactor)) then
11667 integerdatr=nint(voldat*10d0**var%scalefactor)
11668 else
11669 integerdatr=nint(voldat)
11670 endif
11671else
11672 integerdatr=imiss
11673end if
11674
11675end function integerdatr
11676
11677
11678elemental integer function integerdati(voldat,var)
11679integer,intent(in) :: voldat
11680type(vol7d_var),intent(in) :: var
11681
11682integerdati=voldat
11683
11684end function integerdati
11685
11686
11687elemental integer function integerdatb(voldat,var)
11688integer(kind=int_b),intent(in) :: voldat
11689type(vol7d_var),intent(in) :: var
11690
11691if (c_e(voldat))then
11692 integerdatb=voldat
11693else
11694 integerdatb=imiss
11695end if
11696
11697end function integerdatb
11698
11699
11700elemental integer function integerdatc(voldat,var)
11701CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
11702type(vol7d_var),intent(in) :: var
11703
11704integerdatc=c2i(voldat)
11705
11706end function integerdatc
11707
11708
11709! to real
11710elemental real function realdatd(voldat,var)
11711doubleprecision,intent(in) :: voldat
11712type(vol7d_var),intent(in) :: var
11713
11714if (c_e(voldat))then
11715 realdatd=real(voldat)
11716else
11717 realdatd=rmiss
11718end if
11719
11720end function realdatd
11721
11722
11723elemental real function realdatr(voldat,var)
11724real,intent(in) :: voldat
11725type(vol7d_var),intent(in) :: var
11726
11727realdatr=voldat
11728
11729end function realdatr
11730
11731
11732elemental real function realdati(voldat,var)
11733integer,intent(in) :: voldat
11734type(vol7d_var),intent(in) :: var
11735
11736if (c_e(voldat)) then
11737 if (c_e(var%scalefactor))then
11738 realdati=float(voldat)/10.**var%scalefactor
11739 else
11740 realdati=float(voldat)
11741 endif
11742else
11743 realdati=rmiss
11744end if
11745
11746end function realdati
11747
11748
11749elemental real function realdatb(voldat,var)
11750integer(kind=int_b),intent(in) :: voldat
11751type(vol7d_var),intent(in) :: var
11752
11753if (c_e(voldat)) then
11754 if (c_e(var%scalefactor))then
11755 realdatb=float(voldat)/10**var%scalefactor
11756 else
11757 realdatb=float(voldat)
11758 endif
11759else
11760 realdatb=rmiss
11761end if
11762
11763end function realdatb
11764
11765
11766elemental real function realdatc(voldat,var)
11767CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
11768type(vol7d_var),intent(in) :: var
11769
11770realdatc=c2r(voldat)
11771if (c_e(realdatc) .and. c_e(var%scalefactor))then
11772 realdatc=realdatc/10.**var%scalefactor
11773end if
11774
11775end function realdatc
11776
11777
11778!> Return an ana volume of a requested variable as real data.
11779!! It returns a 2-d array of the proper shape (ana x network) for the
11780!! ana variable requested, converted to real type. If the conversion
11781!! fails or if the variable is not contained in the ana volume,
11782!! missing data are returned.
11783FUNCTION realanavol(this, var) RESULT(vol)
11784TYPE(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
11785TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
11786REAL :: vol(SIZE(this%ana),size(this%network))
11787
11788CHARACTER(len=1) :: dtype
11789INTEGER :: indvar
11790
11791dtype = cmiss
11792indvar = index(this%anavar, var, type=dtype)
11793
11794IF (indvar > 0) THEN
11795 SELECT CASE (dtype)
11796 CASE("d")
11797 vol = realdat(this%volanad(:,indvar,:), var)
11798 CASE("r")
11799 vol = this%volanar(:,indvar,:)
11800 CASE("i")
11801 vol = realdat(this%volanai(:,indvar,:), var)
11802 CASE("b")
11803 vol = realdat(this%volanab(:,indvar,:), var)
11804 CASE("c")
11805 vol = realdat(this%volanac(:,indvar,:), var)
11806 CASE default
11807 vol = rmiss
11808 END SELECT
11809ELSE
11810 vol = rmiss
11811ENDIF
11812
11813END FUNCTION realanavol
11814
11815
11816!> Return an ana volume of a requested variable as integer data.
11817!! It returns a 2-d array of the proper shape (ana x network) for the
11818!! ana variable requested, converted to integer type. If the conversion
11819!! fails or if the variable is not contained in the ana volume,
11820!! missing data are returned.
11821FUNCTION integeranavol(this, var) RESULT(vol)
11822TYPE(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
11823TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
11824INTEGER :: vol(SIZE(this%ana),size(this%network))
11825
11826CHARACTER(len=1) :: dtype
11827INTEGER :: indvar
11828
11829dtype = cmiss
11830indvar = index(this%anavar, var, type=dtype)
11831
11832IF (indvar > 0) THEN
11833 SELECT CASE (dtype)
11834 CASE("d")
11835 vol = integerdat(this%volanad(:,indvar,:), var)
11836 CASE("r")
11837 vol = integerdat(this%volanar(:,indvar,:), var)
11838 CASE("i")
11839 vol = this%volanai(:,indvar,:)
11840 CASE("b")
11841 vol = integerdat(this%volanab(:,indvar,:), var)
11842 CASE("c")
11843 vol = integerdat(this%volanac(:,indvar,:), var)
11844 CASE default
11845 vol = imiss
11846 END SELECT
11847ELSE
11848 vol = imiss
11849ENDIF
11850
11851END FUNCTION integeranavol
11852
11853
11854!> Move data for all variables from one coordinate in the character volume to other.
11855!! Only not missing data will be copyed and all attributes will be moved together.
11856!! Usefull to colapse data spread in more indices (level or time or ....).
11857!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
11858!! to obtain a new vol7d with less data shape.
11859subroutine move_datac (v7d,&
11860 indana,indtime,indlevel,indtimerange,indnetwork,&
11861 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
11862
11863TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
11864
11865integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
11866integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
11867integer :: inddativar,inddativarattr
11868
11869
11870do inddativar=1,size(v7d%dativar%c)
11871
11872 if (c_e(v7d%voldatic(indana,indtime,indlevel,indtimerange,inddativar,indnetwork)) .and. &
11873 .not. c_e(v7d%voldatic(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
11874 ) then
11875
11876 ! dati
11877 v7d%voldatic &
11878 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
11879 v7d%voldatic &
11880 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
11881
11882
11883 ! attributi
11884 if (associated (v7d%dativarattr%i)) then
11885 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%c(inddativar))
11886 if (inddativarattr > 0 ) then
11887 v7d%voldatiattri &
11888 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
11889 v7d%voldatiattri &
11890 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
11891 end if
11892 end if
11893
11894 if (associated (v7d%dativarattr%r)) then
11895 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%c(inddativar))
11896 if (inddativarattr > 0 ) then
11897 v7d%voldatiattrr &
11898 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
11899 v7d%voldatiattrr &
11900 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
11901 end if
11902 end if
11903
11904 if (associated (v7d%dativarattr%d)) then
11905 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%c(inddativar))
11906 if (inddativarattr > 0 ) then
11907 v7d%voldatiattrd &
11908 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
11909 v7d%voldatiattrd &
11910 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
11911 end if
11912 end if
11913
11914 if (associated (v7d%dativarattr%b)) then
11915 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%c(inddativar))
11916 if (inddativarattr > 0 ) then
11917 v7d%voldatiattrb &
11918 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
11919 v7d%voldatiattrb &
11920 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
11921 end if
11922 end if
11923
11924 if (associated (v7d%dativarattr%c)) then
11925 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%c(inddativar))
11926 if (inddativarattr > 0 ) then
11927 v7d%voldatiattrc &
11928 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
11929 v7d%voldatiattrc &
11930 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
11931 end if
11932 end if
11933
11934 end if
11935
11936end do
11937
11938end subroutine move_datac
11939
11940!> Move data for all variables from one coordinate in the real volume to other.
11941!! Only not missing data will be copyed and all attributes will be moved together.
11942!! Usefull to colapse data spread in more indices (level or time or ....).
11943!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
11944!! to obtain a new vol7d with less data shape.
11945subroutine move_datar (v7d,&
11946 indana,indtime,indlevel,indtimerange,indnetwork,&
11947 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
11948
11949TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
11950
11951integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
11952integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
11953integer :: inddativar,inddativarattr
11954
11955
11956do inddativar=1,size(v7d%dativar%r)
11957
11958 if (c_e(v7d%voldatir(indana,indtime,indlevel,indtimerange,inddativar,indnetwork)) .and. &
11959 .not. c_e(v7d%voldatir(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
11960 ) then
11961
11962 ! dati
11963 v7d%voldatir &
11964 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
11965 v7d%voldatir &
11966 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
11967
11968
11969 ! attributi
11970 if (associated (v7d%dativarattr%i)) then
11971 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%r(inddativar))
11972 if (inddativarattr > 0 ) then
11973 v7d%voldatiattri &
11974 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
11975 v7d%voldatiattri &
11976 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
11977 end if
11978 end if
11979
11980 if (associated (v7d%dativarattr%r)) then
11981 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%r(inddativar))
11982 if (inddativarattr > 0 ) then
11983 v7d%voldatiattrr &
11984 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
11985 v7d%voldatiattrr &
11986 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
11987 end if
11988 end if
11989
11990 if (associated (v7d%dativarattr%d)) then
11991 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%r(inddativar))
11992 if (inddativarattr > 0 ) then
11993 v7d%voldatiattrd &
11994 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
11995 v7d%voldatiattrd &
11996 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
11997 end if
11998 end if
11999
12000 if (associated (v7d%dativarattr%b)) then
12001 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%r(inddativar))
12002 if (inddativarattr > 0 ) then
12003 v7d%voldatiattrb &
12004 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12005 v7d%voldatiattrb &
12006 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12007 end if
12008 end if
12009
12010 if (associated (v7d%dativarattr%c)) then
12011 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%r(inddativar))
12012 if (inddativarattr > 0 ) then
12013 v7d%voldatiattrc &
12014 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
12015 v7d%voldatiattrc &
12016 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
12017 end if
12018 end if
12019
12020 end if
12021
12022end do
12023
12024end subroutine move_datar
12025
12026
12027!> Reduce some dimensions (level and timerage) for semplification (rounding).
12028!! You can use this for simplify and use variables in computation like alchimia
12029!! where fields have to be on the same coordinate
12030!! It return real or character data only: if input is charcter data only it return character otherwise il return
12031!! all the data converted to real.
12032!! examples:
12033!! means in time for short periods and istantaneous values
12034!! 2 meter and surface levels
12035!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
12036!! will be taken (order is by icreasing var index).
12037!! You can use predefined values for classic semplification
12038!! almost_equal_levels and almost_equal_timeranges
12039!! The level or timerange in output will be defined by the first element of level and timerange list
12040subroutine v7d_rounding(v7din,v7dout,level,timerange,nostatproc)
12041type(vol7d),intent(inout) :: v7din !< input volume
12042type(vol7d),intent(out) :: v7dout !> output volume
12043type(vol7d_level),intent(in),optional :: level(:) !< almost equal level list
12044type(vol7d_timerange),intent(in),optional :: timerange(:) !< almost equal timerange list
12045!logical,intent(in),optional :: merge !< if there are data on more then one almost equal levels or timeranges
12046!! will be merged POINT BY POINT with priority for the fird data found ordered by icreasing var index
12047logical,intent(in),optional :: nostatproc !< do not take in account statistical processing code in timerange and P2
12048
12049integer :: nana,nlevel,ntime,ntimerange,nnetwork,nbin
12050integer :: iana,ilevel,itimerange,indl,indt,itime,inetwork
12051type(vol7d_level) :: roundlevel(size(v7din%level))
12052type(vol7d_timerange) :: roundtimerange(size(v7din%timerange))
12053type(vol7d) :: v7d_tmp
12054
12055
12056nbin=0
12057
12058if (associated(v7din%dativar%r)) nbin = nbin + size(v7din%dativar%r)
12059if (associated(v7din%dativar%i)) nbin = nbin + size(v7din%dativar%i)
12060if (associated(v7din%dativar%d)) nbin = nbin + size(v7din%dativar%d)
12061if (associated(v7din%dativar%b)) nbin = nbin + size(v7din%dativar%b)
12062
12063call init(v7d_tmp)
12064
12065roundlevel=v7din%level
12066
12067if (present(level))then
12068 do ilevel = 1, size(v7din%level)
12069 if ((any(v7din%level(ilevel) .almosteq. level))) then
12070 roundlevel(ilevel)=level(1)
12071 end if
12072 end do
12073end if
12074
12075roundtimerange=v7din%timerange
12076
12077if (present(timerange))then
12078 do itimerange = 1, size(v7din%timerange)
12079 if ((any(v7din%timerange(itimerange) .almosteq. timerange))) then
12080 roundtimerange(itimerange)=timerange(1)
12081 end if
12082 end do
12083end if
12084
12085!set istantaneous values everywere
12086!preserve p1 for forecast time
12087if (optio_log(nostatproc)) then
12088 roundtimerange(:)%timerange=254
12089 roundtimerange(:)%p2=0
12090end if
12091
12092
12093nana=size(v7din%ana)
12094nlevel=count_distinct(roundlevel,back=.true.)
12095ntime=size(v7din%time)
12096ntimerange=count_distinct(roundtimerange,back=.true.)
12097nnetwork=size(v7din%network)
12098
12099call init(v7d_tmp)
12100
12101if (nbin == 0) then
12102 call copy(v7din,v7d_tmp)
12103else
12104 call vol7d_convr(v7din,v7d_tmp)
12105end if
12106
12107v7d_tmp%level=roundlevel
12108v7d_tmp%timerange=roundtimerange
12109
12110do ilevel=1, size(v7d_tmp%level)
12111 indl=index(v7d_tmp%level,roundlevel(ilevel))
12112 do itimerange=1,size(v7d_tmp%timerange)
12113 indt=index(v7d_tmp%timerange,roundtimerange(itimerange))
12114
12115 if (indl /= ilevel .or. indt /= itimerange) then
12116
12117 do iana=1, nana
12118 do itime=1,ntime
12119 do inetwork=1,nnetwork
12120
12121 if (nbin > 0) then
12122 call move_datar (v7d_tmp,&
12123 iana,itime,ilevel,itimerange,inetwork,&
12124 iana,itime,indl,indt,inetwork)
12125 else
12126 call move_datac (v7d_tmp,&
12127 iana,itime,ilevel,itimerange,inetwork,&
12128 iana,itime,indl,indt,inetwork)
12129 end if
12130
12131 end do
12132 end do
12133 end do
12134
12135 end if
12136
12137 end do
12138end do
12139
12140! set to missing level and time > nlevel
12141do ilevel=nlevel+1,size(v7d_tmp%level)
12142 call init (v7d_tmp%level(ilevel))
12143end do
12144
12145do itimerange=ntimerange+1,size(v7d_tmp%timerange)
12146 call init (v7d_tmp%timerange(itimerange))
12147end do
12148
12149!copy with remove
12150CALL copy(v7d_tmp,v7dout,miss=.true.,lsort_timerange=.true.,lsort_level=.true.)
12151CALL delete(v7d_tmp)
12152
12153!call display(v7dout)
12154
12155end subroutine v7d_rounding
12156
12157
12158END MODULE vol7d_class
12159
12160!>\example esempio_qc_convert.f90
12161!!\brief Programma esempio semplice per la scrittura su file di un volume vol7d
12162!!
12163!!Programma che scrive su file un volume vol7d letto da una serie di file ASCII.
12164!!Questo programma scrive i dati del clima che poi verranno letti da modqccli
12165
12166
12167!>\example esempio_v7ddballe_move_and_collapse.f90
12168!!\brief ! Example program to reduce to one the dimensions of levels and time without loss of data
Set of functions that return a trimmed CHARACTER representation of the input variable.
Legge un oggetto datetime/timedelta o un vettore di oggetti datetime/timedelta da un file FORMATTED o...
Scrive un oggetto datetime/timedelta o un vettore di oggetti datetime/timedelta su un file FORMATTED ...
Index method.
Generic subroutine for checking OPTIONAL parameters.
Test for a missing volume.
Check for problems return 0 if all check passed print diagnostics with log4f.
Distruttore per la classe vol7d.
doubleprecision data conversion
Scrittura su file.
Costruttore per la classe vol7d.
integer data conversion
real data conversion
Reduce some dimensions (level and timerage) for semplification (rounding).
Represent data in a pretty string.
This module defines usefull general purpose function and subroutine.
Utilities for CHARACTER variables.
Classi per la gestione delle coordinate temporali.
Gestione degli errori.
Definition of constants to be used for declaring variables of a desired type.
Definition kinds.F90:245
classe per la gestione del logging
Module for quickly interpreting the OPTIONAL parameters passed to a subprogram.
Classe per la gestione dell'anagrafica di stazioni meteo e affini.
Classe per la gestione di un volume completo di dati osservati.
Classe per la gestione dei livelli verticali in osservazioni meteo e affini.
Classe per la gestione delle reti di stazioni per osservazioni meteo e affini.
Classe per la gestione degli intervalli temporali di osservazioni meteo e affini.
Classe per gestire un vettore di oggetti di tipo vol7d_var_class::vol7d_var.
Definisce un oggetto contenente i volumi anagrafica e dati e tutti i descrittori delle loro dimension...

Generated with Doxygen.