libsim Versione 8.0.0

◆ vol7d_get_voldatiattrb()

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

Crea una vista a dimensione ridotta di un volume di attributi di dati 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 :: vol2d(:,:)
...
CALL vol7d_get_voldatiattrb(v7d1, (/vol7d_ana_d, vol7d_time_d/), vol2d)
IF (ASSOCIATED(vol2d)) THEN
print*,vol2d
...
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_d ... vol7d_attr_d, ecc.
vol1dparray che in uscita conterrà la vista 1d
vol2dparray che in uscita conterrà la vista 2d
vol3dparray che in uscita conterrà la vista 3d
vol4dparray che in uscita conterrà la vista 4d
vol5dparray che in uscita conterrà la vista 5d
vol6dparray che in uscita conterrà la vista 6d
vol7dparray che in uscita conterrà la vista 7d

Definizione alla linea 5730 del file vol7d_class.F90.

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