Ticket #431: ropp_io_read_ncdf_get.f90.16072015

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

ropp_io_read_ncdf_get.f90.16072015

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 ! NRT of offline data
2452 CALL ncdf_getatt('environment', readstr)
2453 IF ( readstr /= 'Operational' ) data%PCD = IBSET(data%PCD, PCD_offline)
2454
2455 ! open or closed loop data setting
2456 CALL ncdf_getvar(TRIM(tdir)//'rs_data_available', readbyte1)
2457 CALL ncdf_getvar(TRIM(tdir)//'ol_data_available', readbyte2)
2458! IF ((readbyte1) .OR. (readbyte2)) data%PCD = IBSET(data%PCD, PCD_open_loop) - right now we only us RS, not OL
2459 IF ((readbyte1 /= 0) .OR. (readbyte2 /= 0)) data%PCD = IBSET(data%PCD, PCD_open_loop)
2460
2461 ! setting or rising
2462 CALL ncdf_getatt(TRIM(sdir)//'occultation/occultation_type', readstr)
2463 IF (TRIM(readstr) == 'rising') data%PCD = IBSET(data%PCD, PCD_rising)
2464
2465 ! closed loop phase measurements okay?
2466 CALL ncdf_getvar(TRIM(tdir)//'cl_snr_ca_ok', readbyte1)
2467 CALL ncdf_getvar(TRIM(tdir)//'cl_snr_p1_ok', readbyte2)
2468 CALL ncdf_getvar(TRIM(tdir)//'cl_snr_p2_ok', readbyte3)
2469 IF ((readbyte1 == 0) .AND. (readbyte2 == 0) .AND. (readbyte3 == 0)) &
2470 data%PCD = IBSET(data%PCD, PCD_phase)
2471
2472
2473! 9.5 Date and time
2474! -----------------
2475
2476 ! start time of occultation
2477 tdir = TRIM(sdir) // 'level_1b/'
2478
2479 CALL ncdf_getvar(TRIM(tdir)//'utc_start_absdate', readint)
2480 CALL ncdf_getvar(TRIM(tdir)//'utc_start_abstime', readreal)
2481
2482 ! check that we have the right time
2483 CALL ncdf_getatt(TRIM(tdir)//'units', readstr, 'utc_start_absdate')
2484 IF ( readstr == 'days since 2000-01-01 00:00:00.00' ) THEN
2485 CALL abstimetoDT(readint, readreal, data%DTocc)
2486 ELSE
2487 CALL message(msg_fatal, &
2488 'Time units found for utc_start_absdate are inconsistent.')
2489 ENDIF
2490
2491 ! difference between start time and georef time
2492 tdir = TRIM(sdir) // 'occultation/'
2493 CALL ncdf_getvar(TRIM(tdir)//'utc_georef_absdate', readint2)
2494 CALL ncdf_getvar(TRIM(tdir)//'utc_georef_abstime', readreal2)
2495
2496 ! check that we have the right time
2497 CALL ncdf_getatt(TRIM(tdir)//'units', readstr, 'utc_georef_absdate')
2498 IF ( .NOT. (readstr == 'days since 2000-01-01 00:00:00.00') ) &
2499 CALL message(msg_fatal, &
2500 'Time units found for utc_georef_absdate are inconsistent.')
2501
2502 data%georef%time_offset = 86400.d0*(readint2 - readint) + (readreal2 - readreal)
2503
2504! 9.6 Georeferencing
2505! ------------------
2506
2507 CALL ncdf_getvar(TRIM(tdir)//'latitude', data%georef%lat, &
2508 units=data%georef%units%lat)
2509 CALL ncdf_getvar(TRIM(tdir)//'longitude', data%georef%lon, &
2510 units=data%georef%units%lon)
2511 CALL ncdf_getvar(TRIM(tdir)//'undulation', data%georef%Undulation, &
2512 units=data%georef%units%Undulation)
2513 CALL ncdf_getvar(TRIM(tdir)//'r_curve', data%georef%roc, &
2514 units=data%georef%units%roc)
2515 CALL ncdf_getvar(TRIM(tdir)//'r_curve_centre_fixed', data%georef%r_coc, &
2516 units=data%georef%units%r_coc)
2517 CALL ncdf_getvar(TRIM(tdir)//'azimuth_north', data%georef%azimuth, &
2518 units=data%georef%units%azimuth)
2519
2520 ! FIXME: Do we need this?
2521 data%georef%reference_frame%r_coc = 'ECF'
2522
2523 ! get the location, velocity of leo and gnss, assure that the getbufr flag
2524 ! is set, not the getlevel1a. The getbufr only allocates one level 1a for
2525 ! this info and reads the value from the correct group occultation
2526 ! FIXME: Is this always done like this? What about when the level 1a has
2527 ! a dimension > 1, what is actually chosen for the one bufr value?
2528 ! It would be better to store the reference values for e.g. the bufr
2529 ! in a dedicated dimension, not in the level 1a one! This dimension
2530 ! would always have the value 1 when used, but allows to separate data
2531 ! at the reference point from the general level 1a data, which covers the
2532 ! whole occultation
2533
2534 IF (getbufr .AND. getlevel1a) THEN
2535
2536 CALL message(msg_fatal, &
2537 'Extraction of both BUFR and level1a data is not allowed.')
2538
2539 ELSE
2540
2541! IF (getbufr) THEN
2542 IF (.NOT. getlevel1a) THEN
2543
2544 CALL ropp_io_init(data%Lev1a, 1)
2545 CALL ncdf_getvar(TRIM(tdir)//'position_rec_fixed', data%Lev1a%r_leo(1,:), &
2546 units=data%Lev1a%units%r_leo, range = data%Lev1a%range%r_leo)
2547 CALL ncdf_getvar(TRIM(tdir)//'velocity_rec', data%Lev1a%v_leo(1,:), &
2548 units=data%Lev1a%units%v_leo, range = data%Lev1a%range%v_leo)
2549 CALL ncdf_getvar(TRIM(tdir)//'position_gns_fixed', data%Lev1a%r_gns(1,:), &
2550 units=data%Lev1a%units%r_gns, range = data%Lev1a%range%r_gns)
2551 CALL ncdf_getvar(TRIM(tdir)//'velocity_gns', data%Lev1a%v_gns(1,:), &
2552 units=data%Lev1a%units%v_gns, range = data%Lev1a%range%v_gns)
2553
2554 ! FIXME: Do we need this?
2555 data%Lev1a%reference_frame%r_leo = 'ECF'
2556 data%Lev1a%reference_frame%r_gns = 'ECF'
2557 data%Lev1a%reference_frame%v_leo = 'ECI'
2558 data%Lev1a%reference_frame%v_leo = 'ECI'
2559
2560 ! dtime set to zero for only 1 level 1A field
2561 data%Lev1a%dtime = 0.0_wp
2562
2563 ! mean SNR values for CA, P1, P2
2564 ! FIXME: - this is the EUMETSAT mean value for SLTA > 60km,
2565 ! should be mentioned in ROPP netCDF file if required!
2566 ! - data appears when doing a bufr2ropp, however seems not to be
2567 ! part of the bufr content.
2568 !tdir = TRIM(sdir)//'level_1a/closed_loop/'
2569 !CALL ncdf_getvar(TRIM(tdir)//'snr_ca_mean', data%Lev1a%snr_L1ca(1), &
2570 ! units=data%Lev1a%units%snr, range = data%Lev1a%range%snr)
2571 !CALL ncdf_getvar(TRIM(tdir)//'snr_p1_mean', data%Lev1a%snr_L1p(1), &
2572 ! units=data%Lev1a%units%snr, range = data%Lev1a%range%snr)
2573 !CALL ncdf_getvar(TRIM(tdir)//'snr_p2_mean', data%Lev1a%snr_L2p(1), &
2574 ! units=data%Lev1a%units%snr, range = data%Lev1a%range%snr)
2575
2576 ! data are available
2577 data%Lev1a%Missing = .FALSE.
2578
2579 ENDIF ! getbufr
2580
2581 ENDIF ! getbufr .AND. getlevel1a not both true
2582
2583
2584! 9.7 Level1a variables (if any)
2585! ------------------------------
2586
2587! 9.7.1 Closed Loop Level1a variables (if requested)
2588! --------------------------------------------------
2589
2590 IF (getlevel1a) THEN
2591
2592 ! FIXME: there should be a switch, similar to the level 1b resolution, to
2593 ! determine what lev1a data to read (cl only, cl+rs, cl+ol). For now the
2594 ! approach is to read and combine closed loop and raw sampling records.
2595 ! This and related stuff is Kjartan's update.
2596
2597 tdir = TRIM(sdir) // 'level_1a/closed_loop/'
2598
2599 IF (ncdf_isvar(TRIM(tdir)//'dtime')) THEN ! read CL data
2600
2601 CALL ncdf_getsize(TRIM(tdir)//'dtime', n_cl, dim = 1)
2602 CALL ropp_io_init(data_cl%Lev1a, n_cl)
2603
2604 ! Time
2605
2606 CALL ncdf_getvar(TRIM(tdir)//'dtime', data_cl%Lev1a%dtime, units=data_cl%Lev1a%units%dtime)
2607
2608 ! Position and velocity
2609
2610 ALLOCATE(r_gns(3,n_cl), v_gns(3,n_cl), r_leo(3,n_cl), v_leo(3,n_cl))
2611
2612 CALL ncdf_getvar(TRIM(tdir)//'r_transmitter', r_gns, &
2613 units=data_cl%Lev1a%units%r_gns)
2614 CALL ncdf_getvar(TRIM(tdir)//'v_transmitter', v_gns, &
2615 units=data_cl%Lev1a%units%v_gns)
2616 CALL ncdf_getvar(TRIM(tdir)//'r_receiver', r_leo, &
2617 units=data_cl%Lev1a%units%r_leo)
2618 CALL ncdf_getvar(TRIM(tdir)//'v_receiver', v_leo, &
2619 units=data_cl%Lev1a%units%v_leo)
2620
2621 data_cl%Lev1a%r_gns = TRANSPOSE(r_gns)
2622 data_cl%Lev1a%v_gns = TRANSPOSE(v_gns)
2623 data_cl%Lev1a%r_leo = TRANSPOSE(r_leo)
2624 data_cl%Lev1a%v_leo = TRANSPOSE(v_leo)
2625
2626 DEALLOCATE(r_gns, v_gns, r_leo, v_leo)
2627
2628 ! Phase and amplitude
2629
2630 CALL ncdf_getvar(TRIM(tdir)//'exphase_ca', data_cl%Lev1a%phase_L1, &
2631 units=data_cl%Lev1a%units%phase)
2632 CALL ncdf_getvar(TRIM(tdir)//'exphase_p2', data_cl%Lev1a%phase_L2, &
2633 units=data_cl%Lev1a%units%phase)
2634 CALL ncdf_getvar(TRIM(tdir)//'snr_ca', data_cl%Lev1a%snr_L1ca, &
2635 units=data_cl%Lev1a%units%snr)
2636 CALL ncdf_getvar(TRIM(tdir)//'snr_p1', data_cl%Lev1a%snr_L1p, &
2637 units=data_cl%Lev1a%units%snr)
2638 CALL ncdf_getvar(TRIM(tdir)//'snr_p2', data_cl%Lev1a%snr_L2p, &
2639 units=data_cl%Lev1a%units%snr)
2640
2641 ! Closed loop lost carrier flag (looking for data gaps)
2642
2643 ALLOCATE(cl_LCF(n_cl))
2644 cl_LCF(:) = 0
2645
2646 ts = MINVAL(ABS(data_cl%Lev1a%dtime(2:n_cl) - data_cl%Lev1a%dtime(1:n_cl-1)))
2647
2648 IF (BTEST(data_cl%PCD, PCD_rising)) THEN ! Rising occultation
2649 DO j=n_cl-1,1,-1
2650 ts1 = ABS(data_cl%Lev1a%dtime(j) - data_cl%Lev1a%dtime(j+1))
2651 IF (ts1 > 1.05*ts) THEN
2652 cl_LCF(j) = IBSET(cl_LCF(j), 3)
2653 cl_LCF(j+1) = IBSET(cl_LCF(j+1),3)
2654 ENDIF
2655 ENDDO
2656 ELSE ! Setting occultation
2657 DO j=2,n_cl
2658 ts1 = ABS(data_cl%Lev1a%dtime(j) - data_cl%Lev1a%dtime(j-1))
2659 IF (ts1 > 1.05*ts) THEN
2660 cl_LCF(j) = IBSET(cl_LCF(j), 3)
2661 cl_LCF(j-1) = IBSET(cl_LCF(j-1),3)
2662 ENDIF
2663 ENDDO
2664
2665 ENDIF ! Rising occultation
2666
2667 ENDIF ! /level_1a/closed_loop/dtime = true
2668
2669! 9.7.2 Raw Sampling Level1a variables (if requested)
2670! ---------------------------------------------------
2671
2672 n_rs = 0 ! will be set differently if RS data is available
2673
2674 CALL ncdf_getvar('/quality/rs_data_available', readbyte1)
2675
2676 IF (readbyte1 == 1) THEN
2677
2678 tdir = TRIM(sdir) // 'level_1a/raw_sampling/'
2679
2680 IF (ncdf_isvar(TRIM(tdir)//'dtime')) THEN ! read RS data
2681
2682 data%PCD = IBSET(data%PCD, PCD_open_loop)
2683 CALL ncdf_getsize(TRIM(tdir)//'dtime', n_rs, dim = 1)
2684 CALL ropp_io_init(data_rs%Lev1a, n_rs)
2685
2686 ! Time
2687
2688 CALL ncdf_getvar(TRIM(tdir)//'dtime', data_rs%Lev1a%dtime, units=data_rs%Lev1a%units%dtime)
2689
2690 ! Position and velocity
2691
2692 ALLOCATE(r_leo(3,n_rs), v_leo(3,n_rs), r_gns(3,n_rs), v_gns(3,n_rs))
2693
2694 CALL ncdf_getvar(TRIM(tdir)//'r_transmitter', r_gns, &
2695 units=data_rs%Lev1a%units%r_gns)
2696 CALL ncdf_getvar(TRIM(tdir)//'v_transmitter', v_gns, &
2697 units=data_rs%Lev1a%units%v_gns)
2698 CALL ncdf_getvar(TRIM(tdir)//'r_receiver', r_leo, &
2699 units=data_rs%Lev1a%units%r_leo)
2700 CALL ncdf_getvar(TRIM(tdir)//'v_receiver', v_leo, &
2701 units=data_rs%Lev1a%units%v_leo)
2702
2703 data_rs%Lev1a%r_gns = TRANSPOSE(r_gns)
2704 data_rs%Lev1a%v_gns = TRANSPOSE(v_gns)
2705 data_rs%Lev1a%r_leo = TRANSPOSE(r_leo)
2706 data_rs%Lev1a%v_leo = TRANSPOSE(v_leo)
2707
2708 DEALLOCATE(r_gns, v_gns, r_leo, v_leo)
2709
2710 ! Phase and amplitude
2711
2712 ALLOCATE(rs_navbit_int(n_rs))
2713 ALLOCATE(rs_navbit_ext(n_rs))
2714 ALLOCATE(tracking_state(n_rs))
2715
2716 CALL ncdf_getvar(TRIM(tdir)//'navbits_internal', rs_navbit_int)
2717 CALL ncdf_getvar('/quality/rs_external_navbits_applied', have_nb)
2718 CALL ncdf_getvar(TRIM(tdir)//'tracking_state', tracking_state)
2719
2720 IF (have_nb > 0) THEN
2721 CALL ncdf_getvar(TRIM(tdir)//'navbits_external', rs_navbit_ext)
2722 ELSE
2723 rs_navbit_ext(:) = rs_navbit_int(:)
2724 ENDIF
2725
2726 ALLOCATE(rs_phase_l1_iq(n_rs))
2727 ALLOCATE(rs_i_ca_uncorr(n_rs))
2728 ALLOCATE(rs_q_ca_uncorr(n_rs))
2729 ALLOCATE(rs_exphase_l1_nco(n_rs))
2730
2731 CALL ncdf_getvar(TRIM(tdir)//'i_ca_uncorr', rs_i_ca_uncorr)
2732 CALL ncdf_getvar(TRIM(tdir)//'q_ca_uncorr', rs_q_ca_uncorr)
2733 CALL ncdf_getvar(TRIM(tdir)//'exphase_l1_nco', rs_exphase_l1_nco, &
2734 units=data_rs%Lev1a%units%phase)
2735 CALL ncdf_getvar(TRIM(tdir)//'snr_ca', data_rs%Lev1a%snr_L1ca, &
2736 units=data_rs%Lev1a%units%snr)
2737
2738 DO j=1,n_rs
2739 rs_phase_l1_iq(j) = ATAN2(rs_q_ca_uncorr(j), rs_i_ca_uncorr(j)+TINY(1.0_wp))
2740 ENDDO
2741
2742 CALL Accumulate_Phase(rs_phase_l1_iq)
2743
2744 data_rs%lev1a%phase_l1(:) = rs_exphase_l1_nco(:) + &
2745 (c_light/(2.0_wp*pi1*f_L1))*rs_phase_l1_iq(:)
2746
2747! Comment in the line below if you wish to read the excess phase directly
2748! from the EUMETSAT file instead of deriving from I and Q
2749! CALL ncdf_getvar(TRIM(tdir)//'exphase_ca', &
2750! data_rs%Lev1a%phase_L1, units=data_rs%Lev1a%units%phase)
2751
2752! For rising profiles remove all data with tracking state = 2 in the
2753! beginning of the record as these are not valid.
2754
2755 IF (BTEST(data_rs%PCD, PCD_rising)) THEN ! Rising occultation
2756
2757 first_valid = -1 ! value to mark that this hasn't been set yet
2758
2759 DO j=1,n_rs
2760 IF ((tracking_state(j) /= 2) .AND. (first_valid == -1)) THEN
2761 first_valid = j
2762 ENDIF
2763 ENDDO
2764
2765 CALL ropp_io_shrink(data_rs%Lev1a, first_valid, n_rs, 1)
2766
2767 ALLOCATE(temparray(data_rs%Lev1a%Npoints))
2768
2769 temparray = rs_navbit_int(first_valid:n_rs)
2770
2771 DEALLOCATE(rs_navbit_int)
2772 ALLOCATE(rs_navbit_int(data_rs%Lev1a%Npoints))
2773 rs_navbit_int = temparray
2774
2775 temparray = rs_navbit_ext(first_valid:n_rs)
2776 DEALLOCATE(rs_navbit_ext)
2777 ALLOCATE(rs_navbit_ext(data_rs%Lev1a%Npoints))
2778 rs_navbit_ext = temparray
2779
2780 DEALLOCATE(temparray)
2781
2782 n_rs = data_rs%Lev1a%Npoints
2783
2784 ENDIF ! Rising occultation
2785
2786 ! data flag
2787
2788 ALLOCATE(rs_LCF(n_rs))
2789 rs_LCF(:) = 0
2790
2791 ts = MINVAL(ABS(data_rs%Lev1a%dtime(2:n_rs) - data_rs%Lev1a%dtime(1:n_rs-1)))
2792
2793 IF (BTEST(data_rs%PCD, PCD_rising)) THEN ! Rising occultation
2794 DO j=n_rs-1,1,-1
2795 ts1 = ABS(data_rs%Lev1a%dtime(j) - data_rs%Lev1a%dtime(j+1))
2796 IF (ts1 > 1.05*ts) THEN
2797 rs_LCF(j) = IBSET(rs_LCF(j), 3)
2798 rs_LCF(j+1) = IBSET(rs_LCF(j+1),3)
2799 ENDIF
2800 ENDDO
2801 ELSE ! Setting occultation
2802 DO j=2,n_rs
2803 ts1 = ABS(data_rs%Lev1a%dtime(j) - data_rs%Lev1a%dtime(j-1))
2804 IF (ts1 > 1.05*ts) THEN
2805 rs_LCF(j) = IBSET(rs_LCF(j), 3)
2806 rs_LCF(j-1) = IBSET(rs_LCF(j-1),3)
2807 ENDIF
2808 ENDDO
2809 ENDIF
2810
2811 rs_LCF(:) = IBSET(rs_LCF(:), 0) ! Open loop mode
2812
2813 WHERE (NINT(rs_navbit_ext(:)) == 1) ! External navbit
2814 rs_LCF(:) = IBSET(rs_LCF(:), 1)
2815 ENDWHERE
2816
2817 rs_LCF(:) = IBSET(rs_LCF(:), 2) ! Navbit quality OK
2818
2819 WHERE (NINT(rs_navbit_int(:)) == 1) ! Alternative navbit
2820 rs_LCF(:) = IBSET(rs_LCF(:), 4)
2821 ENDWHERE
2822
2823 rs_LCF(:) = IBSET(rs_LCF(:), 5) ! Alternative navbit quality
2824
2825 ! Setting flag for duplicated CL record
2826 WHERE((data_rs%Lev1a%dtime(1) < data_cl%Lev1a%dtime(:)) .AND. &
2827 (data_cl%Lev1a%dtime(:) < data_rs%Lev1a%dtime(n_rs)))
2828 cl_LCF(:) = IBSET(cl_LCF(:), 6)
2829 ENDWHERE
2830
2831 ENDIF ! /level_1a/raw_sampling/dtime exists
2832
2833 ENDIF ! /quality_control/rs_data_available is true
2834
2835! 9.7.3 Combine CL and RS Level1a variables (if requested)
2836! ---------------------------------------------------------
2837
2838 n = n_cl + n_rs
2839
2840 ! Initialise ro_data structure variables
2841
2842 CALL ropp_io_init(data%Lev1a, n)
2843 ALLOCATE(lcf(n))
2844
2845 ! Set output variables
2846
2847 IF (BTEST(data%PCD, PCD_rising)) THEN ! Rising occultation
2848
2849 DO j=1,n_cl
2850 data%lev1a%dtime(n_rs+j) = data_cl%lev1a%dtime(j)
2851 data%lev1a%r_gns(n_rs+j,:) = data_cl%lev1a%r_gns(j,:)
2852 data%lev1a%v_gns(n_rs+j,:) = data_cl%lev1a%v_gns(j,:)
2853 data%lev1a%r_leo(n_rs+j,:) = data_cl%lev1a%r_leo(j,:)
2854 data%lev1a%v_leo(n_rs+j,:) = data_cl%lev1a%v_leo(j,:)
2855 data%lev1a%snr_L1ca(n_rs+j) = data_cl%lev1a%snr_L1ca(j)
2856 data%lev1a%snr_L1p(n_rs+j) = data_cl%lev1a%snr_L1p(j)
2857 data%lev1a%snr_L2p(n_rs+j) = data_cl%lev1a%snr_L2p(j)
2858 data%lev1a%phase_L1(n_rs+j) = data_cl%lev1a%phase_L1(j)
2859 data%lev1a%phase_L2(n_rs+j) = data_cl%lev1a%phase_L2(j)
2860 lcf(n_rs+j) = cl_LCF(j)
2861 ENDDO
2862
2863 IF (n_rs /= 0) THEN
2864
2865 DO j=1,n_rs
2866 data%lev1a%dtime(j) = data_rs%lev1a%dtime(j)
2867 data%lev1a%r_gns(j,:) = data_rs%lev1a%r_gns(j,:)
2868 data%lev1a%v_gns(j,:) = data_rs%lev1a%v_gns(j,:)
2869 data%lev1a%r_leo(j,:) = data_rs%lev1a%r_leo(j,:)
2870 data%lev1a%v_leo(j,:) = data_rs%lev1a%v_leo(j,:)
2871 data%lev1a%snr_L1ca(j) = data_rs%lev1a%snr_L1ca(j)
2872 data%lev1a%snr_L1p(j) = ropp_MDFV
2873 data%lev1a%snr_L2p(j) = ropp_MDFV
2874 data%lev1a%phase_L1(j) = data_rs%lev1a%phase_L1(j)
2875 data%lev1a%phase_L2(j) = ropp_MDFV
2876 lcf(j) = rs_LCF(j)
2877 ENDDO
2878
2879 ! test for gap between cl and rs records
2880 ts = MINVAL(ABS(data_cl%lev1a%dtime(2:n_cl) - data_cl%lev1a%dtime(1:n_cl-1)))
2881
2882 IF (data_rs%lev1a%dtime(n_rs) < data_cl%lev1a%dtime(1)-1.5*ts) THEN
2883 LCF(n_rs:n_rs+1) = IBSET(LCF(n_rs:n_rs+1),3)
2884 ENDIF
2885
2886 ENDIF ! n_rs /= 0
2887
2888 ELSE ! Setting occultation
2889
2890 DO j=1,n_cl
2891 data%lev1a%dtime(j) = data_cl%lev1a%dtime(j)
2892 data%lev1a%r_gns(j,:) = data_cl%lev1a%r_gns(j,:)
2893 data%lev1a%v_gns(j,:) = data_cl%lev1a%v_gns(j,:)
2894 data%lev1a%r_leo(j,:) = data_cl%lev1a%r_leo(j,:)
2895 data%lev1a%v_leo(j,:) = data_cl%lev1a%v_leo(j,:)
2896 data%lev1a%snr_L1ca(j) = data_cl%lev1a%snr_L1ca(j)
2897 data%lev1a%snr_L1p(j) = data_cl%lev1a%snr_L1p(j)
2898 data%lev1a%snr_L2p(j) = data_cl%lev1a%snr_L2p(j)
2899 data%lev1a%phase_L1(j) = data_cl%lev1a%phase_L1(j)
2900 data%lev1a%phase_L2(j) = data_cl%lev1a%phase_L2(j)
2901 lcf(j) = cl_LCF(j)
2902 ENDDO
2903
2904 IF (n_rs /= 0) THEN
2905
2906 DO j=1,n_rs
2907 data%lev1a%dtime(n_cl+j) = data_rs%lev1a%dtime(j)
2908 data%lev1a%r_gns(n_cl+j,:) = data_rs%lev1a%r_gns(j,:)
2909 data%lev1a%v_gns(n_cl+j,:) = data_rs%lev1a%v_gns(j,:)
2910 data%lev1a%r_leo(n_cl+j,:) = data_rs%lev1a%r_leo(j,:)
2911 data%lev1a%v_leo(n_cl+j,:) = data_rs%lev1a%v_leo(j,:)
2912 data%lev1a%snr_L1ca(n_cl+j) = data_rs%lev1a%snr_L1ca(j)
2913 data%lev1a%snr_L1p(n_cl+j) = ropp_MDFV
2914 data%lev1a%snr_L2p(n_cl+j) = ropp_MDFV
2915 data%lev1a%phase_L1(n_cl+j) = data_rs%lev1a%phase_L1(j)
2916 data%lev1a%phase_L2(n_cl+j) = ropp_MDFV
2917 lcf(n_cl+j) = rs_LCF(j)
2918 ENDDO
2919
2920 ts = MINVAL(ABS(data_cl%lev1a%dtime(2:n_cl) - data_cl%lev1a%dtime(1:n_cl-1)))
2921
2922 IF (data_cl%lev1a%dtime(n_cl) < data_rs%lev1a%dtime(1)-1.5*ts) THEN
2923 LCF(n_cl:n_cl+1) = IBSET(LCF(n_cl:n_cl+1),3)
2924 ENDIF
2925
2926 ENDIF ! n_rs /= 0
2927
2928 ENDIF ! Rising occultation
2929
2930! 9.7.4 Missing/invalid data checks
2931! ---------------------------------
2932
2933 WHERE (ropp_io_isnan(data%Lev1a%phase_L1))
2934 data%Lev1a%phase_L1 = ropp_MDFV
2935 LCF = IBSET(LCF, 3)
2936 ENDWHERE
2937
2938 WHERE (ropp_io_isnan(data%Lev1a%phase_L2))
2939 data%Lev1a%phase_L2 = ropp_MDFV
2940 ENDWHERE
2941
2942 WHERE (ropp_io_isnan(data%Lev1a%snr_L1ca))
2943 data%Lev1a%snr_L1ca = ropp_MDFV
2944 LCF = IBSET(LCF, 3)
2945 ENDWHERE
2946
2947 WHERE (ropp_io_isnan(data%Lev1a%snr_L1p))
2948 data%Lev1a%snr_L1p = ropp_MDFV
2949 ENDWHERE
2950
2951 WHERE (ropp_io_isnan(data%Lev1a%snr_L2p))
2952 data%Lev1a%snr_L2p = ropp_MDFV
2953 ENDWHERE
2954
2955 data%Lev1a%reference_frame%r_gns = 'ECI'
2956 data%Lev1a%reference_frame%r_leo = 'ECI'
2957
2958 data%Lev1a%range%phase = (/ &
2959 MIN(MINVAL(data%Lev1a%phase_L1), data%Lev1a%range%phase(1)), &
2960 MAX(MAXVAL(data%Lev1a%phase_L1), data%Lev1a%range%phase(2)) /)
2961
2962 ! Add lost carrier information to file
2963
2964 CALL ropp_io_addvar_rodataD1d(data, &
2965 name = 'open_loop_lcf', &
2966 long_name= 'Lost Carrier Flag', &
2967 units = '', &
2968 range = (/-1000000.0_wp, 1000000.0_wp/), &
2969 DATA = REAL(LCF,wp) )
2970
2971 DEALLOCATE(LCF, CL_LCF)
2972
2973 CALL ropp_io_free(data_cl)
2974
2975 IF (n_rs /= 0) THEN
2976 DEALLOCATE(RS_LCF)
2977 CALL ropp_io_free(data_rs)
2978 ENDIF
2979
2980 ENDIF ! getlevel1a is true
2981
2982
2983! 9.8 Level1b variables (if any)
2984! ------------------------------
2985
2986 IF (ncdf_isvar(TRIM(ddir)//'impact')) THEN
2987 CALL ncdf_getsize(TRIM(ddir)//'impact', n, dim = 1)
2988 CALL ropp_io_init(data%Lev1b, n)
2989 ELSE
2990 data%Lev1b%Npoints = 0
2991 ENDIF
2992
2993 IF (data%Lev1b%Npoints > 0) THEN
2994
2995 CALL ncdf_getvar(TRIM(ddir)//'lat_tp', data%Lev1b%lat_tp, &
2996 units=data%Lev1b%units%lat_tp)
2997 CALL ncdf_getvar(TRIM(ddir)//'lon_tp', data%Lev1b%lon_tp, &
2998 units=data%Lev1b%units%lon_tp)
2999 CALL ncdf_getvar(TRIM(ddir)//'azimuth_tp', data%Lev1b%azimuth_tp, &
3000 units=data%Lev1b%units%azimuth_tp)
3001 CALL ncdf_getvar(TRIM(ddir)//'impact', data%Lev1b%impact, &
3002 units=data%Lev1b%units%impact)
3003 CALL ncdf_getvar(TRIM(ddir)//'impact', data%Lev1b%impact_L1, &
3004 units=data%Lev1b%units%impact)
3005 CALL ncdf_getvar(TRIM(ddir)//'impact', data%Lev1b%impact_L2, &
3006 units=data%Lev1b%units%impact)
3007 CALL ncdf_getvar(TRIM(ddir)//'bangle', data%Lev1b%bangle, &
3008 units=data%Lev1b%units%bangle)
3009 CALL ncdf_getvar(TRIM(ddir)//'bangle_ca', data%Lev1b%bangle_L1, &
3010 units=data%Lev1b%units%bangle)
3011 CALL ncdf_getvar(TRIM(ddir)//'bangle_p2', data%Lev1b%bangle_L2, &
3012 units=data%Lev1b%units%bangle)
3013
3014 ! remove all NaN from EUM fields
3015 ! FIXME: maybe do this in ncdf_getvar?
3016
3017 WHERE( .NOT. ropp_io_isnan(data%Lev1b%bangle) ) data%Lev1b%bangle_qual = 100.0_wp
3018
3019 WHERE( ropp_io_isnan(data%Lev1b%lat_tp) ) data%Lev1b%lat_tp = ropp_MDFV
3020 WHERE( ropp_io_isnan(data%Lev1b%lon_tp) ) data%Lev1b%lon_tp = ropp_MDFV
3021 WHERE( ropp_io_isnan(data%Lev1b%azimuth_tp) ) data%Lev1b%azimuth_tp = ropp_MDFV
3022 WHERE( ropp_io_isnan(data%Lev1b%bangle) ) data%Lev1b%bangle = ropp_MDFV
3023 WHERE( ropp_io_isnan(data%Lev1b%bangle_L1) ) data%Lev1b%bangle_L1 = ropp_MDFV
3024 WHERE( ropp_io_isnan(data%Lev1b%bangle_L2) ) data%Lev1b%bangle_L2 = ropp_MDFV
3025
3026 ! set the quality for bangle, EUMETSAT data uses NaN for missing
3027
3028 data%Lev1b%Missing = .FALSE.
3029
3030 ENDIF ! data%Lev1b%Npoints > 0
3031
3032
3033! 9.9 (Global) Attributes
3034! -----------------------
3035
3036 data%FmtVersion = ThisFmtVer
3037
3038 data%processing_centre = ' '
3039 CALL ncdf_getatt('institution', data%processing_centre)
3040
3041 data%pod_method = ' '
3042 CALL ncdf_getatt(TRIM(sdir)//'occultation/pod_method', data%pod_method)
3043
3044 data%phase_method = ' '
3045 CALL ncdf_getatt(TRIM(sdir)//'occultation/phase_method', data%phase_method)
3046
3047 data%bangle_method = ' '
3048 CALL ncdf_getatt(TRIM(sdir)//'occultation/retrieval_method', data%bangle_method)
3049
3050 data%refrac_method = 'UNKNOWN'
3051
3052 data%meteo_method = 'UNKNOWN'
3053
3054 IF (TRIM(resolution) == 'high_resolution') THEN
3055 data%thin_method = 'Unthinned data'
3056 ELSE
3057 data%thin_method = ' '
3058 CALL ncdf_getatt(TRIM(ddir)//'thinner_method', data%thin_method)
3059 ENDIF
3060
3061 ! Software version is the ROPP software version, in the format 'vnn.mmm'.
3062 ! At ROPP8.0, a new variable, 'processing_software', has been introduced,
3063 ! which can hold information about other software - in this case, the EUM
3064 ! processing code that generated the data in the first place.
3065
3066 data%software_version = ' ' ; readstr = ' ' ; readstr2 = ' '
3067
3068 CALL ncdf_getatt('/status/processing/processor_name' , readstr)
3069
3070 CALL ncdf_getatt('/status/processing/processor_version' ,readstr2)
3071
3072 data%processing_software = TRIM(readstr) // ' ' // TRIM(readstr2)
3073
3074 ! Processing time, split up string
3075 ! FIXME: Is there a library function for this that does some more format checks?
3076 CALL ncdf_getatt('/status/processing/creation_time', readstr)
3077
3078 SELECT CASE (LEN(TRIM(readstr)))
3079 CASE (14)
3080 READ(readstr, '(i4,i2,i2,i2,i2,i2)') &
3081 data%DTpro%Year, data%DTpro%Month, data%DTpro%Day, &
3082 data%DTpro%Hour, data%DTpro%Minute, data%DTpro%Second
3083 CASE (17)
3084 READ(readstr, '(i4,i2,i2,i2,i2,i2,i3)') &
3085 data%DTpro%Year, data%DTpro%Month, data%DTpro%Day, &
3086 data%DTpro%Hour, data%DTpro%Minute, data%DTpro%Second, data%DTpro%Msec
3087 CASE (19)
3088 READ(readstr, '(i4,1x,i2,1x,i2,1x,i2,1x,i2,1x,i2)') &
3089 data%DTpro%Year, data%DTpro%Month, data%DTpro%Day, &
3090 data%DTpro%Hour, data%DTpro%Minute, data%DTpro%Second
3091 CASE (23)
3092 READ(readstr, '(i4,1x,i2,1x,i2,1x,i2,1x,i2,1x,i2,1x,i3)') &
3093 data%DTpro%Year, data%DTpro%Month, data%DTpro%Day, &
3094 data%DTpro%Hour, data%DTpro%Minute, data%DTpro%Second, data%DTpro%Msec
3095 CASE DEFAULT
3096 CALL message( msg_warn, &
3097 'Invalid /status/processing/creation_time of ' // &
3098 TRIM(readstr) // ' ... defaulting DTpro%year etc.' )
3099 END SELECT
3100
3101
3102! 9.10 Occultation ID
3103! -------------------
3104
3105 CALL ropp_io_occid(DATA)
3106
3107
3108! 9.11 Clean up
3109! -------------
3110
3111! IF (ASSOCIATED(idx)) DEALLOCATE(idx)
3112
3113END SUBROUTINE ropp_io_read_eumdata
3114
3115
3116!-------------------------------------------------------------------------------
3117! 10. Accumulate phase
3118!-------------------------------------------------------------------------------
3119
3120SUBROUTINE Accumulate_Phase(Ph, Sign) ! (Array of (accumulated) phase, dir)
3121
3122! Method:
3123! Sign = 0 or no Sign:
3124! Adding +-2*Pi where phase jumps from
3125! +-Pi to -+Pi,
3126! Sign > 0:
3127! Adding +2*Pi where phase jumps from
3128! - to +
3129! Sign < 0
3130! Adding -2*Pi where phase jumps from
3131! + to -
3132
3133 ! 10.1 Declarations
3134
3135 USE typesizes, ONLY: wp => EightByteReal
3136
3137 IMPLICIT NONE
3138
3139 REAL(wp), DIMENSION(:), INTENT(inout) :: Ph ! Phase --> accumulated phase
3140 INTEGER, OPTIONAL, INTENT(in) :: Sign ! Phase change sign
3141! Pi already defined as parameter in coordinates module. Confuses pgf95.
3142 REAL(wp), PARAMETER :: pi1 = 3.141592653589793238_wp
3143 INTEGER :: i ! Array index
3144 INTEGER :: PSign ! Phase change sign
3145
3146 ! 10.2 Determine phase change sign
3147
3148 IF (.NOT. PRESENT(Sign)) THEN
3149 PSign = 0
3150 ELSE
3151 PSign = Sign
3152 ENDIF
3153
3154 ! 10.3 Accumulate phase
3155
3156 IF (PSign == 0) THEN
3157 DO i=2,SIZE(Ph)
3158 Ph(i) = Ph(i-1) + MODULO(Ph(i)-Ph(i-1)+pi1, 2.0_wp*pi1) - 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)
3163 ENDDO
3164 ELSEIF (PSign < 0) THEN
3165 DO i=2,SIZE(Ph)
3166 Ph(i) = Ph(i-1) + MODULO(Ph(i)-Ph(i-1)+2.0_wp*pi1, 2.0_wp*pi1) - 2.0_wp*pi1
3167 ENDDO
3168 ENDIF
3169
3170END SUBROUTINE Accumulate_Phase
3171
3172!-------------------------------------------------------------------------------
3173! 11. Handle time format of EUM files
3174!-------------------------------------------------------------------------------
3175
3176SUBROUTINE abstimetoDT(i, r, DTocc)
3177
3178! Based on 'Practical Ephemeris Calculations' by Oliver Montenbruck
3179! (Springer-Verlag, 1989). Added handling of hour, seconds as well.
3180!
3181 USE ropp_io_types, ONLY: DT7type
3182
3183 IMPLICIT NONE
3184
3185 INTEGER, INTENT(in) :: i ! number of days since 2000-01-01 00:00:00
3186 REAL(KIND(1.0D0)), INTENT(in) :: r ! seconds since start of day
3187 TYPE(DT7type), INTENT(inout) :: DTocc
3188 REAL(KIND(1.0D0)) :: h, mi, s, ms
3189 INTEGER :: a, b, c, d, e, f, y, m, dd, jd
3190
3191 ! calculate JD from input, 2451545 is JD of 2000-01-01
3192 jd = i + 2451545
3193 a = INT(jd+0.5D0)
3194
3195 IF (a < 2299161) THEN
3196 c = a + 1524
3197 ELSE
3198 b = INT( (a - 1867216.25D0) / 36524.25D0 )
3199 c = a + b - INT(b/4D0) + 1525
3200 ENDIF
3201
3202 d = INT( ( c-122.1D0 ) / 365.25D0 )
3203 e = INT( 365.25D0*d)
3204 f = INT( (c-e) / 30.6001D0 )
3205 dd = c - e - INT( 30.6001*f ) + MOD( ( jd+0.5D0 ), DBLE(a) )
3206 m = f - 1 - 12*INT( f/14D0 )
3207 y = d - 4715 - INT( ( 7+m )/10.D0 )
3208
3209
3210 DTocc%Year = y
3211 DTocc%Month = m
3212 DTocc%Day = dd
3213 h = FLOOR(r/3600.D0)
3214 DTocc%Hour = INT(h)
3215 mi = FLOOR( (r - h*3600.D0) / 60.D0 )
3216 s = FLOOR( (r - h*3600.D0 - mi*60.D0 ) )
3217 ms = (r - h*3600.D0 - mi*60.D0 - s) * 1000.D0
3218 DTocc%Hour = INT(h)
3219 DTocc%Minute = INT(mi)
3220 DTocc%Second = INT(s)
3221 DTocc%Msec = INT(ms)
3222
3223END SUBROUTINE abstimetoDT
3224
3225!-------------------------------------------------------------------------------
3226! 12. Find where reals are NaN (used by EUMETSAT to indicate missing data)
3227!-------------------------------------------------------------------------------
3228
3229FUNCTION ropp_io_isnan(x) RESULT(lnan) ! Says where reals are NaNs.
3230
3231 USE typesizes, ONLY: wp => EightByteReal
3232
3233 IMPLICIT NONE
3234
3235 REAL(wp), DIMENSION(:), INTENT(IN) :: x
3236 LOGICAL, DIMENSION(SIZE(x)) :: lnan
3237 INTEGER :: k
3238
3239 lnan(:) = .FALSE.
3240
3241! g95 doesn't like this.
3242! WHERE ( &
3243! (x /= x) .OR. &
3244! (x + 1.0_wp == x) .OR. &
3245! ((x > 0) .EQV. (x <= 0)) &
3246! ) lnan = .TRUE.
3247
3248 DO k=1,SIZE(x)
3249 IF ( &
3250 (x(k) /= x(k)) .OR. &
3251 (x(k) + 1.0_wp == x(k)) .OR. &
3252 ((x(k) > 0) .EQV. (x(k) <= 0)) &
3253 ) lnan(k) = .TRUE.
3254 END DO
3255
3256END FUNCTION ropp_io_isnan
3257
3258
3259END SUBROUTINE ropp_io_read_ncdf_get_eumdata