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