libsim Versione 8.0.0

◆ vol7d_get_voldatiattri()

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

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

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

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

Definizione alla linea 5054 del file vol7d_class.F90.

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

Generated with Doxygen.