libsim Versione 8.0.0

◆ vol7d_write_on_file()

subroutine, private vol7d_write_on_file ( type(vol7d), intent(in) this,
integer, intent(inout), optional unit,
character(len=*), intent(in), optional description,
character(len=*), intent(in), optional filename,
character(len=*), intent(out), optional filename_auto )
private

Scrittura su file di un volume Vol7d.

Scrittura su file unformatted di un intero volume Vol7d. Il volume viene serializzato e scritto su file. 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. Se non viene fornito il nome file viene utilizzato un file di default con nome pari al nome del programma in esecuzione con postfisso ".v7d". Come parametro opzionale c'è la description che insieme alla data corrente viene inserita nell'header del file.

Parametri
[in]thisvolume vol7d da scrivere
[in,out]unitunità su cui scrivere; se passata =0 ritorna il valore rielaborato (default =rielaborato internamente con getlun )
[in]filenamenome del file su cui scrivere
[out]filename_autonome del file generato se "filename" è omesso
[in]descriptiondescrizione del volume

Definizione alla linea 8469 del file vol7d_class.F90.

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