libsim Versione 8.0.0

◆ vol7d_get_voldatiattrd()

subroutine vol7d_get_voldatiattrd ( type(vol7d), intent(in) this,
integer, dimension(:), intent(in) dimlist,
double precision, dimension(:), optional, pointer vol1dp,
double precision, dimension(:,:), optional, pointer vol2dp,
double precision, dimension(:,:,:), optional, pointer vol3dp,
double precision, dimension(:,:,:,:), optional, pointer vol4dp,
double precision, dimension(:,:,:,:,:), optional, pointer vol5dp,
double precision, dimension(:,:,:,:,:,:), optional, pointer vol6dp,
double precision, dimension(:,:,:,:,:,:,:), optional, pointer vol7dp )

Crea una vista a dimensione ridotta di un volume di attributi di dati di tipo DOUBLE PRECISION.

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

DOUBLE PRECISION, POINTER :: vol2d(:,:)
...
CALL vol7d_get_voldatiattrd(v7d1, (/vol7d_ana_d, vol7d_time_d/), vol2d)
IF (ASSOCIATED(vol2d)) THEN
print*,vol2d
...
ENDIF
return
Parametri
[in]thisoggetto di cui creare la vista
[in]dimlistlista delle dimensioni da includere nella vista, attenzione tutte le dimensioni non degeneri (cioè con estensione >1) devono essere incluse nella lista; utilizzare le costanti vol7d_ana_d ... vol7d_attr_d, ecc.
vol1dparray che in uscita conterrà la vista 1d
vol2dparray che in uscita conterrà la vista 2d
vol3dparray che in uscita conterrà la vista 3d
vol4dparray che in uscita conterrà la vista 4d
vol5dparray che in uscita conterrà la vista 5d
vol6dparray che in uscita conterrà la vista 6d
vol7dparray che in uscita conterrà la vista 7d

Definizione alla linea 4378 del file vol7d_class.F90.

