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