|
libsim Versione 8.0.0
|
◆ vol7d_get_voldatii()
Crea una vista a dimensione ridotta di un volume di dati di tipo INTEGER. È 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: INTEGER, POINTER :: vol2d(:,:)
...
CALL vol7d_get_voldatii(v7d1, (/vol7d_ana_d, vol7d_time_d/), vol2d)
IF (ASSOCIATED(vol2d)) THEN
print*,vol2d
...
ENDIF
return
Definizione alla linea 4998 del file vol7d_class.F90. 5000! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
5001! authors:
5002! Davide Cesari <dcesari@arpa.emr.it>
5003! Paolo Patruno <ppatruno@arpa.emr.it>
5004
5005! This program is free software; you can redistribute it and/or
5006! modify it under the terms of the GNU General Public License as
5007! published by the Free Software Foundation; either version 2 of
5008! the License, or (at your option) any later version.
5009
5010! This program is distributed in the hope that it will be useful,
5011! but WITHOUT ANY WARRANTY; without even the implied warranty of
5012! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5013! GNU General Public License for more details.
5014
5015! You should have received a copy of the GNU General Public License
5016! along with this program. If not, see <http://www.gnu.org/licenses/>.
5017#include "config.h"
5018
5019!> \defgroup vol7d Libsim package, vol7d library.
5020!! The libsim vol7d library contains classes for managing pointwise
5021!! data, tipically weather observations, and for their import from a
5022!! Db-All.e database or from a WMO BUFR file. In order to compile and
5023!! link programs using this library, you have to insert the required
5024!! \c USE statements in the program units involved, specify the
5025!! location of module files when compiling (tipically \c
5026!! -I/usr/lib/gfortran/modules or \c -I/usr/lib64/gfortran/modules or
5027!! \c -I/usr/include) and indicate the library name \c -lsim_vol7d
5028!! when linking, assuming that the library has been installed in a
5029!! default location.
5030
5031!> Classe per la gestione di un volume completo di dati osservati.
5032!! Questo modulo definisce gli oggetti e i metodi per gestire
5033!! volumi di dati meteorologici sparsi.
5034!! I volumi definiti sono principalmente di 4 categorie:
5035!! - volumi di anagrafica (vol7d::volanar & c.), hanno 3 dimensioni:
5036!! - anagrafica
5037!! - variabile di anagrafica
5038!! - rete
5039!! - volumi di attributi di anagrafica (vol7d::volanaattrr & c.), hanno 4 dimensioni:
5040!! - anagrafica
5041!! - variabile di anagrafica
5042!! - rete
5043!! - variabile di attributi delle variabili di anagrafica
5044!! - volumi di dati (vol7d::voldatir & c.), hanno 6 dimensioni:
5045!! - anagrafica
5046!! - tempo
5047!! - livello verticale
5048!! - intervallo temporale (timerange)
5049!! - variabile di dati
5050!! - rete
5051!! - volumi di attributi di dati (vol7d::voldatiattrr & c.), hanno 7 dimensioni:
5052!! - anagrafica
5053!! - tempo
5054!! - livello verticale
5055!! - intervallo temporale (timerange)
5056!! - variabile di dati
5057!! - rete
5058!! - variabile di attributi delle variabili di dati
5059!!
5060!! Tutte le variabili sono inoltre disponibil1 in 5 tipi diversi:
5061!! - reale (abbreviato r)
5062!! - doppia precisione (abbreviato d)
5063!! - intero (abbreviato i)
5064!! - byte (abbreviato b)
5065!! - carattere (abbreviato c)
5066!!
5067!! Per ognuna delle dimensioni possibili, incluse le variabili e gli
5068!! attributi con i loro diversi tipi,
5069!! è definito un cosiddetto "vettore di descrittori", con un
5070!! numero di elementi pari all'estensione della dimensione stessa,
5071!! che contiene le informazioni necessarie a descrivere
5072!! gli elementi di quella dimensione.
5073!! In realtà l'utente non dovrà generalmente occuparsi di costruire
5074!! un oggetto vol7d con le proprie mani ma utilizzerà nella maggior parte
5075!! dei casi i metodi di importazione preconfezionati che importano dati da
5076!! DB-All.e (vol7d_dballe_class) o dal DB Oracle del SIM (vol7d_oraclesim_class).
5077!!
5078!!
5079!! Il programma esempio_v7d.f90 contiene un esempio elementare di uso
5080!! della classe vol7d:
5081!! \include esempio_v7d.f90
5082!!
5083!! \ingroup vol7d
5091USE io_units
5098IMPLICIT NONE
5099
5100
5101INTEGER, PARAMETER :: vol7d_maxdim_a = 3, vol7d_maxdim_aa = 4, &
5102 vol7d_maxdim_d = 6, vol7d_maxdim_ad = 7
5103
5104INTEGER, PARAMETER :: vol7d_ana_a=1 !< indice della dimensione "anagrafica" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
5105INTEGER, PARAMETER :: vol7d_var_a=2 !< indice della dimensione "variabile" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
5106INTEGER, PARAMETER :: vol7d_network_a=3 !< indice della dimensione "rete" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
5107INTEGER, PARAMETER :: vol7d_attr_a=4 !< indice della dimensione "attributo" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
5108INTEGER, PARAMETER :: vol7d_ana_d=1 !< indice della dimensione "anagrafica" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5109INTEGER, PARAMETER :: vol7d_time_d=2 !< indice della dimensione "tempo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5110INTEGER, PARAMETER :: vol7d_level_d=3 !< indice della dimensione "livello verticale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5111INTEGER, PARAMETER :: vol7d_timerange_d=4 !< indice della dimensione "intervallo temporale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5112INTEGER, PARAMETER :: vol7d_var_d=5 !< indice della dimensione "variabile" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5113INTEGER, PARAMETER :: vol7d_network_d=6 !< indice della dimensione "rete" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5114INTEGER, PARAMETER :: vol7d_attr_d=7 !< indice della dimensione "attributo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
5115INTEGER, PARAMETER :: vol7d_cdatalen=32
5116
5117TYPE vol7d_varmap
5118 INTEGER :: r, d, i, b, c
5119END TYPE vol7d_varmap
5120
5121!> Definisce un oggetto contenente i volumi anagrafica e dati e tutti
5122!! i descrittori delle loro dimensioni.
5124!> vettore descrittore della dimensione anagrafica
5125 TYPE(vol7d_ana),POINTER :: ana(:)
5126!> vettore descrittore della dimensione tempo
5127 TYPE(datetime),POINTER :: time(:)
5128!> vettore descrittore della dimensione livello verticale
5129 TYPE(vol7d_level),POINTER :: level(:)
5130!> vettore descrittore della dimensione intervallo temporale (timerange)
5131 TYPE(vol7d_timerange),POINTER :: timerange(:)
5132!> vettore descrittore della dimensione rete
5133 TYPE(vol7d_network),POINTER :: network(:)
5134!> vettore descrittore della dimensione variabile di anagrafica
5135 TYPE(vol7d_varvect) :: anavar
5136!> vettore descrittore della dimensione attributo delle variabili di anagrafica
5137 TYPE(vol7d_varvect) :: anaattr
5138!> vettore descrittore della dimensione variabile di anagrafica che ha tali attributi
5139 TYPE(vol7d_varvect) :: anavarattr
5140!> vettore descrittore della dimensione variabile di dati
5141 TYPE(vol7d_varvect) :: dativar
5142!> vettore descrittore della dimensione attributo delle variabili di dati
5143 TYPE(vol7d_varvect) :: datiattr
5144!> vettore descrittore della dimensione variabile di dati che ha tali attributi
5145 TYPE(vol7d_varvect) :: dativarattr
5146
5147!> volume di anagrafica a valori reali
5148 REAL,POINTER :: volanar(:,:,:)
5149!> volume di anagrafica a valori a doppia precisione
5150 DOUBLE PRECISION,POINTER :: volanad(:,:,:)
5151!> volume di anagrafica a valori interi
5152 INTEGER,POINTER :: volanai(:,:,:)
5153!> volume di anagrafica a valori byte
5154 INTEGER(kind=int_b),POINTER :: volanab(:,:,:)
5155!> volume di anagrafica a valori carattere
5156 CHARACTER(len=vol7d_cdatalen),POINTER :: volanac(:,:,:)
5157
5158!> volume di attributi di anagrafica a valori reali
5159 REAL,POINTER :: volanaattrr(:,:,:,:)
5160!> volume di attributi di anagrafica a valori a doppia precisione
5161 DOUBLE PRECISION,POINTER :: volanaattrd(:,:,:,:)
5162!> volume di attributi di anagrafica a valori interi
5163 INTEGER,POINTER :: volanaattri(:,:,:,:)
5164!> volume di attributi di anagrafica a valori byte
5165 INTEGER(kind=int_b),POINTER :: volanaattrb(:,:,:,:)
5166!> volume di attributi di anagrafica a valori carattere
5167 CHARACTER(len=vol7d_cdatalen),POINTER :: volanaattrc(:,:,:,:)
5168
5169!> volume di dati a valori reali
5170 REAL,POINTER :: voldatir(:,:,:,:,:,:) ! sono i dati
5171!> volume di dati a valori a doppia precisione
5172 DOUBLE PRECISION,POINTER :: voldatid(:,:,:,:,:,:)
5173!> volume di dati a valori interi
5174 INTEGER,POINTER :: voldatii(:,:,:,:,:,:)
5175!> volume di dati a valori byte
5176 INTEGER(kind=int_b),POINTER :: voldatib(:,:,:,:,:,:)
5177!> volume di dati a valori carattere
5178 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatic(:,:,:,:,:,:)
5179
5180!> volume di attributi di dati a valori reali
5181 REAL,POINTER :: voldatiattrr(:,:,:,:,:,:,:)
5182!> volume di attributi di dati a valori a doppia precisione
5183 DOUBLE PRECISION,POINTER :: voldatiattrd(:,:,:,:,:,:,:)
5184!> volume di attributi di dati a valori interi
5185 INTEGER,POINTER :: voldatiattri(:,:,:,:,:,:,:)
5186!> volume di attributi di dati a valori byte
5187 INTEGER(kind=int_b),POINTER :: voldatiattrb(:,:,:,:,:,:,:)
5188!> volume di attributi di dati a valori carattere
5189 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatiattrc(:,:,:,:,:,:,:)
5190
5191!> time definition; 0=time is reference time, 1=time is validity time
5192 integer :: time_definition
5193
5195
5196!> Costruttore per la classe vol7d.
5197!! Deve essere richiamato
5198!! per tutti gli oggetti di questo tipo definiti in un programma.
5200 MODULE PROCEDURE vol7d_init
5201END INTERFACE
5202
5203!> Distruttore per la classe vol7d.
5205 MODULE PROCEDURE vol7d_delete
5206END INTERFACE
5207
5208!> Scrittura su file.
5210 MODULE PROCEDURE vol7d_write_on_file
5211END INTERFACE
5212
5213!> Lettura da file.
5214INTERFACE import
5215 MODULE PROCEDURE vol7d_read_from_file
5216END INTERFACE
5217
5218!>Print object
5220 MODULE PROCEDURE vol7d_display, dat_display, dat_vect_display
5221END INTERFACE
5222
5223!>Represent data in a pretty string
5225 MODULE PROCEDURE to_char_dat
5226END INTERFACE
5227
5228!>doubleprecision data conversion
5230 MODULE PROCEDURE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
5231END INTERFACE
5232
5233!>real data conversion
5235 MODULE PROCEDURE realdatd,realdatr,realdati,realdatb,realdatc
5236END INTERFACE
5237
5238!>integer data conversion
5240 MODULE PROCEDURE integerdatd,integerdatr,integerdati,integerdatb,integerdatc
5241END INTERFACE
5242
5243!>copy object
5245 MODULE PROCEDURE vol7d_copy
5246END INTERFACE
5247
5248!> Test for a missing volume
5250 MODULE PROCEDURE vol7d_c_e
5251END INTERFACE
5252
5253!> Check for problems
5254!! return 0 if all check passed
5255!! print diagnostics with log4f
5257 MODULE PROCEDURE vol7d_check
5258END INTERFACE
5259
5260!> Reduce some dimensions (level and timerage) for semplification (rounding).
5261!! You can use this for simplify and use variables in computation like alchimia
5262!! where fields have to be on the same coordinate
5263!! It return real or character data only: if input is charcter data only it return character otherwise il return
5264!! all the data converted to real.
5265!! examples:
5266!! means in time for short periods and istantaneous values
5267!! 2 meter and surface levels
5268!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
5269!! will be taken (order is by icreasing var index).
5270!! You can use predefined values for classic semplification
5271!! almost_equal_levels and almost_equal_timeranges
5272!! The level or timerange in output will be defined by the first element of level and timerange list
5274 MODULE PROCEDURE v7d_rounding
5275END INTERFACE
5276
5277!!$INTERFACE get_volana
5278!!$ MODULE PROCEDURE vol7d_get_volanar, vol7d_get_volanad, vol7d_get_volanai, &
5279!!$ vol7d_get_volanab, vol7d_get_volanac
5280!!$END INTERFACE
5281!!$
5282!!$INTERFACE get_voldati
5283!!$ MODULE PROCEDURE vol7d_get_voldatir, vol7d_get_voldatid, vol7d_get_voldatii, &
5284!!$ vol7d_get_voldatib, vol7d_get_voldatic
5285!!$END INTERFACE
5286!!$
5287!!$INTERFACE get_volanaattr
5288!!$ MODULE PROCEDURE vol7d_get_volanaattrr, vol7d_get_volanaattrd, &
5289!!$ vol7d_get_volanaattri, vol7d_get_volanaattrb, vol7d_get_volanaattrc
5290!!$END INTERFACE
5291!!$
5292!!$INTERFACE get_voldatiattr
5293!!$ MODULE PROCEDURE vol7d_get_voldatiattrr, vol7d_get_voldatiattrd, &
5294!!$ vol7d_get_voldatiattri, vol7d_get_voldatiattrb, vol7d_get_voldatiattrc
5295!!$END INTERFACE
5296
5297PRIVATE vol7d_get_volr, vol7d_get_vold, vol7d_get_voli, vol7d_get_volb, &
5298 vol7d_get_volc, &
5299 volptr1dr, volptr2dr, volptr3dr, volptr4dr, volptr5dr, volptr6dr, volptr7dr, &
5300 volptr1dd, volptr2dd, volptr3dd, volptr4dd, volptr5dd, volptr6dd, volptr7dd, &
5301 volptr1di, volptr2di, volptr3di, volptr4di, volptr5di, volptr6di, volptr7di, &
5302 volptr1db, volptr2db, volptr3db, volptr4db, volptr5db, volptr6db, volptr7db, &
5303 volptr1dc, volptr2dc, volptr3dc, volptr4dc, volptr5dc, volptr6dc, volptr7dc, &
5304 vol7d_nullifyr, vol7d_nullifyd, vol7d_nullifyi, vol7d_nullifyb, vol7d_nullifyc, &
5305 vol7d_init, vol7d_delete, vol7d_write_on_file, vol7d_read_from_file, &
5306 vol7d_check_alloc_ana, vol7d_force_alloc_ana, &
5307 vol7d_check_alloc_dati, vol7d_force_alloc_dati, vol7d_force_alloc, &
5308 vol7d_display, dat_display, dat_vect_display, &
5309 to_char_dat, vol7d_check
5310
5311PRIVATE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
5312
5313PRIVATE vol7d_c_e
5314
5315CONTAINS
5316
5317
5318!> Inizializza un oggetto di tipo vol7d.
5319!! Non riceve alcun parametro tranne l'oggetto stesso. Attenzione, è necessario
5320!! comunque chiamare sempre il costruttore per evitare di avere dei puntatori in
5321!! uno stato indefinito.
5322SUBROUTINE vol7d_init(this,time_definition)
5323TYPE(vol7d),intent(out) :: this !< oggetto da inizializzare
5324INTEGER,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)
5325
5332
5333NULLIFY(this%ana, this%time, this%level, this%timerange, this%network)
5334
5335NULLIFY(this%volanar, this%volanaattrr, this%voldatir, this%voldatiattrr)
5336NULLIFY(this%volanad, this%volanaattrd, this%voldatid, this%voldatiattrd)
5337NULLIFY(this%volanai, this%volanaattri, this%voldatii, this%voldatiattri)
5338NULLIFY(this%volanab, this%volanaattrb, this%voldatib, this%voldatiattrb)
5339NULLIFY(this%volanac, this%volanaattrc, this%voldatic, this%voldatiattrc)
5340
5341if(present(time_definition)) then
5342 this%time_definition=time_definition
5343else
5344 this%time_definition=1 !default to validity time
5345end if
5346
5347END SUBROUTINE vol7d_init
5348
5349
5350!> Distrugge l'oggetto in maniera pulita, liberando l'eventuale memoria
5351!! dinamicamente allocata. Permette di distruggere la sola parte di dati
5352!! mantenendo l'anagrafica.
5353ELEMENTAL SUBROUTINE vol7d_delete(this, dataonly)
5354TYPE(vol7d),intent(inout) :: this !< oggetto da distruggere
5355LOGICAL, INTENT(in), OPTIONAL :: dataonly !< dealloca solo i dati, tenendo l'anagrafica, (default \c .FALSE.)
5356
5357
5358IF (.NOT. optio_log(dataonly)) THEN
5359 IF (ASSOCIATED(this%volanar)) DEALLOCATE(this%volanar)
5360 IF (ASSOCIATED(this%volanad)) DEALLOCATE(this%volanad)
5361 IF (ASSOCIATED(this%volanai)) DEALLOCATE(this%volanai)
5362 IF (ASSOCIATED(this%volanab)) DEALLOCATE(this%volanab)
5363 IF (ASSOCIATED(this%volanac)) DEALLOCATE(this%volanac)
5364 IF (ASSOCIATED(this%volanaattrr)) DEALLOCATE(this%volanaattrr)
5365 IF (ASSOCIATED(this%volanaattrd)) DEALLOCATE(this%volanaattrd)
5366 IF (ASSOCIATED(this%volanaattri)) DEALLOCATE(this%volanaattri)
5367 IF (ASSOCIATED(this%volanaattrb)) DEALLOCATE(this%volanaattrb)
5368 IF (ASSOCIATED(this%volanaattrc)) DEALLOCATE(this%volanaattrc)
5369ENDIF
5370IF (ASSOCIATED(this%voldatir)) DEALLOCATE(this%voldatir)
5371IF (ASSOCIATED(this%voldatid)) DEALLOCATE(this%voldatid)
5372IF (ASSOCIATED(this%voldatii)) DEALLOCATE(this%voldatii)
5373IF (ASSOCIATED(this%voldatib)) DEALLOCATE(this%voldatib)
5374IF (ASSOCIATED(this%voldatic)) DEALLOCATE(this%voldatic)
5375IF (ASSOCIATED(this%voldatiattrr)) DEALLOCATE(this%voldatiattrr)
5376IF (ASSOCIATED(this%voldatiattrd)) DEALLOCATE(this%voldatiattrd)
5377IF (ASSOCIATED(this%voldatiattri)) DEALLOCATE(this%voldatiattri)
5378IF (ASSOCIATED(this%voldatiattrb)) DEALLOCATE(this%voldatiattrb)
5379IF (ASSOCIATED(this%voldatiattrc)) DEALLOCATE(this%voldatiattrc)
5380
5381IF (.NOT. optio_log(dataonly)) THEN
5382 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
5383 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
5384ENDIF
5385IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
5386IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
5387IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
5388
5389IF (.NOT. optio_log(dataonly)) THEN
5393ENDIF
5397
5398END SUBROUTINE vol7d_delete
5399
5400
5401
5402integer function vol7d_check(this)
5403TYPE(vol7d),intent(in) :: this !< object to check
5404integer :: i,j,k,l,m,n
5405
5406vol7d_check=0
5407
5408if (associated(this%voldatii)) then
5409do i = 1,size(this%voldatii,1)
5410 do j = 1,size(this%voldatii,2)
5411 do k = 1,size(this%voldatii,3)
5412 do l = 1,size(this%voldatii,4)
5413 do m = 1,size(this%voldatii,5)
5414 do n = 1,size(this%voldatii,6)
5415 if (this%voldatii(i,j,k,l,m,n) /= this%voldatii(i,j,k,l,m,n) ) then
5416 CALL l4f_log(l4f_warn,"check: abnormal value at voldatii("&
5418 vol7d_check=1
5419 end if
5420 end do
5421 end do
5422 end do
5423 end do
5424 end do
5425end do
5426end if
5427
5428
5429if (associated(this%voldatir)) then
5430do i = 1,size(this%voldatir,1)
5431 do j = 1,size(this%voldatir,2)
5432 do k = 1,size(this%voldatir,3)
5433 do l = 1,size(this%voldatir,4)
5434 do m = 1,size(this%voldatir,5)
5435 do n = 1,size(this%voldatir,6)
5436 if (this%voldatir(i,j,k,l,m,n) /= this%voldatir(i,j,k,l,m,n) ) then
5437 CALL l4f_log(l4f_warn,"check: abnormal value at voldatir("&
5439 vol7d_check=2
5440 end if
5441 end do
5442 end do
5443 end do
5444 end do
5445 end do
5446end do
5447end if
5448
5449if (associated(this%voldatid)) then
5450do i = 1,size(this%voldatid,1)
5451 do j = 1,size(this%voldatid,2)
5452 do k = 1,size(this%voldatid,3)
5453 do l = 1,size(this%voldatid,4)
5454 do m = 1,size(this%voldatid,5)
5455 do n = 1,size(this%voldatid,6)
5456 if (this%voldatid(i,j,k,l,m,n) /= this%voldatid(i,j,k,l,m,n) ) then
5457 CALL l4f_log(l4f_warn,"check: abnormal value at voldatid("&
5459 vol7d_check=3
5460 end if
5461 end do
5462 end do
5463 end do
5464 end do
5465 end do
5466end do
5467end if
5468
5469if (associated(this%voldatib)) then
5470do i = 1,size(this%voldatib,1)
5471 do j = 1,size(this%voldatib,2)
5472 do k = 1,size(this%voldatib,3)
5473 do l = 1,size(this%voldatib,4)
5474 do m = 1,size(this%voldatib,5)
5475 do n = 1,size(this%voldatib,6)
5476 if (this%voldatib(i,j,k,l,m,n) /= this%voldatib(i,j,k,l,m,n) ) then
5477 CALL l4f_log(l4f_warn,"check: abnormal value at voldatib("&
5479 vol7d_check=4
5480 end if
5481 end do
5482 end do
5483 end do
5484 end do
5485 end do
5486end do
5487end if
5488
5489end function vol7d_check
5490
5491
5492
5493!TODO da completare ! aborta se i volumi sono allocati a dimensione 0
5494!> stampa a video una sintesi del contenuto
5495SUBROUTINE vol7d_display(this)
5496TYPE(vol7d),intent(in) :: this !< oggetto da visualizzare
5497integer :: i
5498
5499REAL :: rdat
5500DOUBLE PRECISION :: ddat
5501INTEGER :: idat
5502INTEGER(kind=int_b) :: bdat
5503CHARACTER(len=vol7d_cdatalen) :: cdat
5504
5505
5506print*,"<<<<<<<<<<<<<<<<<<< vol7d object >>>>>>>>>>>>>>>>>>>>"
5507if (this%time_definition == 0) then
5508 print*,"TIME DEFINITION: time is reference time"
5509else if (this%time_definition == 1) then
5510 print*,"TIME DEFINITION: time is validity time"
5511else if (this%time_definition == 2) then
5512 print*,"TIME DEFINITION: time is validity time, forecast range forced to 0"
5513else
5514 print*,"Time definition has a wrong walue:", this%time_definition
5515end if
5516
5517IF (ASSOCIATED(this%network))then
5518 print*,"---- network vector ----"
5519 print*,"elements=",size(this%network)
5520 do i=1, size(this%network)
5522 end do
5523end IF
5524
5525IF (ASSOCIATED(this%ana))then
5526 print*,"---- ana vector ----"
5527 print*,"elements=",size(this%ana)
5528 do i=1, size(this%ana)
5530 end do
5531end IF
5532
5533IF (ASSOCIATED(this%time))then
5534 print*,"---- time vector ----"
5535 print*,"elements=",size(this%time)
5536 do i=1, size(this%time)
5538 end do
5539end if
5540
5541IF (ASSOCIATED(this%level)) then
5542 print*,"---- level vector ----"
5543 print*,"elements=",size(this%level)
5544 do i =1,size(this%level)
5546 end do
5547end if
5548
5549IF (ASSOCIATED(this%timerange))then
5550 print*,"---- timerange vector ----"
5551 print*,"elements=",size(this%timerange)
5552 do i =1,size(this%timerange)
5554 end do
5555end if
5556
5557
5558print*,"---- ana vector ----"
5559print*,""
5560print*,"->>>>>>>>> anavar -"
5562print*,""
5563print*,"->>>>>>>>> anaattr -"
5565print*,""
5566print*,"->>>>>>>>> anavarattr -"
5568
5569print*,"-- ana data section (first point) --"
5570
5571idat=imiss
5572rdat=rmiss
5573ddat=dmiss
5574bdat=ibmiss
5575cdat=cmiss
5576
5577!ntime = MIN(SIZE(this%time),nprint)
5578!ntimerange = MIN(SIZE(this%timerange),nprint)
5579!nlevel = MIN(SIZE(this%level),nprint)
5580!nnetwork = MIN(SIZE(this%network),nprint)
5581!nana = MIN(SIZE(this%ana),nprint)
5582
5583IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0) THEN
5584if (associated(this%volanai)) then
5585 do i=1,size(this%anavar%i)
5586 idat=this%volanai(1,i,1)
5588 end do
5589end if
5590idat=imiss
5591
5592if (associated(this%volanar)) then
5593 do i=1,size(this%anavar%r)
5594 rdat=this%volanar(1,i,1)
5596 end do
5597end if
5598rdat=rmiss
5599
5600if (associated(this%volanad)) then
5601 do i=1,size(this%anavar%d)
5602 ddat=this%volanad(1,i,1)
5604 end do
5605end if
5606ddat=dmiss
5607
5608if (associated(this%volanab)) then
5609 do i=1,size(this%anavar%b)
5610 bdat=this%volanab(1,i,1)
5612 end do
5613end if
5614bdat=ibmiss
5615
5616if (associated(this%volanac)) then
5617 do i=1,size(this%anavar%c)
5618 cdat=this%volanac(1,i,1)
5620 end do
5621end if
5622cdat=cmiss
5623ENDIF
5624
5625print*,"---- data vector ----"
5626print*,""
5627print*,"->>>>>>>>> dativar -"
5629print*,""
5630print*,"->>>>>>>>> datiattr -"
5632print*,""
5633print*,"->>>>>>>>> dativarattr -"
5635
5636print*,"-- data data section (first point) --"
5637
5638idat=imiss
5639rdat=rmiss
5640ddat=dmiss
5641bdat=ibmiss
5642cdat=cmiss
5643
5644IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0 .AND. size(this%time) > 0 &
5645 .AND. size(this%level) > 0 .AND. size(this%timerange) > 0) THEN
5646if (associated(this%voldatii)) then
5647 do i=1,size(this%dativar%i)
5648 idat=this%voldatii(1,1,1,1,i,1)
5650 end do
5651end if
5652idat=imiss
5653
5654if (associated(this%voldatir)) then
5655 do i=1,size(this%dativar%r)
5656 rdat=this%voldatir(1,1,1,1,i,1)
5658 end do
5659end if
5660rdat=rmiss
5661
5662if (associated(this%voldatid)) then
5663 do i=1,size(this%dativar%d)
5664 ddat=this%voldatid(1,1,1,1,i,1)
5666 end do
5667end if
5668ddat=dmiss
5669
5670if (associated(this%voldatib)) then
5671 do i=1,size(this%dativar%b)
5672 bdat=this%voldatib(1,1,1,1,i,1)
5674 end do
5675end if
5676bdat=ibmiss
5677
5678if (associated(this%voldatic)) then
5679 do i=1,size(this%dativar%c)
5680 cdat=this%voldatic(1,1,1,1,i,1)
5682 end do
5683end if
5684cdat=cmiss
5685ENDIF
5686
5687print*,"<<<<<<<<<<<<<<<<<<< END vol7d object >>>>>>>>>>>>>>>>>>>>"
5688
5689END SUBROUTINE vol7d_display
5690
5691
5692!> stampa a video una sintesi del contenuto
5693SUBROUTINE dat_display(this,idat,rdat,ddat,bdat,cdat)
5694TYPE(vol7d_var),intent(in) :: this !< oggetto da visualizzare
5695!> real
5696REAL :: rdat
5697!> double precision
5698DOUBLE PRECISION :: ddat
5699!> integer
5700INTEGER :: idat
5701!> byte
5702INTEGER(kind=int_b) :: bdat
5703!> character
5704CHARACTER(len=*) :: cdat
5705
5706print *, to_char_dat(this,idat,rdat,ddat,bdat,cdat)
5707
5708end SUBROUTINE dat_display
5709
5710!> stampa a video una sintesi del contenuto
5711SUBROUTINE dat_vect_display(this,idat,rdat,ddat,bdat,cdat)
5712
5713TYPE(vol7d_var),intent(in) :: this(:) !< oggetto da visualizzare
5714!> real
5715REAL :: rdat(:)
5716!> double precision
5717DOUBLE PRECISION :: ddat(:)
5718!> integer
5719INTEGER :: idat(:)
5720!> byte
5721INTEGER(kind=int_b) :: bdat(:)
5722!> character
5723CHARACTER(len=*):: cdat(:)
5724
5725integer :: i
5726
5727do i =1,size(this)
5729end do
5730
5731end SUBROUTINE dat_vect_display
5732
5733
5734FUNCTION to_char_dat(this,idat,rdat,ddat,bdat,cdat)
5735#ifdef HAVE_DBALLE
5736USE dballef
5737#endif
5738TYPE(vol7d_var),INTENT(in) :: this
5739!> real
5740REAL :: rdat
5741!> double precision
5742DOUBLE PRECISION :: ddat
5743!> integer
5744INTEGER :: idat
5745!> byte
5746INTEGER(kind=int_b) :: bdat
5747!> character
5748CHARACTER(len=*) :: cdat
5749CHARACTER(len=80) :: to_char_dat
5750
5751CHARACTER(len=LEN(to_char_dat)) :: to_char_tmp
5752
5753
5754#ifdef HAVE_DBALLE
5755INTEGER :: handle, ier
5756
5757handle = 0
5758to_char_dat="VALUE: "
5759
5764
5766 ier = idba_messaggi(handle,"/dev/null", "w", "BUFR")
5767 ier = idba_spiegab(handle,this%btable,cdat,to_char_tmp)
5768 ier = idba_fatto(handle)
5769 to_char_dat=trim(to_char_dat)//" ;char> "//trim(to_char_tmp)
5770endif
5771
5772#else
5773
5774to_char_dat="VALUE: "
5780
5781#endif
5782
5783END FUNCTION to_char_dat
5784
5785
5786!> Tests whether anything has ever been assigned to a vol7d object
5787!! (.TRUE.) or it is as clean as after an init (.FALSE.).
5788FUNCTION vol7d_c_e(this) RESULT(c_e)
5789TYPE(vol7d), INTENT(in) :: this
5790
5791LOGICAL :: c_e
5792
5794 ASSOCIATED(this%level) .OR. ASSOCIATED(this%timerange) .OR. &
5795 ASSOCIATED(this%network) .OR. &
5796 ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
5797 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
5798 ASSOCIATED(this%anavar%c) .OR. &
5799 ASSOCIATED(this%anaattr%r) .OR. ASSOCIATED(this%anaattr%d) .OR. &
5800 ASSOCIATED(this%anaattr%i) .OR. ASSOCIATED(this%anaattr%b) .OR. &
5801 ASSOCIATED(this%anaattr%c) .OR. &
5802 ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
5803 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
5804 ASSOCIATED(this%dativar%c) .OR. &
5805 ASSOCIATED(this%datiattr%r) .OR. ASSOCIATED(this%datiattr%d) .OR. &
5806 ASSOCIATED(this%datiattr%i) .OR. ASSOCIATED(this%datiattr%b) .OR. &
5807 ASSOCIATED(this%datiattr%c)
5808
5809END FUNCTION vol7d_c_e
5810
5811
5812!> Metodo per allocare i descrittori delle 7 dimensioni.
5813!! Riceve un grande numero di parametri opzionali che
5814!! indicano quali descrittori allocare e con quale estensione;
5815!! i descrittori non specificati non vengono toccati.
5816!! Può essere quindi chiamato più volte allocando via via
5817!! descrittori relativi a dimensioni diverse.
5818!! Se un descrittore richiesto è già allocato, viene deallocato
5819!! (perdendone l'eventuale contenuto) e riallocato con l'estensione
5820!! richiesta.
5821!! Per i descrittori relativi a dimensioni che non siano variabili o attributi,
5822!! è possibile specificare l'estensione di una dimensione a 0,
5823!! in tal caso il descrittore viene comunque allocato con lunghezza nulla,
5824!! che è diverso da non allocarlo. Per i descrittori di variabili e attributi
5825!! passare un'estensione 0 equivale a non fornire il parametro.
5826!! Avere uno o più descrittori dimensionati con estensione nulla fa sì
5827!! che anche il volume dati successivamente allocato abbia estensione nulla;
5828!! sebbene ciò appaia inutile, un volume del genere può in realtà servire,
5829!! in associazione ai metodi ::vol7d_merge o ::vol7d_append per estendere
5830!! un volume esistente aggiungendo elementi in alcune dimensioni (quelle
5831!! a estensione non nulla, ovviamente) e mantenendo invariato tutto il resto.
5832!! Per quanto riguarda i descrittori delle dimensioni relative alle
5833!! variabili, la relativa estensione è specificata con la nomenclatura
5834!! \a n<x><y><z> dove <x> può valere:
5835!! - \a ana per variabili relative a voumi di anagrafica
5836!! - \a dati per variabili relative a voumi di dati
5837!!
5838!! <y> può valere:
5839!! - \a var per variabili
5840!! - \a attr per attributi
5841!! - \a varattr variabili aventi attributi nei volumi di attributi
5842!!
5843!! <z> può valere:
5844!! - \a r per variabili o attributi a valori reali
5845!! - \a d per variabili o attributi a valori a doppia precisione
5846!! - \a i per variabili o attributi a valori interi
5847!! - \a b per variabili o attributi a valori byte
5848!! - \a c per variabili o attributi a valori carattere
5849!!
5850SUBROUTINE vol7d_alloc(this, nana, ntime, nlevel, ntimerange, nnetwork, &
5851 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
5852 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
5853 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
5854 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
5855 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
5856 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc, &
5857 ini)
5858TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i descrittori
5859INTEGER,INTENT(in),OPTIONAL :: nana !< estensione della dimensione anagrafica
5860INTEGER,INTENT(in),OPTIONAL :: ntime !< estensione della dimensione tempo
5861INTEGER,INTENT(in),OPTIONAL :: nlevel !< estensione della dimensione livello varticale
5862INTEGER,INTENT(in),OPTIONAL :: ntimerange !< estensione della dimensione intervallo temporale (timerange)
5863INTEGER,INTENT(in),OPTIONAL :: nnetwork !< estensione della dimensione rete
5864!> estensione delle possibili dimensioni variabile
5865INTEGER,INTENT(in),OPTIONAL :: &
5866 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
5867 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
5868 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
5869 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
5870 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
5871 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc
5872LOGICAL,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
5873
5874INTEGER :: i
5875LOGICAL :: linit
5876
5877IF (PRESENT(ini)) THEN
5878 linit = ini
5879ELSE
5880 linit = .false.
5881ENDIF
5882
5883! Dimensioni principali
5884IF (PRESENT(nana)) THEN
5885 IF (nana >= 0) THEN
5886 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
5887 ALLOCATE(this%ana(nana))
5888 IF (linit) THEN
5889 DO i = 1, nana
5891 ENDDO
5892 ENDIF
5893 ENDIF
5894ENDIF
5895IF (PRESENT(ntime)) THEN
5896 IF (ntime >= 0) THEN
5897 IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
5898 ALLOCATE(this%time(ntime))
5899 IF (linit) THEN
5900 DO i = 1, ntime
5902 ENDDO
5903 ENDIF
5904 ENDIF
5905ENDIF
5906IF (PRESENT(nlevel)) THEN
5907 IF (nlevel >= 0) THEN
5908 IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
5909 ALLOCATE(this%level(nlevel))
5910 IF (linit) THEN
5911 DO i = 1, nlevel
5913 ENDDO
5914 ENDIF
5915 ENDIF
5916ENDIF
5917IF (PRESENT(ntimerange)) THEN
5918 IF (ntimerange >= 0) THEN
5919 IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
5920 ALLOCATE(this%timerange(ntimerange))
5921 IF (linit) THEN
5922 DO i = 1, ntimerange
5924 ENDDO
5925 ENDIF
5926 ENDIF
5927ENDIF
5928IF (PRESENT(nnetwork)) THEN
5929 IF (nnetwork >= 0) THEN
5930 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
5931 ALLOCATE(this%network(nnetwork))
5932 IF (linit) THEN
5933 DO i = 1, nnetwork
5935 ENDDO
5936 ENDIF
5937 ENDIF
5938ENDIF
5939! Dimensioni dei tipi delle variabili
5940CALL vol7d_varvect_alloc(this%anavar, nanavarr, nanavard, &
5941 nanavari, nanavarb, nanavarc, ini)
5942CALL vol7d_varvect_alloc(this%anaattr, nanaattrr, nanaattrd, &
5943 nanaattri, nanaattrb, nanaattrc, ini)
5944CALL vol7d_varvect_alloc(this%anavarattr, nanavarattrr, nanavarattrd, &
5945 nanavarattri, nanavarattrb, nanavarattrc, ini)
5946CALL vol7d_varvect_alloc(this%dativar, ndativarr, ndativard, &
5947 ndativari, ndativarb, ndativarc, ini)
5948CALL vol7d_varvect_alloc(this%datiattr, ndatiattrr, ndatiattrd, &
5949 ndatiattri, ndatiattrb, ndatiattrc, ini)
5950CALL vol7d_varvect_alloc(this%dativarattr, ndativarattrr, ndativarattrd, &
5951 ndativarattri, ndativarattrb, ndativarattrc, ini)
5952
5953END SUBROUTINE vol7d_alloc
5954
5955
5956FUNCTION vol7d_check_alloc_ana(this)
5957TYPE(vol7d),INTENT(in) :: this
5958LOGICAL :: vol7d_check_alloc_ana
5959
5960vol7d_check_alloc_ana = ASSOCIATED(this%ana) .AND. ASSOCIATED(this%network)
5961
5962END FUNCTION vol7d_check_alloc_ana
5963
5964SUBROUTINE vol7d_force_alloc_ana(this, ini)
5965TYPE(vol7d),INTENT(inout) :: this
5966LOGICAL,INTENT(in),OPTIONAL :: ini
5967
5968! Alloco i descrittori minimi per avere un volume di anagrafica
5969IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=1, ini=ini)
5970IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=1, ini=ini)
5971
5972END SUBROUTINE vol7d_force_alloc_ana
5973
5974
5975FUNCTION vol7d_check_alloc_dati(this)
5976TYPE(vol7d),INTENT(in) :: this
5977LOGICAL :: vol7d_check_alloc_dati
5978
5979vol7d_check_alloc_dati = vol7d_check_alloc_ana(this) .AND. &
5980 ASSOCIATED(this%time) .AND. ASSOCIATED(this%level) .AND. &
5981 ASSOCIATED(this%timerange)
5982
5983END FUNCTION vol7d_check_alloc_dati
5984
5985SUBROUTINE vol7d_force_alloc_dati(this, ini)
5986TYPE(vol7d),INTENT(inout) :: this
5987LOGICAL,INTENT(in),OPTIONAL :: ini
5988
5989! Alloco i descrittori minimi per avere un volume di dati
5990CALL vol7d_force_alloc_ana(this, ini)
5991IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=1, ini=ini)
5992IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=1, ini=ini)
5993IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=1, ini=ini)
5994
5995END SUBROUTINE vol7d_force_alloc_dati
5996
5997
5998SUBROUTINE vol7d_force_alloc(this)
5999TYPE(vol7d),INTENT(inout) :: this
6000
6001! If anything really not allocated yet, allocate with size 0
6002IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=0)
6003IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=0)
6004IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=0)
6005IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=0)
6006IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=0)
6007
6008END SUBROUTINE vol7d_force_alloc
6009
6010
6011FUNCTION vol7d_check_vol(this)
6012TYPE(vol7d),INTENT(in) :: this !< oggetto da controllare
6013LOGICAL :: vol7d_check_vol
6014
6015vol7d_check_vol = c_e(this)
6016
6017! Anagrafica
6018IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
6019 vol7d_check_vol = .false.
6020ENDIF
6021
6022IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
6023 vol7d_check_vol = .false.
6024ENDIF
6025
6026IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
6027 vol7d_check_vol = .false.
6028ENDIF
6029
6030IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
6031 vol7d_check_vol = .false.
6032ENDIF
6033
6034IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
6035 vol7d_check_vol = .false.
6036ENDIF
6037IF (ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
6038 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
6039 ASSOCIATED(this%anavar%c)) THEN
6040 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_ana(this)
6041ENDIF
6042
6043! Attributi dell'anagrafica
6044IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
6045 .NOT.ASSOCIATED(this%volanaattrr)) THEN
6046 vol7d_check_vol = .false.
6047ENDIF
6048
6049IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
6050 .NOT.ASSOCIATED(this%volanaattrd)) THEN
6051 vol7d_check_vol = .false.
6052ENDIF
6053
6054IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
6055 .NOT.ASSOCIATED(this%volanaattri)) THEN
6056 vol7d_check_vol = .false.
6057ENDIF
6058
6059IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
6060 .NOT.ASSOCIATED(this%volanaattrb)) THEN
6061 vol7d_check_vol = .false.
6062ENDIF
6063
6064IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
6065 .NOT.ASSOCIATED(this%volanaattrc)) THEN
6066 vol7d_check_vol = .false.
6067ENDIF
6068
6069! Dati
6070IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
6071 vol7d_check_vol = .false.
6072ENDIF
6073
6074IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
6075 vol7d_check_vol = .false.
6076ENDIF
6077
6078IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
6079 vol7d_check_vol = .false.
6080ENDIF
6081
6082IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
6083 vol7d_check_vol = .false.
6084ENDIF
6085
6086IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
6087 vol7d_check_vol = .false.
6088ENDIF
6089
6090! Attributi dei dati
6091IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
6092 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
6093 vol7d_check_vol = .false.
6094ENDIF
6095
6096IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
6097 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
6098 vol7d_check_vol = .false.
6099ENDIF
6100
6101IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
6102 .NOT.ASSOCIATED(this%voldatiattri)) THEN
6103 vol7d_check_vol = .false.
6104ENDIF
6105
6106IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
6107 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
6108 vol7d_check_vol = .false.
6109ENDIF
6110
6111IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
6112 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
6113 vol7d_check_vol = .false.
6114ENDIF
6115IF (ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
6116 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
6117 ASSOCIATED(this%dativar%c)) THEN
6118 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_dati(this)
6119ENDIF
6120
6121END FUNCTION vol7d_check_vol
6122
6123
6124!> Metodo per allocare i volumi richiesti di variabili e attributi per
6125!! anagrafica e dati.
6126!! Se alcuni dei descrittori relativi alle dimensioni anagrafica,
6127!! livello verticale, tempo, intervallo temporale (timerange), rete non sono
6128!! stati richiesti preventivamente con la ::vol7d_alloc, essi vengono allocati
6129!! automaticamente da questo metodo
6130!! con estensione di default pari a 1 (non 0!), questo significa, ad esempio,
6131!! che se prevedo di avere soli dati superficiali, cioè ad un solo livello
6132!! verticale, o una sola rete di stazioni, non devo preoccuparmi di
6133!! specificare questa informazione.
6134!! Tra i 20 possibili volumi allocabili
6135!! ((variabili,attributi)*(anagrafica,dati)*(r,d,i,b,c)=20)
6136!! saranno allocati solo quelli per cui è stato precedentemente richiesto il
6137!! corrispondente descrittore variabili/attributi con la ::vol7d_alloc.
6138SUBROUTINE vol7d_alloc_vol(this, ini, inivol)
6139TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i volumi
6140LOGICAL,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
6141LOGICAL,INTENT(in),OPTIONAL :: inivol !< se fornito e vale \c .TRUE., i volumi allocati saranno inizializzati a valore mancante
6142
6143LOGICAL :: linivol
6144
6145IF (PRESENT(inivol)) THEN
6146 linivol = inivol
6147ELSE
6148 linivol = .true.
6149ENDIF
6150
6151! Anagrafica
6152IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
6153 CALL vol7d_force_alloc_ana(this, ini)
6154 ALLOCATE(this%volanar(SIZE(this%ana), SIZE(this%anavar%r), SIZE(this%network)))
6155 IF (linivol) this%volanar(:,:,:) = rmiss
6156ENDIF
6157
6158IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
6159 CALL vol7d_force_alloc_ana(this, ini)
6160 ALLOCATE(this%volanad(SIZE(this%ana), SIZE(this%anavar%d), SIZE(this%network)))
6161 IF (linivol) this%volanad(:,:,:) = rdmiss
6162ENDIF
6163
6164IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
6165 CALL vol7d_force_alloc_ana(this, ini)
6166 ALLOCATE(this%volanai(SIZE(this%ana), SIZE(this%anavar%i), SIZE(this%network)))
6167 IF (linivol) this%volanai(:,:,:) = imiss
6168ENDIF
6169
6170IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
6171 CALL vol7d_force_alloc_ana(this, ini)
6172 ALLOCATE(this%volanab(SIZE(this%ana), SIZE(this%anavar%b), SIZE(this%network)))
6173 IF (linivol) this%volanab(:,:,:) = ibmiss
6174ENDIF
6175
6176IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
6177 CALL vol7d_force_alloc_ana(this, ini)
6178 ALLOCATE(this%volanac(SIZE(this%ana), SIZE(this%anavar%c), SIZE(this%network)))
6179 IF (linivol) this%volanac(:,:,:) = cmiss
6180ENDIF
6181
6182! Attributi dell'anagrafica
6183IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
6184 .NOT.ASSOCIATED(this%volanaattrr)) THEN
6185 CALL vol7d_force_alloc_ana(this, ini)
6186 ALLOCATE(this%volanaattrr(SIZE(this%ana), SIZE(this%anavarattr%r), &
6187 SIZE(this%network), SIZE(this%anaattr%r)))
6188 IF (linivol) this%volanaattrr(:,:,:,:) = rmiss
6189ENDIF
6190
6191IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
6192 .NOT.ASSOCIATED(this%volanaattrd)) THEN
6193 CALL vol7d_force_alloc_ana(this, ini)
6194 ALLOCATE(this%volanaattrd(SIZE(this%ana), SIZE(this%anavarattr%d), &
6195 SIZE(this%network), SIZE(this%anaattr%d)))
6196 IF (linivol) this%volanaattrd(:,:,:,:) = rdmiss
6197ENDIF
6198
6199IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
6200 .NOT.ASSOCIATED(this%volanaattri)) THEN
6201 CALL vol7d_force_alloc_ana(this, ini)
6202 ALLOCATE(this%volanaattri(SIZE(this%ana), SIZE(this%anavarattr%i), &
6203 SIZE(this%network), SIZE(this%anaattr%i)))
6204 IF (linivol) this%volanaattri(:,:,:,:) = imiss
6205ENDIF
6206
6207IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
6208 .NOT.ASSOCIATED(this%volanaattrb)) THEN
6209 CALL vol7d_force_alloc_ana(this, ini)
6210 ALLOCATE(this%volanaattrb(SIZE(this%ana), SIZE(this%anavarattr%b), &
6211 SIZE(this%network), SIZE(this%anaattr%b)))
6212 IF (linivol) this%volanaattrb(:,:,:,:) = ibmiss
6213ENDIF
6214
6215IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
6216 .NOT.ASSOCIATED(this%volanaattrc)) THEN
6217 CALL vol7d_force_alloc_ana(this, ini)
6218 ALLOCATE(this%volanaattrc(SIZE(this%ana), SIZE(this%anavarattr%c), &
6219 SIZE(this%network), SIZE(this%anaattr%c)))
6220 IF (linivol) this%volanaattrc(:,:,:,:) = cmiss
6221ENDIF
6222
6223! Dati
6224IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
6225 CALL vol7d_force_alloc_dati(this, ini)
6226 ALLOCATE(this%voldatir(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6227 SIZE(this%timerange), SIZE(this%dativar%r), SIZE(this%network)))
6228 IF (linivol) this%voldatir(:,:,:,:,:,:) = rmiss
6229ENDIF
6230
6231IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
6232 CALL vol7d_force_alloc_dati(this, ini)
6233 ALLOCATE(this%voldatid(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6234 SIZE(this%timerange), SIZE(this%dativar%d), SIZE(this%network)))
6235 IF (linivol) this%voldatid(:,:,:,:,:,:) = rdmiss
6236ENDIF
6237
6238IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
6239 CALL vol7d_force_alloc_dati(this, ini)
6240 ALLOCATE(this%voldatii(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6241 SIZE(this%timerange), SIZE(this%dativar%i), SIZE(this%network)))
6242 IF (linivol) this%voldatii(:,:,:,:,:,:) = imiss
6243ENDIF
6244
6245IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
6246 CALL vol7d_force_alloc_dati(this, ini)
6247 ALLOCATE(this%voldatib(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6248 SIZE(this%timerange), SIZE(this%dativar%b), SIZE(this%network)))
6249 IF (linivol) this%voldatib(:,:,:,:,:,:) = ibmiss
6250ENDIF
6251
6252IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
6253 CALL vol7d_force_alloc_dati(this, ini)
6254 ALLOCATE(this%voldatic(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6255 SIZE(this%timerange), SIZE(this%dativar%c), SIZE(this%network)))
6256 IF (linivol) this%voldatic(:,:,:,:,:,:) = cmiss
6257ENDIF
6258
6259! Attributi dei dati
6260IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
6261 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
6262 CALL vol7d_force_alloc_dati(this, ini)
6263 ALLOCATE(this%voldatiattrr(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6264 SIZE(this%timerange), SIZE(this%dativarattr%r), SIZE(this%network), &
6265 SIZE(this%datiattr%r)))
6266 IF (linivol) this%voldatiattrr(:,:,:,:,:,:,:) = rmiss
6267ENDIF
6268
6269IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
6270 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
6271 CALL vol7d_force_alloc_dati(this, ini)
6272 ALLOCATE(this%voldatiattrd(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6273 SIZE(this%timerange), SIZE(this%dativarattr%d), SIZE(this%network), &
6274 SIZE(this%datiattr%d)))
6275 IF (linivol) this%voldatiattrd(:,:,:,:,:,:,:) = rdmiss
6276ENDIF
6277
6278IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
6279 .NOT.ASSOCIATED(this%voldatiattri)) THEN
6280 CALL vol7d_force_alloc_dati(this, ini)
6281 ALLOCATE(this%voldatiattri(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6282 SIZE(this%timerange), SIZE(this%dativarattr%i), SIZE(this%network), &
6283 SIZE(this%datiattr%i)))
6284 IF (linivol) this%voldatiattri(:,:,:,:,:,:,:) = imiss
6285ENDIF
6286
6287IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
6288 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
6289 CALL vol7d_force_alloc_dati(this, ini)
6290 ALLOCATE(this%voldatiattrb(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6291 SIZE(this%timerange), SIZE(this%dativarattr%b), SIZE(this%network), &
6292 SIZE(this%datiattr%b)))
6293 IF (linivol) this%voldatiattrb(:,:,:,:,:,:,:) = ibmiss
6294ENDIF
6295
6296IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
6297 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
6298 CALL vol7d_force_alloc_dati(this, ini)
6299 ALLOCATE(this%voldatiattrc(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
6300 SIZE(this%timerange), SIZE(this%dativarattr%c), SIZE(this%network), &
6301 SIZE(this%datiattr%c)))
6302 IF (linivol) this%voldatiattrc(:,:,:,:,:,:,:) = cmiss
6303ENDIF
6304
6305! Catch-all method
6306CALL vol7d_force_alloc(this)
6307
6308! Creo gli indici var-attr
6309
6310#ifdef DEBUG
6311CALL l4f_log(l4f_debug,"calling: vol7d_set_attr_ind")
6312#endif
6313
6314CALL vol7d_set_attr_ind(this)
6315
6316
6317
6318END SUBROUTINE vol7d_alloc_vol
6319
6320
6321!> Metodo per creare gli indici che associano le variabili aventi attributo
6322!! alle variabili nei relativi descrittori.
6323!! Ha senso chiamare questo metodo solo dopo che i descrittori delle variabili
6324!! e degli attributi desiderati sono stati allocati ed è stato assegnato un
6325!! valore ai relativi membri btable (vedi vol7d_var_class::vol7d_var), se
6326!! i descrittori non sono stati allocati o assegnati, il metodo non fa niente.
6327SUBROUTINE vol7d_set_attr_ind(this)
6328TYPE(vol7d),INTENT(inout) :: this !< oggetto in cui creare gli indici
6329
6330INTEGER :: i
6331
6332! real
6333IF (ASSOCIATED(this%dativar%r)) THEN
6334 IF (ASSOCIATED(this%dativarattr%r)) THEN
6335 DO i = 1, SIZE(this%dativar%r)
6336 this%dativar%r(i)%r = &
6337 firsttrue(this%dativar%r(i)%btable == this%dativarattr%r(:)%btable)
6338 ENDDO
6339 ENDIF
6340
6341 IF (ASSOCIATED(this%dativarattr%d)) THEN
6342 DO i = 1, SIZE(this%dativar%r)
6343 this%dativar%r(i)%d = &
6344 firsttrue(this%dativar%r(i)%btable == this%dativarattr%d(:)%btable)
6345 ENDDO
6346 ENDIF
6347
6348 IF (ASSOCIATED(this%dativarattr%i)) THEN
6349 DO i = 1, SIZE(this%dativar%r)
6350 this%dativar%r(i)%i = &
6351 firsttrue(this%dativar%r(i)%btable == this%dativarattr%i(:)%btable)
6352 ENDDO
6353 ENDIF
6354
6355 IF (ASSOCIATED(this%dativarattr%b)) THEN
6356 DO i = 1, SIZE(this%dativar%r)
6357 this%dativar%r(i)%b = &
6358 firsttrue(this%dativar%r(i)%btable == this%dativarattr%b(:)%btable)
6359 ENDDO
6360 ENDIF
6361
6362 IF (ASSOCIATED(this%dativarattr%c)) THEN
6363 DO i = 1, SIZE(this%dativar%r)
6364 this%dativar%r(i)%c = &
6365 firsttrue(this%dativar%r(i)%btable == this%dativarattr%c(:)%btable)
6366 ENDDO
6367 ENDIF
6368ENDIF
6369! double
6370IF (ASSOCIATED(this%dativar%d)) THEN
6371 IF (ASSOCIATED(this%dativarattr%r)) THEN
6372 DO i = 1, SIZE(this%dativar%d)
6373 this%dativar%d(i)%r = &
6374 firsttrue(this%dativar%d(i)%btable == this%dativarattr%r(:)%btable)
6375 ENDDO
6376 ENDIF
6377
6378 IF (ASSOCIATED(this%dativarattr%d)) THEN
6379 DO i = 1, SIZE(this%dativar%d)
6380 this%dativar%d(i)%d = &
6381 firsttrue(this%dativar%d(i)%btable == this%dativarattr%d(:)%btable)
6382 ENDDO
6383 ENDIF
6384
6385 IF (ASSOCIATED(this%dativarattr%i)) THEN
6386 DO i = 1, SIZE(this%dativar%d)
6387 this%dativar%d(i)%i = &
6388 firsttrue(this%dativar%d(i)%btable == this%dativarattr%i(:)%btable)
6389 ENDDO
6390 ENDIF
6391
6392 IF (ASSOCIATED(this%dativarattr%b)) THEN
6393 DO i = 1, SIZE(this%dativar%d)
6394 this%dativar%d(i)%b = &
6395 firsttrue(this%dativar%d(i)%btable == this%dativarattr%b(:)%btable)
6396 ENDDO
6397 ENDIF
6398
6399 IF (ASSOCIATED(this%dativarattr%c)) THEN
6400 DO i = 1, SIZE(this%dativar%d)
6401 this%dativar%d(i)%c = &
6402 firsttrue(this%dativar%d(i)%btable == this%dativarattr%c(:)%btable)
6403 ENDDO
6404 ENDIF
6405ENDIF
6406! integer
6407IF (ASSOCIATED(this%dativar%i)) THEN
6408 IF (ASSOCIATED(this%dativarattr%r)) THEN
6409 DO i = 1, SIZE(this%dativar%i)
6410 this%dativar%i(i)%r = &
6411 firsttrue(this%dativar%i(i)%btable == this%dativarattr%r(:)%btable)
6412 ENDDO
6413 ENDIF
6414
6415 IF (ASSOCIATED(this%dativarattr%d)) THEN
6416 DO i = 1, SIZE(this%dativar%i)
6417 this%dativar%i(i)%d = &
6418 firsttrue(this%dativar%i(i)%btable == this%dativarattr%d(:)%btable)
6419 ENDDO
6420 ENDIF
6421
6422 IF (ASSOCIATED(this%dativarattr%i)) THEN
6423 DO i = 1, SIZE(this%dativar%i)
6424 this%dativar%i(i)%i = &
6425 firsttrue(this%dativar%i(i)%btable == this%dativarattr%i(:)%btable)
6426 ENDDO
6427 ENDIF
6428
6429 IF (ASSOCIATED(this%dativarattr%b)) THEN
6430 DO i = 1, SIZE(this%dativar%i)
6431 this%dativar%i(i)%b = &
6432 firsttrue(this%dativar%i(i)%btable == this%dativarattr%b(:)%btable)
6433 ENDDO
6434 ENDIF
6435
6436 IF (ASSOCIATED(this%dativarattr%c)) THEN
6437 DO i = 1, SIZE(this%dativar%i)
6438 this%dativar%i(i)%c = &
6439 firsttrue(this%dativar%i(i)%btable == this%dativarattr%c(:)%btable)
6440 ENDDO
6441 ENDIF
6442ENDIF
6443! byte
6444IF (ASSOCIATED(this%dativar%b)) THEN
6445 IF (ASSOCIATED(this%dativarattr%r)) THEN
6446 DO i = 1, SIZE(this%dativar%b)
6447 this%dativar%b(i)%r = &
6448 firsttrue(this%dativar%b(i)%btable == this%dativarattr%r(:)%btable)
6449 ENDDO
6450 ENDIF
6451
6452 IF (ASSOCIATED(this%dativarattr%d)) THEN
6453 DO i = 1, SIZE(this%dativar%b)
6454 this%dativar%b(i)%d = &
6455 firsttrue(this%dativar%b(i)%btable == this%dativarattr%d(:)%btable)
6456 ENDDO
6457 ENDIF
6458
6459 IF (ASSOCIATED(this%dativarattr%i)) THEN
6460 DO i = 1, SIZE(this%dativar%b)
6461 this%dativar%b(i)%i = &
6462 firsttrue(this%dativar%b(i)%btable == this%dativarattr%i(:)%btable)
6463 ENDDO
6464 ENDIF
6465
6466 IF (ASSOCIATED(this%dativarattr%b)) THEN
6467 DO i = 1, SIZE(this%dativar%b)
6468 this%dativar%b(i)%b = &
6469 firsttrue(this%dativar%b(i)%btable == this%dativarattr%b(:)%btable)
6470 ENDDO
6471 ENDIF
6472
6473 IF (ASSOCIATED(this%dativarattr%c)) THEN
6474 DO i = 1, SIZE(this%dativar%b)
6475 this%dativar%b(i)%c = &
6476 firsttrue(this%dativar%b(i)%btable == this%dativarattr%c(:)%btable)
6477 ENDDO
6478 ENDIF
6479ENDIF
6480! character
6481IF (ASSOCIATED(this%dativar%c)) THEN
6482 IF (ASSOCIATED(this%dativarattr%r)) THEN
6483 DO i = 1, SIZE(this%dativar%c)
6484 this%dativar%c(i)%r = &
6485 firsttrue(this%dativar%c(i)%btable == this%dativarattr%r(:)%btable)
6486 ENDDO
6487 ENDIF
6488
6489 IF (ASSOCIATED(this%dativarattr%d)) THEN
6490 DO i = 1, SIZE(this%dativar%c)
6491 this%dativar%c(i)%d = &
6492 firsttrue(this%dativar%c(i)%btable == this%dativarattr%d(:)%btable)
6493 ENDDO
6494 ENDIF
6495
6496 IF (ASSOCIATED(this%dativarattr%i)) THEN
6497 DO i = 1, SIZE(this%dativar%c)
6498 this%dativar%c(i)%i = &
6499 firsttrue(this%dativar%c(i)%btable == this%dativarattr%i(:)%btable)
6500 ENDDO
6501 ENDIF
6502
6503 IF (ASSOCIATED(this%dativarattr%b)) THEN
6504 DO i = 1, SIZE(this%dativar%c)
6505 this%dativar%c(i)%b = &
6506 firsttrue(this%dativar%c(i)%btable == this%dativarattr%b(:)%btable)
6507 ENDDO
6508 ENDIF
6509
6510 IF (ASSOCIATED(this%dativarattr%c)) THEN
6511 DO i = 1, SIZE(this%dativar%c)
6512 this%dativar%c(i)%c = &
6513 firsttrue(this%dativar%c(i)%btable == this%dativarattr%c(:)%btable)
6514 ENDDO
6515 ENDIF
6516ENDIF
6517
6518END SUBROUTINE vol7d_set_attr_ind
6519
6520
6521!> Metodo per fondere 2 oggetti vol7d.
6522!! Il secondo volume viene accodato al primo e poi distrutto, si veda
6523!! quindi la descrizione di ::vol7d_append. Se uno degli oggetti \a
6524!! this o \a that sono vuoti non perde tempo inutile,
6525SUBROUTINE vol7d_merge(this, that, sort, bestdata, &
6526 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
6527TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, alla fine conterrà il risultato della fusione
6528TYPE(vol7d),INTENT(INOUT) :: that !< secondo oggetto in ingresso, alla fine sarà distrutto
6529LOGICAL,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
6530LOGICAL,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
6531LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple ! experimental, please do not use outside the library now
6532
6533TYPE(vol7d) :: v7d_clean
6534
6535
6537 this = that
6539 that = v7d_clean ! destroy that without deallocating
6540ELSE ! Append that to this and destroy that
6542 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
6544ENDIF
6545
6546END SUBROUTINE vol7d_merge
6547
6548
6549!> Metodo per accodare un oggetto vol7d ad un altro.
6550!! Si tratta di un metodo molto potente e versatile;
6551!! i descrittori delle dimensioni del volume finale conterranno i valori
6552!! dei corrispondenti descrittori del primo e del secondo volume
6553!! e i volumi di anagrafica e dati conterranno i valori dei due volumi
6554!! ai posti giusti, e valori mancanti per le nuove combinazioni che
6555!! eventualmente si verranno a creare.
6556!! Se i volumi multidimensionali di anagrafica e/o dati dei 2 oggetti
6557!! hanno un'intersezione non nulla, negli elementi comuni il volume finale
6558!! conterrà il corrispondente elemento del \b secondo volume.
6559!! Attenzione che, durante l'esecuzione del metodo, la memoria richiesta è
6560!! pari alla memoria complessiva occupata dai 2 volumi iniziali più
6561!! la memoria complessiva del volume finale, per cui, nel caso di volumi grandi,
6562!! ci potrebbero essere problemi di esaurimento della memoria centrale.
6563!! Se l'oggetto \a that è vuoto non perde tempo inutile,
6564!!
6565!! \todo nel caso di elementi comuni inserire la possibiità (opzionale per
6566!! non penalizzare le prestazioni quando ciò non serve) di effettuare una scelta
6567!! più ragionata dell'elemento da tenere, almeno controllando i dati mancanti
6568!! se non le flag di qualità
6569!!
6570!! \todo "rateizzare" l'allocazione dei volumi per ridurre l'occupazione di
6571!! memoria nel caso siano allocati contemporaneamente volumi di variabili e
6572!! di attributi o più volumi di tipi diversi
6573!!
6574!! \todo il parametro \a that è dichiarato \a INOUT perché la vol7d_alloc_vol
6575!! può modificarlo, bisognerebbe implementare una vol7d_check_vol che restituisca
6576!! errore anziché usare la vol7d_alloc_vol.
6577SUBROUTINE vol7d_append(this, that, sort, bestdata, &
6578 ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple)
6579TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, a cui sarà accodato il secondo
6580TYPE(vol7d),INTENT(IN) :: that !< secondo oggetto in ingresso, non viene modificato dal metodo
6581LOGICAL,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
6582! experimental, please do not use outside the library now, they force the use
6583! of a simplified mapping algorithm which is valid only whene the dimension
6584! content is the same in both volumes , or when one of them is empty
6585LOGICAL,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
6586LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple
6587
6588
6589TYPE(vol7d) :: v7dtmp
6590LOGICAL :: lsort, lbestdata
6591INTEGER,POINTER :: remapt1(:), remapt2(:), remaptr1(:), remaptr2(:), &
6592 remapl1(:), remapl2(:), remapa1(:), remapa2(:), remapn1(:), remapn2(:)
6593
6595IF (.NOT.vol7d_check_vol(that)) RETURN ! be safe
6598 RETURN
6599ENDIF
6600
6601IF (this%time_definition /= that%time_definition) THEN
6602 CALL l4f_log(l4f_fatal, &
6603 'in vol7d_append, cannot append volumes with different &
6604 &time definition')
6605 CALL raise_fatal_error()
6606ENDIF
6607
6608! Completo l'allocazione per avere volumi a norma
6609CALL vol7d_alloc_vol(this)
6610
6614
6615! Calcolo le mappature tra volumi vecchi e volume nuovo
6616! I puntatori remap* vengono tutti o allocati o nullificati
6617IF (optio_log(ltimesimple)) THEN
6618 CALL vol7d_remap2simple_datetime(this%time, that%time, v7dtmp%time, &
6619 lsort, remapt1, remapt2)
6620ELSE
6621 CALL vol7d_remap2_datetime(this%time, that%time, v7dtmp%time, &
6622 lsort, remapt1, remapt2)
6623ENDIF
6624IF (optio_log(ltimerangesimple)) THEN
6625 CALL vol7d_remap2simple_vol7d_timerange(this%timerange, that%timerange, &
6626 v7dtmp%timerange, lsort, remaptr1, remaptr2)
6627ELSE
6628 CALL vol7d_remap2_vol7d_timerange(this%timerange, that%timerange, &
6629 v7dtmp%timerange, lsort, remaptr1, remaptr2)
6630ENDIF
6631IF (optio_log(llevelsimple)) THEN
6632 CALL vol7d_remap2simple_vol7d_level(this%level, that%level, v7dtmp%level, &
6633 lsort, remapl1, remapl2)
6634ELSE
6635 CALL vol7d_remap2_vol7d_level(this%level, that%level, v7dtmp%level, &
6636 lsort, remapl1, remapl2)
6637ENDIF
6638IF (optio_log(lanasimple)) THEN
6639 CALL vol7d_remap2simple_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
6640 .false., remapa1, remapa2)
6641ELSE
6642 CALL vol7d_remap2_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
6643 .false., remapa1, remapa2)
6644ENDIF
6645IF (optio_log(lnetworksimple)) THEN
6646 CALL vol7d_remap2simple_vol7d_network(this%network, that%network, v7dtmp%network, &
6647 .false., remapn1, remapn2)
6648ELSE
6649 CALL vol7d_remap2_vol7d_network(this%network, that%network, v7dtmp%network, &
6650 .false., remapn1, remapn2)
6651ENDIF
6652
6653! Faccio la fusione fisica dei volumi
6654CALL vol7d_merge_finalr(this, that, v7dtmp, &
6655 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6656 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6657CALL vol7d_merge_finald(this, that, v7dtmp, &
6658 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6659 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6660CALL vol7d_merge_finali(this, that, v7dtmp, &
6661 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6662 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6663CALL vol7d_merge_finalb(this, that, v7dtmp, &
6664 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6665 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6666CALL vol7d_merge_finalc(this, that, v7dtmp, &
6667 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
6668 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
6669
6670! Dealloco i vettori di rimappatura
6671IF (ASSOCIATED(remapt1)) DEALLOCATE(remapt1)
6672IF (ASSOCIATED(remapt2)) DEALLOCATE(remapt2)
6673IF (ASSOCIATED(remaptr1)) DEALLOCATE(remaptr1)
6674IF (ASSOCIATED(remaptr2)) DEALLOCATE(remaptr2)
6675IF (ASSOCIATED(remapl1)) DEALLOCATE(remapl1)
6676IF (ASSOCIATED(remapl2)) DEALLOCATE(remapl2)
6677IF (ASSOCIATED(remapa1)) DEALLOCATE(remapa1)
6678IF (ASSOCIATED(remapa2)) DEALLOCATE(remapa2)
6679IF (ASSOCIATED(remapn1)) DEALLOCATE(remapn1)
6680IF (ASSOCIATED(remapn2)) DEALLOCATE(remapn2)
6681
6682! Distruggo il vecchio volume e assegno il nuovo a this
6684this = v7dtmp
6685! Ricreo gli indici var-attr
6686CALL vol7d_set_attr_ind(this)
6687
6688END SUBROUTINE vol7d_append
6689
6690
6691!> Metodo per creare una copia completa e indipendente di un oggetto vol7d.
6692!! Questo metodo crea un duplicato di tutti i membri di un oggetto vol7d,
6693!! con la possibilità di rielaborarlo durante la copia. Se l'oggetto da copiare
6694!! è vuoto non perde tempo inutile.
6695!! Attenzione, il codice:
6696!! \code
6697!! USE vol7d_class
6698!! TYPE(vol7d) :: vol1, vol2
6699!! CALL init(vol1)
6700!! CALL init(vol2)
6701!! ... ! riempio vol1
6702!! vol2 = vol1
6703!! \endcode
6704!! fa una cosa diversa rispetto a:
6705!! \code
6706!! USE vol7d_class
6707!! TYPE(vol7d) :: vol1, vol2
6708!! CALL init(vol1)
6709!! CALL init(vol2)
6710!! ... ! riempio vol1
6711!! CALL vol7d_copy(vol1, vol2)
6712!! \endcode
6713!! nel primo caso, infatti, l'operatore di assegnazione copia solo i componenti
6714!! statici di \a vol1 nei corrispondenti elementi di \a vol2, mentre i componenti che
6715!! sono allocati dinamicamente (cioè quelli che in ::vol7d hanno l'attributo
6716!! \c POINTER, in pratica quasi tutti) non vengono duplicati, ma per essi vol2
6717!! conterrà un puntatore al corrispondente elemento a cui già punta vol1, e quindi
6718!! eventuali cambiamenti al contenuto di uno dei due oggetti influenzerà il
6719!! contenuto dell'altro; nel secondo caso, invece, vol1 e vol2 sono, dopo la
6720!! vol7d_copy, 2 istanze
6721!! completamente indipendenti, ma uguali tra loro per contenuto, della classe
6722!! vol7d, e quindi hanno vita indipendente.
6723SUBROUTINE vol7d_copy(this, that, sort, unique, miss, &
6724 lsort_time, lsort_timerange, lsort_level, &
6725 ltime, ltimerange, llevel, lana, lnetwork, &
6726 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
6727 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
6728 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
6729 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
6730 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
6731 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
6732TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
6733TYPE(vol7d),INTENT(INOUT) :: that !< oggetto destinazione
6734LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
6735LOGICAL,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)
6736LOGICAL,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
6737LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
6738LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
6739LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
6740!> se fornito, deve essere un vettore logico della stessa lunghezza di
6741!! this%time indicante quali elementi della dimensione \a time
6742!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
6743!! nel volume copiato; in alternativa può essere un vettore di
6744!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
6745!! gli elementi (utile principalmente per le variabili); è compatibile
6746!! col parametro \a miss
6747LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
6748!> come il precedente per la dimensione \a timerange
6749LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:)
6750!> come il precedente per la dimensione \a level
6751LOGICAL,INTENT(IN),OPTIONAL :: llevel(:)
6752!> come il precedente per la dimensione \a ana
6753LOGICAL,INTENT(IN),OPTIONAL :: lana(:)
6754!> come il precedente per la dimensione \a network
6755LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:)
6756!> come il precedente per tutte le possibili dimensioni variabile
6757LOGICAL,INTENT(in),OPTIONAL :: &
6758 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
6759 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
6760 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
6761 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
6762 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
6763 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
6764
6765LOGICAL :: lsort, lunique, lmiss
6766INTEGER,POINTER :: remapt(:), remaptr(:), remapl(:), remapa(:), remapn(:)
6767
6770IF (.NOT.vol7d_check_vol(this)) RETURN ! be safe
6771
6775
6776! Calcolo le mappature tra volume vecchio e volume nuovo
6777! I puntatori remap* vengono tutti o allocati o nullificati
6778CALL vol7d_remap1_datetime(this%time, that%time, &
6779 lsort.OR.optio_log(lsort_time), lunique, lmiss, remapt, ltime)
6780CALL vol7d_remap1_vol7d_timerange(this%timerange, that%timerange, &
6781 lsort.OR.optio_log(lsort_timerange), lunique, lmiss, remaptr, ltimerange)
6782CALL vol7d_remap1_vol7d_level(this%level, that%level, &
6783 lsort.OR.optio_log(lsort_level), lunique, lmiss, remapl, llevel)
6784CALL vol7d_remap1_vol7d_ana(this%ana, that%ana, &
6785 lsort, lunique, lmiss, remapa, lana)
6786CALL vol7d_remap1_vol7d_network(this%network, that%network, &
6787 lsort, lunique, lmiss, remapn, lnetwork)
6788
6789! lanavari, lanavarb, lanavarc, &
6790! lanaattri, lanaattrb, lanaattrc, &
6791! lanavarattri, lanavarattrb, lanavarattrc, &
6792! ldativari, ldativarb, ldativarc, &
6793! ldatiattri, ldatiattrb, ldatiattrc, &
6794! ldativarattri, ldativarattrb, ldativarattrc
6795! Faccio la riforma fisica dei volumi
6796CALL vol7d_reform_finalr(this, that, &
6797 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6798 lanavarr, lanaattrr, lanavarattrr, ldativarr, ldatiattrr, ldativarattrr)
6799CALL vol7d_reform_finald(this, that, &
6800 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6801 lanavard, lanaattrd, lanavarattrd, ldativard, ldatiattrd, ldativarattrd)
6802CALL vol7d_reform_finali(this, that, &
6803 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6804 lanavari, lanaattri, lanavarattri, ldativari, ldatiattri, ldativarattri)
6805CALL vol7d_reform_finalb(this, that, &
6806 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6807 lanavarb, lanaattrb, lanavarattrb, ldativarb, ldatiattrb, ldativarattrb)
6808CALL vol7d_reform_finalc(this, that, &
6809 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
6810 lanavarc, lanaattrc, lanavarattrc, ldativarc, ldatiattrc, ldativarattrc)
6811
6812! Dealloco i vettori di rimappatura
6813IF (ASSOCIATED(remapt)) DEALLOCATE(remapt)
6814IF (ASSOCIATED(remaptr)) DEALLOCATE(remaptr)
6815IF (ASSOCIATED(remapl)) DEALLOCATE(remapl)
6816IF (ASSOCIATED(remapa)) DEALLOCATE(remapa)
6817IF (ASSOCIATED(remapn)) DEALLOCATE(remapn)
6818
6819! Ricreo gli indici var-attr
6820CALL vol7d_set_attr_ind(that)
6821that%time_definition = this%time_definition
6822
6823END SUBROUTINE vol7d_copy
6824
6825
6826!> Metodo per riformare in varie maniere un oggetto vol7d.
6827!! Equivale ad una copia (vedi ::vol7d_copy)
6828!! seguita dalla distruzione del volume iniziale e alla
6829!! sua riassegnazione al volume copiato. Ha senso se almeno uno dei parametri
6830!! \a sort, \a uniq o \a miss è fornito uguale a \c .TRUE., altrimenti
6831!! è solo una perdita di tempo.
6832!! Può essere utile, ad esempio, per eliminare stazioni
6833!! o istanti temporali indesiderati, basta assegnare il loro corrispondente
6834!! elemento del descrittore a valore mancante e chiamare vol7d_reform
6835!! con miss=.TRUE. .
6836SUBROUTINE vol7d_reform(this, sort, unique, miss, &
6837 lsort_time, lsort_timerange, lsort_level, &
6838 ltime, ltimerange, llevel, lana, lnetwork, &
6839 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
6840 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
6841 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
6842 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
6843 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
6844 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc&
6845 ,purgeana)
6846TYPE(vol7d),INTENT(INOUT) :: this !< oggetto da riformare
6847LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
6848LOGICAL,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)
6849LOGICAL,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
6850LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
6851LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
6852LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
6853!> se fornito, deve essere un vettore logico della stessa lunghezza di
6854!! this%time indicante quali elementi della dimensione \a time
6855!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
6856!! nel volume copiato; in alternativa può essere un vettore di
6857!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
6858!! gli elementi (utile principalmente per le variabili); è compatibile
6859!! col parametro \a miss
6860LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
6861LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:) !< come il precedente per la dimensione \a timerange
6862LOGICAL,INTENT(IN),OPTIONAL :: llevel(:) !< come il precedente per la dimensione \a level
6863LOGICAL,INTENT(IN),OPTIONAL :: lana(:) !< come il precedente per la dimensione \a ana
6864LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:) !< come il precedente per la dimensione \a network
6865!> come il precedente per tutte le possibili dimensioni variabile
6866LOGICAL,INTENT(in),OPTIONAL :: &
6867 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
6868 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
6869 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
6870 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
6871 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
6872 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
6873LOGICAL,INTENT(IN),OPTIONAL :: purgeana !< if true remove ana with all data missing
6874
6875TYPE(vol7d) :: v7dtmp
6876logical,allocatable :: llana(:)
6877integer :: i
6878
6880 lsort_time, lsort_timerange, lsort_level, &
6881 ltime, ltimerange, llevel, lana, lnetwork, &
6882 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
6883 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
6884 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
6885 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
6886 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
6887 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
6888
6889! destroy old volume
6891
6892if (optio_log(purgeana)) then
6893 allocate(llana(size(v7dtmp%ana)))
6894 llana =.false.
6895 do i =1,size(v7dtmp%ana)
6896 if (associated(v7dtmp%voldatii)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatii(i,:,:,:,:,:)))
6897 if (associated(v7dtmp%voldatir)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatir(i,:,:,:,:,:)))
6898 if (associated(v7dtmp%voldatid)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatid(i,:,:,:,:,:)))
6899 if (associated(v7dtmp%voldatib)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatib(i,:,:,:,:,:)))
6900 if (associated(v7dtmp%voldatic)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatic(i,:,:,:,:,:)))
6901 end do
6902 CALL vol7d_copy(v7dtmp, this,lana=llana)
6904 deallocate(llana)
6905else
6906 this=v7dtmp
6907end if
6908
6909END SUBROUTINE vol7d_reform
6910
6911
6912!> Sorts the sortable dimensions in the volume \a this only when necessary.
6913!! Most of the times, the time, timerange and level dimensions in a
6914!! vol7d object are correctly sorted; on the other side many methods
6915!! strictly rely on this fact in order to work correctly. This method
6916!! performs a quick check and sorts the required dimensions only if
6917!! they are not sorted in ascending order yet, improving safety
6918!! without impairing much performance.
6919SUBROUTINE vol7d_smart_sort(this, lsort_time, lsort_timerange, lsort_level)
6920TYPE(vol7d),INTENT(INOUT) :: this !< object to be sorted
6921LOGICAL,OPTIONAL,INTENT(in) :: lsort_time !< if present and \a .TRUE., sort time dimension if it is not sorted in ascending order
6922LOGICAL,OPTIONAL,INTENT(in) :: lsort_timerange !< if present and \a .TRUE., sort timerange dimension if it is not sorted in ascending order
6923LOGICAL,OPTIONAL,INTENT(in) :: lsort_level !< if present and \a .TRUE., sort vertical level dimension if it is not sorted in ascending order
6924
6925INTEGER :: i
6926LOGICAL :: to_be_sorted
6927
6928to_be_sorted = .false.
6929CALL vol7d_alloc_vol(this) ! usual safety check
6930
6931IF (optio_log(lsort_time)) THEN
6932 DO i = 2, SIZE(this%time)
6933 IF (this%time(i) < this%time(i-1)) THEN
6934 to_be_sorted = .true.
6935 EXIT
6936 ENDIF
6937 ENDDO
6938ENDIF
6939IF (optio_log(lsort_timerange)) THEN
6940 DO i = 2, SIZE(this%timerange)
6941 IF (this%timerange(i) < this%timerange(i-1)) THEN
6942 to_be_sorted = .true.
6943 EXIT
6944 ENDIF
6945 ENDDO
6946ENDIF
6947IF (optio_log(lsort_level)) THEN
6948 DO i = 2, SIZE(this%level)
6949 IF (this%level(i) < this%level(i-1)) THEN
6950 to_be_sorted = .true.
6951 EXIT
6952 ENDIF
6953 ENDDO
6954ENDIF
6955
6956IF (to_be_sorted) CALL vol7d_reform(this, &
6957 lsort_time=lsort_time, lsort_timerange=lsort_timerange, lsort_level=lsort_level )
6958
6959END SUBROUTINE vol7d_smart_sort
6960
6961!> Filter the contents of a volume keeping only desired data.
6962!! This subroutine filters a vol7d object by keeping only a subset of
6963!! the data contained. It can keep only times within a specified
6964!! interval, only station networks contained in a list and only
6965!! specified station or data variables. If a filter parameter is not
6966!! provided, no filtering will take place according to that criterion.
6967!! The volume is reallocated keeping only the desired data.
6968SUBROUTINE vol7d_filter(this, avl, vl, nl, s_d, e_d)
6969TYPE(vol7d),INTENT(inout) :: this !< volume to be filtered
6970CHARACTER(len=*),INTENT(in),OPTIONAL :: avl(:) !< list of station variables to be kept, if not provided or of zero length, all variables are kept
6971CHARACTER(len=*),INTENT(in),OPTIONAL :: vl(:) !< list of data variables to be kept, if not provided or of zero length, all variables are kept
6972TYPE(vol7d_network),OPTIONAL :: nl(:) !< list of station networks to be kept, if not provided or of zero length, all networks are kept
6973TYPE(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
6974TYPE(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
6975
6976INTEGER :: i
6977
6978IF (PRESENT(avl)) THEN
6979 IF (SIZE(avl) > 0) THEN
6980
6981 IF (ASSOCIATED(this%anavar%r)) THEN
6982 DO i = 1, SIZE(this%anavar%r)
6983 IF (all(this%anavar%r(i)%btable /= avl)) this%anavar%r(i) = vol7d_var_miss
6984 ENDDO
6985 ENDIF
6986
6987 IF (ASSOCIATED(this%anavar%i)) THEN
6988 DO i = 1, SIZE(this%anavar%i)
6989 IF (all(this%anavar%i(i)%btable /= avl)) this%anavar%i(i) = vol7d_var_miss
6990 ENDDO
6991 ENDIF
6992
6993 IF (ASSOCIATED(this%anavar%b)) THEN
6994 DO i = 1, SIZE(this%anavar%b)
6995 IF (all(this%anavar%b(i)%btable /= avl)) this%anavar%b(i) = vol7d_var_miss
6996 ENDDO
6997 ENDIF
6998
6999 IF (ASSOCIATED(this%anavar%d)) THEN
7000 DO i = 1, SIZE(this%anavar%d)
7001 IF (all(this%anavar%d(i)%btable /= avl)) this%anavar%d(i) = vol7d_var_miss
7002 ENDDO
7003 ENDIF
7004
7005 IF (ASSOCIATED(this%anavar%c)) THEN
7006 DO i = 1, SIZE(this%anavar%c)
7007 IF (all(this%anavar%c(i)%btable /= avl)) this%anavar%c(i) = vol7d_var_miss
7008 ENDDO
7009 ENDIF
7010
7011 ENDIF
7012ENDIF
7013
7014
7015IF (PRESENT(vl)) THEN
7016 IF (size(vl) > 0) THEN
7017 IF (ASSOCIATED(this%dativar%r)) THEN
7018 DO i = 1, SIZE(this%dativar%r)
7019 IF (all(this%dativar%r(i)%btable /= vl)) this%dativar%r(i) = vol7d_var_miss
7020 ENDDO
7021 ENDIF
7022
7023 IF (ASSOCIATED(this%dativar%i)) THEN
7024 DO i = 1, SIZE(this%dativar%i)
7025 IF (all(this%dativar%i(i)%btable /= vl)) this%dativar%i(i) = vol7d_var_miss
7026 ENDDO
7027 ENDIF
7028
7029 IF (ASSOCIATED(this%dativar%b)) THEN
7030 DO i = 1, SIZE(this%dativar%b)
7031 IF (all(this%dativar%b(i)%btable /= vl)) this%dativar%b(i) = vol7d_var_miss
7032 ENDDO
7033 ENDIF
7034
7035 IF (ASSOCIATED(this%dativar%d)) THEN
7036 DO i = 1, SIZE(this%dativar%d)
7037 IF (all(this%dativar%d(i)%btable /= vl)) this%dativar%d(i) = vol7d_var_miss
7038 ENDDO
7039 ENDIF
7040
7041 IF (ASSOCIATED(this%dativar%c)) THEN
7042 DO i = 1, SIZE(this%dativar%c)
7043 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
7044 ENDDO
7045 ENDIF
7046
7047 IF (ASSOCIATED(this%dativar%c)) THEN
7048 DO i = 1, SIZE(this%dativar%c)
7049 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
7050 ENDDO
7051 ENDIF
7052
7053 ENDIF
7054ENDIF
7055
7056IF (PRESENT(nl)) THEN
7057 IF (SIZE(nl) > 0) THEN
7058 DO i = 1, SIZE(this%network)
7059 IF (all(this%network(i) /= nl)) this%network(i) = vol7d_network_miss
7060 ENDDO
7061 ENDIF
7062ENDIF
7063
7064IF (PRESENT(s_d)) THEN
7066 WHERE (this%time < s_d)
7067 this%time = datetime_miss
7068 END WHERE
7069 ENDIF
7070ENDIF
7071
7072IF (PRESENT(e_d)) THEN
7074 WHERE (this%time > e_d)
7075 this%time = datetime_miss
7076 END WHERE
7077 ENDIF
7078ENDIF
7079
7080CALL vol7d_reform(this, miss=.true.)
7081
7082END SUBROUTINE vol7d_filter
7083
7084
7085!> Metodo per convertire i volumi di dati di un oggetto vol7d in dati
7086!! reali dove possibile. L'oggetto convertito è una copia completa
7087!! dell'originale che può essere quindi distrutto dopo la chiamata.
7088!! Per i dati di anagrafica, al momento sono convertiti solo
7089!! i dati CHARACTER se è passato \a anaconv=.TRUE.
7090!! Gli attributi non sono toccati.
7091SUBROUTINE vol7d_convr(this, that, anaconv)
7092TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
7093TYPE(vol7d),INTENT(INOUT) :: that !< oggetto convertito
7094LOGICAL,OPTIONAL,INTENT(in) :: anaconv !< converti anche anagrafica
7095INTEGER :: i
7096LOGICAL :: fv(1)=(/.false./), tv(1)=(/.true./), acp(1), acn(1)
7097TYPE(vol7d) :: v7d_tmp
7098
7099IF (optio_log(anaconv)) THEN
7100 acp=fv
7101 acn=tv
7102ELSE
7103 acp=tv
7104 acn=fv
7105ENDIF
7106
7107! Volume con solo i dati reali e tutti gli attributi
7108! l'anagrafica e` copiata interamente se necessario
7109CALL vol7d_copy(this, that, &
7110 lanavarr=tv, lanavard=acp, lanavari=acp, lanavarb=acp, lanavarc=acp, &
7111 ldativarr=tv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=fv)
7112
7113! Volume solo di dati double
7114CALL vol7d_copy(this, v7d_tmp, &
7115 lanavarr=fv, lanavard=acn, lanavari=fv, lanavarb=fv, lanavarc=fv, &
7116 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
7117 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
7118 ldativarr=fv, ldativard=tv, ldativari=fv, ldativarb=fv, ldativarc=fv, &
7119 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
7120 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
7121
7122! converto a dati reali
7123IF (ASSOCIATED(v7d_tmp%anavar%d) .OR. ASSOCIATED(v7d_tmp%dativar%d)) THEN
7124
7125 IF (ASSOCIATED(v7d_tmp%anavar%d)) THEN
7126! alloco i dati reali e vi trasferisco i double
7127 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanad, 1), SIZE(v7d_tmp%volanad, 2), &
7128 SIZE(v7d_tmp%volanad, 3)))
7129 DO i = 1, SIZE(v7d_tmp%anavar%d)
7130 v7d_tmp%volanar(:,i,:) = &
7131 realdat(v7d_tmp%volanad(:,i,:), v7d_tmp%anavar%d(i))
7132 ENDDO
7133 DEALLOCATE(v7d_tmp%volanad)
7134! trasferisco le variabili
7135 v7d_tmp%anavar%r => v7d_tmp%anavar%d
7136 NULLIFY(v7d_tmp%anavar%d)
7137 ENDIF
7138
7139 IF (ASSOCIATED(v7d_tmp%dativar%d)) THEN
7140! alloco i dati reali e vi trasferisco i double
7141 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatid, 1), SIZE(v7d_tmp%voldatid, 2), &
7142 SIZE(v7d_tmp%voldatid, 3), SIZE(v7d_tmp%voldatid, 4), SIZE(v7d_tmp%voldatid, 5), &
7143 SIZE(v7d_tmp%voldatid, 6)))
7144 DO i = 1, SIZE(v7d_tmp%dativar%d)
7145 v7d_tmp%voldatir(:,:,:,:,i,:) = &
7146 realdat(v7d_tmp%voldatid(:,:,:,:,i,:), v7d_tmp%dativar%d(i))
7147 ENDDO
7148 DEALLOCATE(v7d_tmp%voldatid)
7149! trasferisco le variabili
7150 v7d_tmp%dativar%r => v7d_tmp%dativar%d
7151 NULLIFY(v7d_tmp%dativar%d)
7152 ENDIF
7153
7154! fondo con il volume definitivo
7155 CALL vol7d_merge(that, v7d_tmp)
7156ELSE
7158ENDIF
7159
7160
7161! Volume solo di dati interi
7162CALL vol7d_copy(this, v7d_tmp, &
7163 lanavarr=fv, lanavard=fv, lanavari=acn, lanavarb=fv, lanavarc=fv, &
7164 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
7165 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
7166 ldativarr=fv, ldativard=fv, ldativari=tv, ldativarb=fv, ldativarc=fv, &
7167 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
7168 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
7169
7170! converto a dati reali
7171IF (ASSOCIATED(v7d_tmp%anavar%i) .OR. ASSOCIATED(v7d_tmp%dativar%i)) THEN
7172
7173 IF (ASSOCIATED(v7d_tmp%anavar%i)) THEN
7174! alloco i dati reali e vi trasferisco gli interi
7175 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanai, 1), SIZE(v7d_tmp%volanai, 2), &
7176 SIZE(v7d_tmp%volanai, 3)))
7177 DO i = 1, SIZE(v7d_tmp%anavar%i)
7178 v7d_tmp%volanar(:,i,:) = &
7179 realdat(v7d_tmp%volanai(:,i,:), v7d_tmp%anavar%i(i))
7180 ENDDO
7181 DEALLOCATE(v7d_tmp%volanai)
7182! trasferisco le variabili
7183 v7d_tmp%anavar%r => v7d_tmp%anavar%i
7184 NULLIFY(v7d_tmp%anavar%i)
7185 ENDIF
7186
7187 IF (ASSOCIATED(v7d_tmp%dativar%i)) THEN
7188! alloco i dati reali e vi trasferisco gli interi
7189 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatii, 1), SIZE(v7d_tmp%voldatii, 2), &
7190 SIZE(v7d_tmp%voldatii, 3), SIZE(v7d_tmp%voldatii, 4), SIZE(v7d_tmp%voldatii, 5), &
7191 SIZE(v7d_tmp%voldatii, 6)))
7192 DO i = 1, SIZE(v7d_tmp%dativar%i)
7193 v7d_tmp%voldatir(:,:,:,:,i,:) = &
7194 realdat(v7d_tmp%voldatii(:,:,:,:,i,:), v7d_tmp%dativar%i(i))
7195 ENDDO
7196 DEALLOCATE(v7d_tmp%voldatii)
7197! trasferisco le variabili
7198 v7d_tmp%dativar%r => v7d_tmp%dativar%i
7199 NULLIFY(v7d_tmp%dativar%i)
7200 ENDIF
7201
7202! fondo con il volume definitivo
7203 CALL vol7d_merge(that, v7d_tmp)
7204ELSE
7206ENDIF
7207
7208
7209! Volume solo di dati byte
7210CALL vol7d_copy(this, v7d_tmp, &
7211 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=acn, lanavarc=fv, &
7212 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
7213 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
7214 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=tv, ldativarc=fv, &
7215 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
7216 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
7217
7218! converto a dati reali
7219IF (ASSOCIATED(v7d_tmp%anavar%b) .OR. ASSOCIATED(v7d_tmp%dativar%b)) THEN
7220
7221 IF (ASSOCIATED(v7d_tmp%anavar%b)) THEN
7222! alloco i dati reali e vi trasferisco i byte
7223 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanab, 1), SIZE(v7d_tmp%volanab, 2), &
7224 SIZE(v7d_tmp%volanab, 3)))
7225 DO i = 1, SIZE(v7d_tmp%anavar%b)
7226 v7d_tmp%volanar(:,i,:) = &
7227 realdat(v7d_tmp%volanab(:,i,:), v7d_tmp%anavar%b(i))
7228 ENDDO
7229 DEALLOCATE(v7d_tmp%volanab)
7230! trasferisco le variabili
7231 v7d_tmp%anavar%r => v7d_tmp%anavar%b
7232 NULLIFY(v7d_tmp%anavar%b)
7233 ENDIF
7234
7235 IF (ASSOCIATED(v7d_tmp%dativar%b)) THEN
7236! alloco i dati reali e vi trasferisco i byte
7237 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatib, 1), SIZE(v7d_tmp%voldatib, 2), &
7238 SIZE(v7d_tmp%voldatib, 3), SIZE(v7d_tmp%voldatib, 4), SIZE(v7d_tmp%voldatib, 5), &
7239 SIZE(v7d_tmp%voldatib, 6)))
7240 DO i = 1, SIZE(v7d_tmp%dativar%b)
7241 v7d_tmp%voldatir(:,:,:,:,i,:) = &
7242 realdat(v7d_tmp%voldatib(:,:,:,:,i,:), v7d_tmp%dativar%b(i))
7243 ENDDO
7244 DEALLOCATE(v7d_tmp%voldatib)
7245! trasferisco le variabili
7246 v7d_tmp%dativar%r => v7d_tmp%dativar%b
7247 NULLIFY(v7d_tmp%dativar%b)
7248 ENDIF
7249
7250! fondo con il volume definitivo
7251 CALL vol7d_merge(that, v7d_tmp)
7252ELSE
7254ENDIF
7255
7256
7257! Volume solo di dati character
7258CALL vol7d_copy(this, v7d_tmp, &
7259 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=fv, lanavarc=acn, &
7260 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
7261 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
7262 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=tv, &
7263 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
7264 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
7265
7266! converto a dati reali
7267IF (ASSOCIATED(v7d_tmp%anavar%c) .OR. ASSOCIATED(v7d_tmp%dativar%c)) THEN
7268
7269 IF (ASSOCIATED(v7d_tmp%anavar%c)) THEN
7270! alloco i dati reali e vi trasferisco i character
7271 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanac, 1), SIZE(v7d_tmp%volanac, 2), &
7272 SIZE(v7d_tmp%volanac, 3)))
7273 DO i = 1, SIZE(v7d_tmp%anavar%c)
7274 v7d_tmp%volanar(:,i,:) = &
7275 realdat(v7d_tmp%volanac(:,i,:), v7d_tmp%anavar%c(i))
7276 ENDDO
7277 DEALLOCATE(v7d_tmp%volanac)
7278! trasferisco le variabili
7279 v7d_tmp%anavar%r => v7d_tmp%anavar%c
7280 NULLIFY(v7d_tmp%anavar%c)
7281 ENDIF
7282
7283 IF (ASSOCIATED(v7d_tmp%dativar%c)) THEN
7284! alloco i dati reali e vi trasferisco i character
7285 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatic, 1), SIZE(v7d_tmp%voldatic, 2), &
7286 SIZE(v7d_tmp%voldatic, 3), SIZE(v7d_tmp%voldatic, 4), SIZE(v7d_tmp%voldatic, 5), &
7287 SIZE(v7d_tmp%voldatic, 6)))
7288 DO i = 1, SIZE(v7d_tmp%dativar%c)
7289 v7d_tmp%voldatir(:,:,:,:,i,:) = &
7290 realdat(v7d_tmp%voldatic(:,:,:,:,i,:), v7d_tmp%dativar%c(i))
7291 ENDDO
7292 DEALLOCATE(v7d_tmp%voldatic)
7293! trasferisco le variabili
7294 v7d_tmp%dativar%r => v7d_tmp%dativar%c
7295 NULLIFY(v7d_tmp%dativar%c)
7296 ENDIF
7297
7298! fondo con il volume definitivo
7299 CALL vol7d_merge(that, v7d_tmp)
7300ELSE
7302ENDIF
7303
7304END SUBROUTINE vol7d_convr
7305
7306
7307!> Metodo per ottenere solo le differenze tra due oggetti vol7d.
7308!! Il primo volume viene confrontato col secondo; nel secondo volume ovunque
7309!! i dati confrontati siano coincidenti viene impostato valore mancante.
7310SUBROUTINE vol7d_diff_only (this, that, data_only,ana)
7311TYPE(vol7d),INTENT(IN) :: this !< primo volume da confrontare
7312TYPE(vol7d),INTENT(OUT) :: that !< secondo volume da confrontare in cui eliminare i dati coincidenti
7313logical , optional, intent(in) :: data_only !< attiva l'elaborazione dei soli dati e non dell'anagrafica (default: .false.)
7314logical , optional, intent(in) :: ana !< attiva l'elaborazione dell'anagrafica (coordinate e ident) (default: .false.)
7315logical :: ldata_only,lana
7316
7317IF (PRESENT(data_only)) THEN
7318 ldata_only = data_only
7319ELSE
7320 ldata_only = .false.
7321ENDIF
7322
7323IF (PRESENT(ana)) THEN
7324 lana = ana
7325ELSE
7326 lana = .false.
7327ENDIF
7328
7329
7330#undef VOL7D_POLY_ARRAY
7331#define VOL7D_POLY_ARRAY voldati
7332#include "vol7d_class_diff.F90"
7333#undef VOL7D_POLY_ARRAY
7334#define VOL7D_POLY_ARRAY voldatiattr
7335#include "vol7d_class_diff.F90"
7336#undef VOL7D_POLY_ARRAY
7337
7338if ( .not. ldata_only) then
7339
7340#define VOL7D_POLY_ARRAY volana
7341#include "vol7d_class_diff.F90"
7342#undef VOL7D_POLY_ARRAY
7343#define VOL7D_POLY_ARRAY volanaattr
7344#include "vol7d_class_diff.F90"
7345#undef VOL7D_POLY_ARRAY
7346
7347 if(lana)then
7348 where ( this%ana == that%ana )
7349 that%ana = vol7d_ana_miss
7350 end where
7351 end if
7352
7353end if
7354
7355
7356
7357END SUBROUTINE vol7d_diff_only
7358
7359
7360
7361! Creo le routine da ripetere per i vari tipi di dati di v7d
7362! tramite un template e il preprocessore
7363#undef VOL7D_POLY_TYPE
7364#undef VOL7D_POLY_TYPES
7365#define VOL7D_POLY_TYPE REAL
7366#define VOL7D_POLY_TYPES r
7367#include "vol7d_class_type_templ.F90"
7368#undef VOL7D_POLY_TYPE
7369#undef VOL7D_POLY_TYPES
7370#define VOL7D_POLY_TYPE DOUBLE PRECISION
7371#define VOL7D_POLY_TYPES d
7372#include "vol7d_class_type_templ.F90"
7373#undef VOL7D_POLY_TYPE
7374#undef VOL7D_POLY_TYPES
7375#define VOL7D_POLY_TYPE INTEGER
7376#define VOL7D_POLY_TYPES i
7377#include "vol7d_class_type_templ.F90"
7378#undef VOL7D_POLY_TYPE
7379#undef VOL7D_POLY_TYPES
7380#define VOL7D_POLY_TYPE INTEGER(kind=int_b)
7381#define VOL7D_POLY_TYPES b
7382#include "vol7d_class_type_templ.F90"
7383#undef VOL7D_POLY_TYPE
7384#undef VOL7D_POLY_TYPES
7385#define VOL7D_POLY_TYPE CHARACTER(len=vol7d_cdatalen)
7386#define VOL7D_POLY_TYPES c
7387#include "vol7d_class_type_templ.F90"
7388
7389! Creo le routine da ripetere per i vari descrittori di dimensioni di v7d
7390! tramite un template e il preprocessore
7391#define VOL7D_SORT
7392#undef VOL7D_NO_ZERO_ALLOC
7393#undef VOL7D_POLY_TYPE
7394#define VOL7D_POLY_TYPE datetime
7395#include "vol7d_class_desc_templ.F90"
7396#undef VOL7D_POLY_TYPE
7397#define VOL7D_POLY_TYPE vol7d_timerange
7398#include "vol7d_class_desc_templ.F90"
7399#undef VOL7D_POLY_TYPE
7400#define VOL7D_POLY_TYPE vol7d_level
7401#include "vol7d_class_desc_templ.F90"
7402#undef VOL7D_SORT
7403#undef VOL7D_POLY_TYPE
7404#define VOL7D_POLY_TYPE vol7d_network
7405#include "vol7d_class_desc_templ.F90"
7406#undef VOL7D_POLY_TYPE
7407#define VOL7D_POLY_TYPE vol7d_ana
7408#include "vol7d_class_desc_templ.F90"
7409#define VOL7D_NO_ZERO_ALLOC
7410#undef VOL7D_POLY_TYPE
7411#define VOL7D_POLY_TYPE vol7d_var
7412#include "vol7d_class_desc_templ.F90"
7413
7414!>\brief Scrittura su file di un volume Vol7d.
7415!! Scrittura su file unformatted di un intero volume Vol7d.
7416!! Il volume viene serializzato e scritto su file.
7417!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
7418!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
7419!! tali parametri saranno in output.
7420!! Se non viene fornito il nome file viene utilizzato un file di default con nome pari al nome del programma in
7421!! esecuzione con postfisso ".v7d".
7422!! Come parametro opzionale c'è la description che insieme alla data corrente viene inserita nell'header del file.
7423subroutine vol7d_write_on_file (this,unit,description,filename,filename_auto)
7424
7425TYPE(vol7d),INTENT(IN) :: this !< volume vol7d da scrivere
7426integer,optional,intent(inout) :: unit !< unità su cui scrivere; se passata =0 ritorna il valore rielaborato (default =rielaborato internamente con getlun )
7427character(len=*),intent(in),optional :: filename !< nome del file su cui scrivere
7428character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
7429character(len=*),INTENT(IN),optional :: description !< descrizione del volume
7430
7431integer :: lunit
7432character(len=254) :: ldescription,arg,lfilename
7433integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
7434 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
7435 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
7436 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
7437 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
7438 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
7439 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
7440!integer :: im,id,iy
7441integer :: tarray(8)
7442logical :: opened,exist
7443
7444 nana=0
7445 ntime=0
7446 ntimerange=0
7447 nlevel=0
7448 nnetwork=0
7449 ndativarr=0
7450 ndativari=0
7451 ndativarb=0
7452 ndativard=0
7453 ndativarc=0
7454 ndatiattrr=0
7455 ndatiattri=0
7456 ndatiattrb=0
7457 ndatiattrd=0
7458 ndatiattrc=0
7459 ndativarattrr=0
7460 ndativarattri=0
7461 ndativarattrb=0
7462 ndativarattrd=0
7463 ndativarattrc=0
7464 nanavarr=0
7465 nanavari=0
7466 nanavarb=0
7467 nanavard=0
7468 nanavarc=0
7469 nanaattrr=0
7470 nanaattri=0
7471 nanaattrb=0
7472 nanaattrd=0
7473 nanaattrc=0
7474 nanavarattrr=0
7475 nanavarattri=0
7476 nanavarattrb=0
7477 nanavarattrd=0
7478 nanavarattrc=0
7479
7480
7481!call idate(im,id,iy)
7482call date_and_time(values=tarray)
7483call getarg(0,arg)
7484
7485if (present(description))then
7486 ldescription=description
7487else
7488 ldescription="Vol7d generated by: "//trim(arg)
7489end if
7490
7491if (.not. present(unit))then
7492 lunit=getunit()
7493else
7494 if (unit==0)then
7495 lunit=getunit()
7496 unit=lunit
7497 else
7498 lunit=unit
7499 end if
7500end if
7501
7502lfilename=trim(arg)//".v7d"
7504
7505if (present(filename))then
7506 if (filename /= "")then
7507 lfilename=filename
7508 end if
7509end if
7510
7511if (present(filename_auto))filename_auto=lfilename
7512
7513
7514inquire(unit=lunit,opened=opened)
7515if (.not. opened) then
7516! inquire(file=lfilename, EXIST=exist)
7517! IF (exist) THEN
7518! CALL l4f_log(L4F_FATAL, &
7519! 'in vol7d_write_on_file, file exists, cannot open file '//TRIM(lfilename))
7520! CALL raise_fatal_error()
7521! ENDIF
7522 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM')
7523 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
7524end if
7525
7526if (associated(this%ana)) nana=size(this%ana)
7527if (associated(this%time)) ntime=size(this%time)
7528if (associated(this%timerange)) ntimerange=size(this%timerange)
7529if (associated(this%level)) nlevel=size(this%level)
7530if (associated(this%network)) nnetwork=size(this%network)
7531
7532if (associated(this%dativar%r)) ndativarr=size(this%dativar%r)
7533if (associated(this%dativar%i)) ndativari=size(this%dativar%i)
7534if (associated(this%dativar%b)) ndativarb=size(this%dativar%b)
7535if (associated(this%dativar%d)) ndativard=size(this%dativar%d)
7536if (associated(this%dativar%c)) ndativarc=size(this%dativar%c)
7537
7538if (associated(this%datiattr%r)) ndatiattrr=size(this%datiattr%r)
7539if (associated(this%datiattr%i)) ndatiattri=size(this%datiattr%i)
7540if (associated(this%datiattr%b)) ndatiattrb=size(this%datiattr%b)
7541if (associated(this%datiattr%d)) ndatiattrd=size(this%datiattr%d)
7542if (associated(this%datiattr%c)) ndatiattrc=size(this%datiattr%c)
7543
7544if (associated(this%dativarattr%r)) ndativarattrr=size(this%dativarattr%r)
7545if (associated(this%dativarattr%i)) ndativarattri=size(this%dativarattr%i)
7546if (associated(this%dativarattr%b)) ndativarattrb=size(this%dativarattr%b)
7547if (associated(this%dativarattr%d)) ndativarattrd=size(this%dativarattr%d)
7548if (associated(this%dativarattr%c)) ndativarattrc=size(this%dativarattr%c)
7549
7550if (associated(this%anavar%r)) nanavarr=size(this%anavar%r)
7551if (associated(this%anavar%i)) nanavari=size(this%anavar%i)
7552if (associated(this%anavar%b)) nanavarb=size(this%anavar%b)
7553if (associated(this%anavar%d)) nanavard=size(this%anavar%d)
7554if (associated(this%anavar%c)) nanavarc=size(this%anavar%c)
7555
7556if (associated(this%anaattr%r)) nanaattrr=size(this%anaattr%r)
7557if (associated(this%anaattr%i)) nanaattri=size(this%anaattr%i)
7558if (associated(this%anaattr%b)) nanaattrb=size(this%anaattr%b)
7559if (associated(this%anaattr%d)) nanaattrd=size(this%anaattr%d)
7560if (associated(this%anaattr%c)) nanaattrc=size(this%anaattr%c)
7561
7562if (associated(this%anavarattr%r)) nanavarattrr=size(this%anavarattr%r)
7563if (associated(this%anavarattr%i)) nanavarattri=size(this%anavarattr%i)
7564if (associated(this%anavarattr%b)) nanavarattrb=size(this%anavarattr%b)
7565if (associated(this%anavarattr%d)) nanavarattrd=size(this%anavarattr%d)
7566if (associated(this%anavarattr%c)) nanavarattrc=size(this%anavarattr%c)
7567
7568write(unit=lunit)ldescription
7569write(unit=lunit)tarray
7570
7571write(unit=lunit)&
7572 nana, ntime, ntimerange, nlevel, nnetwork, &
7573 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
7574 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
7575 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
7576 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
7577 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
7578 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
7579 this%time_definition
7580
7581
7582!write(unit=lunit)this
7583
7584
7585!! prime 5 dimensioni
7588if (associated(this%level)) write(unit=lunit)this%level
7589if (associated(this%timerange)) write(unit=lunit)this%timerange
7590if (associated(this%network)) write(unit=lunit)this%network
7591
7592 !! 6a dimensione: variabile dell'anagrafica e dei dati
7593 !! con relativi attributi e in 5 tipi diversi
7594
7595if (associated(this%anavar%r)) write(unit=lunit)this%anavar%r
7596if (associated(this%anavar%i)) write(unit=lunit)this%anavar%i
7597if (associated(this%anavar%b)) write(unit=lunit)this%anavar%b
7598if (associated(this%anavar%d)) write(unit=lunit)this%anavar%d
7599if (associated(this%anavar%c)) write(unit=lunit)this%anavar%c
7600
7601if (associated(this%anaattr%r)) write(unit=lunit)this%anaattr%r
7602if (associated(this%anaattr%i)) write(unit=lunit)this%anaattr%i
7603if (associated(this%anaattr%b)) write(unit=lunit)this%anaattr%b
7604if (associated(this%anaattr%d)) write(unit=lunit)this%anaattr%d
7605if (associated(this%anaattr%c)) write(unit=lunit)this%anaattr%c
7606
7607if (associated(this%anavarattr%r)) write(unit=lunit)this%anavarattr%r
7608if (associated(this%anavarattr%i)) write(unit=lunit)this%anavarattr%i
7609if (associated(this%anavarattr%b)) write(unit=lunit)this%anavarattr%b
7610if (associated(this%anavarattr%d)) write(unit=lunit)this%anavarattr%d
7611if (associated(this%anavarattr%c)) write(unit=lunit)this%anavarattr%c
7612
7613if (associated(this%dativar%r)) write(unit=lunit)this%dativar%r
7614if (associated(this%dativar%i)) write(unit=lunit)this%dativar%i
7615if (associated(this%dativar%b)) write(unit=lunit)this%dativar%b
7616if (associated(this%dativar%d)) write(unit=lunit)this%dativar%d
7617if (associated(this%dativar%c)) write(unit=lunit)this%dativar%c
7618
7619if (associated(this%datiattr%r)) write(unit=lunit)this%datiattr%r
7620if (associated(this%datiattr%i)) write(unit=lunit)this%datiattr%i
7621if (associated(this%datiattr%b)) write(unit=lunit)this%datiattr%b
7622if (associated(this%datiattr%d)) write(unit=lunit)this%datiattr%d
7623if (associated(this%datiattr%c)) write(unit=lunit)this%datiattr%c
7624
7625if (associated(this%dativarattr%r)) write(unit=lunit)this%dativarattr%r
7626if (associated(this%dativarattr%i)) write(unit=lunit)this%dativarattr%i
7627if (associated(this%dativarattr%b)) write(unit=lunit)this%dativarattr%b
7628if (associated(this%dativarattr%d)) write(unit=lunit)this%dativarattr%d
7629if (associated(this%dativarattr%c)) write(unit=lunit)this%dativarattr%c
7630
7631!! Volumi di valori e attributi per anagrafica e dati
7632
7633if (associated(this%volanar)) write(unit=lunit)this%volanar
7634if (associated(this%volanaattrr)) write(unit=lunit)this%volanaattrr
7635if (associated(this%voldatir)) write(unit=lunit)this%voldatir
7636if (associated(this%voldatiattrr)) write(unit=lunit)this%voldatiattrr
7637
7638if (associated(this%volanai)) write(unit=lunit)this%volanai
7639if (associated(this%volanaattri)) write(unit=lunit)this%volanaattri
7640if (associated(this%voldatii)) write(unit=lunit)this%voldatii
7641if (associated(this%voldatiattri)) write(unit=lunit)this%voldatiattri
7642
7643if (associated(this%volanab)) write(unit=lunit)this%volanab
7644if (associated(this%volanaattrb)) write(unit=lunit)this%volanaattrb
7645if (associated(this%voldatib)) write(unit=lunit)this%voldatib
7646if (associated(this%voldatiattrb)) write(unit=lunit)this%voldatiattrb
7647
7648if (associated(this%volanad)) write(unit=lunit)this%volanad
7649if (associated(this%volanaattrd)) write(unit=lunit)this%volanaattrd
7650if (associated(this%voldatid)) write(unit=lunit)this%voldatid
7651if (associated(this%voldatiattrd)) write(unit=lunit)this%voldatiattrd
7652
7653if (associated(this%volanac)) write(unit=lunit)this%volanac
7654if (associated(this%volanaattrc)) write(unit=lunit)this%volanaattrc
7655if (associated(this%voldatic)) write(unit=lunit)this%voldatic
7656if (associated(this%voldatiattrc)) write(unit=lunit)this%voldatiattrc
7657
7658if (.not. present(unit)) close(unit=lunit)
7659
7660end subroutine vol7d_write_on_file
7661
7662
7663!>\brief Lettura da file di un volume Vol7d.
7664!! Lettura da file unformatted di un intero volume Vol7d.
7665!! Questa subroutine comprende vol7d_alloc e vol7d_alloc_vol.
7666!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
7667!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
7668!! tali parametri saranno in output.
7669
7670
7671subroutine vol7d_read_from_file (this,unit,filename,description,tarray,filename_auto)
7672
7673TYPE(vol7d),INTENT(OUT) :: this !< Volume vol7d da leggere
7674integer,intent(inout),optional :: unit !< unità su cui è stato aperto un file; se =0 rielaborato internamente (default = elaborato internamente con getunit)
7675character(len=*),INTENT(in),optional :: filename !< nome del file eventualmente da aprire (default = (nome dell'eseguibile)//.v7d )
7676character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
7677character(len=*),INTENT(out),optional :: description !< descrizione del volume letto
7678integer,intent(out),optional :: tarray(8) !< vettore come definito da "date_and_time" della data di scrittura del volume
7679
7680
7681integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
7682 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
7683 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
7684 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
7685 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
7686 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
7687 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
7688
7689character(len=254) :: ldescription,lfilename,arg
7690integer :: ltarray(8),lunit,ios
7691logical :: opened,exist
7692
7693
7694call getarg(0,arg)
7695
7696if (.not. present(unit))then
7697 lunit=getunit()
7698else
7699 if (unit==0)then
7700 lunit=getunit()
7701 unit=lunit
7702 else
7703 lunit=unit
7704 end if
7705end if
7706
7707lfilename=trim(arg)//".v7d"
7709
7710if (present(filename))then
7711 if (filename /= "")then
7712 lfilename=filename
7713 end if
7714end if
7715
7716if (present(filename_auto))filename_auto=lfilename
7717
7718
7719inquire(unit=lunit,opened=opened)
7720IF (.NOT. opened) THEN
7721 inquire(file=lfilename,exist=exist)
7722 IF (.NOT.exist) THEN
7723 CALL l4f_log(l4f_fatal, &
7724 'in vol7d_read_from_file, file does not exists, cannot open')
7725 CALL raise_fatal_error()
7726 ENDIF
7727 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM', &
7728 status='OLD', action='READ')
7729 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
7730end if
7731
7732
7734read(unit=lunit,iostat=ios)ldescription
7735
7736if (ios < 0) then ! A negative value indicates that the End of File or End of Record
7737 call vol7d_alloc (this)
7738 call vol7d_alloc_vol (this)
7739 if (present(description))description=ldescription
7740 if (present(tarray))tarray=ltarray
7741 if (.not. present(unit)) close(unit=lunit)
7742end if
7743
7744read(unit=lunit)ltarray
7745
7746CALL l4f_log(l4f_info, 'Reading vol7d from file')
7747CALL l4f_log(l4f_info, 'description: '//trim(ldescription))
7750
7751if (present(description))description=ldescription
7752if (present(tarray))tarray=ltarray
7753
7754read(unit=lunit)&
7755 nana, ntime, ntimerange, nlevel, nnetwork, &
7756 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
7757 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
7758 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
7759 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
7760 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
7761 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
7762 this%time_definition
7763
7764call vol7d_alloc (this, &
7765 nana=nana, ntime=ntime, ntimerange=ntimerange, nlevel=nlevel, nnetwork=nnetwork,&
7766 ndativarr=ndativarr, ndativari=ndativari, ndativarb=ndativarb,&
7767 ndativard=ndativard, ndativarc=ndativarc,&
7768 ndatiattrr=ndatiattrr, ndatiattri=ndatiattri, ndatiattrb=ndatiattrb,&
7769 ndatiattrd=ndatiattrd, ndatiattrc=ndatiattrc,&
7770 ndativarattrr=ndativarattrr, ndativarattri=ndativarattri, ndativarattrb=ndativarattrb, &
7771 ndativarattrd=ndativarattrd, ndativarattrc=ndativarattrc,&
7772 nanavarr=nanavarr, nanavari=nanavari, nanavarb=nanavarb, &
7773 nanavard=nanavard, nanavarc=nanavarc,&
7774 nanaattrr=nanaattrr, nanaattri=nanaattri, nanaattrb=nanaattrb,&
7775 nanaattrd=nanaattrd, nanaattrc=nanaattrc,&
7776 nanavarattrr=nanavarattrr, nanavarattri=nanavarattri, nanavarattrb=nanavarattrb, &
7777 nanavarattrd=nanavarattrd, nanavarattrc=nanavarattrc)
7778
7779
7782if (associated(this%level)) read(unit=lunit)this%level
7783if (associated(this%timerange)) read(unit=lunit)this%timerange
7784if (associated(this%network)) read(unit=lunit)this%network
7785
7786if (associated(this%anavar%r)) read(unit=lunit)this%anavar%r
7787if (associated(this%anavar%i)) read(unit=lunit)this%anavar%i
7788if (associated(this%anavar%b)) read(unit=lunit)this%anavar%b
7789if (associated(this%anavar%d)) read(unit=lunit)this%anavar%d
7790if (associated(this%anavar%c)) read(unit=lunit)this%anavar%c
7791
7792if (associated(this%anaattr%r)) read(unit=lunit)this%anaattr%r
7793if (associated(this%anaattr%i)) read(unit=lunit)this%anaattr%i
7794if (associated(this%anaattr%b)) read(unit=lunit)this%anaattr%b
7795if (associated(this%anaattr%d)) read(unit=lunit)this%anaattr%d
7796if (associated(this%anaattr%c)) read(unit=lunit)this%anaattr%c
7797
7798if (associated(this%anavarattr%r)) read(unit=lunit)this%anavarattr%r
7799if (associated(this%anavarattr%i)) read(unit=lunit)this%anavarattr%i
7800if (associated(this%anavarattr%b)) read(unit=lunit)this%anavarattr%b
7801if (associated(this%anavarattr%d)) read(unit=lunit)this%anavarattr%d
7802if (associated(this%anavarattr%c)) read(unit=lunit)this%anavarattr%c
7803
7804if (associated(this%dativar%r)) read(unit=lunit)this%dativar%r
7805if (associated(this%dativar%i)) read(unit=lunit)this%dativar%i
7806if (associated(this%dativar%b)) read(unit=lunit)this%dativar%b
7807if (associated(this%dativar%d)) read(unit=lunit)this%dativar%d
7808if (associated(this%dativar%c)) read(unit=lunit)this%dativar%c
7809
7810if (associated(this%datiattr%r)) read(unit=lunit)this%datiattr%r
7811if (associated(this%datiattr%i)) read(unit=lunit)this%datiattr%i
7812if (associated(this%datiattr%b)) read(unit=lunit)this%datiattr%b
7813if (associated(this%datiattr%d)) read(unit=lunit)this%datiattr%d
7814if (associated(this%datiattr%c)) read(unit=lunit)this%datiattr%c
7815
7816if (associated(this%dativarattr%r)) read(unit=lunit)this%dativarattr%r
7817if (associated(this%dativarattr%i)) read(unit=lunit)this%dativarattr%i
7818if (associated(this%dativarattr%b)) read(unit=lunit)this%dativarattr%b
7819if (associated(this%dativarattr%d)) read(unit=lunit)this%dativarattr%d
7820if (associated(this%dativarattr%c)) read(unit=lunit)this%dativarattr%c
7821
7822call vol7d_alloc_vol (this)
7823
7824!! Volumi di valori e attributi per anagrafica e dati
7825
7826if (associated(this%volanar)) read(unit=lunit)this%volanar
7827if (associated(this%volanaattrr)) read(unit=lunit)this%volanaattrr
7828if (associated(this%voldatir)) read(unit=lunit)this%voldatir
7829if (associated(this%voldatiattrr)) read(unit=lunit)this%voldatiattrr
7830
7831if (associated(this%volanai)) read(unit=lunit)this%volanai
7832if (associated(this%volanaattri)) read(unit=lunit)this%volanaattri
7833if (associated(this%voldatii)) read(unit=lunit)this%voldatii
7834if (associated(this%voldatiattri)) read(unit=lunit)this%voldatiattri
7835
7836if (associated(this%volanab)) read(unit=lunit)this%volanab
7837if (associated(this%volanaattrb)) read(unit=lunit)this%volanaattrb
7838if (associated(this%voldatib)) read(unit=lunit)this%voldatib
7839if (associated(this%voldatiattrb)) read(unit=lunit)this%voldatiattrb
7840
7841if (associated(this%volanad)) read(unit=lunit)this%volanad
7842if (associated(this%volanaattrd)) read(unit=lunit)this%volanaattrd
7843if (associated(this%voldatid)) read(unit=lunit)this%voldatid
7844if (associated(this%voldatiattrd)) read(unit=lunit)this%voldatiattrd
7845
7846if (associated(this%volanac)) read(unit=lunit)this%volanac
7847if (associated(this%volanaattrc)) read(unit=lunit)this%volanaattrc
7848if (associated(this%voldatic)) read(unit=lunit)this%voldatic
7849if (associated(this%voldatiattrc)) read(unit=lunit)this%voldatiattrc
7850
7851if (.not. present(unit)) close(unit=lunit)
7852
7853end subroutine vol7d_read_from_file
7854
7855
7856! to double precision
7857elemental doubleprecision function doubledatd(voldat,var)
7858doubleprecision,intent(in) :: voldat
7859type(vol7d_var),intent(in) :: var
7860
7861doubledatd=voldat
7862
7863end function doubledatd
7864
7865
7866elemental doubleprecision function doubledatr(voldat,var)
7867real,intent(in) :: voldat
7868type(vol7d_var),intent(in) :: var
7869
7871 doubledatr=dble(voldat)
7872else
7873 doubledatr=dmiss
7874end if
7875
7876end function doubledatr
7877
7878
7879elemental doubleprecision function doubledati(voldat,var)
7880integer,intent(in) :: voldat
7881type(vol7d_var),intent(in) :: var
7882
7885 doubledati=dble(voldat)/10.d0**var%scalefactor
7886 else
7887 doubledati=dble(voldat)
7888 endif
7889else
7890 doubledati=dmiss
7891end if
7892
7893end function doubledati
7894
7895
7896elemental doubleprecision function doubledatb(voldat,var)
7897integer(kind=int_b),intent(in) :: voldat
7898type(vol7d_var),intent(in) :: var
7899
7902 doubledatb=dble(voldat)/10.d0**var%scalefactor
7903 else
7904 doubledatb=dble(voldat)
7905 endif
7906else
7907 doubledatb=dmiss
7908end if
7909
7910end function doubledatb
7911
7912
7913elemental doubleprecision function doubledatc(voldat,var)
7914CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
7915type(vol7d_var),intent(in) :: var
7916
7917doubledatc = c2d(voldat)
7919 doubledatc=doubledatc/10.d0**var%scalefactor
7920end if
7921
7922end function doubledatc
7923
7924
7925! to integer
7926elemental integer function integerdatd(voldat,var)
7927doubleprecision,intent(in) :: voldat
7928type(vol7d_var),intent(in) :: var
7929
7932 integerdatd=nint(voldat*10d0**var%scalefactor)
7933 else
7934 integerdatd=nint(voldat)
7935 endif
7936else
7937 integerdatd=imiss
7938end if
7939
7940end function integerdatd
7941
7942
7943elemental integer function integerdatr(voldat,var)
7944real,intent(in) :: voldat
7945type(vol7d_var),intent(in) :: var
7946
7949 integerdatr=nint(voldat*10d0**var%scalefactor)
7950 else
7951 integerdatr=nint(voldat)
7952 endif
7953else
7954 integerdatr=imiss
7955end if
7956
7957end function integerdatr
7958
7959
7960elemental integer function integerdati(voldat,var)
7961integer,intent(in) :: voldat
7962type(vol7d_var),intent(in) :: var
7963
7964integerdati=voldat
7965
7966end function integerdati
7967
7968
7969elemental integer function integerdatb(voldat,var)
7970integer(kind=int_b),intent(in) :: voldat
7971type(vol7d_var),intent(in) :: var
7972
7974 integerdatb=voldat
7975else
7976 integerdatb=imiss
7977end if
7978
7979end function integerdatb
7980
7981
7982elemental integer function integerdatc(voldat,var)
7983CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
7984type(vol7d_var),intent(in) :: var
7985
7986integerdatc=c2i(voldat)
7987
7988end function integerdatc
7989
7990
7991! to real
7992elemental real function realdatd(voldat,var)
7993doubleprecision,intent(in) :: voldat
7994type(vol7d_var),intent(in) :: var
7995
7997 realdatd=real(voldat)
7998else
7999 realdatd=rmiss
8000end if
8001
8002end function realdatd
8003
8004
8005elemental real function realdatr(voldat,var)
8006real,intent(in) :: voldat
8007type(vol7d_var),intent(in) :: var
8008
8009realdatr=voldat
8010
8011end function realdatr
8012
8013
8014elemental real function realdati(voldat,var)
8015integer,intent(in) :: voldat
8016type(vol7d_var),intent(in) :: var
8017
8020 realdati=float(voldat)/10.**var%scalefactor
8021 else
8022 realdati=float(voldat)
8023 endif
8024else
8025 realdati=rmiss
8026end if
8027
8028end function realdati
8029
8030
8031elemental real function realdatb(voldat,var)
8032integer(kind=int_b),intent(in) :: voldat
8033type(vol7d_var),intent(in) :: var
8034
8037 realdatb=float(voldat)/10**var%scalefactor
8038 else
8039 realdatb=float(voldat)
8040 endif
8041else
8042 realdatb=rmiss
8043end if
8044
8045end function realdatb
8046
8047
8048elemental real function realdatc(voldat,var)
8049CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
8050type(vol7d_var),intent(in) :: var
8051
8052realdatc=c2r(voldat)
8054 realdatc=realdatc/10.**var%scalefactor
8055end if
8056
8057end function realdatc
8058
8059
8060!> Return an ana volume of a requested variable as real data.
8061!! It returns a 2-d array of the proper shape (ana x network) for the
8062!! ana variable requested, converted to real type. If the conversion
8063!! fails or if the variable is not contained in the ana volume,
8064!! missing data are returned.
8065FUNCTION realanavol(this, var) RESULT(vol)
8066TYPE(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
8067TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
8068REAL :: vol(SIZE(this%ana),size(this%network))
8069
8070CHARACTER(len=1) :: dtype
8071INTEGER :: indvar
8072
8073dtype = cmiss
8074indvar = index(this%anavar, var, type=dtype)
8075
8076IF (indvar > 0) THEN
8077 SELECT CASE (dtype)
8078 CASE("d")
8079 vol = realdat(this%volanad(:,indvar,:), var)
8080 CASE("r")
8081 vol = this%volanar(:,indvar,:)
8082 CASE("i")
8083 vol = realdat(this%volanai(:,indvar,:), var)
8084 CASE("b")
8085 vol = realdat(this%volanab(:,indvar,:), var)
8086 CASE("c")
8087 vol = realdat(this%volanac(:,indvar,:), var)
8088 CASE default
8089 vol = rmiss
8090 END SELECT
8091ELSE
8092 vol = rmiss
8093ENDIF
8094
8095END FUNCTION realanavol
8096
8097
8098!> Return an ana volume of a requested variable as integer data.
8099!! It returns a 2-d array of the proper shape (ana x network) for the
8100!! ana variable requested, converted to integer type. If the conversion
8101!! fails or if the variable is not contained in the ana volume,
8102!! missing data are returned.
8103FUNCTION integeranavol(this, var) RESULT(vol)
8104TYPE(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
8105TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
8106INTEGER :: vol(SIZE(this%ana),size(this%network))
8107
8108CHARACTER(len=1) :: dtype
8109INTEGER :: indvar
8110
8111dtype = cmiss
8112indvar = index(this%anavar, var, type=dtype)
8113
8114IF (indvar > 0) THEN
8115 SELECT CASE (dtype)
8116 CASE("d")
8117 vol = integerdat(this%volanad(:,indvar,:), var)
8118 CASE("r")
8119 vol = integerdat(this%volanar(:,indvar,:), var)
8120 CASE("i")
8121 vol = this%volanai(:,indvar,:)
8122 CASE("b")
8123 vol = integerdat(this%volanab(:,indvar,:), var)
8124 CASE("c")
8125 vol = integerdat(this%volanac(:,indvar,:), var)
8126 CASE default
8127 vol = imiss
8128 END SELECT
8129ELSE
8130 vol = imiss
8131ENDIF
8132
8133END FUNCTION integeranavol
8134
8135
8136!> Move data for all variables from one coordinate in the character volume to other.
8137!! Only not missing data will be copyed and all attributes will be moved together.
8138!! Usefull to colapse data spread in more indices (level or time or ....).
8139!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
8140!! to obtain a new vol7d with less data shape.
8141subroutine move_datac (v7d,&
8142 indana,indtime,indlevel,indtimerange,indnetwork,&
8143 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
8144
8145TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
8146
8147integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
8148integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
8149integer :: inddativar,inddativarattr
8150
8151
8152do inddativar=1,size(v7d%dativar%c)
8153
8155 .not. c_e(v7d%voldatic(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
8156 ) then
8157
8158 ! dati
8159 v7d%voldatic &
8160 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
8161 v7d%voldatic &
8162 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
8163
8164
8165 ! attributi
8166 if (associated (v7d%dativarattr%i)) then
8167 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%c(inddativar))
8168 if (inddativarattr > 0 ) then
8169 v7d%voldatiattri &
8170 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8171 v7d%voldatiattri &
8172 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8173 end if
8174 end if
8175
8176 if (associated (v7d%dativarattr%r)) then
8177 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%c(inddativar))
8178 if (inddativarattr > 0 ) then
8179 v7d%voldatiattrr &
8180 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8181 v7d%voldatiattrr &
8182 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8183 end if
8184 end if
8185
8186 if (associated (v7d%dativarattr%d)) then
8187 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%c(inddativar))
8188 if (inddativarattr > 0 ) then
8189 v7d%voldatiattrd &
8190 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8191 v7d%voldatiattrd &
8192 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8193 end if
8194 end if
8195
8196 if (associated (v7d%dativarattr%b)) then
8197 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%c(inddativar))
8198 if (inddativarattr > 0 ) then
8199 v7d%voldatiattrb &
8200 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8201 v7d%voldatiattrb &
8202 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8203 end if
8204 end if
8205
8206 if (associated (v7d%dativarattr%c)) then
8207 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%c(inddativar))
8208 if (inddativarattr > 0 ) then
8209 v7d%voldatiattrc &
8210 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8211 v7d%voldatiattrc &
8212 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8213 end if
8214 end if
8215
8216 end if
8217
8218end do
8219
8220end subroutine move_datac
8221
8222!> Move data for all variables from one coordinate in the real volume to other.
8223!! Only not missing data will be copyed and all attributes will be moved together.
8224!! Usefull to colapse data spread in more indices (level or time or ....).
8225!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
8226!! to obtain a new vol7d with less data shape.
8227subroutine move_datar (v7d,&
8228 indana,indtime,indlevel,indtimerange,indnetwork,&
8229 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
8230
8231TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
8232
8233integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
8234integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
8235integer :: inddativar,inddativarattr
8236
8237
8238do inddativar=1,size(v7d%dativar%r)
8239
8241 .not. c_e(v7d%voldatir(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
8242 ) then
8243
8244 ! dati
8245 v7d%voldatir &
8246 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
8247 v7d%voldatir &
8248 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
8249
8250
8251 ! attributi
8252 if (associated (v7d%dativarattr%i)) then
8253 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%r(inddativar))
8254 if (inddativarattr > 0 ) then
8255 v7d%voldatiattri &
8256 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8257 v7d%voldatiattri &
8258 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8259 end if
8260 end if
8261
8262 if (associated (v7d%dativarattr%r)) then
8263 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%r(inddativar))
8264 if (inddativarattr > 0 ) then
8265 v7d%voldatiattrr &
8266 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8267 v7d%voldatiattrr &
8268 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8269 end if
8270 end if
8271
8272 if (associated (v7d%dativarattr%d)) then
8273 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%r(inddativar))
8274 if (inddativarattr > 0 ) then
8275 v7d%voldatiattrd &
8276 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8277 v7d%voldatiattrd &
8278 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8279 end if
8280 end if
8281
8282 if (associated (v7d%dativarattr%b)) then
8283 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%r(inddativar))
8284 if (inddativarattr > 0 ) then
8285 v7d%voldatiattrb &
8286 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8287 v7d%voldatiattrb &
8288 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8289 end if
8290 end if
8291
8292 if (associated (v7d%dativarattr%c)) then
8293 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%r(inddativar))
8294 if (inddativarattr > 0 ) then
8295 v7d%voldatiattrc &
8296 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
8297 v7d%voldatiattrc &
8298 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
8299 end if
8300 end if
8301
8302 end if
8303
8304end do
8305
8306end subroutine move_datar
8307
8308
8309!> Reduce some dimensions (level and timerage) for semplification (rounding).
8310!! You can use this for simplify and use variables in computation like alchimia
8311!! where fields have to be on the same coordinate
8312!! It return real or character data only: if input is charcter data only it return character otherwise il return
8313!! all the data converted to real.
8314!! examples:
8315!! means in time for short periods and istantaneous values
8316!! 2 meter and surface levels
8317!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
8318!! will be taken (order is by icreasing var index).
8319!! You can use predefined values for classic semplification
8320!! almost_equal_levels and almost_equal_timeranges
8321!! The level or timerange in output will be defined by the first element of level and timerange list
8322subroutine v7d_rounding(v7din,v7dout,level,timerange,nostatproc)
8323type(vol7d),intent(inout) :: v7din !< input volume
8324type(vol7d),intent(out) :: v7dout !> output volume
8325type(vol7d_level),intent(in),optional :: level(:) !< almost equal level list
8326type(vol7d_timerange),intent(in),optional :: timerange(:) !< almost equal timerange list
8327!logical,intent(in),optional :: merge !< if there are data on more then one almost equal levels or timeranges
8328!! will be merged POINT BY POINT with priority for the fird data found ordered by icreasing var index
8329logical,intent(in),optional :: nostatproc !< do not take in account statistical processing code in timerange and P2
8330
8331integer :: nana,nlevel,ntime,ntimerange,nnetwork,nbin
8332integer :: iana,ilevel,itimerange,indl,indt,itime,inetwork
8333type(vol7d_level) :: roundlevel(size(v7din%level))
8334type(vol7d_timerange) :: roundtimerange(size(v7din%timerange))
8335type(vol7d) :: v7d_tmp
8336
8337
8338nbin=0
8339
8340if (associated(v7din%dativar%r)) nbin = nbin + size(v7din%dativar%r)
8341if (associated(v7din%dativar%i)) nbin = nbin + size(v7din%dativar%i)
8342if (associated(v7din%dativar%d)) nbin = nbin + size(v7din%dativar%d)
8343if (associated(v7din%dativar%b)) nbin = nbin + size(v7din%dativar%b)
8344
8346
8347roundlevel=v7din%level
8348
8349if (present(level))then
8350 do ilevel = 1, size(v7din%level)
8351 if ((any(v7din%level(ilevel) .almosteq. level))) then
8352 roundlevel(ilevel)=level(1)
8353 end if
8354 end do
8355end if
8356
8357roundtimerange=v7din%timerange
8358
8359if (present(timerange))then
8360 do itimerange = 1, size(v7din%timerange)
8361 if ((any(v7din%timerange(itimerange) .almosteq. timerange))) then
8362 roundtimerange(itimerange)=timerange(1)
8363 end if
8364 end do
8365end if
8366
8367!set istantaneous values everywere
8368!preserve p1 for forecast time
8369if (optio_log(nostatproc)) then
8370 roundtimerange(:)%timerange=254
8371 roundtimerange(:)%p2=0
8372end if
8373
8374
8375nana=size(v7din%ana)
8376nlevel=count_distinct(roundlevel,back=.true.)
8377ntime=size(v7din%time)
8378ntimerange=count_distinct(roundtimerange,back=.true.)
8379nnetwork=size(v7din%network)
8380
8382
8383if (nbin == 0) then
8385else
8386 call vol7d_convr(v7din,v7d_tmp)
8387end if
8388
8389v7d_tmp%level=roundlevel
8390v7d_tmp%timerange=roundtimerange
8391
8392do ilevel=1, size(v7d_tmp%level)
8393 indl=index(v7d_tmp%level,roundlevel(ilevel))
8394 do itimerange=1,size(v7d_tmp%timerange)
8395 indt=index(v7d_tmp%timerange,roundtimerange(itimerange))
8396
8397 if (indl /= ilevel .or. indt /= itimerange) then
8398
8399 do iana=1, nana
8400 do itime=1,ntime
8401 do inetwork=1,nnetwork
8402
8403 if (nbin > 0) then
8404 call move_datar (v7d_tmp,&
8405 iana,itime,ilevel,itimerange,inetwork,&
8406 iana,itime,indl,indt,inetwork)
8407 else
8408 call move_datac (v7d_tmp,&
8409 iana,itime,ilevel,itimerange,inetwork,&
8410 iana,itime,indl,indt,inetwork)
8411 end if
8412
8413 end do
8414 end do
8415 end do
8416
8417 end if
8418
8419 end do
8420end do
8421
8422! set to missing level and time > nlevel
8423do ilevel=nlevel+1,size(v7d_tmp%level)
8425end do
8426
8427do itimerange=ntimerange+1,size(v7d_tmp%timerange)
8429end do
8430
8431!copy with remove
8434
8435!call display(v7dout)
8436
8437end subroutine v7d_rounding
8438
8439
8441
8442!>\example esempio_qc_convert.f90
8443!!\brief Programma esempio semplice per la scrittura su file di un volume vol7d
8444!!
8445!!Programma che scrive su file un volume vol7d letto da una serie di file ASCII.
8446!!Questo programma scrive i dati del clima che poi verranno letti da modqccli
8447
8448
8449!>\example esempio_v7ddballe_move_and_collapse.f90
8450!!\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 |