libsim Versione 8.0.0

◆ vol7d_get_volanaattrb()

subroutine vol7d_get_volanaattrb ( type(vol7d), intent(in) this,
integer, dimension(:), intent(in) dimlist,
integer(kind=int_b), dimension(:), optional, pointer vol1dp,
integer(kind=int_b), dimension(:,:), optional, pointer vol2dp,
integer(kind=int_b), dimension(:,:,:), optional, pointer vol3dp,
integer(kind=int_b), dimension(:,:,:,:), optional, pointer vol4dp )

Crea una vista a dimensione ridotta di un volume di attributi di anagrafica di tipo INTEGER(kind=int_b).

È necessario fornire uno solo dei parametri opzionali vol*dp corrispondente al numero di dimensioni richieste. L'ordine delle dimensioni nella vista è quello prefissato in vol7d indipendentemente dall'ordine delle dimensioni fornito in dimlist. In caso di fallimento, in particolare se dimlist non contiene tutte le dimensioni non degeneri del volume richiesto oppure se una delle dimensioni è =0, il puntatore vol*dp è restituito in uno stato disassociato, per cui è opportuno controllare sempre in uscita, lo stato del puntatore per evitare che il programma abortisca con un errore di sistema, ad esempio:

INTEGER(kind=int_b), POINTER :: vol1d(:)
...
CALL vol7d_get_volanaattrb(v7d1, (/vol7d_ana_d/), vol1d)
IF (ASSOCIATED(vol1d)) THEN
print*,vol1d
...
ENDIF
return
Parametri
[in]thisoggetto di cui creare la vista
[in]dimlistlista delle dimensioni da includere nella vista, attenzione tutte le dimensioni non degeneri (cioè con estensione >1) devono essere incluse nella lista; utilizzare le costanti vol7d_ana_a ... vol7d_attr_a, ecc.
vol1dparray che in uscita conterrà la vista 1d
vol2dparray che in uscita conterrà la vista 2d
vol3dparray che in uscita conterrà la vista 3d
vol4dparray che in uscita conterrà la vista 4d

Definizione alla linea 5621 del file vol7d_class.F90.

