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