libsim Versione 8.0.0

◆ realanavol()

real function, dimension(size(this%ana),size(this%network)) realanavol ( type(vol7d), intent(in) this,
type(vol7d_var), intent(in) var )

Return an ana volume of a requested variable as real data.

It returns a 2-d array of the proper shape (ana x network) for the ana variable requested, converted to real type. If the conversion fails or if the variable is not contained in the ana volume, missing data are returned.

Parametri
[in]thisthe vol7d object to query, the method vol7d_alloc_vol must have been called for it otherwise progam may abort
[in]varthe ana variable to be returned

Definizione alla linea 9111 del file vol7d_class.F90.

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