Sample program for module qctem.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "config.h"
21
22program v7d_qctem
23
32
36
37implicit none
38
39integer :: io,ier,i,iun,n,ind
40TYPE(l4f_handle) :: category
41character(len=512):: a_name,output_format, output_template
42
43
44TYPE(optionparser) :: opt
45TYPE(geo_coord) :: coordmin, coordmax
46TYPE(datetime) :: time, timeiqc, timefqc
47type(qctemtype) :: v7dqctem
48type(vol7d) :: v7dana
49
50integer, parameter :: maxvar=10
51character(len=6) :: var(maxvar)=cmiss
52#ifdef HAVE_DBALLE
53type(vol7d_dballe) :: v7ddballe,v7ddballeana,v7d_dba_out
54character(len=512) :: dsn='test1',user='test',password=''
55character(len=512) :: dsne='test',usere='test',passworde=''
56character(len=512) :: dsntem='test',usertem='test',passwordtem=''
57#endif
58integer :: years=imiss,months=imiss,days=imiss,hours=imiss,yeare=imiss,monthe=imiss,daye=imiss,houre=imiss,nvar=0
59doubleprecision :: lons=dmiss,lats=dmiss,lone=dmiss,late=dmiss
60logical :: height2level=.false.,version
61CHARACTER(len=512) :: input_file, output_file
62INTEGER :: optind, optstatus, ninput
63CHARACTER(len=20) :: operation
64TYPE(ARRAYOF_REAL):: grad
65real :: val
66integer :: iostat
67REAL, DIMENSION(11) :: perc_vals=(/(10.*i,i=0,10)/)
68REAL, DIMENSION(size(perc_vals)-1) :: ndi
69REAL, DIMENSION(size(perc_vals)) :: nlimbins
70double precision, dimension(2) :: percentile
71TYPE(cyclicdatetime) :: cyclicdt
72type(vol7d_level) :: level,levelo
73type(vol7d_timerange) :: timerange,timerangeo
74type(vol7d_var) :: varia,variao
75CHARACTER(len=vol7d_ana_lenident) :: ident
76integer :: indcana,indctime,indclevel,indctimerange,indcdativarr,indcnetwork,indcattr,iana
77INTEGER,POINTER :: w_s(:), w_e(:)
78logical :: file
79
80#ifdef HAVE_DBALLE
81namelist /odbc/ dsn,user,password,dsne,usere,passworde
82namelist /odbctem/ dsntem,usertem,passwordtem
83#endif
84namelist /switchtem/ height2level
85namelist /minmax/ years,months,days,hours,lons,lats,yeare,monthe,daye,houre,lone,late
86namelist /varlist/ var
87
88
90
91
92call l4f_launcher(a_name,a_name_force="v7d_qctem")
93
94
95category=l4f_category_get_handle(a_name//".main")
96
97
98
99opt = optionparser_new(description_msg= &
100 'Spatial quality control: compute gradient; compute NDI from gradient; apply quality control', &
101 usage_msg='Usage: v7d_qctem [options] [inputfile1] [inputfile2...] [outputfile] \n&
102 &If input-format is of file type, inputfile ''-'' indicates stdin,'&
103#ifdef HAVE_DBALLE
104 //'if output-format is of database type, outputfile specifies &
105 &database access info in YRI form,' &
106#endif
107 //'if empty or ''-'', a suitable default is used. &
108&')
109
110
112 'operation to execute: ''gradient'' compute gradient and write on files; '&
113 //'''ndi'' compute NDI from gradient;' &
114 //'''run'' apply quality control ')
115
116
117
118output_template = ''
119CALL optionparser_add(opt,
' ',
'output-format', output_format,
'native', help= &
120 'format of output file for "ndi" operation only, in the form ''name[:template]''; ''native'' for vol7d &
121 &native binary format (no template to be specified)'&
122#ifdef HAVE_DBALLE
123 //'; ''BUFR'' and ''CREX'' for corresponding formats, with template as an alias like ''synop'', ''metar'', &
124 &''temp'', ''generic'', empty for ''generic'''&
125#endif
126)
127
128
129CALL optionparser_add_help(opt, 'h', 'help', help='show an help message and exit')
130CALL optionparser_add(opt,
' ',
'version', version, help=
'show version and exit')
131
132
133CALL optionparser_parse(opt, optind, optstatus)
134
135IF (optstatus == optionparser_help) THEN
136 CALL exit(0)
137ELSE IF (optstatus == optionparser_err) THEN
139 CALL raise_fatal_error()
140ENDIF
141IF (version) THEN
142 WRITE(*,'(A,1X,A)')'v7d_qctem',version
143 CALL exit(0)
144ENDIF
145
146
147if (operation /= "gradient" .and. operation /= "ndi" .and. operation /= "run") then
148 CALL optionparser_printhelp(opt)
150 'argument to --operation is wrong')
151 CALL raise_fatal_error()
152end if
153
154
155
156n = word_split(output_format, w_s, w_e, ':')
157IF (n >= 2) THEN
158 output_template = output_format(w_s(2):w_e(2))
159 output_format(w_e(1)+1:) = ' '
160ENDIF
161DEALLOCATE(w_s, w_e)
162
163if (operation == "ndi") then
164
165
166 i = iargc() - optind
167 IF (i < 0) THEN
168 CALL optionparser_printhelp(opt)
170 CALL raise_fatal_error()
171 ELSE IF (i < 1) THEN
172 CALL optionparser_printhelp(opt)
174 CALL raise_fatal_error()
175 ENDIF
176 CALL getarg(iargc(), output_file)
177
179 call init(timerangeo)
181
182 do ninput = optind, iargc()-1
183 call getarg(ninput, input_file)
184
186 open (10,file=input_file,status="old")
187 read (10,*) level,timerange,varia
188
189 if (
c_e(levelo))
then
190 if ( level /= levelo .or. timerange /= timerangeo .or. varia /= variao ) then
191 call l4f_category_log(category,l4f_error,
"Error reading grad files: file are incoerent")
192 call raise_error("")
193 end if
194 else
195 levelo = level
196 timerangeo = timerange
197 variao = varia
198 end if
199
200 do while (.true.)
201 read (10,*,iostat=iostat) val
202 if (iostat /= 0) exit
203 if (val /= 0.)
call insert(grad,val)
204 end do
205
206 close(10)
207 end do
208
209 call delete(v7dqctem%clima)
210 CALL init(v7dqctem%clima, time_definition=0)
211 call vol7d_alloc(v7dqctem%clima,nana=size(perc_vals)-1, &
212 nlevel=1, ntimerange=1, &
213 ndativarr=1, nnetwork=2,ntime=1,ndativarattrr=1,ndatiattrr=1)
214
215 call vol7d_alloc_vol(v7dqctem%clima,inivol=.true.)
216
217 v7dqctem%clima%level=level
218 v7dqctem%clima%timerange=timerange
219 v7dqctem%clima%dativar%r(1)=varia
220 v7dqctem%clima%dativarattr%r(1)=varia
221 call init(v7dqctem%clima%datiattr%r(1), btable=
"*B33209")
222 cyclicdt = cyclicdatetime_new(chardate="/////////")
223 v7dqctem%clima%time(1)=cyclicdatetime_to_conventional(cyclicdt)
224
225 indctime=1
226 indclevel=1
227 indcattr=1
228 indcdativarr=1
229 indctimerange=1
230
231
232 indcnetwork=1
233 call init(v7dqctem%clima%network(indcnetwork),name=
"qctemsndi")
234
236
237 CALL l4f_category_log(category,l4f_info,
"compute percentile to remove the tails")
238 percentile =
stat_percentile(
abs(pack(grad%array(:grad%arraysize),mask=grad%array(:grad%arraysize) >= 0.)),(/10.,90./))
239
240
241 call normalizeddensityindex(
abs(pack(grad%array(:grad%arraysize),&
242 mask=(
abs(grad%array(:grad%arraysize)) < percentile(2) .and. grad%array(:grad%arraysize) >= 0. ))), perc_vals, ndi, nlimbins)
243
244 do indcana=1,size(perc_vals)-1
245 write(ident,'("#",i2.2,2i3.3)')0,0,nint(perc_vals(indcana))
246 call init(v7dqctem%clima%ana(indcana),ident=ident,lat=0d0,lon=0d0)
247 if (
c_e(nlimbins(indcana)).and.
c_e(ndi(indcana)))
then
248 ind=index_c(tem_btable,varia%btable)
249 v7dqctem%clima%voldatir(indcana, indctime, indclevel, indctimerange, indcdativarr, indcnetwork)=&
250 nlimbins(indcana)*tem_a(ind) + tem_b(ind)
251 v7dqctem%clima%voldatiattrr(indcana, indctime, indclevel, indctimerange, indcdativarr, indcnetwork,indcattr)=&
252 ndi(indcana)*100.
253 end if
254 end do
255
256 indcnetwork=2
257 call init(v7dqctem%clima%network(indcnetwork),name=
"qctemgndi")
258
260 CALL l4f_category_log(category,l4f_info,
"compute percentile to remove the tails")
261 percentile =
stat_percentile(
abs(pack(grad%array(:grad%arraysize),mask=grad%array(:grad%arraysize) < 0.)),(/10.,90./))
262
263 call normalizeddensityindex(
abs(pack(grad%array(:grad%arraysize),&
264 mask=(
abs(grad%array(:grad%arraysize)) < percentile(2) .and. grad%array(:grad%arraysize) < 0. ))), perc_vals, ndi, nlimbins)
265
266 do indcana=1,size(perc_vals)-1
267 write(ident,'("#",i2.2,2i3.3)')0,0,nint(perc_vals(indcana))
268 call init(v7dqctem%clima%ana(indcana),ident=ident,lat=0d0,lon=0d0)
269 if (
c_e(nlimbins(indcana)).and.
c_e(ndi(indcana)))
then
270 ind=index_c(tem_btable,varia%btable)
271 v7dqctem%clima%voldatir(indcana, indctime, indclevel, indctimerange, indcdativarr, indcnetwork)=&
272 nlimbins(indcana)*tem_a(ind) + tem_b(ind)
273 v7dqctem%clima%voldatiattrr(indcana, indctime, indclevel, indctimerange, indcdativarr, indcnetwork,indcattr)=&
274 ndi(indcana)*100.
275 end if
276 end do
277
280
281
282
283
284 IF (output_format == 'native') THEN
285 IF (output_file == '-') THEN
286 CALL l4f_category_log(category, l4f_info,
'trying /dev/stdout as stdout unit.')
287 output_file='/dev/stdout'
288 ENDIF
289 iun = getunit()
290 OPEN(iun, file=output_file, form='UNFORMATTED', access='STREAM')
291 CALL export(v7dqctem%clima, unit=iun)
292 CLOSE(iun)
293 CALL delete(v7dqctem%clima)
294
295#ifdef HAVE_DBALLE
296 ELSE IF (output_format == 'BUFR' .OR. output_format == 'CREX' .OR. output_format == 'dba') THEN
297 IF (output_format == 'BUFR' .OR. output_format == 'CREX') THEN
298 IF (output_file == '-') THEN
299 CALL l4f_category_log(category, l4f_info,
'trying /dev/stdout as stdout unit.')
300 output_file='/dev/stdout'
301 ENDIF
302 file=.true.
303
304 ELSE IF (output_format == 'dba') THEN
305 file=.false.
306 ENDIF
307
308 IF (output_template == '') output_template = 'generic'
309
310 CALL init(v7d_dba_out, filename=output_file, format=output_format, &
311 dsn=output_file, file=file, write=.true., wipe=file)
312
313 v7d_dba_out%vol7d = v7dqctem%clima
314 CALL init(v7dqctem%clima)
315 CALL export(v7d_dba_out, template=output_template)
317#endif
318
319 end if
320
321 stop
322
323end if
324
325
326
327
328
329open(10,file='qc.nml',status='old')
330read(10,nml=odbc,iostat=io)
331if ( io == 0 ) read(10,nml=odbctem,iostat=io)
332if ( io == 0 ) read(10,nml=switchtem,iostat=io)
333if ( io == 0 ) read(10,nml=minmax,iostat=io)
334if ( io == 0 ) read(10,nml=varlist,iostat=io)
335
336if (io /= 0 )then
338 call raise_error()
339end if
340close(10)
341
342
343
344
345
346
348
349if (nvar == 0) then
351 call raise_error()
352end if
353
354CALL init(timeiqc, year=years, month=months, day=days, hour=hours)
355CALL init(timefqc, year=yeare, month=monthe, day=daye, hour=houre)
356
359
360
361CALL init(coordmin,lat=lats,lon=lons)
362CALL init(coordmax,lat=late,lon=lone)
363
364
365print*,
"lon lat minimum -> ",
to_char(coordmin)
366
367print*,
"lon lat maximum -> ",
to_char(coordmax)
368
369
371do i=1,nvar
373enddo
380
381
382
383CALL init(v7ddballeana,dsn=dsn,write=.false.,wipe=.false.,categoryappend=
"QCtarget-anaonly")
385CALL import(v7ddballeana,var=var(:nvar),timei=timeiqc,timef=timefqc,coordmin=coordmin,coordmax=coordmax,anaonly=.true.)
386call vol7d_copy(v7ddballeana%vol7d,v7dana)
388
389
390
391
392
393
394
395
396print *,"anagrafica:"
398
399do iana=1, size(v7dana%ana)
400
402
403
404 CALL init(v7ddballe,dsn=dsn,write=.true.,wipe=.false.,categoryappend=
"QCtarget-"//
t2c(time))
406
407 CALL import(v7ddballe,var=var(:nvar),varkind=(/(
"r",i=1,nvar)/),&
408 anavar=(/"B07030"/),anavarkind=(/"r"/),&
409 attr=(/qcattrvarsbtables(1),qcattrvarsbtables(2),qcattrvarsbtables(3)/),attrkind=(/"b","b","b"/)&
410 ,timei=timeiqc,timef=timefqc, ana=v7dana%ana(iana))
411
412
413 if (size(v7ddballe%vol7d%time)==0) then
414 CALL l4f_category_log(category,l4f_info,
'skip empty volume: you are not using dballe >= 6.6 !')
416 cycle
417 end if
418
419 print *,"input volume"
423
425
426
427
428 qcpar%att=bmiss
429
430 call vol7d_peeling(v7ddballe%vol7d,keep_attr=(/qcattrvarsbtables(3)/),purgeana=.true.)
431
432
433 call l4f_category_log(category,l4f_info,
"filtered N time="//
t2c(
size(v7ddballe%vol7d%time)))
434
436
437
438
439 call init(v7dqctem,v7ddballe%vol7d,var(:nvar),timei=timeiqc,timef=timefqc, &
440 coordmin=v7dana%ana(iana)%coord, coordmax=v7dana%ana(iana)%coord,&
441
442 dsne=dsne, usere=usere, passworde=passworde,&
443 dsntem=dsntem, usertem=usertem, passwordtem=passwordtem,&
444 height2level=height2level, operation=operation,&
445 categoryappend="temporal")
446
447
448
449
451
452
454 call quacontem(v7dqctem,timemask= ( v7dqctem%v7d%time >= timeiqc .and. v7dqctem%v7d%time <= timefqc ))
456
457
458
459
460
461 if (v7dqctem%operation == "run") then
463 print *,"output volume"
465
466
467
468
469 CALL export(v7ddballe, attr_only=.true.)
471 end if
472
474
475
477
478end do
479
481
482
483call l4f_category_delete(category)
485
486end program v7d_qctem
Destructor for finalizing an array object.
Method for inserting elements of the array at a desired position.
Operatore di valore assoluto di un intervallo.
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.
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.
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.
Controllo di qualità temporale.
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