5623! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
5624! authors:
5625! Davide Cesari <dcesari@arpa.emr.it>
5626! Paolo Patruno <ppatruno@arpa.emr.it>
5627
5628! This program is free software; you can redistribute it and/or
5629! modify it under the terms of the GNU General Public License as
5630! published by the Free Software Foundation; either version 2 of
5631! the License, or (at your option) any later version.
5632
5633! This program is distributed in the hope that it will be useful,
5634! but WITHOUT ANY WARRANTY; without even the implied warranty of
5635! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5636! GNU General Public License for more details.
5637
5638! You should have received a copy of the GNU General Public License
5639! along with this program. If not, see <http://www.gnu.org/licenses/>.
5640#include "config.h"
5641
5642!> \defgroup vol7d Libsim package, vol7d library.
5643!! The libsim vol7d library contains classes for managing pointwise
5644!! data, tipically weather observations, and for their import from a
5645!! Db-All.e database or from a WMO BUFR file. In order to compile and
5646!! link programs using this library, you have to insert the required
5647!! \c USE statements in the program units involved, specify the
5648!! location of module files when compiling (tipically \c
5649!! -I/usr/lib/gfortran/modules or \c -I/usr/lib64/gfortran/modules or
5650!! \c -I/usr/include) and indicate the library name \c -lsim_vol7d
5651!! when linking, assuming that the library has been installed in a
5652!! default location.
5653
5654!> Classe per la gestione di un volume completo di dati osservati.
5655!! Questo modulo definisce gli oggetti e i metodi per gestire
5656!! volumi di dati meteorologici sparsi.
5657!! I volumi definiti sono principalmente di 4 categorie:
5658!! - volumi di anagrafica (vol7d::volanar & c.), hanno 3 dimensioni:
5659!! - anagrafica
5660!! - variabile di anagrafica
5661!! - rete
5662!! - volumi di attributi di anagrafica (vol7d::volanaattrr & c.), hanno 4 dimensioni:
5663!! - anagrafica
5664!! - variabile di anagrafica
5665!! - rete
5666!! - variabile di attributi delle variabili di anagrafica
5667!! - volumi di dati (vol7d::voldatir & c.), hanno 6 dimensioni:
5668!! - anagrafica
5669!! - tempo
5670!! - livello verticale
5671!! - intervallo temporale (timerange)
5672!! - variabile di dati
5673!! - rete
5674!! - volumi di attributi di dati (vol7d::voldatiattrr & c.), hanno 7 dimensioni:
5675!! - anagrafica
5676!! - tempo
5677!! - livello verticale
5678!! - intervallo temporale (timerange)
5679!! - variabile di dati
5680!! - rete
5681!! - variabile di attributi delle variabili di dati
5682!!
5683!! Tutte le variabili sono inoltre disponibil1 in 5 tipi diversi:
5684!! - reale (abbreviato r)
5685!! - doppia precisione (abbreviato d)
5686!! - intero (abbreviato i)
5687!! - byte (abbreviato b)
5688!! - carattere (abbreviato c)
5689!!
5690!! Per ognuna delle dimensioni possibili, incluse le variabili e gli
5691!! attributi con i loro diversi tipi,
5692!! è definito un cosiddetto "vettore di descrittori", con un
5693!! numero di elementi pari all'estensione della dimensione stessa,
5694!! che contiene le informazioni necessarie a descrivere
5695!! gli elementi di quella dimensione.
5696!! In realtà l'utente non dovrà generalmente occuparsi di costruire
5697!! un oggetto vol7d con le proprie mani ma utilizzerà nella maggior parte
5698!! dei casi i metodi di importazione preconfezionati che importano dati da
5699!! DB-All.e (vol7d_dballe_class) o dal DB Oracle del SIM (vol7d_oraclesim_class).
5700!!
5701!!
5702!! Il programma esempio_v7d.f90 contiene un esempio elementare di uso
5703!! della classe vol7d:
5704!! \include esempio_v7d.f90
5705!!
5706!! \ingroup vol7d
5707MODULE vol7d_class
5708USE kinds
5712USE log4fortran
5713USE err_handling
5714USE io_units
5721IMPLICIT NONE
5722
5723
5724INTEGER, PARAMETER :: vol7d_maxdim_a = 3, vol7d_maxdim_aa = 4, &
5725 vol7d_maxdim_d = 6, vol7d_maxdim_ad = 7
5726
5727INTEGER, PARAMETER :: vol7d_ana_a=1 !< indice della dimensione "anagrafica" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
5728INTEGER, PARAMETER :: vol7d_var_a=2 !< indice della dimensione "variabile" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
5729INTEGER, PARAMETER :: vol7d_network_a=3 !< indice della dimensione "rete" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
5730INTEGER, PARAMETER :: vol7d_attr_a=4 !< indice della dimensione "attributo" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
5731INTEGER, PARAMETER :: vol7d_ana_d=1 !< indice della dimensione "anagrafica" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5732INTEGER, PARAMETER :: vol7d_time_d=2 !< indice della dimensione "tempo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5733INTEGER, PARAMETER :: vol7d_level_d=3 !< indice della dimensione "livello verticale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5734INTEGER, PARAMETER :: vol7d_timerange_d=4 !< indice della dimensione "intervallo temporale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5735INTEGER, PARAMETER :: vol7d_var_d=5 !< indice della dimensione "variabile" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5736INTEGER, PARAMETER :: vol7d_network_d=6 !< indice della dimensione "rete" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5737INTEGER, PARAMETER :: vol7d_attr_d=7 !< indice della dimensione "attributo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5738INTEGER, PARAMETER :: vol7d_cdatalen=32
5739
5740TYPE vol7d_varmap
5741 INTEGER :: r, d, i, b, c
5742END TYPE vol7d_varmap
5743
5744!> Definisce un oggetto contenente i volumi anagrafica e dati e tutti
5745!! i descrittori delle loro dimensioni.
5746TYPE vol7d
5747!> vettore descrittore della dimensione anagrafica
5748 TYPE(vol7d_ana),POINTER :: ana(:)
5749!> vettore descrittore della dimensione tempo
5750 TYPE(datetime),POINTER :: time(:)
5751!> vettore descrittore della dimensione livello verticale
5752 TYPE(vol7d_level),POINTER :: level(:)
5753!> vettore descrittore della dimensione intervallo temporale (timerange)
5754 TYPE(vol7d_timerange),POINTER :: timerange(:)
5755!> vettore descrittore della dimensione rete
5756 TYPE(vol7d_network),POINTER :: network(:)
5757!> vettore descrittore della dimensione variabile di anagrafica
5758 TYPE(vol7d_varvect) :: anavar
5759!> vettore descrittore della dimensione attributo delle variabili di anagrafica
5760 TYPE(vol7d_varvect) :: anaattr
5761!> vettore descrittore della dimensione variabile di anagrafica che ha tali attributi
5762 TYPE(vol7d_varvect) :: anavarattr
5763!> vettore descrittore della dimensione variabile di dati
5764 TYPE(vol7d_varvect) :: dativar
5765!> vettore descrittore della dimensione attributo delle variabili di dati
5766 TYPE(vol7d_varvect) :: datiattr
5767!> vettore descrittore della dimensione variabile di dati che ha tali attributi
5768 TYPE(vol7d_varvect) :: dativarattr
5769
5770!> volume di anagrafica a valori reali
5771 REAL,POINTER :: volanar(:,:,:)
5772!> volume di anagrafica a valori a doppia precisione
5773 DOUBLE PRECISION,POINTER :: volanad(:,:,:)
5774!> volume di anagrafica a valori interi
5775 INTEGER,POINTER :: volanai(:,:,:)
5776!> volume di anagrafica a valori byte
5777 INTEGER(kind=int_b),POINTER :: volanab(:,:,:)
5778!> volume di anagrafica a valori carattere
5779 CHARACTER(len=vol7d_cdatalen),POINTER :: volanac(:,:,:)
5780
5781!> volume di attributi di anagrafica a valori reali
5782 REAL,POINTER :: volanaattrr(:,:,:,:)
5783!> volume di attributi di anagrafica a valori a doppia precisione
5784 DOUBLE PRECISION,POINTER :: volanaattrd(:,:,:,:)
5785!> volume di attributi di anagrafica a valori interi
5786 INTEGER,POINTER :: volanaattri(:,:,:,:)
5787!> volume di attributi di anagrafica a valori byte
5788 INTEGER(kind=int_b),POINTER :: volanaattrb(:,:,:,:)
5789!> volume di attributi di anagrafica a valori carattere
5790 CHARACTER(len=vol7d_cdatalen),POINTER :: volanaattrc(:,:,:,:)
5791
5792!> volume di dati a valori reali
5793 REAL,POINTER :: voldatir(:,:,:,:,:,:) ! sono i dati
5794!> volume di dati a valori a doppia precisione
5795 DOUBLE PRECISION,POINTER :: voldatid(:,:,:,:,:,:)
5796!> volume di dati a valori interi
5797 INTEGER,POINTER :: voldatii(:,:,:,:,:,:)
5798!> volume di dati a valori byte
5799 INTEGER(kind=int_b),POINTER :: voldatib(:,:,:,:,:,:)
5800!> volume di dati a valori carattere
5801 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatic(:,:,:,:,:,:)
5802
5803!> volume di attributi di dati a valori reali
5804 REAL,POINTER :: voldatiattrr(:,:,:,:,:,:,:)
5805!> volume di attributi di dati a valori a doppia precisione
5806 DOUBLE PRECISION,POINTER :: voldatiattrd(:,:,:,:,:,:,:)
5807!> volume di attributi di dati a valori interi
5808 INTEGER,POINTER :: voldatiattri(:,:,:,:,:,:,:)
5809!> volume di attributi di dati a valori byte
5810 INTEGER(kind=int_b),POINTER :: voldatiattrb(:,:,:,:,:,:,:)
5811!> volume di attributi di dati a valori carattere
5812 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatiattrc(:,:,:,:,:,:,:)
5813
5814!> time definition; 0=time is reference time, 1=time is validity time
5815 integer :: time_definition
5816
5817END TYPE vol7d
5818
5819!> Costruttore per la classe vol7d.
5820!! Deve essere richiamato
5821!! per tutti gli oggetti di questo tipo definiti in un programma.
5822INTERFACE init
5823 MODULE PROCEDURE vol7d_init
5824END INTERFACE
5825
5826!> Distruttore per la classe vol7d.
5827INTERFACE delete
5828 MODULE PROCEDURE vol7d_delete
5829END INTERFACE
5830
5831!> Scrittura su file.
5832INTERFACE export
5833 MODULE PROCEDURE vol7d_write_on_file
5834END INTERFACE
5835
5836!> Lettura da file.
5837INTERFACE import
5838 MODULE PROCEDURE vol7d_read_from_file
5839END INTERFACE
5840
5841!>Print object
5842INTERFACE display
5843 MODULE PROCEDURE vol7d_display, dat_display, dat_vect_display
5844END INTERFACE
5845
5846!>Represent data in a pretty string
5847INTERFACE to_char
5848 MODULE PROCEDURE to_char_dat
5849END INTERFACE
5850
5851!>doubleprecision data conversion
5852INTERFACE doubledat
5853 MODULE PROCEDURE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
5854END INTERFACE
5855
5856!>real data conversion
5857INTERFACE realdat
5858 MODULE PROCEDURE realdatd,realdatr,realdati,realdatb,realdatc
5859END INTERFACE
5860
5861!>integer data conversion
5862INTERFACE integerdat
5863 MODULE PROCEDURE integerdatd,integerdatr,integerdati,integerdatb,integerdatc
5864END INTERFACE
5865
5866!>copy object
5867INTERFACE copy
5868 MODULE PROCEDURE vol7d_copy
5869END INTERFACE
5870
5871!> Test for a missing volume
5872INTERFACE c_e
5873 MODULE PROCEDURE vol7d_c_e
5874END INTERFACE
5875
5876!> Check for problems
5877!! return 0 if all check passed
5878!! print diagnostics with log4f
5879INTERFACE check
5880 MODULE PROCEDURE vol7d_check
5881END INTERFACE
5882
5883!> Reduce some dimensions (level and timerage) for semplification (rounding).
5884!! You can use this for simplify and use variables in computation like alchimia
5885!! where fields have to be on the same coordinate
5886!! It return real or character data only: if input is charcter data only it return character otherwise il return
5887!! all the data converted to real.
5888!! examples:
5889!! means in time for short periods and istantaneous values
5890!! 2 meter and surface levels
5891!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
5892!! will be taken (order is by icreasing var index).
5893!! You can use predefined values for classic semplification
5894!! almost_equal_levels and almost_equal_timeranges
5895!! The level or timerange in output will be defined by the first element of level and timerange list
5896INTERFACE rounding
5897 MODULE PROCEDURE v7d_rounding
5898END INTERFACE
5899
5900!!$INTERFACE get_volana
5901!!$ MODULE PROCEDURE vol7d_get_volanar, vol7d_get_volanad, vol7d_get_volanai, &
5902!!$ vol7d_get_volanab, vol7d_get_volanac
5903!!$END INTERFACE
5904!!$
5905!!$INTERFACE get_voldati
5906!!$ MODULE PROCEDURE vol7d_get_voldatir, vol7d_get_voldatid, vol7d_get_voldatii, &
5907!!$ vol7d_get_voldatib, vol7d_get_voldatic
5908!!$END INTERFACE
5909!!$
5910!!$INTERFACE get_volanaattr
5911!!$ MODULE PROCEDURE vol7d_get_volanaattrr, vol7d_get_volanaattrd, &
5912!!$ vol7d_get_volanaattri, vol7d_get_volanaattrb, vol7d_get_volanaattrc
5913!!$END INTERFACE
5914!!$
5915!!$INTERFACE get_voldatiattr
5916!!$ MODULE PROCEDURE vol7d_get_voldatiattrr, vol7d_get_voldatiattrd, &
5917!!$ vol7d_get_voldatiattri, vol7d_get_voldatiattrb, vol7d_get_voldatiattrc
5918!!$END INTERFACE
5919
5920PRIVATE vol7d_get_volr, vol7d_get_vold, vol7d_get_voli, vol7d_get_volb, &
5921 vol7d_get_volc, &
5922 volptr1dr, volptr2dr, volptr3dr, volptr4dr, volptr5dr, volptr6dr, volptr7dr, &
5923 volptr1dd, volptr2dd, volptr3dd, volptr4dd, volptr5dd, volptr6dd, volptr7dd, &
5924 volptr1di, volptr2di, volptr3di, volptr4di, volptr5di, volptr6di, volptr7di, &
5925 volptr1db, volptr2db, volptr3db, volptr4db, volptr5db, volptr6db, volptr7db, &
5926 volptr1dc, volptr2dc, volptr3dc, volptr4dc, volptr5dc, volptr6dc, volptr7dc, &
5927 vol7d_nullifyr, vol7d_nullifyd, vol7d_nullifyi, vol7d_nullifyb, vol7d_nullifyc, &
5928 vol7d_init, vol7d_delete, vol7d_write_on_file, vol7d_read_from_file, &
5929 vol7d_check_alloc_ana, vol7d_force_alloc_ana, &
5930 vol7d_check_alloc_dati, vol7d_force_alloc_dati, vol7d_force_alloc, &
5931 vol7d_display, dat_display, dat_vect_display, &
5932 to_char_dat, vol7d_check
5933
5934PRIVATE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
5935
5936PRIVATE vol7d_c_e
5937
5938CONTAINS
5939
5940
5941!> Inizializza un oggetto di tipo vol7d.
5942!! Non riceve alcun parametro tranne l'oggetto stesso. Attenzione, è necessario
5943!! comunque chiamare sempre il costruttore per evitare di avere dei puntatori in
5944!! uno stato indefinito.
5945SUBROUTINE vol7d_init(this,time_definition)
5946TYPE(vol7d),intent(out) :: this !< oggetto da inizializzare
5947INTEGER,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)
5948
5949CALL init(this%anavar)
5950CALL init(this%anaattr)
5951CALL init(this%anavarattr)
5952CALL init(this%dativar)
5953CALL init(this%datiattr)
5954CALL init(this%dativarattr)
5955
5956NULLIFY(this%ana, this%time, this%level, this%timerange, this%network)
5957
5958NULLIFY(this%volanar, this%volanaattrr, this%voldatir, this%voldatiattrr)
5959NULLIFY(this%volanad, this%volanaattrd, this%voldatid, this%voldatiattrd)
5960NULLIFY(this%volanai, this%volanaattri, this%voldatii, this%voldatiattri)
5961NULLIFY(this%volanab, this%volanaattrb, this%voldatib, this%voldatiattrb)
5962NULLIFY(this%volanac, this%volanaattrc, this%voldatic, this%voldatiattrc)
5963
5964if(present(time_definition)) then
5965 this%time_definition=time_definition
5966else
5967 this%time_definition=1 !default to validity time
5968end if
5969
5970END SUBROUTINE vol7d_init
5971
5972
5973!> Distrugge l'oggetto in maniera pulita, liberando l'eventuale memoria
5974!! dinamicamente allocata. Permette di distruggere la sola parte di dati
5975!! mantenendo l'anagrafica.
5976ELEMENTAL SUBROUTINE vol7d_delete(this, dataonly)
5977TYPE(vol7d),intent(inout) :: this !< oggetto da distruggere
5978LOGICAL, INTENT(in), OPTIONAL :: dataonly !< dealloca solo i dati, tenendo l'anagrafica, (default \c .FALSE.)
5979
5980
5981IF (.NOT. optio_log(dataonly)) THEN
5982 IF (ASSOCIATED(this%volanar)) DEALLOCATE(this%volanar)
5983 IF (ASSOCIATED(this%volanad)) DEALLOCATE(this%volanad)
5984 IF (ASSOCIATED(this%volanai)) DEALLOCATE(this%volanai)
5985 IF (ASSOCIATED(this%volanab)) DEALLOCATE(this%volanab)
5986 IF (ASSOCIATED(this%volanac)) DEALLOCATE(this%volanac)
5987 IF (ASSOCIATED(this%volanaattrr)) DEALLOCATE(this%volanaattrr)
5988 IF (ASSOCIATED(this%volanaattrd)) DEALLOCATE(this%volanaattrd)
5989 IF (ASSOCIATED(this%volanaattri)) DEALLOCATE(this%volanaattri)
5990 IF (ASSOCIATED(this%volanaattrb)) DEALLOCATE(this%volanaattrb)
5991 IF (ASSOCIATED(this%volanaattrc)) DEALLOCATE(this%volanaattrc)
5992ENDIF
5993IF (ASSOCIATED(this%voldatir)) DEALLOCATE(this%voldatir)
5994IF (ASSOCIATED(this%voldatid)) DEALLOCATE(this%voldatid)
5995IF (ASSOCIATED(this%voldatii)) DEALLOCATE(this%voldatii)
5996IF (ASSOCIATED(this%voldatib)) DEALLOCATE(this%voldatib)
5997IF (ASSOCIATED(this%voldatic)) DEALLOCATE(this%voldatic)
5998IF (ASSOCIATED(this%voldatiattrr)) DEALLOCATE(this%voldatiattrr)
5999IF (ASSOCIATED(this%voldatiattrd)) DEALLOCATE(this%voldatiattrd)
6000IF (ASSOCIATED(this%voldatiattri)) DEALLOCATE(this%voldatiattri)
6001IF (ASSOCIATED(this%voldatiattrb)) DEALLOCATE(this%voldatiattrb)
6002IF (ASSOCIATED(this%voldatiattrc)) DEALLOCATE(this%voldatiattrc)
6003
6004IF (.NOT. optio_log(dataonly)) THEN
6005 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
6006 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
6007ENDIF
6008IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
6009IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
6010IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
6011
6012IF (.NOT. optio_log(dataonly)) THEN
6013 CALL delete(this%anavar)
6014 CALL delete(this%anaattr)
6015 CALL delete(this%anavarattr)
6016ENDIF
6017CALL delete(this%dativar)
6018CALL delete(this%datiattr)
6019CALL delete(this%dativarattr)
6020
6021END SUBROUTINE vol7d_delete
6022
6023
6024
6025integer function vol7d_check(this)
6026TYPE(vol7d),intent(in) :: this !< object to check
6027integer :: i,j,k,l,m,n
6028
6029vol7d_check=0
6030
6031if (associated(this%voldatii)) then
6032do i = 1,size(this%voldatii,1)
6033 do j = 1,size(this%voldatii,2)
6034 do k = 1,size(this%voldatii,3)
6035 do l = 1,size(this%voldatii,4)
6036 do m = 1,size(this%voldatii,5)
6037 do n = 1,size(this%voldatii,6)
6038 if (this%voldatii(i,j,k,l,m,n) /= this%voldatii(i,j,k,l,m,n) ) then
6039 CALL l4f_log(l4f_warn,"check: abnormal value at voldatii("&
6040 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
6041 vol7d_check=1
6042 end if
6043 end do
6044 end do
6045 end do
6046 end do
6047 end do
6048end do
6049end if
6050
6051
6052if (associated(this%voldatir)) then
6053do i = 1,size(this%voldatir,1)
6054 do j = 1,size(this%voldatir,2)
6055 do k = 1,size(this%voldatir,3)
6056 do l = 1,size(this%voldatir,4)
6057 do m = 1,size(this%voldatir,5)
6058 do n = 1,size(this%voldatir,6)
6059 if (this%voldatir(i,j,k,l,m,n) /= this%voldatir(i,j,k,l,m,n) ) then
6060 CALL l4f_log(l4f_warn,"check: abnormal value at voldatir("&
6061 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
6062 vol7d_check=2
6063 end if
6064 end do
6065 end do
6066 end do
6067 end do
6068 end do
6069end do
6070end if
6071
6072if (associated(this%voldatid)) then
6073do i = 1,size(this%voldatid,1)
6074 do j = 1,size(this%voldatid,2)
6075 do k = 1,size(this%voldatid,3)
6076 do l = 1,size(this%voldatid,4)
6077 do m = 1,size(this%voldatid,5)
6078 do n = 1,size(this%voldatid,6)
6079 if (this%voldatid(i,j,k,l,m,n) /= this%voldatid(i,j,k,l,m,n) ) then
6080 CALL l4f_log(l4f_warn,"check: abnormal value at voldatid("&
6081 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
6082 vol7d_check=3
6083 end if
6084 end do
6085 end do
6086 end do
6087 end do
6088 end do
6089end do
6090end if
6091
6092if (associated(this%voldatib)) then
6093do i = 1,size(this%voldatib,1)
6094 do j = 1,size(this%voldatib,2)
6095 do k = 1,size(this%voldatib,3)
6096 do l = 1,size(this%voldatib,4)
6097 do m = 1,size(this%voldatib,5)
6098 do n = 1,size(this%voldatib,6)
6099 if (this%voldatib(i,j,k,l,m,n) /= this%voldatib(i,j,k,l,m,n) ) then
6100 CALL l4f_log(l4f_warn,"check: abnormal value at voldatib("&
6101 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
6102 vol7d_check=4
6103 end if
6104 end do
6105 end do
6106 end do
6107 end do
6108 end do
6109end do
6110end if
6111
6112end function vol7d_check
6113
6114
6115
6116!TODO da completare ! aborta se i volumi sono allocati a dimensione 0
6117!> stampa a video una sintesi del contenuto
6118SUBROUTINE vol7d_display(this)
6119TYPE(vol7d),intent(in) :: this !< oggetto da visualizzare
6120integer :: i
6121
6122REAL :: rdat
6123DOUBLE PRECISION :: ddat
6124INTEGER :: idat
6125INTEGER(kind=int_b) :: bdat
6126CHARACTER(len=vol7d_cdatalen) :: cdat
6127
6128
6129print*,"<<<<<<<<<<<<<<<<<<< vol7d object >>>>>>>>>>>>>>>>>>>>"
6130if (this%time_definition == 0) then
6131 print*,"TIME DEFINITION: time is reference time"
6132else if (this%time_definition == 1) then
6133 print*,"TIME DEFINITION: time is validity time"
6134else if (this%time_definition == 2) then
6135 print*,"TIME DEFINITION: time is validity time, forecast range forced to 0"
6136else
6137 print*,"Time definition has a wrong walue:", this%time_definition
6138end if
6139
6140IF (ASSOCIATED(this%network))then
6141 print*,"---- network vector ----"
6142 print*,"elements=",size(this%network)
6143 do i=1, size(this%network)
6144 call display(this%network(i))
6145 end do
6146end IF
6147
6148IF (ASSOCIATED(this%ana))then
6149 print*,"---- ana vector ----"
6150 print*,"elements=",size(this%ana)
6151 do i=1, size(this%ana)
6152 call display(this%ana(i))
6153 end do
6154end IF
6155
6156IF (ASSOCIATED(this%time))then
6157 print*,"---- time vector ----"
6158 print*,"elements=",size(this%time)
6159 do i=1, size(this%time)
6160 call display(this%time(i))
6161 end do
6162end if
6163
6164IF (ASSOCIATED(this%level)) then
6165 print*,"---- level vector ----"
6166 print*,"elements=",size(this%level)
6167 do i =1,size(this%level)
6168 call display(this%level(i))
6169 end do
6170end if
6171
6172IF (ASSOCIATED(this%timerange))then
6173 print*,"---- timerange vector ----"
6174 print*,"elements=",size(this%timerange)
6175 do i =1,size(this%timerange)
6176 call display(this%timerange(i))
6177 end do
6178end if
6179
6180
6181print*,"---- ana vector ----"
6182print*,""
6183print*,"->>>>>>>>> anavar -"
6184call display(this%anavar)
6185print*,""
6186print*,"->>>>>>>>> anaattr -"
6187call display(this%anaattr)
6188print*,""
6189print*,"->>>>>>>>> anavarattr -"
6190call display(this%anavarattr)
6191
6192print*,"-- ana data section (first point) --"
6193
6194idat=imiss
6195rdat=rmiss
6196ddat=dmiss
6197bdat=ibmiss
6198cdat=cmiss
6199
6200!ntime = MIN(SIZE(this%time),nprint)
6201!ntimerange = MIN(SIZE(this%timerange),nprint)
6202!nlevel = MIN(SIZE(this%level),nprint)
6203!nnetwork = MIN(SIZE(this%network),nprint)
6204!nana = MIN(SIZE(this%ana),nprint)
6205
6206IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0) THEN
6207if (associated(this%volanai)) then
6208 do i=1,size(this%anavar%i)
6209 idat=this%volanai(1,i,1)
6210 if (associated(this%anavar%i)) call display(this%anavar%i(i),idat,rdat,ddat,bdat,cdat)
6211 end do
6212end if
6213idat=imiss
6214
6215if (associated(this%volanar)) then
6216 do i=1,size(this%anavar%r)
6217 rdat=this%volanar(1,i,1)
6218 if (associated(this%anavar%r)) call display(this%anavar%r(i),idat,rdat,ddat,bdat,cdat)
6219 end do
6220end if
6221rdat=rmiss
6222
6223if (associated(this%volanad)) then
6224 do i=1,size(this%anavar%d)
6225 ddat=this%volanad(1,i,1)
6226 if (associated(this%anavar%d)) call display(this%anavar%d(i),idat,rdat,ddat,bdat,cdat)
6227 end do
6228end if
6229ddat=dmiss
6230
6231if (associated(this%volanab)) then
6232 do i=1,size(this%anavar%b)
6233 bdat=this%volanab(1,i,1)
6234 if (associated(this%anavar%b)) call display(this%anavar%b(i),idat,rdat,ddat,bdat,cdat)
6235 end do
6236end if
6237bdat=ibmiss
6238
6239if (associated(this%volanac)) then
6240 do i=1,size(this%anavar%c)
6241 cdat=this%volanac(1,i,1)
6242 if (associated(this%anavar%c)) call display(this%anavar%c(i),idat,rdat,ddat,bdat,cdat)
6243 end do
6244end if
6245cdat=cmiss
6246ENDIF
6247
6248print*,"---- data vector ----"
6249print*,""
6250print*,"->>>>>>>>> dativar -"
6251call display(this%dativar)
6252print*,""
6253print*,"->>>>>>>>> datiattr -"
6254call display(this%datiattr)
6255print*,""
6256print*,"->>>>>>>>> dativarattr -"
6257call display(this%dativarattr)
6258
6259print*,"-- data data section (first point) --"
6260
6261idat=imiss
6262rdat=rmiss
6263ddat=dmiss
6264bdat=ibmiss
6265cdat=cmiss
6266
6267IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0 .AND. size(this%time) > 0 &
6268 .AND. size(this%level) > 0 .AND. size(this%timerange) > 0) THEN
6269if (associated(this%voldatii)) then
6270 do i=1,size(this%dativar%i)
6271 idat=this%voldatii(1,1,1,1,i,1)
6272 if (associated(this%dativar%i)) call display(this%dativar%i(i),idat,rdat,ddat,bdat,cdat)
6273 end do
6274end if
6275idat=imiss
6276
6277if (associated(this%voldatir)) then
6278 do i=1,size(this%dativar%r)
6279 rdat=this%voldatir(1,1,1,1,i,1)
6280 if (associated(this%dativar%r)) call display(this%dativar%r(i),idat,rdat,ddat,bdat,cdat)
6281 end do
6282end if
6283rdat=rmiss
6284
6285if (associated(this%voldatid)) then
6286 do i=1,size(this%dativar%d)
6287 ddat=this%voldatid(1,1,1,1,i,1)
6288 if (associated(this%dativar%d)) call display(this%dativar%d(i),idat,rdat,ddat,bdat,cdat)
6289 end do
6290end if
6291ddat=dmiss
6292
6293if (associated(this%voldatib)) then
6294 do i=1,size(this%dativar%b)
6295 bdat=this%voldatib(1,1,1,1,i,1)
6296 if (associated(this%dativar%b)) call display(this%dativar%b(i),idat,rdat,ddat,bdat,cdat)
6297 end do
6298end if
6299bdat=ibmiss
6300
6301if (associated(this%voldatic)) then
6302 do i=1,size(this%dativar%c)
6303 cdat=this%voldatic(1,1,1,1,i,1)
6304 if (associated(this%dativar%c)) call display(this%dativar%c(i),idat,rdat,ddat,bdat,cdat)
6305 end do
6306end if
6307cdat=cmiss
6308ENDIF
6309
6310print*,"<<<<<<<<<<<<<<<<<<< END vol7d object >>>>>>>>>>>>>>>>>>>>"
6311
6312END SUBROUTINE vol7d_display
6313
6314
6315!> stampa a video una sintesi del contenuto
6316SUBROUTINE dat_display(this,idat,rdat,ddat,bdat,cdat)
6317TYPE(vol7d_var),intent(in) :: this !< oggetto da visualizzare
6318!> real
6319REAL :: rdat
6320!> double precision
6321DOUBLE PRECISION :: ddat
6322!> integer
6323INTEGER :: idat
6324!> byte
6325INTEGER(kind=int_b) :: bdat
6326!> character
6327CHARACTER(len=*) :: cdat
6328
6329print *, to_char_dat(this,idat,rdat,ddat,bdat,cdat)
6330
6331end SUBROUTINE dat_display
6332
6333!> stampa a video una sintesi del contenuto
6334SUBROUTINE dat_vect_display(this,idat,rdat,ddat,bdat,cdat)
6335
6336TYPE(vol7d_var),intent(in) :: this(:) !< oggetto da visualizzare
6337!> real
6338REAL :: rdat(:)
6339!> double precision
6340DOUBLE PRECISION :: ddat(:)
6341!> integer
6342INTEGER :: idat(:)
6343!> byte
6344INTEGER(kind=int_b) :: bdat(:)
6345!> character
6346CHARACTER(len=*):: cdat(:)
6347
6348integer :: i
6349
6350do i =1,size(this)
6351 call display(this(i),idat(i),rdat(i),ddat(i),bdat(i),cdat(i))
6352end do
6353
6354end SUBROUTINE dat_vect_display
6355
6356
6357FUNCTION to_char_dat(this,idat,rdat,ddat,bdat,cdat)
6358#ifdef HAVE_DBALLE
6359USE dballef
6360#endif
6361TYPE(vol7d_var),INTENT(in) :: this
6362!> real
6363REAL :: rdat
6364!> double precision
6365DOUBLE PRECISION :: ddat
6366!> integer
6367INTEGER :: idat
6368!> byte
6369INTEGER(kind=int_b) :: bdat
6370!> character
6371CHARACTER(len=*) :: cdat
6372CHARACTER(len=80) :: to_char_dat
6373
6374CHARACTER(len=LEN(to_char_dat)) :: to_char_tmp
6375
6376
6377#ifdef HAVE_DBALLE
6378INTEGER :: handle, ier
6379
6380handle = 0
6381to_char_dat="VALUE: "
6382
6383if (c_e(idat)) to_char_dat=trim(to_char_dat)//" ;int> "//trim(to_char(idat))
6384if (c_e(rdat)) to_char_dat=trim(to_char_dat)//" ;real> "//trim(to_char(rdat))
6385if (c_e(ddat)) to_char_dat=trim(to_char_dat)//" ;double> "//trim(to_char(ddat))
6386if (c_e(bdat)) to_char_dat=trim(to_char_dat)//" ;byte> "//trim(to_char(bdat))
6387
6388if ( c_e(cdat))then
6389 ier = idba_messaggi(handle,"/dev/null", "w", "BUFR")
6390 ier = idba_spiegab(handle,this%btable,cdat,to_char_tmp)
6391 ier = idba_fatto(handle)
6392 to_char_dat=trim(to_char_dat)//" ;char> "//trim(to_char_tmp)
6393endif
6394
6395#else
6396
6397to_char_dat="VALUE: "
6398if (c_e(idat)) to_char_dat=trim(to_char_dat)//" ;int> "//trim(to_char(idat))
6399if (c_e(rdat)) to_char_dat=trim(to_char_dat)//" ;real> "//trim(to_char(rdat))
6400if (c_e(ddat)) to_char_dat=trim(to_char_dat)//" ;double> "//trim(to_char(ddat))
6401if (c_e(bdat)) to_char_dat=trim(to_char_dat)//" ;byte> "//trim(to_char(bdat))
6402if (c_e(cdat)) to_char_dat=trim(to_char_dat)//" ;char> "//trim(cdat)
6403
6404#endif
6405
6406END FUNCTION to_char_dat
6407
6408
6409!> Tests whether anything has ever been assigned to a vol7d object
6410!! (.TRUE.) or it is as clean as after an init (.FALSE.).
6411FUNCTION vol7d_c_e(this) RESULT(c_e)
6412TYPE(vol7d), INTENT(in) :: this
6413
6414LOGICAL :: c_e
6415
6416c_e = ASSOCIATED(this%ana) .OR. ASSOCIATED(this%time) .OR. &
6417 ASSOCIATED(this%level) .OR. ASSOCIATED(this%timerange) .OR. &
6418 ASSOCIATED(this%network) .OR. &
6419 ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
6420 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
6421 ASSOCIATED(this%anavar%c) .OR. &
6422 ASSOCIATED(this%anaattr%r) .OR. ASSOCIATED(this%anaattr%d) .OR. &
6423 ASSOCIATED(this%anaattr%i) .OR. ASSOCIATED(this%anaattr%b) .OR. &
6424 ASSOCIATED(this%anaattr%c) .OR. &
6425 ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
6426 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
6427 ASSOCIATED(this%dativar%c) .OR. &
6428 ASSOCIATED(this%datiattr%r) .OR. ASSOCIATED(this%datiattr%d) .OR. &
6429 ASSOCIATED(this%datiattr%i) .OR. ASSOCIATED(this%datiattr%b) .OR. &
6430 ASSOCIATED(this%datiattr%c)
6431
6432END FUNCTION vol7d_c_e
6433
6434
6435!> Metodo per allocare i descrittori delle 7 dimensioni.
6436!! Riceve un grande numero di parametri opzionali che
6437!! indicano quali descrittori allocare e con quale estensione;
6438!! i descrittori non specificati non vengono toccati.
6439!! Può essere quindi chiamato più volte allocando via via
6440!! descrittori relativi a dimensioni diverse.
6441!! Se un descrittore richiesto è già allocato, viene deallocato
6442!! (perdendone l'eventuale contenuto) e riallocato con l'estensione
6443!! richiesta.
6444!! Per i descrittori relativi a dimensioni che non siano variabili o attributi,
6445!! è possibile specificare l'estensione di una dimensione a 0,
6446!! in tal caso il descrittore viene comunque allocato con lunghezza nulla,
6447!! che è diverso da non allocarlo. Per i descrittori di variabili e attributi
6448!! passare un'estensione 0 equivale a non fornire il parametro.
6449!! Avere uno o più descrittori dimensionati con estensione nulla fa sì
6450!! che anche il volume dati successivamente allocato abbia estensione nulla;
6451!! sebbene ciò appaia inutile, un volume del genere può in realtà servire,
6452!! in associazione ai metodi ::vol7d_merge o ::vol7d_append per estendere
6453!! un volume esistente aggiungendo elementi in alcune dimensioni (quelle
6454!! a estensione non nulla, ovviamente) e mantenendo invariato tutto il resto.
6455!! Per quanto riguarda i descrittori delle dimensioni relative alle
6456!! variabili, la relativa estensione è specificata con la nomenclatura
6457!! \a n&lt;x&gt;&lt;y&gt;&lt;z&gt; dove &lt;x&gt; può valere:
6458!! - \a ana per variabili relative a voumi di anagrafica
6459!! - \a dati per variabili relative a voumi di dati
6460!!
6461!! &lt;y&gt; può valere:
6462!! - \a var per variabili
6463!! - \a attr per attributi
6464!! - \a varattr variabili aventi attributi nei volumi di attributi
6465!!
6466!! &lt;z&gt; può valere:
6467!! - \a r per variabili o attributi a valori reali
6468!! - \a d per variabili o attributi a valori a doppia precisione
6469!! - \a i per variabili o attributi a valori interi
6470!! - \a b per variabili o attributi a valori byte
6471!! - \a c per variabili o attributi a valori carattere
6472!!
6473SUBROUTINE vol7d_alloc(this, nana, ntime, nlevel, ntimerange, nnetwork, &
6474 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
6475 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
6476 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
6477 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
6478 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
6479 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc, &
6480 ini)
6481TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i descrittori
6482INTEGER,INTENT(in),OPTIONAL :: nana !< estensione della dimensione anagrafica
6483INTEGER,INTENT(in),OPTIONAL :: ntime !< estensione della dimensione tempo
6484INTEGER,INTENT(in),OPTIONAL :: nlevel !< estensione della dimensione livello varticale
6485INTEGER,INTENT(in),OPTIONAL :: ntimerange !< estensione della dimensione intervallo temporale (timerange)
6486INTEGER,INTENT(in),OPTIONAL :: nnetwork !< estensione della dimensione rete
6487!> estensione delle possibili dimensioni variabile
6488INTEGER,INTENT(in),OPTIONAL :: &
6489 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
6490 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
6491 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
6492 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
6493 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
6494 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc
6495LOGICAL,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
6496
6497INTEGER :: i
6498LOGICAL :: linit
6499
6500IF (PRESENT(ini)) THEN
6501 linit = ini
6502ELSE
6503 linit = .false.
6504ENDIF
6505
6506! Dimensioni principali
6507IF (PRESENT(nana)) THEN
6508 IF (nana >= 0) THEN
6509 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
6510 ALLOCATE(this%ana(nana))
6511 IF (linit) THEN
6512 DO i = 1, nana
6513 CALL init(this%ana(i))
6514 ENDDO
6515 ENDIF
6516 ENDIF
6517ENDIF
6518IF (PRESENT(ntime)) THEN
6519 IF (ntime >= 0) THEN
6520 IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
6521 ALLOCATE(this%time(ntime))
6522 IF (linit) THEN
6523 DO i = 1, ntime
6524 CALL init(this%time(i))
6525 ENDDO
6526 ENDIF
6527 ENDIF
6528ENDIF
6529IF (PRESENT(nlevel)) THEN
6530 IF (nlevel >= 0) THEN
6531 IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
6532 ALLOCATE(this%level(nlevel))
6533 IF (linit) THEN
6534 DO i = 1, nlevel
6535 CALL init(this%level(i))
6536 ENDDO
6537 ENDIF
6538 ENDIF
6539ENDIF
6540IF (PRESENT(ntimerange)) THEN
6541 IF (ntimerange >= 0) THEN
6542 IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
6543 ALLOCATE(this%timerange(ntimerange))
6544 IF (linit) THEN
6545 DO i = 1, ntimerange
6546 CALL init(this%timerange(i))
6547 ENDDO
6548 ENDIF
6549 ENDIF
6550ENDIF
6551IF (PRESENT(nnetwork)) THEN
6552 IF (nnetwork >= 0) THEN
6553 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
6554 ALLOCATE(this%network(nnetwork))
6555 IF (linit) THEN
6556 DO i = 1, nnetwork
6557 CALL init(this%network(i))
6558 ENDDO
6559 ENDIF
6560 ENDIF
6561ENDIF
6562! Dimensioni dei tipi delle variabili
6563CALL vol7d_varvect_alloc(this%anavar, nanavarr, nanavard, &
6564 nanavari, nanavarb, nanavarc, ini)
6565CALL vol7d_varvect_alloc(this%anaattr, nanaattrr, nanaattrd, &
6566 nanaattri, nanaattrb, nanaattrc, ini)
6567CALL vol7d_varvect_alloc(this%anavarattr, nanavarattrr, nanavarattrd, &
6568 nanavarattri, nanavarattrb, nanavarattrc, ini)
6569CALL vol7d_varvect_alloc(this%dativar, ndativarr, ndativard, &
6570 ndativari, ndativarb, ndativarc, ini)
6571CALL vol7d_varvect_alloc(this%datiattr, ndatiattrr, ndatiattrd, &
6572 ndatiattri, ndatiattrb, ndatiattrc, ini)
6573CALL vol7d_varvect_alloc(this%dativarattr, ndativarattrr, ndativarattrd, &
6574 ndativarattri, ndativarattrb, ndativarattrc, ini)
6575
6576END SUBROUTINE vol7d_alloc
6577
6578
6579FUNCTION vol7d_check_alloc_ana(this)
6580TYPE(vol7d),INTENT(in) :: this
6581LOGICAL :: vol7d_check_alloc_ana
6582
6583vol7d_check_alloc_ana = ASSOCIATED(this%ana) .AND. ASSOCIATED(this%network)
6584
6585END FUNCTION vol7d_check_alloc_ana
6586
6587SUBROUTINE vol7d_force_alloc_ana(this, ini)
6588TYPE(vol7d),INTENT(inout) :: this
6589LOGICAL,INTENT(in),OPTIONAL :: ini
6590
6591! Alloco i descrittori minimi per avere un volume di anagrafica
6592IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=1, ini=ini)
6593IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=1, ini=ini)
6594
6595END SUBROUTINE vol7d_force_alloc_ana
6596
6597
6598FUNCTION vol7d_check_alloc_dati(this)
6599TYPE(vol7d),INTENT(in) :: this
6600LOGICAL :: vol7d_check_alloc_dati
6601
6602vol7d_check_alloc_dati = vol7d_check_alloc_ana(this) .AND. &
6603 ASSOCIATED(this%time) .AND. ASSOCIATED(this%level) .AND. &
6604 ASSOCIATED(this%timerange)
6605
6606END FUNCTION vol7d_check_alloc_dati
6607
6608SUBROUTINE vol7d_force_alloc_dati(this, ini)
6609TYPE(vol7d),INTENT(inout) :: this
6610LOGICAL,INTENT(in),OPTIONAL :: ini
6611
6612! Alloco i descrittori minimi per avere un volume di dati
6613CALL vol7d_force_alloc_ana(this, ini)
6614IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=1, ini=ini)
6615IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=1, ini=ini)
6616IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=1, ini=ini)
6617
6618END SUBROUTINE vol7d_force_alloc_dati
6619
6620
6621SUBROUTINE vol7d_force_alloc(this)
6622TYPE(vol7d),INTENT(inout) :: this
6623
6624! If anything really not allocated yet, allocate with size 0
6625IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=0)
6626IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=0)
6627IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=0)
6628IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=0)
6629IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=0)
6630
6631END SUBROUTINE vol7d_force_alloc
6632
6633
6634FUNCTION vol7d_check_vol(this)
6635TYPE(vol7d),INTENT(in) :: this !< oggetto da controllare
6636LOGICAL :: vol7d_check_vol
6637
6638vol7d_check_vol = c_e(this)
6639
6640! Anagrafica
6641IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
6642 vol7d_check_vol = .false.
6643ENDIF
6644
6645IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
6646 vol7d_check_vol = .false.
6647ENDIF
6648
6649IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
6650 vol7d_check_vol = .false.
6651ENDIF
6652
6653IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
6654 vol7d_check_vol = .false.
6655ENDIF
6656
6657IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
6658 vol7d_check_vol = .false.
6659ENDIF
6660IF (ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
6661 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
6662 ASSOCIATED(this%anavar%c)) THEN
6663 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_ana(this)
6664ENDIF
6665
6666! Attributi dell'anagrafica
6667IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
6668 .NOT.ASSOCIATED(this%volanaattrr)) THEN
6669 vol7d_check_vol = .false.
6670ENDIF
6671
6672IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
6673 .NOT.ASSOCIATED(this%volanaattrd)) THEN
6674 vol7d_check_vol = .false.
6675ENDIF
6676
6677IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
6678 .NOT.ASSOCIATED(this%volanaattri)) THEN
6679 vol7d_check_vol = .false.
6680ENDIF
6681
6682IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
6683 .NOT.ASSOCIATED(this%volanaattrb)) THEN
6684 vol7d_check_vol = .false.
6685ENDIF
6686
6687IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
6688 .NOT.ASSOCIATED(this%volanaattrc)) THEN
6689 vol7d_check_vol = .false.
6690ENDIF
6691
6692! Dati
6693IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
6694 vol7d_check_vol = .false.
6695ENDIF
6696
6697IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
6698 vol7d_check_vol = .false.
6699ENDIF
6700
6701IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
6702 vol7d_check_vol = .false.
6703ENDIF
6704
6705IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
6706 vol7d_check_vol = .false.
6707ENDIF
6708
6709IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
6710 vol7d_check_vol = .false.
6711ENDIF
6712
6713! Attributi dei dati
6714IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
6715 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
6716 vol7d_check_vol = .false.
6717ENDIF
6718
6719IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
6720 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
6721 vol7d_check_vol = .false.
6722ENDIF
6723
6724IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
6725 .NOT.ASSOCIATED(this%voldatiattri)) THEN
6726 vol7d_check_vol = .false.
6727ENDIF
6728
6729IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
6730 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
6731 vol7d_check_vol = .false.
6732ENDIF
6733
6734IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
6735 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
6736 vol7d_check_vol = .false.
6737ENDIF
6738IF (ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
6739 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
6740 ASSOCIATED(this%dativar%c)) THEN
6741 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_dati(this)
6742ENDIF
6743
6744END FUNCTION vol7d_check_vol
6745
6746
6747!> Metodo per allocare i volumi richiesti di variabili e attributi per
6748!! anagrafica e dati.
6749!! Se alcuni dei descrittori relativi alle dimensioni anagrafica,
6750!! livello verticale, tempo, intervallo temporale (timerange), rete non sono
6751!! stati richiesti preventivamente con la ::vol7d_alloc, essi vengono allocati
6752!! automaticamente da questo metodo
6753!! con estensione di default pari a 1 (non 0!), questo significa, ad esempio,
6754!! che se prevedo di avere soli dati superficiali, cioè ad un solo livello
6755!! verticale, o una sola rete di stazioni, non devo preoccuparmi di
6756!! specificare questa informazione.
6757!! Tra i 20 possibili volumi allocabili
6758!! ((variabili,attributi)*(anagrafica,dati)*(r,d,i,b,c)=20)
6759!! saranno allocati solo quelli per cui è stato precedentemente richiesto il
6760!! corrispondente descrittore variabili/attributi con la ::vol7d_alloc.
6761SUBROUTINE vol7d_alloc_vol(this, ini, inivol)
6762TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i volumi
6763LOGICAL,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
6764LOGICAL,INTENT(in),OPTIONAL :: inivol !< se fornito e vale \c .TRUE., i volumi allocati saranno inizializzati a valore mancante
6765
6766LOGICAL :: linivol
6767
6768IF (PRESENT(inivol)) THEN
6769 linivol = inivol
6770ELSE
6771 linivol = .true.
6772ENDIF
6773
6774! Anagrafica
6775IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
6776 CALL vol7d_force_alloc_ana(this, ini)
6777 ALLOCATE(this%volanar(SIZE(this%ana), SIZE(this%anavar%r), SIZE(this%network)))
6778 IF (linivol) this%volanar(:,:,:) = rmiss
6779ENDIF
6780
6781IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
6782 CALL vol7d_force_alloc_ana(this, ini)
6783 ALLOCATE(this%volanad(SIZE(this%ana), SIZE(this%anavar%d), SIZE(this%network)))
6784 IF (linivol) this%volanad(:,:,:) = rdmiss
6785ENDIF
6786
6787IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
6788 CALL vol7d_force_alloc_ana(this, ini)
6789 ALLOCATE(this%volanai(SIZE(this%ana), SIZE(this%anavar%i), SIZE(this%network)))
6790 IF (linivol) this%volanai(:,:,:) = imiss
6791ENDIF
6792
6793IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
6794 CALL vol7d_force_alloc_ana(this, ini)
6795 ALLOCATE(this%volanab(SIZE(this%ana), SIZE(this%anavar%b), SIZE(this%network)))
6796 IF (linivol) this%volanab(:,:,:) = ibmiss
6797ENDIF
6798
6799IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
6800 CALL vol7d_force_alloc_ana(this, ini)
6801 ALLOCATE(this%volanac(SIZE(this%ana), SIZE(this%anavar%c), SIZE(this%network)))
6802 IF (linivol) this%volanac(:,:,:) = cmiss
6803ENDIF
6804
6805! Attributi dell'anagrafica
6806IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
6807 .NOT.ASSOCIATED(this%volanaattrr)) THEN
6808 CALL vol7d_force_alloc_ana(this, ini)
6809 ALLOCATE(this%volanaattrr(SIZE(this%ana), SIZE(this%anavarattr%r), &
6810 SIZE(this%network), SIZE(this%anaattr%r)))
6811 IF (linivol) this%volanaattrr(:,:,:,:) = rmiss
6812ENDIF
6813
6814IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
6815 .NOT.ASSOCIATED(this%volanaattrd)) THEN
6816 CALL vol7d_force_alloc_ana(this, ini)
6817 ALLOCATE(this%volanaattrd(SIZE(this%ana), SIZE(this%anavarattr%d), &
6818 SIZE(this%network), SIZE(this%anaattr%d)))
6819 IF (linivol) this%volanaattrd(:,:,:,:) = rdmiss
6820ENDIF
6821
6822IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
6823 .NOT.ASSOCIATED(this%volanaattri)) THEN
6824 CALL vol7d_force_alloc_ana(this, ini)
6825 ALLOCATE(this%volanaattri(SIZE(this%ana), SIZE(this%anavarattr%i), &
6826 SIZE(this%network), SIZE(this%anaattr%i)))
6827 IF (linivol) this%volanaattri(:,:,:,:) = imiss
6828ENDIF
6829
6830IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
6831 .NOT.ASSOCIATED(this%volanaattrb)) THEN
6832 CALL vol7d_force_alloc_ana(this, ini)
6833 ALLOCATE(this%volanaattrb(SIZE(this%ana), SIZE(this%anavarattr%b), &
6834 SIZE(this%network), SIZE(this%anaattr%b)))
6835 IF (linivol) this%volanaattrb(:,:,:,:) = ibmiss
6836ENDIF
6837
6838IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
6839 .NOT.ASSOCIATED(this%volanaattrc)) THEN
6840 CALL vol7d_force_alloc_ana(this, ini)
6841 ALLOCATE(this%volanaattrc(SIZE(this%ana), SIZE(this%anavarattr%c), &
6842 SIZE(this%network), SIZE(this%anaattr%c)))
6843 IF (linivol) this%volanaattrc(:,:,:,:) = cmiss
6844ENDIF
6845
6846! Dati
6847IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
6848 CALL vol7d_force_alloc_dati(this, ini)
6849 ALLOCATE(this%voldatir(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6850 SIZE(this%timerange), SIZE(this%dativar%r), SIZE(this%network)))
6851 IF (linivol) this%voldatir(:,:,:,:,:,:) = rmiss
6852ENDIF
6853
6854IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
6855 CALL vol7d_force_alloc_dati(this, ini)
6856 ALLOCATE(this%voldatid(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6857 SIZE(this%timerange), SIZE(this%dativar%d), SIZE(this%network)))
6858 IF (linivol) this%voldatid(:,:,:,:,:,:) = rdmiss
6859ENDIF
6860
6861IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
6862 CALL vol7d_force_alloc_dati(this, ini)
6863 ALLOCATE(this%voldatii(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6864 SIZE(this%timerange), SIZE(this%dativar%i), SIZE(this%network)))
6865 IF (linivol) this%voldatii(:,:,:,:,:,:) = imiss
6866ENDIF
6867
6868IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
6869 CALL vol7d_force_alloc_dati(this, ini)
6870 ALLOCATE(this%voldatib(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6871 SIZE(this%timerange), SIZE(this%dativar%b), SIZE(this%network)))
6872 IF (linivol) this%voldatib(:,:,:,:,:,:) = ibmiss
6873ENDIF
6874
6875IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
6876 CALL vol7d_force_alloc_dati(this, ini)
6877 ALLOCATE(this%voldatic(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6878 SIZE(this%timerange), SIZE(this%dativar%c), SIZE(this%network)))
6879 IF (linivol) this%voldatic(:,:,:,:,:,:) = cmiss
6880ENDIF
6881
6882! Attributi dei dati
6883IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
6884 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
6885 CALL vol7d_force_alloc_dati(this, ini)
6886 ALLOCATE(this%voldatiattrr(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6887 SIZE(this%timerange), SIZE(this%dativarattr%r), SIZE(this%network), &
6888 SIZE(this%datiattr%r)))
6889 IF (linivol) this%voldatiattrr(:,:,:,:,:,:,:) = rmiss
6890ENDIF
6891
6892IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
6893 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
6894 CALL vol7d_force_alloc_dati(this, ini)
6895 ALLOCATE(this%voldatiattrd(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6896 SIZE(this%timerange), SIZE(this%dativarattr%d), SIZE(this%network), &
6897 SIZE(this%datiattr%d)))
6898 IF (linivol) this%voldatiattrd(:,:,:,:,:,:,:) = rdmiss
6899ENDIF
6900
6901IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
6902 .NOT.ASSOCIATED(this%voldatiattri)) THEN
6903 CALL vol7d_force_alloc_dati(this, ini)
6904 ALLOCATE(this%voldatiattri(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6905 SIZE(this%timerange), SIZE(this%dativarattr%i), SIZE(this%network), &
6906 SIZE(this%datiattr%i)))
6907 IF (linivol) this%voldatiattri(:,:,:,:,:,:,:) = imiss
6908ENDIF
6909
6910IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
6911 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
6912 CALL vol7d_force_alloc_dati(this, ini)
6913 ALLOCATE(this%voldatiattrb(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6914 SIZE(this%timerange), SIZE(this%dativarattr%b), SIZE(this%network), &
6915 SIZE(this%datiattr%b)))
6916 IF (linivol) this%voldatiattrb(:,:,:,:,:,:,:) = ibmiss
6917ENDIF
6918
6919IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
6920 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
6921 CALL vol7d_force_alloc_dati(this, ini)
6922 ALLOCATE(this%voldatiattrc(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6923 SIZE(this%timerange), SIZE(this%dativarattr%c), SIZE(this%network), &
6924 SIZE(this%datiattr%c)))
6925 IF (linivol) this%voldatiattrc(:,:,:,:,:,:,:) = cmiss
6926ENDIF
6927
6928! Catch-all method
6929CALL vol7d_force_alloc(this)
6930
6931! Creo gli indici var-attr
6932
6933#ifdef DEBUG
6934CALL l4f_log(l4f_debug,"calling: vol7d_set_attr_ind")
6935#endif
6936
6937CALL vol7d_set_attr_ind(this)
6938
6939
6940
6941END SUBROUTINE vol7d_alloc_vol
6942
6943
6944!> Metodo per creare gli indici che associano le variabili aventi attributo
6945!! alle variabili nei relativi descrittori.
6946!! Ha senso chiamare questo metodo solo dopo che i descrittori delle variabili
6947!! e degli attributi desiderati sono stati allocati ed è stato assegnato un
6948!! valore ai relativi membri btable (vedi vol7d_var_class::vol7d_var), se
6949!! i descrittori non sono stati allocati o assegnati, il metodo non fa niente.
6950SUBROUTINE vol7d_set_attr_ind(this)
6951TYPE(vol7d),INTENT(inout) :: this !< oggetto in cui creare gli indici
6952
6953INTEGER :: i
6954
6955! real
6956IF (ASSOCIATED(this%dativar%r)) THEN
6957 IF (ASSOCIATED(this%dativarattr%r)) THEN
6958 DO i = 1, SIZE(this%dativar%r)
6959 this%dativar%r(i)%r = &
6960 firsttrue(this%dativar%r(i)%btable == this%dativarattr%r(:)%btable)
6961 ENDDO
6962 ENDIF
6963
6964 IF (ASSOCIATED(this%dativarattr%d)) THEN
6965 DO i = 1, SIZE(this%dativar%r)
6966 this%dativar%r(i)%d = &
6967 firsttrue(this%dativar%r(i)%btable == this%dativarattr%d(:)%btable)
6968 ENDDO
6969 ENDIF
6970
6971 IF (ASSOCIATED(this%dativarattr%i)) THEN
6972 DO i = 1, SIZE(this%dativar%r)
6973 this%dativar%r(i)%i = &
6974 firsttrue(this%dativar%r(i)%btable == this%dativarattr%i(:)%btable)
6975 ENDDO
6976 ENDIF
6977
6978 IF (ASSOCIATED(this%dativarattr%b)) THEN
6979 DO i = 1, SIZE(this%dativar%r)
6980 this%dativar%r(i)%b = &
6981 firsttrue(this%dativar%r(i)%btable == this%dativarattr%b(:)%btable)
6982 ENDDO
6983 ENDIF
6984
6985 IF (ASSOCIATED(this%dativarattr%c)) THEN
6986 DO i = 1, SIZE(this%dativar%r)
6987 this%dativar%r(i)%c = &
6988 firsttrue(this%dativar%r(i)%btable == this%dativarattr%c(:)%btable)
6989 ENDDO
6990 ENDIF
6991ENDIF
6992! double
6993IF (ASSOCIATED(this%dativar%d)) THEN
6994 IF (ASSOCIATED(this%dativarattr%r)) THEN
6995 DO i = 1, SIZE(this%dativar%d)
6996 this%dativar%d(i)%r = &
6997 firsttrue(this%dativar%d(i)%btable == this%dativarattr%r(:)%btable)
6998 ENDDO
6999 ENDIF
7000
7001 IF (ASSOCIATED(this%dativarattr%d)) THEN
7002 DO i = 1, SIZE(this%dativar%d)
7003 this%dativar%d(i)%d = &
7004 firsttrue(this%dativar%d(i)%btable == this%dativarattr%d(:)%btable)
7005 ENDDO
7006 ENDIF
7007
7008 IF (ASSOCIATED(this%dativarattr%i)) THEN
7009 DO i = 1, SIZE(this%dativar%d)
7010 this%dativar%d(i)%i = &
7011 firsttrue(this%dativar%d(i)%btable == this%dativarattr%i(:)%btable)
7012 ENDDO
7013 ENDIF
7014
7015 IF (ASSOCIATED(this%dativarattr%b)) THEN
7016 DO i = 1, SIZE(this%dativar%d)
7017 this%dativar%d(i)%b = &
7018 firsttrue(this%dativar%d(i)%btable == this%dativarattr%b(:)%btable)
7019 ENDDO
7020 ENDIF
7021
7022 IF (ASSOCIATED(this%dativarattr%c)) THEN
7023 DO i = 1, SIZE(this%dativar%d)
7024 this%dativar%d(i)%c = &
7025 firsttrue(this%dativar%d(i)%btable == this%dativarattr%c(:)%btable)
7026 ENDDO
7027 ENDIF
7028ENDIF
7029! integer
7030IF (ASSOCIATED(this%dativar%i)) THEN
7031 IF (ASSOCIATED(this%dativarattr%r)) THEN
7032 DO i = 1, SIZE(this%dativar%i)
7033 this%dativar%i(i)%r = &
7034 firsttrue(this%dativar%i(i)%btable == this%dativarattr%r(:)%btable)
7035 ENDDO
7036 ENDIF
7037
7038 IF (ASSOCIATED(this%dativarattr%d)) THEN
7039 DO i = 1, SIZE(this%dativar%i)
7040 this%dativar%i(i)%d = &
7041 firsttrue(this%dativar%i(i)%btable == this%dativarattr%d(:)%btable)
7042 ENDDO
7043 ENDIF
7044
7045 IF (ASSOCIATED(this%dativarattr%i)) THEN
7046 DO i = 1, SIZE(this%dativar%i)
7047 this%dativar%i(i)%i = &
7048 firsttrue(this%dativar%i(i)%btable == this%dativarattr%i(:)%btable)
7049 ENDDO
7050 ENDIF
7051
7052 IF (ASSOCIATED(this%dativarattr%b)) THEN
7053 DO i = 1, SIZE(this%dativar%i)
7054 this%dativar%i(i)%b = &
7055 firsttrue(this%dativar%i(i)%btable == this%dativarattr%b(:)%btable)
7056 ENDDO
7057 ENDIF
7058
7059 IF (ASSOCIATED(this%dativarattr%c)) THEN
7060 DO i = 1, SIZE(this%dativar%i)
7061 this%dativar%i(i)%c = &
7062 firsttrue(this%dativar%i(i)%btable == this%dativarattr%c(:)%btable)
7063 ENDDO
7064 ENDIF
7065ENDIF
7066! byte
7067IF (ASSOCIATED(this%dativar%b)) THEN
7068 IF (ASSOCIATED(this%dativarattr%r)) THEN
7069 DO i = 1, SIZE(this%dativar%b)
7070 this%dativar%b(i)%r = &
7071 firsttrue(this%dativar%b(i)%btable == this%dativarattr%r(:)%btable)
7072 ENDDO
7073 ENDIF
7074
7075 IF (ASSOCIATED(this%dativarattr%d)) THEN
7076 DO i = 1, SIZE(this%dativar%b)
7077 this%dativar%b(i)%d = &
7078 firsttrue(this%dativar%b(i)%btable == this%dativarattr%d(:)%btable)
7079 ENDDO
7080 ENDIF
7081
7082 IF (ASSOCIATED(this%dativarattr%i)) THEN
7083 DO i = 1, SIZE(this%dativar%b)
7084 this%dativar%b(i)%i = &
7085 firsttrue(this%dativar%b(i)%btable == this%dativarattr%i(:)%btable)
7086 ENDDO
7087 ENDIF
7088
7089 IF (ASSOCIATED(this%dativarattr%b)) THEN
7090 DO i = 1, SIZE(this%dativar%b)
7091 this%dativar%b(i)%b = &
7092 firsttrue(this%dativar%b(i)%btable == this%dativarattr%b(:)%btable)
7093 ENDDO
7094 ENDIF
7095
7096 IF (ASSOCIATED(this%dativarattr%c)) THEN
7097 DO i = 1, SIZE(this%dativar%b)
7098 this%dativar%b(i)%c = &
7099 firsttrue(this%dativar%b(i)%btable == this%dativarattr%c(:)%btable)
7100 ENDDO
7101 ENDIF
7102ENDIF
7103! character
7104IF (ASSOCIATED(this%dativar%c)) THEN
7105 IF (ASSOCIATED(this%dativarattr%r)) THEN
7106 DO i = 1, SIZE(this%dativar%c)
7107 this%dativar%c(i)%r = &
7108 firsttrue(this%dativar%c(i)%btable == this%dativarattr%r(:)%btable)
7109 ENDDO
7110 ENDIF
7111
7112 IF (ASSOCIATED(this%dativarattr%d)) THEN
7113 DO i = 1, SIZE(this%dativar%c)
7114 this%dativar%c(i)%d = &
7115 firsttrue(this%dativar%c(i)%btable == this%dativarattr%d(:)%btable)
7116 ENDDO
7117 ENDIF
7118
7119 IF (ASSOCIATED(this%dativarattr%i)) THEN
7120 DO i = 1, SIZE(this%dativar%c)
7121 this%dativar%c(i)%i = &
7122 firsttrue(this%dativar%c(i)%btable == this%dativarattr%i(:)%btable)
7123 ENDDO
7124 ENDIF
7125
7126 IF (ASSOCIATED(this%dativarattr%b)) THEN
7127 DO i = 1, SIZE(this%dativar%c)
7128 this%dativar%c(i)%b = &
7129 firsttrue(this%dativar%c(i)%btable == this%dativarattr%b(:)%btable)
7130 ENDDO
7131 ENDIF
7132
7133 IF (ASSOCIATED(this%dativarattr%c)) THEN
7134 DO i = 1, SIZE(this%dativar%c)
7135 this%dativar%c(i)%c = &
7136 firsttrue(this%dativar%c(i)%btable == this%dativarattr%c(:)%btable)
7137 ENDDO
7138 ENDIF
7139ENDIF
7140
7141END SUBROUTINE vol7d_set_attr_ind
7142
7143
7144!> Metodo per fondere 2 oggetti vol7d.
7145!! Il secondo volume viene accodato al primo e poi distrutto, si veda
7146!! quindi la descrizione di ::vol7d_append. Se uno degli oggetti \a
7147!! this o \a that sono vuoti non perde tempo inutile,
7148SUBROUTINE vol7d_merge(this, that, sort, bestdata, &
7149 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
7150TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, alla fine conterrà il risultato della fusione
7151TYPE(vol7d),INTENT(INOUT) :: that !< secondo oggetto in ingresso, alla fine sarà distrutto
7152LOGICAL,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
7153LOGICAL,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
7154LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple ! experimental, please do not use outside the library now
7155
7156TYPE(vol7d) :: v7d_clean
7157
7158
7159IF (.NOT.c_e(this)) THEN ! speedup
7160 this = that
7161 CALL init(v7d_clean)
7162 that = v7d_clean ! destroy that without deallocating
7163ELSE ! Append that to this and destroy that
7164 CALL vol7d_append(this, that, sort, bestdata, &
7165 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
7166 CALL delete(that)
7167ENDIF
7168
7169END SUBROUTINE vol7d_merge
7170
7171
7172!> Metodo per accodare un oggetto vol7d ad un altro.
7173!! Si tratta di un metodo molto potente e versatile;
7174!! i descrittori delle dimensioni del volume finale conterranno i valori
7175!! dei corrispondenti descrittori del primo e del secondo volume
7176!! e i volumi di anagrafica e dati conterranno i valori dei due volumi
7177!! ai posti giusti, e valori mancanti per le nuove combinazioni che
7178!! eventualmente si verranno a creare.
7179!! Se i volumi multidimensionali di anagrafica e/o dati dei 2 oggetti
7180!! hanno un'intersezione non nulla, negli elementi comuni il volume finale
7181!! conterrà il corrispondente elemento del \b secondo volume.
7182!! Attenzione che, durante l'esecuzione del metodo, la memoria richiesta è
7183!! pari alla memoria complessiva occupata dai 2 volumi iniziali più
7184!! la memoria complessiva del volume finale, per cui, nel caso di volumi grandi,
7185!! ci potrebbero essere problemi di esaurimento della memoria centrale.
7186!! Se l'oggetto \a that è vuoto non perde tempo inutile,
7187!!
7188!! \todo nel caso di elementi comuni inserire la possibiità (opzionale per
7189!! non penalizzare le prestazioni quando ciò non serve) di effettuare una scelta
7190!! più ragionata dell'elemento da tenere, almeno controllando i dati mancanti
7191!! se non le flag di qualità
7192!!
7193!! \todo "rateizzare" l'allocazione dei volumi per ridurre l'occupazione di
7194!! memoria nel caso siano allocati contemporaneamente volumi di variabili e
7195!! di attributi o più volumi di tipi diversi
7196!!
7197!! \todo il parametro \a that è dichiarato \a INOUT perché la vol7d_alloc_vol
7198!! può modificarlo, bisognerebbe implementare una vol7d_check_vol che restituisca
7199!! errore anziché usare la vol7d_alloc_vol.
7200SUBROUTINE vol7d_append(this, that, sort, bestdata, &
7201 ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple)
7202TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, a cui sarà accodato il secondo
7203TYPE(vol7d),INTENT(IN) :: that !< secondo oggetto in ingresso, non viene modificato dal metodo
7204LOGICAL,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
7205! experimental, please do not use outside the library now, they force the use
7206! of a simplified mapping algorithm which is valid only whene the dimension
7207! content is the same in both volumes , or when one of them is empty
7208LOGICAL,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
7209LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple
7210
7211
7212TYPE(vol7d) :: v7dtmp
7213LOGICAL :: lsort, lbestdata
7214INTEGER,POINTER :: remapt1(:), remapt2(:), remaptr1(:), remaptr2(:), &
7215 remapl1(:), remapl2(:), remapa1(:), remapa2(:), remapn1(:), remapn2(:)
7216
7217IF (.NOT.c_e(that)) RETURN ! speedup, nothing to do
7218IF (.NOT.vol7d_check_vol(that)) RETURN ! be safe
7219IF (.NOT.c_e(this)) THEN ! this case is like a vol7d_copy, more efficient to copy?
7220 CALL vol7d_copy(that, this, sort=sort)
7221 RETURN
7222ENDIF
7223
7224IF (this%time_definition /= that%time_definition) THEN
7225 CALL l4f_log(l4f_fatal, &
7226 'in vol7d_append, cannot append volumes with different &
7227 &time definition')
7228 CALL raise_fatal_error()
7229ENDIF
7230
7231! Completo l'allocazione per avere volumi a norma
7232CALL vol7d_alloc_vol(this)
7233
7234CALL init(v7dtmp, time_definition=this%time_definition)
7235CALL optio(sort, lsort)
7236CALL optio(bestdata, lbestdata)
7237
7238! Calcolo le mappature tra volumi vecchi e volume nuovo
7239! I puntatori remap* vengono tutti o allocati o nullificati
7240IF (optio_log(ltimesimple)) THEN
7241 CALL vol7d_remap2simple_datetime(this%time, that%time, v7dtmp%time, &
7242 lsort, remapt1, remapt2)
7243ELSE
7244 CALL vol7d_remap2_datetime(this%time, that%time, v7dtmp%time, &
7245 lsort, remapt1, remapt2)
7246ENDIF
7247IF (optio_log(ltimerangesimple)) THEN
7248 CALL vol7d_remap2simple_vol7d_timerange(this%timerange, that%timerange, &
7249 v7dtmp%timerange, lsort, remaptr1, remaptr2)
7250ELSE
7251 CALL vol7d_remap2_vol7d_timerange(this%timerange, that%timerange, &
7252 v7dtmp%timerange, lsort, remaptr1, remaptr2)
7253ENDIF
7254IF (optio_log(llevelsimple)) THEN
7255 CALL vol7d_remap2simple_vol7d_level(this%level, that%level, v7dtmp%level, &
7256 lsort, remapl1, remapl2)
7257ELSE
7258 CALL vol7d_remap2_vol7d_level(this%level, that%level, v7dtmp%level, &
7259 lsort, remapl1, remapl2)
7260ENDIF
7261IF (optio_log(lanasimple)) THEN
7262 CALL vol7d_remap2simple_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
7263 .false., remapa1, remapa2)
7264ELSE
7265 CALL vol7d_remap2_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
7266 .false., remapa1, remapa2)
7267ENDIF
7268IF (optio_log(lnetworksimple)) THEN
7269 CALL vol7d_remap2simple_vol7d_network(this%network, that%network, v7dtmp%network, &
7270 .false., remapn1, remapn2)
7271ELSE
7272 CALL vol7d_remap2_vol7d_network(this%network, that%network, v7dtmp%network, &
7273 .false., remapn1, remapn2)
7274ENDIF
7275
7276! Faccio la fusione fisica dei volumi
7277CALL vol7d_merge_finalr(this, that, v7dtmp, &
7278 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
7279 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
7280CALL vol7d_merge_finald(this, that, v7dtmp, &
7281 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
7282 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
7283CALL vol7d_merge_finali(this, that, v7dtmp, &
7284 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
7285 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
7286CALL vol7d_merge_finalb(this, that, v7dtmp, &
7287 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
7288 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
7289CALL vol7d_merge_finalc(this, that, v7dtmp, &
7290 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
7291 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
7292
7293! Dealloco i vettori di rimappatura
7294IF (ASSOCIATED(remapt1)) DEALLOCATE(remapt1)
7295IF (ASSOCIATED(remapt2)) DEALLOCATE(remapt2)
7296IF (ASSOCIATED(remaptr1)) DEALLOCATE(remaptr1)
7297IF (ASSOCIATED(remaptr2)) DEALLOCATE(remaptr2)
7298IF (ASSOCIATED(remapl1)) DEALLOCATE(remapl1)
7299IF (ASSOCIATED(remapl2)) DEALLOCATE(remapl2)
7300IF (ASSOCIATED(remapa1)) DEALLOCATE(remapa1)
7301IF (ASSOCIATED(remapa2)) DEALLOCATE(remapa2)
7302IF (ASSOCIATED(remapn1)) DEALLOCATE(remapn1)
7303IF (ASSOCIATED(remapn2)) DEALLOCATE(remapn2)
7304
7305! Distruggo il vecchio volume e assegno il nuovo a this
7306CALL delete(this)
7307this = v7dtmp
7308! Ricreo gli indici var-attr
7309CALL vol7d_set_attr_ind(this)
7310
7311END SUBROUTINE vol7d_append
7312
7313
7314!> Metodo per creare una copia completa e indipendente di un oggetto vol7d.
7315!! Questo metodo crea un duplicato di tutti i membri di un oggetto vol7d,
7316!! con la possibilità di rielaborarlo durante la copia. Se l'oggetto da copiare
7317!! è vuoto non perde tempo inutile.
7318!! Attenzione, il codice:
7319!! \code
7320!! USE vol7d_class
7321!! TYPE(vol7d) :: vol1, vol2
7322!! CALL init(vol1)
7323!! CALL init(vol2)
7324!! ... ! riempio vol1
7325!! vol2 = vol1
7326!! \endcode
7327!! fa una cosa diversa rispetto a:
7328!! \code
7329!! USE vol7d_class
7330!! TYPE(vol7d) :: vol1, vol2
7331!! CALL init(vol1)
7332!! CALL init(vol2)
7333!! ... ! riempio vol1
7334!! CALL vol7d_copy(vol1, vol2)
7335!! \endcode
7336!! nel primo caso, infatti, l'operatore di assegnazione copia solo i componenti
7337!! statici di \a vol1 nei corrispondenti elementi di \a vol2, mentre i componenti che
7338!! sono allocati dinamicamente (cioè quelli che in ::vol7d hanno l'attributo
7339!! \c POINTER, in pratica quasi tutti) non vengono duplicati, ma per essi vol2
7340!! conterrà un puntatore al corrispondente elemento a cui già punta vol1, e quindi
7341!! eventuali cambiamenti al contenuto di uno dei due oggetti influenzerà il
7342!! contenuto dell'altro; nel secondo caso, invece, vol1 e vol2 sono, dopo la
7343!! vol7d_copy, 2 istanze
7344!! completamente indipendenti, ma uguali tra loro per contenuto, della classe
7345!! vol7d, e quindi hanno vita indipendente.
7346SUBROUTINE vol7d_copy(this, that, sort, unique, miss, &
7347 lsort_time, lsort_timerange, lsort_level, &
7348 ltime, ltimerange, llevel, lana, lnetwork, &
7349 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
7350 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
7351 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
7352 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
7353 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
7354 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
7355TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
7356TYPE(vol7d),INTENT(INOUT) :: that !< oggetto destinazione
7357LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
7358LOGICAL,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)
7359LOGICAL,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
7360LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
7361LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
7362LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
7363!> se fornito, deve essere un vettore logico della stessa lunghezza di
7364!! this%time indicante quali elementi della dimensione \a time
7365!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
7366!! nel volume copiato; in alternativa può essere un vettore di
7367!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
7368!! gli elementi (utile principalmente per le variabili); è compatibile
7369!! col parametro \a miss
7370LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
7371!> come il precedente per la dimensione \a timerange
7372LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:)
7373!> come il precedente per la dimensione \a level
7374LOGICAL,INTENT(IN),OPTIONAL :: llevel(:)
7375!> come il precedente per la dimensione \a ana
7376LOGICAL,INTENT(IN),OPTIONAL :: lana(:)
7377!> come il precedente per la dimensione \a network
7378LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:)
7379!> come il precedente per tutte le possibili dimensioni variabile
7380LOGICAL,INTENT(in),OPTIONAL :: &
7381 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
7382 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
7383 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
7384 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
7385 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
7386 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
7387
7388LOGICAL :: lsort, lunique, lmiss
7389INTEGER,POINTER :: remapt(:), remaptr(:), remapl(:), remapa(:), remapn(:)
7390
7391CALL init(that)
7392IF (.NOT.c_e(this)) RETURN ! speedup, nothing to do
7393IF (.NOT.vol7d_check_vol(this)) RETURN ! be safe
7394
7395CALL optio(sort, lsort)
7396CALL optio(unique, lunique)
7397CALL optio(miss, lmiss)
7398
7399! Calcolo le mappature tra volume vecchio e volume nuovo
7400! I puntatori remap* vengono tutti o allocati o nullificati
7401CALL vol7d_remap1_datetime(this%time, that%time, &
7402 lsort.OR.optio_log(lsort_time), lunique, lmiss, remapt, ltime)
7403CALL vol7d_remap1_vol7d_timerange(this%timerange, that%timerange, &
7404 lsort.OR.optio_log(lsort_timerange), lunique, lmiss, remaptr, ltimerange)
7405CALL vol7d_remap1_vol7d_level(this%level, that%level, &
7406 lsort.OR.optio_log(lsort_level), lunique, lmiss, remapl, llevel)
7407CALL vol7d_remap1_vol7d_ana(this%ana, that%ana, &
7408 lsort, lunique, lmiss, remapa, lana)
7409CALL vol7d_remap1_vol7d_network(this%network, that%network, &
7410 lsort, lunique, lmiss, remapn, lnetwork)
7411
7412! lanavari, lanavarb, lanavarc, &
7413! lanaattri, lanaattrb, lanaattrc, &
7414! lanavarattri, lanavarattrb, lanavarattrc, &
7415! ldativari, ldativarb, ldativarc, &
7416! ldatiattri, ldatiattrb, ldatiattrc, &
7417! ldativarattri, ldativarattrb, ldativarattrc
7418! Faccio la riforma fisica dei volumi
7419CALL vol7d_reform_finalr(this, that, &
7420 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
7421 lanavarr, lanaattrr, lanavarattrr, ldativarr, ldatiattrr, ldativarattrr)
7422CALL vol7d_reform_finald(this, that, &
7423 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
7424 lanavard, lanaattrd, lanavarattrd, ldativard, ldatiattrd, ldativarattrd)
7425CALL vol7d_reform_finali(this, that, &
7426 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
7427 lanavari, lanaattri, lanavarattri, ldativari, ldatiattri, ldativarattri)
7428CALL vol7d_reform_finalb(this, that, &
7429 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
7430 lanavarb, lanaattrb, lanavarattrb, ldativarb, ldatiattrb, ldativarattrb)
7431CALL vol7d_reform_finalc(this, that, &
7432 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
7433 lanavarc, lanaattrc, lanavarattrc, ldativarc, ldatiattrc, ldativarattrc)
7434
7435! Dealloco i vettori di rimappatura
7436IF (ASSOCIATED(remapt)) DEALLOCATE(remapt)
7437IF (ASSOCIATED(remaptr)) DEALLOCATE(remaptr)
7438IF (ASSOCIATED(remapl)) DEALLOCATE(remapl)
7439IF (ASSOCIATED(remapa)) DEALLOCATE(remapa)
7440IF (ASSOCIATED(remapn)) DEALLOCATE(remapn)
7441
7442! Ricreo gli indici var-attr
7443CALL vol7d_set_attr_ind(that)
7444that%time_definition = this%time_definition
7445
7446END SUBROUTINE vol7d_copy
7447
7448
7449!> Metodo per riformare in varie maniere un oggetto vol7d.
7450!! Equivale ad una copia (vedi ::vol7d_copy)
7451!! seguita dalla distruzione del volume iniziale e alla
7452!! sua riassegnazione al volume copiato. Ha senso se almeno uno dei parametri
7453!! \a sort, \a uniq o \a miss è fornito uguale a \c .TRUE., altrimenti
7454!! è solo una perdita di tempo.
7455!! Può essere utile, ad esempio, per eliminare stazioni
7456!! o istanti temporali indesiderati, basta assegnare il loro corrispondente
7457!! elemento del descrittore a valore mancante e chiamare vol7d_reform
7458!! con miss=.TRUE. .
7459SUBROUTINE vol7d_reform(this, sort, unique, miss, &
7460 lsort_time, lsort_timerange, lsort_level, &
7461 ltime, ltimerange, llevel, lana, lnetwork, &
7462 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
7463 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
7464 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
7465 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
7466 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
7467 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc&
7468 ,purgeana)
7469TYPE(vol7d),INTENT(INOUT) :: this !< oggetto da riformare
7470LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
7471LOGICAL,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)
7472LOGICAL,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
7473LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
7474LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
7475LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
7476!> se fornito, deve essere un vettore logico della stessa lunghezza di
7477!! this%time indicante quali elementi della dimensione \a time
7478!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
7479!! nel volume copiato; in alternativa può essere un vettore di
7480!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
7481!! gli elementi (utile principalmente per le variabili); è compatibile
7482!! col parametro \a miss
7483LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
7484LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:) !< come il precedente per la dimensione \a timerange
7485LOGICAL,INTENT(IN),OPTIONAL :: llevel(:) !< come il precedente per la dimensione \a level
7486LOGICAL,INTENT(IN),OPTIONAL :: lana(:) !< come il precedente per la dimensione \a ana
7487LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:) !< come il precedente per la dimensione \a network
7488!> come il precedente per tutte le possibili dimensioni variabile
7489LOGICAL,INTENT(in),OPTIONAL :: &
7490 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
7491 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
7492 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
7493 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
7494 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
7495 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
7496LOGICAL,INTENT(IN),OPTIONAL :: purgeana !< if true remove ana with all data missing
7497
7498TYPE(vol7d) :: v7dtmp
7499logical,allocatable :: llana(:)
7500integer :: i
7501
7502CALL vol7d_copy(this, v7dtmp, sort, unique, miss, &
7503 lsort_time, lsort_timerange, lsort_level, &
7504 ltime, ltimerange, llevel, lana, lnetwork, &
7505 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
7506 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
7507 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
7508 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
7509 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
7510 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
7511
7512! destroy old volume
7513CALL delete(this)
7514
7515if (optio_log(purgeana)) then
7516 allocate(llana(size(v7dtmp%ana)))
7517 llana =.false.
7518 do i =1,size(v7dtmp%ana)
7519 if (associated(v7dtmp%voldatii)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatii(i,:,:,:,:,:)))
7520 if (associated(v7dtmp%voldatir)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatir(i,:,:,:,:,:)))
7521 if (associated(v7dtmp%voldatid)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatid(i,:,:,:,:,:)))
7522 if (associated(v7dtmp%voldatib)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatib(i,:,:,:,:,:)))
7523 if (associated(v7dtmp%voldatic)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatic(i,:,:,:,:,:)))
7524 end do
7525 CALL vol7d_copy(v7dtmp, this,lana=llana)
7526 CALL delete(v7dtmp)
7527 deallocate(llana)
7528else
7529 this=v7dtmp
7530end if
7531
7532END SUBROUTINE vol7d_reform
7533
7534
7535!> Sorts the sortable dimensions in the volume \a this only when necessary.
7536!! Most of the times, the time, timerange and level dimensions in a
7537!! vol7d object are correctly sorted; on the other side many methods
7538!! strictly rely on this fact in order to work correctly. This method
7539!! performs a quick check and sorts the required dimensions only if
7540!! they are not sorted in ascending order yet, improving safety
7541!! without impairing much performance.
7542SUBROUTINE vol7d_smart_sort(this, lsort_time, lsort_timerange, lsort_level)
7543TYPE(vol7d),INTENT(INOUT) :: this !< object to be sorted
7544LOGICAL,OPTIONAL,INTENT(in) :: lsort_time !< if present and \a .TRUE., sort time dimension if it is not sorted in ascending order
7545LOGICAL,OPTIONAL,INTENT(in) :: lsort_timerange !< if present and \a .TRUE., sort timerange dimension if it is not sorted in ascending order
7546LOGICAL,OPTIONAL,INTENT(in) :: lsort_level !< if present and \a .TRUE., sort vertical level dimension if it is not sorted in ascending order
7547
7548INTEGER :: i
7549LOGICAL :: to_be_sorted
7550
7551to_be_sorted = .false.
7552CALL vol7d_alloc_vol(this) ! usual safety check
7553
7554IF (optio_log(lsort_time)) THEN
7555 DO i = 2, SIZE(this%time)
7556 IF (this%time(i) < this%time(i-1)) THEN
7557 to_be_sorted = .true.
7558 EXIT
7559 ENDIF
7560 ENDDO
7561ENDIF
7562IF (optio_log(lsort_timerange)) THEN
7563 DO i = 2, SIZE(this%timerange)
7564 IF (this%timerange(i) < this%timerange(i-1)) THEN
7565 to_be_sorted = .true.
7566 EXIT
7567 ENDIF
7568 ENDDO
7569ENDIF
7570IF (optio_log(lsort_level)) THEN
7571 DO i = 2, SIZE(this%level)
7572 IF (this%level(i) < this%level(i-1)) THEN
7573 to_be_sorted = .true.
7574 EXIT
7575 ENDIF
7576 ENDDO
7577ENDIF
7578
7579IF (to_be_sorted) CALL vol7d_reform(this, &
7580 lsort_time=lsort_time, lsort_timerange=lsort_timerange, lsort_level=lsort_level )
7581
7582END SUBROUTINE vol7d_smart_sort
7583
7584!> Filter the contents of a volume keeping only desired data.
7585!! This subroutine filters a vol7d object by keeping only a subset of
7586!! the data contained. It can keep only times within a specified
7587!! interval, only station networks contained in a list and only
7588!! specified station or data variables. If a filter parameter is not
7589!! provided, no filtering will take place according to that criterion.
7590!! The volume is reallocated keeping only the desired data.
7591SUBROUTINE vol7d_filter(this, avl, vl, nl, s_d, e_d)
7592TYPE(vol7d),INTENT(inout) :: this !< volume to be filtered
7593CHARACTER(len=*),INTENT(in),OPTIONAL :: avl(:) !< list of station variables to be kept, if not provided or of zero length, all variables are kept
7594CHARACTER(len=*),INTENT(in),OPTIONAL :: vl(:) !< list of data variables to be kept, if not provided or of zero length, all variables are kept
7595TYPE(vol7d_network),OPTIONAL :: nl(:) !< list of station networks to be kept, if not provided or of zero length, all networks are kept
7596TYPE(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
7597TYPE(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
7598
7599INTEGER :: i
7600
7601IF (PRESENT(avl)) THEN
7602 IF (SIZE(avl) > 0) THEN
7603
7604 IF (ASSOCIATED(this%anavar%r)) THEN
7605 DO i = 1, SIZE(this%anavar%r)
7606 IF (all(this%anavar%r(i)%btable /= avl)) this%anavar%r(i) = vol7d_var_miss
7607 ENDDO
7608 ENDIF
7609
7610 IF (ASSOCIATED(this%anavar%i)) THEN
7611 DO i = 1, SIZE(this%anavar%i)
7612 IF (all(this%anavar%i(i)%btable /= avl)) this%anavar%i(i) = vol7d_var_miss
7613 ENDDO
7614 ENDIF
7615
7616 IF (ASSOCIATED(this%anavar%b)) THEN
7617 DO i = 1, SIZE(this%anavar%b)
7618 IF (all(this%anavar%b(i)%btable /= avl)) this%anavar%b(i) = vol7d_var_miss
7619 ENDDO
7620 ENDIF
7621
7622 IF (ASSOCIATED(this%anavar%d)) THEN
7623 DO i = 1, SIZE(this%anavar%d)
7624 IF (all(this%anavar%d(i)%btable /= avl)) this%anavar%d(i) = vol7d_var_miss
7625 ENDDO
7626 ENDIF
7627
7628 IF (ASSOCIATED(this%anavar%c)) THEN
7629 DO i = 1, SIZE(this%anavar%c)
7630 IF (all(this%anavar%c(i)%btable /= avl)) this%anavar%c(i) = vol7d_var_miss
7631 ENDDO
7632 ENDIF
7633
7634 ENDIF
7635ENDIF
7636
7637
7638IF (PRESENT(vl)) THEN
7639 IF (size(vl) > 0) THEN
7640 IF (ASSOCIATED(this%dativar%r)) THEN
7641 DO i = 1, SIZE(this%dativar%r)
7642 IF (all(this%dativar%r(i)%btable /= vl)) this%dativar%r(i) = vol7d_var_miss
7643 ENDDO
7644 ENDIF
7645
7646 IF (ASSOCIATED(this%dativar%i)) THEN
7647 DO i = 1, SIZE(this%dativar%i)
7648 IF (all(this%dativar%i(i)%btable /= vl)) this%dativar%i(i) = vol7d_var_miss
7649 ENDDO
7650 ENDIF
7651
7652 IF (ASSOCIATED(this%dativar%b)) THEN
7653 DO i = 1, SIZE(this%dativar%b)
7654 IF (all(this%dativar%b(i)%btable /= vl)) this%dativar%b(i) = vol7d_var_miss
7655 ENDDO
7656 ENDIF
7657
7658 IF (ASSOCIATED(this%dativar%d)) THEN
7659 DO i = 1, SIZE(this%dativar%d)
7660 IF (all(this%dativar%d(i)%btable /= vl)) this%dativar%d(i) = vol7d_var_miss
7661 ENDDO
7662 ENDIF
7663
7664 IF (ASSOCIATED(this%dativar%c)) THEN
7665 DO i = 1, SIZE(this%dativar%c)
7666 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
7667 ENDDO
7668 ENDIF
7669
7670 IF (ASSOCIATED(this%dativar%c)) THEN
7671 DO i = 1, SIZE(this%dativar%c)
7672 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
7673 ENDDO
7674 ENDIF
7675
7676 ENDIF
7677ENDIF
7678
7679IF (PRESENT(nl)) THEN
7680 IF (SIZE(nl) > 0) THEN
7681 DO i = 1, SIZE(this%network)
7682 IF (all(this%network(i) /= nl)) this%network(i) = vol7d_network_miss
7683 ENDDO
7684 ENDIF
7685ENDIF
7686
7687IF (PRESENT(s_d)) THEN
7688 IF (c_e(s_d)) THEN
7689 WHERE (this%time < s_d)
7690 this%time = datetime_miss
7691 END WHERE
7692 ENDIF
7693ENDIF
7694
7695IF (PRESENT(e_d)) THEN
7696 IF (c_e(e_d)) THEN
7697 WHERE (this%time > e_d)
7698 this%time = datetime_miss
7699 END WHERE
7700 ENDIF
7701ENDIF
7702
7703CALL vol7d_reform(this, miss=.true.)
7704
7705END SUBROUTINE vol7d_filter
7706
7707
7708!> Metodo per convertire i volumi di dati di un oggetto vol7d in dati
7709!! reali dove possibile. L'oggetto convertito è una copia completa
7710!! dell'originale che può essere quindi distrutto dopo la chiamata.
7711!! Per i dati di anagrafica, al momento sono convertiti solo
7712!! i dati CHARACTER se è passato \a anaconv=.TRUE.
7713!! Gli attributi non sono toccati.
7714SUBROUTINE vol7d_convr(this, that, anaconv)
7715TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
7716TYPE(vol7d),INTENT(INOUT) :: that !< oggetto convertito
7717LOGICAL,OPTIONAL,INTENT(in) :: anaconv !< converti anche anagrafica
7718INTEGER :: i
7719LOGICAL :: fv(1)=(/.false./), tv(1)=(/.true./), acp(1), acn(1)
7720TYPE(vol7d) :: v7d_tmp
7721
7722IF (optio_log(anaconv)) THEN
7723 acp=fv
7724 acn=tv
7725ELSE
7726 acp=tv
7727 acn=fv
7728ENDIF
7729
7730! Volume con solo i dati reali e tutti gli attributi
7731! l'anagrafica e` copiata interamente se necessario
7732CALL vol7d_copy(this, that, &
7733 lanavarr=tv, lanavard=acp, lanavari=acp, lanavarb=acp, lanavarc=acp, &
7734 ldativarr=tv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=fv)
7735
7736! Volume solo di dati double
7737CALL vol7d_copy(this, v7d_tmp, &
7738 lanavarr=fv, lanavard=acn, lanavari=fv, lanavarb=fv, lanavarc=fv, &
7739 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
7740 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
7741 ldativarr=fv, ldativard=tv, ldativari=fv, ldativarb=fv, ldativarc=fv, &
7742 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
7743 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
7744
7745! converto a dati reali
7746IF (ASSOCIATED(v7d_tmp%anavar%d) .OR. ASSOCIATED(v7d_tmp%dativar%d)) THEN
7747
7748 IF (ASSOCIATED(v7d_tmp%anavar%d)) THEN
7749! alloco i dati reali e vi trasferisco i double
7750 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanad, 1), SIZE(v7d_tmp%volanad, 2), &
7751 SIZE(v7d_tmp%volanad, 3)))
7752 DO i = 1, SIZE(v7d_tmp%anavar%d)
7753 v7d_tmp%volanar(:,i,:) = &
7754 realdat(v7d_tmp%volanad(:,i,:), v7d_tmp%anavar%d(i))
7755 ENDDO
7756 DEALLOCATE(v7d_tmp%volanad)
7757! trasferisco le variabili
7758 v7d_tmp%anavar%r => v7d_tmp%anavar%d
7759 NULLIFY(v7d_tmp%anavar%d)
7760 ENDIF
7761
7762 IF (ASSOCIATED(v7d_tmp%dativar%d)) THEN
7763! alloco i dati reali e vi trasferisco i double
7764 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatid, 1), SIZE(v7d_tmp%voldatid, 2), &
7765 SIZE(v7d_tmp%voldatid, 3), SIZE(v7d_tmp%voldatid, 4), SIZE(v7d_tmp%voldatid, 5), &
7766 SIZE(v7d_tmp%voldatid, 6)))
7767 DO i = 1, SIZE(v7d_tmp%dativar%d)
7768 v7d_tmp%voldatir(:,:,:,:,i,:) = &
7769 realdat(v7d_tmp%voldatid(:,:,:,:,i,:), v7d_tmp%dativar%d(i))
7770 ENDDO
7771 DEALLOCATE(v7d_tmp%voldatid)
7772! trasferisco le variabili
7773 v7d_tmp%dativar%r => v7d_tmp%dativar%d
7774 NULLIFY(v7d_tmp%dativar%d)
7775 ENDIF
7776
7777! fondo con il volume definitivo
7778 CALL vol7d_merge(that, v7d_tmp)
7779ELSE
7780 CALL delete(v7d_tmp)
7781ENDIF
7782
7783
7784! Volume solo di dati interi
7785CALL vol7d_copy(this, v7d_tmp, &
7786 lanavarr=fv, lanavard=fv, lanavari=acn, lanavarb=fv, lanavarc=fv, &
7787 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
7788 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
7789 ldativarr=fv, ldativard=fv, ldativari=tv, ldativarb=fv, ldativarc=fv, &
7790 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
7791 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
7792
7793! converto a dati reali
7794IF (ASSOCIATED(v7d_tmp%anavar%i) .OR. ASSOCIATED(v7d_tmp%dativar%i)) THEN
7795
7796 IF (ASSOCIATED(v7d_tmp%anavar%i)) THEN
7797! alloco i dati reali e vi trasferisco gli interi
7798 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanai, 1), SIZE(v7d_tmp%volanai, 2), &
7799 SIZE(v7d_tmp%volanai, 3)))
7800 DO i = 1, SIZE(v7d_tmp%anavar%i)
7801 v7d_tmp%volanar(:,i,:) = &
7802 realdat(v7d_tmp%volanai(:,i,:), v7d_tmp%anavar%i(i))
7803 ENDDO
7804 DEALLOCATE(v7d_tmp%volanai)
7805! trasferisco le variabili
7806 v7d_tmp%anavar%r => v7d_tmp%anavar%i
7807 NULLIFY(v7d_tmp%anavar%i)
7808 ENDIF
7809
7810 IF (ASSOCIATED(v7d_tmp%dativar%i)) THEN
7811! alloco i dati reali e vi trasferisco gli interi
7812 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatii, 1), SIZE(v7d_tmp%voldatii, 2), &
7813 SIZE(v7d_tmp%voldatii, 3), SIZE(v7d_tmp%voldatii, 4), SIZE(v7d_tmp%voldatii, 5), &
7814 SIZE(v7d_tmp%voldatii, 6)))
7815 DO i = 1, SIZE(v7d_tmp%dativar%i)
7816 v7d_tmp%voldatir(:,:,:,:,i,:) = &
7817 realdat(v7d_tmp%voldatii(:,:,:,:,i,:), v7d_tmp%dativar%i(i))
7818 ENDDO
7819 DEALLOCATE(v7d_tmp%voldatii)
7820! trasferisco le variabili
7821 v7d_tmp%dativar%r => v7d_tmp%dativar%i
7822 NULLIFY(v7d_tmp%dativar%i)
7823 ENDIF
7824
7825! fondo con il volume definitivo
7826 CALL vol7d_merge(that, v7d_tmp)
7827ELSE
7828 CALL delete(v7d_tmp)
7829ENDIF
7830
7831
7832! Volume solo di dati byte
7833CALL vol7d_copy(this, v7d_tmp, &
7834 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=acn, lanavarc=fv, &
7835 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
7836 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
7837 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=tv, ldativarc=fv, &
7838 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
7839 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
7840
7841! converto a dati reali
7842IF (ASSOCIATED(v7d_tmp%anavar%b) .OR. ASSOCIATED(v7d_tmp%dativar%b)) THEN
7843
7844 IF (ASSOCIATED(v7d_tmp%anavar%b)) THEN
7845! alloco i dati reali e vi trasferisco i byte
7846 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanab, 1), SIZE(v7d_tmp%volanab, 2), &
7847 SIZE(v7d_tmp%volanab, 3)))
7848 DO i = 1, SIZE(v7d_tmp%anavar%b)
7849 v7d_tmp%volanar(:,i,:) = &
7850 realdat(v7d_tmp%volanab(:,i,:), v7d_tmp%anavar%b(i))
7851 ENDDO
7852 DEALLOCATE(v7d_tmp%volanab)
7853! trasferisco le variabili
7854 v7d_tmp%anavar%r => v7d_tmp%anavar%b
7855 NULLIFY(v7d_tmp%anavar%b)
7856 ENDIF
7857
7858 IF (ASSOCIATED(v7d_tmp%dativar%b)) THEN
7859! alloco i dati reali e vi trasferisco i byte
7860 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatib, 1), SIZE(v7d_tmp%voldatib, 2), &
7861 SIZE(v7d_tmp%voldatib, 3), SIZE(v7d_tmp%voldatib, 4), SIZE(v7d_tmp%voldatib, 5), &
7862 SIZE(v7d_tmp%voldatib, 6)))
7863 DO i = 1, SIZE(v7d_tmp%dativar%b)
7864 v7d_tmp%voldatir(:,:,:,:,i,:) = &
7865 realdat(v7d_tmp%voldatib(:,:,:,:,i,:), v7d_tmp%dativar%b(i))
7866 ENDDO
7867 DEALLOCATE(v7d_tmp%voldatib)
7868! trasferisco le variabili
7869 v7d_tmp%dativar%r => v7d_tmp%dativar%b
7870 NULLIFY(v7d_tmp%dativar%b)
7871 ENDIF
7872
7873! fondo con il volume definitivo
7874 CALL vol7d_merge(that, v7d_tmp)
7875ELSE
7876 CALL delete(v7d_tmp)
7877ENDIF
7878
7879
7880! Volume solo di dati character
7881CALL vol7d_copy(this, v7d_tmp, &
7882 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=fv, lanavarc=acn, &
7883 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
7884 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
7885 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=tv, &
7886 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
7887 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
7888
7889! converto a dati reali
7890IF (ASSOCIATED(v7d_tmp%anavar%c) .OR. ASSOCIATED(v7d_tmp%dativar%c)) THEN
7891
7892 IF (ASSOCIATED(v7d_tmp%anavar%c)) THEN
7893! alloco i dati reali e vi trasferisco i character
7894 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanac, 1), SIZE(v7d_tmp%volanac, 2), &
7895 SIZE(v7d_tmp%volanac, 3)))
7896 DO i = 1, SIZE(v7d_tmp%anavar%c)
7897 v7d_tmp%volanar(:,i,:) = &
7898 realdat(v7d_tmp%volanac(:,i,:), v7d_tmp%anavar%c(i))
7899 ENDDO
7900 DEALLOCATE(v7d_tmp%volanac)
7901! trasferisco le variabili
7902 v7d_tmp%anavar%r => v7d_tmp%anavar%c
7903 NULLIFY(v7d_tmp%anavar%c)
7904 ENDIF
7905
7906 IF (ASSOCIATED(v7d_tmp%dativar%c)) THEN
7907! alloco i dati reali e vi trasferisco i character
7908 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatic, 1), SIZE(v7d_tmp%voldatic, 2), &
7909 SIZE(v7d_tmp%voldatic, 3), SIZE(v7d_tmp%voldatic, 4), SIZE(v7d_tmp%voldatic, 5), &
7910 SIZE(v7d_tmp%voldatic, 6)))
7911 DO i = 1, SIZE(v7d_tmp%dativar%c)
7912 v7d_tmp%voldatir(:,:,:,:,i,:) = &
7913 realdat(v7d_tmp%voldatic(:,:,:,:,i,:), v7d_tmp%dativar%c(i))
7914 ENDDO
7915 DEALLOCATE(v7d_tmp%voldatic)
7916! trasferisco le variabili
7917 v7d_tmp%dativar%r => v7d_tmp%dativar%c
7918 NULLIFY(v7d_tmp%dativar%c)
7919 ENDIF
7920
7921! fondo con il volume definitivo
7922 CALL vol7d_merge(that, v7d_tmp)
7923ELSE
7924 CALL delete(v7d_tmp)
7925ENDIF
7926
7927END SUBROUTINE vol7d_convr
7928
7929
7930!> Metodo per ottenere solo le differenze tra due oggetti vol7d.
7931!! Il primo volume viene confrontato col secondo; nel secondo volume ovunque
7932!! i dati confrontati siano coincidenti viene impostato valore mancante.
7933SUBROUTINE vol7d_diff_only (this, that, data_only,ana)
7934TYPE(vol7d),INTENT(IN) :: this !< primo volume da confrontare
7935TYPE(vol7d),INTENT(OUT) :: that !< secondo volume da confrontare in cui eliminare i dati coincidenti
7936logical , optional, intent(in) :: data_only !< attiva l'elaborazione dei soli dati e non dell'anagrafica (default: .false.)
7937logical , optional, intent(in) :: ana !< attiva l'elaborazione dell'anagrafica (coordinate e ident) (default: .false.)
7938logical :: ldata_only,lana
7939
7940IF (PRESENT(data_only)) THEN
7941 ldata_only = data_only
7942ELSE
7943 ldata_only = .false.
7944ENDIF
7945
7946IF (PRESENT(ana)) THEN
7947 lana = ana
7948ELSE
7949 lana = .false.
7950ENDIF
7951
7952
7953#undef VOL7D_POLY_ARRAY
7954#define VOL7D_POLY_ARRAY voldati
7955#include "vol7d_class_diff.F90"
7956#undef VOL7D_POLY_ARRAY
7957#define VOL7D_POLY_ARRAY voldatiattr
7958#include "vol7d_class_diff.F90"
7959#undef VOL7D_POLY_ARRAY
7960
7961if ( .not. ldata_only) then
7962
7963#define VOL7D_POLY_ARRAY volana
7964#include "vol7d_class_diff.F90"
7965#undef VOL7D_POLY_ARRAY
7966#define VOL7D_POLY_ARRAY volanaattr
7967#include "vol7d_class_diff.F90"
7968#undef VOL7D_POLY_ARRAY
7969
7970 if(lana)then
7971 where ( this%ana == that%ana )
7972 that%ana = vol7d_ana_miss
7973 end where
7974 end if
7975
7976end if
7977
7978
7979
7980END SUBROUTINE vol7d_diff_only
7981
7982
7983
7984! Creo le routine da ripetere per i vari tipi di dati di v7d
7985! tramite un template e il preprocessore
7986#undef VOL7D_POLY_TYPE
7987#undef VOL7D_POLY_TYPES
7988#define VOL7D_POLY_TYPE REAL
7989#define VOL7D_POLY_TYPES r
7990#include "vol7d_class_type_templ.F90"
7991#undef VOL7D_POLY_TYPE
7992#undef VOL7D_POLY_TYPES
7993#define VOL7D_POLY_TYPE DOUBLE PRECISION
7994#define VOL7D_POLY_TYPES d
7995#include "vol7d_class_type_templ.F90"
7996#undef VOL7D_POLY_TYPE
7997#undef VOL7D_POLY_TYPES
7998#define VOL7D_POLY_TYPE INTEGER
7999#define VOL7D_POLY_TYPES i
8000#include "vol7d_class_type_templ.F90"
8001#undef VOL7D_POLY_TYPE
8002#undef VOL7D_POLY_TYPES
8003#define VOL7D_POLY_TYPE INTEGER(kind=int_b)
8004#define VOL7D_POLY_TYPES b
8005#include "vol7d_class_type_templ.F90"
8006#undef VOL7D_POLY_TYPE
8007#undef VOL7D_POLY_TYPES
8008#define VOL7D_POLY_TYPE CHARACTER(len=vol7d_cdatalen)
8009#define VOL7D_POLY_TYPES c
8010#include "vol7d_class_type_templ.F90"
8011
8012! Creo le routine da ripetere per i vari descrittori di dimensioni di v7d
8013! tramite un template e il preprocessore
8014#define VOL7D_SORT
8015#undef VOL7D_NO_ZERO_ALLOC
8016#undef VOL7D_POLY_TYPE
8017#define VOL7D_POLY_TYPE datetime
8018#include "vol7d_class_desc_templ.F90"
8019#undef VOL7D_POLY_TYPE
8020#define VOL7D_POLY_TYPE vol7d_timerange
8021#include "vol7d_class_desc_templ.F90"
8022#undef VOL7D_POLY_TYPE
8023#define VOL7D_POLY_TYPE vol7d_level
8024#include "vol7d_class_desc_templ.F90"
8025#undef VOL7D_SORT
8026#undef VOL7D_POLY_TYPE
8027#define VOL7D_POLY_TYPE vol7d_network
8028#include "vol7d_class_desc_templ.F90"
8029#undef VOL7D_POLY_TYPE
8030#define VOL7D_POLY_TYPE vol7d_ana
8031#include "vol7d_class_desc_templ.F90"
8032#define VOL7D_NO_ZERO_ALLOC
8033#undef VOL7D_POLY_TYPE
8034#define VOL7D_POLY_TYPE vol7d_var
8035#include "vol7d_class_desc_templ.F90"
8036
8037!>\brief Scrittura su file di un volume Vol7d.
8038!! Scrittura su file unformatted di un intero volume Vol7d.
8039!! Il volume viene serializzato e scritto su file.
8040!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
8041!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
8042!! tali parametri saranno in output.
8043!! Se non viene fornito il nome file viene utilizzato un file di default con nome pari al nome del programma in
8044!! esecuzione con postfisso ".v7d".
8045!! Come parametro opzionale c'è la description che insieme alla data corrente viene inserita nell'header del file.
8046subroutine vol7d_write_on_file (this,unit,description,filename,filename_auto)
8047
8048TYPE(vol7d),INTENT(IN) :: this !< volume vol7d da scrivere
8049integer,optional,intent(inout) :: unit !< unità su cui scrivere; se passata =0 ritorna il valore rielaborato (default =rielaborato internamente con getlun )
8050character(len=*),intent(in),optional :: filename !< nome del file su cui scrivere
8051character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
8052character(len=*),INTENT(IN),optional :: description !< descrizione del volume
8053
8054integer :: lunit
8055character(len=254) :: ldescription,arg,lfilename
8056integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
8057 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
8058 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
8059 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
8060 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
8061 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
8062 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
8063!integer :: im,id,iy
8064integer :: tarray(8)
8065logical :: opened,exist
8066
8067 nana=0
8068 ntime=0
8069 ntimerange=0
8070 nlevel=0
8071 nnetwork=0
8072 ndativarr=0
8073 ndativari=0
8074 ndativarb=0
8075 ndativard=0
8076 ndativarc=0
8077 ndatiattrr=0
8078 ndatiattri=0
8079 ndatiattrb=0
8080 ndatiattrd=0
8081 ndatiattrc=0
8082 ndativarattrr=0
8083 ndativarattri=0
8084 ndativarattrb=0
8085 ndativarattrd=0
8086 ndativarattrc=0
8087 nanavarr=0
8088 nanavari=0
8089 nanavarb=0
8090 nanavard=0
8091 nanavarc=0
8092 nanaattrr=0
8093 nanaattri=0
8094 nanaattrb=0
8095 nanaattrd=0
8096 nanaattrc=0
8097 nanavarattrr=0
8098 nanavarattri=0
8099 nanavarattrb=0
8100 nanavarattrd=0
8101 nanavarattrc=0
8102
8103
8104!call idate(im,id,iy)
8105call date_and_time(values=tarray)
8106call getarg(0,arg)
8107
8108if (present(description))then
8109 ldescription=description
8110else
8111 ldescription="Vol7d generated by: "//trim(arg)
8112end if
8113
8114if (.not. present(unit))then
8115 lunit=getunit()
8116else
8117 if (unit==0)then
8118 lunit=getunit()
8119 unit=lunit
8120 else
8121 lunit=unit
8122 end if
8123end if
8124
8125lfilename=trim(arg)//".v7d"
8126if (index(arg,'/',back=.true.) > 0) lfilename=lfilename(index(arg,'/',back=.true.)+1 : )
8127
8128if (present(filename))then
8129 if (filename /= "")then
8130 lfilename=filename
8131 end if
8132end if
8133
8134if (present(filename_auto))filename_auto=lfilename
8135
8136
8137inquire(unit=lunit,opened=opened)
8138if (.not. opened) then
8139! inquire(file=lfilename, EXIST=exist)
8140! IF (exist) THEN
8141! CALL l4f_log(L4F_FATAL, &
8142! 'in vol7d_write_on_file, file exists, cannot open file '//TRIM(lfilename))
8143! CALL raise_fatal_error()
8144! ENDIF
8145 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM')
8146 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
8147end if
8148
8149if (associated(this%ana)) nana=size(this%ana)
8150if (associated(this%time)) ntime=size(this%time)
8151if (associated(this%timerange)) ntimerange=size(this%timerange)
8152if (associated(this%level)) nlevel=size(this%level)
8153if (associated(this%network)) nnetwork=size(this%network)
8154
8155if (associated(this%dativar%r)) ndativarr=size(this%dativar%r)
8156if (associated(this%dativar%i)) ndativari=size(this%dativar%i)
8157if (associated(this%dativar%b)) ndativarb=size(this%dativar%b)
8158if (associated(this%dativar%d)) ndativard=size(this%dativar%d)
8159if (associated(this%dativar%c)) ndativarc=size(this%dativar%c)
8160
8161if (associated(this%datiattr%r)) ndatiattrr=size(this%datiattr%r)
8162if (associated(this%datiattr%i)) ndatiattri=size(this%datiattr%i)
8163if (associated(this%datiattr%b)) ndatiattrb=size(this%datiattr%b)
8164if (associated(this%datiattr%d)) ndatiattrd=size(this%datiattr%d)
8165if (associated(this%datiattr%c)) ndatiattrc=size(this%datiattr%c)
8166
8167if (associated(this%dativarattr%r)) ndativarattrr=size(this%dativarattr%r)
8168if (associated(this%dativarattr%i)) ndativarattri=size(this%dativarattr%i)
8169if (associated(this%dativarattr%b)) ndativarattrb=size(this%dativarattr%b)
8170if (associated(this%dativarattr%d)) ndativarattrd=size(this%dativarattr%d)
8171if (associated(this%dativarattr%c)) ndativarattrc=size(this%dativarattr%c)
8172
8173if (associated(this%anavar%r)) nanavarr=size(this%anavar%r)
8174if (associated(this%anavar%i)) nanavari=size(this%anavar%i)
8175if (associated(this%anavar%b)) nanavarb=size(this%anavar%b)
8176if (associated(this%anavar%d)) nanavard=size(this%anavar%d)
8177if (associated(this%anavar%c)) nanavarc=size(this%anavar%c)
8178
8179if (associated(this%anaattr%r)) nanaattrr=size(this%anaattr%r)
8180if (associated(this%anaattr%i)) nanaattri=size(this%anaattr%i)
8181if (associated(this%anaattr%b)) nanaattrb=size(this%anaattr%b)
8182if (associated(this%anaattr%d)) nanaattrd=size(this%anaattr%d)
8183if (associated(this%anaattr%c)) nanaattrc=size(this%anaattr%c)
8184
8185if (associated(this%anavarattr%r)) nanavarattrr=size(this%anavarattr%r)
8186if (associated(this%anavarattr%i)) nanavarattri=size(this%anavarattr%i)
8187if (associated(this%anavarattr%b)) nanavarattrb=size(this%anavarattr%b)
8188if (associated(this%anavarattr%d)) nanavarattrd=size(this%anavarattr%d)
8189if (associated(this%anavarattr%c)) nanavarattrc=size(this%anavarattr%c)
8190
8191write(unit=lunit)ldescription
8192write(unit=lunit)tarray
8193
8194write(unit=lunit)&
8195 nana, ntime, ntimerange, nlevel, nnetwork, &
8196 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
8197 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
8198 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
8199 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
8200 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
8201 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
8202 this%time_definition
8203
8204
8205!write(unit=lunit)this
8206
8207
8208!! prime 5 dimensioni
8209if (associated(this%ana)) call write_unit(this%ana, lunit)
8210if (associated(this%time)) call write_unit(this%time, lunit)
8211if (associated(this%level)) write(unit=lunit)this%level
8212if (associated(this%timerange)) write(unit=lunit)this%timerange
8213if (associated(this%network)) write(unit=lunit)this%network
8214
8215 !! 6a dimensione: variabile dell'anagrafica e dei dati
8216 !! con relativi attributi e in 5 tipi diversi
8217
8218if (associated(this%anavar%r)) write(unit=lunit)this%anavar%r
8219if (associated(this%anavar%i)) write(unit=lunit)this%anavar%i
8220if (associated(this%anavar%b)) write(unit=lunit)this%anavar%b
8221if (associated(this%anavar%d)) write(unit=lunit)this%anavar%d
8222if (associated(this%anavar%c)) write(unit=lunit)this%anavar%c
8223
8224if (associated(this%anaattr%r)) write(unit=lunit)this%anaattr%r
8225if (associated(this%anaattr%i)) write(unit=lunit)this%anaattr%i
8226if (associated(this%anaattr%b)) write(unit=lunit)this%anaattr%b
8227if (associated(this%anaattr%d)) write(unit=lunit)this%anaattr%d
8228if (associated(this%anaattr%c)) write(unit=lunit)this%anaattr%c
8229
8230if (associated(this%anavarattr%r)) write(unit=lunit)this%anavarattr%r
8231if (associated(this%anavarattr%i)) write(unit=lunit)this%anavarattr%i
8232if (associated(this%anavarattr%b)) write(unit=lunit)this%anavarattr%b
8233if (associated(this%anavarattr%d)) write(unit=lunit)this%anavarattr%d
8234if (associated(this%anavarattr%c)) write(unit=lunit)this%anavarattr%c
8235
8236if (associated(this%dativar%r)) write(unit=lunit)this%dativar%r
8237if (associated(this%dativar%i)) write(unit=lunit)this%dativar%i
8238if (associated(this%dativar%b)) write(unit=lunit)this%dativar%b
8239if (associated(this%dativar%d)) write(unit=lunit)this%dativar%d
8240if (associated(this%dativar%c)) write(unit=lunit)this%dativar%c
8241
8242if (associated(this%datiattr%r)) write(unit=lunit)this%datiattr%r
8243if (associated(this%datiattr%i)) write(unit=lunit)this%datiattr%i
8244if (associated(this%datiattr%b)) write(unit=lunit)this%datiattr%b
8245if (associated(this%datiattr%d)) write(unit=lunit)this%datiattr%d
8246if (associated(this%datiattr%c)) write(unit=lunit)this%datiattr%c
8247
8248if (associated(this%dativarattr%r)) write(unit=lunit)this%dativarattr%r
8249if (associated(this%dativarattr%i)) write(unit=lunit)this%dativarattr%i
8250if (associated(this%dativarattr%b)) write(unit=lunit)this%dativarattr%b
8251if (associated(this%dativarattr%d)) write(unit=lunit)this%dativarattr%d
8252if (associated(this%dativarattr%c)) write(unit=lunit)this%dativarattr%c
8253
8254!! Volumi di valori e attributi per anagrafica e dati
8255
8256if (associated(this%volanar)) write(unit=lunit)this%volanar
8257if (associated(this%volanaattrr)) write(unit=lunit)this%volanaattrr
8258if (associated(this%voldatir)) write(unit=lunit)this%voldatir
8259if (associated(this%voldatiattrr)) write(unit=lunit)this%voldatiattrr
8260
8261if (associated(this%volanai)) write(unit=lunit)this%volanai
8262if (associated(this%volanaattri)) write(unit=lunit)this%volanaattri
8263if (associated(this%voldatii)) write(unit=lunit)this%voldatii
8264if (associated(this%voldatiattri)) write(unit=lunit)this%voldatiattri
8265
8266if (associated(this%volanab)) write(unit=lunit)this%volanab
8267if (associated(this%volanaattrb)) write(unit=lunit)this%volanaattrb
8268if (associated(this%voldatib)) write(unit=lunit)this%voldatib
8269if (associated(this%voldatiattrb)) write(unit=lunit)this%voldatiattrb
8270
8271if (associated(this%volanad)) write(unit=lunit)this%volanad
8272if (associated(this%volanaattrd)) write(unit=lunit)this%volanaattrd
8273if (associated(this%voldatid)) write(unit=lunit)this%voldatid
8274if (associated(this%voldatiattrd)) write(unit=lunit)this%voldatiattrd
8275
8276if (associated(this%volanac)) write(unit=lunit)this%volanac
8277if (associated(this%volanaattrc)) write(unit=lunit)this%volanaattrc
8278if (associated(this%voldatic)) write(unit=lunit)this%voldatic
8279if (associated(this%voldatiattrc)) write(unit=lunit)this%voldatiattrc
8280
8281if (.not. present(unit)) close(unit=lunit)
8282
8283end subroutine vol7d_write_on_file
8284
8285
8286!>\brief Lettura da file di un volume Vol7d.
8287!! Lettura da file unformatted di un intero volume Vol7d.
8288!! Questa subroutine comprende vol7d_alloc e vol7d_alloc_vol.
8289!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
8290!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
8291!! tali parametri saranno in output.
8292
8293
8294subroutine vol7d_read_from_file (this,unit,filename,description,tarray,filename_auto)
8295
8296TYPE(vol7d),INTENT(OUT) :: this !< Volume vol7d da leggere
8297integer,intent(inout),optional :: unit !< unità su cui è stato aperto un file; se =0 rielaborato internamente (default = elaborato internamente con getunit)
8298character(len=*),INTENT(in),optional :: filename !< nome del file eventualmente da aprire (default = (nome dell'eseguibile)//.v7d )
8299character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
8300character(len=*),INTENT(out),optional :: description !< descrizione del volume letto
8301integer,intent(out),optional :: tarray(8) !< vettore come definito da "date_and_time" della data di scrittura del volume
8302
8303
8304integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
8305 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
8306 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
8307 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
8308 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
8309 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
8310 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
8311
8312character(len=254) :: ldescription,lfilename,arg
8313integer :: ltarray(8),lunit,ios
8314logical :: opened,exist
8315
8316
8317call getarg(0,arg)
8318
8319if (.not. present(unit))then
8320 lunit=getunit()
8321else
8322 if (unit==0)then
8323 lunit=getunit()
8324 unit=lunit
8325 else
8326 lunit=unit
8327 end if
8328end if
8329
8330lfilename=trim(arg)//".v7d"
8331if (index(arg,'/',back=.true.) > 0) lfilename=lfilename(index(arg,'/',back=.true.)+1 : )
8332
8333if (present(filename))then
8334 if (filename /= "")then
8335 lfilename=filename
8336 end if
8337end if
8338
8339if (present(filename_auto))filename_auto=lfilename
8340
8341
8342inquire(unit=lunit,opened=opened)
8343IF (.NOT. opened) THEN
8344 inquire(file=lfilename,exist=exist)
8345 IF (.NOT.exist) THEN
8346 CALL l4f_log(l4f_fatal, &
8347 'in vol7d_read_from_file, file does not exists, cannot open')
8348 CALL raise_fatal_error()
8349 ENDIF
8350 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM', &
8351 status='OLD', action='READ')
8352 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
8353end if
8354
8355
8356call init(this)
8357read(unit=lunit,iostat=ios)ldescription
8358
8359if (ios < 0) then ! A negative value indicates that the End of File or End of Record
8360 call vol7d_alloc (this)
8361 call vol7d_alloc_vol (this)
8362 if (present(description))description=ldescription
8363 if (present(tarray))tarray=ltarray
8364 if (.not. present(unit)) close(unit=lunit)
8365end if
8366
8367read(unit=lunit)ltarray
8368
8369CALL l4f_log(l4f_info, 'Reading vol7d from file')
8370CALL l4f_log(l4f_info, 'description: '//trim(ldescription))
8371CALL l4f_log(l4f_info, 'written on '//trim(to_char(ltarray(1)))//' '// &
8372 trim(to_char(ltarray(2)))//' '//trim(to_char(ltarray(3))))
8373
8374if (present(description))description=ldescription
8375if (present(tarray))tarray=ltarray
8376
8377read(unit=lunit)&
8378 nana, ntime, ntimerange, nlevel, nnetwork, &
8379 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
8380 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
8381 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
8382 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
8383 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
8384 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
8385 this%time_definition
8386
8387call vol7d_alloc (this, &
8388 nana=nana, ntime=ntime, ntimerange=ntimerange, nlevel=nlevel, nnetwork=nnetwork,&
8389 ndativarr=ndativarr, ndativari=ndativari, ndativarb=ndativarb,&
8390 ndativard=ndativard, ndativarc=ndativarc,&
8391 ndatiattrr=ndatiattrr, ndatiattri=ndatiattri, ndatiattrb=ndatiattrb,&
8392 ndatiattrd=ndatiattrd, ndatiattrc=ndatiattrc,&
8393 ndativarattrr=ndativarattrr, ndativarattri=ndativarattri, ndativarattrb=ndativarattrb, &
8394 ndativarattrd=ndativarattrd, ndativarattrc=ndativarattrc,&
8395 nanavarr=nanavarr, nanavari=nanavari, nanavarb=nanavarb, &
8396 nanavard=nanavard, nanavarc=nanavarc,&
8397 nanaattrr=nanaattrr, nanaattri=nanaattri, nanaattrb=nanaattrb,&
8398 nanaattrd=nanaattrd, nanaattrc=nanaattrc,&
8399 nanavarattrr=nanavarattrr, nanavarattri=nanavarattri, nanavarattrb=nanavarattrb, &
8400 nanavarattrd=nanavarattrd, nanavarattrc=nanavarattrc)
8401
8402
8403if (associated(this%ana)) call read_unit(this%ana, lunit)
8404if (associated(this%time)) call read_unit(this%time, lunit)
8405if (associated(this%level)) read(unit=lunit)this%level
8406if (associated(this%timerange)) read(unit=lunit)this%timerange
8407if (associated(this%network)) read(unit=lunit)this%network
8408
8409if (associated(this%anavar%r)) read(unit=lunit)this%anavar%r
8410if (associated(this%anavar%i)) read(unit=lunit)this%anavar%i
8411if (associated(this%anavar%b)) read(unit=lunit)this%anavar%b
8412if (associated(this%anavar%d)) read(unit=lunit)this%anavar%d
8413if (associated(this%anavar%c)) read(unit=lunit)this%anavar%c
8414
8415if (associated(this%anaattr%r)) read(unit=lunit)this%anaattr%r
8416if (associated(this%anaattr%i)) read(unit=lunit)this%anaattr%i
8417if (associated(this%anaattr%b)) read(unit=lunit)this%anaattr%b
8418if (associated(this%anaattr%d)) read(unit=lunit)this%anaattr%d
8419if (associated(this%anaattr%c)) read(unit=lunit)this%anaattr%c
8420
8421if (associated(this%anavarattr%r)) read(unit=lunit)this%anavarattr%r
8422if (associated(this%anavarattr%i)) read(unit=lunit)this%anavarattr%i
8423if (associated(this%anavarattr%b)) read(unit=lunit)this%anavarattr%b
8424if (associated(this%anavarattr%d)) read(unit=lunit)this%anavarattr%d
8425if (associated(this%anavarattr%c)) read(unit=lunit)this%anavarattr%c
8426
8427if (associated(this%dativar%r)) read(unit=lunit)this%dativar%r
8428if (associated(this%dativar%i)) read(unit=lunit)this%dativar%i
8429if (associated(this%dativar%b)) read(unit=lunit)this%dativar%b
8430if (associated(this%dativar%d)) read(unit=lunit)this%dativar%d
8431if (associated(this%dativar%c)) read(unit=lunit)this%dativar%c
8432
8433if (associated(this%datiattr%r)) read(unit=lunit)this%datiattr%r
8434if (associated(this%datiattr%i)) read(unit=lunit)this%datiattr%i
8435if (associated(this%datiattr%b)) read(unit=lunit)this%datiattr%b
8436if (associated(this%datiattr%d)) read(unit=lunit)this%datiattr%d
8437if (associated(this%datiattr%c)) read(unit=lunit)this%datiattr%c
8438
8439if (associated(this%dativarattr%r)) read(unit=lunit)this%dativarattr%r
8440if (associated(this%dativarattr%i)) read(unit=lunit)this%dativarattr%i
8441if (associated(this%dativarattr%b)) read(unit=lunit)this%dativarattr%b
8442if (associated(this%dativarattr%d)) read(unit=lunit)this%dativarattr%d
8443if (associated(this%dativarattr%c)) read(unit=lunit)this%dativarattr%c
8444
8445call vol7d_alloc_vol (this)
8446
8447!! Volumi di valori e attributi per anagrafica e dati
8448
8449if (associated(this%volanar)) read(unit=lunit)this%volanar
8450if (associated(this%volanaattrr)) read(unit=lunit)this%volanaattrr
8451if (associated(this%voldatir)) read(unit=lunit)this%voldatir
8452if (associated(this%voldatiattrr)) read(unit=lunit)this%voldatiattrr
8453
8454if (associated(this%volanai)) read(unit=lunit)this%volanai
8455if (associated(this%volanaattri)) read(unit=lunit)this%volanaattri
8456if (associated(this%voldatii)) read(unit=lunit)this%voldatii
8457if (associated(this%voldatiattri)) read(unit=lunit)this%voldatiattri
8458
8459if (associated(this%volanab)) read(unit=lunit)this%volanab
8460if (associated(this%volanaattrb)) read(unit=lunit)this%volanaattrb
8461if (associated(this%voldatib)) read(unit=lunit)this%voldatib
8462if (associated(this%voldatiattrb)) read(unit=lunit)this%voldatiattrb
8463
8464if (associated(this%volanad)) read(unit=lunit)this%volanad
8465if (associated(this%volanaattrd)) read(unit=lunit)this%volanaattrd
8466if (associated(this%voldatid)) read(unit=lunit)this%voldatid
8467if (associated(this%voldatiattrd)) read(unit=lunit)this%voldatiattrd
8468
8469if (associated(this%volanac)) read(unit=lunit)this%volanac
8470if (associated(this%volanaattrc)) read(unit=lunit)this%volanaattrc
8471if (associated(this%voldatic)) read(unit=lunit)this%voldatic
8472if (associated(this%voldatiattrc)) read(unit=lunit)this%voldatiattrc
8473
8474if (.not. present(unit)) close(unit=lunit)
8475
8476end subroutine vol7d_read_from_file
8477
8478
8479! to double precision
8480elemental doubleprecision function doubledatd(voldat,var)
8481doubleprecision,intent(in) :: voldat
8482type(vol7d_var),intent(in) :: var
8483
8484doubledatd=voldat
8485
8486end function doubledatd
8487
8488
8489elemental doubleprecision function doubledatr(voldat,var)
8490real,intent(in) :: voldat
8491type(vol7d_var),intent(in) :: var
8492
8493if (c_e(voldat))then
8494 doubledatr=dble(voldat)
8495else
8496 doubledatr=dmiss
8497end if
8498
8499end function doubledatr
8500
8501
8502elemental doubleprecision function doubledati(voldat,var)
8503integer,intent(in) :: voldat
8504type(vol7d_var),intent(in) :: var
8505
8506if (c_e(voldat)) then
8507 if (c_e(var%scalefactor))then
8508 doubledati=dble(voldat)/10.d0**var%scalefactor
8509 else
8510 doubledati=dble(voldat)
8511 endif
8512else
8513 doubledati=dmiss
8514end if
8515
8516end function doubledati
8517
8518
8519elemental doubleprecision function doubledatb(voldat,var)
8520integer(kind=int_b),intent(in) :: voldat
8521type(vol7d_var),intent(in) :: var
8522
8523if (c_e(voldat)) then
8524 if (c_e(var%scalefactor))then
8525 doubledatb=dble(voldat)/10.d0**var%scalefactor
8526 else
8527 doubledatb=dble(voldat)
8528 endif
8529else
8530 doubledatb=dmiss
8531end if
8532
8533end function doubledatb
8534
8535
8536elemental doubleprecision function doubledatc(voldat,var)
8537CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
8538type(vol7d_var),intent(in) :: var
8539
8540doubledatc = c2d(voldat)
8541if (c_e(doubledatc) .and. c_e(var%scalefactor))then
8542 doubledatc=doubledatc/10.d0**var%scalefactor
8543end if
8544
8545end function doubledatc
8546
8547
8548! to integer
8549elemental integer function integerdatd(voldat,var)
8550doubleprecision,intent(in) :: voldat
8551type(vol7d_var),intent(in) :: var
8552
8553if (c_e(voldat))then
8554 if (c_e(var%scalefactor)) then
8555 integerdatd=nint(voldat*10d0**var%scalefactor)
8556 else
8557 integerdatd=nint(voldat)
8558 endif
8559else
8560 integerdatd=imiss
8561end if
8562
8563end function integerdatd
8564
8565
8566elemental integer function integerdatr(voldat,var)
8567real,intent(in) :: voldat
8568type(vol7d_var),intent(in) :: var
8569
8570if (c_e(voldat))then
8571 if (c_e(var%scalefactor)) then
8572 integerdatr=nint(voldat*10d0**var%scalefactor)
8573 else
8574 integerdatr=nint(voldat)
8575 endif
8576else
8577 integerdatr=imiss
8578end if
8579
8580end function integerdatr
8581
8582
8583elemental integer function integerdati(voldat,var)
8584integer,intent(in) :: voldat
8585type(vol7d_var),intent(in) :: var
8586
8587integerdati=voldat
8588
8589end function integerdati
8590
8591
8592elemental integer function integerdatb(voldat,var)
8593integer(kind=int_b),intent(in) :: voldat
8594type(vol7d_var),intent(in) :: var
8595
8596if (c_e(voldat))then
8597 integerdatb=voldat
8598else
8599 integerdatb=imiss
8600end if
8601
8602end function integerdatb
8603
8604
8605elemental integer function integerdatc(voldat,var)
8606CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
8607type(vol7d_var),intent(in) :: var
8608
8609integerdatc=c2i(voldat)
8610
8611end function integerdatc
8612
8613
8614! to real
8615elemental real function realdatd(voldat,var)
8616doubleprecision,intent(in) :: voldat
8617type(vol7d_var),intent(in) :: var
8618
8619if (c_e(voldat))then
8620 realdatd=real(voldat)
8621else
8622 realdatd=rmiss
8623end if
8624
8625end function realdatd
8626
8627
8628elemental real function realdatr(voldat,var)
8629real,intent(in) :: voldat
8630type(vol7d_var),intent(in) :: var
8631
8632realdatr=voldat
8633
8634end function realdatr
8635
8636
8637elemental real function realdati(voldat,var)
8638integer,intent(in) :: voldat
8639type(vol7d_var),intent(in) :: var
8640
8641if (c_e(voldat)) then
8642 if (c_e(var%scalefactor))then
8643 realdati=float(voldat)/10.**var%scalefactor
8644 else
8645 realdati=float(voldat)
8646 endif
8647else
8648 realdati=rmiss
8649end if
8650
8651end function realdati
8652
8653
8654elemental real function realdatb(voldat,var)
8655integer(kind=int_b),intent(in) :: voldat
8656type(vol7d_var),intent(in) :: var
8657
8658if (c_e(voldat)) then
8659 if (c_e(var%scalefactor))then
8660 realdatb=float(voldat)/10**var%scalefactor
8661 else
8662 realdatb=float(voldat)
8663 endif
8664else
8665 realdatb=rmiss
8666end if
8667
8668end function realdatb
8669
8670
8671elemental real function realdatc(voldat,var)
8672CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
8673type(vol7d_var),intent(in) :: var
8674
8675realdatc=c2r(voldat)
8676if (c_e(realdatc) .and. c_e(var%scalefactor))then
8677 realdatc=realdatc/10.**var%scalefactor
8678end if
8679
8680end function realdatc
8681
8682
8683!> Return an ana volume of a requested variable as real data.
8684!! It returns a 2-d array of the proper shape (ana x network) for the
8685!! ana variable requested, converted to real type. If the conversion
8686!! fails or if the variable is not contained in the ana volume,
8687!! missing data are returned.
8688FUNCTION realanavol(this, var) RESULT(vol)
8689TYPE(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
8690TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
8691REAL :: vol(SIZE(this%ana),size(this%network))
8692
8693CHARACTER(len=1) :: dtype
8694INTEGER :: indvar
8695
8696dtype = cmiss
8697indvar = index(this%anavar, var, type=dtype)
8698
8699IF (indvar > 0) THEN
8700 SELECT CASE (dtype)
8701 CASE("d")
8702 vol = realdat(this%volanad(:,indvar,:), var)
8703 CASE("r")
8704 vol = this%volanar(:,indvar,:)
8705 CASE("i")
8706 vol = realdat(this%volanai(:,indvar,:), var)
8707 CASE("b")
8708 vol = realdat(this%volanab(:,indvar,:), var)
8709 CASE("c")
8710 vol = realdat(this%volanac(:,indvar,:), var)
8711 CASE default
8712 vol = rmiss
8713 END SELECT
8714ELSE
8715 vol = rmiss
8716ENDIF
8717
8718END FUNCTION realanavol
8719
8720
8721!> Return an ana volume of a requested variable as integer data.
8722!! It returns a 2-d array of the proper shape (ana x network) for the
8723!! ana variable requested, converted to integer type. If the conversion
8724!! fails or if the variable is not contained in the ana volume,
8725!! missing data are returned.
8726FUNCTION integeranavol(this, var) RESULT(vol)
8727TYPE(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
8728TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
8729INTEGER :: vol(SIZE(this%ana),size(this%network))
8730
8731CHARACTER(len=1) :: dtype
8732INTEGER :: indvar
8733
8734dtype = cmiss
8735indvar = index(this%anavar, var, type=dtype)
8736
8737IF (indvar > 0) THEN
8738 SELECT CASE (dtype)
8739 CASE("d")
8740 vol = integerdat(this%volanad(:,indvar,:), var)
8741 CASE("r")
8742 vol = integerdat(this%volanar(:,indvar,:), var)
8743 CASE("i")
8744 vol = this%volanai(:,indvar,:)
8745 CASE("b")
8746 vol = integerdat(this%volanab(:,indvar,:), var)
8747 CASE("c")
8748 vol = integerdat(this%volanac(:,indvar,:), var)
8749 CASE default
8750 vol = imiss
8751 END SELECT
8752ELSE
8753 vol = imiss
8754ENDIF
8755
8756END FUNCTION integeranavol
8757
8758
8759!> Move data for all variables from one coordinate in the character volume to other.
8760!! Only not missing data will be copyed and all attributes will be moved together.
8761!! Usefull to colapse data spread in more indices (level or time or ....).
8762!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
8763!! to obtain a new vol7d with less data shape.
8764subroutine move_datac (v7d,&
8765 indana,indtime,indlevel,indtimerange,indnetwork,&
8766 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
8767
8768TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
8769
8770integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
8771integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
8772integer :: inddativar,inddativarattr
8773
8774
8775do inddativar=1,size(v7d%dativar%c)
8776
8777 if (c_e(v7d%voldatic(indana,indtime,indlevel,indtimerange,inddativar,indnetwork)) .and. &
8778 .not. c_e(v7d%voldatic(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
8779 ) then
8780
8781 ! dati
8782 v7d%voldatic &
8783 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
8784 v7d%voldatic &
8785 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
8786
8787
8788 ! attributi
8789 if (associated (v7d%dativarattr%i)) then
8790 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%c(inddativar))
8791 if (inddativarattr > 0 ) then
8792 v7d%voldatiattri &
8793 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8794 v7d%voldatiattri &
8795 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8796 end if
8797 end if
8798
8799 if (associated (v7d%dativarattr%r)) then
8800 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%c(inddativar))
8801 if (inddativarattr > 0 ) then
8802 v7d%voldatiattrr &
8803 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8804 v7d%voldatiattrr &
8805 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8806 end if
8807 end if
8808
8809 if (associated (v7d%dativarattr%d)) then
8810 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%c(inddativar))
8811 if (inddativarattr > 0 ) then
8812 v7d%voldatiattrd &
8813 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8814 v7d%voldatiattrd &
8815 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8816 end if
8817 end if
8818
8819 if (associated (v7d%dativarattr%b)) then
8820 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%c(inddativar))
8821 if (inddativarattr > 0 ) then
8822 v7d%voldatiattrb &
8823 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8824 v7d%voldatiattrb &
8825 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8826 end if
8827 end if
8828
8829 if (associated (v7d%dativarattr%c)) then
8830 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%c(inddativar))
8831 if (inddativarattr > 0 ) then
8832 v7d%voldatiattrc &
8833 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8834 v7d%voldatiattrc &
8835 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8836 end if
8837 end if
8838
8839 end if
8840
8841end do
8842
8843end subroutine move_datac
8844
8845!> Move data for all variables from one coordinate in the real volume to other.
8846!! Only not missing data will be copyed and all attributes will be moved together.
8847!! Usefull to colapse data spread in more indices (level or time or ....).
8848!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
8849!! to obtain a new vol7d with less data shape.
8850subroutine move_datar (v7d,&
8851 indana,indtime,indlevel,indtimerange,indnetwork,&
8852 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
8853
8854TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
8855
8856integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
8857integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
8858integer :: inddativar,inddativarattr
8859
8860
8861do inddativar=1,size(v7d%dativar%r)
8862
8863 if (c_e(v7d%voldatir(indana,indtime,indlevel,indtimerange,inddativar,indnetwork)) .and. &
8864 .not. c_e(v7d%voldatir(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
8865 ) then
8866
8867 ! dati
8868 v7d%voldatir &
8869 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
8870 v7d%voldatir &
8871 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
8872
8873
8874 ! attributi
8875 if (associated (v7d%dativarattr%i)) then
8876 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%r(inddativar))
8877 if (inddativarattr > 0 ) then
8878 v7d%voldatiattri &
8879 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8880 v7d%voldatiattri &
8881 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8882 end if
8883 end if
8884
8885 if (associated (v7d%dativarattr%r)) then
8886 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%r(inddativar))
8887 if (inddativarattr > 0 ) then
8888 v7d%voldatiattrr &
8889 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8890 v7d%voldatiattrr &
8891 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8892 end if
8893 end if
8894
8895 if (associated (v7d%dativarattr%d)) then
8896 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%r(inddativar))
8897 if (inddativarattr > 0 ) then
8898 v7d%voldatiattrd &
8899 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8900 v7d%voldatiattrd &
8901 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8902 end if
8903 end if
8904
8905 if (associated (v7d%dativarattr%b)) then
8906 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%r(inddativar))
8907 if (inddativarattr > 0 ) then
8908 v7d%voldatiattrb &
8909 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8910 v7d%voldatiattrb &
8911 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8912 end if
8913 end if
8914
8915 if (associated (v7d%dativarattr%c)) then
8916 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%r(inddativar))
8917 if (inddativarattr > 0 ) then
8918 v7d%voldatiattrc &
8919 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8920 v7d%voldatiattrc &
8921 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8922 end if
8923 end if
8924
8925 end if
8926
8927end do
8928
8929end subroutine move_datar
8930
8931
8932!> Reduce some dimensions (level and timerage) for semplification (rounding).
8933!! You can use this for simplify and use variables in computation like alchimia
8934!! where fields have to be on the same coordinate
8935!! It return real or character data only: if input is charcter data only it return character otherwise il return
8936!! all the data converted to real.
8937!! examples:
8938!! means in time for short periods and istantaneous values
8939!! 2 meter and surface levels
8940!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
8941!! will be taken (order is by icreasing var index).
8942!! You can use predefined values for classic semplification
8943!! almost_equal_levels and almost_equal_timeranges
8944!! The level or timerange in output will be defined by the first element of level and timerange list
8945subroutine v7d_rounding(v7din,v7dout,level,timerange,nostatproc)
8946type(vol7d),intent(inout) :: v7din !< input volume
8947type(vol7d),intent(out) :: v7dout !> output volume
8948type(vol7d_level),intent(in),optional :: level(:) !< almost equal level list
8949type(vol7d_timerange),intent(in),optional :: timerange(:) !< almost equal timerange list
8950!logical,intent(in),optional :: merge !< if there are data on more then one almost equal levels or timeranges
8951!! will be merged POINT BY POINT with priority for the fird data found ordered by icreasing var index
8952logical,intent(in),optional :: nostatproc !< do not take in account statistical processing code in timerange and P2
8953
8954integer :: nana,nlevel,ntime,ntimerange,nnetwork,nbin
8955integer :: iana,ilevel,itimerange,indl,indt,itime,inetwork
8956type(vol7d_level) :: roundlevel(size(v7din%level))
8957type(vol7d_timerange) :: roundtimerange(size(v7din%timerange))
8958type(vol7d) :: v7d_tmp
8959
8960
8961nbin=0
8962
8963if (associated(v7din%dativar%r)) nbin = nbin + size(v7din%dativar%r)
8964if (associated(v7din%dativar%i)) nbin = nbin + size(v7din%dativar%i)
8965if (associated(v7din%dativar%d)) nbin = nbin + size(v7din%dativar%d)
8966if (associated(v7din%dativar%b)) nbin = nbin + size(v7din%dativar%b)
8967
8968call init(v7d_tmp)
8969
8970roundlevel=v7din%level
8971
8972if (present(level))then
8973 do ilevel = 1, size(v7din%level)
8974 if ((any(v7din%level(ilevel) .almosteq. level))) then
8975 roundlevel(ilevel)=level(1)
8976 end if
8977 end do
8978end if
8979
8980roundtimerange=v7din%timerange
8981
8982if (present(timerange))then
8983 do itimerange = 1, size(v7din%timerange)
8984 if ((any(v7din%timerange(itimerange) .almosteq. timerange))) then
8985 roundtimerange(itimerange)=timerange(1)
8986 end if
8987 end do
8988end if
8989
8990!set istantaneous values everywere
8991!preserve p1 for forecast time
8992if (optio_log(nostatproc)) then
8993 roundtimerange(:)%timerange=254
8994 roundtimerange(:)%p2=0
8995end if
8996
8997
8998nana=size(v7din%ana)
8999nlevel=count_distinct(roundlevel,back=.true.)
9000ntime=size(v7din%time)
9001ntimerange=count_distinct(roundtimerange,back=.true.)
9002nnetwork=size(v7din%network)
9003
9004call init(v7d_tmp)
9005
9006if (nbin == 0) then
9007 call copy(v7din,v7d_tmp)
9008else
9009 call vol7d_convr(v7din,v7d_tmp)
9010end if
9011
9012v7d_tmp%level=roundlevel
9013v7d_tmp%timerange=roundtimerange
9014
9015do ilevel=1, size(v7d_tmp%level)
9016 indl=index(v7d_tmp%level,roundlevel(ilevel))
9017 do itimerange=1,size(v7d_tmp%timerange)
9018 indt=index(v7d_tmp%timerange,roundtimerange(itimerange))
9019
9020 if (indl /= ilevel .or. indt /= itimerange) then
9021
9022 do iana=1, nana
9023 do itime=1,ntime
9024 do inetwork=1,nnetwork
9025
9026 if (nbin > 0) then
9027 call move_datar (v7d_tmp,&
9028 iana,itime,ilevel,itimerange,inetwork,&
9029 iana,itime,indl,indt,inetwork)
9030 else
9031 call move_datac (v7d_tmp,&
9032 iana,itime,ilevel,itimerange,inetwork,&
9033 iana,itime,indl,indt,inetwork)
9034 end if
9035
9036 end do
9037 end do
9038 end do
9039
9040 end if
9041
9042 end do
9043end do
9044
9045! set to missing level and time > nlevel
9046do ilevel=nlevel+1,size(v7d_tmp%level)
9047 call init (v7d_tmp%level(ilevel))
9048end do
9049
9050do itimerange=ntimerange+1,size(v7d_tmp%timerange)
9051 call init (v7d_tmp%timerange(itimerange))
9052end do
9053
9054!copy with remove
9055CALL copy(v7d_tmp,v7dout,miss=.true.,lsort_timerange=.true.,lsort_level=.true.)
9056CALL delete(v7d_tmp)
9057
9058!call display(v7dout)
9059
9060end subroutine v7d_rounding
9061
9062
9063END MODULE vol7d_class
9064
9065!>\example esempio_qc_convert.f90
9066!!\brief Programma esempio semplice per la scrittura su file di un volume vol7d
9067!!
9068!!Programma che scrive su file un volume vol7d letto da una serie di file ASCII.
9069!!Questo programma scrive i dati del clima che poi verranno letti da modqccli
9070
9071
9072!>\example esempio_v7ddballe_move_and_collapse.f90
9073!!\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.