libsim Versione 8.0.0

◆ vol7d_get_volanaattrd()

subroutine vol7d_get_volanaattrd ( 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 )

Crea una vista a dimensione ridotta di un volume di attributi di anagrafica 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 :: vol1d(:)
...
CALL vol7d_get_volanaattrd(v7d1, (/vol7d_ana_d/), vol1d)
IF (ASSOCIATED(vol1d)) THEN
print*,vol1d
...
ENDIF
return
Parametri
[in]thisoggetto di cui creare la vista
[in]dimlistlista delle dimensioni da includere nella vista, attenzione tutte le dimensioni non degeneri (cioè con estensione >1) devono essere incluse nella lista; utilizzare le costanti vol7d_ana_a ... vol7d_attr_a, ecc.
vol1dparray che in uscita conterrà la vista 1d
vol2dparray che in uscita conterrà la vista 2d
vol3dparray che in uscita conterrà la vista 3d
vol4dparray che in uscita conterrà la vista 4d

Definizione alla linea 4269 del file vol7d_class.F90.

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