libsim Versione 8.0.0

◆ vol7d_get_volanab()

subroutine vol7d_get_volanab ( 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 )

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

Definizione alla linea 5569 del file vol7d_class.F90.

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