libsim Versione 8.0.0
v7d_qcspa.F90

Sample program for module qcspa.

Sample program for module qcspa

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! Program to quality control data with climatological values
19
20#include "config.h"
21
22program v7d_qcspa
23
30use modqc
31use modqcspa
32!use vol7d_dballeold_class
37
38#ifdef HAVE_LIBNCARG
39USE ncar_plot_class
40#endif
41
42implicit none
43
44integer :: io,ier,i,iun,n,ind
45TYPE(l4f_handle) :: category
46character(len=512):: a_name,output_format, output_template
47
48 !tipi derivati.
49TYPE(optionparser) :: opt
50TYPE(geo_coord) :: coordmin, coordmax
51TYPE(datetime) :: time,ti, tf, timei, timef, timeiqc, timefqc
52type(qcspatype) :: v7dqcspa
53type(vol7d_dballe) :: v7ddballe
54#ifdef HAVE_LIBNCARG
55type(ncar_plot) :: plot
56#endif
57
58integer, parameter :: maxvar=10
59character(len=6) :: var(maxvar)=cmiss ! variables to elaborate
60#ifdef HAVE_DBALLE
61character(len=512) :: dsn='test1',user='test',password=''
62character(len=512) :: dsne='test',usere='test',passworde=''
63character(len=512) :: dsnspa='test',userspa='test',passwordspa=''
64#endif
65integer :: years=imiss,months=imiss,days=imiss,hours=imiss,yeare=imiss,monthe=imiss,daye=imiss,houre=imiss,nvar=0
66doubleprecision :: lons=dmiss,lats=dmiss,lone=dmiss,late=dmiss
67integer :: year, month, day, hour
68logical :: height2level=.false.,doplot=.false.,version
69CHARACTER(len=512) :: input_file, output_file
70INTEGER :: optind, optstatus, ninput
71CHARACTER(len=20) :: operation
72TYPE(ARRAYOF_REAL):: grad
73real :: val
74integer :: iostat
75REAL, DIMENSION(11) :: perc_vals=(/(10.*i,i=0,10)/) !(/0.,10.,20.,30.,40.,50.,60.,70.,80.,90.,100./) !<the percentiles values to be computed, between 0. and 100.
76REAL, DIMENSION(size(perc_vals)-1) :: ndi !< normalized density index
77REAL, DIMENSION(size(perc_vals)) :: nlimbins !< the extreme values of data taken in account for ndi computation
78double precision, dimension(2) :: percentile
79TYPE(cyclicdatetime) :: cyclicdt !< cyclic date and time
80type(vol7d_level) :: level,levelo
81type(vol7d_timerange) :: timerange,timerangeo
82type(vol7d_var) :: varia,variao
83CHARACTER(len=vol7d_ana_lenident) :: ident
84integer :: indcana,indctime,indclevel,indctimerange,indcdativarr,indcnetwork,indcattr
85INTEGER,POINTER :: w_s(:), w_e(:)
86TYPE(vol7d_dballe) :: v7d_dba_out
87logical :: file
88integer :: status,grunit
89
90#ifdef HAVE_DBALLE
91namelist /odbc/ dsn,user,password,dsne,usere,passworde
92namelist /odbcspa/ dsnspa,userspa,passwordspa ! namelist to define DSN
93#endif
94namelist /switchspa/ height2level,doplot
95namelist /minmax/ years,months,days,hours,lons,lats,yeare,monthe,daye,houre,lone,late
96namelist /varlist/ var
97
98!init log4fortran
99ier=l4f_init()
100
101! unique name from launcher
102call l4f_launcher(a_name,a_name_force="v7d_qcspa")
103
104! set a_name
105category=l4f_category_get_handle(a_name//".main")
106
107
108! define the option parser
109opt = optionparser_new(description_msg= &
110 'Spatial quality control: compute gradient; compute NDI from gradient; apply quality control', &
111 usage_msg='Usage: v7d_qcspa [options] [inputfile1] [inputfile2...] [outputfile] \n&
112 &If input-format is of file type, inputfile ''-'' indicates stdin,'&
113#ifdef HAVE_DBALLE
114 //'if output-format is of database type, outputfile specifies &
115 &database access info in URI form,' &
116#endif
117 //'if empty or ''-'', a suitable default is used. &
118&')
119
120! options for defining input
121CALL optionparser_add(opt, ' ', 'operation', operation, "run", help= &
122 'operation to execute: ''gradient'' compute gradient and write on files; '&
123 //'''ndi'' compute NDI from gradient;' &
124 //'''run'' apply quality control ')
125
126
127! options for defining output
128output_template = ''
129CALL optionparser_add(opt, ' ', 'output-format', output_format, 'native', help= &
130 'format of output file for "ndi" operation only, in the form ''name[:template]''; ''native'' for vol7d &
131 &native binary format (no template to be specified)'&
132#ifdef HAVE_DBALLE
133 //'; ''BUFR'' and ''CREX'' for corresponding formats, with template as an alias like ''synop'', ''metar'', &
134 &''temp'', ''generic'', empty for ''generic'''&
135#endif
136)
137
138! help options
139CALL optionparser_add_help(opt, 'h', 'help', help='show an help message and exit')
140CALL optionparser_add(opt, ' ', 'version', version, help='show version and exit')
141
142! parse options and check for errors
143CALL optionparser_parse(opt, optind, optstatus)
144
145IF (optstatus == optionparser_help) THEN
146 CALL exit(0) ! generate a clean manpage
147ELSE IF (optstatus == optionparser_err) THEN
148 CALL l4f_category_log(category,l4f_error,'in command-line parameters')
149 CALL raise_fatal_error()
150ENDIF
151IF (version) THEN
152 WRITE(*,'(A,1X,A)')'v7d_qcspa',version
153 CALL exit(0)
154ENDIF
155
156
157if (operation /= "gradient" .and. operation /= "ndi" .and. operation /= "run") then
158 CALL optionparser_printhelp(opt)
159 CALL l4f_category_log(category, l4f_error, &
160 'argument to --operation is wrong')
161 CALL raise_fatal_error()
162end if
163
164
165! check output format/template
166n = word_split(output_format, w_s, w_e, ':')
167IF (n >= 2) THEN ! set output template if present
168 output_template = output_format(w_s(2):w_e(2))
169 output_format(w_e(1)+1:) = ' '
170ENDIF
171DEALLOCATE(w_s, w_e)
172
173if (operation == "ndi") then
174
175 ! check input/output files
176 i = iargc() - optind
177 IF (i < 0) THEN
178 CALL optionparser_printhelp(opt)
179 CALL l4f_category_log(category,l4f_error,'input file missing')
180 CALL raise_fatal_error()
181 ELSE IF (i < 1) THEN
182 CALL optionparser_printhelp(opt)
183 CALL l4f_category_log(category,l4f_error,'output file missing')
184 CALL raise_fatal_error()
185 ENDIF
186 CALL getarg(iargc(), output_file)
187
188
189 !you can define level, timerange, var or get it from file
190 call init(levelo)
191 call init(timerangeo)
192 call init (variao)
193
194 do ninput = optind, iargc()-1
195 call getarg(ninput, input_file)
196
197 CALL l4f_category_log(category,l4f_info,"open file: "//t2c(input_file))
198 grunit=getunit()
199 open (grunit,file=input_file,status="old")
200 read (grunit,*,iostat=status) level,timerange,varia
201 if (status /= 0) then
202 CALL l4f_category_log(category,l4f_warn,"error reading: "//t2c(input_file))
203 close(grunit)
204 cycle
205 endif
206
207 if (c_e(levelo)) then
208
209 !if (t2c(input_file) /= to_char(levelo)//"_"//to_char(timerangeo)//"_"//variao%btable//".grad")
210 if ( level /= levelo .or. timerange /= timerangeo .or. varia /= variao ) then
211 call l4f_category_log(category,l4f_error,"Error reading grad files: file are incoerent")
212 call raise_error("")
213 end if
214 else
215 levelo = level
216 timerangeo = timerange
217 variao = varia
218 end if
219
220 do while (.true.)
221 read (grunit,*,iostat=iostat) val
222 if (iostat /= 0) exit
223 if (val /= 0.) call insert(grad,val)
224 end do
225
226 close(grunit)
227 end do
228
229 CALL l4f_category_log(category,l4f_info,"compute percentile to remove the tails")
230 percentile = stat_percentile(grad%array(:grad%arraysize),(/10.,90./))
231 !print *,percentile
232
233 CALL l4f_category_log(category,l4f_info,"compute NDI")
234 call normalizeddensityindex(pack(grad%array(:grad%arraysize),&
235 mask=(grad%array(:grad%arraysize) < percentile(2) )), perc_vals, ndi, nlimbins)
236
237 call delete(grad)
238 call delete(v7dqcspa%clima)
239 CALL init(v7dqcspa%clima, time_definition=0)
240 call vol7d_alloc(v7dqcspa%clima,nana=size(perc_vals)-1, &
241 nlevel=1, ntimerange=1, &
242 ndativarr=1, nnetwork=1,ntime=1,ndativarattrr=1,ndatiattrr=1)
243
244 call vol7d_alloc_vol(v7dqcspa%clima,inivol=.true.)
245
246 call init(v7dqcspa%clima%network(1),name="qcspa-ndi")
247 v7dqcspa%clima%level=level
248 v7dqcspa%clima%timerange=timerange
249 v7dqcspa%clima%dativar%r(1)=varia
250 v7dqcspa%clima%dativarattr%r(1)=varia
251 call init(v7dqcspa%clima%datiattr%r(1), btable="*B33209") ! NDI order number
252 cyclicdt = cyclicdatetime_new(chardate="/////////") !TMMGGhhmm
253 v7dqcspa%clima%time(1)=cyclicdatetime_to_conventional(cyclicdt)
254
255 indctime=1
256 indclevel=1
257 indcnetwork=1
258 indcattr=1
259 indcdativarr=1
260 indctimerange=1
261
262 do indcana=1,size(perc_vals)-1
263 write(ident,'("#",i2.2,2i3.3)')0,0,nint(perc_vals(indcana))
264 call init(v7dqcspa%clima%ana(indcana),ident=ident,lat=0d0,lon=0d0)
265 if (c_e(nlimbins(indcana)).and.c_e(ndi(indcana)))then
266 ind=index_c(spa_btable,varia%btable)
267 v7dqcspa%clima%voldatir(indcana, indctime, indclevel, indctimerange, indcdativarr, indcnetwork)=&
268 nlimbins(indcana)*spa_a(ind) + spa_b(ind)
269 v7dqcspa%clima%voldatiattrr(indcana, indctime, indclevel, indctimerange, indcdativarr, indcnetwork,indcattr)=&
270 ndi(indcana)*100.
271 end if
272 end do
273
274 print *,">>>>>> NDI Volume <<<<<<"
275 call display (v7dqcspa%clima)
276
277 IF (output_format == 'native') THEN
278 IF (output_file == '-') THEN ! stdout_unit does not work with unformatted
279 CALL l4f_category_log(category, l4f_info, 'trying /dev/stdout as stdout unit.')
280 output_file='/dev/stdout'
281 ENDIF
282 iun = getunit()
283 OPEN(iun, file=output_file, form='UNFORMATTED', access='STREAM')
284 CALL export(v7dqcspa%clima, unit=iun)
285 CLOSE(iun)
286 CALL delete(v7dqcspa%clima)
287
288#ifdef HAVE_DBALLE
289 ELSE IF (output_format == 'BUFR' .OR. output_format == 'CREX' .OR. output_format == 'dba') THEN
290 IF (output_format == 'BUFR' .OR. output_format == 'CREX') THEN
291 IF (output_file == '-') THEN
292 CALL l4f_category_log(category, l4f_info, 'trying /dev/stdout as stdout unit.')
293 output_file='/dev/stdout'
294 ENDIF
295 file=.true.
296
297 ELSE IF (output_format == 'dba') THEN
298 file=.false.
299 ENDIF
300
301 IF (output_template == '') output_template = 'generic'
302 ! check whether wipe=file is reasonable
303 CALL init(v7d_dba_out, filename=output_file, format=output_format, &
304 dsn=output_file, file=file, write=.true., wipe=file)
305
306 v7d_dba_out%vol7d = v7dqcspa%clima
307 CALL init(v7dqcspa%clima) ! nullify without deallocating
308 CALL export(v7d_dba_out, template=output_template)
309 CALL delete(v7d_dba_out)
310#endif
311
312 end if
313
314 stop
315
316end if
317
318!------------------------------------------------------------------------
319! read the namelist to define DSN
320!------------------------------------------------------------------------
321
322open(10,file='qc.nml',status='old')
323read(10,nml=odbc,iostat=io)
324if ( io == 0 ) read(10,nml=odbcspa,iostat=io)
325if ( io == 0 ) read(10,nml=switchspa,iostat=io)
326if ( io == 0 ) read(10,nml=minmax,iostat=io)
327if ( io == 0 ) read(10,nml=varlist,iostat=io)
328
329if (io /= 0 )then
330 call l4f_category_log(category,l4f_error,"Error reading namelist qc.nml")
331 call raise_error("Error reading namelist qc.nml")
332end if
333close(10)
334
335
336!------------------------------------------------------------------------
337! Define what you want to QC
338!------------------------------------------------------------------------
339
340nvar=count(c_e(var))
341
342if (nvar == 0) then
343 call l4f_category_log(category,l4f_error,"0 variables defined")
344 call raise_error()
345end if
346 ! Definisco le date iniziale e finale
347CALL init(ti, year=years, month=months, day=days, hour=hours)
348CALL init(tf, year=yeare, month=monthe, day=daye, hour=houre)
349print *,"time extreme"
350call display(ti)
351call display(tf)
352
353 ! Define coordinate box
354CALL init(coordmin,lat=lats,lon=lons)
355CALL init(coordmax,lat=late,lon=lone)
356
357!call getval(coordmin,lon=lon,lat=lat)
358print*,"lon lat minimum -> ",to_char(coordmin)
359!call getval(coordmax,lon=lon,lat=lat)
360print*,"lon lat maximum -> ",to_char(coordmax)
361
362!------------------------------------------------------------------------
363call l4f_category_log(category,l4f_info,"QC on "//t2c(nvar)//" variables")
364do i=1,nvar
365 call l4f_category_log(category,l4f_info,"QC on "//var(i)//" variable")
366enddo
367if (c_e(lons)) call l4f_category_log(category,l4f_info,"QC on "//t2c(lons)//" lon min value")
368if (c_e(lone)) call l4f_category_log(category,l4f_info,"QC on "//t2c(lone)//" lon max value")
369if (c_e(lats)) call l4f_category_log(category,l4f_info,"QC on "//t2c(lats)//" lat min value")
370if (c_e(late)) call l4f_category_log(category,l4f_info,"QC on "//t2c(late)//" lat max value")
371if (c_e(ti)) call l4f_category_log(category,l4f_info,"QC on "//t2c(ti)//" datetime min value")
372if (c_e(tf)) call l4f_category_log(category,l4f_info,"QC on "//t2c(tf)//" datetime max value")
373!------------------------------------------------------------------------
374
375time=ti
376
377! aproximate to integer hours (not required reading date from namelist)
378!time=ti+timedelta_new(minute=30)
379!CALL getval(time,year, month, day, hour)
380!call init(time, year, month, day, hour, minute=00, msec=00)
381
382!if (time < timei) time=time+timedelta_new(hour=1)
383!timef=tf
384!if (time > timef) time=timei
385
386#ifdef HAVE_LIBNCARG
387if (doplot) then
388 call l4f_category_log(category,l4f_info,"start plot")
389 call init(plot,pstype='PS', orient='LANDSCAPE',color='COLOR',file="v7d_qcspa.ps")
390end if
391#endif
392DO WHILE (time <= tf)
393 timei = time - timedelta_new(minute=30)
394 timef = time + timedelta_new(minute=30)
395 timeiqc = time - timedelta_new(minute=15)
396 timefqc = time + timedelta_new(minute=15)
397 call l4f_category_log(category,l4f_info,"elaborate from "//t2c(timeiqc)//" to "//t2c(timefqc))
398
399 ! Chiamo il costruttore della classe vol7d_dballe per il mio oggetto in import
400 CALL init(v7ddballe,dsn=dsn,write=.true.,wipe=.false.,categoryappend="data-"//t2c(time))
401 call l4f_category_log(category,l4f_info,"start data import")
402
403 CALL import(v7ddballe,var=var(:nvar),varkind=(/("r",i=1,nvar)/),&
404 anavar=(/"B07030"/),anavarkind=(/"r"/),&
405 attr=(/qcattrvarsbtables(1),qcattrvarsbtables(2),qcattrvarsbtables(4)/),attrkind=(/"b","b","b"/)&
406 ,timei=timei,timef=timef,coordmin=coordmin,coordmax=coordmax)
407
408! call display(v7ddballe%vol7d)
409 call l4f_category_log(category,l4f_info,"end data import")
410 call l4f_category_log(category,l4f_info, "input N staz="//t2c(size(v7ddballe%vol7d%ana)))
411
412 call l4f_category_log(category,l4f_info,"start peeling")
413
414 !remove data invalidated and gross error only
415 !this change the behaviour of qcsummary_flag to ignore confidence att thresold
416 !qcpar=qcpartype(0_int_b,0_int_b,1_int_b)
417 qcpar%att=bmiss
418 !call vol7d_peeling(v7ddballe%vol7d,v7ddballe%data_id,keep_attr=(/qcattrvarsbtables(4)/),purgeana=.true.)
419 call vol7d_peeling(v7ddballe%vol7d,keep_attr=(/qcattrvarsbtables(4)/),purgeana=.true.)
420! call display(v7ddballe%vol7d)
421
422 call l4f_category_log(category,l4f_info, "filtered N staz="//t2c(size(v7ddballe%vol7d%ana)))
423
424 call l4f_category_log(category,l4f_info,"initialize QC")
425
426 ! chiamiamo il "costruttore" per il Q.C.
427
428
429 call init(v7dqcspa,v7ddballe%vol7d,var(:nvar),timei=timeiqc,timef=timefqc, coordmin=coordmin, coordmax=coordmax,&
430 !data_id_in=v7ddballe%data_id, &
431 dsne=dsne, usere=usere, passworde=passworde,&
432 dsnspa=dsnspa, userspa=userspa, passwordspa=passwordspa,&
433 height2level=height2level, operation=operation,&
434 categoryappend="space"//t2c(time))
435
436! print *,">>>>>> Clima Spatial Volume <<<<<<"
437! call display(v7dqcspa%clima)
438
439 !print *,">>>>>> Pre Data Volume <<<<<<"
440 !call display(v7dqcspa%v7d)
441
442 call alloc(v7dqcspa)
443
444 ! spatial QC
445 !attention: do not exclude the first/last time so we check data two times
446 call l4f_category_log(category,l4f_info,"start spatial QC")
447 !call quaconspa(v7dqcspa,noborder=.true.,timemask= ( v7dqcspa%v7d%time >= timeiqc .and. v7dqcspa%v7d%time < timefqc ))
448 call quaconspa(v7dqcspa,timetollerance=timedelta_new(minute=15),noborder=.true.,&
449 timemask= ( v7dqcspa%v7d%time >= timeiqc .and. v7dqcspa%v7d%time <= timefqc ))
450 call l4f_category_log(category,l4f_info,"end spatial QC")
451
452#ifdef HAVE_LIBNCARG
453 if (doplot) then
454 call l4f_category_log(category,l4f_info,"start plot")
455 call plot_triangles(plot,v7dqcspa%co,v7dqcspa%tri,logo="Time: "//t2c(timeiqc)//" to "//t2c(timefqc))
456 call frame()
457 end if
458#endif
459
460
461 ! prepare data_id to be recreated
462 !deallocate(v7ddballe%data_id)
463 !nullify(v7ddballe%data_id)
464
465 if (v7dqcspa%operation == "run") then
466 call l4f_category_log(category,l4f_info,"start export data")
467 !print *,">>>>>> Post Data Volume <<<<<<"
468 !call display(v7ddballe%vol7d)
469
470 ! data_id to use is the new one
471 !v7ddballe%data_id => v7dqcspa%data_id_out
472
473 CALL export(v7ddballe,&
474 filter=dbafilter(datetimemin=dbadatetime(timeiqc),datetimemax=dbadatetime(timefqc)),&
475 attr_only=.true.)
476 !CALL export(v7ddballe)
477 call l4f_category_log(category,l4f_info,"end export data")
478 end if
479
480 call delete(v7dqcspa)
481 ! data_id was allready deleted
482 !nullify(v7ddballe%data_id)
483 call delete(v7ddballe)
484
485 time = time + timedelta_new(minute=30)
486end do
487
488#ifdef HAVE_LIBNCARG
489 if (doplot) then
490 call delete(plot)
491 end if
492#endif
493
494!close logger
495call l4f_category_delete(category)
496ier=l4f_fini()
497
498end program v7d_qcspa
Destructor for finalizing an array object.
Method for inserting elements of the array at a desired position.
Costruttori per le classi datetime e timedelta.
Functions that return a trimmed CHARACTER representation of the input variable.
Restituiscono il valore dell'oggetto in forma di stringa stampabile.
Export one or more geo_coordvect objects to a plain text file or to a file in ESRI/Shapefile format.
Import one or more geo_coordvect objects from a plain text file or for a file in ESRI/Shapefile forma...
Emit log message for a category with specific priority.
Global log4fortran destructor.
Global log4fortran constructor.
Allocazione di memoria.
Definition modqcspa.F90:326
Add a new option of a specific type.
Compute a set of percentiles for a random variable.
This module defines usefull general purpose function and subroutine.
Classi per la gestione delle coordinate temporali.
class for import and export data from e to DB-All.e.
Classes for handling georeferenced sparse points in geographical corodinates.
classe per la gestione del logging
Definitions of constants and functions for working with missing values.
Utilities and defines for quality control.
Definition modqc.F90:357
Controllo di qualità spaziale.
Definition modqcspa.F90:273
Module for parsing command-line optons.
Module for basic statistical computations taking into account missing data.
Classe per la gestione di un volume completo di dati osservati.
classe per import ed export di volumi da e in DB-All.e
filter to apply before ingest data

Generated with Doxygen.