libsim Versione 8.0.0
vol7d_class.F90
1! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
2! authors:
3! Davide Cesari <dcesari@arpa.emr.it>
4! Paolo Patruno <ppatruno@arpa.emr.it>
5
6! This program is free software; you can redistribute it and/or
7! modify it under the terms of the GNU General Public License as
8! published by the Free Software Foundation; either version 2 of
9! the License, or (at your option) any later version.
10
11! This program is distributed in the hope that it will be useful,
12! but WITHOUT ANY WARRANTY; without even the implied warranty of
13! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14! GNU General Public License for more details.
15
16! You should have received a copy of the GNU General Public License
17! along with this program. If not, see <http://www.gnu.org/licenses/>.
18#include "config.h"
19
20!> \defgroup vol7d Libsim package, vol7d library.
21!! The libsim vol7d library contains classes for managing pointwise
22!! data, tipically weather observations, and for their import from a
23!! Db-All.e database or from a WMO BUFR file. In order to compile and
24!! link programs using this library, you have to insert the required
25!! \c USE statements in the program units involved, specify the
26!! location of module files when compiling (tipically \c
27!! -I/usr/lib/gfortran/modules or \c -I/usr/lib64/gfortran/modules or
28!! \c -I/usr/include) and indicate the library name \c -lsim_vol7d
29!! when linking, assuming that the library has been installed in a
30!! default location.
31
32!> Classe per la gestione di un volume completo di dati osservati.
33!! Questo modulo definisce gli oggetti e i metodi per gestire
34!! volumi di dati meteorologici sparsi.
35!! I volumi definiti sono principalmente di 4 categorie:
36!! - volumi di anagrafica (vol7d::volanar & c.), hanno 3 dimensioni:
37!! - anagrafica
38!! - variabile di anagrafica
39!! - rete
40!! - volumi di attributi di anagrafica (vol7d::volanaattrr & c.), hanno 4 dimensioni:
41!! - anagrafica
42!! - variabile di anagrafica
43!! - rete
44!! - variabile di attributi delle variabili di anagrafica
45!! - volumi di dati (vol7d::voldatir & c.), hanno 6 dimensioni:
46!! - anagrafica
47!! - tempo
48!! - livello verticale
49!! - intervallo temporale (timerange)
50!! - variabile di dati
51!! - rete
52!! - volumi di attributi di dati (vol7d::voldatiattrr & c.), hanno 7 dimensioni:
53!! - anagrafica
54!! - tempo
55!! - livello verticale
56!! - intervallo temporale (timerange)
57!! - variabile di dati
58!! - rete
59!! - variabile di attributi delle variabili di dati
60!!
61!! Tutte le variabili sono inoltre disponibil1 in 5 tipi diversi:
62!! - reale (abbreviato r)
63!! - doppia precisione (abbreviato d)
64!! - intero (abbreviato i)
65!! - byte (abbreviato b)
66!! - carattere (abbreviato c)
67!!
68!! Per ognuna delle dimensioni possibili, incluse le variabili e gli
69!! attributi con i loro diversi tipi,
70!! è definito un cosiddetto "vettore di descrittori", con un
71!! numero di elementi pari all'estensione della dimensione stessa,
72!! che contiene le informazioni necessarie a descrivere
73!! gli elementi di quella dimensione.
74!! In realtà l'utente non dovrà generalmente occuparsi di costruire
75!! un oggetto vol7d con le proprie mani ma utilizzerà nella maggior parte
76!! dei casi i metodi di importazione preconfezionati che importano dati da
77!! DB-All.e (vol7d_dballe_class) o dal DB Oracle del SIM (vol7d_oraclesim_class).
78!!
79!!
80!! Il programma esempio_v7d.f90 contiene un esempio elementare di uso
81!! della classe vol7d:
82!! \include esempio_v7d.f90
83!!
84!! \ingroup vol7d
85MODULE vol7d_class
86USE kinds
92USE io_units
99IMPLICIT NONE
100
101
102INTEGER, PARAMETER :: vol7d_maxdim_a = 3, vol7d_maxdim_aa = 4, &
103 vol7d_maxdim_d = 6, vol7d_maxdim_ad = 7
104
105INTEGER, PARAMETER :: vol7d_ana_a=1 !< indice della dimensione "anagrafica" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
106INTEGER, PARAMETER :: vol7d_var_a=2 !< indice della dimensione "variabile" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
107INTEGER, PARAMETER :: vol7d_network_a=3 !< indice della dimensione "rete" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
108INTEGER, PARAMETER :: vol7d_attr_a=4 !< indice della dimensione "attributo" nei volumi di anagrafica, da usare nei metodi vol7d_get_volana*
109INTEGER, PARAMETER :: vol7d_ana_d=1 !< indice della dimensione "anagrafica" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
110INTEGER, PARAMETER :: vol7d_time_d=2 !< indice della dimensione "tempo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
111INTEGER, PARAMETER :: vol7d_level_d=3 !< indice della dimensione "livello verticale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
112INTEGER, PARAMETER :: vol7d_timerange_d=4 !< indice della dimensione "intervallo temporale" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
113INTEGER, PARAMETER :: vol7d_var_d=5 !< indice della dimensione "variabile" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
114INTEGER, PARAMETER :: vol7d_network_d=6 !< indice della dimensione "rete" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
115INTEGER, PARAMETER :: vol7d_attr_d=7 !< indice della dimensione "attributo" nei volumi di dati, da usare nei metodi vol7d_get_voldati*
116INTEGER, PARAMETER :: vol7d_cdatalen=32
117
118TYPE vol7d_varmap
119 INTEGER :: r, d, i, b, c
120END TYPE vol7d_varmap
121
122!> Definisce un oggetto contenente i volumi anagrafica e dati e tutti
123!! i descrittori delle loro dimensioni.
124TYPE vol7d
125!> vettore descrittore della dimensione anagrafica
126 TYPE(vol7d_ana),POINTER :: ana(:)
127!> vettore descrittore della dimensione tempo
128 TYPE(datetime),POINTER :: time(:)
129!> vettore descrittore della dimensione livello verticale
130 TYPE(vol7d_level),POINTER :: level(:)
131!> vettore descrittore della dimensione intervallo temporale (timerange)
132 TYPE(vol7d_timerange),POINTER :: timerange(:)
133!> vettore descrittore della dimensione rete
134 TYPE(vol7d_network),POINTER :: network(:)
135!> vettore descrittore della dimensione variabile di anagrafica
136 TYPE(vol7d_varvect) :: anavar
137!> vettore descrittore della dimensione attributo delle variabili di anagrafica
138 TYPE(vol7d_varvect) :: anaattr
139!> vettore descrittore della dimensione variabile di anagrafica che ha tali attributi
140 TYPE(vol7d_varvect) :: anavarattr
141!> vettore descrittore della dimensione variabile di dati
142 TYPE(vol7d_varvect) :: dativar
143!> vettore descrittore della dimensione attributo delle variabili di dati
144 TYPE(vol7d_varvect) :: datiattr
145!> vettore descrittore della dimensione variabile di dati che ha tali attributi
146 TYPE(vol7d_varvect) :: dativarattr
147
148!> volume di anagrafica a valori reali
149 REAL,POINTER :: volanar(:,:,:)
150!> volume di anagrafica a valori a doppia precisione
151 DOUBLE PRECISION,POINTER :: volanad(:,:,:)
152!> volume di anagrafica a valori interi
153 INTEGER,POINTER :: volanai(:,:,:)
154!> volume di anagrafica a valori byte
155 INTEGER(kind=int_b),POINTER :: volanab(:,:,:)
156!> volume di anagrafica a valori carattere
157 CHARACTER(len=vol7d_cdatalen),POINTER :: volanac(:,:,:)
158
159!> volume di attributi di anagrafica a valori reali
160 REAL,POINTER :: volanaattrr(:,:,:,:)
161!> volume di attributi di anagrafica a valori a doppia precisione
162 DOUBLE PRECISION,POINTER :: volanaattrd(:,:,:,:)
163!> volume di attributi di anagrafica a valori interi
164 INTEGER,POINTER :: volanaattri(:,:,:,:)
165!> volume di attributi di anagrafica a valori byte
166 INTEGER(kind=int_b),POINTER :: volanaattrb(:,:,:,:)
167!> volume di attributi di anagrafica a valori carattere
168 CHARACTER(len=vol7d_cdatalen),POINTER :: volanaattrc(:,:,:,:)
169
170!> volume di dati a valori reali
171 REAL,POINTER :: voldatir(:,:,:,:,:,:) ! sono i dati
172!> volume di dati a valori a doppia precisione
173 DOUBLE PRECISION,POINTER :: voldatid(:,:,:,:,:,:)
174!> volume di dati a valori interi
175 INTEGER,POINTER :: voldatii(:,:,:,:,:,:)
176!> volume di dati a valori byte
177 INTEGER(kind=int_b),POINTER :: voldatib(:,:,:,:,:,:)
178!> volume di dati a valori carattere
179 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatic(:,:,:,:,:,:)
180
181!> volume di attributi di dati a valori reali
182 REAL,POINTER :: voldatiattrr(:,:,:,:,:,:,:)
183!> volume di attributi di dati a valori a doppia precisione
184 DOUBLE PRECISION,POINTER :: voldatiattrd(:,:,:,:,:,:,:)
185!> volume di attributi di dati a valori interi
186 INTEGER,POINTER :: voldatiattri(:,:,:,:,:,:,:)
187!> volume di attributi di dati a valori byte
188 INTEGER(kind=int_b),POINTER :: voldatiattrb(:,:,:,:,:,:,:)
189!> volume di attributi di dati a valori carattere
190 CHARACTER(len=vol7d_cdatalen),POINTER :: voldatiattrc(:,:,:,:,:,:,:)
191
192!> time definition; 0=time is reference time, 1=time is validity time
193 integer :: time_definition
194
195END TYPE vol7d
196
197!> Costruttore per la classe vol7d.
198!! Deve essere richiamato
199!! per tutti gli oggetti di questo tipo definiti in un programma.
200INTERFACE init
201 MODULE PROCEDURE vol7d_init
202END INTERFACE
203
204!> Distruttore per la classe vol7d.
205INTERFACE delete
206 MODULE PROCEDURE vol7d_delete
207END INTERFACE
208
209!> Scrittura su file.
210INTERFACE export
211 MODULE PROCEDURE vol7d_write_on_file
212END INTERFACE
213
214!> Lettura da file.
215INTERFACE import
216 MODULE PROCEDURE vol7d_read_from_file
217END INTERFACE
218
219!>Print object
220INTERFACE display
221 MODULE PROCEDURE vol7d_display, dat_display, dat_vect_display
222END INTERFACE
223
224!>Represent data in a pretty string
225INTERFACE to_char
226 MODULE PROCEDURE to_char_dat
227END INTERFACE
228
229!>doubleprecision data conversion
230INTERFACE doubledat
231 MODULE PROCEDURE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
232END INTERFACE
233
234!>real data conversion
235INTERFACE realdat
236 MODULE PROCEDURE realdatd,realdatr,realdati,realdatb,realdatc
237END INTERFACE
238
239!>integer data conversion
240INTERFACE integerdat
241 MODULE PROCEDURE integerdatd,integerdatr,integerdati,integerdatb,integerdatc
242END INTERFACE
243
244!>copy object
245INTERFACE copy
246 MODULE PROCEDURE vol7d_copy
247END INTERFACE
248
249!> Test for a missing volume
250INTERFACE c_e
251 MODULE PROCEDURE vol7d_c_e
252END INTERFACE
253
254!> Check for problems
255!! return 0 if all check passed
256!! print diagnostics with log4f
257INTERFACE check
258 MODULE PROCEDURE vol7d_check
259END INTERFACE
260
261!> Reduce some dimensions (level and timerage) for semplification (rounding).
262!! You can use this for simplify and use variables in computation like alchimia
263!! where fields have to be on the same coordinate
264!! It return real or character data only: if input is charcter data only it return character otherwise il return
265!! all the data converted to real.
266!! examples:
267!! means in time for short periods and istantaneous values
268!! 2 meter and surface levels
269!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
270!! will be taken (order is by icreasing var index).
271!! You can use predefined values for classic semplification
272!! almost_equal_levels and almost_equal_timeranges
273!! The level or timerange in output will be defined by the first element of level and timerange list
274INTERFACE rounding
275 MODULE PROCEDURE v7d_rounding
276END INTERFACE
277
278!!$INTERFACE get_volana
279!!$ MODULE PROCEDURE vol7d_get_volanar, vol7d_get_volanad, vol7d_get_volanai, &
280!!$ vol7d_get_volanab, vol7d_get_volanac
281!!$END INTERFACE
282!!$
283!!$INTERFACE get_voldati
284!!$ MODULE PROCEDURE vol7d_get_voldatir, vol7d_get_voldatid, vol7d_get_voldatii, &
285!!$ vol7d_get_voldatib, vol7d_get_voldatic
286!!$END INTERFACE
287!!$
288!!$INTERFACE get_volanaattr
289!!$ MODULE PROCEDURE vol7d_get_volanaattrr, vol7d_get_volanaattrd, &
290!!$ vol7d_get_volanaattri, vol7d_get_volanaattrb, vol7d_get_volanaattrc
291!!$END INTERFACE
292!!$
293!!$INTERFACE get_voldatiattr
294!!$ MODULE PROCEDURE vol7d_get_voldatiattrr, vol7d_get_voldatiattrd, &
295!!$ vol7d_get_voldatiattri, vol7d_get_voldatiattrb, vol7d_get_voldatiattrc
296!!$END INTERFACE
298PRIVATE vol7d_get_volr, vol7d_get_vold, vol7d_get_voli, vol7d_get_volb, &
299 vol7d_get_volc, &
300 volptr1dr, volptr2dr, volptr3dr, volptr4dr, volptr5dr, volptr6dr, volptr7dr, &
301 volptr1dd, volptr2dd, volptr3dd, volptr4dd, volptr5dd, volptr6dd, volptr7dd, &
302 volptr1di, volptr2di, volptr3di, volptr4di, volptr5di, volptr6di, volptr7di, &
303 volptr1db, volptr2db, volptr3db, volptr4db, volptr5db, volptr6db, volptr7db, &
304 volptr1dc, volptr2dc, volptr3dc, volptr4dc, volptr5dc, volptr6dc, volptr7dc, &
305 vol7d_nullifyr, vol7d_nullifyd, vol7d_nullifyi, vol7d_nullifyb, vol7d_nullifyc, &
306 vol7d_init, vol7d_delete, vol7d_write_on_file, vol7d_read_from_file, &
307 vol7d_check_alloc_ana, vol7d_force_alloc_ana, &
308 vol7d_check_alloc_dati, vol7d_force_alloc_dati, vol7d_force_alloc, &
309 vol7d_display, dat_display, dat_vect_display, &
310 to_char_dat, vol7d_check
311
312PRIVATE doubledatd,doubledatr,doubledati,doubledatb,doubledatc
313
314PRIVATE vol7d_c_e
315
316CONTAINS
317
319!> Inizializza un oggetto di tipo vol7d.
320!! Non riceve alcun parametro tranne l'oggetto stesso. Attenzione, è necessario
321!! comunque chiamare sempre il costruttore per evitare di avere dei puntatori in
322!! uno stato indefinito.
323SUBROUTINE vol7d_init(this,time_definition)
324TYPE(vol7d),intent(out) :: this !< oggetto da inizializzare
325INTEGER,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)
327CALL init(this%anavar)
328CALL init(this%anaattr)
329CALL init(this%anavarattr)
330CALL init(this%dativar)
331CALL init(this%datiattr)
332CALL init(this%dativarattr)
333
334NULLIFY(this%ana, this%time, this%level, this%timerange, this%network)
335
336NULLIFY(this%volanar, this%volanaattrr, this%voldatir, this%voldatiattrr)
337NULLIFY(this%volanad, this%volanaattrd, this%voldatid, this%voldatiattrd)
338NULLIFY(this%volanai, this%volanaattri, this%voldatii, this%voldatiattri)
339NULLIFY(this%volanab, this%volanaattrb, this%voldatib, this%voldatiattrb)
340NULLIFY(this%volanac, this%volanaattrc, this%voldatic, this%voldatiattrc)
342if(present(time_definition)) then
343 this%time_definition=time_definition
344else
345 this%time_definition=1 !default to validity time
346end if
347
348END SUBROUTINE vol7d_init
349
351!> Distrugge l'oggetto in maniera pulita, liberando l'eventuale memoria
352!! dinamicamente allocata. Permette di distruggere la sola parte di dati
353!! mantenendo l'anagrafica.
354ELEMENTAL SUBROUTINE vol7d_delete(this, dataonly)
355TYPE(vol7d),intent(inout) :: this !< oggetto da distruggere
356LOGICAL, INTENT(in), OPTIONAL :: dataonly !< dealloca solo i dati, tenendo l'anagrafica, (default \c .FALSE.)
357
358
359IF (.NOT. optio_log(dataonly)) THEN
360 IF (ASSOCIATED(this%volanar)) DEALLOCATE(this%volanar)
361 IF (ASSOCIATED(this%volanad)) DEALLOCATE(this%volanad)
362 IF (ASSOCIATED(this%volanai)) DEALLOCATE(this%volanai)
363 IF (ASSOCIATED(this%volanab)) DEALLOCATE(this%volanab)
364 IF (ASSOCIATED(this%volanac)) DEALLOCATE(this%volanac)
365 IF (ASSOCIATED(this%volanaattrr)) DEALLOCATE(this%volanaattrr)
366 IF (ASSOCIATED(this%volanaattrd)) DEALLOCATE(this%volanaattrd)
367 IF (ASSOCIATED(this%volanaattri)) DEALLOCATE(this%volanaattri)
368 IF (ASSOCIATED(this%volanaattrb)) DEALLOCATE(this%volanaattrb)
369 IF (ASSOCIATED(this%volanaattrc)) DEALLOCATE(this%volanaattrc)
370ENDIF
371IF (ASSOCIATED(this%voldatir)) DEALLOCATE(this%voldatir)
372IF (ASSOCIATED(this%voldatid)) DEALLOCATE(this%voldatid)
373IF (ASSOCIATED(this%voldatii)) DEALLOCATE(this%voldatii)
374IF (ASSOCIATED(this%voldatib)) DEALLOCATE(this%voldatib)
375IF (ASSOCIATED(this%voldatic)) DEALLOCATE(this%voldatic)
376IF (ASSOCIATED(this%voldatiattrr)) DEALLOCATE(this%voldatiattrr)
377IF (ASSOCIATED(this%voldatiattrd)) DEALLOCATE(this%voldatiattrd)
378IF (ASSOCIATED(this%voldatiattri)) DEALLOCATE(this%voldatiattri)
379IF (ASSOCIATED(this%voldatiattrb)) DEALLOCATE(this%voldatiattrb)
380IF (ASSOCIATED(this%voldatiattrc)) DEALLOCATE(this%voldatiattrc)
382IF (.NOT. optio_log(dataonly)) THEN
383 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
384 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
385ENDIF
386IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
387IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
388IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
389
390IF (.NOT. optio_log(dataonly)) THEN
391 CALL delete(this%anavar)
392 CALL delete(this%anaattr)
393 CALL delete(this%anavarattr)
394ENDIF
395CALL delete(this%dativar)
396CALL delete(this%datiattr)
397CALL delete(this%dativarattr)
399END SUBROUTINE vol7d_delete
400
401
402
403integer function vol7d_check(this)
404TYPE(vol7d),intent(in) :: this !< object to check
405integer :: i,j,k,l,m,n
406
407vol7d_check=0
409if (associated(this%voldatii)) then
410do i = 1,size(this%voldatii,1)
411 do j = 1,size(this%voldatii,2)
412 do k = 1,size(this%voldatii,3)
413 do l = 1,size(this%voldatii,4)
414 do m = 1,size(this%voldatii,5)
415 do n = 1,size(this%voldatii,6)
416 if (this%voldatii(i,j,k,l,m,n) /= this%voldatii(i,j,k,l,m,n) ) then
417 CALL l4f_log(l4f_warn,"check: abnormal value at voldatii("&
418 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
419 vol7d_check=1
420 end if
421 end do
422 end do
423 end do
424 end do
425 end do
426end do
427end if
429
430if (associated(this%voldatir)) then
431do i = 1,size(this%voldatir,1)
432 do j = 1,size(this%voldatir,2)
433 do k = 1,size(this%voldatir,3)
434 do l = 1,size(this%voldatir,4)
435 do m = 1,size(this%voldatir,5)
436 do n = 1,size(this%voldatir,6)
437 if (this%voldatir(i,j,k,l,m,n) /= this%voldatir(i,j,k,l,m,n) ) then
438 CALL l4f_log(l4f_warn,"check: abnormal value at voldatir("&
439 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
440 vol7d_check=2
441 end if
442 end do
443 end do
444 end do
445 end do
446 end do
447end do
448end if
449
450if (associated(this%voldatid)) then
451do i = 1,size(this%voldatid,1)
452 do j = 1,size(this%voldatid,2)
453 do k = 1,size(this%voldatid,3)
454 do l = 1,size(this%voldatid,4)
455 do m = 1,size(this%voldatid,5)
456 do n = 1,size(this%voldatid,6)
457 if (this%voldatid(i,j,k,l,m,n) /= this%voldatid(i,j,k,l,m,n) ) then
458 CALL l4f_log(l4f_warn,"check: abnormal value at voldatid("&
459 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
460 vol7d_check=3
461 end if
462 end do
463 end do
464 end do
465 end do
466 end do
467end do
468end if
469
470if (associated(this%voldatib)) then
471do i = 1,size(this%voldatib,1)
472 do j = 1,size(this%voldatib,2)
473 do k = 1,size(this%voldatib,3)
474 do l = 1,size(this%voldatib,4)
475 do m = 1,size(this%voldatib,5)
476 do n = 1,size(this%voldatib,6)
477 if (this%voldatib(i,j,k,l,m,n) /= this%voldatib(i,j,k,l,m,n) ) then
478 CALL l4f_log(l4f_warn,"check: abnormal value at voldatib("&
479 //t2c(i)//","//t2c(j)//","//t2c(k)//","//t2c(l)//","//t2c(m)//","//t2c(n)//",)")
480 vol7d_check=4
481 end if
482 end do
483 end do
484 end do
485 end do
486 end do
487end do
488end if
489
490end function vol7d_check
491
492
493
494!TODO da completare ! aborta se i volumi sono allocati a dimensione 0
495!> stampa a video una sintesi del contenuto
496SUBROUTINE vol7d_display(this)
497TYPE(vol7d),intent(in) :: this !< oggetto da visualizzare
498integer :: i
499
500REAL :: rdat
501DOUBLE PRECISION :: ddat
502INTEGER :: idat
503INTEGER(kind=int_b) :: bdat
504CHARACTER(len=vol7d_cdatalen) :: cdat
505
506
507print*,"<<<<<<<<<<<<<<<<<<< vol7d object >>>>>>>>>>>>>>>>>>>>"
508if (this%time_definition == 0) then
509 print*,"TIME DEFINITION: time is reference time"
510else if (this%time_definition == 1) then
511 print*,"TIME DEFINITION: time is validity time"
512else if (this%time_definition == 2) then
513 print*,"TIME DEFINITION: time is validity time, forecast range forced to 0"
514else
515 print*,"Time definition has a wrong walue:", this%time_definition
516end if
517
518IF (ASSOCIATED(this%network))then
519 print*,"---- network vector ----"
520 print*,"elements=",size(this%network)
521 do i=1, size(this%network)
522 call display(this%network(i))
523 end do
524end IF
525
526IF (ASSOCIATED(this%ana))then
527 print*,"---- ana vector ----"
528 print*,"elements=",size(this%ana)
529 do i=1, size(this%ana)
530 call display(this%ana(i))
531 end do
532end IF
533
534IF (ASSOCIATED(this%time))then
535 print*,"---- time vector ----"
536 print*,"elements=",size(this%time)
537 do i=1, size(this%time)
538 call display(this%time(i))
539 end do
540end if
541
542IF (ASSOCIATED(this%level)) then
543 print*,"---- level vector ----"
544 print*,"elements=",size(this%level)
545 do i =1,size(this%level)
546 call display(this%level(i))
547 end do
548end if
549
550IF (ASSOCIATED(this%timerange))then
551 print*,"---- timerange vector ----"
552 print*,"elements=",size(this%timerange)
553 do i =1,size(this%timerange)
554 call display(this%timerange(i))
555 end do
556end if
557
558
559print*,"---- ana vector ----"
560print*,""
561print*,"->>>>>>>>> anavar -"
562call display(this%anavar)
563print*,""
564print*,"->>>>>>>>> anaattr -"
565call display(this%anaattr)
566print*,""
567print*,"->>>>>>>>> anavarattr -"
568call display(this%anavarattr)
569
570print*,"-- ana data section (first point) --"
571
572idat=imiss
573rdat=rmiss
574ddat=dmiss
575bdat=ibmiss
576cdat=cmiss
577
578!ntime = MIN(SIZE(this%time),nprint)
579!ntimerange = MIN(SIZE(this%timerange),nprint)
580!nlevel = MIN(SIZE(this%level),nprint)
581!nnetwork = MIN(SIZE(this%network),nprint)
582!nana = MIN(SIZE(this%ana),nprint)
583
584IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0) THEN
585if (associated(this%volanai)) then
586 do i=1,size(this%anavar%i)
587 idat=this%volanai(1,i,1)
588 if (associated(this%anavar%i)) call display(this%anavar%i(i),idat,rdat,ddat,bdat,cdat)
589 end do
590end if
591idat=imiss
592
593if (associated(this%volanar)) then
594 do i=1,size(this%anavar%r)
595 rdat=this%volanar(1,i,1)
596 if (associated(this%anavar%r)) call display(this%anavar%r(i),idat,rdat,ddat,bdat,cdat)
597 end do
598end if
599rdat=rmiss
600
601if (associated(this%volanad)) then
602 do i=1,size(this%anavar%d)
603 ddat=this%volanad(1,i,1)
604 if (associated(this%anavar%d)) call display(this%anavar%d(i),idat,rdat,ddat,bdat,cdat)
605 end do
606end if
607ddat=dmiss
608
609if (associated(this%volanab)) then
610 do i=1,size(this%anavar%b)
611 bdat=this%volanab(1,i,1)
612 if (associated(this%anavar%b)) call display(this%anavar%b(i),idat,rdat,ddat,bdat,cdat)
613 end do
614end if
615bdat=ibmiss
616
617if (associated(this%volanac)) then
618 do i=1,size(this%anavar%c)
619 cdat=this%volanac(1,i,1)
620 if (associated(this%anavar%c)) call display(this%anavar%c(i),idat,rdat,ddat,bdat,cdat)
621 end do
622end if
623cdat=cmiss
624ENDIF
625
626print*,"---- data vector ----"
627print*,""
628print*,"->>>>>>>>> dativar -"
629call display(this%dativar)
630print*,""
631print*,"->>>>>>>>> datiattr -"
632call display(this%datiattr)
633print*,""
634print*,"->>>>>>>>> dativarattr -"
635call display(this%dativarattr)
636
637print*,"-- data data section (first point) --"
638
639idat=imiss
640rdat=rmiss
641ddat=dmiss
642bdat=ibmiss
643cdat=cmiss
644
645IF (SIZE(this%ana) > 0 .AND. SIZE(this%network) > 0 .AND. size(this%time) > 0 &
646 .AND. size(this%level) > 0 .AND. size(this%timerange) > 0) THEN
647if (associated(this%voldatii)) then
648 do i=1,size(this%dativar%i)
649 idat=this%voldatii(1,1,1,1,i,1)
650 if (associated(this%dativar%i)) call display(this%dativar%i(i),idat,rdat,ddat,bdat,cdat)
651 end do
652end if
653idat=imiss
654
655if (associated(this%voldatir)) then
656 do i=1,size(this%dativar%r)
657 rdat=this%voldatir(1,1,1,1,i,1)
658 if (associated(this%dativar%r)) call display(this%dativar%r(i),idat,rdat,ddat,bdat,cdat)
659 end do
660end if
661rdat=rmiss
662
663if (associated(this%voldatid)) then
664 do i=1,size(this%dativar%d)
665 ddat=this%voldatid(1,1,1,1,i,1)
666 if (associated(this%dativar%d)) call display(this%dativar%d(i),idat,rdat,ddat,bdat,cdat)
667 end do
668end if
669ddat=dmiss
670
671if (associated(this%voldatib)) then
672 do i=1,size(this%dativar%b)
673 bdat=this%voldatib(1,1,1,1,i,1)
674 if (associated(this%dativar%b)) call display(this%dativar%b(i),idat,rdat,ddat,bdat,cdat)
675 end do
676end if
677bdat=ibmiss
678
679if (associated(this%voldatic)) then
680 do i=1,size(this%dativar%c)
681 cdat=this%voldatic(1,1,1,1,i,1)
682 if (associated(this%dativar%c)) call display(this%dativar%c(i),idat,rdat,ddat,bdat,cdat)
683 end do
684end if
685cdat=cmiss
686ENDIF
687
688print*,"<<<<<<<<<<<<<<<<<<< END vol7d object >>>>>>>>>>>>>>>>>>>>"
689
690END SUBROUTINE vol7d_display
691
692
693!> stampa a video una sintesi del contenuto
694SUBROUTINE dat_display(this,idat,rdat,ddat,bdat,cdat)
695TYPE(vol7d_var),intent(in) :: this !< oggetto da visualizzare
696!> real
697REAL :: rdat
698!> double precision
699DOUBLE PRECISION :: ddat
700!> integer
701INTEGER :: idat
702!> byte
703INTEGER(kind=int_b) :: bdat
704!> character
705CHARACTER(len=*) :: cdat
706
707print *, to_char_dat(this,idat,rdat,ddat,bdat,cdat)
708
709end SUBROUTINE dat_display
710
711!> stampa a video una sintesi del contenuto
712SUBROUTINE dat_vect_display(this,idat,rdat,ddat,bdat,cdat)
713
714TYPE(vol7d_var),intent(in) :: this(:) !< oggetto da visualizzare
715!> real
716REAL :: rdat(:)
717!> double precision
718DOUBLE PRECISION :: ddat(:)
719!> integer
720INTEGER :: idat(:)
721!> byte
722INTEGER(kind=int_b) :: bdat(:)
723!> character
724CHARACTER(len=*):: cdat(:)
725
726integer :: i
727
728do i =1,size(this)
729 call display(this(i),idat(i),rdat(i),ddat(i),bdat(i),cdat(i))
730end do
731
732end SUBROUTINE dat_vect_display
733
734
735FUNCTION to_char_dat(this,idat,rdat,ddat,bdat,cdat)
736#ifdef HAVE_DBALLE
737USE dballef
738#endif
739TYPE(vol7d_var),INTENT(in) :: this
740!> real
741REAL :: rdat
742!> double precision
743DOUBLE PRECISION :: ddat
744!> integer
745INTEGER :: idat
746!> byte
747INTEGER(kind=int_b) :: bdat
748!> character
749CHARACTER(len=*) :: cdat
750CHARACTER(len=80) :: to_char_dat
751
752CHARACTER(len=LEN(to_char_dat)) :: to_char_tmp
753
754
755#ifdef HAVE_DBALLE
756INTEGER :: handle, ier
757
758handle = 0
759to_char_dat="VALUE: "
760
761if (c_e(idat)) to_char_dat=trim(to_char_dat)//" ;int> "//trim(to_char(idat))
762if (c_e(rdat)) to_char_dat=trim(to_char_dat)//" ;real> "//trim(to_char(rdat))
763if (c_e(ddat)) to_char_dat=trim(to_char_dat)//" ;double> "//trim(to_char(ddat))
764if (c_e(bdat)) to_char_dat=trim(to_char_dat)//" ;byte> "//trim(to_char(bdat))
765
766if ( c_e(cdat))then
767 ier = idba_messaggi(handle,"/dev/null", "w", "BUFR")
768 ier = idba_spiegab(handle,this%btable,cdat,to_char_tmp)
769 ier = idba_fatto(handle)
770 to_char_dat=trim(to_char_dat)//" ;char> "//trim(to_char_tmp)
771endif
772
773#else
774
775to_char_dat="VALUE: "
776if (c_e(idat)) to_char_dat=trim(to_char_dat)//" ;int> "//trim(to_char(idat))
777if (c_e(rdat)) to_char_dat=trim(to_char_dat)//" ;real> "//trim(to_char(rdat))
778if (c_e(ddat)) to_char_dat=trim(to_char_dat)//" ;double> "//trim(to_char(ddat))
779if (c_e(bdat)) to_char_dat=trim(to_char_dat)//" ;byte> "//trim(to_char(bdat))
780if (c_e(cdat)) to_char_dat=trim(to_char_dat)//" ;char> "//trim(cdat)
781
782#endif
783
784END FUNCTION to_char_dat
785
786
787!> Tests whether anything has ever been assigned to a vol7d object
788!! (.TRUE.) or it is as clean as after an init (.FALSE.).
789FUNCTION vol7d_c_e(this) RESULT(c_e)
790TYPE(vol7d), INTENT(in) :: this
791
792LOGICAL :: c_e
793
794c_e = ASSOCIATED(this%ana) .OR. ASSOCIATED(this%time) .OR. &
795 ASSOCIATED(this%level) .OR. ASSOCIATED(this%timerange) .OR. &
796 ASSOCIATED(this%network) .OR. &
797 ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
798 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
799 ASSOCIATED(this%anavar%c) .OR. &
800 ASSOCIATED(this%anaattr%r) .OR. ASSOCIATED(this%anaattr%d) .OR. &
801 ASSOCIATED(this%anaattr%i) .OR. ASSOCIATED(this%anaattr%b) .OR. &
802 ASSOCIATED(this%anaattr%c) .OR. &
803 ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
804 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
805 ASSOCIATED(this%dativar%c) .OR. &
806 ASSOCIATED(this%datiattr%r) .OR. ASSOCIATED(this%datiattr%d) .OR. &
807 ASSOCIATED(this%datiattr%i) .OR. ASSOCIATED(this%datiattr%b) .OR. &
808 ASSOCIATED(this%datiattr%c)
809
810END FUNCTION vol7d_c_e
811
812
813!> Metodo per allocare i descrittori delle 7 dimensioni.
814!! Riceve un grande numero di parametri opzionali che
815!! indicano quali descrittori allocare e con quale estensione;
816!! i descrittori non specificati non vengono toccati.
817!! Può essere quindi chiamato più volte allocando via via
818!! descrittori relativi a dimensioni diverse.
819!! Se un descrittore richiesto è già allocato, viene deallocato
820!! (perdendone l'eventuale contenuto) e riallocato con l'estensione
821!! richiesta.
822!! Per i descrittori relativi a dimensioni che non siano variabili o attributi,
823!! è possibile specificare l'estensione di una dimensione a 0,
824!! in tal caso il descrittore viene comunque allocato con lunghezza nulla,
825!! che è diverso da non allocarlo. Per i descrittori di variabili e attributi
826!! passare un'estensione 0 equivale a non fornire il parametro.
827!! Avere uno o più descrittori dimensionati con estensione nulla fa sì
828!! che anche il volume dati successivamente allocato abbia estensione nulla;
829!! sebbene ciò appaia inutile, un volume del genere può in realtà servire,
830!! in associazione ai metodi ::vol7d_merge o ::vol7d_append per estendere
831!! un volume esistente aggiungendo elementi in alcune dimensioni (quelle
832!! a estensione non nulla, ovviamente) e mantenendo invariato tutto il resto.
833!! Per quanto riguarda i descrittori delle dimensioni relative alle
834!! variabili, la relativa estensione è specificata con la nomenclatura
835!! \a n&lt;x&gt;&lt;y&gt;&lt;z&gt; dove &lt;x&gt; può valere:
836!! - \a ana per variabili relative a voumi di anagrafica
837!! - \a dati per variabili relative a voumi di dati
838!!
839!! &lt;y&gt; può valere:
840!! - \a var per variabili
841!! - \a attr per attributi
842!! - \a varattr variabili aventi attributi nei volumi di attributi
843!!
844!! &lt;z&gt; può valere:
845!! - \a r per variabili o attributi a valori reali
846!! - \a d per variabili o attributi a valori a doppia precisione
847!! - \a i per variabili o attributi a valori interi
848!! - \a b per variabili o attributi a valori byte
849!! - \a c per variabili o attributi a valori carattere
850!!
851SUBROUTINE vol7d_alloc(this, nana, ntime, nlevel, ntimerange, nnetwork, &
852 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
853 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
854 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
855 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
856 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
857 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc, &
858 ini)
859TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i descrittori
860INTEGER,INTENT(in),OPTIONAL :: nana !< estensione della dimensione anagrafica
861INTEGER,INTENT(in),OPTIONAL :: ntime !< estensione della dimensione tempo
862INTEGER,INTENT(in),OPTIONAL :: nlevel !< estensione della dimensione livello varticale
863INTEGER,INTENT(in),OPTIONAL :: ntimerange !< estensione della dimensione intervallo temporale (timerange)
864INTEGER,INTENT(in),OPTIONAL :: nnetwork !< estensione della dimensione rete
865!> estensione delle possibili dimensioni variabile
866INTEGER,INTENT(in),OPTIONAL :: &
867 nanavarr, nanavard, nanavari, nanavarb, nanavarc, &
868 nanaattrr, nanaattrd, nanaattri, nanaattrb, nanaattrc, &
869 nanavarattrr, nanavarattrd, nanavarattri, nanavarattrb, nanavarattrc, &
870 ndativarr, ndativard, ndativari, ndativarb, ndativarc, &
871 ndatiattrr, ndatiattrd, ndatiattri, ndatiattrb, ndatiattrc, &
872 ndativarattrr, ndativarattrd, ndativarattri, ndativarattrb, ndativarattrc
873LOGICAL,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
874
875INTEGER :: i
876LOGICAL :: linit
877
878IF (PRESENT(ini)) THEN
879 linit = ini
880ELSE
881 linit = .false.
882ENDIF
883
884! Dimensioni principali
885IF (PRESENT(nana)) THEN
886 IF (nana >= 0) THEN
887 IF (ASSOCIATED(this%ana)) DEALLOCATE(this%ana)
888 ALLOCATE(this%ana(nana))
889 IF (linit) THEN
890 DO i = 1, nana
891 CALL init(this%ana(i))
892 ENDDO
893 ENDIF
894 ENDIF
895ENDIF
896IF (PRESENT(ntime)) THEN
897 IF (ntime >= 0) THEN
898 IF (ASSOCIATED(this%time)) DEALLOCATE(this%time)
899 ALLOCATE(this%time(ntime))
900 IF (linit) THEN
901 DO i = 1, ntime
902 CALL init(this%time(i))
903 ENDDO
904 ENDIF
905 ENDIF
906ENDIF
907IF (PRESENT(nlevel)) THEN
908 IF (nlevel >= 0) THEN
909 IF (ASSOCIATED(this%level)) DEALLOCATE(this%level)
910 ALLOCATE(this%level(nlevel))
911 IF (linit) THEN
912 DO i = 1, nlevel
913 CALL init(this%level(i))
914 ENDDO
915 ENDIF
916 ENDIF
917ENDIF
918IF (PRESENT(ntimerange)) THEN
919 IF (ntimerange >= 0) THEN
920 IF (ASSOCIATED(this%timerange)) DEALLOCATE(this%timerange)
921 ALLOCATE(this%timerange(ntimerange))
922 IF (linit) THEN
923 DO i = 1, ntimerange
924 CALL init(this%timerange(i))
925 ENDDO
926 ENDIF
927 ENDIF
928ENDIF
929IF (PRESENT(nnetwork)) THEN
930 IF (nnetwork >= 0) THEN
931 IF (ASSOCIATED(this%network)) DEALLOCATE(this%network)
932 ALLOCATE(this%network(nnetwork))
933 IF (linit) THEN
934 DO i = 1, nnetwork
935 CALL init(this%network(i))
936 ENDDO
937 ENDIF
938 ENDIF
939ENDIF
940! Dimensioni dei tipi delle variabili
941CALL vol7d_varvect_alloc(this%anavar, nanavarr, nanavard, &
942 nanavari, nanavarb, nanavarc, ini)
943CALL vol7d_varvect_alloc(this%anaattr, nanaattrr, nanaattrd, &
944 nanaattri, nanaattrb, nanaattrc, ini)
945CALL vol7d_varvect_alloc(this%anavarattr, nanavarattrr, nanavarattrd, &
946 nanavarattri, nanavarattrb, nanavarattrc, ini)
947CALL vol7d_varvect_alloc(this%dativar, ndativarr, ndativard, &
948 ndativari, ndativarb, ndativarc, ini)
949CALL vol7d_varvect_alloc(this%datiattr, ndatiattrr, ndatiattrd, &
950 ndatiattri, ndatiattrb, ndatiattrc, ini)
951CALL vol7d_varvect_alloc(this%dativarattr, ndativarattrr, ndativarattrd, &
952 ndativarattri, ndativarattrb, ndativarattrc, ini)
953
954END SUBROUTINE vol7d_alloc
955
956
957FUNCTION vol7d_check_alloc_ana(this)
958TYPE(vol7d),INTENT(in) :: this
959LOGICAL :: vol7d_check_alloc_ana
960
961vol7d_check_alloc_ana = ASSOCIATED(this%ana) .AND. ASSOCIATED(this%network)
962
963END FUNCTION vol7d_check_alloc_ana
964
965SUBROUTINE vol7d_force_alloc_ana(this, ini)
966TYPE(vol7d),INTENT(inout) :: this
967LOGICAL,INTENT(in),OPTIONAL :: ini
969! Alloco i descrittori minimi per avere un volume di anagrafica
970IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=1, ini=ini)
971IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=1, ini=ini)
972
973END SUBROUTINE vol7d_force_alloc_ana
974
975
976FUNCTION vol7d_check_alloc_dati(this)
977TYPE(vol7d),INTENT(in) :: this
978LOGICAL :: vol7d_check_alloc_dati
979
980vol7d_check_alloc_dati = vol7d_check_alloc_ana(this) .AND. &
981 ASSOCIATED(this%time) .AND. ASSOCIATED(this%level) .AND. &
982 ASSOCIATED(this%timerange)
983
984END FUNCTION vol7d_check_alloc_dati
985
986SUBROUTINE vol7d_force_alloc_dati(this, ini)
987TYPE(vol7d),INTENT(inout) :: this
988LOGICAL,INTENT(in),OPTIONAL :: ini
989
990! Alloco i descrittori minimi per avere un volume di dati
991CALL vol7d_force_alloc_ana(this, ini)
992IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=1, ini=ini)
993IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=1, ini=ini)
994IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=1, ini=ini)
995
996END SUBROUTINE vol7d_force_alloc_dati
997
998
999SUBROUTINE vol7d_force_alloc(this)
1000TYPE(vol7d),INTENT(inout) :: this
1001
1002! If anything really not allocated yet, allocate with size 0
1003IF (.NOT. ASSOCIATED(this%ana)) CALL vol7d_alloc(this, nana=0)
1004IF (.NOT. ASSOCIATED(this%network)) CALL vol7d_alloc(this, nnetwork=0)
1005IF (.NOT. ASSOCIATED(this%time)) CALL vol7d_alloc(this, ntime=0)
1006IF (.NOT. ASSOCIATED(this%level)) CALL vol7d_alloc(this, nlevel=0)
1007IF (.NOT. ASSOCIATED(this%timerange)) CALL vol7d_alloc(this, ntimerange=0)
1008
1009END SUBROUTINE vol7d_force_alloc
1010
1011
1012FUNCTION vol7d_check_vol(this)
1013TYPE(vol7d),INTENT(in) :: this !< oggetto da controllare
1014LOGICAL :: vol7d_check_vol
1015
1016vol7d_check_vol = c_e(this)
1017
1018! Anagrafica
1019IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
1020 vol7d_check_vol = .false.
1021ENDIF
1022
1023IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
1024 vol7d_check_vol = .false.
1025ENDIF
1026
1027IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
1028 vol7d_check_vol = .false.
1029ENDIF
1031IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
1032 vol7d_check_vol = .false.
1033ENDIF
1034
1035IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
1036 vol7d_check_vol = .false.
1037ENDIF
1038IF (ASSOCIATED(this%anavar%r) .OR. ASSOCIATED(this%anavar%d) .OR. &
1039 ASSOCIATED(this%anavar%i) .OR. ASSOCIATED(this%anavar%b) .OR. &
1040 ASSOCIATED(this%anavar%c)) THEN
1041 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_ana(this)
1042ENDIF
1043
1044! Attributi dell'anagrafica
1045IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
1046 .NOT.ASSOCIATED(this%volanaattrr)) THEN
1047 vol7d_check_vol = .false.
1048ENDIF
1049
1050IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
1051 .NOT.ASSOCIATED(this%volanaattrd)) THEN
1052 vol7d_check_vol = .false.
1053ENDIF
1054
1055IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
1056 .NOT.ASSOCIATED(this%volanaattri)) THEN
1057 vol7d_check_vol = .false.
1058ENDIF
1059
1060IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
1061 .NOT.ASSOCIATED(this%volanaattrb)) THEN
1062 vol7d_check_vol = .false.
1063ENDIF
1064
1065IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
1066 .NOT.ASSOCIATED(this%volanaattrc)) THEN
1067 vol7d_check_vol = .false.
1068ENDIF
1069
1070! Dati
1071IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
1072 vol7d_check_vol = .false.
1073ENDIF
1074
1075IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
1076 vol7d_check_vol = .false.
1077ENDIF
1078
1079IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
1080 vol7d_check_vol = .false.
1081ENDIF
1082
1083IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
1084 vol7d_check_vol = .false.
1085ENDIF
1086
1087IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
1088 vol7d_check_vol = .false.
1089ENDIF
1090
1091! Attributi dei dati
1092IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
1093 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
1094 vol7d_check_vol = .false.
1095ENDIF
1096
1097IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
1098 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
1099 vol7d_check_vol = .false.
1100ENDIF
1101
1102IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
1103 .NOT.ASSOCIATED(this%voldatiattri)) THEN
1104 vol7d_check_vol = .false.
1105ENDIF
1106
1107IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
1108 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
1109 vol7d_check_vol = .false.
1110ENDIF
1111
1112IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
1113 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
1114 vol7d_check_vol = .false.
1115ENDIF
1116IF (ASSOCIATED(this%dativar%r) .OR. ASSOCIATED(this%dativar%d) .OR. &
1117 ASSOCIATED(this%dativar%i) .OR. ASSOCIATED(this%dativar%b) .OR. &
1118 ASSOCIATED(this%dativar%c)) THEN
1119 vol7d_check_vol = vol7d_check_vol .AND. vol7d_check_alloc_dati(this)
1120ENDIF
1121
1122END FUNCTION vol7d_check_vol
1123
1124
1125!> Metodo per allocare i volumi richiesti di variabili e attributi per
1126!! anagrafica e dati.
1127!! Se alcuni dei descrittori relativi alle dimensioni anagrafica,
1128!! livello verticale, tempo, intervallo temporale (timerange), rete non sono
1129!! stati richiesti preventivamente con la ::vol7d_alloc, essi vengono allocati
1130!! automaticamente da questo metodo
1131!! con estensione di default pari a 1 (non 0!), questo significa, ad esempio,
1132!! che se prevedo di avere soli dati superficiali, cioè ad un solo livello
1133!! verticale, o una sola rete di stazioni, non devo preoccuparmi di
1134!! specificare questa informazione.
1135!! Tra i 20 possibili volumi allocabili
1136!! ((variabili,attributi)*(anagrafica,dati)*(r,d,i,b,c)=20)
1137!! saranno allocati solo quelli per cui è stato precedentemente richiesto il
1138!! corrispondente descrittore variabili/attributi con la ::vol7d_alloc.
1139SUBROUTINE vol7d_alloc_vol(this, ini, inivol)
1140TYPE(vol7d),INTENT(inout) :: this !< oggetto di cui allocare i volumi
1141LOGICAL,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
1142LOGICAL,INTENT(in),OPTIONAL :: inivol !< se fornito e vale \c .TRUE., i volumi allocati saranno inizializzati a valore mancante
1143
1144LOGICAL :: linivol
1145
1146IF (PRESENT(inivol)) THEN
1147 linivol = inivol
1148ELSE
1149 linivol = .true.
1150ENDIF
1151
1152! Anagrafica
1153IF (ASSOCIATED(this%anavar%r) .AND. .NOT.ASSOCIATED(this%volanar)) THEN
1154 CALL vol7d_force_alloc_ana(this, ini)
1155 ALLOCATE(this%volanar(SIZE(this%ana), SIZE(this%anavar%r), SIZE(this%network)))
1156 IF (linivol) this%volanar(:,:,:) = rmiss
1157ENDIF
1158
1159IF (ASSOCIATED(this%anavar%d) .AND. .NOT.ASSOCIATED(this%volanad)) THEN
1160 CALL vol7d_force_alloc_ana(this, ini)
1161 ALLOCATE(this%volanad(SIZE(this%ana), SIZE(this%anavar%d), SIZE(this%network)))
1162 IF (linivol) this%volanad(:,:,:) = rdmiss
1163ENDIF
1164
1165IF (ASSOCIATED(this%anavar%i) .AND. .NOT.ASSOCIATED(this%volanai)) THEN
1166 CALL vol7d_force_alloc_ana(this, ini)
1167 ALLOCATE(this%volanai(SIZE(this%ana), SIZE(this%anavar%i), SIZE(this%network)))
1168 IF (linivol) this%volanai(:,:,:) = imiss
1169ENDIF
1170
1171IF (ASSOCIATED(this%anavar%b) .AND. .NOT.ASSOCIATED(this%volanab)) THEN
1172 CALL vol7d_force_alloc_ana(this, ini)
1173 ALLOCATE(this%volanab(SIZE(this%ana), SIZE(this%anavar%b), SIZE(this%network)))
1174 IF (linivol) this%volanab(:,:,:) = ibmiss
1175ENDIF
1176
1177IF (ASSOCIATED(this%anavar%c) .AND. .NOT.ASSOCIATED(this%volanac)) THEN
1178 CALL vol7d_force_alloc_ana(this, ini)
1179 ALLOCATE(this%volanac(SIZE(this%ana), SIZE(this%anavar%c), SIZE(this%network)))
1180 IF (linivol) this%volanac(:,:,:) = cmiss
1181ENDIF
1182
1183! Attributi dell'anagrafica
1184IF (ASSOCIATED(this%anaattr%r) .AND. ASSOCIATED(this%anavarattr%r) .AND. &
1185 .NOT.ASSOCIATED(this%volanaattrr)) THEN
1186 CALL vol7d_force_alloc_ana(this, ini)
1187 ALLOCATE(this%volanaattrr(SIZE(this%ana), SIZE(this%anavarattr%r), &
1188 SIZE(this%network), SIZE(this%anaattr%r)))
1189 IF (linivol) this%volanaattrr(:,:,:,:) = rmiss
1190ENDIF
1192IF (ASSOCIATED(this%anaattr%d) .AND. ASSOCIATED(this%anavarattr%d) .AND. &
1193 .NOT.ASSOCIATED(this%volanaattrd)) THEN
1194 CALL vol7d_force_alloc_ana(this, ini)
1195 ALLOCATE(this%volanaattrd(SIZE(this%ana), SIZE(this%anavarattr%d), &
1196 SIZE(this%network), SIZE(this%anaattr%d)))
1197 IF (linivol) this%volanaattrd(:,:,:,:) = rdmiss
1198ENDIF
1199
1200IF (ASSOCIATED(this%anaattr%i) .AND. ASSOCIATED(this%anavarattr%i) .AND. &
1201 .NOT.ASSOCIATED(this%volanaattri)) THEN
1202 CALL vol7d_force_alloc_ana(this, ini)
1203 ALLOCATE(this%volanaattri(SIZE(this%ana), SIZE(this%anavarattr%i), &
1204 SIZE(this%network), SIZE(this%anaattr%i)))
1205 IF (linivol) this%volanaattri(:,:,:,:) = imiss
1206ENDIF
1207
1208IF (ASSOCIATED(this%anaattr%b) .AND. ASSOCIATED(this%anavarattr%b) .AND. &
1209 .NOT.ASSOCIATED(this%volanaattrb)) THEN
1210 CALL vol7d_force_alloc_ana(this, ini)
1211 ALLOCATE(this%volanaattrb(SIZE(this%ana), SIZE(this%anavarattr%b), &
1212 SIZE(this%network), SIZE(this%anaattr%b)))
1213 IF (linivol) this%volanaattrb(:,:,:,:) = ibmiss
1214ENDIF
1215
1216IF (ASSOCIATED(this%anaattr%c) .AND. ASSOCIATED(this%anavarattr%c) .AND. &
1217 .NOT.ASSOCIATED(this%volanaattrc)) THEN
1218 CALL vol7d_force_alloc_ana(this, ini)
1219 ALLOCATE(this%volanaattrc(SIZE(this%ana), SIZE(this%anavarattr%c), &
1220 SIZE(this%network), SIZE(this%anaattr%c)))
1221 IF (linivol) this%volanaattrc(:,:,:,:) = cmiss
1222ENDIF
1223
1224! Dati
1225IF (ASSOCIATED(this%dativar%r) .AND. .NOT.ASSOCIATED(this%voldatir)) THEN
1226 CALL vol7d_force_alloc_dati(this, ini)
1227 ALLOCATE(this%voldatir(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1228 SIZE(this%timerange), SIZE(this%dativar%r), SIZE(this%network)))
1229 IF (linivol) this%voldatir(:,:,:,:,:,:) = rmiss
1230ENDIF
1231
1232IF (ASSOCIATED(this%dativar%d) .AND. .NOT.ASSOCIATED(this%voldatid)) THEN
1233 CALL vol7d_force_alloc_dati(this, ini)
1234 ALLOCATE(this%voldatid(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1235 SIZE(this%timerange), SIZE(this%dativar%d), SIZE(this%network)))
1236 IF (linivol) this%voldatid(:,:,:,:,:,:) = rdmiss
1237ENDIF
1238
1239IF (ASSOCIATED(this%dativar%i) .AND. .NOT.ASSOCIATED(this%voldatii)) THEN
1240 CALL vol7d_force_alloc_dati(this, ini)
1241 ALLOCATE(this%voldatii(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1242 SIZE(this%timerange), SIZE(this%dativar%i), SIZE(this%network)))
1243 IF (linivol) this%voldatii(:,:,:,:,:,:) = imiss
1244ENDIF
1245
1246IF (ASSOCIATED(this%dativar%b) .AND. .NOT.ASSOCIATED(this%voldatib)) THEN
1247 CALL vol7d_force_alloc_dati(this, ini)
1248 ALLOCATE(this%voldatib(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1249 SIZE(this%timerange), SIZE(this%dativar%b), SIZE(this%network)))
1250 IF (linivol) this%voldatib(:,:,:,:,:,:) = ibmiss
1251ENDIF
1252
1253IF (ASSOCIATED(this%dativar%c) .AND. .NOT.ASSOCIATED(this%voldatic)) THEN
1254 CALL vol7d_force_alloc_dati(this, ini)
1255 ALLOCATE(this%voldatic(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1256 SIZE(this%timerange), SIZE(this%dativar%c), SIZE(this%network)))
1257 IF (linivol) this%voldatic(:,:,:,:,:,:) = cmiss
1258ENDIF
1259
1260! Attributi dei dati
1261IF (ASSOCIATED(this%datiattr%r) .AND. ASSOCIATED(this%dativarattr%r) .AND. &
1262 .NOT.ASSOCIATED(this%voldatiattrr)) THEN
1263 CALL vol7d_force_alloc_dati(this, ini)
1264 ALLOCATE(this%voldatiattrr(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1265 SIZE(this%timerange), SIZE(this%dativarattr%r), SIZE(this%network), &
1266 SIZE(this%datiattr%r)))
1267 IF (linivol) this%voldatiattrr(:,:,:,:,:,:,:) = rmiss
1268ENDIF
1269
1270IF (ASSOCIATED(this%datiattr%d) .AND. ASSOCIATED(this%dativarattr%d) .AND. &
1271 .NOT.ASSOCIATED(this%voldatiattrd)) THEN
1272 CALL vol7d_force_alloc_dati(this, ini)
1273 ALLOCATE(this%voldatiattrd(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1274 SIZE(this%timerange), SIZE(this%dativarattr%d), SIZE(this%network), &
1275 SIZE(this%datiattr%d)))
1276 IF (linivol) this%voldatiattrd(:,:,:,:,:,:,:) = rdmiss
1277ENDIF
1278
1279IF (ASSOCIATED(this%datiattr%i) .AND. ASSOCIATED(this%dativarattr%i) .AND. &
1280 .NOT.ASSOCIATED(this%voldatiattri)) THEN
1281 CALL vol7d_force_alloc_dati(this, ini)
1282 ALLOCATE(this%voldatiattri(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1283 SIZE(this%timerange), SIZE(this%dativarattr%i), SIZE(this%network), &
1284 SIZE(this%datiattr%i)))
1285 IF (linivol) this%voldatiattri(:,:,:,:,:,:,:) = imiss
1286ENDIF
1287
1288IF (ASSOCIATED(this%datiattr%b) .AND. ASSOCIATED(this%dativarattr%b) .AND. &
1289 .NOT.ASSOCIATED(this%voldatiattrb)) THEN
1290 CALL vol7d_force_alloc_dati(this, ini)
1291 ALLOCATE(this%voldatiattrb(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1292 SIZE(this%timerange), SIZE(this%dativarattr%b), SIZE(this%network), &
1293 SIZE(this%datiattr%b)))
1294 IF (linivol) this%voldatiattrb(:,:,:,:,:,:,:) = ibmiss
1295ENDIF
1296
1297IF (ASSOCIATED(this%datiattr%c) .AND. ASSOCIATED(this%dativarattr%c) .AND. &
1298 .NOT.ASSOCIATED(this%voldatiattrc)) THEN
1299 CALL vol7d_force_alloc_dati(this, ini)
1300 ALLOCATE(this%voldatiattrc(SIZE(this%ana), SIZE(this%time), SIZE(this%level), &
1301 SIZE(this%timerange), SIZE(this%dativarattr%c), SIZE(this%network), &
1302 SIZE(this%datiattr%c)))
1303 IF (linivol) this%voldatiattrc(:,:,:,:,:,:,:) = cmiss
1304ENDIF
1305
1306! Catch-all method
1307CALL vol7d_force_alloc(this)
1308
1309! Creo gli indici var-attr
1310
1311#ifdef DEBUG
1312CALL l4f_log(l4f_debug,"calling: vol7d_set_attr_ind")
1313#endif
1314
1315CALL vol7d_set_attr_ind(this)
1316
1317
1319END SUBROUTINE vol7d_alloc_vol
1320
1321
1322!> Metodo per creare gli indici che associano le variabili aventi attributo
1323!! alle variabili nei relativi descrittori.
1324!! Ha senso chiamare questo metodo solo dopo che i descrittori delle variabili
1325!! e degli attributi desiderati sono stati allocati ed è stato assegnato un
1326!! valore ai relativi membri btable (vedi vol7d_var_class::vol7d_var), se
1327!! i descrittori non sono stati allocati o assegnati, il metodo non fa niente.
1328SUBROUTINE vol7d_set_attr_ind(this)
1329TYPE(vol7d),INTENT(inout) :: this !< oggetto in cui creare gli indici
1330
1331INTEGER :: i
1332
1333! real
1334IF (ASSOCIATED(this%dativar%r)) THEN
1335 IF (ASSOCIATED(this%dativarattr%r)) THEN
1336 DO i = 1, SIZE(this%dativar%r)
1337 this%dativar%r(i)%r = &
1338 firsttrue(this%dativar%r(i)%btable == this%dativarattr%r(:)%btable)
1339 ENDDO
1340 ENDIF
1341
1342 IF (ASSOCIATED(this%dativarattr%d)) THEN
1343 DO i = 1, SIZE(this%dativar%r)
1344 this%dativar%r(i)%d = &
1345 firsttrue(this%dativar%r(i)%btable == this%dativarattr%d(:)%btable)
1346 ENDDO
1347 ENDIF
1348
1349 IF (ASSOCIATED(this%dativarattr%i)) THEN
1350 DO i = 1, SIZE(this%dativar%r)
1351 this%dativar%r(i)%i = &
1352 firsttrue(this%dativar%r(i)%btable == this%dativarattr%i(:)%btable)
1353 ENDDO
1354 ENDIF
1355
1356 IF (ASSOCIATED(this%dativarattr%b)) THEN
1357 DO i = 1, SIZE(this%dativar%r)
1358 this%dativar%r(i)%b = &
1359 firsttrue(this%dativar%r(i)%btable == this%dativarattr%b(:)%btable)
1360 ENDDO
1361 ENDIF
1362
1363 IF (ASSOCIATED(this%dativarattr%c)) THEN
1364 DO i = 1, SIZE(this%dativar%r)
1365 this%dativar%r(i)%c = &
1366 firsttrue(this%dativar%r(i)%btable == this%dativarattr%c(:)%btable)
1367 ENDDO
1368 ENDIF
1369ENDIF
1370! double
1371IF (ASSOCIATED(this%dativar%d)) THEN
1372 IF (ASSOCIATED(this%dativarattr%r)) THEN
1373 DO i = 1, SIZE(this%dativar%d)
1374 this%dativar%d(i)%r = &
1375 firsttrue(this%dativar%d(i)%btable == this%dativarattr%r(:)%btable)
1376 ENDDO
1377 ENDIF
1378
1379 IF (ASSOCIATED(this%dativarattr%d)) THEN
1380 DO i = 1, SIZE(this%dativar%d)
1381 this%dativar%d(i)%d = &
1382 firsttrue(this%dativar%d(i)%btable == this%dativarattr%d(:)%btable)
1383 ENDDO
1384 ENDIF
1385
1386 IF (ASSOCIATED(this%dativarattr%i)) THEN
1387 DO i = 1, SIZE(this%dativar%d)
1388 this%dativar%d(i)%i = &
1389 firsttrue(this%dativar%d(i)%btable == this%dativarattr%i(:)%btable)
1390 ENDDO
1391 ENDIF
1392
1393 IF (ASSOCIATED(this%dativarattr%b)) THEN
1394 DO i = 1, SIZE(this%dativar%d)
1395 this%dativar%d(i)%b = &
1396 firsttrue(this%dativar%d(i)%btable == this%dativarattr%b(:)%btable)
1397 ENDDO
1398 ENDIF
1399
1400 IF (ASSOCIATED(this%dativarattr%c)) THEN
1401 DO i = 1, SIZE(this%dativar%d)
1402 this%dativar%d(i)%c = &
1403 firsttrue(this%dativar%d(i)%btable == this%dativarattr%c(:)%btable)
1404 ENDDO
1405 ENDIF
1406ENDIF
1407! integer
1408IF (ASSOCIATED(this%dativar%i)) THEN
1409 IF (ASSOCIATED(this%dativarattr%r)) THEN
1410 DO i = 1, SIZE(this%dativar%i)
1411 this%dativar%i(i)%r = &
1412 firsttrue(this%dativar%i(i)%btable == this%dativarattr%r(:)%btable)
1413 ENDDO
1414 ENDIF
1415
1416 IF (ASSOCIATED(this%dativarattr%d)) THEN
1417 DO i = 1, SIZE(this%dativar%i)
1418 this%dativar%i(i)%d = &
1419 firsttrue(this%dativar%i(i)%btable == this%dativarattr%d(:)%btable)
1420 ENDDO
1421 ENDIF
1422
1423 IF (ASSOCIATED(this%dativarattr%i)) THEN
1424 DO i = 1, SIZE(this%dativar%i)
1425 this%dativar%i(i)%i = &
1426 firsttrue(this%dativar%i(i)%btable == this%dativarattr%i(:)%btable)
1427 ENDDO
1428 ENDIF
1429
1430 IF (ASSOCIATED(this%dativarattr%b)) THEN
1431 DO i = 1, SIZE(this%dativar%i)
1432 this%dativar%i(i)%b = &
1433 firsttrue(this%dativar%i(i)%btable == this%dativarattr%b(:)%btable)
1434 ENDDO
1435 ENDIF
1436
1437 IF (ASSOCIATED(this%dativarattr%c)) THEN
1438 DO i = 1, SIZE(this%dativar%i)
1439 this%dativar%i(i)%c = &
1440 firsttrue(this%dativar%i(i)%btable == this%dativarattr%c(:)%btable)
1441 ENDDO
1442 ENDIF
1443ENDIF
1444! byte
1445IF (ASSOCIATED(this%dativar%b)) THEN
1446 IF (ASSOCIATED(this%dativarattr%r)) THEN
1447 DO i = 1, SIZE(this%dativar%b)
1448 this%dativar%b(i)%r = &
1449 firsttrue(this%dativar%b(i)%btable == this%dativarattr%r(:)%btable)
1450 ENDDO
1451 ENDIF
1452
1453 IF (ASSOCIATED(this%dativarattr%d)) THEN
1454 DO i = 1, SIZE(this%dativar%b)
1455 this%dativar%b(i)%d = &
1456 firsttrue(this%dativar%b(i)%btable == this%dativarattr%d(:)%btable)
1457 ENDDO
1458 ENDIF
1459
1460 IF (ASSOCIATED(this%dativarattr%i)) THEN
1461 DO i = 1, SIZE(this%dativar%b)
1462 this%dativar%b(i)%i = &
1463 firsttrue(this%dativar%b(i)%btable == this%dativarattr%i(:)%btable)
1464 ENDDO
1465 ENDIF
1466
1467 IF (ASSOCIATED(this%dativarattr%b)) THEN
1468 DO i = 1, SIZE(this%dativar%b)
1469 this%dativar%b(i)%b = &
1470 firsttrue(this%dativar%b(i)%btable == this%dativarattr%b(:)%btable)
1471 ENDDO
1472 ENDIF
1473
1474 IF (ASSOCIATED(this%dativarattr%c)) THEN
1475 DO i = 1, SIZE(this%dativar%b)
1476 this%dativar%b(i)%c = &
1477 firsttrue(this%dativar%b(i)%btable == this%dativarattr%c(:)%btable)
1478 ENDDO
1479 ENDIF
1480ENDIF
1481! character
1482IF (ASSOCIATED(this%dativar%c)) THEN
1483 IF (ASSOCIATED(this%dativarattr%r)) THEN
1484 DO i = 1, SIZE(this%dativar%c)
1485 this%dativar%c(i)%r = &
1486 firsttrue(this%dativar%c(i)%btable == this%dativarattr%r(:)%btable)
1487 ENDDO
1488 ENDIF
1489
1490 IF (ASSOCIATED(this%dativarattr%d)) THEN
1491 DO i = 1, SIZE(this%dativar%c)
1492 this%dativar%c(i)%d = &
1493 firsttrue(this%dativar%c(i)%btable == this%dativarattr%d(:)%btable)
1494 ENDDO
1495 ENDIF
1496
1497 IF (ASSOCIATED(this%dativarattr%i)) THEN
1498 DO i = 1, SIZE(this%dativar%c)
1499 this%dativar%c(i)%i = &
1500 firsttrue(this%dativar%c(i)%btable == this%dativarattr%i(:)%btable)
1501 ENDDO
1502 ENDIF
1503
1504 IF (ASSOCIATED(this%dativarattr%b)) THEN
1505 DO i = 1, SIZE(this%dativar%c)
1506 this%dativar%c(i)%b = &
1507 firsttrue(this%dativar%c(i)%btable == this%dativarattr%b(:)%btable)
1508 ENDDO
1509 ENDIF
1510
1511 IF (ASSOCIATED(this%dativarattr%c)) THEN
1512 DO i = 1, SIZE(this%dativar%c)
1513 this%dativar%c(i)%c = &
1514 firsttrue(this%dativar%c(i)%btable == this%dativarattr%c(:)%btable)
1515 ENDDO
1516 ENDIF
1517ENDIF
1518
1519END SUBROUTINE vol7d_set_attr_ind
1520
1521
1522!> Metodo per fondere 2 oggetti vol7d.
1523!! Il secondo volume viene accodato al primo e poi distrutto, si veda
1524!! quindi la descrizione di ::vol7d_append. Se uno degli oggetti \a
1525!! this o \a that sono vuoti non perde tempo inutile,
1526SUBROUTINE vol7d_merge(this, that, sort, bestdata, &
1527 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
1528TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, alla fine conterrà il risultato della fusione
1529TYPE(vol7d),INTENT(INOUT) :: that !< secondo oggetto in ingresso, alla fine sarà distrutto
1530LOGICAL,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
1531LOGICAL,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
1532LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple ! experimental, please do not use outside the library now
1533
1534TYPE(vol7d) :: v7d_clean
1535
1536
1537IF (.NOT.c_e(this)) THEN ! speedup
1538 this = that
1539 CALL init(v7d_clean)
1540 that = v7d_clean ! destroy that without deallocating
1541ELSE ! Append that to this and destroy that
1542 CALL vol7d_append(this, that, sort, bestdata, &
1543 ltimesimple, ltimerangesimple, llevelsimple, lanasimple)
1544 CALL delete(that)
1545ENDIF
1546
1547END SUBROUTINE vol7d_merge
1548
1549
1550!> Metodo per accodare un oggetto vol7d ad un altro.
1551!! Si tratta di un metodo molto potente e versatile;
1552!! i descrittori delle dimensioni del volume finale conterranno i valori
1553!! dei corrispondenti descrittori del primo e del secondo volume
1554!! e i volumi di anagrafica e dati conterranno i valori dei due volumi
1555!! ai posti giusti, e valori mancanti per le nuove combinazioni che
1556!! eventualmente si verranno a creare.
1557!! Se i volumi multidimensionali di anagrafica e/o dati dei 2 oggetti
1558!! hanno un'intersezione non nulla, negli elementi comuni il volume finale
1559!! conterrà il corrispondente elemento del \b secondo volume.
1560!! Attenzione che, durante l'esecuzione del metodo, la memoria richiesta è
1561!! pari alla memoria complessiva occupata dai 2 volumi iniziali più
1562!! la memoria complessiva del volume finale, per cui, nel caso di volumi grandi,
1563!! ci potrebbero essere problemi di esaurimento della memoria centrale.
1564!! Se l'oggetto \a that è vuoto non perde tempo inutile,
1565!!
1566!! \todo nel caso di elementi comuni inserire la possibiità (opzionale per
1567!! non penalizzare le prestazioni quando ciò non serve) di effettuare una scelta
1568!! più ragionata dell'elemento da tenere, almeno controllando i dati mancanti
1569!! se non le flag di qualità
1570!!
1571!! \todo "rateizzare" l'allocazione dei volumi per ridurre l'occupazione di
1572!! memoria nel caso siano allocati contemporaneamente volumi di variabili e
1573!! di attributi o più volumi di tipi diversi
1574!!
1575!! \todo il parametro \a that è dichiarato \a INOUT perché la vol7d_alloc_vol
1576!! può modificarlo, bisognerebbe implementare una vol7d_check_vol che restituisca
1577!! errore anziché usare la vol7d_alloc_vol.
1578SUBROUTINE vol7d_append(this, that, sort, bestdata, &
1579 ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple)
1580TYPE(vol7d),INTENT(INOUT) :: this !< primo oggetto in ingresso, a cui sarà accodato il secondo
1581TYPE(vol7d),INTENT(IN) :: that !< secondo oggetto in ingresso, non viene modificato dal metodo
1582LOGICAL,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
1583! experimental, please do not use outside the library now, they force the use
1584! of a simplified mapping algorithm which is valid only whene the dimension
1585! content is the same in both volumes , or when one of them is empty
1586LOGICAL,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
1587LOGICAL,INTENT(IN),OPTIONAL :: ltimesimple, ltimerangesimple, llevelsimple, lanasimple, lnetworksimple
1588
1589
1590TYPE(vol7d) :: v7dtmp
1591LOGICAL :: lsort, lbestdata
1592INTEGER,POINTER :: remapt1(:), remapt2(:), remaptr1(:), remaptr2(:), &
1593 remapl1(:), remapl2(:), remapa1(:), remapa2(:), remapn1(:), remapn2(:)
1594
1595IF (.NOT.c_e(that)) RETURN ! speedup, nothing to do
1596IF (.NOT.vol7d_check_vol(that)) RETURN ! be safe
1597IF (.NOT.c_e(this)) THEN ! this case is like a vol7d_copy, more efficient to copy?
1598 CALL vol7d_copy(that, this, sort=sort)
1599 RETURN
1600ENDIF
1601
1602IF (this%time_definition /= that%time_definition) THEN
1603 CALL l4f_log(l4f_fatal, &
1604 'in vol7d_append, cannot append volumes with different &
1605 &time definition')
1606 CALL raise_fatal_error()
1607ENDIF
1608
1609! Completo l'allocazione per avere volumi a norma
1610CALL vol7d_alloc_vol(this)
1611
1612CALL init(v7dtmp, time_definition=this%time_definition)
1613CALL optio(sort, lsort)
1614CALL optio(bestdata, lbestdata)
1615
1616! Calcolo le mappature tra volumi vecchi e volume nuovo
1617! I puntatori remap* vengono tutti o allocati o nullificati
1618IF (optio_log(ltimesimple)) THEN
1619 CALL vol7d_remap2simple_datetime(this%time, that%time, v7dtmp%time, &
1620 lsort, remapt1, remapt2)
1621ELSE
1622 CALL vol7d_remap2_datetime(this%time, that%time, v7dtmp%time, &
1623 lsort, remapt1, remapt2)
1624ENDIF
1625IF (optio_log(ltimerangesimple)) THEN
1626 CALL vol7d_remap2simple_vol7d_timerange(this%timerange, that%timerange, &
1627 v7dtmp%timerange, lsort, remaptr1, remaptr2)
1628ELSE
1629 CALL vol7d_remap2_vol7d_timerange(this%timerange, that%timerange, &
1630 v7dtmp%timerange, lsort, remaptr1, remaptr2)
1631ENDIF
1632IF (optio_log(llevelsimple)) THEN
1633 CALL vol7d_remap2simple_vol7d_level(this%level, that%level, v7dtmp%level, &
1634 lsort, remapl1, remapl2)
1635ELSE
1636 CALL vol7d_remap2_vol7d_level(this%level, that%level, v7dtmp%level, &
1637 lsort, remapl1, remapl2)
1638ENDIF
1639IF (optio_log(lanasimple)) THEN
1640 CALL vol7d_remap2simple_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
1641 .false., remapa1, remapa2)
1642ELSE
1643 CALL vol7d_remap2_vol7d_ana(this%ana, that%ana, v7dtmp%ana, &
1644 .false., remapa1, remapa2)
1645ENDIF
1646IF (optio_log(lnetworksimple)) THEN
1647 CALL vol7d_remap2simple_vol7d_network(this%network, that%network, v7dtmp%network, &
1648 .false., remapn1, remapn2)
1649ELSE
1650 CALL vol7d_remap2_vol7d_network(this%network, that%network, v7dtmp%network, &
1651 .false., remapn1, remapn2)
1652ENDIF
1653
1654! Faccio la fusione fisica dei volumi
1655CALL vol7d_merge_finalr(this, that, v7dtmp, &
1656 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
1657 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
1658CALL vol7d_merge_finald(this, that, v7dtmp, &
1659 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
1660 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
1661CALL vol7d_merge_finali(this, that, v7dtmp, &
1662 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
1663 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
1664CALL vol7d_merge_finalb(this, that, v7dtmp, &
1665 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
1666 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
1667CALL vol7d_merge_finalc(this, that, v7dtmp, &
1668 remapa1, remapa2, remapt1, remapt2, remapl1, remapl2, &
1669 remaptr1, remaptr2, remapn1, remapn2, lbestdata)
1670
1671! Dealloco i vettori di rimappatura
1672IF (ASSOCIATED(remapt1)) DEALLOCATE(remapt1)
1673IF (ASSOCIATED(remapt2)) DEALLOCATE(remapt2)
1674IF (ASSOCIATED(remaptr1)) DEALLOCATE(remaptr1)
1675IF (ASSOCIATED(remaptr2)) DEALLOCATE(remaptr2)
1676IF (ASSOCIATED(remapl1)) DEALLOCATE(remapl1)
1677IF (ASSOCIATED(remapl2)) DEALLOCATE(remapl2)
1678IF (ASSOCIATED(remapa1)) DEALLOCATE(remapa1)
1679IF (ASSOCIATED(remapa2)) DEALLOCATE(remapa2)
1680IF (ASSOCIATED(remapn1)) DEALLOCATE(remapn1)
1681IF (ASSOCIATED(remapn2)) DEALLOCATE(remapn2)
1682
1683! Distruggo il vecchio volume e assegno il nuovo a this
1684CALL delete(this)
1685this = v7dtmp
1686! Ricreo gli indici var-attr
1687CALL vol7d_set_attr_ind(this)
1688
1689END SUBROUTINE vol7d_append
1690
1691
1692!> Metodo per creare una copia completa e indipendente di un oggetto vol7d.
1693!! Questo metodo crea un duplicato di tutti i membri di un oggetto vol7d,
1694!! con la possibilità di rielaborarlo durante la copia. Se l'oggetto da copiare
1695!! è vuoto non perde tempo inutile.
1696!! Attenzione, il codice:
1697!! \code
1698!! USE vol7d_class
1699!! TYPE(vol7d) :: vol1, vol2
1700!! CALL init(vol1)
1701!! CALL init(vol2)
1702!! ... ! riempio vol1
1703!! vol2 = vol1
1704!! \endcode
1705!! fa una cosa diversa rispetto a:
1706!! \code
1707!! USE vol7d_class
1708!! TYPE(vol7d) :: vol1, vol2
1709!! CALL init(vol1)
1710!! CALL init(vol2)
1711!! ... ! riempio vol1
1712!! CALL vol7d_copy(vol1, vol2)
1713!! \endcode
1714!! nel primo caso, infatti, l'operatore di assegnazione copia solo i componenti
1715!! statici di \a vol1 nei corrispondenti elementi di \a vol2, mentre i componenti che
1716!! sono allocati dinamicamente (cioè quelli che in ::vol7d hanno l'attributo
1717!! \c POINTER, in pratica quasi tutti) non vengono duplicati, ma per essi vol2
1718!! conterrà un puntatore al corrispondente elemento a cui già punta vol1, e quindi
1719!! eventuali cambiamenti al contenuto di uno dei due oggetti influenzerà il
1720!! contenuto dell'altro; nel secondo caso, invece, vol1 e vol2 sono, dopo la
1721!! vol7d_copy, 2 istanze
1722!! completamente indipendenti, ma uguali tra loro per contenuto, della classe
1723!! vol7d, e quindi hanno vita indipendente.
1724SUBROUTINE vol7d_copy(this, that, sort, unique, miss, &
1725 lsort_time, lsort_timerange, lsort_level, &
1726 ltime, ltimerange, llevel, lana, lnetwork, &
1727 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
1728 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
1729 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
1730 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
1731 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
1732 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
1733TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
1734TYPE(vol7d),INTENT(INOUT) :: that !< oggetto destinazione
1735LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
1736LOGICAL,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)
1737LOGICAL,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
1738LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
1739LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
1740LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
1741!> se fornito, deve essere un vettore logico della stessa lunghezza di
1742!! this%time indicante quali elementi della dimensione \a time
1743!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
1744!! nel volume copiato; in alternativa può essere un vettore di
1745!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
1746!! gli elementi (utile principalmente per le variabili); è compatibile
1747!! col parametro \a miss
1748LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
1749!> come il precedente per la dimensione \a timerange
1750LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:)
1751!> come il precedente per la dimensione \a level
1752LOGICAL,INTENT(IN),OPTIONAL :: llevel(:)
1753!> come il precedente per la dimensione \a ana
1754LOGICAL,INTENT(IN),OPTIONAL :: lana(:)
1755!> come il precedente per la dimensione \a network
1756LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:)
1757!> come il precedente per tutte le possibili dimensioni variabile
1758LOGICAL,INTENT(in),OPTIONAL :: &
1759 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
1760 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
1761 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
1762 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
1763 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
1764 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
1765
1766LOGICAL :: lsort, lunique, lmiss
1767INTEGER,POINTER :: remapt(:), remaptr(:), remapl(:), remapa(:), remapn(:)
1768
1769CALL init(that)
1770IF (.NOT.c_e(this)) RETURN ! speedup, nothing to do
1771IF (.NOT.vol7d_check_vol(this)) RETURN ! be safe
1772
1773CALL optio(sort, lsort)
1774CALL optio(unique, lunique)
1775CALL optio(miss, lmiss)
1776
1777! Calcolo le mappature tra volume vecchio e volume nuovo
1778! I puntatori remap* vengono tutti o allocati o nullificati
1779CALL vol7d_remap1_datetime(this%time, that%time, &
1780 lsort.OR.optio_log(lsort_time), lunique, lmiss, remapt, ltime)
1781CALL vol7d_remap1_vol7d_timerange(this%timerange, that%timerange, &
1782 lsort.OR.optio_log(lsort_timerange), lunique, lmiss, remaptr, ltimerange)
1783CALL vol7d_remap1_vol7d_level(this%level, that%level, &
1784 lsort.OR.optio_log(lsort_level), lunique, lmiss, remapl, llevel)
1785CALL vol7d_remap1_vol7d_ana(this%ana, that%ana, &
1786 lsort, lunique, lmiss, remapa, lana)
1787CALL vol7d_remap1_vol7d_network(this%network, that%network, &
1788 lsort, lunique, lmiss, remapn, lnetwork)
1789
1790! lanavari, lanavarb, lanavarc, &
1791! lanaattri, lanaattrb, lanaattrc, &
1792! lanavarattri, lanavarattrb, lanavarattrc, &
1793! ldativari, ldativarb, ldativarc, &
1794! ldatiattri, ldatiattrb, ldatiattrc, &
1795! ldativarattri, ldativarattrb, ldativarattrc
1796! Faccio la riforma fisica dei volumi
1797CALL vol7d_reform_finalr(this, that, &
1798 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
1799 lanavarr, lanaattrr, lanavarattrr, ldativarr, ldatiattrr, ldativarattrr)
1800CALL vol7d_reform_finald(this, that, &
1801 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
1802 lanavard, lanaattrd, lanavarattrd, ldativard, ldatiattrd, ldativarattrd)
1803CALL vol7d_reform_finali(this, that, &
1804 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
1805 lanavari, lanaattri, lanavarattri, ldativari, ldatiattri, ldativarattri)
1806CALL vol7d_reform_finalb(this, that, &
1807 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
1808 lanavarb, lanaattrb, lanavarattrb, ldativarb, ldatiattrb, ldativarattrb)
1809CALL vol7d_reform_finalc(this, that, &
1810 remapa, remapt, remapl, remaptr, remapn, lsort, lunique, lmiss, &
1811 lanavarc, lanaattrc, lanavarattrc, ldativarc, ldatiattrc, ldativarattrc)
1812
1813! Dealloco i vettori di rimappatura
1814IF (ASSOCIATED(remapt)) DEALLOCATE(remapt)
1815IF (ASSOCIATED(remaptr)) DEALLOCATE(remaptr)
1816IF (ASSOCIATED(remapl)) DEALLOCATE(remapl)
1817IF (ASSOCIATED(remapa)) DEALLOCATE(remapa)
1818IF (ASSOCIATED(remapn)) DEALLOCATE(remapn)
1819
1820! Ricreo gli indici var-attr
1821CALL vol7d_set_attr_ind(that)
1822that%time_definition = this%time_definition
1823
1824END SUBROUTINE vol7d_copy
1825
1826
1827!> Metodo per riformare in varie maniere un oggetto vol7d.
1828!! Equivale ad una copia (vedi ::vol7d_copy)
1829!! seguita dalla distruzione del volume iniziale e alla
1830!! sua riassegnazione al volume copiato. Ha senso se almeno uno dei parametri
1831!! \a sort, \a uniq o \a miss è fornito uguale a \c .TRUE., altrimenti
1832!! è solo una perdita di tempo.
1833!! Può essere utile, ad esempio, per eliminare stazioni
1834!! o istanti temporali indesiderati, basta assegnare il loro corrispondente
1835!! elemento del descrittore a valore mancante e chiamare vol7d_reform
1836!! con miss=.TRUE. .
1837SUBROUTINE vol7d_reform(this, sort, unique, miss, &
1838 lsort_time, lsort_timerange, lsort_level, &
1839 ltime, ltimerange, llevel, lana, lnetwork, &
1840 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
1841 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
1842 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
1843 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
1844 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
1845 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc&
1846 ,purgeana)
1847TYPE(vol7d),INTENT(INOUT) :: this !< oggetto da riformare
1848LOGICAL,INTENT(IN),OPTIONAL :: sort !< if present and \a .TRUE., sort all the sortable dimensions
1849LOGICAL,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)
1850LOGICAL,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
1851LOGICAL,INTENT(IN),OPTIONAL :: lsort_time !< if present and \a .TRUE., sort only time dimension (alternative to \a sort )
1852LOGICAL,INTENT(IN),OPTIONAL :: lsort_timerange !< if present and \a .TRUE., sort only timerange dimension (alternative to \a sort )
1853LOGICAL,INTENT(IN),OPTIONAL :: lsort_level !< if present and \a .TRUE., sort only level dimension (alternative to \a sort )
1854!> se fornito, deve essere un vettore logico della stessa lunghezza di
1855!! this%time indicante quali elementi della dimensione \a time
1856!! mantenere (valori \c .TRUE.) e quali scartare (valori \c .FALSE.)
1857!! nel volume copiato; in alternativa può essere un vettore di
1858!! lunghezza 1, in tal caso, se \c .FALSE. , equivale a scartare tutti
1859!! gli elementi (utile principalmente per le variabili); è compatibile
1860!! col parametro \a miss
1861LOGICAL,INTENT(IN),OPTIONAL :: ltime(:)
1862LOGICAL,INTENT(IN),OPTIONAL :: ltimerange(:) !< come il precedente per la dimensione \a timerange
1863LOGICAL,INTENT(IN),OPTIONAL :: llevel(:) !< come il precedente per la dimensione \a level
1864LOGICAL,INTENT(IN),OPTIONAL :: lana(:) !< come il precedente per la dimensione \a ana
1865LOGICAL,INTENT(IN),OPTIONAL :: lnetwork(:) !< come il precedente per la dimensione \a network
1866!> come il precedente per tutte le possibili dimensioni variabile
1867LOGICAL,INTENT(in),OPTIONAL :: &
1868 lanavarr(:), lanavard(:), lanavari(:), lanavarb(:), lanavarc(:), &
1869 lanaattrr(:), lanaattrd(:), lanaattri(:), lanaattrb(:), lanaattrc(:), &
1870 lanavarattrr(:), lanavarattrd(:), lanavarattri(:), lanavarattrb(:), lanavarattrc(:), &
1871 ldativarr(:), ldativard(:), ldativari(:), ldativarb(:), ldativarc(:), &
1872 ldatiattrr(:), ldatiattrd(:), ldatiattri(:), ldatiattrb(:), ldatiattrc(:), &
1873 ldativarattrr(:), ldativarattrd(:), ldativarattri(:), ldativarattrb(:), ldativarattrc(:)
1874LOGICAL,INTENT(IN),OPTIONAL :: purgeana !< if true remove ana with all data missing
1875
1876TYPE(vol7d) :: v7dtmp
1877logical,allocatable :: llana(:)
1878integer :: i
1879
1880CALL vol7d_copy(this, v7dtmp, sort, unique, miss, &
1881 lsort_time, lsort_timerange, lsort_level, &
1882 ltime, ltimerange, llevel, lana, lnetwork, &
1883 lanavarr, lanavard, lanavari, lanavarb, lanavarc, &
1884 lanaattrr, lanaattrd, lanaattri, lanaattrb, lanaattrc, &
1885 lanavarattrr, lanavarattrd, lanavarattri, lanavarattrb, lanavarattrc, &
1886 ldativarr, ldativard, ldativari, ldativarb, ldativarc, &
1887 ldatiattrr, ldatiattrd, ldatiattri, ldatiattrb, ldatiattrc, &
1888 ldativarattrr, ldativarattrd, ldativarattri, ldativarattrb, ldativarattrc)
1889
1890! destroy old volume
1891CALL delete(this)
1892
1893if (optio_log(purgeana)) then
1894 allocate(llana(size(v7dtmp%ana)))
1895 llana =.false.
1896 do i =1,size(v7dtmp%ana)
1897 if (associated(v7dtmp%voldatii)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatii(i,:,:,:,:,:)))
1898 if (associated(v7dtmp%voldatir)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatir(i,:,:,:,:,:)))
1899 if (associated(v7dtmp%voldatid)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatid(i,:,:,:,:,:)))
1900 if (associated(v7dtmp%voldatib)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatib(i,:,:,:,:,:)))
1901 if (associated(v7dtmp%voldatic)) llana(i)= llana(i) .or. any(c_e(v7dtmp%voldatic(i,:,:,:,:,:)))
1902 end do
1903 CALL vol7d_copy(v7dtmp, this,lana=llana)
1904 CALL delete(v7dtmp)
1905 deallocate(llana)
1906else
1907 this=v7dtmp
1908end if
1909
1910END SUBROUTINE vol7d_reform
1911
1912
1913!> Sorts the sortable dimensions in the volume \a this only when necessary.
1914!! Most of the times, the time, timerange and level dimensions in a
1915!! vol7d object are correctly sorted; on the other side many methods
1916!! strictly rely on this fact in order to work correctly. This method
1917!! performs a quick check and sorts the required dimensions only if
1918!! they are not sorted in ascending order yet, improving safety
1919!! without impairing much performance.
1920SUBROUTINE vol7d_smart_sort(this, lsort_time, lsort_timerange, lsort_level)
1921TYPE(vol7d),INTENT(INOUT) :: this !< object to be sorted
1922LOGICAL,OPTIONAL,INTENT(in) :: lsort_time !< if present and \a .TRUE., sort time dimension if it is not sorted in ascending order
1923LOGICAL,OPTIONAL,INTENT(in) :: lsort_timerange !< if present and \a .TRUE., sort timerange dimension if it is not sorted in ascending order
1924LOGICAL,OPTIONAL,INTENT(in) :: lsort_level !< if present and \a .TRUE., sort vertical level dimension if it is not sorted in ascending order
1925
1926INTEGER :: i
1927LOGICAL :: to_be_sorted
1928
1929to_be_sorted = .false.
1930CALL vol7d_alloc_vol(this) ! usual safety check
1931
1932IF (optio_log(lsort_time)) THEN
1933 DO i = 2, SIZE(this%time)
1934 IF (this%time(i) < this%time(i-1)) THEN
1935 to_be_sorted = .true.
1936 EXIT
1937 ENDIF
1938 ENDDO
1939ENDIF
1940IF (optio_log(lsort_timerange)) THEN
1941 DO i = 2, SIZE(this%timerange)
1942 IF (this%timerange(i) < this%timerange(i-1)) THEN
1943 to_be_sorted = .true.
1944 EXIT
1945 ENDIF
1946 ENDDO
1947ENDIF
1948IF (optio_log(lsort_level)) THEN
1949 DO i = 2, SIZE(this%level)
1950 IF (this%level(i) < this%level(i-1)) THEN
1951 to_be_sorted = .true.
1952 EXIT
1953 ENDIF
1954 ENDDO
1955ENDIF
1956
1957IF (to_be_sorted) CALL vol7d_reform(this, &
1958 lsort_time=lsort_time, lsort_timerange=lsort_timerange, lsort_level=lsort_level )
1959
1960END SUBROUTINE vol7d_smart_sort
1961
1962!> Filter the contents of a volume keeping only desired data.
1963!! This subroutine filters a vol7d object by keeping only a subset of
1964!! the data contained. It can keep only times within a specified
1965!! interval, only station networks contained in a list and only
1966!! specified station or data variables. If a filter parameter is not
1967!! provided, no filtering will take place according to that criterion.
1968!! The volume is reallocated keeping only the desired data.
1969SUBROUTINE vol7d_filter(this, avl, vl, nl, s_d, e_d)
1970TYPE(vol7d),INTENT(inout) :: this !< volume to be filtered
1971CHARACTER(len=*),INTENT(in),OPTIONAL :: avl(:) !< list of station variables to be kept, if not provided or of zero length, all variables are kept
1972CHARACTER(len=*),INTENT(in),OPTIONAL :: vl(:) !< list of data variables to be kept, if not provided or of zero length, all variables are kept
1973TYPE(vol7d_network),OPTIONAL :: nl(:) !< list of station networks to be kept, if not provided or of zero length, all networks are kept
1974TYPE(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
1975TYPE(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
1976
1977INTEGER :: i
1978
1979IF (PRESENT(avl)) THEN
1980 IF (SIZE(avl) > 0) THEN
1981
1982 IF (ASSOCIATED(this%anavar%r)) THEN
1983 DO i = 1, SIZE(this%anavar%r)
1984 IF (all(this%anavar%r(i)%btable /= avl)) this%anavar%r(i) = vol7d_var_miss
1985 ENDDO
1986 ENDIF
1987
1988 IF (ASSOCIATED(this%anavar%i)) THEN
1989 DO i = 1, SIZE(this%anavar%i)
1990 IF (all(this%anavar%i(i)%btable /= avl)) this%anavar%i(i) = vol7d_var_miss
1991 ENDDO
1992 ENDIF
1993
1994 IF (ASSOCIATED(this%anavar%b)) THEN
1995 DO i = 1, SIZE(this%anavar%b)
1996 IF (all(this%anavar%b(i)%btable /= avl)) this%anavar%b(i) = vol7d_var_miss
1997 ENDDO
1998 ENDIF
1999
2000 IF (ASSOCIATED(this%anavar%d)) THEN
2001 DO i = 1, SIZE(this%anavar%d)
2002 IF (all(this%anavar%d(i)%btable /= avl)) this%anavar%d(i) = vol7d_var_miss
2003 ENDDO
2004 ENDIF
2005
2006 IF (ASSOCIATED(this%anavar%c)) THEN
2007 DO i = 1, SIZE(this%anavar%c)
2008 IF (all(this%anavar%c(i)%btable /= avl)) this%anavar%c(i) = vol7d_var_miss
2009 ENDDO
2010 ENDIF
2011
2012 ENDIF
2013ENDIF
2014
2015
2016IF (PRESENT(vl)) THEN
2017 IF (size(vl) > 0) THEN
2018 IF (ASSOCIATED(this%dativar%r)) THEN
2019 DO i = 1, SIZE(this%dativar%r)
2020 IF (all(this%dativar%r(i)%btable /= vl)) this%dativar%r(i) = vol7d_var_miss
2021 ENDDO
2022 ENDIF
2023
2024 IF (ASSOCIATED(this%dativar%i)) THEN
2025 DO i = 1, SIZE(this%dativar%i)
2026 IF (all(this%dativar%i(i)%btable /= vl)) this%dativar%i(i) = vol7d_var_miss
2027 ENDDO
2028 ENDIF
2029
2030 IF (ASSOCIATED(this%dativar%b)) THEN
2031 DO i = 1, SIZE(this%dativar%b)
2032 IF (all(this%dativar%b(i)%btable /= vl)) this%dativar%b(i) = vol7d_var_miss
2033 ENDDO
2034 ENDIF
2035
2036 IF (ASSOCIATED(this%dativar%d)) THEN
2037 DO i = 1, SIZE(this%dativar%d)
2038 IF (all(this%dativar%d(i)%btable /= vl)) this%dativar%d(i) = vol7d_var_miss
2039 ENDDO
2040 ENDIF
2041
2042 IF (ASSOCIATED(this%dativar%c)) THEN
2043 DO i = 1, SIZE(this%dativar%c)
2044 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
2045 ENDDO
2046 ENDIF
2047
2048 IF (ASSOCIATED(this%dativar%c)) THEN
2049 DO i = 1, SIZE(this%dativar%c)
2050 IF (all(this%dativar%c(i)%btable /= vl)) this%dativar%c(i) = vol7d_var_miss
2051 ENDDO
2052 ENDIF
2053
2054 ENDIF
2055ENDIF
2056
2057IF (PRESENT(nl)) THEN
2058 IF (SIZE(nl) > 0) THEN
2059 DO i = 1, SIZE(this%network)
2060 IF (all(this%network(i) /= nl)) this%network(i) = vol7d_network_miss
2061 ENDDO
2062 ENDIF
2063ENDIF
2064
2065IF (PRESENT(s_d)) THEN
2066 IF (c_e(s_d)) THEN
2067 WHERE (this%time < s_d)
2068 this%time = datetime_miss
2069 END WHERE
2070 ENDIF
2071ENDIF
2072
2073IF (PRESENT(e_d)) THEN
2074 IF (c_e(e_d)) THEN
2075 WHERE (this%time > e_d)
2076 this%time = datetime_miss
2077 END WHERE
2078 ENDIF
2079ENDIF
2080
2081CALL vol7d_reform(this, miss=.true.)
2082
2083END SUBROUTINE vol7d_filter
2084
2085
2086!> Metodo per convertire i volumi di dati di un oggetto vol7d in dati
2087!! reali dove possibile. L'oggetto convertito è una copia completa
2088!! dell'originale che può essere quindi distrutto dopo la chiamata.
2089!! Per i dati di anagrafica, al momento sono convertiti solo
2090!! i dati CHARACTER se è passato \a anaconv=.TRUE.
2091!! Gli attributi non sono toccati.
2092SUBROUTINE vol7d_convr(this, that, anaconv)
2093TYPE(vol7d),INTENT(IN) :: this !< oggetto origine
2094TYPE(vol7d),INTENT(INOUT) :: that !< oggetto convertito
2095LOGICAL,OPTIONAL,INTENT(in) :: anaconv !< converti anche anagrafica
2096INTEGER :: i
2097LOGICAL :: fv(1)=(/.false./), tv(1)=(/.true./), acp(1), acn(1)
2098TYPE(vol7d) :: v7d_tmp
2100IF (optio_log(anaconv)) THEN
2101 acp=fv
2102 acn=tv
2103ELSE
2104 acp=tv
2105 acn=fv
2106ENDIF
2107
2108! Volume con solo i dati reali e tutti gli attributi
2109! l'anagrafica e` copiata interamente se necessario
2110CALL vol7d_copy(this, that, &
2111 lanavarr=tv, lanavard=acp, lanavari=acp, lanavarb=acp, lanavarc=acp, &
2112 ldativarr=tv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=fv)
2113
2114! Volume solo di dati double
2115CALL vol7d_copy(this, v7d_tmp, &
2116 lanavarr=fv, lanavard=acn, lanavari=fv, lanavarb=fv, lanavarc=fv, &
2117 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
2118 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
2119 ldativarr=fv, ldativard=tv, ldativari=fv, ldativarb=fv, ldativarc=fv, &
2120 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
2121 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
2122
2123! converto a dati reali
2124IF (ASSOCIATED(v7d_tmp%anavar%d) .OR. ASSOCIATED(v7d_tmp%dativar%d)) THEN
2125
2126 IF (ASSOCIATED(v7d_tmp%anavar%d)) THEN
2127! alloco i dati reali e vi trasferisco i double
2128 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanad, 1), SIZE(v7d_tmp%volanad, 2), &
2129 SIZE(v7d_tmp%volanad, 3)))
2130 DO i = 1, SIZE(v7d_tmp%anavar%d)
2131 v7d_tmp%volanar(:,i,:) = &
2132 realdat(v7d_tmp%volanad(:,i,:), v7d_tmp%anavar%d(i))
2133 ENDDO
2134 DEALLOCATE(v7d_tmp%volanad)
2135! trasferisco le variabili
2136 v7d_tmp%anavar%r => v7d_tmp%anavar%d
2137 NULLIFY(v7d_tmp%anavar%d)
2138 ENDIF
2139
2140 IF (ASSOCIATED(v7d_tmp%dativar%d)) THEN
2141! alloco i dati reali e vi trasferisco i double
2142 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatid, 1), SIZE(v7d_tmp%voldatid, 2), &
2143 SIZE(v7d_tmp%voldatid, 3), SIZE(v7d_tmp%voldatid, 4), SIZE(v7d_tmp%voldatid, 5), &
2144 SIZE(v7d_tmp%voldatid, 6)))
2145 DO i = 1, SIZE(v7d_tmp%dativar%d)
2146 v7d_tmp%voldatir(:,:,:,:,i,:) = &
2147 realdat(v7d_tmp%voldatid(:,:,:,:,i,:), v7d_tmp%dativar%d(i))
2148 ENDDO
2149 DEALLOCATE(v7d_tmp%voldatid)
2150! trasferisco le variabili
2151 v7d_tmp%dativar%r => v7d_tmp%dativar%d
2152 NULLIFY(v7d_tmp%dativar%d)
2153 ENDIF
2154
2155! fondo con il volume definitivo
2156 CALL vol7d_merge(that, v7d_tmp)
2157ELSE
2158 CALL delete(v7d_tmp)
2159ENDIF
2160
2161
2162! Volume solo di dati interi
2163CALL vol7d_copy(this, v7d_tmp, &
2164 lanavarr=fv, lanavard=fv, lanavari=acn, lanavarb=fv, lanavarc=fv, &
2165 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
2166 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
2167 ldativarr=fv, ldativard=fv, ldativari=tv, ldativarb=fv, ldativarc=fv, &
2168 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
2169 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
2170
2171! converto a dati reali
2172IF (ASSOCIATED(v7d_tmp%anavar%i) .OR. ASSOCIATED(v7d_tmp%dativar%i)) THEN
2173
2174 IF (ASSOCIATED(v7d_tmp%anavar%i)) THEN
2175! alloco i dati reali e vi trasferisco gli interi
2176 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanai, 1), SIZE(v7d_tmp%volanai, 2), &
2177 SIZE(v7d_tmp%volanai, 3)))
2178 DO i = 1, SIZE(v7d_tmp%anavar%i)
2179 v7d_tmp%volanar(:,i,:) = &
2180 realdat(v7d_tmp%volanai(:,i,:), v7d_tmp%anavar%i(i))
2181 ENDDO
2182 DEALLOCATE(v7d_tmp%volanai)
2183! trasferisco le variabili
2184 v7d_tmp%anavar%r => v7d_tmp%anavar%i
2185 NULLIFY(v7d_tmp%anavar%i)
2186 ENDIF
2187
2188 IF (ASSOCIATED(v7d_tmp%dativar%i)) THEN
2189! alloco i dati reali e vi trasferisco gli interi
2190 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatii, 1), SIZE(v7d_tmp%voldatii, 2), &
2191 SIZE(v7d_tmp%voldatii, 3), SIZE(v7d_tmp%voldatii, 4), SIZE(v7d_tmp%voldatii, 5), &
2192 SIZE(v7d_tmp%voldatii, 6)))
2193 DO i = 1, SIZE(v7d_tmp%dativar%i)
2194 v7d_tmp%voldatir(:,:,:,:,i,:) = &
2195 realdat(v7d_tmp%voldatii(:,:,:,:,i,:), v7d_tmp%dativar%i(i))
2196 ENDDO
2197 DEALLOCATE(v7d_tmp%voldatii)
2198! trasferisco le variabili
2199 v7d_tmp%dativar%r => v7d_tmp%dativar%i
2200 NULLIFY(v7d_tmp%dativar%i)
2201 ENDIF
2202
2203! fondo con il volume definitivo
2204 CALL vol7d_merge(that, v7d_tmp)
2205ELSE
2206 CALL delete(v7d_tmp)
2207ENDIF
2208
2209
2210! Volume solo di dati byte
2211CALL vol7d_copy(this, v7d_tmp, &
2212 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=acn, lanavarc=fv, &
2213 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
2214 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
2215 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=tv, ldativarc=fv, &
2216 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
2217 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
2218
2219! converto a dati reali
2220IF (ASSOCIATED(v7d_tmp%anavar%b) .OR. ASSOCIATED(v7d_tmp%dativar%b)) THEN
2221
2222 IF (ASSOCIATED(v7d_tmp%anavar%b)) THEN
2223! alloco i dati reali e vi trasferisco i byte
2224 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanab, 1), SIZE(v7d_tmp%volanab, 2), &
2225 SIZE(v7d_tmp%volanab, 3)))
2226 DO i = 1, SIZE(v7d_tmp%anavar%b)
2227 v7d_tmp%volanar(:,i,:) = &
2228 realdat(v7d_tmp%volanab(:,i,:), v7d_tmp%anavar%b(i))
2229 ENDDO
2230 DEALLOCATE(v7d_tmp%volanab)
2231! trasferisco le variabili
2232 v7d_tmp%anavar%r => v7d_tmp%anavar%b
2233 NULLIFY(v7d_tmp%anavar%b)
2234 ENDIF
2235
2236 IF (ASSOCIATED(v7d_tmp%dativar%b)) THEN
2237! alloco i dati reali e vi trasferisco i byte
2238 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatib, 1), SIZE(v7d_tmp%voldatib, 2), &
2239 SIZE(v7d_tmp%voldatib, 3), SIZE(v7d_tmp%voldatib, 4), SIZE(v7d_tmp%voldatib, 5), &
2240 SIZE(v7d_tmp%voldatib, 6)))
2241 DO i = 1, SIZE(v7d_tmp%dativar%b)
2242 v7d_tmp%voldatir(:,:,:,:,i,:) = &
2243 realdat(v7d_tmp%voldatib(:,:,:,:,i,:), v7d_tmp%dativar%b(i))
2244 ENDDO
2245 DEALLOCATE(v7d_tmp%voldatib)
2246! trasferisco le variabili
2247 v7d_tmp%dativar%r => v7d_tmp%dativar%b
2248 NULLIFY(v7d_tmp%dativar%b)
2249 ENDIF
2250
2251! fondo con il volume definitivo
2252 CALL vol7d_merge(that, v7d_tmp)
2253ELSE
2254 CALL delete(v7d_tmp)
2255ENDIF
2256
2257
2258! Volume solo di dati character
2259CALL vol7d_copy(this, v7d_tmp, &
2260 lanavarr=fv, lanavard=fv, lanavari=fv, lanavarb=fv, lanavarc=acn, &
2261 lanaattrr=fv, lanaattrd=fv, lanaattri=fv, lanaattrb=fv, lanaattrc=fv, &
2262 lanavarattrr=fv, lanavarattrd=fv, lanavarattri=fv, lanavarattrb=fv, lanavarattrc=fv, &
2263 ldativarr=fv, ldativard=fv, ldativari=fv, ldativarb=fv, ldativarc=tv, &
2264 ldatiattrr=fv, ldatiattrd=fv, ldatiattri=fv, ldatiattrb=fv, ldatiattrc=fv, &
2265 ldativarattrr=fv, ldativarattrd=fv, ldativarattri=fv, ldativarattrb=fv, ldativarattrc=fv)
2266
2267! converto a dati reali
2268IF (ASSOCIATED(v7d_tmp%anavar%c) .OR. ASSOCIATED(v7d_tmp%dativar%c)) THEN
2269
2270 IF (ASSOCIATED(v7d_tmp%anavar%c)) THEN
2271! alloco i dati reali e vi trasferisco i character
2272 ALLOCATE(v7d_tmp%volanar(SIZE(v7d_tmp%volanac, 1), SIZE(v7d_tmp%volanac, 2), &
2273 SIZE(v7d_tmp%volanac, 3)))
2274 DO i = 1, SIZE(v7d_tmp%anavar%c)
2275 v7d_tmp%volanar(:,i,:) = &
2276 realdat(v7d_tmp%volanac(:,i,:), v7d_tmp%anavar%c(i))
2277 ENDDO
2278 DEALLOCATE(v7d_tmp%volanac)
2279! trasferisco le variabili
2280 v7d_tmp%anavar%r => v7d_tmp%anavar%c
2281 NULLIFY(v7d_tmp%anavar%c)
2282 ENDIF
2283
2284 IF (ASSOCIATED(v7d_tmp%dativar%c)) THEN
2285! alloco i dati reali e vi trasferisco i character
2286 ALLOCATE(v7d_tmp%voldatir(SIZE(v7d_tmp%voldatic, 1), SIZE(v7d_tmp%voldatic, 2), &
2287 SIZE(v7d_tmp%voldatic, 3), SIZE(v7d_tmp%voldatic, 4), SIZE(v7d_tmp%voldatic, 5), &
2288 SIZE(v7d_tmp%voldatic, 6)))
2289 DO i = 1, SIZE(v7d_tmp%dativar%c)
2290 v7d_tmp%voldatir(:,:,:,:,i,:) = &
2291 realdat(v7d_tmp%voldatic(:,:,:,:,i,:), v7d_tmp%dativar%c(i))
2292 ENDDO
2293 DEALLOCATE(v7d_tmp%voldatic)
2294! trasferisco le variabili
2295 v7d_tmp%dativar%r => v7d_tmp%dativar%c
2296 NULLIFY(v7d_tmp%dativar%c)
2297 ENDIF
2298
2299! fondo con il volume definitivo
2300 CALL vol7d_merge(that, v7d_tmp)
2301ELSE
2302 CALL delete(v7d_tmp)
2303ENDIF
2304
2305END SUBROUTINE vol7d_convr
2306
2307
2308!> Metodo per ottenere solo le differenze tra due oggetti vol7d.
2309!! Il primo volume viene confrontato col secondo; nel secondo volume ovunque
2310!! i dati confrontati siano coincidenti viene impostato valore mancante.
2311SUBROUTINE vol7d_diff_only (this, that, data_only,ana)
2312TYPE(vol7d),INTENT(IN) :: this !< primo volume da confrontare
2313TYPE(vol7d),INTENT(OUT) :: that !< secondo volume da confrontare in cui eliminare i dati coincidenti
2314logical , optional, intent(in) :: data_only !< attiva l'elaborazione dei soli dati e non dell'anagrafica (default: .false.)
2315logical , optional, intent(in) :: ana !< attiva l'elaborazione dell'anagrafica (coordinate e ident) (default: .false.)
2316logical :: ldata_only,lana
2317
2318IF (PRESENT(data_only)) THEN
2319 ldata_only = data_only
2320ELSE
2321 ldata_only = .false.
2322ENDIF
2323
2324IF (PRESENT(ana)) THEN
2325 lana = ana
2326ELSE
2327 lana = .false.
2328ENDIF
2329
2330
2331#undef VOL7D_POLY_ARRAY
2332#define VOL7D_POLY_ARRAY voldati
2333#include "vol7d_class_diff.F90"
2334#undef VOL7D_POLY_ARRAY
2335#define VOL7D_POLY_ARRAY voldatiattr
2336#include "vol7d_class_diff.F90"
2337#undef VOL7D_POLY_ARRAY
2338
2339if ( .not. ldata_only) then
2340
2341#define VOL7D_POLY_ARRAY volana
2342#include "vol7d_class_diff.F90"
2343#undef VOL7D_POLY_ARRAY
2344#define VOL7D_POLY_ARRAY volanaattr
2345#include "vol7d_class_diff.F90"
2346#undef VOL7D_POLY_ARRAY
2347
2348 if(lana)then
2349 where ( this%ana == that%ana )
2350 that%ana = vol7d_ana_miss
2351 end where
2352 end if
2353
2354end if
2355
2356
2357
2358END SUBROUTINE vol7d_diff_only
2359
2360
2361
2362! Creo le routine da ripetere per i vari tipi di dati di v7d
2363! tramite un template e il preprocessore
2364#undef VOL7D_POLY_TYPE
2365#undef VOL7D_POLY_TYPES
2366#define VOL7D_POLY_TYPE REAL
2367#define VOL7D_POLY_TYPES r
2368#include "vol7d_class_type_templ.F90"
2369#undef VOL7D_POLY_TYPE
2370#undef VOL7D_POLY_TYPES
2371#define VOL7D_POLY_TYPE DOUBLE PRECISION
2372#define VOL7D_POLY_TYPES d
2373#include "vol7d_class_type_templ.F90"
2374#undef VOL7D_POLY_TYPE
2375#undef VOL7D_POLY_TYPES
2376#define VOL7D_POLY_TYPE INTEGER
2377#define VOL7D_POLY_TYPES i
2378#include "vol7d_class_type_templ.F90"
2379#undef VOL7D_POLY_TYPE
2380#undef VOL7D_POLY_TYPES
2381#define VOL7D_POLY_TYPE INTEGER(kind=int_b)
2382#define VOL7D_POLY_TYPES b
2383#include "vol7d_class_type_templ.F90"
2384#undef VOL7D_POLY_TYPE
2385#undef VOL7D_POLY_TYPES
2386#define VOL7D_POLY_TYPE CHARACTER(len=vol7d_cdatalen)
2387#define VOL7D_POLY_TYPES c
2388#include "vol7d_class_type_templ.F90"
2389
2390! Creo le routine da ripetere per i vari descrittori di dimensioni di v7d
2391! tramite un template e il preprocessore
2392#define VOL7D_SORT
2393#undef VOL7D_NO_ZERO_ALLOC
2394#undef VOL7D_POLY_TYPE
2395#define VOL7D_POLY_TYPE datetime
2396#include "vol7d_class_desc_templ.F90"
2397#undef VOL7D_POLY_TYPE
2398#define VOL7D_POLY_TYPE vol7d_timerange
2399#include "vol7d_class_desc_templ.F90"
2400#undef VOL7D_POLY_TYPE
2401#define VOL7D_POLY_TYPE vol7d_level
2402#include "vol7d_class_desc_templ.F90"
2403#undef VOL7D_SORT
2404#undef VOL7D_POLY_TYPE
2405#define VOL7D_POLY_TYPE vol7d_network
2406#include "vol7d_class_desc_templ.F90"
2407#undef VOL7D_POLY_TYPE
2408#define VOL7D_POLY_TYPE vol7d_ana
2409#include "vol7d_class_desc_templ.F90"
2410#define VOL7D_NO_ZERO_ALLOC
2411#undef VOL7D_POLY_TYPE
2412#define VOL7D_POLY_TYPE vol7d_var
2413#include "vol7d_class_desc_templ.F90"
2414
2415!>\brief Scrittura su file di un volume Vol7d.
2416!! Scrittura su file unformatted di un intero volume Vol7d.
2417!! Il volume viene serializzato e scritto su file.
2418!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
2419!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
2420!! tali parametri saranno in output.
2421!! Se non viene fornito il nome file viene utilizzato un file di default con nome pari al nome del programma in
2422!! esecuzione con postfisso ".v7d".
2423!! Come parametro opzionale c'è la description che insieme alla data corrente viene inserita nell'header del file.
2424subroutine vol7d_write_on_file (this,unit,description,filename,filename_auto)
2425
2426TYPE(vol7d),INTENT(IN) :: this !< volume vol7d da scrivere
2427integer,optional,intent(inout) :: unit !< unità su cui scrivere; se passata =0 ritorna il valore rielaborato (default =rielaborato internamente con getlun )
2428character(len=*),intent(in),optional :: filename !< nome del file su cui scrivere
2429character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
2430character(len=*),INTENT(IN),optional :: description !< descrizione del volume
2431
2432integer :: lunit
2433character(len=254) :: ldescription,arg,lfilename
2434integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
2435 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
2436 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
2437 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
2438 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
2439 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
2440 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
2441!integer :: im,id,iy
2442integer :: tarray(8)
2443logical :: opened,exist
2444
2445 nana=0
2446 ntime=0
2447 ntimerange=0
2448 nlevel=0
2449 nnetwork=0
2450 ndativarr=0
2451 ndativari=0
2452 ndativarb=0
2453 ndativard=0
2454 ndativarc=0
2455 ndatiattrr=0
2456 ndatiattri=0
2457 ndatiattrb=0
2458 ndatiattrd=0
2459 ndatiattrc=0
2460 ndativarattrr=0
2461 ndativarattri=0
2462 ndativarattrb=0
2463 ndativarattrd=0
2464 ndativarattrc=0
2465 nanavarr=0
2466 nanavari=0
2467 nanavarb=0
2468 nanavard=0
2469 nanavarc=0
2470 nanaattrr=0
2471 nanaattri=0
2472 nanaattrb=0
2473 nanaattrd=0
2474 nanaattrc=0
2475 nanavarattrr=0
2476 nanavarattri=0
2477 nanavarattrb=0
2478 nanavarattrd=0
2479 nanavarattrc=0
2480
2481
2482!call idate(im,id,iy)
2483call date_and_time(values=tarray)
2484call getarg(0,arg)
2485
2486if (present(description))then
2487 ldescription=description
2488else
2489 ldescription="Vol7d generated by: "//trim(arg)
2490end if
2491
2492if (.not. present(unit))then
2493 lunit=getunit()
2494else
2495 if (unit==0)then
2496 lunit=getunit()
2497 unit=lunit
2498 else
2499 lunit=unit
2500 end if
2501end if
2502
2503lfilename=trim(arg)//".v7d"
2504if (index(arg,'/',back=.true.) > 0) lfilename=lfilename(index(arg,'/',back=.true.)+1 : )
2505
2506if (present(filename))then
2507 if (filename /= "")then
2508 lfilename=filename
2509 end if
2510end if
2511
2512if (present(filename_auto))filename_auto=lfilename
2513
2514
2515inquire(unit=lunit,opened=opened)
2516if (.not. opened) then
2517! inquire(file=lfilename, EXIST=exist)
2518! IF (exist) THEN
2519! CALL l4f_log(L4F_FATAL, &
2520! 'in vol7d_write_on_file, file exists, cannot open file '//TRIM(lfilename))
2521! CALL raise_fatal_error()
2522! ENDIF
2523 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM')
2524 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
2525end if
2526
2527if (associated(this%ana)) nana=size(this%ana)
2528if (associated(this%time)) ntime=size(this%time)
2529if (associated(this%timerange)) ntimerange=size(this%timerange)
2530if (associated(this%level)) nlevel=size(this%level)
2531if (associated(this%network)) nnetwork=size(this%network)
2532
2533if (associated(this%dativar%r)) ndativarr=size(this%dativar%r)
2534if (associated(this%dativar%i)) ndativari=size(this%dativar%i)
2535if (associated(this%dativar%b)) ndativarb=size(this%dativar%b)
2536if (associated(this%dativar%d)) ndativard=size(this%dativar%d)
2537if (associated(this%dativar%c)) ndativarc=size(this%dativar%c)
2538
2539if (associated(this%datiattr%r)) ndatiattrr=size(this%datiattr%r)
2540if (associated(this%datiattr%i)) ndatiattri=size(this%datiattr%i)
2541if (associated(this%datiattr%b)) ndatiattrb=size(this%datiattr%b)
2542if (associated(this%datiattr%d)) ndatiattrd=size(this%datiattr%d)
2543if (associated(this%datiattr%c)) ndatiattrc=size(this%datiattr%c)
2544
2545if (associated(this%dativarattr%r)) ndativarattrr=size(this%dativarattr%r)
2546if (associated(this%dativarattr%i)) ndativarattri=size(this%dativarattr%i)
2547if (associated(this%dativarattr%b)) ndativarattrb=size(this%dativarattr%b)
2548if (associated(this%dativarattr%d)) ndativarattrd=size(this%dativarattr%d)
2549if (associated(this%dativarattr%c)) ndativarattrc=size(this%dativarattr%c)
2550
2551if (associated(this%anavar%r)) nanavarr=size(this%anavar%r)
2552if (associated(this%anavar%i)) nanavari=size(this%anavar%i)
2553if (associated(this%anavar%b)) nanavarb=size(this%anavar%b)
2554if (associated(this%anavar%d)) nanavard=size(this%anavar%d)
2555if (associated(this%anavar%c)) nanavarc=size(this%anavar%c)
2556
2557if (associated(this%anaattr%r)) nanaattrr=size(this%anaattr%r)
2558if (associated(this%anaattr%i)) nanaattri=size(this%anaattr%i)
2559if (associated(this%anaattr%b)) nanaattrb=size(this%anaattr%b)
2560if (associated(this%anaattr%d)) nanaattrd=size(this%anaattr%d)
2561if (associated(this%anaattr%c)) nanaattrc=size(this%anaattr%c)
2562
2563if (associated(this%anavarattr%r)) nanavarattrr=size(this%anavarattr%r)
2564if (associated(this%anavarattr%i)) nanavarattri=size(this%anavarattr%i)
2565if (associated(this%anavarattr%b)) nanavarattrb=size(this%anavarattr%b)
2566if (associated(this%anavarattr%d)) nanavarattrd=size(this%anavarattr%d)
2567if (associated(this%anavarattr%c)) nanavarattrc=size(this%anavarattr%c)
2568
2569write(unit=lunit)ldescription
2570write(unit=lunit)tarray
2571
2572write(unit=lunit)&
2573 nana, ntime, ntimerange, nlevel, nnetwork, &
2574 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
2575 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
2576 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
2577 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
2578 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
2579 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
2580 this%time_definition
2581
2582
2583!write(unit=lunit)this
2584
2585
2586!! prime 5 dimensioni
2587if (associated(this%ana)) call write_unit(this%ana, lunit)
2588if (associated(this%time)) call write_unit(this%time, lunit)
2589if (associated(this%level)) write(unit=lunit)this%level
2590if (associated(this%timerange)) write(unit=lunit)this%timerange
2591if (associated(this%network)) write(unit=lunit)this%network
2592
2593 !! 6a dimensione: variabile dell'anagrafica e dei dati
2594 !! con relativi attributi e in 5 tipi diversi
2595
2596if (associated(this%anavar%r)) write(unit=lunit)this%anavar%r
2597if (associated(this%anavar%i)) write(unit=lunit)this%anavar%i
2598if (associated(this%anavar%b)) write(unit=lunit)this%anavar%b
2599if (associated(this%anavar%d)) write(unit=lunit)this%anavar%d
2600if (associated(this%anavar%c)) write(unit=lunit)this%anavar%c
2601
2602if (associated(this%anaattr%r)) write(unit=lunit)this%anaattr%r
2603if (associated(this%anaattr%i)) write(unit=lunit)this%anaattr%i
2604if (associated(this%anaattr%b)) write(unit=lunit)this%anaattr%b
2605if (associated(this%anaattr%d)) write(unit=lunit)this%anaattr%d
2606if (associated(this%anaattr%c)) write(unit=lunit)this%anaattr%c
2607
2608if (associated(this%anavarattr%r)) write(unit=lunit)this%anavarattr%r
2609if (associated(this%anavarattr%i)) write(unit=lunit)this%anavarattr%i
2610if (associated(this%anavarattr%b)) write(unit=lunit)this%anavarattr%b
2611if (associated(this%anavarattr%d)) write(unit=lunit)this%anavarattr%d
2612if (associated(this%anavarattr%c)) write(unit=lunit)this%anavarattr%c
2613
2614if (associated(this%dativar%r)) write(unit=lunit)this%dativar%r
2615if (associated(this%dativar%i)) write(unit=lunit)this%dativar%i
2616if (associated(this%dativar%b)) write(unit=lunit)this%dativar%b
2617if (associated(this%dativar%d)) write(unit=lunit)this%dativar%d
2618if (associated(this%dativar%c)) write(unit=lunit)this%dativar%c
2619
2620if (associated(this%datiattr%r)) write(unit=lunit)this%datiattr%r
2621if (associated(this%datiattr%i)) write(unit=lunit)this%datiattr%i
2622if (associated(this%datiattr%b)) write(unit=lunit)this%datiattr%b
2623if (associated(this%datiattr%d)) write(unit=lunit)this%datiattr%d
2624if (associated(this%datiattr%c)) write(unit=lunit)this%datiattr%c
2625
2626if (associated(this%dativarattr%r)) write(unit=lunit)this%dativarattr%r
2627if (associated(this%dativarattr%i)) write(unit=lunit)this%dativarattr%i
2628if (associated(this%dativarattr%b)) write(unit=lunit)this%dativarattr%b
2629if (associated(this%dativarattr%d)) write(unit=lunit)this%dativarattr%d
2630if (associated(this%dativarattr%c)) write(unit=lunit)this%dativarattr%c
2631
2632!! Volumi di valori e attributi per anagrafica e dati
2633
2634if (associated(this%volanar)) write(unit=lunit)this%volanar
2635if (associated(this%volanaattrr)) write(unit=lunit)this%volanaattrr
2636if (associated(this%voldatir)) write(unit=lunit)this%voldatir
2637if (associated(this%voldatiattrr)) write(unit=lunit)this%voldatiattrr
2638
2639if (associated(this%volanai)) write(unit=lunit)this%volanai
2640if (associated(this%volanaattri)) write(unit=lunit)this%volanaattri
2641if (associated(this%voldatii)) write(unit=lunit)this%voldatii
2642if (associated(this%voldatiattri)) write(unit=lunit)this%voldatiattri
2643
2644if (associated(this%volanab)) write(unit=lunit)this%volanab
2645if (associated(this%volanaattrb)) write(unit=lunit)this%volanaattrb
2646if (associated(this%voldatib)) write(unit=lunit)this%voldatib
2647if (associated(this%voldatiattrb)) write(unit=lunit)this%voldatiattrb
2648
2649if (associated(this%volanad)) write(unit=lunit)this%volanad
2650if (associated(this%volanaattrd)) write(unit=lunit)this%volanaattrd
2651if (associated(this%voldatid)) write(unit=lunit)this%voldatid
2652if (associated(this%voldatiattrd)) write(unit=lunit)this%voldatiattrd
2653
2654if (associated(this%volanac)) write(unit=lunit)this%volanac
2655if (associated(this%volanaattrc)) write(unit=lunit)this%volanaattrc
2656if (associated(this%voldatic)) write(unit=lunit)this%voldatic
2657if (associated(this%voldatiattrc)) write(unit=lunit)this%voldatiattrc
2658
2659if (.not. present(unit)) close(unit=lunit)
2660
2661end subroutine vol7d_write_on_file
2662
2663
2664!>\brief Lettura da file di un volume Vol7d.
2665!! Lettura da file unformatted di un intero volume Vol7d.
2666!! Questa subroutine comprende vol7d_alloc e vol7d_alloc_vol.
2667!! Il file puo' essere aperto opzionalmente dall'utente. Si possono passare
2668!! opzionalmente unità e nome del file altrimenti assegnati internamente a dei default; se assegnati internamente
2669!! tali parametri saranno in output.
2670
2671
2672subroutine vol7d_read_from_file (this,unit,filename,description,tarray,filename_auto)
2673
2674TYPE(vol7d),INTENT(OUT) :: this !< Volume vol7d da leggere
2675integer,intent(inout),optional :: unit !< unità su cui è stato aperto un file; se =0 rielaborato internamente (default = elaborato internamente con getunit)
2676character(len=*),INTENT(in),optional :: filename !< nome del file eventualmente da aprire (default = (nome dell'eseguibile)//.v7d )
2677character(len=*),intent(out),optional :: filename_auto !< nome del file generato se "filename" è omesso
2678character(len=*),INTENT(out),optional :: description !< descrizione del volume letto
2679integer,intent(out),optional :: tarray(8) !< vettore come definito da "date_and_time" della data di scrittura del volume
2680
2681
2682integer :: nana, ntime, ntimerange, nlevel, nnetwork, &
2683 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
2684 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
2685 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
2686 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
2687 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
2688 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc
2689
2690character(len=254) :: ldescription,lfilename,arg
2691integer :: ltarray(8),lunit,ios
2692logical :: opened,exist
2693
2694
2695call getarg(0,arg)
2696
2697if (.not. present(unit))then
2698 lunit=getunit()
2699else
2700 if (unit==0)then
2701 lunit=getunit()
2702 unit=lunit
2703 else
2704 lunit=unit
2705 end if
2706end if
2707
2708lfilename=trim(arg)//".v7d"
2709if (index(arg,'/',back=.true.) > 0) lfilename=lfilename(index(arg,'/',back=.true.)+1 : )
2710
2711if (present(filename))then
2712 if (filename /= "")then
2713 lfilename=filename
2714 end if
2715end if
2716
2717if (present(filename_auto))filename_auto=lfilename
2718
2719
2720inquire(unit=lunit,opened=opened)
2721IF (.NOT. opened) THEN
2722 inquire(file=lfilename,exist=exist)
2723 IF (.NOT.exist) THEN
2724 CALL l4f_log(l4f_fatal, &
2725 'in vol7d_read_from_file, file does not exists, cannot open')
2726 CALL raise_fatal_error()
2727 ENDIF
2728 OPEN(unit=lunit, file=lfilename, form='UNFORMATTED', access='STREAM', &
2729 status='OLD', action='READ')
2730 CALL l4f_log(l4f_info, 'opened: '//trim(lfilename))
2731end if
2732
2733
2734call init(this)
2735read(unit=lunit,iostat=ios)ldescription
2736
2737if (ios < 0) then ! A negative value indicates that the End of File or End of Record
2738 call vol7d_alloc (this)
2739 call vol7d_alloc_vol (this)
2740 if (present(description))description=ldescription
2741 if (present(tarray))tarray=ltarray
2742 if (.not. present(unit)) close(unit=lunit)
2743end if
2744
2745read(unit=lunit)ltarray
2746
2747CALL l4f_log(l4f_info, 'Reading vol7d from file')
2748CALL l4f_log(l4f_info, 'description: '//trim(ldescription))
2749CALL l4f_log(l4f_info, 'written on '//trim(to_char(ltarray(1)))//' '// &
2750 trim(to_char(ltarray(2)))//' '//trim(to_char(ltarray(3))))
2751
2752if (present(description))description=ldescription
2753if (present(tarray))tarray=ltarray
2754
2755read(unit=lunit)&
2756 nana, ntime, ntimerange, nlevel, nnetwork, &
2757 ndativarr, ndativari, ndativarb, ndativard, ndativarc,&
2758 ndatiattrr, ndatiattri, ndatiattrb, ndatiattrd, ndatiattrc,&
2759 ndativarattrr, ndativarattri, ndativarattrb, ndativarattrd, ndativarattrc,&
2760 nanavarr, nanavari, nanavarb, nanavard, nanavarc,&
2761 nanaattrr, nanaattri, nanaattrb, nanaattrd, nanaattrc,&
2762 nanavarattrr, nanavarattri, nanavarattrb, nanavarattrd, nanavarattrc, &
2763 this%time_definition
2764
2765call vol7d_alloc (this, &
2766 nana=nana, ntime=ntime, ntimerange=ntimerange, nlevel=nlevel, nnetwork=nnetwork,&
2767 ndativarr=ndativarr, ndativari=ndativari, ndativarb=ndativarb,&
2768 ndativard=ndativard, ndativarc=ndativarc,&
2769 ndatiattrr=ndatiattrr, ndatiattri=ndatiattri, ndatiattrb=ndatiattrb,&
2770 ndatiattrd=ndatiattrd, ndatiattrc=ndatiattrc,&
2771 ndativarattrr=ndativarattrr, ndativarattri=ndativarattri, ndativarattrb=ndativarattrb, &
2772 ndativarattrd=ndativarattrd, ndativarattrc=ndativarattrc,&
2773 nanavarr=nanavarr, nanavari=nanavari, nanavarb=nanavarb, &
2774 nanavard=nanavard, nanavarc=nanavarc,&
2775 nanaattrr=nanaattrr, nanaattri=nanaattri, nanaattrb=nanaattrb,&
2776 nanaattrd=nanaattrd, nanaattrc=nanaattrc,&
2777 nanavarattrr=nanavarattrr, nanavarattri=nanavarattri, nanavarattrb=nanavarattrb, &
2778 nanavarattrd=nanavarattrd, nanavarattrc=nanavarattrc)
2779
2780
2781if (associated(this%ana)) call read_unit(this%ana, lunit)
2782if (associated(this%time)) call read_unit(this%time, lunit)
2783if (associated(this%level)) read(unit=lunit)this%level
2784if (associated(this%timerange)) read(unit=lunit)this%timerange
2785if (associated(this%network)) read(unit=lunit)this%network
2786
2787if (associated(this%anavar%r)) read(unit=lunit)this%anavar%r
2788if (associated(this%anavar%i)) read(unit=lunit)this%anavar%i
2789if (associated(this%anavar%b)) read(unit=lunit)this%anavar%b
2790if (associated(this%anavar%d)) read(unit=lunit)this%anavar%d
2791if (associated(this%anavar%c)) read(unit=lunit)this%anavar%c
2792
2793if (associated(this%anaattr%r)) read(unit=lunit)this%anaattr%r
2794if (associated(this%anaattr%i)) read(unit=lunit)this%anaattr%i
2795if (associated(this%anaattr%b)) read(unit=lunit)this%anaattr%b
2796if (associated(this%anaattr%d)) read(unit=lunit)this%anaattr%d
2797if (associated(this%anaattr%c)) read(unit=lunit)this%anaattr%c
2798
2799if (associated(this%anavarattr%r)) read(unit=lunit)this%anavarattr%r
2800if (associated(this%anavarattr%i)) read(unit=lunit)this%anavarattr%i
2801if (associated(this%anavarattr%b)) read(unit=lunit)this%anavarattr%b
2802if (associated(this%anavarattr%d)) read(unit=lunit)this%anavarattr%d
2803if (associated(this%anavarattr%c)) read(unit=lunit)this%anavarattr%c
2804
2805if (associated(this%dativar%r)) read(unit=lunit)this%dativar%r
2806if (associated(this%dativar%i)) read(unit=lunit)this%dativar%i
2807if (associated(this%dativar%b)) read(unit=lunit)this%dativar%b
2808if (associated(this%dativar%d)) read(unit=lunit)this%dativar%d
2809if (associated(this%dativar%c)) read(unit=lunit)this%dativar%c
2810
2811if (associated(this%datiattr%r)) read(unit=lunit)this%datiattr%r
2812if (associated(this%datiattr%i)) read(unit=lunit)this%datiattr%i
2813if (associated(this%datiattr%b)) read(unit=lunit)this%datiattr%b
2814if (associated(this%datiattr%d)) read(unit=lunit)this%datiattr%d
2815if (associated(this%datiattr%c)) read(unit=lunit)this%datiattr%c
2816
2817if (associated(this%dativarattr%r)) read(unit=lunit)this%dativarattr%r
2818if (associated(this%dativarattr%i)) read(unit=lunit)this%dativarattr%i
2819if (associated(this%dativarattr%b)) read(unit=lunit)this%dativarattr%b
2820if (associated(this%dativarattr%d)) read(unit=lunit)this%dativarattr%d
2821if (associated(this%dativarattr%c)) read(unit=lunit)this%dativarattr%c
2822
2823call vol7d_alloc_vol (this)
2824
2825!! Volumi di valori e attributi per anagrafica e dati
2826
2827if (associated(this%volanar)) read(unit=lunit)this%volanar
2828if (associated(this%volanaattrr)) read(unit=lunit)this%volanaattrr
2829if (associated(this%voldatir)) read(unit=lunit)this%voldatir
2830if (associated(this%voldatiattrr)) read(unit=lunit)this%voldatiattrr
2831
2832if (associated(this%volanai)) read(unit=lunit)this%volanai
2833if (associated(this%volanaattri)) read(unit=lunit)this%volanaattri
2834if (associated(this%voldatii)) read(unit=lunit)this%voldatii
2835if (associated(this%voldatiattri)) read(unit=lunit)this%voldatiattri
2836
2837if (associated(this%volanab)) read(unit=lunit)this%volanab
2838if (associated(this%volanaattrb)) read(unit=lunit)this%volanaattrb
2839if (associated(this%voldatib)) read(unit=lunit)this%voldatib
2840if (associated(this%voldatiattrb)) read(unit=lunit)this%voldatiattrb
2841
2842if (associated(this%volanad)) read(unit=lunit)this%volanad
2843if (associated(this%volanaattrd)) read(unit=lunit)this%volanaattrd
2844if (associated(this%voldatid)) read(unit=lunit)this%voldatid
2845if (associated(this%voldatiattrd)) read(unit=lunit)this%voldatiattrd
2846
2847if (associated(this%volanac)) read(unit=lunit)this%volanac
2848if (associated(this%volanaattrc)) read(unit=lunit)this%volanaattrc
2849if (associated(this%voldatic)) read(unit=lunit)this%voldatic
2850if (associated(this%voldatiattrc)) read(unit=lunit)this%voldatiattrc
2851
2852if (.not. present(unit)) close(unit=lunit)
2853
2854end subroutine vol7d_read_from_file
2855
2856
2857! to double precision
2858elemental doubleprecision function doubledatd(voldat,var)
2859doubleprecision,intent(in) :: voldat
2860type(vol7d_var),intent(in) :: var
2861
2862doubledatd=voldat
2863
2864end function doubledatd
2865
2866
2867elemental doubleprecision function doubledatr(voldat,var)
2868real,intent(in) :: voldat
2869type(vol7d_var),intent(in) :: var
2870
2871if (c_e(voldat))then
2872 doubledatr=dble(voldat)
2873else
2874 doubledatr=dmiss
2875end if
2876
2877end function doubledatr
2878
2879
2880elemental doubleprecision function doubledati(voldat,var)
2881integer,intent(in) :: voldat
2882type(vol7d_var),intent(in) :: var
2883
2884if (c_e(voldat)) then
2885 if (c_e(var%scalefactor))then
2886 doubledati=dble(voldat)/10.d0**var%scalefactor
2887 else
2888 doubledati=dble(voldat)
2889 endif
2890else
2891 doubledati=dmiss
2892end if
2893
2894end function doubledati
2895
2896
2897elemental doubleprecision function doubledatb(voldat,var)
2898integer(kind=int_b),intent(in) :: voldat
2899type(vol7d_var),intent(in) :: var
2900
2901if (c_e(voldat)) then
2902 if (c_e(var%scalefactor))then
2903 doubledatb=dble(voldat)/10.d0**var%scalefactor
2904 else
2905 doubledatb=dble(voldat)
2906 endif
2907else
2908 doubledatb=dmiss
2909end if
2910
2911end function doubledatb
2912
2913
2914elemental doubleprecision function doubledatc(voldat,var)
2915CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
2916type(vol7d_var),intent(in) :: var
2917
2918doubledatc = c2d(voldat)
2919if (c_e(doubledatc) .and. c_e(var%scalefactor))then
2920 doubledatc=doubledatc/10.d0**var%scalefactor
2921end if
2922
2923end function doubledatc
2924
2925
2926! to integer
2927elemental integer function integerdatd(voldat,var)
2928doubleprecision,intent(in) :: voldat
2929type(vol7d_var),intent(in) :: var
2930
2931if (c_e(voldat))then
2932 if (c_e(var%scalefactor)) then
2933 integerdatd=nint(voldat*10d0**var%scalefactor)
2934 else
2935 integerdatd=nint(voldat)
2936 endif
2937else
2938 integerdatd=imiss
2939end if
2940
2941end function integerdatd
2942
2943
2944elemental integer function integerdatr(voldat,var)
2945real,intent(in) :: voldat
2946type(vol7d_var),intent(in) :: var
2947
2948if (c_e(voldat))then
2949 if (c_e(var%scalefactor)) then
2950 integerdatr=nint(voldat*10d0**var%scalefactor)
2951 else
2952 integerdatr=nint(voldat)
2953 endif
2954else
2955 integerdatr=imiss
2956end if
2957
2958end function integerdatr
2959
2960
2961elemental integer function integerdati(voldat,var)
2962integer,intent(in) :: voldat
2963type(vol7d_var),intent(in) :: var
2964
2965integerdati=voldat
2966
2967end function integerdati
2968
2969
2970elemental integer function integerdatb(voldat,var)
2971integer(kind=int_b),intent(in) :: voldat
2972type(vol7d_var),intent(in) :: var
2973
2974if (c_e(voldat))then
2975 integerdatb=voldat
2976else
2977 integerdatb=imiss
2978end if
2979
2980end function integerdatb
2981
2982
2983elemental integer function integerdatc(voldat,var)
2984CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
2985type(vol7d_var),intent(in) :: var
2986
2987integerdatc=c2i(voldat)
2988
2989end function integerdatc
2990
2991
2992! to real
2993elemental real function realdatd(voldat,var)
2994doubleprecision,intent(in) :: voldat
2995type(vol7d_var),intent(in) :: var
2996
2997if (c_e(voldat))then
2998 realdatd=real(voldat)
2999else
3000 realdatd=rmiss
3001end if
3002
3003end function realdatd
3004
3005
3006elemental real function realdatr(voldat,var)
3007real,intent(in) :: voldat
3008type(vol7d_var),intent(in) :: var
3009
3010realdatr=voldat
3011
3012end function realdatr
3013
3014
3015elemental real function realdati(voldat,var)
3016integer,intent(in) :: voldat
3017type(vol7d_var),intent(in) :: var
3018
3019if (c_e(voldat)) then
3020 if (c_e(var%scalefactor))then
3021 realdati=float(voldat)/10.**var%scalefactor
3022 else
3023 realdati=float(voldat)
3024 endif
3025else
3026 realdati=rmiss
3027end if
3028
3029end function realdati
3030
3031
3032elemental real function realdatb(voldat,var)
3033integer(kind=int_b),intent(in) :: voldat
3034type(vol7d_var),intent(in) :: var
3035
3036if (c_e(voldat)) then
3037 if (c_e(var%scalefactor))then
3038 realdatb=float(voldat)/10**var%scalefactor
3039 else
3040 realdatb=float(voldat)
3041 endif
3042else
3043 realdatb=rmiss
3044end if
3045
3046end function realdatb
3047
3048
3049elemental real function realdatc(voldat,var)
3050CHARACTER(len=vol7d_cdatalen),intent(in) :: voldat
3051type(vol7d_var),intent(in) :: var
3052
3053realdatc=c2r(voldat)
3054if (c_e(realdatc) .and. c_e(var%scalefactor))then
3055 realdatc=realdatc/10.**var%scalefactor
3056end if
3057
3058end function realdatc
3059
3060
3061!> Return an ana volume of a requested variable as real data.
3062!! It returns a 2-d array of the proper shape (ana x network) for the
3063!! ana variable requested, converted to real type. If the conversion
3064!! fails or if the variable is not contained in the ana volume,
3065!! missing data are returned.
3066FUNCTION realanavol(this, var) RESULT(vol)
3067TYPE(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
3068TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
3069REAL :: vol(SIZE(this%ana),size(this%network))
3070
3071CHARACTER(len=1) :: dtype
3072INTEGER :: indvar
3073
3074dtype = cmiss
3075indvar = index(this%anavar, var, type=dtype)
3076
3077IF (indvar > 0) THEN
3078 SELECT CASE (dtype)
3079 CASE("d")
3080 vol = realdat(this%volanad(:,indvar,:), var)
3081 CASE("r")
3082 vol = this%volanar(:,indvar,:)
3083 CASE("i")
3084 vol = realdat(this%volanai(:,indvar,:), var)
3085 CASE("b")
3086 vol = realdat(this%volanab(:,indvar,:), var)
3087 CASE("c")
3088 vol = realdat(this%volanac(:,indvar,:), var)
3089 CASE default
3090 vol = rmiss
3091 END SELECT
3092ELSE
3093 vol = rmiss
3094ENDIF
3095
3096END FUNCTION realanavol
3097
3098
3099!> Return an ana volume of a requested variable as integer data.
3100!! It returns a 2-d array of the proper shape (ana x network) for the
3101!! ana variable requested, converted to integer type. If the conversion
3102!! fails or if the variable is not contained in the ana volume,
3103!! missing data are returned.
3104FUNCTION integeranavol(this, var) RESULT(vol)
3105TYPE(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
3106TYPE(vol7d_var),INTENT(in) :: var !< the ana variable to be returned
3107INTEGER :: vol(SIZE(this%ana),size(this%network))
3108
3109CHARACTER(len=1) :: dtype
3110INTEGER :: indvar
3111
3112dtype = cmiss
3113indvar = index(this%anavar, var, type=dtype)
3114
3115IF (indvar > 0) THEN
3116 SELECT CASE (dtype)
3117 CASE("d")
3118 vol = integerdat(this%volanad(:,indvar,:), var)
3119 CASE("r")
3120 vol = integerdat(this%volanar(:,indvar,:), var)
3121 CASE("i")
3122 vol = this%volanai(:,indvar,:)
3123 CASE("b")
3124 vol = integerdat(this%volanab(:,indvar,:), var)
3125 CASE("c")
3126 vol = integerdat(this%volanac(:,indvar,:), var)
3127 CASE default
3128 vol = imiss
3129 END SELECT
3130ELSE
3131 vol = imiss
3132ENDIF
3133
3134END FUNCTION integeranavol
3135
3136
3137!> Move data for all variables from one coordinate in the character volume to other.
3138!! Only not missing data will be copyed and all attributes will be moved together.
3139!! Usefull to colapse data spread in more indices (level or time or ....).
3140!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
3141!! to obtain a new vol7d with less data shape.
3142subroutine move_datac (v7d,&
3143 indana,indtime,indlevel,indtimerange,indnetwork,&
3144 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
3145
3146TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
3147
3148integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
3149integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
3150integer :: inddativar,inddativarattr
3151
3152
3153do inddativar=1,size(v7d%dativar%c)
3154
3155 if (c_e(v7d%voldatic(indana,indtime,indlevel,indtimerange,inddativar,indnetwork)) .and. &
3156 .not. c_e(v7d%voldatic(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
3157 ) then
3158
3159 ! dati
3160 v7d%voldatic &
3161 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
3162 v7d%voldatic &
3163 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
3164
3165
3166 ! attributi
3167 if (associated (v7d%dativarattr%i)) then
3168 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%c(inddativar))
3169 if (inddativarattr > 0 ) then
3170 v7d%voldatiattri &
3171 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3172 v7d%voldatiattri &
3173 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3174 end if
3175 end if
3176
3177 if (associated (v7d%dativarattr%r)) then
3178 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%c(inddativar))
3179 if (inddativarattr > 0 ) then
3180 v7d%voldatiattrr &
3181 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3182 v7d%voldatiattrr &
3183 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3184 end if
3185 end if
3186
3187 if (associated (v7d%dativarattr%d)) then
3188 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%c(inddativar))
3189 if (inddativarattr > 0 ) then
3190 v7d%voldatiattrd &
3191 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3192 v7d%voldatiattrd &
3193 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3194 end if
3195 end if
3196
3197 if (associated (v7d%dativarattr%b)) then
3198 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%c(inddativar))
3199 if (inddativarattr > 0 ) then
3200 v7d%voldatiattrb &
3201 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3202 v7d%voldatiattrb &
3203 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3204 end if
3205 end if
3206
3207 if (associated (v7d%dativarattr%c)) then
3208 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%c(inddativar))
3209 if (inddativarattr > 0 ) then
3210 v7d%voldatiattrc &
3211 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3212 v7d%voldatiattrc &
3213 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3214 end if
3215 end if
3216
3217 end if
3218
3219end do
3220
3221end subroutine move_datac
3222
3223!> Move data for all variables from one coordinate in the real volume to other.
3224!! Only not missing data will be copyed and all attributes will be moved together.
3225!! Usefull to colapse data spread in more indices (level or time or ....).
3226!! After the move is possible to set to missing some descriptor and make a copy with miss=.true.
3227!! to obtain a new vol7d with less data shape.
3228subroutine move_datar (v7d,&
3229 indana,indtime,indlevel,indtimerange,indnetwork,&
3230 indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew)
3231
3232TYPE(vol7d),intent(inout) :: v7d !< data in form of character in this object will be moved
3233
3234integer,intent(in) :: indana,indtime,indlevel,indtimerange,indnetwork !< source coordinate of the data
3235integer,intent(in) :: indananew,indtimenew,indlevelnew,indtimerangenew,indnetworknew !< destination coordinate of data
3236integer :: inddativar,inddativarattr
3237
3238
3239do inddativar=1,size(v7d%dativar%r)
3240
3241 if (c_e(v7d%voldatir(indana,indtime,indlevel,indtimerange,inddativar,indnetwork)) .and. &
3242 .not. c_e(v7d%voldatir(indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew))&
3243 ) then
3244
3245 ! dati
3246 v7d%voldatir &
3247 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativar,indnetworknew) = &
3248 v7d%voldatir &
3249 (indana,indtime,indlevel,indtimerange,inddativar,indnetwork)
3250
3251
3252 ! attributi
3253 if (associated (v7d%dativarattr%i)) then
3254 inddativarattr = index(v7d%dativarattr%i,v7d%dativar%r(inddativar))
3255 if (inddativarattr > 0 ) then
3256 v7d%voldatiattri &
3257 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3258 v7d%voldatiattri &
3259 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3260 end if
3261 end if
3262
3263 if (associated (v7d%dativarattr%r)) then
3264 inddativarattr = index(v7d%dativarattr%r,v7d%dativar%r(inddativar))
3265 if (inddativarattr > 0 ) then
3266 v7d%voldatiattrr &
3267 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3268 v7d%voldatiattrr &
3269 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3270 end if
3271 end if
3272
3273 if (associated (v7d%dativarattr%d)) then
3274 inddativarattr = index(v7d%dativarattr%d,v7d%dativar%r(inddativar))
3275 if (inddativarattr > 0 ) then
3276 v7d%voldatiattrd &
3277 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3278 v7d%voldatiattrd &
3279 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3280 end if
3281 end if
3282
3283 if (associated (v7d%dativarattr%b)) then
3284 inddativarattr = index(v7d%dativarattr%b,v7d%dativar%r(inddativar))
3285 if (inddativarattr > 0 ) then
3286 v7d%voldatiattrb &
3287 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3288 v7d%voldatiattrb &
3289 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3290 end if
3291 end if
3292
3293 if (associated (v7d%dativarattr%c)) then
3294 inddativarattr = index(v7d%dativarattr%c,v7d%dativar%r(inddativar))
3295 if (inddativarattr > 0 ) then
3296 v7d%voldatiattrc &
3297 (indananew,indtimenew,indlevelnew,indtimerangenew,inddativarattr,indnetworknew,:) = &
3298 v7d%voldatiattrc &
3299 (indana,indtime,indlevel,indtimerange,inddativarattr,indnetwork,:)
3300 end if
3301 end if
3302
3303 end if
3304
3305end do
3306
3307end subroutine move_datar
3308
3309
3310!> Reduce some dimensions (level and timerage) for semplification (rounding).
3311!! You can use this for simplify and use variables in computation like alchimia
3312!! where fields have to be on the same coordinate
3313!! It return real or character data only: if input is charcter data only it return character otherwise il return
3314!! all the data converted to real.
3315!! examples:
3316!! means in time for short periods and istantaneous values
3317!! 2 meter and surface levels
3318!! If there are data on more then one almost equal levels or timeranges, the first var present (at least one point)
3319!! will be taken (order is by icreasing var index).
3320!! You can use predefined values for classic semplification
3321!! almost_equal_levels and almost_equal_timeranges
3322!! The level or timerange in output will be defined by the first element of level and timerange list
3323subroutine v7d_rounding(v7din,v7dout,level,timerange,nostatproc)
3324type(vol7d),intent(inout) :: v7din !< input volume
3325type(vol7d),intent(out) :: v7dout !> output volume
3326type(vol7d_level),intent(in),optional :: level(:) !< almost equal level list
3327type(vol7d_timerange),intent(in),optional :: timerange(:) !< almost equal timerange list
3328!logical,intent(in),optional :: merge !< if there are data on more then one almost equal levels or timeranges
3329!! will be merged POINT BY POINT with priority for the fird data found ordered by icreasing var index
3330logical,intent(in),optional :: nostatproc !< do not take in account statistical processing code in timerange and P2
3331
3332integer :: nana,nlevel,ntime,ntimerange,nnetwork,nbin
3333integer :: iana,ilevel,itimerange,indl,indt,itime,inetwork
3334type(vol7d_level) :: roundlevel(size(v7din%level))
3335type(vol7d_timerange) :: roundtimerange(size(v7din%timerange))
3336type(vol7d) :: v7d_tmp
3337
3338
3339nbin=0
3340
3341if (associated(v7din%dativar%r)) nbin = nbin + size(v7din%dativar%r)
3342if (associated(v7din%dativar%i)) nbin = nbin + size(v7din%dativar%i)
3343if (associated(v7din%dativar%d)) nbin = nbin + size(v7din%dativar%d)
3344if (associated(v7din%dativar%b)) nbin = nbin + size(v7din%dativar%b)
3345
3346call init(v7d_tmp)
3347
3348roundlevel=v7din%level
3349
3350if (present(level))then
3351 do ilevel = 1, size(v7din%level)
3352 if ((any(v7din%level(ilevel) .almosteq. level))) then
3353 roundlevel(ilevel)=level(1)
3354 end if
3355 end do
3356end if
3357
3358roundtimerange=v7din%timerange
3359
3360if (present(timerange))then
3361 do itimerange = 1, size(v7din%timerange)
3362 if ((any(v7din%timerange(itimerange) .almosteq. timerange))) then
3363 roundtimerange(itimerange)=timerange(1)
3364 end if
3365 end do
3366end if
3367
3368!set istantaneous values everywere
3369!preserve p1 for forecast time
3370if (optio_log(nostatproc)) then
3371 roundtimerange(:)%timerange=254
3372 roundtimerange(:)%p2=0
3373end if
3374
3375
3376nana=size(v7din%ana)
3377nlevel=count_distinct(roundlevel,back=.true.)
3378ntime=size(v7din%time)
3379ntimerange=count_distinct(roundtimerange,back=.true.)
3380nnetwork=size(v7din%network)
3381
3382call init(v7d_tmp)
3383
3384if (nbin == 0) then
3385 call copy(v7din,v7d_tmp)
3386else
3387 call vol7d_convr(v7din,v7d_tmp)
3388end if
3389
3390v7d_tmp%level=roundlevel
3391v7d_tmp%timerange=roundtimerange
3392
3393do ilevel=1, size(v7d_tmp%level)
3394 indl=index(v7d_tmp%level,roundlevel(ilevel))
3395 do itimerange=1,size(v7d_tmp%timerange)
3396 indt=index(v7d_tmp%timerange,roundtimerange(itimerange))
3397
3398 if (indl /= ilevel .or. indt /= itimerange) then
3399
3400 do iana=1, nana
3401 do itime=1,ntime
3402 do inetwork=1,nnetwork
3403
3404 if (nbin > 0) then
3405 call move_datar (v7d_tmp,&
3406 iana,itime,ilevel,itimerange,inetwork,&
3407 iana,itime,indl,indt,inetwork)
3408 else
3409 call move_datac (v7d_tmp,&
3410 iana,itime,ilevel,itimerange,inetwork,&
3411 iana,itime,indl,indt,inetwork)
3412 end if
3413
3414 end do
3415 end do
3416 end do
3417
3418 end if
3419
3420 end do
3421end do
3422
3423! set to missing level and time > nlevel
3424do ilevel=nlevel+1,size(v7d_tmp%level)
3425 call init (v7d_tmp%level(ilevel))
3426end do
3427
3428do itimerange=ntimerange+1,size(v7d_tmp%timerange)
3429 call init (v7d_tmp%timerange(itimerange))
3430end do
3431
3432!copy with remove
3433CALL copy(v7d_tmp,v7dout,miss=.true.,lsort_timerange=.true.,lsort_level=.true.)
3434CALL delete(v7d_tmp)
3435
3436!call display(v7dout)
3437
3438end subroutine v7d_rounding
3439
3440
3441END MODULE vol7d_class
3442
3443!>\example esempio_qc_convert.f90
3444!!\brief Programma esempio semplice per la scrittura su file di un volume vol7d
3445!!
3446!!Programma che scrive su file un volume vol7d letto da una serie di file ASCII.
3447!!Questo programma scrive i dati del clima che poi verranno letti da modqccli
3448
3449
3450!>\example esempio_v7ddballe_move_and_collapse.f90
3451!!\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.
Class for expressing an absolute time value.
Definisce l'anagrafica di una stazione.
Definisce un oggetto contenente i volumi anagrafica e dati e tutti i descrittori delle loro dimension...
Definisce il livello verticale di un'osservazione.
Definisce la rete a cui appartiene una stazione.
Definisce l'intervallo temporale di un'osservazione meteo.
Definisce un vettore di vol7d_var_class::vol7d_var per ogni tipo di dato supportato.

Generated with Doxygen.