Ticket #429: ropp_io_read_ncdf_get.f90

File ropp_io_read_ncdf_get.f90, 129.5 KB (added by Ian Culverwell, 9 years ago)

ropp_io_read_ncdf_get.f90

Line 
1! $Id: ropp_io_read_ncdf_get.f90 4512 2015-04-28 14:21:22Z idculv $
2
3!****is* Reading/ropp_io_read_ncdf_get *
4!
5! NAME
6! ropp_io_read_ncdf_get - Get data from an (already defined) netCDF.
7!
8! SYNOPSIS
9! call ropp_io_read_ncdf_get(data, rec)
10!
11! DESCRIPTION
12! This subroutine gets variables from an already openend / netCDF data
13! file.
14! Reads core parameters from V1.0 format version and new parameters
15! added in V1.1. Additional variables contained in the netCDF file are
16! read in and define elements of the Vlist structures in ROprof.
17!
18! NOTES
19! A netCDF file must have been opened before; this subroutine only works
20! on the current netcdf file. The netCDF data file is left open.
21!
22! AUTHOR
23! Met Office, Exeter, UK.
24! Any comments on this software should be given via the ROM SAF
25! Helpdesk at http://www.romsaf.org
26!
27! COPYRIGHT
28! (c) EUMETSAT. All rights reserved.
29! For further details please refer to the file COPYRIGHT
30! which you should have received as part of this distribution.
31!
32!****
33
34!-------------------------------------------------------------------------------
35! 1. Core RO data
36!-------------------------------------------------------------------------------
37
38SUBROUTINE ropp_io_read_ncdf_get_rodata(DATA, rec)
39
40! 1.1 Declarations
41! ----------------
42
43 USE ropp_utils
44 USE ncdf
45 USE ropp_io, not_this => ropp_io_read_ncdf_get_rodata
46 USE ropp_io_types, ONLY: ROprof, &
47 ThisFmtVer
48
49 IMPLICIT NONE
50
51 TYPE(ROprof), INTENT(inout) :: DATA
52 INTEGER, OPTIONAL :: rec
53
54 INTEGER :: n, ierr
55 INTEGER :: irec
56 INTEGER, DIMENSION(8) :: DT8 ! Date/time array
57
58 CHARACTER(len = 23) :: proc_date
59 CHARACTER(LEN=15) :: cval
60
61 REAL(dp) :: time, start_time, dtocc_time, now_time !dp defined in DateTimeTypes
62 REAL :: fmtver
63
64 INTEGER :: status, varid, ndim, TYPE
65 CHARACTER(len = 256) :: routine
66
67! 1.2 Error handling
68! ------------------
69
70 CALL message_get_routine(routine)
71 CALL message_set_routine('ropp_io_read_ncdf_get')
72
73! 1.3 Default parameters
74! ----------------------
75
76 IF (PRESENT(rec)) THEN
77 irec = rec
78 ELSE
79 irec = 1
80 ENDIF
81
82! 1.4 (Global) Attributes
83! ------------------------
84
85 data%FmtVersion = ' ' ; CALL ncdf_getatt('format_version', data%FmtVersion)
86 READ ( data%FmtVersion(11:), fmt=*, iostat=ierr ) fmtver
87 IF ( ierr /= 0 ) data%FmtVersion = ThisFmtVer
88 data%processing_centre = ' ' ; CALL ncdf_getatt('processing_centre', data%processing_centre)
89 IF (ncdf_isatt('processing_software')) THEN ! added at V8.0
90 data%processing_software = ' ' ; CALL ncdf_getatt('processing_software', data%processing_software)
91 ENDIF
92 proc_date = ' ' ; CALL ncdf_getatt('processing_date', proc_date)
93 data%pod_method = ' ' ; CALL ncdf_getatt('pod_method', data%pod_method)
94 data%phase_method = ' ' ; CALL ncdf_getatt('phase_method', data%phase_method)
95 data%bangle_method = ' ' ; CALL ncdf_getatt('bangle_method', data%bangle_method)
96 data%refrac_method = ' ' ; CALL ncdf_getatt('refrac_method', data%refrac_method)
97 data%meteo_method = ' ' ; CALL ncdf_getatt('meteo_method', data%meteo_method)
98IF(ncdf_isatt('thin_method'))THEN ! added at V1.1
99 data%thin_method = ' ' ; CALL ncdf_getatt('thin_method', data%thin_method)
100ENDIF
101 data%software_version = ' ' ; CALL ncdf_getatt('software_version', data%software_version)
102
103 IF (proc_date( 1: 4) /= ' ') READ(proc_date( 1: 4), *) data%DTpro%Year
104 IF (proc_date( 6: 7) /= ' ') READ(proc_date( 6: 7), *) data%DTpro%Month
105 IF (proc_date( 9:10) /= ' ') READ(proc_date( 9:10), *) data%DTpro%Day
106 IF (proc_date(12:13) /= ' ') READ(proc_date(12:13), *) data%DTpro%Hour
107 IF (proc_date(15:16) /= ' ') READ(proc_date(15:16), *) data%DTpro%Minute
108 IF (proc_date(18:19) /= ' ') READ(proc_date(18:19), *) data%DTpro%Second
109 IF (proc_date(21:23) /= ' ') READ(proc_date(21:23), *) data%DTpro%Msec
110
111! 1.5 Header variables
112! --------------------
113
114 CALL ncdf_getvar('occ_id', data%occ_id, rec = irec)
115 CALL ncdf_getvar('gns_id', data%gns_id, rec = irec)
116 CALL ncdf_getvar('leo_id', data%leo_id, rec = irec)
117 CALL ncdf_getvar('stn_id', data%stn_id, rec = irec)
118
119! 1.6 Date and time
120! -----------------
121
122 CALL ncdf_getvar('start_time', start_time, rec=irec)
123 CALL ncdf_getvar('year', data%DTocc%Year, &
124 units = data%DTocc%units%Year, &
125 range = data%DTocc%range%Year, &
126 rec = irec)
127 CALL ncdf_getvar('month', data%DTocc%Month, &
128 units = data%DTocc%units%Month, &
129 range = data%DTocc%range%Month, &
130 rec = irec)
131 CALL ncdf_getvar('day', data%DTocc%Day, &
132 units = data%DTocc%units%Day, &
133 range = data%DTocc%range%Day, &
134 rec = irec)
135 CALL ncdf_getvar('hour', data%DTocc%Hour, &
136 units = data%DTocc%units%Hour, &
137 range = data%DTocc%range%Hour, &
138 rec = irec)
139 CALL ncdf_getvar('minute', data%DTocc%Minute, &
140 units = data%DTocc%units%Minute, &
141 range = data%DTocc%range%Minute, &
142 rec = irec)
143 CALL ncdf_getvar('second', data%DTocc%Second, &
144 units = data%DTocc%units%Second, &
145 range = data%DTocc%range%Second, &
146 rec = irec)
147 CALL ncdf_getvar('msec', data%DTocc%Msec, &
148 units = data%DTocc%units%Msec, &
149 range = data%DTocc%range%Msec, &
150 rec = irec)
151
152! 1.6.1 Check consistency: start_time and DTocc (if both are valid)
153! should refer to the same epoch within 1ms. Issue a warning if not.
154
155 CALL Date_and_Time_UTC(Values=DT8)
156
157 CALL TimeSince(DT8, now_time, 1, Base="JS2000")
158
159 IF (isroppinrange(data%DTocc)) THEN
160 IF ( isinrange(start_time, (/ 0.001_dp, now_time /)) ) THEN
161 DT8 = (/ data%DTocc%Year, data%DTocc%Month, data%DTocc%Day, 0, &
162 data%DTocc%Hour, data%DTocc%Minute, data%DTocc%Second, &
163 data%DTocc%Msec /)
164 CALL TimeSince(DT8, dtocc_time, 1, Base="JS2000")
165 time = ABS(start_time - dtocc_time)
166 IF ( time > 0.0005_dp ) THEN
167 WRITE ( cval, FMT="(F15.3)" ) time
168 CALL message(msg_warn, "'start_time' and yr/mo/dy/hr/mn/sc/ms " // &
169 "timestamps differ by " // &
170 TRIM(ADJUSTL(cval))//" seconds - using yr/../ms timestamp")
171 END IF
172 END IF
173
174! If any DTocc element is invalid, substitute converted start_time
175! (if that is valid) and issue a warning.
176 ELSE
177
178 IF ( isinrange(start_time, (/ 0.001_dp, now_time /)) ) THEN
179 CALL message(msg_warn, "One or more of yr/mo/dy/hr/mn/sc/ms times " // &
180 "are invalid - using 'start_time' instead")
181 CALL TimeSince(DT8, start_time, -1, Base="JS2000")
182 data%DTocc%Year = DT8(1)
183 data%DTocc%Month = DT8(2)
184 data%DTocc%Day = DT8(3)
185 data%DTocc%Hour = DT8(5)
186 data%DTocc%Minute = DT8(6)
187 data%DTocc%Second = DT8(7)
188 data%DTocc%Msec = DT8(8)
189 END IF
190
191! NB if neither DTocc nor start_time are valid, do nothing here; missing
192! coordinates should be dealt with as part of generic Q/C.
193 END IF
194
195! 1.7 Overall quality
196! -------------------
197
198 CALL ncdf_getvar('pcd', data%pcd, &
199 units = data%units%pcd, &
200 range = data%range%pcd, &
201 rec = irec)
202 CALL ncdf_getvar('overall_qual', data%overall_qual, &
203 units = data%units%overall_qual, &
204 range = data%range%overall_qual, &
205 rec = irec)
206
207! 1.8 Georeferencing
208! ------------------
209
210 CALL ncdf_getvar('time', time, rec=irec)
211 CALL ncdf_getvar('lat', data%georef%lat, &
212 units = data%georef%units%lat, &
213 range = data%georef%range%lat, &
214 rec = irec)
215 CALL ncdf_getvar('lon', data%georef%lon, &
216 units = data%georef%units%lon, &
217 range = data%georef%range%lon, &
218 rec = irec)
219 CALL ncdf_getvar('time_offset', data%georef%time_offset, &
220 units = data%georef%units%time_offset, &
221 range = data%georef%range%time_offset, &
222 rec = irec)
223 CALL ncdf_getvar('undulation', data%georef%Undulation, &
224 units = data%georef%units%Undulation, &
225 range = data%georef%range%undulation, &
226 rec = irec)
227 CALL ncdf_getvar('roc', data%georef%roc, &
228 units = data%georef%units%roc, &
229 range = data%georef%range%roc, &
230 rec = irec)
231 CALL ncdf_getvar('r_coc', data%georef%r_coc, &
232 units = data%georef%units%r_coc, &
233 range = data%georef%range%r_coc, &
234 rec = irec)
235 CALL ncdf_getvar('azimuth', data%georef%azimuth, &
236 units = data%georef%units%azimuth, &
237 range = data%georef%range%azimuth, &
238 rec = irec)
239
240! 1.8.1 Other attributes
241
242 CALL ncdf_getatt('reference_frame', data%georef%reference_frame%r_coc, varname= 'r_coc')
243
244! 1.9 Background characterisation (if any)
245! ----------------------------------------
246
247 IF (ncdf_isvar('bg_source')) THEN
248 data%BG%Source = 'TBD'
249 ELSE
250 data%BG%Source = 'NONE'
251 ENDIF
252
253 IF (data%BG%Source /= 'NONE') THEN
254 CALL ncdf_getvar('bg_source', data%BG%Source, rec = irec)
255 CALL ncdf_getvar('bg_year', data%BG%Year, &
256 units = data%BG%units%Year, &
257 range = data%BG%range%Year, &
258 rec = irec)
259 CALL ncdf_getvar('bg_month', data%BG%Month, &
260 units = data%BG%units%Month, &
261 range = data%BG%range%Month, &
262 rec = irec)
263 CALL ncdf_getvar('bg_day', data%BG%Day, &
264 units = data%BG%units%Day, &
265 range = data%BG%range%Day, &
266 rec = irec)
267 CALL ncdf_getvar('bg_hour', data%BG%Hour, &
268 units = data%BG%units%Hour, &
269 range = data%BG%range%Hour, &
270 rec = irec)
271 CALL ncdf_getvar('bg_minute', data%BG%Minute, &
272 units = data%BG%units%Minute, &
273 range = data%BG%range%Minute, &
274 rec = irec)
275 CALL ncdf_getvar('bg_fcperiod', data%BG%fcPeriod, &
276 units = data%BG%units%fcPeriod, &
277 range = data%BG%range%fcPeriod, &
278 rec = irec)
279 ENDIF
280
281! 1.10 Level1a variables (if any)
282! ------------------------------
283
284 IF (ncdf_isvar('dtime')) THEN
285 CALL ncdf_getsize('dtime', n, dim = 1)
286 CALL ropp_io_init(data%Lev1a, n)
287 ELSE
288 data%Lev1a%Npoints = 0
289 ENDIF
290
291 IF (data%Lev1a%Npoints > 0) THEN
292 CALL ncdf_getvar('dtime', data%Lev1a%dtime, &
293 units = data%Lev1a%units%dtime, &
294 range = data%Lev1a%range%dtime, &
295 rec = irec)
296 CALL ncdf_getvar('snr_L1ca', data%Lev1a%snr_L1ca, &
297 units = data%Lev1a%units%snr, &
298 range = data%Lev1a%range%snr, &
299 rec = irec)
300 CALL ncdf_getvar('snr_L1p', data%Lev1a%snr_L1p, &
301 units = data%Lev1a%units%snr, &
302 range = data%Lev1a%range%snr, &
303 rec = irec)
304 CALL ncdf_getvar('snr_L2p', data%Lev1a%snr_L2p, &
305 units = data%Lev1a%units%snr, &
306 range = data%Lev1a%range%snr, &
307 rec = irec)
308 CALL ncdf_getvar('phase_L1', data%Lev1a%phase_L1, &
309 units = data%Lev1a%units%phase, &
310 range = data%Lev1a%range%phase, &
311 rec = irec)
312 CALL ncdf_getvar('phase_L2', data%Lev1a%phase_L2, &
313 units = data%Lev1a%units%phase, &
314 range = data%Lev1a%range%phase, &
315 rec = irec)
316 CALL ncdf_getvar('r_gns', data%Lev1a%r_gns, &
317 units = data%Lev1a%units%r_gns, &
318 range = data%Lev1a%range%r_gns, &
319 rec = irec)
320 CALL ncdf_getvar('v_gns', data%Lev1a%v_gns, &
321 units = data%Lev1a%units%v_gns, &
322 range = data%Lev1a%range%v_gns, &
323 rec = irec)
324 CALL ncdf_getvar('r_leo', data%Lev1a%r_leo, &
325 units = data%Lev1a%units%r_leo, &
326 range = data%Lev1a%range%r_leo, &
327 rec = irec)
328 CALL ncdf_getvar('v_leo', data%Lev1a%v_leo, &
329 units = data%Lev1a%units%v_leo, &
330 range = data%Lev1a%range%v_leo, &
331 rec = irec)
332 CALL ncdf_getvar('phase_qual', data%Lev1a%phase_qual, &
333 units = data%Lev1a%units%phase_qual, &
334 range = data%Lev1a%range%phase_qual, &
335 rec = irec)
336! 1.10.1 Other attributes
337
338 CALL ncdf_getatt('reference_frame', data%Lev1a%reference_frame%r_gns, varname = 'r_gns')
339 CALL ncdf_getatt('reference_frame', data%Lev1a%reference_frame%v_gns, varname = 'v_gns')
340 CALL ncdf_getatt('reference_frame', data%Lev1a%reference_frame%r_leo, varname = 'r_leo')
341 CALL ncdf_getatt('reference_frame', data%Lev1a%reference_frame%v_leo, varname = 'v_leo')
342
343 data%Lev1a%Missing = .FALSE.
344 ENDIF
345
346! 1.11 Level1b variables (if any)
347! -------------------------------
348
349 IF (ncdf_isvar('lat_tp')) THEN
350 CALL ncdf_getsize('lat_tp', n, dim = 1)
351 CALL ropp_io_init(data%Lev1b, n)
352 ELSE
353 data%Lev1b%Npoints = 0
354 ENDIF
355
356 IF (data%Lev1b%Npoints > 0) THEN
357
358 CALL ncdf_getvar('lat_tp', data%Lev1b%lat_tp, &
359 units = data%Lev1b%units%lat_tp, &
360 range = data%Lev1b%range%lat_tp, &
361 rec = irec)
362 CALL ncdf_getvar('lon_tp', data%Lev1b%lon_tp, &
363 units = data%Lev1b%units%lon_tp, &
364 range = data%Lev1b%range%lon_tp, &
365 rec = irec)
366 CALL ncdf_getvar('azimuth_tp', data%Lev1b%azimuth_tp, &
367 units = data%Lev1b%units%azimuth_tp, &
368 range = data%Lev1b%range%azimuth_tp, &
369 rec = irec)
370
371 CALL ncdf_getvar('impact_L1', data%Lev1b%impact_L1, &
372 units = data%Lev1b%units%impact, &
373 range = data%Lev1b%range%impact, &
374 rec = irec)
375 CALL ncdf_getvar('impact_L2', data%Lev1b%impact_L2, &
376 units = data%Lev1b%units%impact, &
377 range = data%Lev1b%range%impact, &
378 rec = irec)
379 CALL ncdf_getvar('impact', data%Lev1b%impact, &
380 units = data%Lev1b%units%impact, &
381 range = data%Lev1b%range%impact, &
382 rec = irec)
383 IF (ncdf_isvar('impact_opt')) & ! added at v1.1
384 CALL ncdf_getvar('impact_opt', data%Lev1b%impact_opt, &
385 units = data%Lev1b%units%impact, &
386 range = data%Lev1b%range%impact, &
387 rec = irec)
388
389 CALL ncdf_getvar('bangle_L1', data%Lev1b%bangle_L1, &
390 units = data%Lev1b%units%bangle, &
391 range = data%Lev1b%range%bangle, &
392 rec = irec)
393 CALL ncdf_getvar('bangle_L2', data%Lev1b%bangle_L2, &
394 units = data%Lev1b%units%bangle, &
395 range = data%Lev1b%range%bangle, &
396 rec = irec)
397 CALL ncdf_getvar('bangle', data%Lev1b%bangle, &
398 units = data%Lev1b%units%bangle, &
399 range = data%Lev1b%range%bangle, &
400 rec = irec)
401 IF (ncdf_isvar('bangle_opt')) & ! added at v1.1
402 CALL ncdf_getvar('bangle_opt', data%Lev1b%bangle_opt, &
403 units = data%Lev1b%units%bangle, &
404 range = data%Lev1b%range%bangle, &
405 rec = irec)
406
407 CALL ncdf_getvar('bangle_L1_sigma', data%Lev1b%bangle_L1_sigma, &
408 units = data%Lev1b%units%bangle_sigma, &
409 range = data%Lev1b%range%bangle_sigma, &
410 rec = irec)
411 CALL ncdf_getvar('bangle_L2_sigma', data%Lev1b%bangle_L2_sigma, &
412 units = data%Lev1b%units%bangle_sigma, &
413 range = data%Lev1b%range%bangle_sigma, &
414 rec = irec)
415 CALL ncdf_getvar('bangle_sigma', data%Lev1b%bangle_sigma, &
416 units = data%Lev1b%units%bangle_sigma, &
417 range = data%Lev1b%range%bangle_sigma, &
418 rec = irec)
419 IF (ncdf_isvar('bangle_opt_sigma')) & ! added at v1.1
420 CALL ncdf_getvar('bangle_opt_sigma', data%Lev1b%bangle_opt_sigma, &
421 units = data%Lev1b%units%bangle_sigma, &
422 range = data%Lev1b%range%bangle_sigma, &
423 rec = irec)
424
425 CALL ncdf_getvar('bangle_L1_qual', data%Lev1b%bangle_L1_qual, &
426 units = data%Lev1b%units%bangle_qual, &
427 range = data%Lev1b%range%bangle_qual, &
428 rec = irec)
429 CALL ncdf_getvar('bangle_L2_qual', data%Lev1b%bangle_L2_qual, &
430 units = data%Lev1b%units%bangle_qual, &
431 range = data%Lev1b%range%bangle_qual, &
432 rec = irec)
433 CALL ncdf_getvar('bangle_qual', data%Lev1b%bangle_qual, &
434 units = data%Lev1b%units%bangle_qual, &
435 range = data%Lev1b%range%bangle_qual, &
436 rec = irec)
437 IF (ncdf_isvar('bangle_opt_qual')) & ! added at v1.1
438 CALL ncdf_getvar('bangle_opt_qual', data%Lev1b%bangle_opt_qual, &
439 units = data%Lev1b%units%bangle_qual, &
440 range = data%Lev1b%range%bangle_qual, &
441 rec = irec)
442 data%Lev1b%Missing = .FALSE.
443 ENDIF
444
445! 1.12 Level2a variables (if any)
446! -------------------------------
447
448 IF (ncdf_isvar('alt_refrac')) THEN
449 CALL ncdf_getsize('alt_refrac', n, dim = 1)
450 CALL ropp_io_init(data%Lev2a, n)
451 ELSE
452 data%Lev2a%Npoints = 0
453 ENDIF
454
455 IF (data%Lev2a%Npoints > 0) THEN
456
457 CALL ncdf_getvar('alt_refrac', data%Lev2a%alt_refrac, &
458 units = data%Lev2a%units%alt_refrac, &
459 range = data%Lev2a%range%alt_refrac, &
460 rec = irec)
461 CALL ncdf_getvar('geop_refrac', data%Lev2a%geop_refrac, &
462 units = data%Lev2a%units%geop_refrac, &
463 range = data%Lev2a%range%geop_refrac, &
464 rec = irec)
465 CALL ncdf_getvar('refrac', data%Lev2a%refrac, &
466 units = data%Lev2a%units%refrac, &
467 range = data%Lev2a%range%refrac, &
468 rec = irec)
469 CALL ncdf_getvar('refrac_sigma', data%Lev2a%refrac_sigma, &
470 units = data%Lev2a%units%refrac_sigma, &
471 range = data%Lev2a%range%refrac_sigma, &
472 rec = irec)
473 CALL ncdf_getvar('refrac_qual', data%Lev2a%refrac_qual, &
474 units = data%Lev2a%units%refrac_qual, &
475 range = data%Lev2a%range%refrac_qual, &
476 rec = irec)
477 IF (ncdf_isvar('dry_temp')) THEN !For backward compatibility
478 CALL ncdf_getvar('dry_temp', data%Lev2a%dry_temp, &
479 units = data%Lev2a%units%dry_temp, &
480 range = data%Lev2a%range%dry_temp, &
481 rec = irec)
482 CALL ncdf_getvar('dry_temp_sigma', data%Lev2a%dry_temp_sigma, &
483 units = data%Lev2a%units%dry_temp_sigma, &
484 range = data%Lev2a%range%dry_temp_sigma, &
485 rec = irec)
486 CALL ncdf_getvar('dry_temp_qual', data%Lev2a%dry_temp_qual, &
487 units = data%Lev2a%units%dry_temp_qual, &
488 range = data%Lev2a%range%dry_temp_qual, &
489 rec = irec)
490 ENDIF
491 data%Lev2a%Missing = .FALSE.
492 ENDIF
493
494! 1.13 Level2b variables (if any)
495! -------------------------------
496
497 IF (ncdf_isvar('geop')) THEN
498 CALL ncdf_getsize('geop', n, dim = 1)
499 CALL ropp_io_init(data%Lev2b, n)
500 ELSE
501 data%Lev2b%Npoints = 0
502 ENDIF
503
504 IF (data%Lev2b%Npoints > 0) THEN
505
506 CALL ncdf_getvar('geop', data%Lev2b%geop, &
507 units = data%Lev2b%units%geop, &
508 range = data%Lev2b%range%geop, &
509 rec = irec)
510 CALL ncdf_getvar('geop_sigma', data%Lev2b%geop_sigma, &
511 units = data%Lev2b%units%geop_sigma, &
512 range = data%Lev2b%range%geop_sigma, &
513 rec = irec)
514 CALL ncdf_getvar('press', data%Lev2b%press, &
515 units = data%Lev2b%units%press, &
516 range = data%Lev2b%range%press, &
517 rec = irec)
518 CALL ncdf_getvar('press_sigma', data%Lev2b%press_sigma, &
519 units = data%Lev2b%units%press_sigma, &
520 range = data%Lev2b%range%press_sigma, &
521 rec = irec)
522 CALL ncdf_getvar('temp', data%Lev2b%temp, &
523 units = data%Lev2b%units%temp, &
524 range = data%Lev2b%range%temp, &
525 rec = irec)
526 CALL ncdf_getvar('temp_sigma', data%Lev2b%temp_sigma, &
527 units = data%Lev2b%units%temp_sigma, &
528 range = data%Lev2b%range%temp_sigma, &
529 rec = irec)
530 CALL ncdf_getvar('shum', data%Lev2b%shum, &
531 units = data%Lev2b%units%shum, &
532 range = data%Lev2b%range%shum, &
533 rec = irec)
534 CALL ncdf_getvar('shum_sigma', data%Lev2b%shum_sigma, &
535 units = data%Lev2b%units%shum_sigma, &
536 range = data%Lev2b%range%shum_sigma, &
537 rec = irec)
538 CALL ncdf_getvar('meteo_qual', data%Lev2b%meteo_qual, &
539 units = data%Lev2b%units%meteo_qual, &
540 range = data%Lev2b%range%meteo_qual, &
541 rec = irec)
542
543 data%Lev2b%Missing = .FALSE.
544 ENDIF
545
546! 1.14 Level2c variables (if any)
547! -------------------------------
548
549 IF (ncdf_isvar('geop_sfc')) THEN
550 data%Lev2c%Npoints = 1
551 ELSE
552 data%Lev2c%Npoints = 0
553 ENDIF
554
555 IF (data%Lev2c%Npoints > 0) THEN
556
557 CALL ncdf_getvar('geop_sfc', data%Lev2c%geop_sfc, &
558 units = data%Lev2c%units%geop_sfc, &
559 range = data%Lev2c%range%geop_sfc, &
560 rec = irec)
561 CALL ncdf_getvar('press_sfc', data%Lev2c%press_sfc, &
562 units = data%Lev2c%units%press_sfc, &
563 range = data%Lev2c%range%press_sfc, &
564 rec = irec)
565 CALL ncdf_getvar('press_sfc_sigma', data%Lev2c%press_sfc_sigma, &
566 units = data%Lev2c%units%press_sfc_sigma, &
567 range = data%Lev2c%range%press_sfc_sigma, &
568 rec = irec)
569 CALL ncdf_getvar('press_sfc_qual', data%Lev2c%press_sfc_qual, &
570 units = data%Lev2c%units%press_sfc_qual, &
571 range = data%Lev2c%range%press_sfc_qual, &
572 rec = irec)
573
574 IF (ncdf_isvar('Ne_max')) THEN !For backward compatibility
575 CALL ncdf_getvar('Ne_max', data%Lev2c%Ne_max, &
576 units = data%Lev2c%units%Ne_max, &
577 range = data%Lev2c%range%Ne_max, &
578 rec = irec)
579 ENDIF
580 IF (ncdf_isvar('Ne_max_sigma')) THEN !For backward compatibility
581 CALL ncdf_getvar('Ne_max_sigma', data%Lev2c%Ne_max_sigma, &
582 units = data%Lev2c%units%Ne_max_sigma, &
583 range = data%Lev2c%range%Ne_max_sigma, &
584 rec = irec)
585 ENDIF
586
587 IF (ncdf_isvar('H_peak')) THEN !For backward compatibility
588 CALL ncdf_getvar('H_peak', data%Lev2c%H_peak, &
589 units = data%Lev2c%units%H_peak, &
590 range = data%Lev2c%range%H_peak, &
591 rec = irec)
592 ENDIF
593 IF (ncdf_isvar('H_peak_sigma')) THEN !For backward compatibility
594 CALL ncdf_getvar('H_peak_sigma', data%Lev2c%H_peak_sigma, &
595 units = data%Lev2c%units%H_peak_sigma, &
596 range = data%Lev2c%range%H_peak_sigma, &
597 rec = irec)
598 ENDIF
599
600 IF (ncdf_isvar('H_width')) THEN !For backward compatibility
601 CALL ncdf_getvar('H_width', data%Lev2c%H_width, &
602 units = data%Lev2c%units%H_width, &
603 range = data%Lev2c%range%H_width, &
604 rec = irec)
605 ENDIF
606 IF (ncdf_isvar('H_width_sigma')) THEN !For backward compatibility
607 CALL ncdf_getvar('H_width_sigma', data%Lev2c%H_width_sigma, &
608 units = data%Lev2c%units%H_width_sigma, &
609 range = data%Lev2c%range%H_width_sigma, &
610 rec = irec)
611 ENDIF
612
613 IF (ncdf_isvar('tph_bangle')) THEN !For backward compatibility
614 CALL ncdf_getvar('tph_bangle', data%Lev2c%tph_bangle, &
615 units = data%Lev2c%units%tph_bangle, &
616 range = data%Lev2c%range%tph_bangle, &
617 rec = irec)
618 ENDIF
619 IF (ncdf_isvar('tpa_bangle')) THEN !For backward compatibility
620 CALL ncdf_getvar('tpa_bangle', data%Lev2c%tpa_bangle, &
621 units = data%Lev2c%units%tpa_bangle, &
622 range = data%Lev2c%range%tpa_bangle, &
623 rec = irec)
624 ENDIF
625 IF (ncdf_isvar('tph_bangle_flag')) THEN !For backward compatibility
626 CALL ncdf_getvar('tph_bangle_flag', data%Lev2c%tph_bangle_flag, &
627 units = data%Lev2c%units%tph_bangle_flag, &
628 range = data%Lev2c%range%tph_bangle_flag, &
629 rec = irec)
630 ENDIF
631
632 IF (ncdf_isvar('tph_refrac')) THEN !For backward compatibility
633 CALL ncdf_getvar('tph_refrac', data%Lev2c%tph_refrac, &
634 units = data%Lev2c%units%tph_refrac, &
635 range = data%Lev2c%range%tph_refrac, &
636 rec = irec)
637 ENDIF
638 IF (ncdf_isvar('tpn_refrac')) THEN !For backward compatibility
639 CALL ncdf_getvar('tpn_refrac', data%Lev2c%tpn_refrac, &
640 units = data%Lev2c%units%tpn_refrac, &
641 range = data%Lev2c%range%tpn_refrac, &
642 rec = irec)
643 ENDIF
644 IF (ncdf_isvar('tph_refrac_flag')) THEN !For backward compatibility
645 CALL ncdf_getvar('tph_refrac_flag', data%Lev2c%tph_refrac_flag, &
646 units = data%Lev2c%units%tph_refrac_flag, &
647 range = data%Lev2c%range%tph_refrac_flag, &
648 rec = irec)
649 ENDIF
650
651 IF (ncdf_isvar('tph_tdry_lrt')) THEN !For backward compatibility
652 CALL ncdf_getvar('tph_tdry_lrt', data%Lev2c%tph_tdry_lrt, &
653 units = data%Lev2c%units%tph_tdry_lrt, &
654 range = data%Lev2c%range%tph_tdry_lrt, &
655 rec = irec)
656 ENDIF
657 IF (ncdf_isvar('tpt_tdry_lrt')) THEN !For backward compatibility
658 CALL ncdf_getvar('tpt_tdry_lrt', data%Lev2c%tpt_tdry_lrt, &
659 units = data%Lev2c%units%tpt_tdry_lrt, &
660 range = data%Lev2c%range%tpt_tdry_lrt, &
661 rec = irec)
662 ENDIF
663 IF (ncdf_isvar('tph_tdry_lrt_flag')) THEN !For backward compatibility
664 CALL ncdf_getvar('tph_tdry_lrt_flag', data%Lev2c%tph_tdry_lrt_flag, &
665 units = data%Lev2c%units%tph_tdry_lrt_flag, &
666 range = data%Lev2c%range%tph_tdry_lrt_flag, &
667 rec = irec)
668 ENDIF
669
670 IF (ncdf_isvar('tph_tdry_cpt')) THEN !For backward compatibility
671 CALL ncdf_getvar('tph_tdry_cpt', data%Lev2c%tph_tdry_cpt, &
672 units = data%Lev2c%units%tph_tdry_cpt, &
673 range = data%Lev2c%range%tph_tdry_cpt, &
674 rec = irec)
675 ENDIF
676 IF (ncdf_isvar('tpt_tdry_cpt')) THEN !For backward compatibility
677 CALL ncdf_getvar('tpt_tdry_cpt', data%Lev2c%tpt_tdry_cpt, &
678 units = data%Lev2c%units%tpt_tdry_cpt, &
679 range = data%Lev2c%range%tpt_tdry_cpt, &
680 rec = irec)
681 ENDIF
682 IF (ncdf_isvar('tph_tdry_cpt_flag')) THEN !For backward compatibility
683 CALL ncdf_getvar('tph_tdry_cpt_flag', data%Lev2c%tph_tdry_cpt_flag, &
684 units = data%Lev2c%units%tph_tdry_cpt_flag, &
685 range = data%Lev2c%range%tph_tdry_cpt_flag, &
686 rec = irec)
687 ENDIF
688
689 IF (ncdf_isvar('prh_tdry_cpt')) THEN !For backward compatibility
690 CALL ncdf_getvar('prh_tdry_cpt', data%Lev2c%prh_tdry_cpt, &
691 units = data%Lev2c%units%prh_tdry_cpt, &
692 range = data%Lev2c%range%prh_tdry_cpt, &
693 rec = irec)
694 ENDIF
695 IF (ncdf_isvar('prt_tdry_cpt')) THEN !For backward compatibility
696 CALL ncdf_getvar('prt_tdry_cpt', data%Lev2c%prt_tdry_cpt, &
697 units = data%Lev2c%units%prt_tdry_cpt, &
698 range = data%Lev2c%range%prt_tdry_cpt, &
699 rec = irec)
700 ENDIF
701 IF (ncdf_isvar('prh_tdry_cpt_flag')) THEN !For backward compatibility
702 CALL ncdf_getvar('prh_tdry_cpt_flag', data%Lev2c%prh_tdry_cpt_flag, &
703 units = data%Lev2c%units%prh_tdry_cpt_flag, &
704 range = data%Lev2c%range%prh_tdry_cpt_flag, &
705 rec = irec)
706 ENDIF
707
708 IF (ncdf_isvar('tph_temp_lrt')) THEN !For backward compatibility
709 CALL ncdf_getvar('tph_temp_lrt', data%Lev2c%tph_temp_lrt, &
710 units = data%Lev2c%units%tph_temp_lrt, &
711 range = data%Lev2c%range%tph_temp_lrt, &
712 rec = irec)
713 ENDIF
714 IF (ncdf_isvar('tpt_temp_lrt')) THEN !For backward compatibility
715 CALL ncdf_getvar('tpt_temp_lrt', data%Lev2c%tpt_temp_lrt, &
716 units = data%Lev2c%units%tpt_temp_lrt, &
717 range = data%Lev2c%range%tpt_temp_lrt, &
718 rec = irec)
719 ENDIF
720 IF (ncdf_isvar('tph_temp_lrt_flag')) THEN !For backward compatibility
721 CALL ncdf_getvar('tph_temp_lrt_flag', data%Lev2c%tph_temp_lrt_flag, &
722 units = data%Lev2c%units%tph_temp_lrt_flag, &
723 range = data%Lev2c%range%tph_temp_lrt_flag, &
724 rec = irec)
725 ENDIF
726
727 IF (ncdf_isvar('tph_temp_cpt')) THEN !For backward compatibility
728 CALL ncdf_getvar('tph_temp_cpt', data%Lev2c%tph_temp_cpt, &
729 units = data%Lev2c%units%tph_temp_cpt, &
730 range = data%Lev2c%range%tph_temp_cpt, &
731 rec = irec)
732 ENDIF
733 IF (ncdf_isvar('tpt_temp_cpt')) THEN !For backward compatibility
734 CALL ncdf_getvar('tpt_temp_cpt', data%Lev2c%tpt_temp_cpt, &
735 units = data%Lev2c%units%tpt_temp_cpt, &
736 range = data%Lev2c%range%tpt_temp_cpt, &
737 rec = irec)
738 ENDIF
739 IF (ncdf_isvar('tph_temp_cpt_flag')) THEN !For backward compatibility
740 CALL ncdf_getvar('tph_temp_cpt_flag', data%Lev2c%tph_temp_cpt_flag, &
741 units = data%Lev2c%units%tph_temp_cpt_flag, &
742 range = data%Lev2c%range%tph_temp_cpt_flag, &
743 rec = irec)
744 ENDIF
745
746 IF (ncdf_isvar('prh_temp_cpt')) THEN !For backward compatibility
747 CALL ncdf_getvar('prh_temp_cpt', data%Lev2c%prh_temp_cpt, &
748 units = data%Lev2c%units%prh_temp_cpt, &
749 range = data%Lev2c%range%prh_temp_cpt, &
750 rec = irec)
751 ENDIF
752 IF (ncdf_isvar('prt_temp_cpt')) THEN !For backward compatibility
753 CALL ncdf_getvar('prt_temp_cpt', data%Lev2c%prt_temp_cpt, &
754 units = data%Lev2c%units%prt_temp_cpt, &
755 range = data%Lev2c%range%prt_temp_cpt, &
756 rec = irec)
757 ENDIF
758 IF (ncdf_isvar('prh_temp_cpt_flag')) THEN !For backward compatibility
759 CALL ncdf_getvar('prh_temp_cpt_flag', data%Lev2c%prh_temp_cpt_flag, &
760 units = data%Lev2c%units%prh_temp_cpt_flag, &
761 range = data%Lev2c%range%prh_temp_cpt_flag, &
762 rec = irec)
763 ENDIF
764
765 IF (ncdf_isvar('pblh_bangle')) THEN !For backward compatibility
766 CALL ncdf_getvar('pblh_bangle', data%Lev2c%pblh_bangle, &
767 units = data%Lev2c%units%pblh_bangle, &
768 range = data%Lev2c%range%pblh_bangle, &
769 rec = irec)
770 ENDIF
771 IF (ncdf_isvar('pbla_bangle')) THEN !For backward compatibility
772 CALL ncdf_getvar('pbla_bangle', data%Lev2c%pbla_bangle, &
773 units = data%Lev2c%units%pbla_bangle, &
774 range = data%Lev2c%range%pbla_bangle, &
775 rec = irec)
776 ENDIF
777 IF (ncdf_isvar('pblh_bangle_flag')) THEN !For backward compatibility
778 CALL ncdf_getvar('pblh_bangle_flag', data%Lev2c%pblh_bangle_flag, &
779 units = data%Lev2c%units%pblh_bangle_flag, &
780 range = data%Lev2c%range%pblh_bangle_flag, &
781 rec = irec)
782 ENDIF
783
784 IF (ncdf_isvar('pblh_refrac')) THEN !For backward compatibility
785 CALL ncdf_getvar('pblh_refrac', data%Lev2c%pblh_refrac, &
786 units = data%Lev2c%units%pblh_refrac, &
787 range = data%Lev2c%range%pblh_refrac, &
788 rec = irec)
789 ENDIF
790 IF (ncdf_isvar('pbln_refrac')) THEN !For backward compatibility
791 CALL ncdf_getvar('pbln_refrac', data%Lev2c%pbln_refrac, &
792 units = data%Lev2c%units%pbln_refrac, &
793 range = data%Lev2c%range%pbln_refrac, &
794 rec = irec)
795 ENDIF
796 IF (ncdf_isvar('pblh_refrac_flag')) THEN !For backward compatibility
797 CALL ncdf_getvar('pblh_refrac_flag', data%Lev2c%pblh_refrac_flag, &
798 units = data%Lev2c%units%pblh_refrac_flag, &
799 range = data%Lev2c%range%pblh_refrac_flag, &
800 rec = irec)
801 ENDIF
802
803 IF (ncdf_isvar('pblh_tdry')) THEN !For backward compatibility
804 CALL ncdf_getvar('pblh_tdry', data%Lev2c%pblh_tdry, &
805 units = data%Lev2c%units%pblh_tdry, &
806 range = data%Lev2c%range%pblh_tdry, &
807 rec = irec)
808 ENDIF
809 IF (ncdf_isvar('pblt_tdry')) THEN !For backward compatibility
810 CALL ncdf_getvar('pblt_tdry', data%Lev2c%pblt_tdry, &
811 units = data%Lev2c%units%pblt_tdry, &
812 range = data%Lev2c%range%pblt_tdry, &
813 rec = irec)
814 ENDIF
815 IF (ncdf_isvar('pblh_tdry_flag')) THEN !For backward compatibility
816 CALL ncdf_getvar('pblh_tdry_flag', data%Lev2c%pblh_tdry_flag, &
817 units = data%Lev2c%units%pblh_tdry_flag, &
818 range = data%Lev2c%range%pblh_tdry_flag, &
819 rec = irec)
820 ENDIF
821
822 IF (ncdf_isvar('pblh_temp')) THEN !For backward compatibility
823 CALL ncdf_getvar('pblh_temp', data%Lev2c%pblh_temp, &
824 units = data%Lev2c%units%pblh_temp, &
825 range = data%Lev2c%range%pblh_temp, &
826 rec = irec)
827 ENDIF
828 IF (ncdf_isvar('pblt_temp')) THEN !For backward compatibility
829 CALL ncdf_getvar('pblt_temp', data%Lev2c%pblt_temp, &
830 units = data%Lev2c%units%pblt_temp, &
831 range = data%Lev2c%range%pblt_temp, &
832 rec = irec)
833 ENDIF
834 IF (ncdf_isvar('pblh_temp_flag')) THEN !For backward compatibility
835 CALL ncdf_getvar('pblh_temp_flag', data%Lev2c%pblh_temp_flag, &
836 units = data%Lev2c%units%pblh_temp_flag, &
837 range = data%Lev2c%range%pblh_temp_flag, &
838 rec = irec)
839 ENDIF
840
841 IF (ncdf_isvar('pblh_shum')) THEN !For backward compatibility
842 CALL ncdf_getvar('pblh_shum', data%Lev2c%pblh_shum, &
843 units = data%Lev2c%units%pblh_shum, &
844 range = data%Lev2c%range%pblh_shum, &
845 rec = irec)
846 ENDIF
847 IF (ncdf_isvar('pblq_shum')) THEN !For backward compatibility
848 CALL ncdf_getvar('pblq_shum', data%Lev2c%pblq_shum, &
849 units = data%Lev2c%units%pblq_shum, &
850 range = data%Lev2c%range%pblq_shum, &
851 rec = irec)
852 ENDIF
853 IF (ncdf_isvar('pblh_shum_flag')) THEN !For backward compatibility
854 CALL ncdf_getvar('pblh_shum_flag', data%Lev2c%pblh_shum_flag, &
855 units = data%Lev2c%units%pblh_shum_flag, &
856 range = data%Lev2c%range%pblh_shum_flag, &
857 rec = irec)
858 ENDIF
859
860 IF (ncdf_isvar('pblh_rhum')) THEN !For backward compatibility
861 CALL ncdf_getvar('pblh_rhum', data%Lev2c%pblh_rhum, &
862 units = data%Lev2c%units%pblh_rhum, &
863 range = data%Lev2c%range%pblh_rhum, &
864 rec = irec)
865 ENDIF
866 IF (ncdf_isvar('pblr_rhum')) THEN !For backward compatibility
867 CALL ncdf_getvar('pblr_rhum', data%Lev2c%pblr_rhum, &
868 units = data%Lev2c%units%pblr_rhum, &
869 range = data%Lev2c%range%pblr_rhum, &
870 rec = irec)
871 ENDIF
872 IF (ncdf_isvar('pblh_rhum_flag')) THEN !For backward compatibility
873 CALL ncdf_getvar('pblh_rhum_flag', data%Lev2c%pblh_rhum_flag, &
874 units = data%Lev2c%units%pblh_rhum_flag, &
875 range = data%Lev2c%range%pblh_rhum_flag, &
876 rec = irec)
877 ENDIF
878
879 data%Lev2c%Missing = .FALSE.
880
881 ENDIF
882
883! 1.15 Level2d variables (if any)
884! -------------------------------
885
886 IF (ncdf_isvar('level_coeff_a')) THEN
887 CALL ncdf_getsize('level_coeff_a', n, dim = 1)
888 CALL ropp_io_init(data%Lev2d, n)
889 ELSE
890 data%Lev2d%Npoints = 0
891 ENDIF
892
893 IF (data%Lev2d%Npoints > 0) THEN
894
895 CALL ncdf_getvar('level_type', data%Lev2d%level_type, &
896 rec = irec)
897 CALL ncdf_getvar('level_coeff_a', data%Lev2d%level_coeff_a, &
898 units = data%Lev2d%units%level_coeff_a, &
899 range = data%Lev2d%range%level_coeff_a, &
900 rec = irec)
901 CALL ncdf_getvar('level_coeff_b', data%Lev2d%level_coeff_b, &
902 units = data%Lev2d%units%level_coeff_b, &
903 range = data%Lev2d%range%level_coeff_b, &
904 rec = irec)
905
906 data%Lev2d%Missing = .FALSE.
907 ENDIF
908
909! 1.16 Additional variables (if any)
910! ----------------------------------
911
912 CALL ropp_io_init(data%vlist)
913
914 DO varid=1,ncdf_nvars
915
916 IF(.NOT. ncdf_read(varid))THEN
917
918 status = nf90_inquire_variable(ncdf_ncid, varid, xtype=TYPE, ndims=ndim)
919
920 IF (TYPE .NE. NF90_CHAR) THEN ! only read scalar variables
921
922 IF(ndim == 1)THEN
923 CALL ropp_io_read_ncdf_get_vlistD0d(varid, data%vlist%VlistD0d, irec)
924 ENDIF
925 IF(ndim == 2)THEN
926 CALL ropp_io_read_ncdf_get_vlistD1d(varid, data%vlist%VlistD1d, irec)
927 ENDIF
928 IF(ndim == 3)THEN
929 CALL ropp_io_read_ncdf_get_vlistD2d(varid, data%vlist%VlistD2d, irec)
930 ENDIF
931 ENDIF
932
933 ENDIF
934
935 ncdf_read(varid) = .FALSE. ! reset 'read variable' flag
936 ENDDO
937
938! 1.17 Clean up
939! -------------
940
941 CALL message_set_routine(routine)
942
943END SUBROUTINE ropp_io_read_ncdf_get_rodata
944
945
946!-------------------------------------------------------------------------------
947! 2. Core RO data (two-dimensional meteorological data)
948!-------------------------------------------------------------------------------
949
950SUBROUTINE ropp_io_read_ncdf_get_rodata_2d(DATA, rec)
951
952! 2.1 Declarations
953! ----------------
954
955 USE ropp_utils
956 USE ncdf
957 USE ropp_io, not_this => ropp_io_read_ncdf_get_rodata_2d
958 USE ropp_io_types, ONLY: ROprof2d, &
959 ThisFmtVer
960
961 IMPLICIT NONE
962
963 TYPE(ROprof2d), INTENT(inout) :: DATA
964 INTEGER, OPTIONAL :: rec
965
966 INTEGER :: n, ierr
967 INTEGER :: irec
968 INTEGER, DIMENSION(2) :: n2d
969
970 INTEGER, DIMENSION(8) :: DT8 ! Date/time array
971
972 CHARACTER(LEN=15) :: cval
973
974 REAL(dp) :: time, start_time, dtocc_time, now_time !dp defined in DateTimeTypes
975 CHARACTER(len = 23) :: proc_date
976 CHARACTER(len = 256) :: routine
977
978 REAL :: fmtver
979
980 INTEGER :: status, varid, ndim, TYPE
981
982! 2.2 Error handling
983! ------------------
984
985 CALL message_get_routine(routine)
986 CALL message_set_routine('ropp_io_read_ncdf_get')
987
988! 2.3 Default parameters
989! ----------------------
990
991 IF (PRESENT(rec)) THEN
992 irec = rec
993 ELSE
994 irec = 1
995 ENDIF
996
997! 2.4 (Global) Attributes
998! ------------------------
999
1000 data%FmtVersion = ' ' ; CALL ncdf_getatt('format_version', data%FmtVersion)
1001 READ ( data%FmtVersion(11:), fmt=*, iostat=ierr ) fmtver
1002 IF ( ierr /= 0 ) data%FmtVersion = ThisFmtVer
1003 data%processing_centre = ' ' ; CALL ncdf_getatt('processing_centre', data%processing_centre)
1004 IF (ncdf_isatt('processing_software')) THEN ! added at V8.0
1005 data%processing_software = ' ' ; CALL ncdf_getatt('processing_software', data%processing_software)
1006 ENDIF
1007 proc_date = ' ' ; CALL ncdf_getatt('processing_date', proc_date)
1008 data%pod_method = ' ' ; CALL ncdf_getatt('pod_method', data%pod_method)
1009 data%phase_method = ' ' ; CALL ncdf_getatt('phase_method', data%phase_method)
1010 data%bangle_method = ' ' ; CALL ncdf_getatt('bangle_method', data%bangle_method)
1011 data%refrac_method = ' ' ; CALL ncdf_getatt('refrac_method', data%refrac_method)
1012 data%meteo_method = ' ' ; CALL ncdf_getatt('meteo_method', data%meteo_method)
1013IF(ncdf_isatt('thin_method'))THEN ! added at V1.1
1014 data%thin_method = ' ' ; CALL ncdf_getatt('thin_method', data%thin_method)
1015ENDIF
1016 data%software_version = ' ' ; CALL ncdf_getatt('software_version', data%software_version)
1017
1018 IF (proc_date( 1: 4) /= ' ') READ(proc_date( 1: 4), *) data%DTpro%Year
1019 IF (proc_date( 6: 7) /= ' ') READ(proc_date( 6: 7), *) data%DTpro%Month
1020 IF (proc_date( 9:10) /= ' ') READ(proc_date( 9:10), *) data%DTpro%Day
1021 IF (proc_date(12:13) /= ' ') READ(proc_date(12:13), *) data%DTpro%Hour
1022 IF (proc_date(15:16) /= ' ') READ(proc_date(15:16), *) data%DTpro%Minute
1023 IF (proc_date(18:19) /= ' ') READ(proc_date(18:19), *) data%DTpro%Second
1024 IF (proc_date(21:23) /= ' ') READ(proc_date(21:23), *) data%DTpro%Msec
1025
1026! 2.5 Header variables
1027! --------------------
1028
1029 CALL ncdf_getvar('occ_id', data%occ_id, rec = irec)
1030 CALL ncdf_getvar('gns_id', data%gns_id, rec = irec)
1031 CALL ncdf_getvar('leo_id', data%leo_id, rec = irec)
1032 CALL ncdf_getvar('stn_id', data%stn_id, rec = irec)
1033
1034! 2.6 Date and time
1035! -----------------
1036
1037 CALL ncdf_getvar('start_time', start_time, rec=irec)
1038 CALL ncdf_getvar('year', data%DTocc%Year, &
1039 units = data%DTocc%units%Year, &
1040 range = data%DTocc%range%Year, &
1041 rec = irec)
1042 CALL ncdf_getvar('month', data%DTocc%Month, &
1043 units = data%DTocc%units%Month, &
1044 range = data%DTocc%range%Month, &
1045 rec = irec)
1046 CALL ncdf_getvar('day', data%DTocc%Day, &
1047 units = data%DTocc%units%Day, &
1048 range = data%DTocc%range%Day, &
1049 rec = irec)
1050 CALL ncdf_getvar('hour', data%DTocc%Hour, &
1051 units = data%DTocc%units%Hour, &
1052 range = data%DTocc%range%Hour, &
1053 rec = irec)
1054 CALL ncdf_getvar('minute', data%DTocc%Minute, &
1055 units = data%DTocc%units%Minute, &
1056 range = data%DTocc%range%Minute, &
1057 rec = irec)
1058 CALL ncdf_getvar('second', data%DTocc%Second, &
1059 units = data%DTocc%units%Second, &
1060 range = data%DTocc%range%Second, &
1061 rec = irec)
1062 CALL ncdf_getvar('msec', data%DTocc%Msec, &
1063 units = data%DTocc%units%Msec, &
1064 range = data%DTocc%range%Msec, &
1065 rec = irec)
1066
1067! 2.6.1 Check consistency: start_time and DTocc (if both are valid)
1068! should refer to the same epoch within 1ms. Issue a warning if not.
1069
1070 CALL Date_and_Time_UTC(Values=DT8)
1071
1072 CALL TimeSince(DT8, now_time, 1, Base="JS2000")
1073
1074 IF (isroppinrange(data%DTocc)) THEN
1075 IF ( isinrange(start_time, (/ 0.001_dp, now_time /)) ) THEN
1076 DT8 = (/ data%DTocc%Year, data%DTocc%Month, data%DTocc%Day, 0, &
1077 data%DTocc%Hour, data%DTocc%Minute, data%DTocc%Second, &
1078 data%DTocc%Msec /)
1079 CALL TimeSince(DT8, dtocc_time, 1, Base="JS2000")
1080 time = ABS(start_time - dtocc_time)
1081 IF ( time > 0.0005_dp ) THEN
1082 WRITE ( cval, FMT="(F15.3)" ) time
1083 CALL message(msg_warn, "'start_time' and yr/mo/dy/hr/mn/sc/ms " // &
1084 "timestamps differ by " // &
1085 TRIM(ADJUSTL(cval))//" seconds - using yr/../ms timestamp")
1086 END IF
1087 END IF
1088
1089! If any DTocc element is invalid, substitute converted start_time
1090! (if that is valid) and issue a warning.
1091 ELSE
1092
1093 IF ( isinrange(start_time, (/ 0.001_dp, now_time /)) ) THEN
1094 CALL message(msg_warn, "One or more of yr/mo/dy/hr/mn/sc/ms times " // &
1095 "are invalid - using 'start_time' instead")
1096 CALL TimeSince(DT8, start_time, -1, Base="JS2000")
1097 data%DTocc%Year = DT8(1)
1098 data%DTocc%Month = DT8(2)
1099 data%DTocc%Day = DT8(3)
1100 data%DTocc%Hour = DT8(5)
1101 data%DTocc%Minute = DT8(6)
1102 data%DTocc%Second = DT8(7)
1103 data%DTocc%Msec = DT8(8)
1104 END IF
1105
1106! NB if neither DTocc nor start_time are valid, do nothing here; missing
1107! coordinates should be dealt with as part of generic Q/C.
1108 END IF
1109
1110! 2.7 Overall quality
1111! -------------------
1112
1113 CALL ncdf_getvar('pcd', data%pcd, &
1114 units = data%units%pcd, &
1115 range = data%range%pcd, &
1116 rec = irec)
1117 CALL ncdf_getvar('overall_qual', data%overall_qual, &
1118 units = data%units%overall_qual, &
1119 range = data%range%overall_qual, &
1120 rec = irec)
1121
1122! 2.8 Georeferencing
1123! ------------------
1124
1125 CALL ncdf_getvar('time', time, rec=irec)
1126 CALL ncdf_getvar('lat', data%georef%lat, &
1127 units = data%georef%units%lat, &
1128 range = data%georef%range%lat, &
1129 rec = irec)
1130 CALL ncdf_getvar('lon', data%georef%lon, &
1131 units = data%georef%units%lon, &
1132 range = data%georef%range%lon, &
1133 rec = irec)
1134 CALL ncdf_getvar('time_offset', data%georef%time_offset, &
1135 units = data%georef%units%time_offset, &
1136 range = data%georef%range%time_offset, &
1137 rec = irec)
1138 CALL ncdf_getvar('undulation', data%georef%Undulation, &
1139 units = data%georef%units%Undulation, &
1140 range = data%georef%range%undulation, &
1141 rec = irec)
1142 CALL ncdf_getvar('roc', data%georef%roc, &
1143 units = data%georef%units%roc, &
1144 range = data%georef%range%roc, &
1145 rec = irec)
1146 CALL ncdf_getvar('r_coc', data%georef%r_coc, &
1147 units = data%georef%units%r_coc, &
1148 range = data%georef%range%r_coc, &
1149 rec = irec)
1150 CALL ncdf_getvar('azimuth', data%georef%azimuth, &
1151 units = data%georef%units%azimuth, &
1152 range = data%georef%range%azimuth, &
1153 rec = irec)
1154
1155! 2.8.1 Other attributes
1156
1157 CALL ncdf_getatt('reference_frame', data%georef%reference_frame%r_coc, varname= 'r_coc')
1158
1159! 2.9 Background characterisation (if any)
1160! ----------------------------------------
1161
1162 IF (ncdf_isvar('bg_source')) THEN
1163 data%BG%Source = 'TBD'
1164 ELSE
1165 data%BG%Source = 'NONE'
1166 ENDIF
1167
1168 IF (data%BG%Source /= 'NONE') THEN
1169 CALL ncdf_getvar('bg_source', data%BG%Source, rec = irec)
1170 CALL ncdf_getvar('bg_year', data%BG%Year, &
1171 units = data%BG%units%Year, &
1172 range = data%BG%range%Year, &
1173 rec = irec)
1174 CALL ncdf_getvar('bg_month', data%BG%Month, &
1175 units = data%BG%units%Month, &
1176 range = data%BG%range%Month, &
1177 rec = irec)
1178 CALL ncdf_getvar('bg_day', data%BG%Day, &
1179 units = data%BG%units%Day, &
1180 range = data%BG%range%Day, &
1181 rec = irec)
1182 CALL ncdf_getvar('bg_hour', data%BG%Hour, &
1183 units = data%BG%units%Hour, &
1184 range = data%BG%range%Hour, &
1185 rec = irec)
1186 CALL ncdf_getvar('bg_minute', data%BG%Minute, &
1187 units = data%BG%units%Minute, &
1188 range = data%BG%range%Minute, &
1189 rec = irec)
1190 CALL ncdf_getvar('bg_fcperiod', data%BG%fcPeriod, &
1191 units = data%BG%units%fcPeriod, &
1192 range = data%BG%range%fcPeriod, &
1193 rec = irec)
1194 ENDIF
1195
1196! 2.10 Level1a variables (if any)
1197! ------------------------------
1198
1199 IF (ncdf_isvar('dtime')) THEN
1200 CALL ncdf_getsize('dtime', n, dim = 1)
1201 CALL ropp_io_init(data%Lev1a, n)
1202 ELSE
1203 data%Lev1a%Npoints = 0
1204 ENDIF
1205
1206 IF (data%Lev1a%Npoints > 0) THEN
1207
1208 CALL ncdf_getvar('dtime', data%Lev1a%dtime, &
1209 units = data%Lev1a%units%dtime, &
1210 range = data%Lev1a%range%dtime, &
1211 rec = irec)
1212 CALL ncdf_getvar('snr_L1ca', data%Lev1a%snr_L1ca, &
1213 units = data%Lev1a%units%snr, &
1214 range = data%Lev1a%range%snr, &
1215 rec = irec)
1216 CALL ncdf_getvar('snr_L1p', data%Lev1a%snr_L1p, &
1217 units = data%Lev1a%units%snr, &
1218 range = data%Lev1a%range%snr, &
1219 rec = irec)
1220 CALL ncdf_getvar('snr_L2p', data%Lev1a%snr_L2p, &
1221 units = data%Lev1a%units%snr, &
1222 range = data%Lev1a%range%snr, &
1223 rec = irec)
1224 CALL ncdf_getvar('phase_L1', data%Lev1a%phase_L1, &
1225 units = data%Lev1a%units%phase, &
1226 range = data%Lev1a%range%phase, &
1227 rec = irec)
1228 CALL ncdf_getvar('phase_L2', data%Lev1a%phase_L2, &
1229 units = data%Lev1a%units%phase, &
1230 range = data%Lev1a%range%phase, &
1231 rec = irec)
1232 CALL ncdf_getvar('r_gns', data%Lev1a%r_gns, &
1233 units = data%Lev1a%units%r_gns, &
1234 range = data%Lev1a%range%r_gns, &
1235 rec = irec)
1236 CALL ncdf_getvar('v_gns', data%Lev1a%v_gns, &
1237 units = data%Lev1a%units%v_gns, &
1238 range = data%Lev1a%range%v_gns, &
1239 rec = irec)
1240 CALL ncdf_getvar('r_leo', data%Lev1a%r_leo, &
1241 units = data%Lev1a%units%r_leo, &
1242 range = data%Lev1a%range%r_leo, &
1243 rec = irec)
1244 CALL ncdf_getvar('v_leo', data%Lev1a%v_leo, &
1245 units = data%Lev1a%units%v_leo, &
1246 range = data%Lev1a%range%v_leo, &
1247 rec = irec)
1248 CALL ncdf_getvar('phase_qual', data%Lev1a%phase_qual, &
1249 units = data%Lev1a%units%phase_qual, &
1250 range = data%Lev1a%range%phase_qual, &
1251 rec = irec)
1252
1253! 2.10.1 Other attributes
1254
1255 CALL ncdf_getatt('reference_frame', data%Lev1a%reference_frame%r_gns, varname = 'r_gns')
1256 CALL ncdf_getatt('reference_frame', data%Lev1a%reference_frame%v_gns, varname = 'v_gns')
1257 CALL ncdf_getatt('reference_frame', data%Lev1a%reference_frame%r_leo, varname = 'r_leo')
1258 CALL ncdf_getatt('reference_frame', data%Lev1a%reference_frame%v_leo, varname = 'v_leo')
1259
1260 ENDIF
1261
1262! 2.11 Level1b variables (if any)
1263! -------------------------------
1264
1265 IF (ncdf_isvar('lat_tp')) THEN
1266 CALL ncdf_getsize('lat_tp', n, dim = 1)
1267 CALL ropp_io_init(data%Lev1b, n)
1268 ELSE
1269 data%Lev1b%Npoints = 0
1270 ENDIF
1271
1272 IF (data%Lev1b%Npoints > 0) THEN
1273
1274 CALL ncdf_getvar('lat_tp', data%Lev1b%lat_tp, &
1275 units = data%Lev1b%units%lat_tp, &
1276 range = data%Lev1b%range%lat_tp, &
1277 rec = irec)
1278 CALL ncdf_getvar('lon_tp', data%Lev1b%lon_tp, &
1279 units = data%Lev1b%units%lon_tp, &
1280 range = data%Lev1b%range%lon_tp, &
1281 rec = irec)
1282 CALL ncdf_getvar('azimuth_tp', data%Lev1b%azimuth_tp, &
1283 units = data%Lev1b%units%azimuth_tp, &
1284 range = data%Lev1b%range%azimuth_tp, &
1285 rec = irec)
1286
1287 CALL ncdf_getvar('impact_L1', data%Lev1b%impact_L1, &
1288 units = data%Lev1b%units%impact, &
1289 range = data%Lev1b%range%impact, &
1290 rec = irec)
1291 CALL ncdf_getvar('impact_L2', data%Lev1b%impact_L2, &
1292 units = data%Lev1b%units%impact, &
1293 range = data%Lev1b%range%impact, &
1294 rec = irec)
1295 CALL ncdf_getvar('impact', data%Lev1b%impact, &
1296 units = data%Lev1b%units%impact, &
1297 range = data%Lev1b%range%impact, &
1298 rec = irec)
1299 IF (ncdf_isvar('impact_opt')) & ! added at v1.1
1300 CALL ncdf_getvar('impact_opt', data%Lev1b%impact_opt, &
1301 units = data%Lev1b%units%impact, &
1302 range = data%Lev1b%range%impact, &
1303 rec = irec)
1304
1305 CALL ncdf_getvar('bangle_L1', data%Lev1b%bangle_L1, &
1306 units = data%Lev1b%units%bangle, &
1307 range = data%Lev1b%range%bangle, &
1308 rec = irec)
1309 CALL ncdf_getvar('bangle_L2', data%Lev1b%bangle_L2, &
1310 units = data%Lev1b%units%bangle, &
1311 range = data%Lev1b%range%bangle, &
1312 rec = irec)
1313 CALL ncdf_getvar('bangle', data%Lev1b%bangle, &
1314 units = data%Lev1b%units%bangle, &
1315 range = data%Lev1b%range%bangle, &
1316 rec = irec)
1317 IF (ncdf_isvar('bangle_opt')) & ! added at v1.1
1318 CALL ncdf_getvar('bangle_opt', data%Lev1b%bangle_opt, &
1319 units = data%Lev1b%units%bangle, &
1320 range = data%Lev1b%range%bangle, &
1321 rec = irec)
1322
1323 CALL ncdf_getvar('bangle_L1_sigma', data%Lev1b%bangle_L1_sigma, &
1324 units = data%Lev1b%units%bangle_sigma, &
1325 range = data%Lev1b%range%bangle_sigma, &
1326 rec = irec)
1327 CALL ncdf_getvar('bangle_L2_sigma', data%Lev1b%bangle_L2_sigma, &
1328 units = data%Lev1b%units%bangle_sigma, &
1329 range = data%Lev1b%range%bangle_sigma, &
1330 rec = irec)
1331 CALL ncdf_getvar('bangle_sigma', data%Lev1b%bangle_sigma, &
1332 units = data%Lev1b%units%bangle_sigma, &
1333 range = data%Lev1b%range%bangle_sigma, &
1334 rec = irec)
1335 IF (ncdf_isvar('bangle_opt_sigma')) & ! added at v1.1
1336 CALL ncdf_getvar('bangle_opt_sigma', data%Lev1b%bangle_opt_sigma, &
1337 units = data%Lev1b%units%bangle_sigma, &
1338 range = data%Lev1b%range%bangle_sigma, &
1339 rec = irec)
1340
1341 CALL ncdf_getvar('bangle_L1_qual', data%Lev1b%bangle_L1_qual, &
1342 units = data%Lev1b%units%bangle_qual, &
1343 range = data%Lev1b%range%bangle_qual, &
1344 rec = irec)
1345 CALL ncdf_getvar('bangle_L2_qual', data%Lev1b%bangle_L2_qual, &
1346 units = data%Lev1b%units%bangle_qual, &
1347 range = data%Lev1b%range%bangle_qual, &
1348 rec = irec)
1349 CALL ncdf_getvar('bangle_qual', data%Lev1b%bangle_qual, &
1350 units = data%Lev1b%units%bangle_qual, &
1351 range = data%Lev1b%range%bangle_qual, &
1352 rec = irec)
1353 IF (ncdf_isvar('bangle_opt_qual')) & ! added at v1.1
1354 CALL ncdf_getvar('bangle_opt_qual', data%Lev1b%bangle_opt_qual, &
1355 units = data%Lev1b%units%bangle_qual, &
1356 range = data%Lev1b%range%bangle_qual, &
1357 rec = irec)
1358 ENDIF
1359
1360! 2.12 Level2a variables (if any)
1361! -------------------------------
1362
1363 IF (ncdf_isvar('alt_refrac')) THEN
1364 CALL ncdf_getsize('alt_refrac', n, dim = 1)
1365 CALL ropp_io_init(data%Lev2a, n)
1366 ELSE
1367 data%Lev2a%Npoints = 0
1368 ENDIF
1369
1370 IF (data%Lev2a%Npoints > 0) THEN
1371
1372 CALL ncdf_getvar('alt_refrac', data%Lev2a%alt_refrac, &
1373 units = data%Lev2a%units%alt_refrac, &
1374 range = data%Lev2a%range%alt_refrac, &
1375 rec = irec)
1376 CALL ncdf_getvar('geop_refrac', data%Lev2a%geop_refrac, &
1377 units = data%Lev2a%units%geop_refrac, &
1378 range = data%Lev2a%range%geop_refrac, &
1379 rec = irec)
1380 CALL ncdf_getvar('refrac', data%Lev2a%refrac, &
1381 units = data%Lev2a%units%refrac, &
1382 range = data%Lev2a%range%refrac, &
1383 rec = irec)
1384 CALL ncdf_getvar('refrac_sigma', data%Lev2a%refrac_sigma, &
1385 units = data%Lev2a%units%refrac_sigma, &
1386 range = data%Lev2a%range%refrac_sigma, &
1387 rec = irec)
1388 CALL ncdf_getvar('refrac_qual', data%Lev2a%refrac_qual, &
1389 units = data%Lev2a%units%refrac_qual, &
1390 range = data%Lev2a%range%refrac_qual, &
1391 rec = irec)
1392 IF (ncdf_isvar('dry_temp')) THEN !For backward compatibility
1393 CALL ncdf_getvar('dry_temp', data%Lev2a%dry_temp, &
1394 units = data%Lev2a%units%dry_temp, &
1395 range = data%Lev2a%range%dry_temp, &
1396 rec = irec)
1397 CALL ncdf_getvar('dry_temp_sigma', data%Lev2a%dry_temp_sigma, &
1398 units = data%Lev2a%units%dry_temp_sigma, &
1399 range = data%Lev2a%range%dry_temp_sigma, &
1400 rec = irec)
1401 CALL ncdf_getvar('dry_temp_qual', data%Lev2a%dry_temp_qual, &
1402 units = data%Lev2a%units%dry_temp_qual, &
1403 range = data%Lev2a%range%dry_temp_qual, &
1404 rec = irec)
1405 ENDIF
1406
1407 ENDIF
1408
1409! 2.13 Level2b variables (if any)
1410! -------------------------------
1411
1412 IF (ncdf_isvar('geop')) THEN
1413 n2d(1) = 0
1414 n2d(2) = 0
1415 CALL ncdf_getsize('geop', n2d)
1416 CALL ropp_io_init(data%Lev2b, n2d)
1417 ELSE
1418 data%Lev2b%Npoints = 0
1419 data%Lev2b%Nhoriz = 0
1420 ENDIF
1421
1422 IF (data%Lev2b%Npoints > 0) THEN
1423
1424 CALL ncdf_getvar('geop', data%Lev2b%geop, &
1425 units = data%Lev2b%units%geop, &
1426 range = data%Lev2b%range%geop, &
1427 rec = irec)
1428 CALL ncdf_getvar('geop_sigma', data%Lev2b%geop_sigma, &
1429 units = data%Lev2b%units%geop_sigma, &
1430 range = data%Lev2b%range%geop_sigma, &
1431 rec = irec)
1432 CALL ncdf_getvar('press', data%Lev2b%press, &
1433 units = data%Lev2b%units%press, &
1434 range = data%Lev2b%range%press, &
1435 rec = irec)
1436 CALL ncdf_getvar('press_sigma', data%Lev2b%press_sigma, &
1437 units = data%Lev2b%units%press_sigma, &
1438 range = data%Lev2b%range%press_sigma, &
1439 rec = irec)
1440 CALL ncdf_getvar('temp', data%Lev2b%temp, &
1441 units = data%Lev2b%units%temp, &
1442 range = data%Lev2b%range%temp, &
1443 rec = irec)
1444 CALL ncdf_getvar('temp_sigma', data%Lev2b%temp_sigma, &
1445 units = data%Lev2b%units%temp_sigma, &
1446 range = data%Lev2b%range%temp_sigma, &
1447 rec = irec)
1448 CALL ncdf_getvar('shum', data%Lev2b%shum, &
1449 units = data%Lev2b%units%shum, &
1450 range = data%Lev2b%range%shum, &
1451 rec = irec)
1452 CALL ncdf_getvar('shum_sigma', data%Lev2b%shum_sigma, &
1453 units = data%Lev2b%units%shum_sigma, &
1454 range = data%Lev2b%range%shum_sigma, &
1455 rec = irec)
1456 CALL ncdf_getvar('meteo_qual', data%Lev2b%meteo_qual, &
1457 units = data%Lev2b%units%meteo_qual, &
1458 range = data%Lev2b%range%meteo_qual, &
1459 rec = irec)
1460
1461 ENDIF
1462
1463! 2.14 Level2c variables (if any)
1464! -------------------------------
1465
1466 IF (ncdf_isvar('geop_sfc')) THEN
1467 n2d(1) = 1
1468 n2d(2) = 0
1469 CALL ncdf_getsize('geop_sfc', n2d(2), dim = 1)
1470 CALL ropp_io_init(data%Lev2c, n2d)
1471 ELSE
1472 data%Lev2c%Npoints = 0
1473 data%Lev2c%Nhoriz = 0
1474 ENDIF
1475
1476 IF (data%Lev2c%Npoints > 0) THEN
1477
1478! new 2d code
1479
1480 CALL ncdf_getvar('dtheta', data%Lev2c%dtheta, &
1481 units = data%Lev2c%units%dtheta, &
1482 range = data%Lev2c%range%dtheta, &
1483 rec = irec)
1484 CALL ncdf_getvar('lat_2d', data%Lev2c%lat_2d, &
1485 units = data%Lev2c%units%lat_2d, &
1486 range = data%Lev2c%range%lat_2d, &
1487 rec = irec)
1488 CALL ncdf_getvar('lon_2d', data%Lev2c%lon_2d, &
1489 units = data%Lev2c%units%lon_2d, &
1490 range = data%Lev2c%range%lon_2d, &
1491 rec = irec)
1492 CALL ncdf_getvar('geop_sfc', data%Lev2c%geop_sfc, &
1493 units = data%Lev2c%units%geop_sfc, &
1494 range = data%Lev2c%range%geop_sfc, &
1495 rec = irec)
1496 CALL ncdf_getvar('press_sfc', data%Lev2c%press_sfc, &
1497 units = data%Lev2c%units%press_sfc, &
1498 range = data%Lev2c%range%press_sfc, &
1499 rec = irec)
1500 CALL ncdf_getvar('press_sfc_sigma', data%Lev2c%press_sfc_sigma, &
1501 units = data%Lev2c%units%press_sfc_sigma, &
1502 range = data%Lev2c%range%press_sfc_sigma, &
1503 rec = irec)
1504 CALL ncdf_getvar('press_sfc_qual', data%Lev2c%press_sfc_qual, &
1505 units = data%Lev2c%units%press_sfc_qual, &
1506 range = data%Lev2c%range%press_sfc_qual, &
1507 rec = irec)
1508 ENDIF
1509
1510! 2.15 Level2d variables (if any)
1511! -------------------------------
1512
1513 IF (ncdf_isvar('level_coeff_a')) THEN
1514 CALL ncdf_getsize('level_coeff_a', n, dim = 1)
1515 CALL ropp_io_init(data%Lev2d, n)
1516 ELSE
1517 data%Lev2d%Npoints = 0
1518 ENDIF
1519
1520 IF (data%Lev2d%Npoints > 0) THEN
1521
1522 CALL ncdf_getvar('level_type', data%Lev2d%level_type, &
1523 rec = irec)
1524 CALL ncdf_getvar('level_coeff_a', data%Lev2d%level_coeff_a, &
1525 units = data%Lev2d%units%level_coeff_a, &
1526 range = data%Lev2d%range%level_coeff_a, &
1527 rec = irec)
1528 CALL ncdf_getvar('level_coeff_b', data%Lev2d%level_coeff_b, &
1529 units = data%Lev2d%units%level_coeff_b, &
1530 range = data%Lev2d%range%level_coeff_b, &
1531 rec = irec)
1532 ENDIF
1533
1534! 2.16 Additional variables (if any)
1535! ----------------------------------
1536
1537 CALL ropp_io_init(data%vlist)
1538
1539 DO varid=1,ncdf_nvars
1540
1541 IF(.NOT. ncdf_read(varid))THEN
1542
1543 status = nf90_inquire_variable(ncdf_ncid, varid, xtype=TYPE, ndims=ndim)
1544
1545 IF (TYPE .NE. NF90_CHAR) THEN ! only read scalar variables
1546
1547 IF(ndim == 1)THEN
1548 CALL ropp_io_read_ncdf_get_vlistD0d(varid, data%vlist%VlistD0d, irec)
1549 ENDIF
1550 IF(ndim == 2)THEN
1551 CALL ropp_io_read_ncdf_get_vlistD1d(varid, data%vlist%VlistD1d, irec)
1552 ENDIF
1553 IF(ndim == 3)THEN
1554 CALL ropp_io_read_ncdf_get_vlistD2d(varid, data%vlist%VlistD2d, irec)
1555 ENDIF
1556 ENDIF
1557
1558 ENDIF
1559
1560 ncdf_read(varid) = .FALSE. ! reset 'read variable' flag
1561
1562 ENDDO
1563
1564! 2.17 Clean up
1565! -------------
1566
1567 CALL message_set_routine(routine)
1568
1569END SUBROUTINE ropp_io_read_ncdf_get_rodata_2d
1570
1571
1572!-------------------------------------------------------------------------------
1573! 3. Error correlation and covariance matrices
1574!-------------------------------------------------------------------------------
1575
1576SUBROUTINE ropp_io_read_ncdf_get_rocorcov(DATA)
1577
1578! 3.1 Declarations
1579! ----------------
1580
1581 USE ropp_utils
1582 USE ncdf
1583 USE ropp_io, not_this => ropp_io_read_ncdf_get_rocorcov
1584 USE ropp_io_types, ONLY: ROcorcov
1585
1586 IMPLICIT NONE
1587
1588 TYPE(ROcorcov), DIMENSION(:), POINTER :: DATA
1589
1590 REAL(wp), DIMENSION(:), POINTER :: lat_min => null()
1591 REAL(wp), DIMENSION(:), POINTER :: lat_max => null()
1592 REAL(wp), DIMENSION(:,:), POINTER :: corr => null()
1593 REAL(wp), DIMENSION(:,:), POINTER :: sigma => null()
1594
1595 INTEGER :: i, m, n
1596 CHARACTER(len = 256) :: routine
1597
1598! 3.2 Error handling
1599! ------------------
1600
1601 CALL message_get_routine(routine)
1602 CALL message_set_routine('ropp_io_read_ncdf_get')
1603
1604! 3.3 Latitude bins
1605! -----------------
1606
1607 IF (ncdf_isvar('lat_min') .AND. ncdf_isvar('lat_max')) THEN
1608 CALL ncdf_getsize('lat_min', m)
1609 CALL ncdf_getsize('lat_max', n)
1610 ELSE
1611 CALL message(msg_fatal, &
1612 "NetCDF data file does not seem to contain an error correlation or covariance structure.")
1613 ENDIF
1614
1615 IF (m /= m) THEN
1616 CALL message(msg_fatal, &
1617 "Number of latitude bin boundaries in the netCDF data file is inconsistent.")
1618 ENDIF
1619
1620 CALL ncdf_getvar_alloc('lat_min', lat_min)
1621 CALL ncdf_getvar_alloc('lat_max', lat_max)
1622
1623! 3.4 Error correlation matrices
1624! ------------------------------
1625
1626 IF (ncdf_isvar('corr')) THEN
1627 CALL ncdf_getvar_alloc('corr', corr)
1628 ELSE
1629 CALL message(msg_fatal, &
1630 "NetCDF data file does not seem to contain an error correlation matrix.")
1631 ENDIF
1632
1633! 3.5 Error standard deviations
1634! -----------------------------
1635
1636 IF (ncdf_isvar('sigma')) THEN
1637 CALL ncdf_getvar_alloc('sigma', sigma)
1638 ENDIF
1639
1640! 3.6 Allocate and fill ROPP structure
1641! ------------------------------------
1642
1643 ALLOCATE(DATA(n))
1644
1645 DO i = 1, n
1646
1647 DATA(i)%lat_min = lat_min(i)
1648 DATA(i)%lat_max = lat_max(i)
1649
1650 ALLOCATE(DATA(i)%corr(SIZE(corr(:,i), 1)))
1651 DATA(i)%corr = corr(:,i)
1652
1653 IF (ASSOCIATED(sigma)) THEN
1654 ALLOCATE(DATA(i)%sigma(SIZE(sigma(:,i), 1)))
1655 DATA(i)%sigma = sigma(:, i)
1656 ENDIF
1657
1658 ENDDO
1659
1660! 3.7 Clean up
1661! ------------
1662
1663 DEALLOCATE(lat_min)
1664 DEALLOCATE(lat_max)
1665 DEALLOCATE(corr)
1666 IF (ASSOCIATED(sigma)) DEALLOCATE(sigma)
1667
1668 CALL message_set_routine(routine)
1669
1670END SUBROUTINE ropp_io_read_ncdf_get_rocorcov
1671
1672!-------------------------------------------------------------------------------
1673! 4. wrapper for other centres' RO data
1674!-------------------------------------------------------------------------------
1675
1676SUBROUTINE ropp_io_read_ncdf_get_otherdata(DATA, file, centre, rec, resolution, getlevel1a, getbufr)
1677
1678! 4.1 Declarations
1679! ----------------
1680
1681 USE ropp_io, not_this => ropp_io_read_ncdf_get_otherdata
1682 USE ropp_io_types, ONLY: ROprof
1683
1684 IMPLICIT NONE
1685
1686 TYPE(ROprof), INTENT(inout) :: DATA
1687 CHARACTER (len = *), INTENT(in) :: file
1688 CHARACTER (len=20), INTENT(in) :: centre
1689 INTEGER, OPTIONAL :: rec
1690 CHARACTER (len=20), OPTIONAL :: resolution
1691 LOGICAL, OPTIONAL :: getlevel1a
1692 LOGICAL, OPTIONAL :: getbufr
1693
1694 CHARACTER (len=20) :: lresolution = 'thinned'
1695 LOGICAL :: lgetlevel1a = .FALSE.
1696 LOGICAL :: lgetbufr = .FALSE.
1697 LOGICAL :: ldummy = .FALSE.
1698
1699! defaults
1700 IF (PRESENT(resolution)) lresolution=resolution
1701 IF (PRESENT(getlevel1a)) lgetlevel1a=getlevel1a
1702 IF (PRESENT(getbufr)) lgetbufr=getbufr
1703
1704! call the appropriate data handling function, default is ROPP format
1705 SELECT CASE (centre)
1706 CASE('UCAR')
1707 CALL ropp_io_read_ncdf_get_ucardata(DATA, file)
1708 CASE('EUM')
1709 CALL ropp_io_read_ncdf_get_eumdata(DATA, file, lresolution, lgetlevel1a, lgetbufr, ldummy)
1710 CASE default
1711 CALL ropp_io_read_ncdf_get_rodata(DATA, rec)
1712 END SELECT
1713
1714END SUBROUTINE ropp_io_read_ncdf_get_otherdata
1715
1716!-------------------------------------------------------------------------------
1717! 5. UCAR RO data
1718!-------------------------------------------------------------------------------
1719
1720SUBROUTINE ropp_io_read_ncdf_get_ucardata(DATA, file)
1721
1722! 5.1 Declarations
1723! ----------------
1724
1725 USE ncdf
1726 USE ropp_utils
1727 USE ropp_io_types, ONLY: ROprof
1728
1729 IMPLICIT NONE
1730
1731 TYPE(ROprof), INTENT(inout) :: DATA
1732 CHARACTER(len = *), INTENT(in) :: file
1733 CHARACTER(len = 256) :: routine
1734
1735! 5.2 Error handling
1736! ------------------
1737
1738 CALL message_get_routine(routine)
1739 CALL message_set_routine('ropp_io_read_ucardata')
1740
1741! 5.3 Identify file type
1742! ----------------------
1743
1744 IF (ncdf_isvar('Bend_ang') .AND. &
1745 (ncdf_isvar('Impact_parm') .OR. ncdf_isvar('Impact_height'))) THEN
1746 CALL ropp_io_read_ucardata_atmPrf(DATA, file)
1747 ELSE IF (ncdf_isvar('pL1Snr') .AND. ncdf_isvar('pL2Snr')) THEN
1748 CALL ropp_io_read_ucardata_atmPhs(DATA, file)
1749 ELSE IF (ncdf_isvar('MSL_alt') .AND. ncdf_isvar ('Pres')) THEN
1750 CALL ropp_io_read_ucardata_atmPrf(DATA, file)
1751 ELSE
1752 CALL message(msg_fatal, &
1753 "Routine ropp_io_read_ncdf_get_ucardata does not support this" // &
1754 "file type. Only atmPrf, ecmPrf, gfsPrf, ncpPrf, sonPrf and atmPhs "// &
1755 "files supported. Check input file type.")
1756 ENDIF
1757
1758 CALL message_set_routine(routine)
1759
1760CONTAINS
1761
1762!-------------------------------------------------------------------------------
1763! 6. UCAR RO data - atmPrf files
1764!-------------------------------------------------------------------------------
1765
1766 SUBROUTINE ropp_io_read_ucardata_atmPrf(DATA, file)
1767
1768! NB this routine only supports UCAR 'Prf' format netCDF files
1769! (i.e. atmPrf, ecmPrf, gfsPrf, ncpPrf and sonPrf)
1770! See: http://cosmic-io.cosmic.ucar.edu/cdaac/fileFormats/atmPrf.html
1771
1772! 6.1 Declarations
1773! ----------------
1774
1775 USE DateTimeProgs, ONLY: Date_and_Time_UTC
1776 USE DateTimeTypes
1777 USE ropp_utils
1778 USE ncdf
1779 USE ropp_io
1780 USE ropp_io_types, ONLY: ROprof, &
1781 ThisFmtVer, &
1782 PCD_open_loop, &
1783 PCD_rising, &
1784 PCD_occultation
1785 USE geodesy, ONLY: geometric2geopotential
1786
1787 IMPLICIT NONE
1788
1789 TYPE(ROprof), INTENT(inout) :: DATA
1790 CHARACTER(len = *), INTENT(in) :: file
1791
1792 INTEGER :: n
1793 INTEGER :: readint
1794 REAL(wp) :: readreal
1795 CHARACTER (len = 256) :: readstr
1796
1797 REAL(wp), PARAMETER :: g_wmo = 9.80665_wp
1798 REAL(wp), PARAMETER :: epsilon_water = 0.621971_wp
1799 INTEGER, DIMENSION(8) :: DTnow
1800
1801! holds where output
1802! INTEGER, DIMENSION(:), POINTER :: idx => null()
1803 INTEGER :: nidx
1804
1805! 6.3 Header variables
1806! --------------------
1807
1808 readstr = ' '
1809 CALL ncdf_getatt('fileStamp', readstr)
1810 data%leo_id = readstr(1:4)
1811 CALL ncdf_getatt('occulting_sat_id', readint)
1812 WRITE(data%gns_id,'(A1,I3.3)') 'G', readint
1813 readstr = ' '
1814 CALL ncdf_getatt('fiducial_id', readstr)
1815 IF(readstr /= " ") data%stn_id = readstr(1:4)
1816
1817! 6.4 Overall quality
1818! -------------------
1819
1820 IF (ncdf_isvar('Bend_ang') .AND. &
1821 (ncdf_isvar('Impact_parm') .OR. ncdf_isvar('Impact_height'))) THEN
1822 CALL ncdf_getatt('bad', readstr)
1823 data%PCD = 0
1824 IF (TRIM(readstr) == "0") THEN
1825 data%PCD = 0
1826 data%overall_qual = 100.0
1827 END IF
1828 IF (TRIM(readstr) == "1") THEN
1829 data%PCD = 1 ! non nominal
1830 data%overall_qual = 0.0
1831 END IF
1832 data%units%overall_qual = "%"
1833 IF (ncdf_isatt('iol') .AND. ncdf_isatt('irs')) THEN
1834 CALL ncdf_getatt('iol', readint)
1835 IF (readint == 1) &
1836 data%PCD = IBSET(data%PCD, PCD_open_loop) ! open loop used
1837 CALL ncdf_getatt('irs', readint)
1838 IF (readint == -1) &
1839 data%PCD = IBSET(data%PCD, PCD_rising) ! rising occultation
1840 ENDIF
1841 ELSE
1842 data%PCD = 0
1843 data%PCD = IBSET(data%PCD, PCD_occultation) ! background data
1844 ENDIF
1845
1846! 6.5 Date and time
1847! -----------------
1848
1849 CALL gettime(data%DTocc)
1850
1851! 6.6 Georeferencing
1852! ------------------
1853
1854 CALL ncdf_getatt('lat', data%georef%lat)
1855 data%georef%units%lat = "degrees_north"
1856
1857 CALL ncdf_getatt('lon', data%georef%lon)
1858 data%georef%units%lon = "degrees_east"
1859
1860 IF (ncdf_isvar('Bend_ang') .AND. &
1861 (ncdf_isvar('Impact_parm') .OR. ncdf_isvar('Impact_height'))) THEN
1862
1863 CALL ncdf_getatt('occpt_offset', data%georef%time_offset)
1864 data%georef%units%time_offset = "seconds"
1865
1866 CALL ncdf_getatt('rgeoid', data%georef%Undulation)
1867 data%georef%Undulation = data%georef%Undulation * 1000.0
1868 data%georef%units%Undulation = "meters"
1869
1870 CALL ncdf_getatt('rfict', data%georef%roc)
1871 data%georef%roc = data%georef%roc * 1000.0
1872 data%georef%units%roc = "meters"
1873
1874 CALL ncdf_getatt('curv', data%georef%r_coc)
1875 data%georef%r_coc = data%georef%r_coc * 1000.0
1876 data%georef%units%r_coc = "meters"
1877
1878 CALL ncdf_getatt('azim', data%georef%azimuth)
1879 IF ((data%georef%azimuth < 0.0) .AND. &
1880 (data%georef%azimuth > -180.0)) &
1881 data%georef%azimuth = data%georef%azimuth + 360.0
1882 data%georef%units%azimuth = "degrees"
1883
1884 ENDIF
1885
1886! 6.7 Level1b variables (if any)
1887! -------------------------------
1888
1889 IF (ncdf_isvar('Bend_ang') .AND. &
1890 (ncdf_isvar('Impact_parm') .OR. ncdf_isvar('Impact_height'))) THEN
1891 CALL ncdf_getsize('Bend_ang', n, dim = 1)
1892 CALL ropp_io_init(data%Lev1b, n)
1893 ELSE
1894 data%Lev1b%Npoints = 0
1895 ENDIF
1896
1897 IF (data%Lev1b%Npoints > 0) THEN
1898
1899 CALL ncdf_getvar('Lat', data%Lev1b%lat_tp)
1900 data%Lev1b%units%lat_tp = "degrees_north"
1901
1902 CALL ncdf_getvar('Lon', data%Lev1b%lon_tp)
1903 data%Lev1b%units%lon_tp = "degrees_east"
1904
1905 CALL ncdf_getvar('Azim', data%Lev1b%azimuth_tp)
1906! idx => WHERE( (data%Lev1b%azimuth_tp < 0.0) .AND. &
1907! (data%Lev1b%azimuth_tp > -180.0), nidx)
1908! IF (nidx > 0) data%Lev1b%azimuth_tp(idx) = data%Lev1b%azimuth_tp(idx) + 360.0
1909 WHERE ( (data%Lev1b%azimuth_tp < 0.0) .AND. &
1910 (data%Lev1b%azimuth_tp > -180.0) ) &
1911 data%Lev1b%azimuth_tp = data%Lev1b%azimuth_tp + 360.0
1912 data%Lev1b%units%azimuth_tp = "degrees"
1913
1914 IF (ncdf_isvar('Impact_parm')) THEN
1915
1916 CALL ncdf_getvar('Impact_parm', data%Lev1b%impact, &
1917 units = data%Lev1b%units%impact)
1918
1919 ELSE ! If both are present, use Impact_parm
1920
1921 IF (ncdf_isvar('Impact_height')) THEN
1922
1923 CALL ncdf_getvar('Impact_height', data%Lev1b%impact, &
1924 units = data%Lev1b%units%impact)
1925 data%Lev1b%impact = data%Lev1b%impact + data%georef%roc ! Both are in m at this point
1926
1927 END IF
1928
1929 END IF
1930
1931 data%lev1b%impact_opt = data%Lev1b%impact
1932
1933 CALL ncdf_getvar('Bend_ang', data%Lev1b%bangle)
1934 data%Lev1b%units%bangle = "radians"
1935
1936 CALL ncdf_getvar('Opt_bend_ang', data%Lev1b%bangle_opt)
1937
1938 CALL ncdf_getvar('Bend_ang_stdv', data%Lev1b%bangle_sigma)
1939 data%Lev1b%units%bangle_sigma = "radians"
1940
1941 data%Lev1b%bangle_opt_sigma = data%Lev1b%bangle_sigma
1942
1943! set the quality for bangle
1944 CALL ncdf_getatt('_FillValue', readreal, 'Opt_bend_ang')
1945! idx => WHERE( data%Lev1b%bangle > readreal, nidx)
1946! IF (nidx > 0) data%Lev1b%bangle_qual(idx) = 100.0
1947 WHERE (data%Lev1b%bangle > readreal) &
1948 data%Lev1b%bangle_qual = 100.0
1949 data%Lev1b%bangle_opt_qual = data%Lev1b%bangle_qual
1950
1951 ENDIF
1952
1953! 6.8 Level2a variables (if any)
1954! -------------------------------
1955
1956 IF (ncdf_isvar('MSL_alt') .AND. ncdf_isvar('Ref')) THEN
1957 CALL ncdf_getsize('MSL_alt', n, dim = 1)
1958 CALL ropp_io_init(data%Lev2a, n)
1959 ELSE
1960 data%Lev2a%Npoints = 0
1961 ENDIF
1962
1963 IF (data%Lev2a%Npoints > 0) THEN
1964
1965 CALL ncdf_getvar('MSL_alt', data%Lev2a%alt_refrac, &
1966 units = data%Lev2a%units%alt_refrac)
1967! geopotential not in UCAR files - generate from altitude
1968! idx => WHERE((data%Lev2a%alt_refrac > -999.0), nidx)
1969! IF (nidx > 0 .AND. &
1970! data%georef%lat > -999.0) &
1971! data%Lev2a%geop_refrac(idx) = geometric2geopotential(data%georef%lat, &
1972! data%Lev2a%alt_refrac(idx))
1973 IF (data%georef%lat > -999.0) THEN
1974 WHERE(data%Lev2a%alt_refrac > -999.0) &
1975 data%Lev2a%geop_refrac = geometric2geopotential(data%georef%lat, &
1976 data%Lev2a%alt_refrac)
1977 ENDIF
1978
1979 CALL ncdf_getvar('Ref', data%Lev2a%refrac)
1980 data%Lev2a%units%refrac = "1"
1981
1982 IF (ncdf_isvar('Ref_stdv')) THEN
1983 CALL ncdf_getvar('Ref_stdv', data%Lev2a%refrac_sigma)
1984 data%Lev2a%units%refrac_sigma = "1"
1985
1986 ! set the quality for ref
1987 CALL ncdf_getatt('_FillValue', readreal, 'Ref' )
1988! idx => WHERE( data%Lev2a%refrac > readreal, nidx)
1989! IF (nidx > 0) data%Lev2a%refrac_qual(idx) = 100.0
1990 WHERE( data%Lev2a%refrac > readreal) &
1991 data%Lev2a%refrac_qual = 100.0
1992 ENDIF
1993
1994!! include dry temperature in Level 2a - if variable 'Bend_ang' exists, the
1995!! UCAR file is an atmPrf file, and the 'Temp' variable is actually dry temperature.
1996 IF (ncdf_isvar('Temp') .AND. ncdf_isvar('Bend_ang')) THEN
1997
1998 CALL ncdf_getvar('Temp', data%Lev2a%dry_temp)
1999
2000! idx => WHERE((data%Lev2a%dry_temp > -999.0), nidx)
2001! IF (nidx > 0) THEN
2002! data%Lev2a%dry_temp(idx) = data%Lev2a%dry_temp(idx) + 273.15_wp
2003! ENDIF
2004 WHERE(data%Lev2a%dry_temp > -999.0) &
2005 data%Lev2a%dry_temp = data%Lev2a%dry_temp + 273.15_wp
2006 data%Lev2a%units%dry_temp = "kelvin"
2007
2008 END IF
2009
2010 ENDIF
2011
2012! 6.9 Level2b variables (if any)
2013! -------------------------------
2014
2015 IF (ncdf_isvar('MSL_alt') .AND. ncdf_isvar('Pres')) THEN
2016 CALL ncdf_getsize('MSL_alt', n, dim = 1)
2017 CALL ropp_io_init(data%Lev2b, n)
2018 ELSE
2019 data%Lev2b%Npoints = 0
2020 ENDIF
2021
2022 IF (data%Lev2b%Npoints > 0) THEN
2023
2024 CALL ncdf_getvar('Pres', data%Lev2b%press)
2025 data%Lev2b%units%press = "hPa"
2026 CALL ncdf_getvar('Temp', data%Lev2b%temp)
2027! idx => WHERE(data%Lev2b%temp > -999.0, nidx)
2028! IF (nidx > 0) data%Lev2b%temp(idx) = data%Lev2b%temp(idx) + 273.15_wp
2029 WHERE (data%Lev2b%temp > -999.0) &
2030 data%Lev2b%temp = data%Lev2b%temp + 273.15_wp
2031 data%Lev2b%units%temp = "kelvin"
2032
2033 IF (ncdf_isvar('Vp')) THEN
2034 CALL ncdf_getvar('Vp', data%Lev2b%shum)
2035! idx => WHERE(data%Lev2b%shum > -999.0, nidx)
2036! IF (nidx > 0) data%Lev2b%shum(idx) = &
2037! (data%Lev2b%shum(idx)*epsilon_water) / &
2038! (data%Lev2b%press(idx) - &
2039! (data%Lev2b%shum(idx)*(1.0_wp - epsilon_water)))
2040 WHERE (data%Lev2b%shum > -999.0) &
2041 data%Lev2b%shum = &
2042 (data%Lev2b%shum*epsilon_water) / &
2043 (data%Lev2b%press - &
2044 (data%Lev2b%shum*(1.0_wp - epsilon_water)))
2045 data%Lev2b%units%shum = "kilogram/kilogram"
2046 ENDIF
2047
2048! get the geopotential from L2a
2049 CALL ncdf_getvar('MSL_alt', data%Lev2b%geop, units = 'metres')
2050 data%Lev2b%geop = geometric2geopotential(data%georef%lat,data%Lev2b%geop)
2051
2052! background time
2053 data%bg%Year = data%DTocc%Year
2054 data%bg%Month = data%DTocc%Month
2055 data%bg%Day = data%DTocc%Day
2056 data%bg%Hour = data%DTocc%Hour
2057 data%bg%Minute = data%DTocc%Minute
2058 nidx = INDEX(file, 'Prf_', .TRUE.)
2059 IF ( nidx > 3 ) data%bg%source = file(nidx-3:nidx-1) ! read from filename
2060
2061 ENDIF
2062
2063! 6.10 (Global) Attributes
2064! ------------------------
2065
2066 data%FmtVersion = ' ' ; data%FmtVersion = ThisFmtVer
2067 data%processing_centre = ' ' ; CALL ncdf_getatt('center', data%processing_centre)
2068 data%pod_method = ' ' ; data%pod_method = "UNKNOWN"
2069 data%phase_method = ' ' ; data%phase_method = "UNKNOWN"
2070 data%bangle_method = ' ' ; data%bangle_method = "UNKNOWN"
2071 data%refrac_method = ' ' ; data%refrac_method = "UNKNOWN"
2072 data%meteo_method = ' ' ; data%meteo_method = "UNKNOWN"
2073 data%thin_method = ' ' ; data%thin_method = "UNKNOWN"
2074 data%software_version = ' ' ; data%software_version = "UNKNOWN"
2075 nidx = INDEX(file, 'Prf_', .TRUE.)
2076 IF ( nidx > 0 ) & ! VNN.nnn from file name
2077 data%software_version = "V" // file(nidx+38:nidx+39) // &
2078 "." // file(nidx+32:nidx+34)
2079
2080! COSMIC has no processing date, set to current utc date/time
2081 CALL Date_and_Time_UTC ( Values=DTnow )
2082 data%DTpro%Year = DTnow(1)
2083 data%DTpro%Month = DTnow(2)
2084 data%DTpro%Day = DTnow(3)
2085 data%DTpro%Hour = DTnow(5)
2086 data%DTpro%Minute = DTnow(6)
2087 data%DTpro%Second = DTnow(7)
2088 data%DTpro%Msec = DTnow(8)
2089
2090! 6.11 Occultation ID
2091! -------------------
2092
2093 CALL ropp_io_occid(DATA)
2094
2095! 6.12 Clean up
2096! -------------
2097
2098! IF (ASSOCIATED(idx)) DEALLOCATE(idx)
2099
2100END SUBROUTINE ropp_io_read_ucardata_atmPrf
2101
2102!-------------------------------------------------------------------------------
2103! 7. UCAR RO data - atmPhs files
2104!-------------------------------------------------------------------------------
2105
2106SUBROUTINE ropp_io_read_ucardata_atmPhs(DATA, file)
2107
2108! NB this routine only supports UCAR atmPhs netCDF files,
2109! See: http://cosmic-io.cosmic.ucar.edu/cdaac/fileFormats/atmPhs.html
2110
2111! 7.1 Declarations
2112! ----------------
2113
2114 USE DateTimeProgs, ONLY: Date_and_Time_UTC
2115 USE DateTimeTypes
2116 USE ropp_utils
2117 USE ncdf
2118 USE ropp_io
2119 USE ropp_io_types, ONLY: ROprof, &
2120 ThisFmtVer
2121
2122 IMPLICIT NONE
2123
2124 TYPE(ROprof), INTENT(inout) :: DATA
2125 CHARACTER(len = *), INTENT(in) :: file
2126
2127 INTEGER :: n
2128 INTEGER :: readint
2129 REAL(wp) :: readreal
2130 CHARACTER (len = 256) :: readstr
2131
2132 REAL(wp), PARAMETER :: g_wmo = 9.80665
2133 INTEGER, DIMENSION(8) :: DTnow
2134
2135 REAL(wp), DIMENSION(:), ALLOCATABLE :: workdata
2136
2137! holds where output
2138! INTEGER, DIMENSION(:), POINTER :: idx => null()
2139 INTEGER :: nidx
2140
2141! 7.3 Header variables
2142! --------------------
2143
2144 readstr = ' '
2145 CALL ncdf_getatt('fileStamp', readstr)
2146 data%leo_id = readstr(1:4)
2147 CALL ncdf_getatt('occsatId', readint)
2148 WRITE(data%gns_id,'(A1,I3.3)') 'G', readint
2149 readstr = ' '
2150 data%stn_id = ' '
2151
2152! 7.4 Date and time
2153! -----------------
2154
2155 CALL gettime(data%DTocc)
2156
2157! 7.5 Overall quality
2158! -------------------
2159
2160 CALL ncdf_getatt('bad', readstr)
2161 data%PCD = 0
2162 IF (TRIM(readstr) == "0") THEN
2163 data%PCD = 0
2164 data%overall_qual = 100.0
2165 END IF
2166 IF (TRIM(readstr) == "1") THEN
2167 data%PCD = 1 ! non nominal
2168 data%overall_qual = 0.0
2169 END IF
2170 data%units%overall_qual = "%"
2171
2172! 7.6 Level1a variables (if any)
2173! -------------------------------
2174
2175 IF (ncdf_isvar('time')) THEN
2176 CALL ncdf_getsize('time', n, dim = 1)
2177 CALL ropp_io_init(data%Lev1a, n)
2178 ELSE
2179 data%Lev1a%Npoints = 0
2180 ENDIF
2181
2182 IF (data%Lev1a%Npoints > 0) THEN
2183
2184 CALL ncdf_getvar('time', data%Lev1a%dtime)
2185 CALL ncdf_getvar('caL1Snr', data%Lev1a%snr_L1ca)
2186 CALL ncdf_getvar('pL1Snr', data%Lev1a%snr_L1p)
2187 CALL ncdf_getvar('pL2Snr', data%Lev1a%snr_L2p)
2188 data%Lev1a%units%snr = "volt/volt"
2189
2190 CALL ncdf_getvar('xLeo', data%Lev1a%r_leo(:,1))
2191 CALL ncdf_getvar('yLeo', data%Lev1a%r_leo(:,2))
2192 CALL ncdf_getvar('zLeo', data%Lev1a%r_leo(:,3))
2193 data%Lev1a%r_leo(:,:) = data%Lev1a%r_leo(:,:) * 1000.0_wp
2194 data%Lev1a%units%r_leo = "metres"
2195 data%Lev1a%reference_frame%r_leo = "ECI"
2196
2197 CALL ncdf_getvar('xdLeo', data%Lev1a%v_leo(:,1))
2198 CALL ncdf_getvar('ydLeo', data%Lev1a%v_leo(:,2))
2199 CALL ncdf_getvar('zdLeo', data%Lev1a%v_leo(:,3))
2200 data%Lev1a%v_leo(:,:) = data%Lev1a%v_leo(:,:) * 1000.0_wp
2201 data%Lev1a%units%v_leo = "metres / seconds"
2202
2203 CALL ncdf_getvar('xGps', data%Lev1a%r_gns(:,1))
2204 CALL ncdf_getvar('yGps', data%Lev1a%r_gns(:,2))
2205 CALL ncdf_getvar('zGps', data%Lev1a%r_gns(:,3))
2206 data%Lev1a%r_gns(:,:) = data%Lev1a%r_gns(:,:) * 1000.0_wp
2207 data%Lev1a%units%r_gns = "metres"
2208 data%Lev1a%reference_frame%r_gns = "ECI"
2209
2210 CALL ncdf_getvar('xdGps', data%Lev1a%v_gns(:,1))
2211 CALL ncdf_getvar('ydGps', data%Lev1a%v_gns(:,2))
2212 CALL ncdf_getvar('zdGps', data%Lev1a%v_gns(:,3))
2213 data%Lev1a%v_gns(:,:) = data%Lev1a%v_gns(:,:) * 1000.0_wp
2214 data%Lev1a%units%v_gns = "metres / seconds"
2215
2216 CALL ncdf_getvar('exL1', data%Lev1a%phase_L1)
2217 CALL ncdf_getvar('exL2', data%Lev1a%phase_L2)
2218 data%Lev1a%units%phase = "metres"
2219
2220! open loop phase model data
2221 ALLOCATE(workdata(data%Lev1a%Npoints))
2222 CALL ncdf_getvar('xmdl', workdata)
2223 CALL ropp_io_addvar_rodataD1d(DATA, &
2224 name = "open_loop_lcf", &
2225 long_name= "Lost Carrier Flag", &
2226 units = "metres", &
2227 range = (/-1000000.0_wp, 1000000.0_wp/), &
2228 DATA = workdata)
2229 DEALLOCATE(workdata)
2230
2231! set the quality for phase
2232 CALL ncdf_getatt('_FillValue', readreal, 'exL1')
2233! idx => WHERE( data%Lev1a%phase_L1 > readreal, nidx)
2234! IF (nidx > 0) data%Lev1a%phase_qual(idx) = 100.0
2235 WHERE (data%Lev1a%phase_L1 > readreal) &
2236 data%Lev1a%phase_qual = 100.0
2237 ENDIF
2238
2239! 7.7 (Global) Attributes
2240! ------------------------
2241
2242 data%FmtVersion = ' ' ; data%FmtVersion = ThisFmtVer
2243 data%processing_centre = ' ' ; CALL ncdf_getatt('center', data%processing_centre)
2244 data%pod_method = ' ' ; data%pod_method = "UNKNOWN"
2245 data%phase_method = ' ' ; data%phase_method = "UNKNOWN"
2246 data%bangle_method = ' ' ; data%bangle_method = "UNKNOWN"
2247 data%refrac_method = ' ' ; data%refrac_method = "UNKNOWN"
2248 data%meteo_method = ' ' ; data%meteo_method = "UNKNOWN"
2249 data%thin_method = ' ' ; data%thin_method = "UNKNOWN"
2250 data%software_version = ' ' ; data%software_version = "UNKNOWN"
2251 nidx = INDEX(file, 'atmPhs_', .TRUE.)
2252 IF ( nidx > 0 ) & ! VNN.nnn from file name
2253 data%software_version = "V" // file(nidx+38:nidx+39) // &
2254 "." // file(nidx+32:nidx+34)
2255
2256! COSMIC has no processing date, set to current utc date/time
2257 CALL Date_and_Time_UTC ( Values=DTnow )
2258 data%DTpro%Year = DTnow(1)
2259 data%DTpro%Month = DTnow(2)
2260 data%DTpro%Day = DTnow(3)
2261 data%DTpro%Hour = DTnow(5)
2262 data%DTpro%Minute = DTnow(6)
2263 data%DTpro%Second = DTnow(7)
2264 data%DTpro%Msec = DTnow(8)
2265
2266! 7.8 Occultation ID
2267! -------------------
2268
2269 CALL ropp_io_occid(DATA)
2270
2271! 7.9 Clean up
2272! -------------
2273
2274! IF (ASSOCIATED(idx)) DEALLOCATE(idx)
2275 CALL message_set_routine(routine)
2276
2277END SUBROUTINE ropp_io_read_ucardata_atmPhs
2278
2279SUBROUTINE gettime(DTocc)
2280
2281 USE ropp_io_types, ONLY: DT7type
2282 USE ncdf
2283
2284 IMPLICIT NONE
2285
2286 TYPE(DT7type), INTENT(inout) :: DTocc
2287 REAL :: sec
2288
2289 CALL ncdf_getatt('year', DTocc%Year)
2290 CALL ncdf_getatt('month', DTocc%Month)
2291 CALL ncdf_getatt('day', DTocc%Day)
2292 CALL ncdf_getatt('hour', DTocc%Hour)
2293 CALL ncdf_getatt('minute', DTocc%Minute)
2294 CALL ncdf_getatt('second', sec)
2295 DTocc%Second = NINT(sec)
2296 DTocc%Msec = 0
2297
2298END SUBROUTINE gettime
2299
2300END SUBROUTINE ropp_io_read_ncdf_get_ucardata
2301
2302!-------------------------------------------------------------------------------
2303! 8. EUM RO data
2304!-------------------------------------------------------------------------------
2305
2306SUBROUTINE ropp_io_read_ncdf_get_eumdata(DATA, file, resolution, getlevel1a, getbufr, ldummy)
2307
2308! 8.1 Declarations
2309! ----------------
2310
2311 USE ncdf
2312 USE ropp_utils
2313 USE ropp_io_types, ONLY: ROprof
2314
2315 IMPLICIT NONE
2316
2317 TYPE(ROprof), INTENT(inout) :: DATA
2318 CHARACTER(len = *), INTENT(in) :: file
2319 CHARACTER(len = 20), INTENT(in) :: resolution
2320 LOGICAL, INTENT(IN) :: getlevel1a
2321 LOGICAL, INTENT(IN) :: getbufr
2322 CHARACTER(len = 256) :: routine
2323 LOGICAL, INTENT(IN) :: ldummy ! needed to differentiate between
2324 ! ropp_io_read_ncdf_get_eumdata and
2325 ! ropp_io_read_ncdf_get_otherdata
2326
2327! 8.2 Error handling
2328! ------------------
2329
2330 CALL message_get_routine(routine)
2331 CALL message_set_routine('ropp_io_read_eumdata')
2332
2333 CALL ropp_io_read_eumdata(DATA, file, resolution, getlevel1a, getbufr)
2334
2335 CALL message_set_routine(routine)
2336
2337
2338CONTAINS
2339
2340
2341!-------------------------------------------------------------------------------
2342! 9. EUMETSAT RO data - level 1B
2343!-------------------------------------------------------------------------------
2344
2345 SUBROUTINE ropp_io_read_eumdata(DATA, file, resolution, getlevel1a, getbufr)
2346
2347! This routine reads the netCDF4 EUMETSAT format into an internal ROPP structure.
2348
2349! 9.1 Declarations
2350! ----------------
2351
2352 USE DateTimeTypes
2353 USE ropp_utils
2354 USE coordinates
2355 USE ncdf
2356 USE ropp_io
2357 USE ropp_io_types, ONLY: ROprof, &
2358 ThisFmtVer, &
2359 PCD_open_loop, &
2360 PCD_rising
2361
2362 IMPLICIT NONE
2363
2364 TYPE(ROprof), INTENT(inout) :: DATA
2365 TYPE(ROprof) :: DATA_CL, DATA_RS
2366 CHARACTER(len = 20), INTENT(in) :: resolution
2367 CHARACTER(len = *), INTENT(in) :: file
2368 LOGICAL, INTENT(IN) :: getlevel1a
2369 LOGICAL, INTENT(IN) :: getbufr
2370
2371 REAL(wp), DIMENSION(:), ALLOCATABLE :: rs_navbit_ext ! RS navbits (external)
2372 REAL(wp), DIMENSION(:), ALLOCATABLE :: rs_navbit_int ! RS navbits (internal)
2373 REAL(wp), DIMENSION(:), ALLOCATABLE :: temparray ! Temporary array
2374 INTEGER, DIMENSION(:), ALLOCATABLE :: rs_lcf, cl_lcf, lcf ! Lost carrier flag
2375
2376 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: r_gns, v_gns ! Temporary pos/velocity arrays
2377 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: r_leo, v_leo ! Temporary pos/velocity arrays
2378
2379 REAL(wp), DIMENSION(:), ALLOCATABLE :: rs_i_ca_uncorr ! RS I component [V]
2380 REAL(wp), DIMENSION(:), ALLOCATABLE :: rs_q_ca_uncorr ! RS Q component [V]
2381 REAL(wp), DIMENSION(:), ALLOCATABLE :: rs_exphase_l1_nco ! RS NCO excess phase [m]
2382 REAL(wp), DIMENSION(:), ALLOCATABLE :: rs_phase_l1_iq ! I/Q contribution
2383 Integer, DIMENSION(:), ALLOCATABLE :: tracking_state ! Tracking state
2384
2385 INTEGER :: n, n_cl, n_rs, first_valid, j
2386 INTEGER :: readint, readint2
2387 REAL(EightByteReal) :: readreal, readreal2, ts, ts1
2388 CHARACTER (len = 256) :: readstr, readstr2
2389
2390 INTEGER(OneByteInt) :: readbyte1, readbyte2, readbyte3
2391
2392 CHARACTER (len = 256) :: sdir ! directory to science info in netCDF4
2393 CHARACTER (len = 256) :: ddir ! directory to science/data in netCDF4
2394 CHARACTER (len = 256) :: tdir ! tmp directory for use
2395
2396 REAL(wp), PARAMETER :: g_wmo = 9.80665_wp
2397 REAL(wp), PARAMETER :: epsilon_water = 0.621971_wp
2398 REAL(wp), PARAMETER :: f_L1 = 1.57542e9_wp
2399 REAL(wp), PARAMETER :: c_light = 299792458.0_wp
2400! Pi already defined as parameter in coordinates module. Confuses pgf95.
2401 REAL(wp), PARAMETER :: pi1 = 3.141592653589793238_wp
2402
2403 INTEGER :: have_nb = 0
2404
2405! INTEGER, DIMENSION(:), POINTER :: idx => null() ! Holds 'where' output
2406! INTEGER :: nidx
2407
2408! 9.2 Group path for science, level 1B data
2409! -----------------------------------------
2410
2411 sdir = '/data/'
2412
2413 ddir = TRIM(sdir) // 'level_1b/' // TRIM(resolution) // '/'
2414
2415! 9.3 Header variables
2416! --------------------
2417
2418 ! receiver satellite ID in ROPP format
2419 readstr = ' '
2420 CALL ncdf_getatt('spacecraft', readstr)
2421 IF ( readstr == 'M02' ) data%leo_id = 'META'
2422 IF ( readstr == 'M01' ) data%leo_id = 'METB'
2423 IF ( readstr == 'M03' ) data%leo_id = 'METC'
2424
2425 ! occulting GNSS satellite
2426 CALL ncdf_getvar(TRIM(sdir)//'occultation/prn', readint)
2427 WRITE(data%gns_id,'(A1,I3.3)') 'G', readint
2428
2429 ! station ID unused for EUMETSAT data
2430 ! readstr = ' '
2431 ! CALL ncdf_getatt('fiducial_id', readstr)
2432 ! IF(readstr /= ' ') data%stn_id = readstr(1:4)
2433
2434! 9.4 Overall quality
2435! -------------------
2436
2437 ! Overall nominal / non-nominal
2438 tdir = '/quality/'
2439 CALL ncdf_getvar(TRIM(tdir)//'overall_quality_ok', readbyte1)
2440
2441 data%PCD = 0
2442 IF (readbyte1 == 0) data%PCD = 1
2443
2444 ! BA nominal (set to same value as overall)
2445 IF (readbyte1 == 0) data%PCD = IBSET(data%PCD, PCD_bangle) ! set to same value as overall
2446
2447 ! quality indicator, currently just set to 100% or 0%
2448 data%overall_qual = 100.0_wp * readbyte1
2449 data%units%overall_qual = '%'
2450
2451 ! open or closed loop data setting
2452 CALL ncdf_getvar(TRIM(tdir)//'rs_data_available', readbyte1)
2453 CALL ncdf_getvar(TRIM(tdir)//'ol_data_available', readbyte2)
2454! IF ((readbyte1) .OR. (readbyte2)) data%PCD = IBSET(data%PCD, PCD_open_loop) - right now we only us RS, not OL
2455 IF ((readbyte1 /= 0) .OR. (readbyte2 /= 0)) data%PCD = IBSET(data%PCD, PCD_open_loop)
2456
2457 ! setting or rising
2458 CALL ncdf_getatt(TRIM(sdir)//'occultation/occultation_type', readstr)
2459 IF (TRIM(readstr) == 'rising') data%PCD = IBSET(data%PCD, PCD_rising)
2460
2461 ! closed loop phase measurements okay?
2462 CALL ncdf_getvar(TRIM(tdir)//'cl_snr_ca_ok', readbyte1)
2463 CALL ncdf_getvar(TRIM(tdir)//'cl_snr_p1_ok', readbyte2)
2464 CALL ncdf_getvar(TRIM(tdir)//'cl_snr_p2_ok', readbyte3)
2465 IF ((readbyte1 == 0) .AND. (readbyte2 == 0) .AND. (readbyte3 == 0)) &
2466 data%PCD = IBSET(data%PCD, PCD_phase)
2467
2468
2469! 9.5 Date and time
2470! -----------------
2471
2472 ! start time of occultation
2473 tdir = TRIM(sdir) // 'level_1b/'
2474
2475 CALL ncdf_getvar(TRIM(tdir)//'utc_start_absdate', readint)
2476 CALL ncdf_getvar(TRIM(tdir)//'utc_start_abstime', readreal)
2477
2478 ! check that we have the right time
2479 CALL ncdf_getatt(TRIM(tdir)//'units', readstr, 'utc_start_absdate')
2480 IF ( readstr == 'days since 2000-01-01 00:00:00.00' ) THEN
2481 CALL abstimetoDT(readint, readreal, data%DTocc)
2482 ELSE
2483 CALL message(msg_fatal, &
2484 'Time units found for utc_start_absdate are inconsistent.')
2485 ENDIF
2486
2487 ! difference between start time and georef time
2488 tdir = TRIM(sdir) // 'occultation/'
2489 CALL ncdf_getvar(TRIM(tdir)//'utc_georef_absdate', readint2)
2490 CALL ncdf_getvar(TRIM(tdir)//'utc_georef_abstime', readreal2)
2491
2492 ! check that we have the right time
2493 CALL ncdf_getatt(TRIM(tdir)//'units', readstr, 'utc_georef_absdate')
2494 IF ( .NOT. (readstr == 'days since 2000-01-01 00:00:00.00') ) &
2495 CALL message(msg_fatal, &
2496 'Time units found for utc_georef_absdate are inconsistent.')
2497
2498 data%georef%time_offset = 86400.d0*(readint2 - readint) + (readreal2 - readreal)
2499
2500! 9.6 Georeferencing
2501! ------------------
2502
2503 CALL ncdf_getvar(TRIM(tdir)//'latitude', data%georef%lat, &
2504 units=data%georef%units%lat)
2505 CALL ncdf_getvar(TRIM(tdir)//'longitude', data%georef%lon, &
2506 units=data%georef%units%lon)
2507 CALL ncdf_getvar(TRIM(tdir)//'undulation', data%georef%Undulation, &
2508 units=data%georef%units%Undulation)
2509 CALL ncdf_getvar(TRIM(tdir)//'r_curve', data%georef%roc, &
2510 units=data%georef%units%roc)
2511 CALL ncdf_getvar(TRIM(tdir)//'r_curve_centre_fixed', data%georef%r_coc, &
2512 units=data%georef%units%r_coc)
2513 CALL ncdf_getvar(TRIM(tdir)//'azimuth_north', data%georef%azimuth, &
2514 units=data%georef%units%azimuth)
2515
2516 ! FIXME: Do we need this?
2517 data%georef%reference_frame%r_coc = 'ECF'
2518
2519 ! get the location, velocity of leo and gnss, assure that the getbufr flag
2520 ! is set, not the getlevel1a. The getbufr only allocates one level 1a for
2521 ! this info and reads the value from the correct group occultation
2522 ! FIXME: Is this always done like this? What about when the level 1a has
2523 ! a dimension > 1, what is actually chosen for the one bufr value?
2524 ! It would be better to store the reference values for e.g. the bufr
2525 ! in a dedicated dimension, not in the level 1a one! This dimension
2526 ! would always have the value 1 when used, but allows to separate data
2527 ! at the reference point from the general level 1a data, which covers the
2528 ! whole occultation
2529
2530 IF (getbufr .AND. getlevel1a) THEN
2531
2532 CALL message(msg_fatal, &
2533 'Extraction of both BUFR and level1a data is not allowed.')
2534
2535 ELSE
2536
2537! IF (getbufr) THEN
2538 IF (.NOT. getlevel1a) THEN
2539
2540 CALL ropp_io_init(data%Lev1a, 1)
2541 CALL ncdf_getvar(TRIM(tdir)//'position_rec_fixed', data%Lev1a%r_leo(1,:), &
2542 units=data%Lev1a%units%r_leo, range = data%Lev1a%range%r_leo)
2543 CALL ncdf_getvar(TRIM(tdir)//'velocity_rec', data%Lev1a%v_leo(1,:), &
2544 units=data%Lev1a%units%v_leo, range = data%Lev1a%range%v_leo)
2545 CALL ncdf_getvar(TRIM(tdir)//'position_gns_fixed', data%Lev1a%r_gns(1,:), &
2546 units=data%Lev1a%units%r_gns, range = data%Lev1a%range%r_gns)
2547 CALL ncdf_getvar(TRIM(tdir)//'velocity_gns', data%Lev1a%v_gns(1,:), &
2548 units=data%Lev1a%units%v_gns, range = data%Lev1a%range%v_gns)
2549
2550 ! FIXME: Do we need this?
2551 data%Lev1a%reference_frame%r_leo = 'ECF'
2552 data%Lev1a%reference_frame%r_gns = 'ECF'
2553 data%Lev1a%reference_frame%v_leo = 'ECI'
2554 data%Lev1a%reference_frame%v_leo = 'ECI'
2555
2556 ! dtime set to zero for only 1 level 1A field
2557 data%Lev1a%dtime = 0.0_wp
2558
2559 ! mean SNR values for CA, P1, P2
2560 ! FIXME: - this is the EUMETSAT mean value for SLTA > 60km,
2561 ! should be mentioned in ROPP netCDF file if required!
2562 ! - data appears when doing a bufr2ropp, however seems not to be
2563 ! part of the bufr content.
2564 !tdir = TRIM(sdir)//'level_1a/closed_loop/'
2565 !CALL ncdf_getvar(TRIM(tdir)//'snr_ca_mean', data%Lev1a%snr_L1ca(1), &
2566 ! units=data%Lev1a%units%snr, range = data%Lev1a%range%snr)
2567 !CALL ncdf_getvar(TRIM(tdir)//'snr_p1_mean', data%Lev1a%snr_L1p(1), &
2568 ! units=data%Lev1a%units%snr, range = data%Lev1a%range%snr)
2569 !CALL ncdf_getvar(TRIM(tdir)//'snr_p2_mean', data%Lev1a%snr_L2p(1), &
2570 ! units=data%Lev1a%units%snr, range = data%Lev1a%range%snr)
2571
2572 ! data are available
2573 data%Lev1a%Missing = .FALSE.
2574
2575 ENDIF ! getbufr
2576
2577 ENDIF ! getbufr .AND. getlevel1a not both true
2578
2579
2580! 9.7 Level1a variables (if any)
2581! ------------------------------
2582
2583! 9.7.1 Closed Loop Level1a variables (if requested)
2584! --------------------------------------------------
2585
2586 IF (getlevel1a) THEN
2587
2588 ! FIXME: there should be a switch, similar to the level 1b resolution, to
2589 ! determine what lev1a data to read (cl only, cl+rs, cl+ol). For now the
2590 ! approach is to read and combine closed loop and raw sampling records.
2591 ! This and related stuff is Kjartan's update.
2592
2593 tdir = TRIM(sdir) // 'level_1a/closed_loop/'
2594
2595 IF (ncdf_isvar(TRIM(tdir)//'dtime')) THEN ! read CL data
2596
2597 CALL ncdf_getsize(TRIM(tdir)//'dtime', n_cl, dim = 1)
2598 CALL ropp_io_init(data_cl%Lev1a, n_cl)
2599
2600 ! Time
2601
2602 CALL ncdf_getvar(TRIM(tdir)//'dtime', data_cl%Lev1a%dtime, units=data_cl%Lev1a%units%dtime)
2603
2604 ! Position and velocity
2605
2606 ALLOCATE(r_gns(3,n_cl), v_gns(3,n_cl), r_leo(3,n_cl), v_leo(3,n_cl))
2607
2608 CALL ncdf_getvar(TRIM(tdir)//'r_transmitter', r_gns, &
2609 units=data_cl%Lev1a%units%r_gns)
2610 CALL ncdf_getvar(TRIM(tdir)//'v_transmitter', v_gns, &
2611 units=data_cl%Lev1a%units%v_gns)
2612 CALL ncdf_getvar(TRIM(tdir)//'r_receiver', r_leo, &
2613 units=data_cl%Lev1a%units%r_leo)
2614 CALL ncdf_getvar(TRIM(tdir)//'v_receiver', v_leo, &
2615 units=data_cl%Lev1a%units%v_leo)
2616
2617 data_cl%Lev1a%r_gns = TRANSPOSE(r_gns)
2618 data_cl%Lev1a%v_gns = TRANSPOSE(v_gns)
2619 data_cl%Lev1a%r_leo = TRANSPOSE(r_leo)
2620 data_cl%Lev1a%v_leo = TRANSPOSE(v_leo)
2621
2622 DEALLOCATE(r_gns, v_gns, r_leo, v_leo)
2623
2624 ! Phase and amplitude
2625
2626 CALL ncdf_getvar(TRIM(tdir)//'exphase_ca', data_cl%Lev1a%phase_L1, &
2627 units=data_cl%Lev1a%units%phase)
2628 CALL ncdf_getvar(TRIM(tdir)//'exphase_p2', data_cl%Lev1a%phase_L2, &
2629 units=data_cl%Lev1a%units%phase)
2630 CALL ncdf_getvar(TRIM(tdir)//'snr_ca', data_cl%Lev1a%snr_L1ca, &
2631 units=data_cl%Lev1a%units%snr)
2632 CALL ncdf_getvar(TRIM(tdir)//'snr_p1', data_cl%Lev1a%snr_L1p, &
2633 units=data_cl%Lev1a%units%snr)
2634 CALL ncdf_getvar(TRIM(tdir)//'snr_p2', data_cl%Lev1a%snr_L2p, &
2635 units=data_cl%Lev1a%units%snr)
2636
2637 ! Closed loop lost carrier flag (looking for data gaps)
2638
2639 ALLOCATE(cl_LCF(n_cl))
2640 cl_LCF(:) = 0
2641
2642 ts = MINVAL(ABS(data_cl%Lev1a%dtime(2:n_cl) - data_cl%Lev1a%dtime(1:n_cl-1)))
2643
2644 IF (BTEST(data_cl%PCD, PCD_rising)) THEN ! Rising occultation
2645 DO j=n_cl-1,1,-1
2646 ts1 = ABS(data_cl%Lev1a%dtime(j) - data_cl%Lev1a%dtime(j+1))
2647 IF (ts1 > 1.05*ts) THEN
2648 cl_LCF(j) = IBSET(cl_LCF(j), 3)
2649 cl_LCF(j+1) = IBSET(cl_LCF(j+1),3)
2650 ENDIF
2651 ENDDO
2652 ELSE ! Setting occultation
2653 DO j=2,n_cl
2654 ts1 = ABS(data_cl%Lev1a%dtime(j) - data_cl%Lev1a%dtime(j-1))
2655 IF (ts1 > 1.05*ts) THEN
2656 cl_LCF(j) = IBSET(cl_LCF(j), 3)
2657 cl_LCF(j-1) = IBSET(cl_LCF(j-1),3)
2658 ENDIF
2659 ENDDO
2660
2661 ENDIF ! Rising occultation
2662
2663 ENDIF ! /level_1a/closed_loop/dtime = true
2664
2665! 9.7.2 Raw Sampling Level1a variables (if requested)
2666! ---------------------------------------------------
2667
2668 n_rs = 0 ! will be set differently if RS data is available
2669
2670 CALL ncdf_getvar('/quality/rs_data_available', readbyte1)
2671
2672 IF (readbyte1 == 1) THEN
2673
2674 tdir = TRIM(sdir) // 'level_1a/raw_sampling/'
2675
2676 IF (ncdf_isvar(TRIM(tdir)//'dtime')) THEN ! read RS data
2677
2678 data%PCD = IBSET(data%PCD, PCD_open_loop)
2679 CALL ncdf_getsize(TRIM(tdir)//'dtime', n_rs, dim = 1)
2680 CALL ropp_io_init(data_rs%Lev1a, n_rs)
2681
2682 ! Time
2683
2684 CALL ncdf_getvar(TRIM(tdir)//'dtime', data_rs%Lev1a%dtime, units=data_rs%Lev1a%units%dtime)
2685
2686 ! Position and velocity
2687
2688 ALLOCATE(r_leo(3,n_rs), v_leo(3,n_rs), r_gns(3,n_rs), v_gns(3,n_rs))
2689
2690 CALL ncdf_getvar(TRIM(tdir)//'r_transmitter', r_gns, &
2691 units=data_rs%Lev1a%units%r_gns)
2692 CALL ncdf_getvar(TRIM(tdir)//'v_transmitter', v_gns, &
2693 units=data_rs%Lev1a%units%v_gns)
2694 CALL ncdf_getvar(TRIM(tdir)//'r_receiver', r_leo, &
2695 units=data_rs%Lev1a%units%r_leo)
2696 CALL ncdf_getvar(TRIM(tdir)//'v_receiver', v_leo, &
2697 units=data_rs%Lev1a%units%v_leo)
2698
2699 data_rs%Lev1a%r_gns = TRANSPOSE(r_gns)
2700 data_rs%Lev1a%v_gns = TRANSPOSE(v_gns)
2701 data_rs%Lev1a%r_leo = TRANSPOSE(r_leo)
2702 data_rs%Lev1a%v_leo = TRANSPOSE(v_leo)
2703
2704 DEALLOCATE(r_gns, v_gns, r_leo, v_leo)
2705
2706 ! Phase and amplitude
2707
2708 ALLOCATE(rs_navbit_int(n_rs))
2709 ALLOCATE(rs_navbit_ext(n_rs))
2710 ALLOCATE(tracking_state(n_rs))
2711
2712 CALL ncdf_getvar(TRIM(tdir)//'navbits_internal', rs_navbit_int)
2713 CALL ncdf_getvar('/quality/rs_external_navbits_applied', have_nb)
2714 CALL ncdf_getvar(TRIM(tdir)//'tracking_state', tracking_state)
2715
2716 IF (have_nb > 0) THEN
2717 CALL ncdf_getvar(TRIM(tdir)//'navbits_external', rs_navbit_ext)
2718 ELSE
2719 rs_navbit_ext(:) = rs_navbit_int(:)
2720 ENDIF
2721
2722 ALLOCATE(rs_phase_l1_iq(n_rs))
2723 ALLOCATE(rs_i_ca_uncorr(n_rs))
2724 ALLOCATE(rs_q_ca_uncorr(n_rs))
2725 ALLOCATE(rs_exphase_l1_nco(n_rs))
2726
2727 CALL ncdf_getvar(TRIM(tdir)//'i_ca_uncorr', rs_i_ca_uncorr)
2728 CALL ncdf_getvar(TRIM(tdir)//'q_ca_uncorr', rs_q_ca_uncorr)
2729 CALL ncdf_getvar(TRIM(tdir)//'exphase_l1_nco', rs_exphase_l1_nco, &
2730 units=data_rs%Lev1a%units%phase)
2731 CALL ncdf_getvar(TRIM(tdir)//'snr_ca', data_rs%Lev1a%snr_L1ca, &
2732 units=data_rs%Lev1a%units%snr)
2733
2734 DO j=1,n_rs
2735 rs_phase_l1_iq(j) = ATAN2(rs_q_ca_uncorr(j), rs_i_ca_uncorr(j)+TINY(1.0_wp))
2736 ENDDO
2737
2738 CALL Accumulate_Phase(rs_phase_l1_iq)
2739
2740 data_rs%lev1a%phase_l1(:) = rs_exphase_l1_nco(:) + &
2741 (c_light/(2.0_wp*pi1*f_L1))*rs_phase_l1_iq(:)
2742
2743! Comment in the line below if you wish to read the excess phase directly
2744! from the EUMETSAT file instead of deriving from I and Q
2745! CALL ncdf_getvar(TRIM(tdir)//'exphase_ca', &
2746! data_rs%Lev1a%phase_L1, units=data_rs%Lev1a%units%phase)
2747
2748! For rising profiles remove all data with tracking state = 2 in the
2749! beginning of the record as these are not valid.
2750
2751 IF (BTEST(data_rs%PCD, PCD_rising)) THEN ! Rising occultation
2752
2753 first_valid = -1 ! value to mark that this hasn't been set yet
2754
2755 DO j=1,n_rs
2756 IF ((tracking_state(j) /= 2) .AND. (first_valid == -1)) THEN
2757 first_valid = j
2758 ENDIF
2759 ENDDO
2760
2761 CALL ropp_io_shrink(data_rs%Lev1a, first_valid, n_rs, 1)
2762
2763 ALLOCATE(temparray(data_rs%Lev1a%Npoints))
2764
2765 temparray = rs_navbit_int(first_valid:n_rs)
2766
2767 DEALLOCATE(rs_navbit_int)
2768 ALLOCATE(rs_navbit_int(data_rs%Lev1a%Npoints))
2769 rs_navbit_int = temparray
2770
2771 temparray = rs_navbit_ext(first_valid:n_rs)
2772 DEALLOCATE(rs_navbit_ext)
2773 ALLOCATE(rs_navbit_ext(data_rs%Lev1a%Npoints))
2774 rs_navbit_ext = temparray
2775
2776 DEALLOCATE(temparray)
2777
2778 n_rs = data_rs%Lev1a%Npoints
2779
2780 ENDIF ! Rising occultation
2781
2782 ! data flag
2783
2784 ALLOCATE(rs_LCF(n_rs))
2785 rs_LCF(:) = 0
2786
2787 ts = MINVAL(ABS(data_rs%Lev1a%dtime(2:n_rs) - data_rs%Lev1a%dtime(1:n_rs-1)))
2788
2789 IF (BTEST(data_rs%PCD, PCD_rising)) THEN ! Rising occultation
2790 DO j=n_rs-1,1,-1
2791 ts1 = ABS(data_rs%Lev1a%dtime(j) - data_rs%Lev1a%dtime(j+1))
2792 IF (ts1 > 1.05*ts) THEN
2793 rs_LCF(j) = IBSET(rs_LCF(j), 3)
2794 rs_LCF(j+1) = IBSET(rs_LCF(j+1),3)
2795 ENDIF
2796 ENDDO
2797 ELSE ! Setting occultation
2798 DO j=2,n_rs
2799 ts1 = ABS(data_rs%Lev1a%dtime(j) - data_rs%Lev1a%dtime(j-1))
2800 IF (ts1 > 1.05*ts) THEN
2801 rs_LCF(j) = IBSET(rs_LCF(j), 3)
2802 rs_LCF(j-1) = IBSET(rs_LCF(j-1),3)
2803 ENDIF
2804 ENDDO
2805 ENDIF
2806
2807 rs_LCF(:) = IBSET(rs_LCF(:), 0) ! Open loop mode
2808
2809 WHERE (NINT(rs_navbit_ext(:)) == 1) ! External navbit
2810 rs_LCF(:) = IBSET(rs_LCF(:), 1)
2811 ENDWHERE
2812
2813 rs_LCF(:) = IBSET(rs_LCF(:), 2) ! Navbit quality OK
2814
2815 WHERE (NINT(rs_navbit_int(:)) == 1) ! Alternative navbit
2816 rs_LCF(:) = IBSET(rs_LCF(:), 4)
2817 ENDWHERE
2818
2819 rs_LCF(:) = IBSET(rs_LCF(:), 5) ! Alternative navbit quality
2820
2821 ! Setting flag for duplicated CL record
2822 WHERE((data_rs%Lev1a%dtime(1) < data_cl%Lev1a%dtime(:)) .AND. &
2823 (data_cl%Lev1a%dtime(:) < data_rs%Lev1a%dtime(n_rs)))
2824 cl_LCF(:) = IBSET(cl_LCF(:), 6)
2825 ENDWHERE
2826
2827 ENDIF ! /level_1a/raw_sampling/dtime exists
2828
2829 ENDIF ! /quality_control/rs_data_available is true
2830
2831! 9.7.3 Combine CL and RS Level1a variables (if requested)
2832! ---------------------------------------------------------
2833
2834 n = n_cl + n_rs
2835
2836 ! Initialise ro_data structure variables
2837
2838 CALL ropp_io_init(data%Lev1a, n)
2839 ALLOCATE(lcf(n))
2840
2841 ! Set output variables
2842
2843 IF (BTEST(data%PCD, PCD_rising)) THEN ! Rising occultation
2844
2845 DO j=1,n_cl
2846 data%lev1a%dtime(n_rs+j) = data_cl%lev1a%dtime(j)
2847 data%lev1a%r_gns(n_rs+j,:) = data_cl%lev1a%r_gns(j,:)
2848 data%lev1a%v_gns(n_rs+j,:) = data_cl%lev1a%v_gns(j,:)
2849 data%lev1a%r_leo(n_rs+j,:) = data_cl%lev1a%r_leo(j,:)
2850 data%lev1a%v_leo(n_rs+j,:) = data_cl%lev1a%v_leo(j,:)
2851 data%lev1a%snr_L1ca(n_rs+j) = data_cl%lev1a%snr_L1ca(j)
2852 data%lev1a%snr_L1p(n_rs+j) = data_cl%lev1a%snr_L1p(j)
2853 data%lev1a%snr_L2p(n_rs+j) = data_cl%lev1a%snr_L2p(j)
2854 data%lev1a%phase_L1(n_rs+j) = data_cl%lev1a%phase_L1(j)
2855 data%lev1a%phase_L2(n_rs+j) = data_cl%lev1a%phase_L2(j)
2856 lcf(n_rs+j) = cl_LCF(j)
2857 ENDDO
2858
2859 IF (n_rs /= 0) THEN
2860
2861 DO j=1,n_rs
2862 data%lev1a%dtime(j) = data_rs%lev1a%dtime(j)
2863 data%lev1a%r_gns(j,:) = data_rs%lev1a%r_gns(j,:)
2864 data%lev1a%v_gns(j,:) = data_rs%lev1a%v_gns(j,:)
2865 data%lev1a%r_leo(j,:) = data_rs%lev1a%r_leo(j,:)
2866 data%lev1a%v_leo(j,:) = data_rs%lev1a%v_leo(j,:)
2867 data%lev1a%snr_L1ca(j) = data_rs%lev1a%snr_L1ca(j)
2868 data%lev1a%snr_L1p(j) = ropp_MDFV
2869 data%lev1a%snr_L2p(j) = ropp_MDFV
2870 data%lev1a%phase_L1(j) = data_rs%lev1a%phase_L1(j)
2871 data%lev1a%phase_L2(j) = ropp_MDFV
2872 lcf(j) = rs_LCF(j)
2873 ENDDO
2874
2875 ! test for gap between cl and rs records
2876 ts = MINVAL(ABS(data_cl%lev1a%dtime(2:n_cl) - data_cl%lev1a%dtime(1:n_cl-1)))
2877
2878 IF (data_rs%lev1a%dtime(n_rs) < data_cl%lev1a%dtime(1)-1.5*ts) THEN
2879 LCF(n_rs:n_rs+1) = IBSET(LCF(n_rs:n_rs+1),3)
2880 ENDIF
2881
2882 ENDIF ! n_rs /= 0
2883
2884 ELSE ! Setting occultation
2885
2886 DO j=1,n_cl
2887 data%lev1a%dtime(j) = data_cl%lev1a%dtime(j)
2888 data%lev1a%r_gns(j,:) = data_cl%lev1a%r_gns(j,:)
2889 data%lev1a%v_gns(j,:) = data_cl%lev1a%v_gns(j,:)
2890 data%lev1a%r_leo(j,:) = data_cl%lev1a%r_leo(j,:)
2891 data%lev1a%v_leo(j,:) = data_cl%lev1a%v_leo(j,:)
2892 data%lev1a%snr_L1ca(j) = data_cl%lev1a%snr_L1ca(j)
2893 data%lev1a%snr_L1p(j) = data_cl%lev1a%snr_L1p(j)
2894 data%lev1a%snr_L2p(j) = data_cl%lev1a%snr_L2p(j)
2895 data%lev1a%phase_L1(j) = data_cl%lev1a%phase_L1(j)
2896 data%lev1a%phase_L2(j) = data_cl%lev1a%phase_L2(j)
2897 lcf(j) = cl_LCF(j)
2898 ENDDO
2899
2900 IF (n_rs /= 0) THEN
2901
2902 DO j=1,n_rs
2903 data%lev1a%dtime(n_cl+j) = data_rs%lev1a%dtime(j)
2904 data%lev1a%r_gns(n_cl+j,:) = data_rs%lev1a%r_gns(j,:)
2905 data%lev1a%v_gns(n_cl+j,:) = data_rs%lev1a%v_gns(j,:)
2906 data%lev1a%r_leo(n_cl+j,:) = data_rs%lev1a%r_leo(j,:)
2907 data%lev1a%v_leo(n_cl+j,:) = data_rs%lev1a%v_leo(j,:)
2908 data%lev1a%snr_L1ca(n_cl+j) = data_rs%lev1a%snr_L1ca(j)
2909 data%lev1a%snr_L1p(n_cl+j) = ropp_MDFV
2910 data%lev1a%snr_L2p(n_cl+j) = ropp_MDFV
2911 data%lev1a%phase_L1(n_cl+j) = data_rs%lev1a%phase_L1(j)
2912 data%lev1a%phase_L2(n_cl+j) = ropp_MDFV
2913 lcf(n_cl+j) = rs_LCF(j)
2914 ENDDO
2915
2916 ts = MINVAL(ABS(data_cl%lev1a%dtime(2:n_cl) - data_cl%lev1a%dtime(1:n_cl-1)))
2917
2918 IF (data_cl%lev1a%dtime(n_cl) < data_rs%lev1a%dtime(1)-1.5*ts) THEN
2919 LCF(n_cl:n_cl+1) = IBSET(LCF(n_cl:n_cl+1),3)
2920 ENDIF
2921
2922 ENDIF ! n_rs /= 0
2923
2924 ENDIF ! Rising occultation
2925
2926! 9.7.4 Missing/invalid data checks
2927! ---------------------------------
2928
2929 WHERE (ropp_io_isnan(data%Lev1a%phase_L1))
2930 data%Lev1a%phase_L1 = ropp_MDFV
2931 LCF = IBSET(LCF, 3)
2932 ENDWHERE
2933
2934 WHERE (ropp_io_isnan(data%Lev1a%phase_L2))
2935 data%Lev1a%phase_L2 = ropp_MDFV
2936 ENDWHERE
2937
2938 WHERE (ropp_io_isnan(data%Lev1a%snr_L1ca))
2939 data%Lev1a%snr_L1ca = ropp_MDFV
2940 LCF = IBSET(LCF, 3)
2941 ENDWHERE
2942
2943 WHERE (ropp_io_isnan(data%Lev1a%snr_L1p))
2944 data%Lev1a%snr_L1p = ropp_MDFV
2945 ENDWHERE
2946
2947 WHERE (ropp_io_isnan(data%Lev1a%snr_L2p))
2948 data%Lev1a%snr_L2p = ropp_MDFV
2949 ENDWHERE
2950
2951 data%Lev1a%reference_frame%r_gns = 'ECI'
2952 data%Lev1a%reference_frame%r_leo = 'ECI'
2953
2954 data%Lev1a%range%phase = (/ &
2955 MIN(MINVAL(data%Lev1a%phase_L1), data%Lev1a%range%phase(1)), &
2956 MAX(MAXVAL(data%Lev1a%phase_L1), data%Lev1a%range%phase(2)) /)
2957
2958 ! Add lost carrier information to file
2959
2960 CALL ropp_io_addvar_rodataD1d(data, &
2961 name = 'open_loop_lcf', &
2962 long_name= 'Lost Carrier Flag', &
2963 units = '', &
2964 range = (/-1000000.0_wp, 1000000.0_wp/), &
2965 DATA = REAL(LCF,wp) )
2966
2967 DEALLOCATE(LCF, CL_LCF)
2968
2969 CALL ropp_io_free(data_cl)
2970
2971 IF (n_rs /= 0) THEN
2972 DEALLOCATE(RS_LCF)
2973 CALL ropp_io_free(data_rs)
2974 ENDIF
2975
2976 ENDIF ! getlevel1a is true
2977
2978
2979! 9.8 Level1b variables (if any)
2980! ------------------------------
2981
2982 IF (ncdf_isvar(TRIM(ddir)//'impact')) THEN
2983 CALL ncdf_getsize(TRIM(ddir)//'impact', n, dim = 1)
2984 CALL ropp_io_init(data%Lev1b, n)
2985 ELSE
2986 data%Lev1b%Npoints = 0
2987 ENDIF
2988
2989 IF (data%Lev1b%Npoints > 0) THEN
2990
2991 CALL ncdf_getvar(TRIM(ddir)//'lat_tp', data%Lev1b%lat_tp, &
2992 units=data%Lev1b%units%lat_tp)
2993 CALL ncdf_getvar(TRIM(ddir)//'lon_tp', data%Lev1b%lon_tp, &
2994 units=data%Lev1b%units%lon_tp)
2995 CALL ncdf_getvar(TRIM(ddir)//'azimuth_tp', data%Lev1b%azimuth_tp, &
2996 units=data%Lev1b%units%azimuth_tp)
2997 CALL ncdf_getvar(TRIM(ddir)//'impact', data%Lev1b%impact, &
2998 units=data%Lev1b%units%impact)
2999 CALL ncdf_getvar(TRIM(ddir)//'impact', data%Lev1b%impact_L1, &
3000 units=data%Lev1b%units%impact)
3001 CALL ncdf_getvar(TRIM(ddir)//'impact', data%Lev1b%impact_L2, &
3002 units=data%Lev1b%units%impact)
3003 CALL ncdf_getvar(TRIM(ddir)//'bangle', data%Lev1b%bangle, &
3004 units=data%Lev1b%units%bangle)
3005 CALL ncdf_getvar(TRIM(ddir)//'bangle_ca', data%Lev1b%bangle_L1, &
3006 units=data%Lev1b%units%bangle)
3007 CALL ncdf_getvar(TRIM(ddir)//'bangle_p2', data%Lev1b%bangle_L2, &
3008 units=data%Lev1b%units%bangle)
3009
3010 ! remove all NaN from EUM fields
3011 ! FIXME: maybe do this in ncdf_getvar?
3012
3013 WHERE( .NOT. ropp_io_isnan(data%Lev1b%bangle) ) data%Lev1b%bangle_qual = 100.0_wp
3014
3015 WHERE( ropp_io_isnan(data%Lev1b%lat_tp) ) data%Lev1b%lat_tp = ropp_MDFV
3016 WHERE( ropp_io_isnan(data%Lev1b%lon_tp) ) data%Lev1b%lon_tp = ropp_MDFV
3017 WHERE( ropp_io_isnan(data%Lev1b%azimuth_tp) ) data%Lev1b%azimuth_tp = ropp_MDFV
3018 WHERE( ropp_io_isnan(data%Lev1b%bangle) ) data%Lev1b%bangle = ropp_MDFV
3019 WHERE( ropp_io_isnan(data%Lev1b%bangle_L1) ) data%Lev1b%bangle_L1 = ropp_MDFV
3020 WHERE( ropp_io_isnan(data%Lev1b%bangle_L2) ) data%Lev1b%bangle_L2 = ropp_MDFV
3021
3022 ! set the quality for bangle, EUMETSAT data uses NaN for missing
3023
3024 data%Lev1b%Missing = .FALSE.
3025
3026 ENDIF ! data%Lev1b%Npoints > 0
3027
3028
3029! 9.9 (Global) Attributes
3030! -----------------------
3031
3032 data%FmtVersion = ThisFmtVer
3033
3034 data%processing_centre = ' '
3035 CALL ncdf_getatt('institution', data%processing_centre)
3036
3037 data%pod_method = ' '
3038 CALL ncdf_getatt(TRIM(sdir)//'occultation/pod_method', data%pod_method)
3039
3040 data%phase_method = ' '
3041 CALL ncdf_getatt(TRIM(sdir)//'occultation/phase_method', data%phase_method)
3042
3043 data%bangle_method = ' '
3044 CALL ncdf_getatt(TRIM(sdir)//'occultation/retrieval_method', data%bangle_method)
3045
3046 data%refrac_method = 'UNKNOWN'
3047
3048 data%meteo_method = 'UNKNOWN'
3049
3050 IF (TRIM(resolution) == 'high_resolution') THEN
3051 data%thin_method = 'Unthinned data'
3052 ELSE
3053 data%thin_method = ' '
3054 CALL ncdf_getatt(TRIM(ddir)//'thinner_method', data%thin_method)
3055 ENDIF
3056
3057 ! Software version is the ROPP software version, in the format 'vnn.mmm'.
3058 ! At ROPP8.0, a new variable, 'processing_software', has been introduced,
3059 ! which can hold information about other software - in this case, the EUM
3060 ! processing code that generated the data in the first place.
3061
3062 data%software_version = ' ' ; readstr = ' ' ; readstr2 = ' '
3063
3064 CALL ncdf_getatt('/status/processing/processor_name' , readstr)
3065
3066 CALL ncdf_getatt('/status/processing/processor_version' ,readstr2)
3067
3068 data%processing_software = TRIM(readstr) // ' ' // TRIM(readstr2)
3069
3070 ! Processing time, split up string
3071 ! FIXME: Is there a library function for this that does some more format checks?
3072 CALL ncdf_getatt('/status/processing/creation_time', readstr)
3073
3074 SELECT CASE (LEN(TRIM(readstr)))
3075 CASE (14)
3076 READ(readstr, '(i4,i2,i2,i2,i2,i2)') &
3077 data%DTpro%Year, data%DTpro%Month, data%DTpro%Day, &
3078 data%DTpro%Hour, data%DTpro%Minute, data%DTpro%Second
3079 CASE (17)
3080 READ(readstr, '(i4,i2,i2,i2,i2,i2,i3)') &
3081 data%DTpro%Year, data%DTpro%Month, data%DTpro%Day, &
3082 data%DTpro%Hour, data%DTpro%Minute, data%DTpro%Second, data%DTpro%Msec
3083 CASE (19)
3084 READ(readstr, '(i4,1x,i2,1x,i2,1x,i2,1x,i2,1x,i2)') &
3085 data%DTpro%Year, data%DTpro%Month, data%DTpro%Day, &
3086 data%DTpro%Hour, data%DTpro%Minute, data%DTpro%Second
3087 CASE (23)
3088 READ(readstr, '(i4,1x,i2,1x,i2,1x,i2,1x,i2,1x,i2,1x,i3)') &
3089 data%DTpro%Year, data%DTpro%Month, data%DTpro%Day, &
3090 data%DTpro%Hour, data%DTpro%Minute, data%DTpro%Second, data%DTpro%Msec
3091 CASE DEFAULT
3092 CALL message( msg_warn, &
3093 'Invalid /status/processing/creation_time of ' // &
3094 TRIM(readstr) // ' ... defaulting DTpro%year etc.' )
3095 END SELECT
3096
3097
3098! 9.10 Occultation ID
3099! -------------------
3100
3101 CALL ropp_io_occid(DATA)
3102
3103
3104! 9.11 Clean up
3105! -------------
3106
3107! IF (ASSOCIATED(idx)) DEALLOCATE(idx)
3108
3109END SUBROUTINE ropp_io_read_eumdata
3110
3111
3112!-------------------------------------------------------------------------------
3113! 10. Accumulate phase
3114!-------------------------------------------------------------------------------
3115
3116SUBROUTINE Accumulate_Phase(Ph, Sign) ! (Array of (accumulated) phase, dir)
3117
3118! Method:
3119! Sign = 0 or no Sign:
3120! Adding +-2*Pi where phase jumps from
3121! +-Pi to -+Pi,
3122! Sign > 0:
3123! Adding +2*Pi where phase jumps from
3124! - to +
3125! Sign < 0
3126! Adding -2*Pi where phase jumps from
3127! + to -
3128
3129 ! 10.1 Declarations
3130
3131 USE typesizes, ONLY: wp => EightByteReal
3132
3133 IMPLICIT NONE
3134
3135 REAL(wp), DIMENSION(:), INTENT(inout) :: Ph ! Phase --> accumulated phase
3136 INTEGER, OPTIONAL, INTENT(in) :: Sign ! Phase change sign
3137! Pi already defined as parameter in coordinates module. Confuses pgf95.
3138 REAL(wp), PARAMETER :: pi1 = 3.141592653589793238_wp
3139 INTEGER :: i ! Array index
3140 INTEGER :: PSign ! Phase change sign
3141
3142 ! 10.2 Determine phase change sign
3143
3144 IF (.NOT. PRESENT(Sign)) THEN
3145 PSign = 0
3146 ELSE
3147 PSign = Sign
3148 ENDIF
3149
3150 ! 10.3 Accumulate phase
3151
3152 IF (PSign == 0) THEN
3153 DO i=2,SIZE(Ph)
3154 Ph(i) = Ph(i-1) + MODULO(Ph(i)-Ph(i-1)+pi1, 2.0_wp*pi1) - pi1
3155 ENDDO
3156 ELSEIF (PSign > 0) THEN
3157 DO i=2,SIZE(Ph)
3158 Ph(i) = Ph(i-1) + MODULO(Ph(i)-Ph(i-1), 2.0_wp*pi1)
3159 ENDDO
3160 ELSEIF (PSign < 0) THEN
3161 DO i=2,SIZE(Ph)
3162 Ph(i) = Ph(i-1) + MODULO(Ph(i)-Ph(i-1)+2.0_wp*pi1, 2.0_wp*pi1) - 2.0_wp*pi1
3163 ENDDO
3164 ENDIF
3165
3166END SUBROUTINE Accumulate_Phase
3167
3168!-------------------------------------------------------------------------------
3169! 11. Handle time format of EUM files
3170!-------------------------------------------------------------------------------
3171
3172SUBROUTINE abstimetoDT(i, r, DTocc)
3173
3174! Based on 'Practical Ephemeris Calculations' by Oliver Montenbruck
3175! (Springer-Verlag, 1989). Added handling of hour, seconds as well.
3176!
3177 USE ropp_io_types, ONLY: DT7type
3178
3179 IMPLICIT NONE
3180
3181 INTEGER, INTENT(in) :: i ! number of days since 2000-01-01 00:00:00
3182 REAL(KIND(1.0D0)), INTENT(in) :: r ! seconds since start of day
3183 TYPE(DT7type), INTENT(inout) :: DTocc
3184 REAL(KIND(1.0D0)) :: h, mi, s, ms
3185 INTEGER :: a, b, c, d, e, f, y, m, dd, jd
3186
3187 ! calculate JD from input, 2451545 is JD of 2000-01-01
3188 jd = i + 2451545
3189 a = INT(jd+0.5D0)
3190
3191 IF (a < 2299161) THEN
3192 c = a + 1524
3193 ELSE
3194 b = INT( (a - 1867216.25D0) / 36524.25D0 )
3195 c = a + b - INT(b/4D0) + 1525
3196 ENDIF
3197
3198 d = INT( ( c-122.1D0 ) / 365.25D0 )
3199 e = INT( 365.25D0*d)
3200 f = INT( (c-e) / 30.6001D0 )
3201 dd = c - e - INT( 30.6001*f ) + MOD( ( jd+0.5D0 ), DBLE(a) )
3202 m = f - 1 - 12*INT( f/14D0 )
3203 y = d - 4715 - INT( ( 7+m )/10.D0 )
3204
3205
3206 DTocc%Year = y
3207 DTocc%Month = m
3208 DTocc%Day = dd
3209 h = FLOOR(r/3600.D0)
3210 DTocc%Hour = INT(h)
3211 mi = FLOOR( (r - h*3600.D0) / 60.D0 )
3212 s = FLOOR( (r - h*3600.D0 - mi*60.D0 ) )
3213 ms = (r - h*3600.D0 - mi*60.D0 - s) * 1000.D0
3214 DTocc%Hour = INT(h)
3215 DTocc%Minute = INT(mi)
3216 DTocc%Second = INT(s)
3217 DTocc%Msec = INT(ms)
3218
3219END SUBROUTINE abstimetoDT
3220
3221!-------------------------------------------------------------------------------
3222! 12. Find where reals are NaN (used by EUMETSAT to indicate missing data)
3223!-------------------------------------------------------------------------------
3224
3225FUNCTION ropp_io_isnan(x) RESULT(lnan) ! Says where reals are NaNs.
3226
3227 USE typesizes, ONLY: wp => EightByteReal
3228
3229 IMPLICIT NONE
3230
3231 REAL(wp), DIMENSION(:), INTENT(IN) :: x
3232 LOGICAL, DIMENSION(SIZE(x)) :: lnan
3233 INTEGER :: k
3234
3235 lnan(:) = .FALSE.
3236
3237! g95 doesn't like this.
3238! WHERE ( &
3239! (x /= x) .OR. &
3240! (x + 1.0_wp == x) .OR. &
3241! ((x > 0) .EQV. (x <= 0)) &
3242! ) lnan = .TRUE.
3243
3244 DO k=1,SIZE(x)
3245 IF ( &
3246 (x(k) /= x(k)) .OR. &
3247 (x(k) + 1.0_wp == x(k)) .OR. &
3248 ((x(k) > 0) .EQV. (x(k) <= 0)) &
3249 ) lnan(k) = .TRUE.
3250 END DO
3251
3252END FUNCTION ropp_io_isnan
3253
3254
3255END SUBROUTINE ropp_io_read_ncdf_get_eumdata