libsim Versione 8.0.0

◆ vol7d_get_volanac()

subroutine vol7d_get_volanac ( type(vol7d), intent(in) this,
integer, dimension(:), intent(in) dimlist,
character(len=vol7d_cdatalen), dimension(:), optional, pointer vol1dp,
character(len=vol7d_cdatalen), dimension(:,:), optional, pointer vol2dp,
character(len=vol7d_cdatalen), dimension(:,:,:), optional, pointer vol3dp )

Crea una vista a dimensione ridotta di un volume di anagrafica di tipo CHARACTER(len=vol7d_cdatalen).

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

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

Definizione alla linea 6245 del file vol7d_class.F90.

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