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