4380! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
4381! authors:
4382! Davide Cesari <dcesari@arpa.emr.it>
4383! Paolo Patruno <ppatruno@arpa.emr.it>
4384
4385! This program is free software; you can redistribute it and/or
4386! modify it under the terms of the GNU General Public License as
4387! published by the Free Software Foundation; either version 2 of
4388! the License, or (at your option) any later version.
4389
4390! This program is distributed in the hope that it will be useful,
4391! but WITHOUT ANY WARRANTY; without even the implied warranty of
4392! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4393! GNU General Public License for more details.
4394
4395! You should have received a copy of the GNU General Public License
4396! along with this program. If not, see <http://www.gnu.org/licenses/>.
4397#include "config.h"
4398
4399!> \defgroup vol7d Libsim package, vol7d library.
4400!! The libsim vol7d library contains classes for managing pointwise
4401!! data, tipically weather observations, and for their import from a
4402!! Db-All.e database or from a WMO BUFR file. In order to compile and
4403!! link programs using this library, you have to insert the required
4404!! \c USE statements in the program units involved, specify the
4405!! location of module files when compiling (tipically \c
4406!! -I/usr/lib/gfortran/modules or \c -I/usr/lib64/gfortran/modules or
4407!! \c -I/usr/include) and indicate the library name \c -lsim_vol7d
4408!! when linking, assuming that the library has been installed in a
4409!! default location.
4410
4411!> Classe per la gestione di un volume completo di dati osservati.
4412!! Questo modulo definisce gli oggetti e i metodi per gestire
4413!! volumi di dati meteorologici sparsi.
4414!! I volumi definiti sono principalmente di 4 categorie:
4415!! - volumi di anagrafica (vol7d::volanar & c.), hanno 3 dimensioni:
4416!! - anagrafica
4417!! - variabile di anagrafica
4418!! - rete
4419!! - volumi di attributi di anagrafica (vol7d::volanaattrr & c.), hanno 4 dimensioni:
4420!! - anagrafica
4421!! - variabile di anagrafica
4422!! - rete
4423!! - variabile di attributi delle variabili di anagrafica
4424!! - volumi di dati (vol7d::voldatir & c.), hanno 6 dimensioni:
4425!! - anagrafica
4426!! - tempo
4427!! - livello verticale
4428!! - intervallo temporale (timerange)
4429!! - variabile di dati
4430!! - rete
4431!! - volumi di attributi di dati (vol7d::voldatiattrr & c.), hanno 7 dimensioni:
4432!! - anagrafica
4433!! - tempo
4434!! - livello verticale
4435!! - intervallo temporale (timerange)
4436!! - variabile di dati
4437!! - rete
4438!! - variabile di attributi delle variabili di dati
4439!!
4440!! Tutte le variabili sono inoltre disponibil1 in 5 tipi diversi:
4441!! - reale (abbreviato r)
4442!! - doppia precisione (abbreviato d)
4443!! - intero (abbreviato i)
4444!! - byte (abbreviato b)
4445!! - carattere (abbreviato c)
4446!!
4447!! Per ognuna delle dimensioni possibili, incluse le variabili e gli
4448!! attributi con i loro diversi tipi,
4449!! è definito un cosiddetto "vettore di descrittori", con un
4450!! numero di elementi pari all'estensione della dimensione stessa,
4451!! che contiene le informazioni necessarie a descrivere
4452!! gli elementi di quella dimensione.
4453!! In realtà l'utente non dovrà generalmente occuparsi di costruire
4454!! un oggetto vol7d con le proprie mani ma utilizzerà nella maggior parte
4455!! dei casi i metodi di importazione preconfezionati che importano dati da
4456!! DB-All.e (vol7d_dballe_class) o dal DB Oracle del SIM (vol7d_oraclesim_class).
4457!!
4458!!
4459!! Il programma esempio_v7d.f90 contiene un esempio elementare di uso
4460!! della classe vol7d:
4461!! \include esempio_v7d.f90
4462!!
4463!! \ingroup vol7d
4464MODULE vol7d_class
4465USE kinds
4469USE log4fortran
4470USE err_handling
4471USE io_units
4478IMPLICIT NONE
4479
4480
4481INTEGER, PARAMETER :: vol7d_maxdim_a = 3, vol7d_maxdim_aa = 4, &
4482 vol7d_maxdim_d = 6, vol7d_maxdim_ad = 7
4483
4484INTEGER, PARAMETER :: vol7d_ana_a=1 !< indice della dimensione "anagrafica" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
4485INTEGER, PARAMETER :: vol7d_var_a=2 !< indice della dimensione "variabile" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
4486INTEGER, PARAMETER :: vol7d_network_a=3 !< indice della dimensione "rete" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
4487INTEGER, PARAMETER :: vol7d_attr_a=4 !< indice della dimensione "attributo" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
4488INTEGER, PARAMETER :: vol7d_ana_d=1 !< indice della dimensione "anagrafica" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
4489INTEGER, PARAMETER :: vol7d_time_d=2 !< indice della dimensione "tempo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
4490INTEGER, PARAMETER :: vol7d_level_d=3 !< indice della dimensione "livello verticale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
4491INTEGER, PARAMETER :: vol7d_timerange_d=4 !< indice della dimensione "intervallo temporale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
4492INTEGER, PARAMETER :: vol7d_var_d=5 !< indice della dimensione "variabile" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
4493INTEGER, PARAMETER :: vol7d_network_d=6 !< indice della dimensione "rete" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
4494INTEGER, PARAMETER :: vol7d_attr_d=7 !< indice della dimensione "attributo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
4495INTEGER, PARAMETER :: vol7d_cdatalen=32
4496
4497TYPE vol7d_varmap
4498 INTEGER :: r, d, i, b, c
4499END TYPE vol7d_varmap
4500
4501!> Definisce un oggetto contenente i volumi anagrafica e dati e tutti
4502!! i descrittori delle loro dimensioni.
4503TYPE vol7d
4504!> vettore descrittore della dimensione anagrafica
4505 TYPE(vol7d_ana),POINTER :: ana(:)
4506!> vettore descrittore della dimensione tempo
4507 TYPE(datetime),POINTER :: time(:)
4508!> vettore descrittore della dimensione livello verticale
4509 TYPE(vol7d_level),POINTER :: level(:)
4510!> vettore descrittore della dimensione intervallo temporale (timerange)
4511 TYPE(vol7d_timerange),POINTER :: timerange(:)
4512!> vettore descrittore della dimensione rete
4513 TYPE(vol7d_network),POINTER :: network(:)
4514!> vettore descrittore della dimensione variabile di anagrafica
4515 TYPE(vol7d_varvect) :: anavar
4516!> vettore descrittore della dimensione attributo delle variabili di anagrafica
4517 TYPE(vol7d_varvect) :: anaattr
4518!> vettore descrittore della dimensione variabile di anagrafica che ha tali attributi
4519 TYPE(vol7d_varvect) :: anavarattr
4520!> vettore descrittore della dimensione variabile di dati
4521 TYPE(vol7d_varvect) :: dativar
4522!> vettore descrittore della dimensione attributo delle variabili di dati
4523 TYPE(vol7d_varvect) :: datiattr
4524!> vettore descrittore della dimensione variabile di dati che ha tali attributi
4525 TYPE(vol7d_varvect) :: dativarattr
4526
4527!> volume di anagrafica a valori reali
4528 REAL,POINTER :: volanar(:,:,:)
4529!> volume di anagrafica a valori a doppia precisione
4530 DOUBLE PRECISION,POINTER :: volanad(:,:,:)
4531!> volume di anagrafica a valori interi
4532 INTEGER,POINTER :: volanai(:,:,:)
4533!> volume di anagrafica a valori byte
4534 INTEGER(kind=int_b),POINTER :: volanab(:,:,:)
4535!> volume di anagrafica a valori carattere
4536 CHARACTER(len=vol7d_cdatalen),POINTER :: volanac(:,:,:)
4537
4538!> volume di attributi di anagrafica a valori reali
4539 REAL,POINTER :: volanaattrr(:,:,:,:)
4540!> volume di attributi di anagrafica a valori a doppia precisione
4541 DOUBLE PRECISION,POINTER :: volanaattrd(:,:,:,:)
4542!> volume di attributi di anagrafica a valori interi
4543 INTEGER,POINTER :: volanaattri(:,:,:,:)
4544!> volume di attributi di anagrafica a valori byte
4545 INTEGER(kind=int_b),POINTER :: volanaattrb(:,:,:,:)
4546!> volume di attributi di anagrafica a valori carattere
4547 CHARACTER(len=vol7d_cdatalen),POINTER :: volanaattrc(:,:,:,:)
4548
4549!> volume di dati a valori reali
4550 REAL,POINTER :: voldatir(:,:,:,:,:,:) ! sono i dati
4551!> volume di dati a valori a doppia precisione
4552 DOUBLE PRECISION,POINTER :: voldatid(:,:,:,:,:,:)
4553!> volume di dati a valori interi
4554 INTEGER,POINTER :: voldatii(:,:,:,:,:,:)
4555!> volume di dati a valori byte
4556 INTEGER(kind=int_b),POINTER :: voldatib(:,:,:,:,:,:)
4557!> volume di dati a valori carattere
4558 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatic(:,:,:,:,:,:)
4559
4560!> volume di attributi di dati a valori reali
4561 REAL,POINTER :: voldatiattrr(:,:,:,:,:,:,:)
4562!> volume di attributi di dati a valori a doppia precisione
4563 DOUBLE PRECISION,POINTER :: voldatiattrd(:,:,:,:,:,:,:)
4564!> volume di attributi di dati a valori interi
4565 INTEGER,POINTER :: voldatiattri(:,:,:,:,:,:,:)
4566!> volume di attributi di dati a valori byte
4567 INTEGER(kind=int_b),POINTER :: voldatiattrb(:,:,:,:,:,:,:)
4568!> volume di attributi di dati a valori carattere
4569 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatiattrc(:,:,:,:,:,:,:)
4570
4571!> time definition; 0=time is reference time, 1=time is validity time
4572 integer :: time_definition
4573
4574END TYPE vol7d
4575
4576!> Costruttore per la classe vol7d.
4577!! Deve essere richiamato
4578!! per tutti gli oggetti di questo tipo definiti in un programma.
4579INTERFACE init
4580 MODULE PROCEDURE vol7d_init
4581END INTERFACE
4582
4583!> Distruttore per la classe vol7d.
4584INTERFACE delete
4585 MODULE PROCEDURE vol7d_delete
4586END INTERFACE
4587
4588!> Scrittura su file.
4589INTERFACE export
4590 MODULE PROCEDURE vol7d_write_on_file
4591END INTERFACE
4592
4593!> Lettura da file.
4594INTERFACE import
4595 MODULE PROCEDURE vol7d_read_from_file
4596END INTERFACE
4597
4598!>Print object
4599INTERFACE display
4600 MODULE PROCEDURE vol7d_display, dat_display, dat_vect_display
4601END INTERFACE
4602
4603!>Represent data in a pretty string
4604INTERFACE to_char
4605 MODULE PROCEDURE to_char_dat
4606END INTERFACE
4607
4608!>doubleprecision data conversion
4609INTERFACE doubledat
4610 MODULE PROCEDURE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
4611END INTERFACE
4612
4613!>real data conversion
4614INTERFACE realdat
4615 MODULE PROCEDURE realdatd,realdatr,realdati,realdatb,realdatc
4616END INTERFACE
4617
4618!>integer data conversion
4619INTERFACE integerdat
4620 MODULE PROCEDURE integerdatd,integerdatr,integerdati,integerdatb,integerdatc
4621END INTERFACE
4622
4623!>copy object
4624INTERFACE copy
4625 MODULE PROCEDURE vol7d_copy
4626END INTERFACE
4627
4628!> Test for a missing volume
4629INTERFACE c_e
4630 MODULE PROCEDURE vol7d_c_e
4631END INTERFACE
4632
4633!> Check for problems
4634!! return 0 if all check passed
4635!! print diagnostics with log4f
4636INTERFACE check
4637 MODULE PROCEDURE vol7d_check
4638END INTERFACE
4639
4640!> Reduce some dimensions (level and timerage) for semplification (rounding).
4641!! You can use this for simplify and use variables in computation like alchimia
4642!! where fields have to be on the same coordinate
4643!! It return real or character data only: if input is charcter data only it return character otherwise il return
4644!! all the data converted to real.
4645!! examples:
4646!! means in time for short periods and istantaneous values
4647!! 2 meter and surface levels
4648!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
4649!! will be taken (order is by icreasing var index).
4650!! You can use predefined values for classic semplification
4651!! almost_equal_levels and almost_equal_timeranges
4652!! The level or timerange in output will be defined by the first element of level and timerange list
4653INTERFACE rounding
4654 MODULE PROCEDURE v7d_rounding
4655END INTERFACE
4656
4657!!$INTERFACE get_volana
4658!!$ MODULE PROCEDURE vol7d_get_volanar, vol7d_get_volanad, vol7d_get_volanai, &
4659!!$ vol7d_get_volanab, vol7d_get_volanac
4660!!$END INTERFACE
4661!!$
4662!!$INTERFACE get_voldati
4663!!$ MODULE PROCEDURE vol7d_get_voldatir, vol7d_get_voldatid, vol7d_get_voldatii, &
4664!!$ vol7d_get_voldatib, vol7d_get_voldatic
4665!!$END INTERFACE
4666!!$
4667!!$INTERFACE get_volanaattr
4668!!$ MODULE PROCEDURE vol7d_get_volanaattrr, vol7d_get_volanaattrd, &
4669!!$ vol7d_get_volanaattri, vol7d_get_volanaattrb, vol7d_get_volanaattrc
4670!!$END INTERFACE
4671!!$
4672!!$INTERFACE get_voldatiattr
4673!!$ MODULE PROCEDURE vol7d_get_voldatiattrr, vol7d_get_voldatiattrd, &
4674!!$ vol7d_get_voldatiattri, vol7d_get_voldatiattrb, vol7d_get_voldatiattrc
4675!!$END INTERFACE
4676
4677PRIVATE vol7d_get_volr, vol7d_get_vold, vol7d_get_voli, vol7d_get_volb, &
4678 vol7d_get_volc, &
4679 volptr1dr, volptr2dr, volptr3dr, volptr4dr, volptr5dr, volptr6dr, volptr7dr, &
4680 volptr1dd, volptr2dd, volptr3dd, volptr4dd, volptr5dd, volptr6dd, volptr7dd, &
4681 volptr1di, volptr2di, volptr3di, volptr4di, volptr5di, volptr6di, volptr7di, &
4682 volptr1db, volptr2db, volptr3db, volptr4db, volptr5db, volptr6db, volptr7db, &
4683 volptr1dc, volptr2dc, volptr3dc, volptr4dc, volptr5dc, volptr6dc, volptr7dc, &
4684 vol7d_nullifyr, vol7d_nullifyd, vol7d_nullifyi, vol7d_nullifyb, vol7d_nullifyc, &
4685 vol7d_init, vol7d_delete, vol7d_write_on_file, vol7d_read_from_file, &
4686 vol7d_check_alloc_ana, vol7d_force_alloc_ana, &
4687 vol7d_check_alloc_dati, vol7d_force_alloc_dati, vol7d_force_alloc, &
4688 vol7d_display, dat_display, dat_vect_display, &
4689 to_char_dat, vol7d_check
4690
4691PRIVATE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
4692
4693PRIVATE vol7d_c_e
4694
4695CONTAINS
4696
4697
4698!> Inizializza un oggetto di tipo vol7d.
4699!! Non riceve alcun parametro tranne l'oggetto stesso. Attenzione, è necessario
4700!! comunque chiamare sempre il costruttore per evitare di avere dei puntatori in
4701!! uno stato indefinito.
4702SUBROUTINE vol7d_init(this,time_definition)
4703TYPE(vol7d),intent(out) :: this !< oggetto da inizializzare
4704INTEGER,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)
4705
4706CALL init(this%anavar)
4707CALL init(this%anaattr)
4708CALL init(this%anavarattr)
4709CALL init(this%dativar)
4710CALL init(this%datiattr)
4711CALL init(this%dativarattr)
4712
4713NULLIFY(this%ana, this%time, this%level, this%timerange, this%network)
4714
4715NULLIFY(this%volanar, this%volanaattrr, this%voldatir, this%voldatiattrr)
4716NULLIFY(this%volanad, this%volanaattrd, this%voldatid, this%voldatiattrd)
4717NULLIFY(this%volanai, this%volanaattri, this%voldatii, this%voldatiattri)
4718NULLIFY(this%volanab, this%volanaattrb, this%voldatib, this%voldatiattrb)
4719NULLIFY(this%volanac, this%volanaattrc, this%voldatic, this%voldatiattrc)
4720
4721if(present(time_definition)) then
4722 this%time_definition=time_definition
4723else
4724 this%time_definition=1 !default to validity time
4725end if
4726
4727END SUBROUTINE vol7d_init
4728
4729
4730!> Distrugge l'oggetto in maniera pulita, liberando l'eventuale memoria
4731!! dinamicamente allocata. Permette di distruggere la sola parte di dati
4732!! mantenendo l'anagrafica.
4733ELEMENTAL SUBROUTINE vol7d_delete(this, dataonly)
4734TYPE(vol7d),intent(inout) :: this !< oggetto da distruggere
4735LOGICAL, INTENT(in), OPTIONAL :: dataonly !< dealloca solo i dati, tenendo l'anagrafica, (default \c .FALSE.)
4736
4737
4738IF (.NOT. optio_log(dataonly)) THEN
4739 IF (ASSOCIATED(this%volanar)) DEALLOCATE(this%volanar)
4740 IF (ASSOCIATED(this%volanad)) DEALLOCATE(this%volanad)
4741 IF (ASSOCIATED(this%volanai)) DEALLOCATE(this%volanai)
4742 IF (ASSOCIATED(this%volanab)) DEALLOCATE(this%volanab)
4743 IF (ASSOCIATED(this%volanac)) DEALLOCATE(this%volanac)
4744 IF (ASSOCIATED(this%volanaattrr)) DEALLOCATE(this%volanaattrr)
4745 IF (ASSOCIATED(this%volanaattrd)) DEALLOCATE(this%volanaattrd)
4746 IF (ASSOCIATED(this%volanaattri)) DEALLOCATE(this%volanaattri)
4747 IF (ASSOCIATED(this%volanaattrb)) DEALLOCATE(this%volanaattrb)
4748 IF (ASSOCIATED(this%volanaattrc)) DEALLOCATE(this%volanaattrc)
4749ENDIF
4750IF (ASSOCIATED(this%voldatir)) DEALLOCATE(this%voldatir)
4751IF (ASSOCIATED(this%voldatid)) DEALLOCATE(this%voldatid)
4752IF (ASSOCIATED(this%voldatii)) DEALLOCATE(this%voldatii)
4753IF (ASSOCIATED(this%voldatib)) DEALLOCATE(this%voldatib)
4754IF (ASSOCIATED(this%voldatic)) DEALLOCATE(this%voldatic)
4755IF (ASSOCIATED(this%voldatiattrr)) DEALLOCATE(this%voldatiattrr)
4756IF (ASSOCIATED(this%voldatiattrd)) DEALLOCATE(this%voldatiattrd)
4757IF (ASSOCIATED(this%voldatiattri)) DEALLOCATE(this%voldatiattri)
4758IF (ASSOCIATED(this%voldatiattrb)) DEALLOCATE(this%voldatiattrb)
4759IF (ASSOCIATED(this%voldatiattrc)) DEALLOCATE(this%voldatiattrc)
4760
4761IF (.NOT. optio_log(dataonly)) THEN
4762 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
4763 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
4764ENDIF
4765IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
4766IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
4767IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
4768
4769IF (.NOT. optio_log(dataonly)) THEN
4770 CALL delete(this%anavar)
4771 CALL delete(this%anaattr)
4772 CALL delete(this%anavarattr)
4773ENDIF
4774CALL delete(this%dativar)
4775CALL delete(this%datiattr)
4776CALL delete(this%dativarattr)
4777
4778END SUBROUTINE vol7d_delete
4779
4780
4781
4782integer function vol7d_check(this)
4783TYPE(vol7d),intent(in) :: this !< object to check
4784integer :: i,j,k,l,m,n
4785
4786vol7d_check=0
4787
4788if (associated(this%voldatii)) then
4789do i = 1,size(this%voldatii,1)
4790 do j = 1,size(this%voldatii,2)
4791 do k = 1,size(this%voldatii,3)
4792 do l = 1,size(this%voldatii,4)
4793 do m = 1,size(this%voldatii,5)
4794 do n = 1,size(this%voldatii,6)
4795 if (this%voldatii(i,j,k,l,m,n) /= this%voldatii(i,j,k,l,m,n) ) then
4796 CALL l4f_log(l4f_warn,"check: abnormal value at voldatii("&
4797 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
4798 vol7d_check=1
4799 end if
4800 end do
4801 end do
4802 end do
4803 end do
4804 end do
4805end do
4806end if
4807
4808
4809if (associated(this%voldatir)) then
4810do i = 1,size(this%voldatir,1)
4811 do j = 1,size(this%voldatir,2)
4812 do k = 1,size(this%voldatir,3)
4813 do l = 1,size(this%voldatir,4)
4814 do m = 1,size(this%voldatir,5)
4815 do n = 1,size(this%voldatir,6)
4816 if (this%voldatir(i,j,k,l,m,n) /= this%voldatir(i,j,k,l,m,n) ) then
4817 CALL l4f_log(l4f_warn,"check: abnormal value at voldatir("&
4818 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
4819 vol7d_check=2
4820 end if
4821 end do
4822 end do
4823 end do
4824 end do
4825 end do
4826end do
4827end if
4828
4829if (associated(this%voldatid)) then
4830do i = 1,size(this%voldatid,1)
4831 do j = 1,size(this%voldatid,2)
4832 do k = 1,size(this%voldatid,3)
4833 do l = 1,size(this%voldatid,4)
4834 do m = 1,size(this%voldatid,5)
4835 do n = 1,size(this%voldatid,6)
4836 if (this%voldatid(i,j,k,l,m,n) /= this%voldatid(i,j,k,l,m,n) ) then
4837 CALL l4f_log(l4f_warn,"check: abnormal value at voldatid("&
4838 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
4839 vol7d_check=3
4840 end if
4841 end do
4842 end do
4843 end do
4844 end do
4845 end do
4846end do
4847end if
4848
4849if (associated(this%voldatib)) then
4850do i = 1,size(this%voldatib,1)
4851 do j = 1,size(this%voldatib,2)
4852 do k = 1,size(this%voldatib,3)
4853 do l = 1,size(this%voldatib,4)
4854 do m = 1,size(this%voldatib,5)
4855 do n = 1,size(this%voldatib,6)
4856 if (this%voldatib(i,j,k,l,m,n) /= this%voldatib(i,j,k,l,m,n) ) then
4857 CALL l4f_log(l4f_warn,"check: abnormal value at voldatib("&
4858 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
4859 vol7d_check=4
4860 end if
4861 end do
4862 end do
4863 end do
4864 end do
4865 end do
4866end do
4867end if
4868
4869end function vol7d_check
4870
4871
4872
4873!TODO da completare ! aborta se i volumi sono allocati a dimensione 0
4874!> stampa a video una sintesi del contenuto
4875SUBROUTINE vol7d_display(this)
4876TYPE(vol7d),intent(in) :: this !< oggetto da visualizzare
4877integer :: i
4878
4879REAL :: rdat
4880DOUBLE PRECISION :: ddat
4881INTEGER :: idat
4882INTEGER(kind=int_b) :: bdat
4883CHARACTER(len=vol7d_cdatalen) :: cdat
4884
4885
4886print*,"<<<<<<<<<<<<<<<<<<< vol7d object >>>>>>>>>>>>>>>>>>>>"
4887if (this%time_definition == 0) then
4888 print*,"TIME DEFINITION: time is reference time"
4889else if (this%time_definition == 1) then
4890 print*,"TIME DEFINITION: time is validity time"
4891else if (this%time_definition == 2) then
4892 print*,"TIME DEFINITION: time is validity time, forecast range forced to 0"
4893else
4894 print*,"Time definition has a wrong walue:", this%time_definition
4895end if
4896
4897IF (ASSOCIATED(this%network))then
4898 print*,"---- network vector ----"
4899 print*,"elements=",size(this%network)
4900 do i=1, size(this%network)
4901 call display(this%network(i))
4902 end do
4903end IF
4904
4905IF (ASSOCIATED(this%ana))then
4906 print*,"---- ana vector ----"
4907 print*,"elements=",size(this%ana)
4908 do i=1, size(this%ana)
4909 call display(this%ana(i))
4910 end do
4911end IF
4912
4913IF (ASSOCIATED(this%time))then
4914 print*,"---- time vector ----"
4915 print*,"elements=",size(this%time)
4916 do i=1, size(this%time)
4917 call display(this%time(i))
4918 end do
4919end if
4920
4921IF (ASSOCIATED(this%level)) then
4922 print*,"---- level vector ----"
4923 print*,"elements=",size(this%level)
4924 do i =1,size(this%level)
4925 call display(this%level(i))
4926 end do
4927end if
4928
4929IF (ASSOCIATED(this%timerange))then
4930 print*,"---- timerange vector ----"
4931 print*,"elements=",size(this%timerange)
4932 do i =1,size(this%timerange)
4933 call display(this%timerange(i))
4934 end do
4935end if
4936
4937
4938print*,"---- ana vector ----"
4939print*,""
4940print*,"->>>>>>>>> anavar -"
4941call display(this%anavar)
4942print*,""
4943print*,"->>>>>>>>> anaattr -"
4944call display(this%anaattr)
4945print*,""
4946print*,"->>>>>>>>> anavarattr -"
4947call display(this%anavarattr)
4948
4949print*,"-- ana data section (first point) --"
4950
4951idat=imiss
4952rdat=rmiss
4953ddat=dmiss
4954bdat=ibmiss
4955cdat=cmiss
4956
4957!ntime = MIN(SIZE(this%time),nprint)
4958!ntimerange = MIN(SIZE(this%timerange),nprint)
4959!nlevel = MIN(SIZE(this%level),nprint)
4960!nnetwork = MIN(SIZE(this%network),nprint)
4961!nana = MIN(SIZE(this%ana),nprint)
4962
4963IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0) THEN
4964if (associated(this%volanai)) then
4965 do i=1,size(this%anavar%i)
4966 idat=this%volanai(1,i,1)
4967 if (associated(this%anavar%i)) call display(this%anavar%i(i),idat,rdat,ddat,bdat,cdat)
4968 end do
4969end if
4970idat=imiss
4971
4972if (associated(this%volanar)) then
4973 do i=1,size(this%anavar%r)
4974 rdat=this%volanar(1,i,1)
4975 if (associated(this%anavar%r)) call display(this%anavar%r(i),idat,rdat,ddat,bdat,cdat)
4976 end do
4977end if
4978rdat=rmiss
4979
4980if (associated(this%volanad)) then
4981 do i=1,size(this%anavar%d)
4982 ddat=this%volanad(1,i,1)
4983 if (associated(this%anavar%d)) call display(this%anavar%d(i),idat,rdat,ddat,bdat,cdat)
4984 end do
4985end if
4986ddat=dmiss
4987
4988if (associated(this%volanab)) then
4989 do i=1,size(this%anavar%b)
4990 bdat=this%volanab(1,i,1)
4991 if (associated(this%anavar%b)) call display(this%anavar%b(i),idat,rdat,ddat,bdat,cdat)
4992 end do
4993end if
4994bdat=ibmiss
4995
4996if (associated(this%volanac)) then
4997 do i=1,size(this%anavar%c)
4998 cdat=this%volanac(1,i,1)
4999 if (associated(this%anavar%c)) call display(this%anavar%c(i),idat,rdat,ddat,bdat,cdat)
5000 end do
5001end if
5002cdat=cmiss
5003ENDIF
5004
5005print*,"---- data vector ----"
5006print*,""
5007print*,"->>>>>>>>> dativar -"
5008call display(this%dativar)
5009print*,""
5010print*,"->>>>>>>>> datiattr -"
5011call display(this%datiattr)
5012print*,""
5013print*,"->>>>>>>>> dativarattr -"
5014call display(this%dativarattr)
5015
5016print*,"-- data data section (first point) --"
5017
5018idat=imiss
5019rdat=rmiss
5020ddat=dmiss
5021bdat=ibmiss
5022cdat=cmiss
5023
5024IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0 .AND. size(this%time) > 0 &
5025 .AND. size(this%level) > 0 .AND. size(this%timerange) > 0) THEN
5026if (associated(this%voldatii)) then
5027 do i=1,size(this%dativar%i)
5028 idat=this%voldatii(1,1,1,1,i,1)
5029 if (associated(this%dativar%i)) call display(this%dativar%i(i),idat,rdat,ddat,bdat,cdat)
5030 end do
5031end if
5032idat=imiss
5033
5034if (associated(this%voldatir)) then
5035 do i=1,size(this%dativar%r)
5036 rdat=this%voldatir(1,1,1,1,i,1)
5037 if (associated(this%dativar%r)) call display(this%dativar%r(i),idat,rdat,ddat,bdat,cdat)
5038 end do
5039end if
5040rdat=rmiss
5041
5042if (associated(this%voldatid)) then
5043 do i=1,size(this%dativar%d)
5044 ddat=this%voldatid(1,1,1,1,i,1)
5045 if (associated(this%dativar%d)) call display(this%dativar%d(i),idat,rdat,ddat,bdat,cdat)
5046 end do
5047end if
5048ddat=dmiss
5049
5050if (associated(this%voldatib)) then
5051 do i=1,size(this%dativar%b)
5052 bdat=this%voldatib(1,1,1,1,i,1)
5053 if (associated(this%dativar%b)) call display(this%dativar%b(i),idat,rdat,ddat,bdat,cdat)
5054 end do
5055end if
5056bdat=ibmiss
5057
5058if (associated(this%voldatic)) then
5059 do i=1,size(this%dativar%c)
5060 cdat=this%voldatic(1,1,1,1,i,1)
5061 if (associated(this%dativar%c)) call display(this%dativar%c(i),idat,rdat,ddat,bdat,cdat)
5062 end do
5063end if
5064cdat=cmiss
5065ENDIF
5066
5067print*,"<<<<<<<<<<<<<<<<<<< END vol7d object >>>>>>>>>>>>>>>>>>>>"
5068
5069END SUBROUTINE vol7d_display
5070
5071
5072!> stampa a video una sintesi del contenuto
5073SUBROUTINE dat_display(this,idat,rdat,ddat,bdat,cdat)
5074TYPE(vol7d_var),intent(in) :: this !< oggetto da visualizzare
5075!> real
5076REAL :: rdat
5077!> double precision
5078DOUBLE PRECISION :: ddat
5079!> integer
5080INTEGER :: idat
5081!> byte
5082INTEGER(kind=int_b) :: bdat
5083!> character
5084CHARACTER(len=*) :: cdat
5085
5086print *, to_char_dat(this,idat,rdat,ddat,bdat,cdat)
5087
5088end SUBROUTINE dat_display
5089
5090!> stampa a video una sintesi del contenuto
5091SUBROUTINE dat_vect_display(this,idat,rdat,ddat,bdat,cdat)
5092
5093TYPE(vol7d_var),intent(in) :: this(:) !< oggetto da visualizzare
5094!> real
5095REAL :: rdat(:)
5096!> double precision
5097DOUBLE PRECISION :: ddat(:)
5098!> integer
5099INTEGER :: idat(:)
5100!> byte
5101INTEGER(kind=int_b) :: bdat(:)
5102!> character
5103CHARACTER(len=*):: cdat(:)
5104
5105integer :: i
5106
5107do i =1,size(this)
5108 call display(this(i),idat(i),rdat(i),ddat(i),bdat(i),cdat(i))
5109end do
5110
5111end SUBROUTINE dat_vect_display
5112
5113
5114FUNCTION to_char_dat(this,idat,rdat,ddat,bdat,cdat)
5115#ifdef HAVE_DBALLE
5116USE dballef
5117#endif
5118TYPE(vol7d_var),INTENT(in) :: this
5119!> real
5120REAL :: rdat
5121!> double precision
5122DOUBLE PRECISION :: ddat
5123!> integer
5124INTEGER :: idat
5125!> byte
5126INTEGER(kind=int_b) :: bdat
5127!> character
5128CHARACTER(len=*) :: cdat
5129CHARACTER(len=80) :: to_char_dat
5130
5131CHARACTER(len=LEN(to_char_dat)) :: to_char_tmp
5132
5133
5134#ifdef HAVE_DBALLE
5135INTEGER :: handle, ier
5136
5137handle = 0
5138to_char_dat="VALUE: "
5139
5140if (c_e(idat)) to_char_dat=trim(to_char_dat)//" ;int> "//trim(to_char(idat))
5141if (c_e(rdat)) to_char_dat=trim(to_char_dat)//" ;real> "//trim(to_char(rdat))
5142if (c_e(ddat)) to_char_dat=trim(to_char_dat)//" ;double> "//trim(to_char(ddat))
5143if (c_e(bdat)) to_char_dat=trim(to_char_dat)//" ;byte> "//trim(to_char(bdat))
5144
5145if ( c_e(cdat))then
5146 ier = idba_messaggi(handle,"/dev/null", "w", "BUFR")
5147 ier = idba_spiegab(handle,this%btable,cdat,to_char_tmp)
5148 ier = idba_fatto(handle)
5149 to_char_dat=trim(to_char_dat)//" ;char> "//trim(to_char_tmp)
5150endif
5151
5152#else
5153
5154to_char_dat="VALUE: "
5155if (c_e(idat)) to_char_dat=trim(to_char_dat)//" ;int> "//trim(to_char(idat))
5156if (c_e(rdat)) to_char_dat=trim(to_char_dat)//" ;real> "//trim(to_char(rdat))
5157if (c_e(ddat)) to_char_dat=trim(to_char_dat)//" ;double> "//trim(to_char(ddat))
5158if (c_e(bdat)) to_char_dat=trim(to_char_dat)//" ;byte> "//trim(to_char(bdat))
5159if (c_e(cdat)) to_char_dat=trim(to_char_dat)//" ;char> "//trim(cdat)
5160
5161#endif
5162
5163END FUNCTION to_char_dat
5164
5165
5166!> Tests whether anything has ever been assigned to a vol7d object
5167!! (.TRUE.) or it is as clean as after an init (.FALSE.).
5168FUNCTION vol7d_c_e(this) RESULT(c_e)
5169TYPE(vol7d), INTENT(in) :: this
5170
5171LOGICAL :: c_e
5172
5173c_e = ASSOCIATED(this%ana) .OR. ASSOCIATED(this%time) .OR. &
5174 ASSOCIATED(this%level) .OR. ASSOCIATED(this%timerange) .OR. &
5175 ASSOCIATED(this%network) .OR. &
5176 ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
5177 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
5178 ASSOCIATED(this%anavar%c) .OR. &
5179 ASSOCIATED(this%anaattr%r) .OR. ASSOCIATED(this%anaattr%d) .OR. &
5180 ASSOCIATED(this%anaattr%i) .OR. ASSOCIATED(this%anaattr%b) .OR. &
5181 ASSOCIATED(this%anaattr%c) .OR. &
5182 ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
5183 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
5184 ASSOCIATED(this%dativar%c) .OR. &
5185 ASSOCIATED(this%datiattr%r) .OR. ASSOCIATED(this%datiattr%d) .OR. &
5186 ASSOCIATED(this%datiattr%i) .OR. ASSOCIATED(this%datiattr%b) .OR. &
5187 ASSOCIATED(this%datiattr%c)
5188
5189END FUNCTION vol7d_c_e
5190
5191
5192!> Metodo per allocare i descrittori delle 7 dimensioni.
5193!! Riceve un grande numero di parametri opzionali che
5194!! indicano quali descrittori allocare e con quale estensione;
5195!! i descrittori non specificati non vengono toccati.
5196!! Può essere quindi chiamato più volte allocando via via
5197!! descrittori relativi a dimensioni diverse.
5198!! Se un descrittore richiesto è già allocato, viene deallocato
5199!! (perdendone l'eventuale contenuto) e riallocato con l'estensione
5200!! richiesta.
5201!! Per i descrittori relativi a dimensioni che non siano variabili o attributi,
5202!! è possibile specificare l'estensione di una dimensione a 0,
5203!! in tal caso il descrittore viene comunque allocato con lunghezza nulla,
5204!! che è diverso da non allocarlo. Per i descrittori di variabili e attributi
5205!! passare un'estensione 0 equivale a non fornire il parametro.
5206!! Avere uno o più descrittori dimensionati con estensione nulla fa sì
5207!! che anche il volume dati successivamente allocato abbia estensione nulla;
5208!! sebbene ciò appaia inutile, un volume del genere può in realtà servire,
5209!! in associazione ai metodi ::vol7d_merge o ::vol7d_append per estendere
5210!! un volume esistente aggiungendo elementi in alcune dimensioni (quelle
5211!! a estensione non nulla, ovviamente) e mantenendo invariato tutto il resto.
5212!! Per quanto riguarda i descrittori delle dimensioni relative alle
5213!! variabili, la relativa estensione è specificata con la nomenclatura
5214!! \a n&lt;x&gt;&lt;y&gt;&lt;z&gt; dove &lt;x&gt; può valere:
5215!! - \a ana per variabili relative a voumi di anagrafica
5216!! - \a dati per variabili relative a voumi di dati
5217!!
5218!! &lt;y&gt; può valere:
5219!! - \a var per variabili
5220!! - \a attr per attributi
5221!! - \a varattr variabili aventi attributi nei volumi di attributi
5222!!
5223!! &lt;z&gt; può valere:
5224!! - \a r per variabili o attributi a valori reali
5225!! - \a d per variabili o attributi a valori a doppia precisione
5226!! - \a i per variabili o attributi a valori interi
5227!! - \a b per variabili o attributi a valori byte
5228!! - \a c per variabili o attributi a valori carattere
5229!!
5230SUBROUTINE vol7d_alloc(this, nana, ntime, nlevel, ntimerange, nnetwork, &
5231 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
5232 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
5233 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
5234 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
5235 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
5236 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc, &
5237 ini)
5238TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i descrittori
5239INTEGER,INTENT(in),OPTIONAL :: nana !< estensione della dimensione anagrafica
5240INTEGER,INTENT(in),OPTIONAL :: ntime !< estensione della dimensione tempo
5241INTEGER,INTENT(in),OPTIONAL :: nlevel !< estensione della dimensione livello varticale
5242INTEGER,INTENT(in),OPTIONAL :: ntimerange !< estensione della dimensione intervallo temporale (timerange)
5243INTEGER,INTENT(in),OPTIONAL :: nnetwork !< estensione della dimensione rete
5244!> estensione delle possibili dimensioni variabile
5245INTEGER,INTENT(in),OPTIONAL :: &
5246 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
5247 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
5248 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
5249 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
5250 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
5251 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc
5252LOGICAL,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
5253
5254INTEGER :: i
5255LOGICAL :: linit
5256
5257IF (PRESENT(ini)) THEN
5258 linit = ini
5259ELSE
5260 linit = .false.
5261ENDIF
5262
5263! Dimensioni principali
5264IF (PRESENT(nana)) THEN
5265 IF (nana >= 0) THEN
5266 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
5267 ALLOCATE(this%ana(nana))
5268 IF (linit) THEN
5269 DO i = 1, nana
5270 CALL init(this%ana(i))
5271 ENDDO
5272 ENDIF
5273 ENDIF
5274ENDIF
5275IF (PRESENT(ntime)) THEN
5276 IF (ntime >= 0) THEN
5277 IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
5278 ALLOCATE(this%time(ntime))
5279 IF (linit) THEN
5280 DO i = 1, ntime
5281 CALL init(this%time(i))
5282 ENDDO
5283 ENDIF
5284 ENDIF
5285ENDIF
5286IF (PRESENT(nlevel)) THEN
5287 IF (nlevel >= 0) THEN
5288 IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
5289 ALLOCATE(this%level(nlevel))
5290 IF (linit) THEN
5291 DO i = 1, nlevel
5292 CALL init(this%level(i))
5293 ENDDO
5294 ENDIF
5295 ENDIF
5296ENDIF
5297IF (PRESENT(ntimerange)) THEN
5298 IF (ntimerange >= 0) THEN
5299 IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
5300 ALLOCATE(this%timerange(ntimerange))
5301 IF (linit) THEN
5302 DO i = 1, ntimerange
5303 CALL init(this%timerange(i))
5304 ENDDO
5305 ENDIF
5306 ENDIF
5307ENDIF
5308IF (PRESENT(nnetwork)) THEN
5309 IF (nnetwork >= 0) THEN
5310 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
5311 ALLOCATE(this%network(nnetwork))
5312 IF (linit) THEN
5313 DO i = 1, nnetwork
5314 CALL init(this%network(i))
5315 ENDDO
5316 ENDIF
5317 ENDIF
5318ENDIF
5319! Dimensioni dei tipi delle variabili
5320CALL vol7d_varvect_alloc(this%anavar, nanavarr, nanavard, &
5321 nanavari, nanavarb, nanavarc, ini)
5322CALL vol7d_varvect_alloc(this%anaattr, nanaattrr, nanaattrd, &
5323 nanaattri, nanaattrb, nanaattrc, ini)
5324CALL vol7d_varvect_alloc(this%anavarattr, nanavarattrr, nanavarattrd, &
5325 nanavarattri, nanavarattrb, nanavarattrc, ini)
5326CALL vol7d_varvect_alloc(this%dativar, ndativarr, ndativard, &
5327 ndativari, ndativarb, ndativarc, ini)
5328CALL vol7d_varvect_alloc(this%datiattr, ndatiattrr, ndatiattrd, &
5329 ndatiattri, ndatiattrb, ndatiattrc, ini)
5330CALL vol7d_varvect_alloc(this%dativarattr, ndativarattrr, ndativarattrd, &
5331 ndativarattri, ndativarattrb, ndativarattrc, ini)
5332
5333END SUBROUTINE vol7d_alloc
5334
5335
5336FUNCTION vol7d_check_alloc_ana(this)
5337TYPE(vol7d),INTENT(in) :: this
5338LOGICAL :: vol7d_check_alloc_ana
5339
5340vol7d_check_alloc_ana = ASSOCIATED(this%ana) .AND. ASSOCIATED(this%network)
5341
5342END FUNCTION vol7d_check_alloc_ana
5343
5344SUBROUTINE vol7d_force_alloc_ana(this, ini)
5345TYPE(vol7d),INTENT(inout) :: this
5346LOGICAL,INTENT(in),OPTIONAL :: ini
5347
5348! Alloco i descrittori minimi per avere un volume di anagrafica
5349IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=1, ini=ini)
5350IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=1, ini=ini)
5351
5352END SUBROUTINE vol7d_force_alloc_ana
5353
5354
5355FUNCTION vol7d_check_alloc_dati(this)
5356TYPE(vol7d),INTENT(in) :: this
5357LOGICAL :: vol7d_check_alloc_dati
5358
5359vol7d_check_alloc_dati = vol7d_check_alloc_ana(this) .AND. &
5360 ASSOCIATED(this%time) .AND. ASSOCIATED(this%level) .AND. &
5361 ASSOCIATED(this%timerange)
5362
5363END FUNCTION vol7d_check_alloc_dati
5364
5365SUBROUTINE vol7d_force_alloc_dati(this, ini)
5366TYPE(vol7d),INTENT(inout) :: this
5367LOGICAL,INTENT(in),OPTIONAL :: ini
5368
5369! Alloco i descrittori minimi per avere un volume di dati
5370CALL vol7d_force_alloc_ana(this, ini)
5371IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=1, ini=ini)
5372IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=1, ini=ini)
5373IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=1, ini=ini)
5374
5375END SUBROUTINE vol7d_force_alloc_dati
5376
5377
5378SUBROUTINE vol7d_force_alloc(this)
5379TYPE(vol7d),INTENT(inout) :: this
5380
5381! If anything really not allocated yet, allocate with size 0
5382IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=0)
5383IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=0)
5384IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=0)
5385IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=0)
5386IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=0)
5387
5388END SUBROUTINE vol7d_force_alloc
5389
5390
5391FUNCTION vol7d_check_vol(this)
5392TYPE(vol7d),INTENT(in) :: this !< oggetto da controllare
5393LOGICAL :: vol7d_check_vol
5394
5395vol7d_check_vol = c_e(this)
5396
5397! Anagrafica
5398IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
5399 vol7d_check_vol = .false.
5400ENDIF
5401
5402IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
5403 vol7d_check_vol = .false.
5404ENDIF
5405
5406IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
5407 vol7d_check_vol = .false.
5408ENDIF
5409
5410IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
5411 vol7d_check_vol = .false.
5412ENDIF
5413
5414IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
5415 vol7d_check_vol = .false.
5416ENDIF
5417IF (ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
5418 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
5419 ASSOCIATED(this%anavar%c)) THEN
5420 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_ana(this)
5421ENDIF
5422
5423! Attributi dell'anagrafica
5424IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
5425 .NOT.ASSOCIATED(this%volanaattrr)) THEN
5426 vol7d_check_vol = .false.
5427ENDIF
5428
5429IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
5430 .NOT.ASSOCIATED(this%volanaattrd)) THEN
5431 vol7d_check_vol = .false.
5432ENDIF
5433
5434IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
5435 .NOT.ASSOCIATED(this%volanaattri)) THEN
5436 vol7d_check_vol = .false.
5437ENDIF
5438
5439IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
5440 .NOT.ASSOCIATED(this%volanaattrb)) THEN
5441 vol7d_check_vol = .false.
5442ENDIF
5443
5444IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
5445 .NOT.ASSOCIATED(this%volanaattrc)) THEN
5446 vol7d_check_vol = .false.
5447ENDIF
5448
5449! Dati
5450IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
5451 vol7d_check_vol = .false.
5452ENDIF
5453
5454IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
5455 vol7d_check_vol = .false.
5456ENDIF
5457
5458IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
5459 vol7d_check_vol = .false.
5460ENDIF
5461
5462IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
5463 vol7d_check_vol = .false.
5464ENDIF
5465
5466IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
5467 vol7d_check_vol = .false.
5468ENDIF
5469
5470! Attributi dei dati
5471IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
5472 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
5473 vol7d_check_vol = .false.
5474ENDIF
5475
5476IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
5477 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
5478 vol7d_check_vol = .false.
5479ENDIF
5480
5481IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
5482 .NOT.ASSOCIATED(this%voldatiattri)) THEN
5483 vol7d_check_vol = .false.
5484ENDIF
5485
5486IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
5487 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
5488 vol7d_check_vol = .false.
5489ENDIF
5490
5491IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
5492 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
5493 vol7d_check_vol = .false.
5494ENDIF
5495IF (ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
5496 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
5497 ASSOCIATED(this%dativar%c)) THEN
5498 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_dati(this)
5499ENDIF
5500
5501END FUNCTION vol7d_check_vol
5502
5503
5504!> Metodo per allocare i volumi richiesti di variabili e attributi per
5505!! anagrafica e dati.
5506!! Se alcuni dei descrittori relativi alle dimensioni anagrafica,
5507!! livello verticale, tempo, intervallo temporale (timerange), rete non sono
5508!! stati richiesti preventivamente con la ::vol7d_alloc, essi vengono allocati
5509!! automaticamente da questo metodo
5510!! con estensione di default pari a 1 (non 0!), questo significa, ad esempio,
5511!! che se prevedo di avere soli dati superficiali, cioè ad un solo livello
5512!! verticale, o una sola rete di stazioni, non devo preoccuparmi di
5513!! specificare questa informazione.
5514!! Tra i 20 possibili volumi allocabili
5515!! ((variabili,attributi)*(anagrafica,dati)*(r,d,i,b,c)=20)
5516!! saranno allocati solo quelli per cui è stato precedentemente richiesto il
5517!! corrispondente descrittore variabili/attributi con la ::vol7d_alloc.
5518SUBROUTINE vol7d_alloc_vol(this, ini, inivol)
5519TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i volumi
5520LOGICAL,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
5521LOGICAL,INTENT(in),OPTIONAL :: inivol !< se fornito e vale \c .TRUE., i volumi allocati saranno inizializzati a valore mancante
5522
5523LOGICAL :: linivol
5524
5525IF (PRESENT(inivol)) THEN
5526 linivol = inivol
5527ELSE
5528 linivol = .true.
5529ENDIF
5530
5531! Anagrafica
5532IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
5533 CALL vol7d_force_alloc_ana(this, ini)
5534 ALLOCATE(this%volanar(SIZE(this%ana), SIZE(this%anavar%r), SIZE(this%network)))
5535 IF (linivol) this%volanar(:,:,:) = rmiss
5536ENDIF
5537
5538IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
5539 CALL vol7d_force_alloc_ana(this, ini)
5540 ALLOCATE(this%volanad(SIZE(this%ana), SIZE(this%anavar%d), SIZE(this%network)))
5541 IF (linivol) this%volanad(:,:,:) = rdmiss
5542ENDIF
5543
5544IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
5545 CALL vol7d_force_alloc_ana(this, ini)
5546 ALLOCATE(this%volanai(SIZE(this%ana), SIZE(this%anavar%i), SIZE(this%network)))
5547 IF (linivol) this%volanai(:,:,:) = imiss
5548ENDIF
5549
5550IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
5551 CALL vol7d_force_alloc_ana(this, ini)
5552 ALLOCATE(this%volanab(SIZE(this%ana), SIZE(this%anavar%b), SIZE(this%network)))
5553 IF (linivol) this%volanab(:,:,:) = ibmiss
5554ENDIF
5555
5556IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
5557 CALL vol7d_force_alloc_ana(this, ini)
5558 ALLOCATE(this%volanac(SIZE(this%ana), SIZE(this%anavar%c), SIZE(this%network)))
5559 IF (linivol) this%volanac(:,:,:) = cmiss
5560ENDIF
5561
5562! Attributi dell'anagrafica
5563IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
5564 .NOT.ASSOCIATED(this%volanaattrr)) THEN
5565 CALL vol7d_force_alloc_ana(this, ini)
5566 ALLOCATE(this%volanaattrr(SIZE(this%ana), SIZE(this%anavarattr%r), &
5567 SIZE(this%network), SIZE(this%anaattr%r)))
5568 IF (linivol) this%volanaattrr(:,:,:,:) = rmiss
5569ENDIF
5570
5571IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
5572 .NOT.ASSOCIATED(this%volanaattrd)) THEN
5573 CALL vol7d_force_alloc_ana(this, ini)
5574 ALLOCATE(this%volanaattrd(SIZE(this%ana), SIZE(this%anavarattr%d), &
5575 SIZE(this%network), SIZE(this%anaattr%d)))
5576 IF (linivol) this%volanaattrd(:,:,:,:) = rdmiss
5577ENDIF
5578
5579IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
5580 .NOT.ASSOCIATED(this%volanaattri)) THEN
5581 CALL vol7d_force_alloc_ana(this, ini)
5582 ALLOCATE(this%volanaattri(SIZE(this%ana), SIZE(this%anavarattr%i), &
5583 SIZE(this%network), SIZE(this%anaattr%i)))
5584 IF (linivol) this%volanaattri(:,:,:,:) = imiss
5585ENDIF
5586
5587IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
5588 .NOT.ASSOCIATED(this%volanaattrb)) THEN
5589 CALL vol7d_force_alloc_ana(this, ini)
5590 ALLOCATE(this%volanaattrb(SIZE(this%ana), SIZE(this%anavarattr%b), &
5591 SIZE(this%network), SIZE(this%anaattr%b)))
5592 IF (linivol) this%volanaattrb(:,:,:,:) = ibmiss
5593ENDIF
5594
5595IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
5596 .NOT.ASSOCIATED(this%volanaattrc)) THEN
5597 CALL vol7d_force_alloc_ana(this, ini)
5598 ALLOCATE(this%volanaattrc(SIZE(this%ana), SIZE(this%anavarattr%c), &
5599 SIZE(this%network), SIZE(this%anaattr%c)))
5600 IF (linivol) this%volanaattrc(:,:,:,:) = cmiss
5601ENDIF
5602
5603! Dati
5604IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
5605 CALL vol7d_force_alloc_dati(this, ini)
5606 ALLOCATE(this%voldatir(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5607 SIZE(this%timerange), SIZE(this%dativar%r), SIZE(this%network)))
5608 IF (linivol) this%voldatir(:,:,:,:,:,:) = rmiss
5609ENDIF
5610
5611IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
5612 CALL vol7d_force_alloc_dati(this, ini)
5613 ALLOCATE(this%voldatid(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5614 SIZE(this%timerange), SIZE(this%dativar%d), SIZE(this%network)))
5615 IF (linivol) this%voldatid(:,:,:,:,:,:) = rdmiss
5616ENDIF
5617
5618IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
5619 CALL vol7d_force_alloc_dati(this, ini)
5620 ALLOCATE(this%voldatii(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5621 SIZE(this%timerange), SIZE(this%dativar%i), SIZE(this%network)))
5622 IF (linivol) this%voldatii(:,:,:,:,:,:) = imiss
5623ENDIF
5624
5625IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
5626 CALL vol7d_force_alloc_dati(this, ini)
5627 ALLOCATE(this%voldatib(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5628 SIZE(this%timerange), SIZE(this%dativar%b), SIZE(this%network)))
5629 IF (linivol) this%voldatib(:,:,:,:,:,:) = ibmiss
5630ENDIF
5631
5632IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
5633 CALL vol7d_force_alloc_dati(this, ini)
5634 ALLOCATE(this%voldatic(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5635 SIZE(this%timerange), SIZE(this%dativar%c), SIZE(this%network)))
5636 IF (linivol) this%voldatic(:,:,:,:,:,:) = cmiss
5637ENDIF
5638
5639! Attributi dei dati
5640IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
5641 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
5642 CALL vol7d_force_alloc_dati(this, ini)
5643 ALLOCATE(this%voldatiattrr(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5644 SIZE(this%timerange), SIZE(this%dativarattr%r), SIZE(this%network), &
5645 SIZE(this%datiattr%r)))
5646 IF (linivol) this%voldatiattrr(:,:,:,:,:,:,:) = rmiss
5647ENDIF
5648
5649IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
5650 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
5651 CALL vol7d_force_alloc_dati(this, ini)
5652 ALLOCATE(this%voldatiattrd(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5653 SIZE(this%timerange), SIZE(this%dativarattr%d), SIZE(this%network), &
5654 SIZE(this%datiattr%d)))
5655 IF (linivol) this%voldatiattrd(:,:,:,:,:,:,:) = rdmiss
5656ENDIF
5657
5658IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
5659 .NOT.ASSOCIATED(this%voldatiattri)) THEN
5660 CALL vol7d_force_alloc_dati(this, ini)
5661 ALLOCATE(this%voldatiattri(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5662 SIZE(this%timerange), SIZE(this%dativarattr%i), SIZE(this%network), &
5663 SIZE(this%datiattr%i)))
5664 IF (linivol) this%voldatiattri(:,:,:,:,:,:,:) = imiss
5665ENDIF
5666
5667IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
5668 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
5669 CALL vol7d_force_alloc_dati(this, ini)
5670 ALLOCATE(this%voldatiattrb(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5671 SIZE(this%timerange), SIZE(this%dativarattr%b), SIZE(this%network), &
5672 SIZE(this%datiattr%b)))
5673 IF (linivol) this%voldatiattrb(:,:,:,:,:,:,:) = ibmiss
5674ENDIF
5675
5676IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
5677 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
5678 CALL vol7d_force_alloc_dati(this, ini)
5679 ALLOCATE(this%voldatiattrc(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
5680 SIZE(this%timerange), SIZE(this%dativarattr%c), SIZE(this%network), &
5681 SIZE(this%datiattr%c)))
5682 IF (linivol) this%voldatiattrc(:,:,:,:,:,:,:) = cmiss
5683ENDIF
5684
5685! Catch-all method
5686CALL vol7d_force_alloc(this)
5687
5688! Creo gli indici var-attr
5689
5690#ifdef DEBUG
5691CALL l4f_log(l4f_debug,"calling: vol7d_set_attr_ind")
5692#endif
5693
5694CALL vol7d_set_attr_ind(this)
5695
5696
5697
5698END SUBROUTINE vol7d_alloc_vol
5699
5700
5701!> Metodo per creare gli indici che associano le variabili aventi attributo
5702!! alle variabili nei relativi descrittori.
5703!! Ha senso chiamare questo metodo solo dopo che i descrittori delle variabili
5704!! e degli attributi desiderati sono stati allocati ed è stato assegnato un
5705!! valore ai relativi membri btable (vedi vol7d_var_class::vol7d_var), se
5706!! i descrittori non sono stati allocati o assegnati, il metodo non fa niente.
5707SUBROUTINE vol7d_set_attr_ind(this)
5708TYPE(vol7d),INTENT(inout) :: this !< oggetto in cui creare gli indici
5709
5710INTEGER :: i
5711
5712! real
5713IF (ASSOCIATED(this%dativar%r)) THEN
5714 IF (ASSOCIATED(this%dativarattr%r)) THEN
5715 DO i = 1, SIZE(this%dativar%r)
5716 this%dativar%r(i)%r = &
5717 firsttrue(this%dativar%r(i)%btable == this%dativarattr%r(:)%btable)
5718 ENDDO
5719 ENDIF
5720
5721 IF (ASSOCIATED(this%dativarattr%d)) THEN
5722 DO i = 1, SIZE(this%dativar%r)
5723 this%dativar%r(i)%d = &
5724 firsttrue(this%dativar%r(i)%btable == this%dativarattr%d(:)%btable)
5725 ENDDO
5726 ENDIF
5727
5728 IF (ASSOCIATED(this%dativarattr%i)) THEN
5729 DO i = 1, SIZE(this%dativar%r)
5730 this%dativar%r(i)%i = &
5731 firsttrue(this%dativar%r(i)%btable == this%dativarattr%i(:)%btable)
5732 ENDDO
5733 ENDIF
5734
5735 IF (ASSOCIATED(this%dativarattr%b)) THEN
5736 DO i = 1, SIZE(this%dativar%r)
5737 this%dativar%r(i)%b = &
5738 firsttrue(this%dativar%r(i)%btable == this%dativarattr%b(:)%btable)
5739 ENDDO
5740 ENDIF
5741
5742 IF (ASSOCIATED(this%dativarattr%c)) THEN
5743 DO i = 1, SIZE(this%dativar%r)
5744 this%dativar%r(i)%c = &
5745 firsttrue(this%dativar%r(i)%btable == this%dativarattr%c(:)%btable)
5746 ENDDO
5747 ENDIF
5748ENDIF
5749! double
5750IF (ASSOCIATED(this%dativar%d)) THEN
5751 IF (ASSOCIATED(this%dativarattr%r)) THEN
5752 DO i = 1, SIZE(this%dativar%d)
5753 this%dativar%d(i)%r = &
5754 firsttrue(this%dativar%d(i)%btable == this%dativarattr%r(:)%btable)
5755 ENDDO
5756 ENDIF
5757
5758 IF (ASSOCIATED(this%dativarattr%d)) THEN
5759 DO i = 1, SIZE(this%dativar%d)
5760 this%dativar%d(i)%d = &
5761 firsttrue(this%dativar%d(i)%btable == this%dativarattr%d(:)%btable)
5762 ENDDO
5763 ENDIF
5764
5765 IF (ASSOCIATED(this%dativarattr%i)) THEN
5766 DO i = 1, SIZE(this%dativar%d)
5767 this%dativar%d(i)%i = &
5768 firsttrue(this%dativar%d(i)%btable == this%dativarattr%i(:)%btable)
5769 ENDDO
5770 ENDIF
5771
5772 IF (ASSOCIATED(this%dativarattr%b)) THEN
5773 DO i = 1, SIZE(this%dativar%d)
5774 this%dativar%d(i)%b = &
5775 firsttrue(this%dativar%d(i)%btable == this%dativarattr%b(:)%btable)
5776 ENDDO
5777 ENDIF
5778
5779 IF (ASSOCIATED(this%dativarattr%c)) THEN
5780 DO i = 1, SIZE(this%dativar%d)
5781 this%dativar%d(i)%c = &
5782 firsttrue(this%dativar%d(i)%btable == this%dativarattr%c(:)%btable)
5783 ENDDO
5784 ENDIF
5785ENDIF
5786! integer
5787IF (ASSOCIATED(this%dativar%i)) THEN
5788 IF (ASSOCIATED(this%dativarattr%r)) THEN
5789 DO i = 1, SIZE(this%dativar%i)
5790 this%dativar%i(i)%r = &
5791 firsttrue(this%dativar%i(i)%btable == this%dativarattr%r(:)%btable)
5792 ENDDO
5793 ENDIF
5794
5795 IF (ASSOCIATED(this%dativarattr%d)) THEN
5796 DO i = 1, SIZE(this%dativar%i)
5797 this%dativar%i(i)%d = &
5798 firsttrue(this%dativar%i(i)%btable == this%dativarattr%d(:)%btable)
5799 ENDDO
5800 ENDIF
5801
5802 IF (ASSOCIATED(this%dativarattr%i)) THEN
5803 DO i = 1, SIZE(this%dativar%i)
5804 this%dativar%i(i)%i = &
5805 firsttrue(this%dativar%i(i)%btable == this%dativarattr%i(:)%btable)
5806 ENDDO
5807 ENDIF
5808
5809 IF (ASSOCIATED(this%dativarattr%b)) THEN
5810 DO i = 1, SIZE(this%dativar%i)
5811 this%dativar%i(i)%b = &
5812 firsttrue(this%dativar%i(i)%btable == this%dativarattr%b(:)%btable)
5813 ENDDO
5814 ENDIF
5815
5816 IF (ASSOCIATED(this%dativarattr%c)) THEN
5817 DO i = 1, SIZE(this%dativar%i)
5818 this%dativar%i(i)%c = &
5819 firsttrue(this%dativar%i(i)%btable == this%dativarattr%c(:)%btable)
5820 ENDDO
5821 ENDIF
5822ENDIF
5823! byte
5824IF (ASSOCIATED(this%dativar%b)) THEN
5825 IF (ASSOCIATED(this%dativarattr%r)) THEN
5826 DO i = 1, SIZE(this%dativar%b)
5827 this%dativar%b(i)%r = &
5828 firsttrue(this%dativar%b(i)%btable == this%dativarattr%r(:)%btable)
5829 ENDDO
5830 ENDIF
5831
5832 IF (ASSOCIATED(this%dativarattr%d)) THEN
5833 DO i = 1, SIZE(this%dativar%b)
5834 this%dativar%b(i)%d = &
5835 firsttrue(this%dativar%b(i)%btable == this%dativarattr%d(:)%btable)
5836 ENDDO
5837 ENDIF
5838
5839 IF (ASSOCIATED(this%dativarattr%i)) THEN
5840 DO i = 1, SIZE(this%dativar%b)
5841 this%dativar%b(i)%i = &
5842 firsttrue(this%dativar%b(i)%btable == this%dativarattr%i(:)%btable)
5843 ENDDO
5844 ENDIF
5845
5846 IF (ASSOCIATED(this%dativarattr%b)) THEN
5847 DO i = 1, SIZE(this%dativar%b)
5848 this%dativar%b(i)%b = &
5849 firsttrue(this%dativar%b(i)%btable == this%dativarattr%b(:)%btable)
5850 ENDDO
5851 ENDIF
5852
5853 IF (ASSOCIATED(this%dativarattr%c)) THEN
5854 DO i = 1, SIZE(this%dativar%b)
5855 this%dativar%b(i)%c = &
5856 firsttrue(this%dativar%b(i)%btable == this%dativarattr%c(:)%btable)
5857 ENDDO
5858 ENDIF
5859ENDIF
5860! character
5861IF (ASSOCIATED(this%dativar%c)) THEN
5862 IF (ASSOCIATED(this%dativarattr%r)) THEN
5863 DO i = 1, SIZE(this%dativar%c)
5864 this%dativar%c(i)%r = &
5865 firsttrue(this%dativar%c(i)%btable == this%dativarattr%r(:)%btable)
5866 ENDDO
5867 ENDIF
5868
5869 IF (ASSOCIATED(this%dativarattr%d)) THEN
5870 DO i = 1, SIZE(this%dativar%c)
5871 this%dativar%c(i)%d = &
5872 firsttrue(this%dativar%c(i)%btable == this%dativarattr%d(:)%btable)
5873 ENDDO
5874 ENDIF
5875
5876 IF (ASSOCIATED(this%dativarattr%i)) THEN
5877 DO i = 1, SIZE(this%dativar%c)
5878 this%dativar%c(i)%i = &
5879 firsttrue(this%dativar%c(i)%btable == this%dativarattr%i(:)%btable)
5880 ENDDO
5881 ENDIF
5882
5883 IF (ASSOCIATED(this%dativarattr%b)) THEN
5884 DO i = 1, SIZE(this%dativar%c)
5885 this%dativar%c(i)%b = &
5886 firsttrue(this%dativar%c(i)%btable == this%dativarattr%b(:)%btable)
5887 ENDDO
5888 ENDIF
5889
5890 IF (ASSOCIATED(this%dativarattr%c)) THEN
5891 DO i = 1, SIZE(this%dativar%c)
5892 this%dativar%c(i)%c = &
5893 firsttrue(this%dativar%c(i)%btable == this%dativarattr%c(:)%btable)
5894 ENDDO
5895 ENDIF
5896ENDIF
5897
5898END SUBROUTINE vol7d_set_attr_ind
5899
5900
5901!> Metodo per fondere 2 oggetti vol7d.
5902!! Il secondo volume viene accodato al primo e poi distrutto, si veda
5903!! quindi la descrizione di ::vol7d_append. Se uno degli oggetti \a
5904!! this o \a that sono vuoti non perde tempo inutile,
5905SUBROUTINE vol7d_merge(this, that, sort, bestdata, &
5906 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
5907TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, alla fine conterrà il risultato della fusione
5908TYPE(vol7d),INTENT(INOUT) :: that !< secondo oggetto in ingresso, alla fine sarà distrutto
5909LOGICAL,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
5910LOGICAL,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
5911LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple ! experimental, please do not use outside the library now
5912
5913TYPE(vol7d) :: v7d_clean
5914
5915
5916IF (.NOT.c_e(this)) THEN ! speedup
5917 this = that
5918 CALL init(v7d_clean)
5919 that = v7d_clean ! destroy that without deallocating
5920ELSE ! Append that to this and destroy that
5921 CALL vol7d_append(this, that, sort, bestdata, &
5922 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
5923 CALL delete(that)
5924ENDIF
5925
5926END SUBROUTINE vol7d_merge
5927
5928
5929!> Metodo per accodare un oggetto vol7d ad un altro.
5930!! Si tratta di un metodo molto potente e versatile;
5931!! i descrittori delle dimensioni del volume finale conterranno i valori
5932!! dei corrispondenti descrittori del primo e del secondo volume
5933!! e i volumi di anagrafica e dati conterranno i valori dei due volumi
5934!! ai posti giusti, e valori mancanti per le nuove combinazioni che
5935!! eventualmente si verranno a creare.
5936!! Se i volumi multidimensionali di anagrafica e/o dati dei 2 oggetti
5937!! hanno un'intersezione non nulla, negli elementi comuni il volume finale
5938!! conterrà il corrispondente elemento del \b secondo volume.
5939!! Attenzione che, durante l'esecuzione del metodo, la memoria richiesta è
5940!! pari alla memoria complessiva occupata dai 2 volumi iniziali più
5941!! la memoria complessiva del volume finale, per cui, nel caso di volumi grandi,
5942!! ci potrebbero essere problemi di esaurimento della memoria centrale.
5943!! Se l'oggetto \a that è vuoto non perde tempo inutile,
5944!!
5945!! \todo nel caso di elementi comuni inserire la possibiità (opzionale per
5946!! non penalizzare le prestazioni quando ciò non serve) di effettuare una scelta
5947!! più ragionata dell'elemento da tenere, almeno controllando i dati mancanti
5948!! se non le flag di qualità
5949!!
5950!! \todo "rateizzare" l'allocazione dei volumi per ridurre l'occupazione di
5951!! memoria nel caso siano allocati contemporaneamente volumi di variabili e
5952!! di attributi o più volumi di tipi diversi
5953!!
5954!! \todo il parametro \a that è dichiarato \a INOUT perché la vol7d_alloc_vol
5955!! può modificarlo, bisognerebbe implementare una vol7d_check_vol che restituisca
5956!! errore anziché usare la vol7d_alloc_vol.
5957SUBROUTINE vol7d_append(this, that, sort, bestdata, &
5958 ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple)
5959TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, a cui sarà accodato il secondo
5960TYPE(vol7d),INTENT(IN) :: that !< secondo oggetto in ingresso, non viene modificato dal metodo
5961LOGICAL,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
5962! experimental, please do not use outside the library now, they force the use
5963! of a simplified mapping algorithm which is valid only whene the dimension
5964! content is the same in both volumes , or when one of them is empty
5965LOGICAL,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
5966LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple
5967
5968
5969TYPE(vol7d) :: v7dtmp
5970LOGICAL :: lsort, lbestdata
5971INTEGER,POINTER :: remapt1(:), remapt2(:), remaptr1(:), remaptr2(:), &
5972 remapl1(:), remapl2(:), remapa1(:), remapa2(:), remapn1(:), remapn2(:)
5973
5974IF (.NOT.c_e(that)) RETURN ! speedup, nothing to do
5975IF (.NOT.vol7d_check_vol(that)) RETURN ! be safe
5976IF (.NOT.c_e(this)) THEN ! this case is like a vol7d_copy, more efficient to copy?
5977 CALL vol7d_copy(that, this, sort=sort)
5978 RETURN
5979ENDIF
5980
5981IF (this%time_definition /= that%time_definition) THEN
5982 CALL l4f_log(l4f_fatal, &
5983 'in vol7d_append, cannot append volumes with different &
5984 &time definition')
5985 CALL raise_fatal_error()
5986ENDIF
5987
5988! Completo l'allocazione per avere volumi a norma
5989CALL vol7d_alloc_vol(this)
5990
5991CALL init(v7dtmp, time_definition=this%time_definition)
5992CALL optio(sort, lsort)
5993CALL optio(bestdata, lbestdata)
5994
5995! Calcolo le mappature tra volumi vecchi e volume nuovo
5996! I puntatori remap* vengono tutti o allocati o nullificati
5997IF (optio_log(ltimesimple)) THEN
5998 CALL vol7d_remap2simple_datetime(this%time, that%time, v7dtmp%time, &
5999 lsort, remapt1, remapt2)
6000ELSE
6001 CALL vol7d_remap2_datetime(this%time, that%time, v7dtmp%time, &
6002 lsort, remapt1, remapt2)
6003ENDIF
6004IF (optio_log(ltimerangesimple)) THEN
6005 CALL vol7d_remap2simple_vol7d_timerange(this%timerange, that%timerange, &
6006 v7dtmp%timerange, lsort, remaptr1, remaptr2)
6007ELSE
6008 CALL vol7d_remap2_vol7d_timerange(this%timerange, that%timerange, &
6009 v7dtmp%timerange, lsort, remaptr1, remaptr2)
6010ENDIF
6011IF (optio_log(llevelsimple)) THEN
6012 CALL vol7d_remap2simple_vol7d_level(this%level, that%level, v7dtmp%level, &
6013 lsort, remapl1, remapl2)
6014ELSE
6015 CALL vol7d_remap2_vol7d_level(this%level, that%level, v7dtmp%level, &
6016 lsort, remapl1, remapl2)
6017ENDIF
6018IF (optio_log(lanasimple)) THEN
6019 CALL vol7d_remap2simple_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
6020 .false., remapa1, remapa2)
6021ELSE
6022 CALL vol7d_remap2_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
6023 .false., remapa1, remapa2)
6024ENDIF
6025IF (optio_log(lnetworksimple)) THEN
6026 CALL vol7d_remap2simple_vol7d_network(this%network, that%network, v7dtmp%network, &
6027 .false., remapn1, remapn2)
6028ELSE
6029 CALL vol7d_remap2_vol7d_network(this%network, that%network, v7dtmp%network, &
6030 .false., remapn1, remapn2)
6031ENDIF
6032
6033! Faccio la fusione fisica dei volumi
6034CALL vol7d_merge_finalr(this, that, v7dtmp, &
6035 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6036 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6037CALL vol7d_merge_finald(this, that, v7dtmp, &
6038 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6039 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6040CALL vol7d_merge_finali(this, that, v7dtmp, &
6041 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6042 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6043CALL vol7d_merge_finalb(this, that, v7dtmp, &
6044 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6045 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6046CALL vol7d_merge_finalc(this, that, v7dtmp, &
6047 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6048 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6049
6050! Dealloco i vettori di rimappatura
6051IF (ASSOCIATED(remapt1)) DEALLOCATE(remapt1)
6052IF (ASSOCIATED(remapt2)) DEALLOCATE(remapt2)
6053IF (ASSOCIATED(remaptr1)) DEALLOCATE(remaptr1)
6054IF (ASSOCIATED(remaptr2)) DEALLOCATE(remaptr2)
6055IF (ASSOCIATED(remapl1)) DEALLOCATE(remapl1)
6056IF (ASSOCIATED(remapl2)) DEALLOCATE(remapl2)
6057IF (ASSOCIATED(remapa1)) DEALLOCATE(remapa1)
6058IF (ASSOCIATED(remapa2)) DEALLOCATE(remapa2)
6059IF (ASSOCIATED(remapn1)) DEALLOCATE(remapn1)
6060IF (ASSOCIATED(remapn2)) DEALLOCATE(remapn2)
6061
6062! Distruggo il vecchio volume e assegno il nuovo a this
6063CALL delete(this)
6064this = v7dtmp
6065! Ricreo gli indici var-attr
6066CALL vol7d_set_attr_ind(this)
6067
6068END SUBROUTINE vol7d_append
6069
6070
6071!> Metodo per creare una copia completa e indipendente di un oggetto vol7d.
6072!! Questo metodo crea un duplicato di tutti i membri di un oggetto vol7d,
6073!! con la possibilità di rielaborarlo durante la copia. Se l'oggetto da copiare
6074!! è vuoto non perde tempo inutile.
6075!! Attenzione, il codice:
6076!! \code
6077!! USE vol7d_class
6078!! TYPE(vol7d) :: vol1, vol2
6079!! CALL init(vol1)
6080!! CALL init(vol2)
6081!! ... ! riempio vol1
6082!! vol2 = vol1
6083!! \endcode
6084!! fa una cosa diversa rispetto a:
6085!! \code
6086!! USE vol7d_class
6087!! TYPE(vol7d) :: vol1, vol2
6088!! CALL init(vol1)
6089!! CALL init(vol2)
6090!! ... ! riempio vol1
6091!! CALL vol7d_copy(vol1, vol2)
6092!! \endcode
6093!! nel primo caso, infatti, l'operatore di assegnazione copia solo i componenti
6094!! statici di \a vol1 nei corrispondenti elementi di \a vol2, mentre i componenti che
6095!! sono allocati dinamicamente (cioè quelli che in ::vol7d hanno l'attributo
6096!! \c POINTER, in pratica quasi tutti) non vengono duplicati, ma per essi vol2
6097!! conterrà un puntatore al corrispondente elemento a cui già punta vol1, e quindi
6098!! eventuali cambiamenti al contenuto di uno dei due oggetti influenzerà il
6099!! contenuto dell'altro; nel secondo caso, invece, vol1 e vol2 sono, dopo la
6100!! vol7d_copy, 2 istanze
6101!! completamente indipendenti, ma uguali tra loro per contenuto, della classe
6102!! vol7d, e quindi hanno vita indipendente.
6103SUBROUTINE vol7d_copy(this, that, sort, unique, miss, &
6104 lsort_time, lsort_timerange, lsort_level, &
6105 ltime, ltimerange, llevel, lana, lnetwork, &
6106 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
6107 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
6108 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
6109 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
6110 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
6111 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
6112TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
6113TYPE(vol7d),INTENT(INOUT) :: that !< oggetto destinazione
6114LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
6115LOGICAL,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)
6116LOGICAL,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
6117LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
6118LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
6119LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
6120!> se fornito, deve essere un vettore logico della stessa lunghezza di
6121!! this%time indicante quali elementi della dimensione \a time
6122!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
6123!! nel volume copiato; in alternativa può essere un vettore di
6124!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
6125!! gli elementi (utile principalmente per le variabili); è compatibile
6126!! col parametro \a miss
6127LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
6128!> come il precedente per la dimensione \a timerange
6129LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:)
6130!> come il precedente per la dimensione \a level
6131LOGICAL,INTENT(IN),OPTIONAL :: llevel(:)
6132!> come il precedente per la dimensione \a ana
6133LOGICAL,INTENT(IN),OPTIONAL :: lana(:)
6134!> come il precedente per la dimensione \a network
6135LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:)
6136!> come il precedente per tutte le possibili dimensioni variabile
6137LOGICAL,INTENT(in),OPTIONAL :: &
6138 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
6139 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
6140 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
6141 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
6142 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
6143 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
6144
6145LOGICAL :: lsort, lunique, lmiss
6146INTEGER,POINTER :: remapt(:), remaptr(:), remapl(:), remapa(:), remapn(:)
6147
6148CALL init(that)
6149IF (.NOT.c_e(this)) RETURN ! speedup, nothing to do
6150IF (.NOT.vol7d_check_vol(this)) RETURN ! be safe
6151
6152CALL optio(sort, lsort)
6153CALL optio(unique, lunique)
6154CALL optio(miss, lmiss)
6155
6156! Calcolo le mappature tra volume vecchio e volume nuovo
6157! I puntatori remap* vengono tutti o allocati o nullificati
6158CALL vol7d_remap1_datetime(this%time, that%time, &
6159 lsort.OR.optio_log(lsort_time), lunique, lmiss, remapt, ltime)
6160CALL vol7d_remap1_vol7d_timerange(this%timerange, that%timerange, &
6161 lsort.OR.optio_log(lsort_timerange), lunique, lmiss, remaptr, ltimerange)
6162CALL vol7d_remap1_vol7d_level(this%level, that%level, &
6163 lsort.OR.optio_log(lsort_level), lunique, lmiss, remapl, llevel)
6164CALL vol7d_remap1_vol7d_ana(this%ana, that%ana, &
6165 lsort, lunique, lmiss, remapa, lana)
6166CALL vol7d_remap1_vol7d_network(this%network, that%network, &
6167 lsort, lunique, lmiss, remapn, lnetwork)
6168
6169! lanavari, lanavarb, lanavarc, &
6170! lanaattri, lanaattrb, lanaattrc, &
6171! lanavarattri, lanavarattrb, lanavarattrc, &
6172! ldativari, ldativarb, ldativarc, &
6173! ldatiattri, ldatiattrb, ldatiattrc, &
6174! ldativarattri, ldativarattrb, ldativarattrc
6175! Faccio la riforma fisica dei volumi
6176CALL vol7d_reform_finalr(this, that, &
6177 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6178 lanavarr, lanaattrr, lanavarattrr, ldativarr, ldatiattrr, ldativarattrr)
6179CALL vol7d_reform_finald(this, that, &
6180 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6181 lanavard, lanaattrd, lanavarattrd, ldativard, ldatiattrd, ldativarattrd)
6182CALL vol7d_reform_finali(this, that, &
6183 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6184 lanavari, lanaattri, lanavarattri, ldativari, ldatiattri, ldativarattri)
6185CALL vol7d_reform_finalb(this, that, &
6186 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6187 lanavarb, lanaattrb, lanavarattrb, ldativarb, ldatiattrb, ldativarattrb)
6188CALL vol7d_reform_finalc(this, that, &
6189 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6190 lanavarc, lanaattrc, lanavarattrc, ldativarc, ldatiattrc, ldativarattrc)
6191
6192! Dealloco i vettori di rimappatura
6193IF (ASSOCIATED(remapt)) DEALLOCATE(remapt)
6194IF (ASSOCIATED(remaptr)) DEALLOCATE(remaptr)
6195IF (ASSOCIATED(remapl)) DEALLOCATE(remapl)
6196IF (ASSOCIATED(remapa)) DEALLOCATE(remapa)
6197IF (ASSOCIATED(remapn)) DEALLOCATE(remapn)
6198
6199! Ricreo gli indici var-attr
6200CALL vol7d_set_attr_ind(that)
6201that%time_definition = this%time_definition
6202
6203END SUBROUTINE vol7d_copy
6204
6205
6206!> Metodo per riformare in varie maniere un oggetto vol7d.
6207!! Equivale ad una copia (vedi ::vol7d_copy)
6208!! seguita dalla distruzione del volume iniziale e alla
6209!! sua riassegnazione al volume copiato. Ha senso se almeno uno dei parametri
6210!! \a sort, \a uniq o \a miss è fornito uguale a \c .TRUE., altrimenti
6211!! è solo una perdita di tempo.
6212!! Può essere utile, ad esempio, per eliminare stazioni
6213!! o istanti temporali indesiderati, basta assegnare il loro corrispondente
6214!! elemento del descrittore a valore mancante e chiamare vol7d_reform
6215!! con miss=.TRUE. .
6216SUBROUTINE vol7d_reform(this, sort, unique, miss, &
6217 lsort_time, lsort_timerange, lsort_level, &
6218 ltime, ltimerange, llevel, lana, lnetwork, &
6219 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
6220 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
6221 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
6222 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
6223 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
6224 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc&
6225 ,purgeana)
6226TYPE(vol7d),INTENT(INOUT) :: this !< oggetto da riformare
6227LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
6228LOGICAL,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)
6229LOGICAL,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
6230LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
6231LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
6232LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
6233!> se fornito, deve essere un vettore logico della stessa lunghezza di
6234!! this%time indicante quali elementi della dimensione \a time
6235!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
6236!! nel volume copiato; in alternativa può essere un vettore di
6237!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
6238!! gli elementi (utile principalmente per le variabili); è compatibile
6239!! col parametro \a miss
6240LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
6241LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:) !< come il precedente per la dimensione \a timerange
6242LOGICAL,INTENT(IN),OPTIONAL :: llevel(:) !< come il precedente per la dimensione \a level
6243LOGICAL,INTENT(IN),OPTIONAL :: lana(:) !< come il precedente per la dimensione \a ana
6244LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:) !< come il precedente per la dimensione \a network
6245!> come il precedente per tutte le possibili dimensioni variabile
6246LOGICAL,INTENT(in),OPTIONAL :: &
6247 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
6248 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
6249 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
6250 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
6251 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
6252 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
6253LOGICAL,INTENT(IN),OPTIONAL :: purgeana !< if true remove ana with all data missing
6254
6255TYPE(vol7d) :: v7dtmp
6256logical,allocatable :: llana(:)
6257integer :: i
6258
6259CALL vol7d_copy(this, v7dtmp, sort, unique, miss, &
6260 lsort_time, lsort_timerange, lsort_level, &
6261 ltime, ltimerange, llevel, lana, lnetwork, &
6262 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
6263 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
6264 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
6265 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
6266 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
6267 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
6268
6269! destroy old volume
6270CALL delete(this)
6271
6272if (optio_log(purgeana)) then
6273 allocate(llana(size(v7dtmp%ana)))
6274 llana =.false.
6275 do i =1,size(v7dtmp%ana)
6276 if (associated(v7dtmp%voldatii)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatii(i,:,:,:,:,:)))
6277 if (associated(v7dtmp%voldatir)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatir(i,:,:,:,:,:)))
6278 if (associated(v7dtmp%voldatid)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatid(i,:,:,:,:,:)))
6279 if (associated(v7dtmp%voldatib)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatib(i,:,:,:,:,:)))
6280 if (associated(v7dtmp%voldatic)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatic(i,:,:,:,:,:)))
6281 end do
6282 CALL vol7d_copy(v7dtmp, this,lana=llana)
6283 CALL delete(v7dtmp)
6284 deallocate(llana)
6285else
6286 this=v7dtmp
6287end if
6288
6289END SUBROUTINE vol7d_reform
6290
6291
6292!> Sorts the sortable dimensions in the volume \a this only when necessary.
6293!! Most of the times, the time, timerange and level dimensions in a
6294!! vol7d object are correctly sorted; on the other side many methods
6295!! strictly rely on this fact in order to work correctly. This method
6296!! performs a quick check and sorts the required dimensions only if
6297!! they are not sorted in ascending order yet, improving safety
6298!! without impairing much performance.
6299SUBROUTINE vol7d_smart_sort(this, lsort_time, lsort_timerange, lsort_level)
6300TYPE(vol7d),INTENT(INOUT) :: this !< object to be sorted
6301LOGICAL,OPTIONAL,INTENT(in) :: lsort_time !< if present and \a .TRUE., sort time dimension if it is not sorted in ascending order
6302LOGICAL,OPTIONAL,INTENT(in) :: lsort_timerange !< if present and \a .TRUE., sort timerange dimension if it is not sorted in ascending order
6303LOGICAL,OPTIONAL,INTENT(in) :: lsort_level !< if present and \a .TRUE., sort vertical level dimension if it is not sorted in ascending order
6304
6305INTEGER :: i
6306LOGICAL :: to_be_sorted
6307
6308to_be_sorted = .false.
6309CALL vol7d_alloc_vol(this) ! usual safety check
6310
6311IF (optio_log(lsort_time)) THEN
6312 DO i = 2, SIZE(this%time)
6313 IF (this%time(i) < this%time(i-1)) THEN
6314 to_be_sorted = .true.
6315 EXIT
6316 ENDIF
6317 ENDDO
6318ENDIF
6319IF (optio_log(lsort_timerange)) THEN
6320 DO i = 2, SIZE(this%timerange)
6321 IF (this%timerange(i) < this%timerange(i-1)) THEN
6322 to_be_sorted = .true.
6323 EXIT
6324 ENDIF
6325 ENDDO
6326ENDIF
6327IF (optio_log(lsort_level)) THEN
6328 DO i = 2, SIZE(this%level)
6329 IF (this%level(i) < this%level(i-1)) THEN
6330 to_be_sorted = .true.
6331 EXIT
6332 ENDIF
6333 ENDDO
6334ENDIF
6335
6336IF (to_be_sorted) CALL vol7d_reform(this, &
6337 lsort_time=lsort_time, lsort_timerange=lsort_timerange, lsort_level=lsort_level )
6338
6339END SUBROUTINE vol7d_smart_sort
6340
6341!> Filter the contents of a volume keeping only desired data.
6342!! This subroutine filters a vol7d object by keeping only a subset of
6343!! the data contained. It can keep only times within a specified
6344!! interval, only station networks contained in a list and only
6345!! specified station or data variables. If a filter parameter is not
6346!! provided, no filtering will take place according to that criterion.
6347!! The volume is reallocated keeping only the desired data.
6348SUBROUTINE vol7d_filter(this, avl, vl, nl, s_d, e_d)
6349TYPE(vol7d),INTENT(inout) :: this !< volume to be filtered
6350CHARACTER(len=*),INTENT(in),OPTIONAL :: avl(:) !< list of station variables to be kept, if not provided or of zero length, all variables are kept
6351CHARACTER(len=*),INTENT(in),OPTIONAL :: vl(:) !< list of data variables to be kept, if not provided or of zero length, all variables are kept
6352TYPE(vol7d_network),OPTIONAL :: nl(:) !< list of station networks to be kept, if not provided or of zero length, all networks are kept
6353TYPE(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
6354TYPE(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
6355
6356INTEGER :: i
6357
6358IF (PRESENT(avl)) THEN
6359 IF (SIZE(avl) > 0) THEN
6360
6361 IF (ASSOCIATED(this%anavar%r)) THEN
6362 DO i = 1, SIZE(this%anavar%r)
6363 IF (all(this%anavar%r(i)%btable /= avl)) this%anavar%r(i) = vol7d_var_miss
6364 ENDDO
6365 ENDIF
6366
6367 IF (ASSOCIATED(this%anavar%i)) THEN
6368 DO i = 1, SIZE(this%anavar%i)
6369 IF (all(this%anavar%i(i)%btable /= avl)) this%anavar%i(i) = vol7d_var_miss
6370 ENDDO
6371 ENDIF
6372
6373 IF (ASSOCIATED(this%anavar%b)) THEN
6374 DO i = 1, SIZE(this%anavar%b)
6375 IF (all(this%anavar%b(i)%btable /= avl)) this%anavar%b(i) = vol7d_var_miss
6376 ENDDO
6377 ENDIF
6378
6379 IF (ASSOCIATED(this%anavar%d)) THEN
6380 DO i = 1, SIZE(this%anavar%d)
6381 IF (all(this%anavar%d(i)%btable /= avl)) this%anavar%d(i) = vol7d_var_miss
6382 ENDDO
6383 ENDIF
6384
6385 IF (ASSOCIATED(this%anavar%c)) THEN
6386 DO i = 1, SIZE(this%anavar%c)
6387 IF (all(this%anavar%c(i)%btable /= avl)) this%anavar%c(i) = vol7d_var_miss
6388 ENDDO
6389 ENDIF
6390
6391 ENDIF
6392ENDIF
6393
6394
6395IF (PRESENT(vl)) THEN
6396 IF (size(vl) > 0) THEN
6397 IF (ASSOCIATED(this%dativar%r)) THEN
6398 DO i = 1, SIZE(this%dativar%r)
6399 IF (all(this%dativar%r(i)%btable /= vl)) this%dativar%r(i) = vol7d_var_miss
6400 ENDDO
6401 ENDIF
6402
6403 IF (ASSOCIATED(this%dativar%i)) THEN
6404 DO i = 1, SIZE(this%dativar%i)
6405 IF (all(this%dativar%i(i)%btable /= vl)) this%dativar%i(i) = vol7d_var_miss
6406 ENDDO
6407 ENDIF
6408
6409 IF (ASSOCIATED(this%dativar%b)) THEN
6410 DO i = 1, SIZE(this%dativar%b)
6411 IF (all(this%dativar%b(i)%btable /= vl)) this%dativar%b(i) = vol7d_var_miss
6412 ENDDO
6413 ENDIF
6414
6415 IF (ASSOCIATED(this%dativar%d)) THEN
6416 DO i = 1, SIZE(this%dativar%d)
6417 IF (all(this%dativar%d(i)%btable /= vl)) this%dativar%d(i) = vol7d_var_miss
6418 ENDDO
6419 ENDIF
6420
6421 IF (ASSOCIATED(this%dativar%c)) THEN
6422 DO i = 1, SIZE(this%dativar%c)
6423 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
6424 ENDDO
6425 ENDIF
6426
6427 IF (ASSOCIATED(this%dativar%c)) THEN
6428 DO i = 1, SIZE(this%dativar%c)
6429 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
6430 ENDDO
6431 ENDIF
6432
6433 ENDIF
6434ENDIF
6435
6436IF (PRESENT(nl)) THEN
6437 IF (SIZE(nl) > 0) THEN
6438 DO i = 1, SIZE(this%network)
6439 IF (all(this%network(i) /= nl)) this%network(i) = vol7d_network_miss
6440 ENDDO
6441 ENDIF
6442ENDIF
6443
6444IF (PRESENT(s_d)) THEN
6445 IF (c_e(s_d)) THEN
6446 WHERE (this%time < s_d)
6447 this%time = datetime_miss
6448 END WHERE
6449 ENDIF
6450ENDIF
6451
6452IF (PRESENT(e_d)) THEN
6453 IF (c_e(e_d)) THEN
6454 WHERE (this%time > e_d)
6455 this%time = datetime_miss
6456 END WHERE
6457 ENDIF
6458ENDIF
6459
6460CALL vol7d_reform(this, miss=.true.)
6461
6462END SUBROUTINE vol7d_filter
6463
6464
6465!> Metodo per convertire i volumi di dati di un oggetto vol7d in dati
6466!! reali dove possibile. L'oggetto convertito è una copia completa
6467!! dell'originale che può essere quindi distrutto dopo la chiamata.
6468!! Per i dati di anagrafica, al momento sono convertiti solo
6469!! i dati CHARACTER se è passato \a anaconv=.TRUE.
6470!! Gli attributi non sono toccati.
6471SUBROUTINE vol7d_convr(this, that, anaconv)
6472TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
6473TYPE(vol7d),INTENT(INOUT) :: that !< oggetto convertito
6474LOGICAL,OPTIONAL,INTENT(in) :: anaconv !< converti anche anagrafica
6475INTEGER :: i
6476LOGICAL :: fv(1)=(/.false./), tv(1)=(/.true./), acp(1), acn(1)
6477TYPE(vol7d) :: v7d_tmp
6478
6479IF (optio_log(anaconv)) THEN
6480 acp=fv
6481 acn=tv
6482ELSE
6483 acp=tv
6484 acn=fv
6485ENDIF
6486
6487! Volume con solo i dati reali e tutti gli attributi
6488! l'anagrafica e` copiata interamente se necessario
6489CALL vol7d_copy(this, that, &
6490 lanavarr=tv, lanavard=acp, lanavari=acp, lanavarb=acp, lanavarc=acp, &
6491 ldativarr=tv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=fv)
6492
6493! Volume solo di dati double
6494CALL vol7d_copy(this, v7d_tmp, &
6495 lanavarr=fv, lanavard=acn, lanavari=fv, lanavarb=fv, lanavarc=fv, &
6496 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
6497 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
6498 ldativarr=fv, ldativard=tv, ldativari=fv, ldativarb=fv, ldativarc=fv, &
6499 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
6500 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
6501
6502! converto a dati reali
6503IF (ASSOCIATED(v7d_tmp%anavar%d) .OR. ASSOCIATED(v7d_tmp%dativar%d)) THEN
6504
6505 IF (ASSOCIATED(v7d_tmp%anavar%d)) THEN
6506! alloco i dati reali e vi trasferisco i double
6507 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanad, 1), SIZE(v7d_tmp%volanad, 2), &
6508 SIZE(v7d_tmp%volanad, 3)))
6509 DO i = 1, SIZE(v7d_tmp%anavar%d)
6510 v7d_tmp%volanar(:,i,:) = &
6511 realdat(v7d_tmp%volanad(:,i,:), v7d_tmp%anavar%d(i))
6512 ENDDO
6513 DEALLOCATE(v7d_tmp%volanad)
6514! trasferisco le variabili
6515 v7d_tmp%anavar%r => v7d_tmp%anavar%d
6516 NULLIFY(v7d_tmp%anavar%d)
6517 ENDIF
6518
6519 IF (ASSOCIATED(v7d_tmp%dativar%d)) THEN
6520! alloco i dati reali e vi trasferisco i double
6521 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatid, 1), SIZE(v7d_tmp%voldatid, 2), &
6522 SIZE(v7d_tmp%voldatid, 3), SIZE(v7d_tmp%voldatid, 4), SIZE(v7d_tmp%voldatid, 5), &
6523 SIZE(v7d_tmp%voldatid, 6)))
6524 DO i = 1, SIZE(v7d_tmp%dativar%d)
6525 v7d_tmp%voldatir(:,:,:,:,i,:) = &
6526 realdat(v7d_tmp%voldatid(:,:,:,:,i,:), v7d_tmp%dativar%d(i))
6527 ENDDO
6528 DEALLOCATE(v7d_tmp%voldatid)
6529! trasferisco le variabili
6530 v7d_tmp%dativar%r => v7d_tmp%dativar%d
6531 NULLIFY(v7d_tmp%dativar%d)
6532 ENDIF
6533
6534! fondo con il volume definitivo
6535 CALL vol7d_merge(that, v7d_tmp)
6536ELSE
6537 CALL delete(v7d_tmp)
6538ENDIF
6539
6540
6541! Volume solo di dati interi
6542CALL vol7d_copy(this, v7d_tmp, &
6543 lanavarr=fv, lanavard=fv, lanavari=acn, lanavarb=fv, lanavarc=fv, &
6544 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
6545 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
6546 ldativarr=fv, ldativard=fv, ldativari=tv, ldativarb=fv, ldativarc=fv, &
6547 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
6548 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
6549
6550! converto a dati reali
6551IF (ASSOCIATED(v7d_tmp%anavar%i) .OR. ASSOCIATED(v7d_tmp%dativar%i)) THEN
6552
6553 IF (ASSOCIATED(v7d_tmp%anavar%i)) THEN
6554! alloco i dati reali e vi trasferisco gli interi
6555 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanai, 1), SIZE(v7d_tmp%volanai, 2), &
6556 SIZE(v7d_tmp%volanai, 3)))
6557 DO i = 1, SIZE(v7d_tmp%anavar%i)
6558 v7d_tmp%volanar(:,i,:) = &
6559 realdat(v7d_tmp%volanai(:,i,:), v7d_tmp%anavar%i(i))
6560 ENDDO
6561 DEALLOCATE(v7d_tmp%volanai)
6562! trasferisco le variabili
6563 v7d_tmp%anavar%r => v7d_tmp%anavar%i
6564 NULLIFY(v7d_tmp%anavar%i)
6565 ENDIF
6566
6567 IF (ASSOCIATED(v7d_tmp%dativar%i)) THEN
6568! alloco i dati reali e vi trasferisco gli interi
6569 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatii, 1), SIZE(v7d_tmp%voldatii, 2), &
6570 SIZE(v7d_tmp%voldatii, 3), SIZE(v7d_tmp%voldatii, 4), SIZE(v7d_tmp%voldatii, 5), &
6571 SIZE(v7d_tmp%voldatii, 6)))
6572 DO i = 1, SIZE(v7d_tmp%dativar%i)
6573 v7d_tmp%voldatir(:,:,:,:,i,:) = &
6574 realdat(v7d_tmp%voldatii(:,:,:,:,i,:), v7d_tmp%dativar%i(i))
6575 ENDDO
6576 DEALLOCATE(v7d_tmp%voldatii)
6577! trasferisco le variabili
6578 v7d_tmp%dativar%r => v7d_tmp%dativar%i
6579 NULLIFY(v7d_tmp%dativar%i)
6580 ENDIF
6581
6582! fondo con il volume definitivo
6583 CALL vol7d_merge(that, v7d_tmp)
6584ELSE
6585 CALL delete(v7d_tmp)
6586ENDIF
6587
6588
6589! Volume solo di dati byte
6590CALL vol7d_copy(this, v7d_tmp, &
6591 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=acn, lanavarc=fv, &
6592 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
6593 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
6594 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=tv, ldativarc=fv, &
6595 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
6596 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
6597
6598! converto a dati reali
6599IF (ASSOCIATED(v7d_tmp%anavar%b) .OR. ASSOCIATED(v7d_tmp%dativar%b)) THEN
6600
6601 IF (ASSOCIATED(v7d_tmp%anavar%b)) THEN
6602! alloco i dati reali e vi trasferisco i byte
6603 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanab, 1), SIZE(v7d_tmp%volanab, 2), &
6604 SIZE(v7d_tmp%volanab, 3)))
6605 DO i = 1, SIZE(v7d_tmp%anavar%b)
6606 v7d_tmp%volanar(:,i,:) = &
6607 realdat(v7d_tmp%volanab(:,i,:), v7d_tmp%anavar%b(i))
6608 ENDDO
6609 DEALLOCATE(v7d_tmp%volanab)
6610! trasferisco le variabili
6611 v7d_tmp%anavar%r => v7d_tmp%anavar%b
6612 NULLIFY(v7d_tmp%anavar%b)
6613 ENDIF
6614
6615 IF (ASSOCIATED(v7d_tmp%dativar%b)) THEN
6616! alloco i dati reali e vi trasferisco i byte
6617 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatib, 1), SIZE(v7d_tmp%voldatib, 2), &
6618 SIZE(v7d_tmp%voldatib, 3), SIZE(v7d_tmp%voldatib, 4), SIZE(v7d_tmp%voldatib, 5), &
6619 SIZE(v7d_tmp%voldatib, 6)))
6620 DO i = 1, SIZE(v7d_tmp%dativar%b)
6621 v7d_tmp%voldatir(:,:,:,:,i,:) = &
6622 realdat(v7d_tmp%voldatib(:,:,:,:,i,:), v7d_tmp%dativar%b(i))
6623 ENDDO
6624 DEALLOCATE(v7d_tmp%voldatib)
6625! trasferisco le variabili
6626 v7d_tmp%dativar%r => v7d_tmp%dativar%b
6627 NULLIFY(v7d_tmp%dativar%b)
6628 ENDIF
6629
6630! fondo con il volume definitivo
6631 CALL vol7d_merge(that, v7d_tmp)
6632ELSE
6633 CALL delete(v7d_tmp)
6634ENDIF
6635
6636
6637! Volume solo di dati character
6638CALL vol7d_copy(this, v7d_tmp, &
6639 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=fv, lanavarc=acn, &
6640 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
6641 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
6642 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=tv, &
6643 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
6644 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
6645
6646! converto a dati reali
6647IF (ASSOCIATED(v7d_tmp%anavar%c) .OR. ASSOCIATED(v7d_tmp%dativar%c)) THEN
6648
6649 IF (ASSOCIATED(v7d_tmp%anavar%c)) THEN
6650! alloco i dati reali e vi trasferisco i character
6651 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanac, 1), SIZE(v7d_tmp%volanac, 2), &
6652 SIZE(v7d_tmp%volanac, 3)))
6653 DO i = 1, SIZE(v7d_tmp%anavar%c)
6654 v7d_tmp%volanar(:,i,:) = &
6655 realdat(v7d_tmp%volanac(:,i,:), v7d_tmp%anavar%c(i))
6656 ENDDO
6657 DEALLOCATE(v7d_tmp%volanac)
6658! trasferisco le variabili
6659 v7d_tmp%anavar%r => v7d_tmp%anavar%c
6660 NULLIFY(v7d_tmp%anavar%c)
6661 ENDIF
6662
6663 IF (ASSOCIATED(v7d_tmp%dativar%c)) THEN
6664! alloco i dati reali e vi trasferisco i character
6665 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatic, 1), SIZE(v7d_tmp%voldatic, 2), &
6666 SIZE(v7d_tmp%voldatic, 3), SIZE(v7d_tmp%voldatic, 4), SIZE(v7d_tmp%voldatic, 5), &
6667 SIZE(v7d_tmp%voldatic, 6)))
6668 DO i = 1, SIZE(v7d_tmp%dativar%c)
6669 v7d_tmp%voldatir(:,:,:,:,i,:) = &
6670 realdat(v7d_tmp%voldatic(:,:,:,:,i,:), v7d_tmp%dativar%c(i))
6671 ENDDO
6672 DEALLOCATE(v7d_tmp%voldatic)
6673! trasferisco le variabili
6674 v7d_tmp%dativar%r => v7d_tmp%dativar%c
6675 NULLIFY(v7d_tmp%dativar%c)
6676 ENDIF
6677
6678! fondo con il volume definitivo
6679 CALL vol7d_merge(that, v7d_tmp)
6680ELSE
6681 CALL delete(v7d_tmp)
6682ENDIF
6683
6684END SUBROUTINE vol7d_convr
6685
6686
6687!> Metodo per ottenere solo le differenze tra due oggetti vol7d.
6688!! Il primo volume viene confrontato col secondo; nel secondo volume ovunque
6689!! i dati confrontati siano coincidenti viene impostato valore mancante.
6690SUBROUTINE vol7d_diff_only (this, that, data_only,ana)
6691TYPE(vol7d),INTENT(IN) :: this !< primo volume da confrontare
6692TYPE(vol7d),INTENT(OUT) :: that !< secondo volume da confrontare in cui eliminare i dati coincidenti
6693logical , optional, intent(in) :: data_only !< attiva l'elaborazione dei soli dati e non dell'anagrafica (default: .false.)
6694logical , optional, intent(in) :: ana !< attiva l'elaborazione dell'anagrafica (coordinate e ident) (default: .false.)
6695logical :: ldata_only,lana
6696
6697IF (PRESENT(data_only)) THEN
6698 ldata_only = data_only
6699ELSE
6700 ldata_only = .false.
6701ENDIF
6702
6703IF (PRESENT(ana)) THEN
6704 lana = ana
6705ELSE
6706 lana = .false.
6707ENDIF
6708
6709
6710#undef VOL7D_POLY_ARRAY
6711#define VOL7D_POLY_ARRAY voldati
6712#include "vol7d_class_diff.F90"
6713#undef VOL7D_POLY_ARRAY
6714#define VOL7D_POLY_ARRAY voldatiattr
6715#include "vol7d_class_diff.F90"
6716#undef VOL7D_POLY_ARRAY
6717
6718if ( .not. ldata_only) then
6719
6720#define VOL7D_POLY_ARRAY volana
6721#include "vol7d_class_diff.F90"
6722#undef VOL7D_POLY_ARRAY
6723#define VOL7D_POLY_ARRAY volanaattr
6724#include "vol7d_class_diff.F90"
6725#undef VOL7D_POLY_ARRAY
6726
6727 if(lana)then
6728 where ( this%ana == that%ana )
6729 that%ana = vol7d_ana_miss
6730 end where
6731 end if
6732
6733end if
6734
6735
6736
6737END SUBROUTINE vol7d_diff_only
6738
6739
6740
6741! Creo le routine da ripetere per i vari tipi di dati di v7d
6742! tramite un template e il preprocessore
6743#undef VOL7D_POLY_TYPE
6744#undef VOL7D_POLY_TYPES
6745#define VOL7D_POLY_TYPE REAL
6746#define VOL7D_POLY_TYPES r
6747#include "vol7d_class_type_templ.F90"
6748#undef VOL7D_POLY_TYPE
6749#undef VOL7D_POLY_TYPES
6750#define VOL7D_POLY_TYPE DOUBLE PRECISION
6751#define VOL7D_POLY_TYPES d
6752#include "vol7d_class_type_templ.F90"
6753#undef VOL7D_POLY_TYPE
6754#undef VOL7D_POLY_TYPES
6755#define VOL7D_POLY_TYPE INTEGER
6756#define VOL7D_POLY_TYPES i
6757#include "vol7d_class_type_templ.F90"
6758#undef VOL7D_POLY_TYPE
6759#undef VOL7D_POLY_TYPES
6760#define VOL7D_POLY_TYPE INTEGER(kind=int_b)
6761#define VOL7D_POLY_TYPES b
6762#include "vol7d_class_type_templ.F90"
6763#undef VOL7D_POLY_TYPE
6764#undef VOL7D_POLY_TYPES
6765#define VOL7D_POLY_TYPE CHARACTER(len=vol7d_cdatalen)
6766#define VOL7D_POLY_TYPES c
6767#include "vol7d_class_type_templ.F90"
6768
6769! Creo le routine da ripetere per i vari descrittori di dimensioni di v7d
6770! tramite un template e il preprocessore
6771#define VOL7D_SORT
6772#undef VOL7D_NO_ZERO_ALLOC
6773#undef VOL7D_POLY_TYPE
6774#define VOL7D_POLY_TYPE datetime
6775#include "vol7d_class_desc_templ.F90"
6776#undef VOL7D_POLY_TYPE
6777#define VOL7D_POLY_TYPE vol7d_timerange
6778#include "vol7d_class_desc_templ.F90"
6779#undef VOL7D_POLY_TYPE
6780#define VOL7D_POLY_TYPE vol7d_level
6781#include "vol7d_class_desc_templ.F90"
6782#undef VOL7D_SORT
6783#undef VOL7D_POLY_TYPE
6784#define VOL7D_POLY_TYPE vol7d_network
6785#include "vol7d_class_desc_templ.F90"
6786#undef VOL7D_POLY_TYPE
6787#define VOL7D_POLY_TYPE vol7d_ana
6788#include "vol7d_class_desc_templ.F90"
6789#define VOL7D_NO_ZERO_ALLOC
6790#undef VOL7D_POLY_TYPE
6791#define VOL7D_POLY_TYPE vol7d_var
6792#include "vol7d_class_desc_templ.F90"
6793
6794!>\brief Scrittura su file di un volume Vol7d.
6795!! Scrittura su file unformatted di un intero volume Vol7d.
6796!! Il volume viene serializzato e scritto su file.
6797!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
6798!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
6799!! tali parametri saranno in output.
6800!! Se non viene fornito il nome file viene utilizzato un file di default con nome pari al nome del programma in
6801!! esecuzione con postfisso ".v7d".
6802!! Come parametro opzionale c'è la description che insieme alla data corrente viene inserita nell'header del file.
6803subroutine vol7d_write_on_file (this,unit,description,filename,filename_auto)
6804
6805TYPE(vol7d),INTENT(IN) :: this !< volume vol7d da scrivere
6806integer,optional,intent(inout) :: unit !< unità su cui scrivere; se passata =0 ritorna il valore rielaborato (default =rielaborato internamente con getlun )
6807character(len=*),intent(in),optional :: filename !< nome del file su cui scrivere
6808character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
6809character(len=*),INTENT(IN),optional :: description !< descrizione del volume
6810
6811integer :: lunit
6812character(len=254) :: ldescription,arg,lfilename
6813integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
6814 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
6815 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
6816 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
6817 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
6818 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
6819 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
6820!integer :: im,id,iy
6821integer :: tarray(8)
6822logical :: opened,exist
6823
6824 nana=0
6825 ntime=0
6826 ntimerange=0
6827 nlevel=0
6828 nnetwork=0
6829 ndativarr=0
6830 ndativari=0
6831 ndativarb=0
6832 ndativard=0
6833 ndativarc=0
6834 ndatiattrr=0
6835 ndatiattri=0
6836 ndatiattrb=0
6837 ndatiattrd=0
6838 ndatiattrc=0
6839 ndativarattrr=0
6840 ndativarattri=0
6841 ndativarattrb=0
6842 ndativarattrd=0
6843 ndativarattrc=0
6844 nanavarr=0
6845 nanavari=0
6846 nanavarb=0
6847 nanavard=0
6848 nanavarc=0
6849 nanaattrr=0
6850 nanaattri=0
6851 nanaattrb=0
6852 nanaattrd=0
6853 nanaattrc=0
6854 nanavarattrr=0
6855 nanavarattri=0
6856 nanavarattrb=0
6857 nanavarattrd=0
6858 nanavarattrc=0
6859
6860
6861!call idate(im,id,iy)
6862call date_and_time(values=tarray)
6863call getarg(0,arg)
6864
6865if (present(description))then
6866 ldescription=description
6867else
6868 ldescription="Vol7d generated by: "//trim(arg)
6869end if
6870
6871if (.not. present(unit))then
6872 lunit=getunit()
6873else
6874 if (unit==0)then
6875 lunit=getunit()
6876 unit=lunit
6877 else
6878 lunit=unit
6879 end if
6880end if
6881
6882lfilename=trim(arg)//".v7d"
6883if (index(arg,'/',back=.true.) > 0) lfilename=lfilename(index(arg,'/',back=.true.)+1 : )
6884
6885if (present(filename))then
6886 if (filename /= "")then
6887 lfilename=filename
6888 end if
6889end if
6890
6891if (present(filename_auto))filename_auto=lfilename
6892
6893
6894inquire(unit=lunit,opened=opened)
6895if (.not. opened) then
6896! inquire(file=lfilename, EXIST=exist)
6897! IF (exist) THEN
6898! CALL l4f_log(L4F_FATAL, &
6899! 'in vol7d_write_on_file, file exists, cannot open file '//TRIM(lfilename))
6900! CALL raise_fatal_error()
6901! ENDIF
6902 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM')
6903 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
6904end if
6905
6906if (associated(this%ana)) nana=size(this%ana)
6907if (associated(this%time)) ntime=size(this%time)
6908if (associated(this%timerange)) ntimerange=size(this%timerange)
6909if (associated(this%level)) nlevel=size(this%level)
6910if (associated(this%network)) nnetwork=size(this%network)
6911
6912if (associated(this%dativar%r)) ndativarr=size(this%dativar%r)
6913if (associated(this%dativar%i)) ndativari=size(this%dativar%i)
6914if (associated(this%dativar%b)) ndativarb=size(this%dativar%b)
6915if (associated(this%dativar%d)) ndativard=size(this%dativar%d)
6916if (associated(this%dativar%c)) ndativarc=size(this%dativar%c)
6917
6918if (associated(this%datiattr%r)) ndatiattrr=size(this%datiattr%r)
6919if (associated(this%datiattr%i)) ndatiattri=size(this%datiattr%i)
6920if (associated(this%datiattr%b)) ndatiattrb=size(this%datiattr%b)
6921if (associated(this%datiattr%d)) ndatiattrd=size(this%datiattr%d)
6922if (associated(this%datiattr%c)) ndatiattrc=size(this%datiattr%c)
6923
6924if (associated(this%dativarattr%r)) ndativarattrr=size(this%dativarattr%r)
6925if (associated(this%dativarattr%i)) ndativarattri=size(this%dativarattr%i)
6926if (associated(this%dativarattr%b)) ndativarattrb=size(this%dativarattr%b)
6927if (associated(this%dativarattr%d)) ndativarattrd=size(this%dativarattr%d)
6928if (associated(this%dativarattr%c)) ndativarattrc=size(this%dativarattr%c)
6929
6930if (associated(this%anavar%r)) nanavarr=size(this%anavar%r)
6931if (associated(this%anavar%i)) nanavari=size(this%anavar%i)
6932if (associated(this%anavar%b)) nanavarb=size(this%anavar%b)
6933if (associated(this%anavar%d)) nanavard=size(this%anavar%d)
6934if (associated(this%anavar%c)) nanavarc=size(this%anavar%c)
6935
6936if (associated(this%anaattr%r)) nanaattrr=size(this%anaattr%r)
6937if (associated(this%anaattr%i)) nanaattri=size(this%anaattr%i)
6938if (associated(this%anaattr%b)) nanaattrb=size(this%anaattr%b)
6939if (associated(this%anaattr%d)) nanaattrd=size(this%anaattr%d)
6940if (associated(this%anaattr%c)) nanaattrc=size(this%anaattr%c)
6941
6942if (associated(this%anavarattr%r)) nanavarattrr=size(this%anavarattr%r)
6943if (associated(this%anavarattr%i)) nanavarattri=size(this%anavarattr%i)
6944if (associated(this%anavarattr%b)) nanavarattrb=size(this%anavarattr%b)
6945if (associated(this%anavarattr%d)) nanavarattrd=size(this%anavarattr%d)
6946if (associated(this%anavarattr%c)) nanavarattrc=size(this%anavarattr%c)
6947
6948write(unit=lunit)ldescription
6949write(unit=lunit)tarray
6950
6951write(unit=lunit)&
6952 nana, ntime, ntimerange, nlevel, nnetwork, &
6953 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
6954 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
6955 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
6956 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
6957 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
6958 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
6959 this%time_definition
6960
6961
6962!write(unit=lunit)this
6963
6964
6965!! prime 5 dimensioni
6966if (associated(this%ana)) call write_unit(this%ana, lunit)
6967if (associated(this%time)) call write_unit(this%time, lunit)
6968if (associated(this%level)) write(unit=lunit)this%level
6969if (associated(this%timerange)) write(unit=lunit)this%timerange
6970if (associated(this%network)) write(unit=lunit)this%network
6971
6972 !! 6a dimensione: variabile dell'anagrafica e dei dati
6973 !! con relativi attributi e in 5 tipi diversi
6974
6975if (associated(this%anavar%r)) write(unit=lunit)this%anavar%r
6976if (associated(this%anavar%i)) write(unit=lunit)this%anavar%i
6977if (associated(this%anavar%b)) write(unit=lunit)this%anavar%b
6978if (associated(this%anavar%d)) write(unit=lunit)this%anavar%d
6979if (associated(this%anavar%c)) write(unit=lunit)this%anavar%c
6980
6981if (associated(this%anaattr%r)) write(unit=lunit)this%anaattr%r
6982if (associated(this%anaattr%i)) write(unit=lunit)this%anaattr%i
6983if (associated(this%anaattr%b)) write(unit=lunit)this%anaattr%b
6984if (associated(this%anaattr%d)) write(unit=lunit)this%anaattr%d
6985if (associated(this%anaattr%c)) write(unit=lunit)this%anaattr%c
6986
6987if (associated(this%anavarattr%r)) write(unit=lunit)this%anavarattr%r
6988if (associated(this%anavarattr%i)) write(unit=lunit)this%anavarattr%i
6989if (associated(this%anavarattr%b)) write(unit=lunit)this%anavarattr%b
6990if (associated(this%anavarattr%d)) write(unit=lunit)this%anavarattr%d
6991if (associated(this%anavarattr%c)) write(unit=lunit)this%anavarattr%c
6992
6993if (associated(this%dativar%r)) write(unit=lunit)this%dativar%r
6994if (associated(this%dativar%i)) write(unit=lunit)this%dativar%i
6995if (associated(this%dativar%b)) write(unit=lunit)this%dativar%b
6996if (associated(this%dativar%d)) write(unit=lunit)this%dativar%d
6997if (associated(this%dativar%c)) write(unit=lunit)this%dativar%c
6998
6999if (associated(this%datiattr%r)) write(unit=lunit)this%datiattr%r
7000if (associated(this%datiattr%i)) write(unit=lunit)this%datiattr%i
7001if (associated(this%datiattr%b)) write(unit=lunit)this%datiattr%b
7002if (associated(this%datiattr%d)) write(unit=lunit)this%datiattr%d
7003if (associated(this%datiattr%c)) write(unit=lunit)this%datiattr%c
7004
7005if (associated(this%dativarattr%r)) write(unit=lunit)this%dativarattr%r
7006if (associated(this%dativarattr%i)) write(unit=lunit)this%dativarattr%i
7007if (associated(this%dativarattr%b)) write(unit=lunit)this%dativarattr%b
7008if (associated(this%dativarattr%d)) write(unit=lunit)this%dativarattr%d
7009if (associated(this%dativarattr%c)) write(unit=lunit)this%dativarattr%c
7010
7011!! Volumi di valori e attributi per anagrafica e dati
7012
7013if (associated(this%volanar)) write(unit=lunit)this%volanar
7014if (associated(this%volanaattrr)) write(unit=lunit)this%volanaattrr
7015if (associated(this%voldatir)) write(unit=lunit)this%voldatir
7016if (associated(this%voldatiattrr)) write(unit=lunit)this%voldatiattrr
7017
7018if (associated(this%volanai)) write(unit=lunit)this%volanai
7019if (associated(this%volanaattri)) write(unit=lunit)this%volanaattri
7020if (associated(this%voldatii)) write(unit=lunit)this%voldatii
7021if (associated(this%voldatiattri)) write(unit=lunit)this%voldatiattri
7022
7023if (associated(this%volanab)) write(unit=lunit)this%volanab
7024if (associated(this%volanaattrb)) write(unit=lunit)this%volanaattrb
7025if (associated(this%voldatib)) write(unit=lunit)this%voldatib
7026if (associated(this%voldatiattrb)) write(unit=lunit)this%voldatiattrb
7027
7028if (associated(this%volanad)) write(unit=lunit)this%volanad
7029if (associated(this%volanaattrd)) write(unit=lunit)this%volanaattrd
7030if (associated(this%voldatid)) write(unit=lunit)this%voldatid
7031if (associated(this%voldatiattrd)) write(unit=lunit)this%voldatiattrd
7032
7033if (associated(this%volanac)) write(unit=lunit)this%volanac
7034if (associated(this%volanaattrc)) write(unit=lunit)this%volanaattrc
7035if (associated(this%voldatic)) write(unit=lunit)this%voldatic
7036if (associated(this%voldatiattrc)) write(unit=lunit)this%voldatiattrc
7037
7038if (.not. present(unit)) close(unit=lunit)
7039
7040end subroutine vol7d_write_on_file
7041
7042
7043!>\brief Lettura da file di un volume Vol7d.
7044!! Lettura da file unformatted di un intero volume Vol7d.
7045!! Questa subroutine comprende vol7d_alloc e vol7d_alloc_vol.
7046!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
7047!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
7048!! tali parametri saranno in output.
7049
7050
7051subroutine vol7d_read_from_file (this,unit,filename,description,tarray,filename_auto)
7052
7053TYPE(vol7d),INTENT(OUT) :: this !< Volume vol7d da leggere
7054integer,intent(inout),optional :: unit !< unità su cui è stato aperto un file; se =0 rielaborato internamente (default = elaborato internamente con getunit)
7055character(len=*),INTENT(in),optional :: filename !< nome del file eventualmente da aprire (default = (nome dell'eseguibile)//.v7d )
7056character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
7057character(len=*),INTENT(out),optional :: description !< descrizione del volume letto
7058integer,intent(out),optional :: tarray(8) !< vettore come definito da "date_and_time" della data di scrittura del volume
7059
7060
7061integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
7062 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
7063 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
7064 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
7065 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
7066 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
7067 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
7068
7069character(len=254) :: ldescription,lfilename,arg
7070integer :: ltarray(8),lunit,ios
7071logical :: opened,exist
7072
7073
7074call getarg(0,arg)
7075
7076if (.not. present(unit))then
7077 lunit=getunit()
7078else
7079 if (unit==0)then
7080 lunit=getunit()
7081 unit=lunit
7082 else
7083 lunit=unit
7084 end if
7085end if
7086
7087lfilename=trim(arg)//".v7d"
7088if (index(arg,'/',back=.true.) > 0) lfilename=lfilename(index(arg,'/',back=.true.)+1 : )
7089
7090if (present(filename))then
7091 if (filename /= "")then
7092 lfilename=filename
7093 end if
7094end if
7095
7096if (present(filename_auto))filename_auto=lfilename
7097
7098
7099inquire(unit=lunit,opened=opened)
7100IF (.NOT. opened) THEN
7101 inquire(file=lfilename,exist=exist)
7102 IF (.NOT.exist) THEN
7103 CALL l4f_log(l4f_fatal, &
7104 'in vol7d_read_from_file, file does not exists, cannot open')
7105 CALL raise_fatal_error()
7106 ENDIF
7107 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM', &
7108 status='OLD', action='READ')
7109 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
7110end if
7111
7112
7113call init(this)
7114read(unit=lunit,iostat=ios)ldescription
7115
7116if (ios < 0) then ! A negative value indicates that the End of File or End of Record
7117 call vol7d_alloc (this)
7118 call vol7d_alloc_vol (this)
7119 if (present(description))description=ldescription
7120 if (present(tarray))tarray=ltarray
7121 if (.not. present(unit)) close(unit=lunit)
7122end if
7123
7124read(unit=lunit)ltarray
7125
7126CALL l4f_log(l4f_info, 'Reading vol7d from file')
7127CALL l4f_log(l4f_info, 'description: '//trim(ldescription))
7128CALL l4f_log(l4f_info, 'written on '//trim(to_char(ltarray(1)))//' '// &
7129 trim(to_char(ltarray(2)))//' '//trim(to_char(ltarray(3))))
7130
7131if (present(description))description=ldescription
7132if (present(tarray))tarray=ltarray
7133
7134read(unit=lunit)&
7135 nana, ntime, ntimerange, nlevel, nnetwork, &
7136 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
7137 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
7138 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
7139 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
7140 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
7141 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
7142 this%time_definition
7143
7144call vol7d_alloc (this, &
7145 nana=nana, ntime=ntime, ntimerange=ntimerange, nlevel=nlevel, nnetwork=nnetwork,&
7146 ndativarr=ndativarr, ndativari=ndativari, ndativarb=ndativarb,&
7147 ndativard=ndativard, ndativarc=ndativarc,&
7148 ndatiattrr=ndatiattrr, ndatiattri=ndatiattri, ndatiattrb=ndatiattrb,&
7149 ndatiattrd=ndatiattrd, ndatiattrc=ndatiattrc,&
7150 ndativarattrr=ndativarattrr, ndativarattri=ndativarattri, ndativarattrb=ndativarattrb, &
7151 ndativarattrd=ndativarattrd, ndativarattrc=ndativarattrc,&
7152 nanavarr=nanavarr, nanavari=nanavari, nanavarb=nanavarb, &
7153 nanavard=nanavard, nanavarc=nanavarc,&
7154 nanaattrr=nanaattrr, nanaattri=nanaattri, nanaattrb=nanaattrb,&
7155 nanaattrd=nanaattrd, nanaattrc=nanaattrc,&
7156 nanavarattrr=nanavarattrr, nanavarattri=nanavarattri, nanavarattrb=nanavarattrb, &
7157 nanavarattrd=nanavarattrd, nanavarattrc=nanavarattrc)
7158
7159
7160if (associated(this%ana)) call read_unit(this%ana, lunit)
7161if (associated(this%time)) call read_unit(this%time, lunit)
7162if (associated(this%level)) read(unit=lunit)this%level
7163if (associated(this%timerange)) read(unit=lunit)this%timerange
7164if (associated(this%network)) read(unit=lunit)this%network
7165
7166if (associated(this%anavar%r)) read(unit=lunit)this%anavar%r
7167if (associated(this%anavar%i)) read(unit=lunit)this%anavar%i
7168if (associated(this%anavar%b)) read(unit=lunit)this%anavar%b
7169if (associated(this%anavar%d)) read(unit=lunit)this%anavar%d
7170if (associated(this%anavar%c)) read(unit=lunit)this%anavar%c
7171
7172if (associated(this%anaattr%r)) read(unit=lunit)this%anaattr%r
7173if (associated(this%anaattr%i)) read(unit=lunit)this%anaattr%i
7174if (associated(this%anaattr%b)) read(unit=lunit)this%anaattr%b
7175if (associated(this%anaattr%d)) read(unit=lunit)this%anaattr%d
7176if (associated(this%anaattr%c)) read(unit=lunit)this%anaattr%c
7177
7178if (associated(this%anavarattr%r)) read(unit=lunit)this%anavarattr%r
7179if (associated(this%anavarattr%i)) read(unit=lunit)this%anavarattr%i
7180if (associated(this%anavarattr%b)) read(unit=lunit)this%anavarattr%b
7181if (associated(this%anavarattr%d)) read(unit=lunit)this%anavarattr%d
7182if (associated(this%anavarattr%c)) read(unit=lunit)this%anavarattr%c
7183
7184if (associated(this%dativar%r)) read(unit=lunit)this%dativar%r
7185if (associated(this%dativar%i)) read(unit=lunit)this%dativar%i
7186if (associated(this%dativar%b)) read(unit=lunit)this%dativar%b
7187if (associated(this%dativar%d)) read(unit=lunit)this%dativar%d
7188if (associated(this%dativar%c)) read(unit=lunit)this%dativar%c
7189
7190if (associated(this%datiattr%r)) read(unit=lunit)this%datiattr%r
7191if (associated(this%datiattr%i)) read(unit=lunit)this%datiattr%i
7192if (associated(this%datiattr%b)) read(unit=lunit)this%datiattr%b
7193if (associated(this%datiattr%d)) read(unit=lunit)this%datiattr%d
7194if (associated(this%datiattr%c)) read(unit=lunit)this%datiattr%c
7195
7196if (associated(this%dativarattr%r)) read(unit=lunit)this%dativarattr%r
7197if (associated(this%dativarattr%i)) read(unit=lunit)this%dativarattr%i
7198if (associated(this%dativarattr%b)) read(unit=lunit)this%dativarattr%b
7199if (associated(this%dativarattr%d)) read(unit=lunit)this%dativarattr%d
7200if (associated(this%dativarattr%c)) read(unit=lunit)this%dativarattr%c
7201
7202call vol7d_alloc_vol (this)
7203
7204!! Volumi di valori e attributi per anagrafica e dati
7205
7206if (associated(this%volanar)) read(unit=lunit)this%volanar
7207if (associated(this%volanaattrr)) read(unit=lunit)this%volanaattrr
7208if (associated(this%voldatir)) read(unit=lunit)this%voldatir
7209if (associated(this%voldatiattrr)) read(unit=lunit)this%voldatiattrr
7210
7211if (associated(this%volanai)) read(unit=lunit)this%volanai
7212if (associated(this%volanaattri)) read(unit=lunit)this%volanaattri
7213if (associated(this%voldatii)) read(unit=lunit)this%voldatii
7214if (associated(this%voldatiattri)) read(unit=lunit)this%voldatiattri
7215
7216if (associated(this%volanab)) read(unit=lunit)this%volanab
7217if (associated(this%volanaattrb)) read(unit=lunit)this%volanaattrb
7218if (associated(this%voldatib)) read(unit=lunit)this%voldatib
7219if (associated(this%voldatiattrb)) read(unit=lunit)this%voldatiattrb
7220
7221if (associated(this%volanad)) read(unit=lunit)this%volanad
7222if (associated(this%volanaattrd)) read(unit=lunit)this%volanaattrd
7223if (associated(this%voldatid)) read(unit=lunit)this%voldatid
7224if (associated(this%voldatiattrd)) read(unit=lunit)this%voldatiattrd
7225
7226if (associated(this%volanac)) read(unit=lunit)this%volanac
7227if (associated(this%volanaattrc)) read(unit=lunit)this%volanaattrc
7228if (associated(this%voldatic)) read(unit=lunit)this%voldatic
7229if (associated(this%voldatiattrc)) read(unit=lunit)this%voldatiattrc
7230
7231if (.not. present(unit)) close(unit=lunit)
7232
7233end subroutine vol7d_read_from_file
7234
7235
7236! to double precision
7237elemental doubleprecision function doubledatd(voldat,var)
7238doubleprecision,intent(in) :: voldat
7239type(vol7d_var),intent(in) :: var
7240
7241doubledatd=voldat
7242
7243end function doubledatd
7244
7245
7246elemental doubleprecision function doubledatr(voldat,var)
7247real,intent(in) :: voldat
7248type(vol7d_var),intent(in) :: var
7249
7250if (c_e(voldat))then
7251 doubledatr=dble(voldat)
7252else
7253 doubledatr=dmiss
7254end if
7255
7256end function doubledatr
7257
7258
7259elemental doubleprecision function doubledati(voldat,var)
7260integer,intent(in) :: voldat
7261type(vol7d_var),intent(in) :: var
7262
7263if (c_e(voldat)) then
7264 if (c_e(var%scalefactor))then
7265 doubledati=dble(voldat)/10.d0**var%scalefactor
7266 else
7267 doubledati=dble(voldat)
7268 endif
7269else
7270 doubledati=dmiss
7271end if
7272
7273end function doubledati
7274
7275
7276elemental doubleprecision function doubledatb(voldat,var)
7277integer(kind=int_b),intent(in) :: voldat
7278type(vol7d_var),intent(in) :: var
7279
7280if (c_e(voldat)) then
7281 if (c_e(var%scalefactor))then
7282 doubledatb=dble(voldat)/10.d0**var%scalefactor
7283 else
7284 doubledatb=dble(voldat)
7285 endif
7286else
7287 doubledatb=dmiss
7288end if
7289
7290end function doubledatb
7291
7292
7293elemental doubleprecision function doubledatc(voldat,var)
7294CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
7295type(vol7d_var),intent(in) :: var
7296
7297doubledatc = c2d(voldat)
7298if (c_e(doubledatc) .and. c_e(var%scalefactor))then
7299 doubledatc=doubledatc/10.d0**var%scalefactor
7300end if
7301
7302end function doubledatc
7303
7304
7305! to integer
7306elemental integer function integerdatd(voldat,var)
7307doubleprecision,intent(in) :: voldat
7308type(vol7d_var),intent(in) :: var
7309
7310if (c_e(voldat))then
7311 if (c_e(var%scalefactor)) then
7312 integerdatd=nint(voldat*10d0**var%scalefactor)
7313 else
7314 integerdatd=nint(voldat)
7315 endif
7316else
7317 integerdatd=imiss
7318end if
7319
7320end function integerdatd
7321
7322
7323elemental integer function integerdatr(voldat,var)
7324real,intent(in) :: voldat
7325type(vol7d_var),intent(in) :: var
7326
7327if (c_e(voldat))then
7328 if (c_e(var%scalefactor)) then
7329 integerdatr=nint(voldat*10d0**var%scalefactor)
7330 else
7331 integerdatr=nint(voldat)
7332 endif
7333else
7334 integerdatr=imiss
7335end if
7336
7337end function integerdatr
7338
7339
7340elemental integer function integerdati(voldat,var)
7341integer,intent(in) :: voldat
7342type(vol7d_var),intent(in) :: var
7343
7344integerdati=voldat
7345
7346end function integerdati
7347
7348
7349elemental integer function integerdatb(voldat,var)
7350integer(kind=int_b),intent(in) :: voldat
7351type(vol7d_var),intent(in) :: var
7352
7353if (c_e(voldat))then
7354 integerdatb=voldat
7355else
7356 integerdatb=imiss
7357end if
7358
7359end function integerdatb
7360
7361
7362elemental integer function integerdatc(voldat,var)
7363CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
7364type(vol7d_var),intent(in) :: var
7365
7366integerdatc=c2i(voldat)
7367
7368end function integerdatc
7369
7370
7371! to real
7372elemental real function realdatd(voldat,var)
7373doubleprecision,intent(in) :: voldat
7374type(vol7d_var),intent(in) :: var
7375
7376if (c_e(voldat))then
7377 realdatd=real(voldat)
7378else
7379 realdatd=rmiss
7380end if
7381
7382end function realdatd
7383
7384
7385elemental real function realdatr(voldat,var)
7386real,intent(in) :: voldat
7387type(vol7d_var),intent(in) :: var
7388
7389realdatr=voldat
7390
7391end function realdatr
7392
7393
7394elemental real function realdati(voldat,var)
7395integer,intent(in) :: voldat
7396type(vol7d_var),intent(in) :: var
7397
7398if (c_e(voldat)) then
7399 if (c_e(var%scalefactor))then
7400 realdati=float(voldat)/10.**var%scalefactor
7401 else
7402 realdati=float(voldat)
7403 endif
7404else
7405 realdati=rmiss
7406end if
7407
7408end function realdati
7409
7410
7411elemental real function realdatb(voldat,var)
7412integer(kind=int_b),intent(in) :: voldat
7413type(vol7d_var),intent(in) :: var
7414
7415if (c_e(voldat)) then
7416 if (c_e(var%scalefactor))then
7417 realdatb=float(voldat)/10**var%scalefactor
7418 else
7419 realdatb=float(voldat)
7420 endif
7421else
7422 realdatb=rmiss
7423end if
7424
7425end function realdatb
7426
7427
7428elemental real function realdatc(voldat,var)
7429CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
7430type(vol7d_var),intent(in) :: var
7431
7432realdatc=c2r(voldat)
7433if (c_e(realdatc) .and. c_e(var%scalefactor))then
7434 realdatc=realdatc/10.**var%scalefactor
7435end if
7436
7437end function realdatc
7438
7439
7440!> Return an ana volume of a requested variable as real data.
7441!! It returns a 2-d array of the proper shape (ana x network) for the
7442!! ana variable requested, converted to real type. If the conversion
7443!! fails or if the variable is not contained in the ana volume,
7444!! missing data are returned.
7445FUNCTION realanavol(this, var) RESULT(vol)
7446TYPE(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
7447TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
7448REAL :: vol(SIZE(this%ana),size(this%network))
7449
7450CHARACTER(len=1) :: dtype
7451INTEGER :: indvar
7452
7453dtype = cmiss
7454indvar = index(this%anavar, var, type=dtype)
7455
7456IF (indvar > 0) THEN
7457 SELECT CASE (dtype)
7458 CASE("d")
7459 vol = realdat(this%volanad(:,indvar,:), var)
7460 CASE("r")
7461 vol = this%volanar(:,indvar,:)
7462 CASE("i")
7463 vol = realdat(this%volanai(:,indvar,:), var)
7464 CASE("b")
7465 vol = realdat(this%volanab(:,indvar,:), var)
7466 CASE("c")
7467 vol = realdat(this%volanac(:,indvar,:), var)
7468 CASE default
7469 vol = rmiss
7470 END SELECT
7471ELSE
7472 vol = rmiss
7473ENDIF
7474
7475END FUNCTION realanavol
7476
7477
7478!> Return an ana volume of a requested variable as integer data.
7479!! It returns a 2-d array of the proper shape (ana x network) for the
7480!! ana variable requested, converted to integer type. If the conversion
7481!! fails or if the variable is not contained in the ana volume,
7482!! missing data are returned.
7483FUNCTION integeranavol(this, var) RESULT(vol)
7484TYPE(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
7485TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
7486INTEGER :: vol(SIZE(this%ana),size(this%network))
7487
7488CHARACTER(len=1) :: dtype
7489INTEGER :: indvar
7490
7491dtype = cmiss
7492indvar = index(this%anavar, var, type=dtype)
7493
7494IF (indvar > 0) THEN
7495 SELECT CASE (dtype)
7496 CASE("d")
7497 vol = integerdat(this%volanad(:,indvar,:), var)
7498 CASE("r")
7499 vol = integerdat(this%volanar(:,indvar,:), var)
7500 CASE("i")
7501 vol = this%volanai(:,indvar,:)
7502 CASE("b")
7503 vol = integerdat(this%volanab(:,indvar,:), var)
7504 CASE("c")
7505 vol = integerdat(this%volanac(:,indvar,:), var)
7506 CASE default
7507 vol = imiss
7508 END SELECT
7509ELSE
7510 vol = imiss
7511ENDIF
7512
7513END FUNCTION integeranavol
7514
7515
7516!> Move data for all variables from one coordinate in the character volume to other.
7517!! Only not missing data will be copyed and all attributes will be moved together.
7518!! Usefull to colapse data spread in more indices (level or time or ....).
7519!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
7520!! to obtain a new vol7d with less data shape.
7521subroutine move_datac (v7d,&
7522 indana,indtime,indlevel,indtimerange,indnetwork,&
7523 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
7524
7525TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
7526
7527integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
7528integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
7529integer :: inddativar,inddativarattr
7530
7531
7532do inddativar=1,size(v7d%dativar%c)
7533
7534 if (c_e(v7d%voldatic(indana,indtime,indlevel,indtimerange,inddativar,indnetwork)) .and. &
7535 .not. c_e(v7d%voldatic(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
7536 ) then
7537
7538 ! dati
7539 v7d%voldatic &
7540 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
7541 v7d%voldatic &
7542 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
7543
7544
7545 ! attributi
7546 if (associated (v7d%dativarattr%i)) then
7547 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%c(inddativar))
7548 if (inddativarattr > 0 ) then
7549 v7d%voldatiattri &
7550 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7551 v7d%voldatiattri &
7552 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7553 end if
7554 end if
7555
7556 if (associated (v7d%dativarattr%r)) then
7557 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%c(inddativar))
7558 if (inddativarattr > 0 ) then
7559 v7d%voldatiattrr &
7560 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7561 v7d%voldatiattrr &
7562 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7563 end if
7564 end if
7565
7566 if (associated (v7d%dativarattr%d)) then
7567 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%c(inddativar))
7568 if (inddativarattr > 0 ) then
7569 v7d%voldatiattrd &
7570 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7571 v7d%voldatiattrd &
7572 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7573 end if
7574 end if
7575
7576 if (associated (v7d%dativarattr%b)) then
7577 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%c(inddativar))
7578 if (inddativarattr > 0 ) then
7579 v7d%voldatiattrb &
7580 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7581 v7d%voldatiattrb &
7582 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7583 end if
7584 end if
7585
7586 if (associated (v7d%dativarattr%c)) then
7587 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%c(inddativar))
7588 if (inddativarattr > 0 ) then
7589 v7d%voldatiattrc &
7590 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7591 v7d%voldatiattrc &
7592 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7593 end if
7594 end if
7595
7596 end if
7597
7598end do
7599
7600end subroutine move_datac
7601
7602!> Move data for all variables from one coordinate in the real volume to other.
7603!! Only not missing data will be copyed and all attributes will be moved together.
7604!! Usefull to colapse data spread in more indices (level or time or ....).
7605!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
7606!! to obtain a new vol7d with less data shape.
7607subroutine move_datar (v7d,&
7608 indana,indtime,indlevel,indtimerange,indnetwork,&
7609 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
7610
7611TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
7612
7613integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
7614integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
7615integer :: inddativar,inddativarattr
7616
7617
7618do inddativar=1,size(v7d%dativar%r)
7619
7620 if (c_e(v7d%voldatir(indana,indtime,indlevel,indtimerange,inddativar,indnetwork)) .and. &
7621 .not. c_e(v7d%voldatir(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
7622 ) then
7623
7624 ! dati
7625 v7d%voldatir &
7626 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
7627 v7d%voldatir &
7628 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
7629
7630
7631 ! attributi
7632 if (associated (v7d%dativarattr%i)) then
7633 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%r(inddativar))
7634 if (inddativarattr > 0 ) then
7635 v7d%voldatiattri &
7636 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7637 v7d%voldatiattri &
7638 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7639 end if
7640 end if
7641
7642 if (associated (v7d%dativarattr%r)) then
7643 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%r(inddativar))
7644 if (inddativarattr > 0 ) then
7645 v7d%voldatiattrr &
7646 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7647 v7d%voldatiattrr &
7648 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7649 end if
7650 end if
7651
7652 if (associated (v7d%dativarattr%d)) then
7653 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%r(inddativar))
7654 if (inddativarattr > 0 ) then
7655 v7d%voldatiattrd &
7656 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7657 v7d%voldatiattrd &
7658 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7659 end if
7660 end if
7661
7662 if (associated (v7d%dativarattr%b)) then
7663 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%r(inddativar))
7664 if (inddativarattr > 0 ) then
7665 v7d%voldatiattrb &
7666 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7667 v7d%voldatiattrb &
7668 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7669 end if
7670 end if
7671
7672 if (associated (v7d%dativarattr%c)) then
7673 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%r(inddativar))
7674 if (inddativarattr > 0 ) then
7675 v7d%voldatiattrc &
7676 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
7677 v7d%voldatiattrc &
7678 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
7679 end if
7680 end if
7681
7682 end if
7683
7684end do
7685
7686end subroutine move_datar
7687
7688
7689!> Reduce some dimensions (level and timerage) for semplification (rounding).
7690!! You can use this for simplify and use variables in computation like alchimia
7691!! where fields have to be on the same coordinate
7692!! It return real or character data only: if input is charcter data only it return character otherwise il return
7693!! all the data converted to real.
7694!! examples:
7695!! means in time for short periods and istantaneous values
7696!! 2 meter and surface levels
7697!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
7698!! will be taken (order is by icreasing var index).
7699!! You can use predefined values for classic semplification
7700!! almost_equal_levels and almost_equal_timeranges
7701!! The level or timerange in output will be defined by the first element of level and timerange list
7702subroutine v7d_rounding(v7din,v7dout,level,timerange,nostatproc)
7703type(vol7d),intent(inout) :: v7din !< input volume
7704type(vol7d),intent(out) :: v7dout !> output volume
7705type(vol7d_level),intent(in),optional :: level(:) !< almost equal level list
7706type(vol7d_timerange),intent(in),optional :: timerange(:) !< almost equal timerange list
7707!logical,intent(in),optional :: merge !< if there are data on more then one almost equal levels or timeranges
7708!! will be merged POINT BY POINT with priority for the fird data found ordered by icreasing var index
7709logical,intent(in),optional :: nostatproc !< do not take in account statistical processing code in timerange and P2
7710
7711integer :: nana,nlevel,ntime,ntimerange,nnetwork,nbin
7712integer :: iana,ilevel,itimerange,indl,indt,itime,inetwork
7713type(vol7d_level) :: roundlevel(size(v7din%level))
7714type(vol7d_timerange) :: roundtimerange(size(v7din%timerange))
7715type(vol7d) :: v7d_tmp
7716
7717
7718nbin=0
7719
7720if (associated(v7din%dativar%r)) nbin = nbin + size(v7din%dativar%r)
7721if (associated(v7din%dativar%i)) nbin = nbin + size(v7din%dativar%i)
7722if (associated(v7din%dativar%d)) nbin = nbin + size(v7din%dativar%d)
7723if (associated(v7din%dativar%b)) nbin = nbin + size(v7din%dativar%b)
7724
7725call init(v7d_tmp)
7726
7727roundlevel=v7din%level
7728
7729if (present(level))then
7730 do ilevel = 1, size(v7din%level)
7731 if ((any(v7din%level(ilevel) .almosteq. level))) then
7732 roundlevel(ilevel)=level(1)
7733 end if
7734 end do
7735end if
7736
7737roundtimerange=v7din%timerange
7738
7739if (present(timerange))then
7740 do itimerange = 1, size(v7din%timerange)
7741 if ((any(v7din%timerange(itimerange) .almosteq. timerange))) then
7742 roundtimerange(itimerange)=timerange(1)
7743 end if
7744 end do
7745end if
7746
7747!set istantaneous values everywere
7748!preserve p1 for forecast time
7749if (optio_log(nostatproc)) then
7750 roundtimerange(:)%timerange=254
7751 roundtimerange(:)%p2=0
7752end if
7753
7754
7755nana=size(v7din%ana)
7756nlevel=count_distinct(roundlevel,back=.true.)
7757ntime=size(v7din%time)
7758ntimerange=count_distinct(roundtimerange,back=.true.)
7759nnetwork=size(v7din%network)
7760
7761call init(v7d_tmp)
7762
7763if (nbin == 0) then
7764 call copy(v7din,v7d_tmp)
7765else
7766 call vol7d_convr(v7din,v7d_tmp)
7767end if
7768
7769v7d_tmp%level=roundlevel
7770v7d_tmp%timerange=roundtimerange
7771
7772do ilevel=1, size(v7d_tmp%level)
7773 indl=index(v7d_tmp%level,roundlevel(ilevel))
7774 do itimerange=1,size(v7d_tmp%timerange)
7775 indt=index(v7d_tmp%timerange,roundtimerange(itimerange))
7776
7777 if (indl /= ilevel .or. indt /= itimerange) then
7778
7779 do iana=1, nana
7780 do itime=1,ntime
7781 do inetwork=1,nnetwork
7782
7783 if (nbin > 0) then
7784 call move_datar (v7d_tmp,&
7785 iana,itime,ilevel,itimerange,inetwork,&
7786 iana,itime,indl,indt,inetwork)
7787 else
7788 call move_datac (v7d_tmp,&
7789 iana,itime,ilevel,itimerange,inetwork,&
7790 iana,itime,indl,indt,inetwork)
7791 end if
7792
7793 end do
7794 end do
7795 end do
7796
7797 end if
7798
7799 end do
7800end do
7801
7802! set to missing level and time > nlevel
7803do ilevel=nlevel+1,size(v7d_tmp%level)
7804 call init (v7d_tmp%level(ilevel))
7805end do
7806
7807do itimerange=ntimerange+1,size(v7d_tmp%timerange)
7808 call init (v7d_tmp%timerange(itimerange))
7809end do
7810
7811!copy with remove
7812CALL copy(v7d_tmp,v7dout,miss=.true.,lsort_timerange=.true.,lsort_level=.true.)
7813CALL delete(v7d_tmp)
7814
7815!call display(v7dout)
7816
7817end subroutine v7d_rounding
7818
7819
7820END MODULE vol7d_class
7821
7822!>\example esempio_qc_convert.f90
7823!!\brief Programma esempio semplice per la scrittura su file di un volume vol7d
7824!!
7825!!Programma che scrive su file un volume vol7d letto da una serie di file ASCII.
7826!!Questo programma scrive i dati del clima che poi verranno letti da modqccli
7827
7828
7829!>\example esempio_v7ddballe_move_and_collapse.f90
7830!!\brief ! Example program to reduce to one the dimensions of levels and time without loss of data
Set of functions that return a trimmed CHARACTER representation of the input variable.
Legge un oggetto datetime/timedelta o un vettore di oggetti datetime/timedelta da un file FORMATTED o...
Scrive un oggetto datetime/timedelta o un vettore di oggetti datetime/timedelta su un file FORMATTED ...
Index method.
Generic subroutine for checking OPTIONAL parameters.
Test for a missing volume.
Check for problems return 0 if all check passed print diagnostics with log4f.
Distruttore per la classe vol7d.
doubleprecision data conversion
Scrittura su file.
Costruttore per la classe vol7d.
integer data conversion
real data conversion
Reduce some dimensions (level and timerage) for semplification (rounding).
Represent data in a pretty string.
This module defines usefull general purpose function and subroutine.
Utilities for CHARACTER variables.
Classi per la gestione delle coordinate temporali.
Gestione degli errori.
Definition of constants to be used for declaring variables of a desired type.
Definition kinds.F90:245
classe per la gestione del logging
Module for quickly interpreting the OPTIONAL parameters passed to a subprogram.
Classe per la gestione dell'anagrafica di stazioni meteo e affini.
Classe per la gestione di un volume completo di dati osservati.
Classe per la gestione dei livelli verticali in osservazioni meteo e affini.
Classe per la gestione delle reti di stazioni per osservazioni meteo e affini.
Classe per la gestione degli intervalli temporali di osservazioni meteo e affini.
Classe per gestire un vettore di oggetti di tipo vol7d_var_class::vol7d_var.
Definisce un oggetto contenente i volumi anagrafica e dati e tutti i descrittori delle loro dimension...

Generated with Doxygen.