8 use netcdf,
only: nf90_float, nf90_int, nf90_char
19 character(len=nstring) :: msg_type
20 integer(i_kind) :: satid
21 integer(i_kind) :: instid
22 character(len=nstring) :: inst
23 character(len=ndatetime) :: datetime
24 integer(i_kind) :: nchan
29 integer(i_kind) :: inst_idx
30 integer(i_kind) :: landsea
31 integer(i_kind) :: scanpos
32 integer(i_kind) :: scanline
81 character (len=*),
intent(in) :: filename
82 character (len=10),
intent(out) :: filedate
85 integer(i_kind),
parameter :: ntime = 6
86 integer(i_kind),
parameter :: ninfo = 10
87 integer(i_kind),
parameter :: nlalo = 2
88 integer(i_kind),
parameter :: nbrit = 2
89 integer(i_kind),
parameter :: maxchan = 15
91 character(len=80) :: timestr, infostr, lalostr, britstr
93 real(
r_double),
dimension(ntime) :: timedat
94 real(
r_double),
dimension(ninfo) :: infodat
95 real(
r_double),
dimension(nlalo) :: lalodat
96 real(
r_double),
dimension(2,maxchan) :: data1b8
98 character(len=8) :: subset
99 character(len=10) :: cdate
101 integer(i_kind) :: iunit, iost, iret, i
102 integer(i_kind) :: nchan
103 integer(i_kind) :: idate
104 integer(i_kind) :: num_report_infile
105 integer(i_kind) :: ireadmg, ireadsb
107 integer(i_kind) :: iyear, imonth, iday, ihour, imin, isec
108 real(
r_double) :: ref_time, obs_time
110 write(*,*)
'--- reading '//trim(filename)//
' ---'
112 timestr =
'YEAR MNTH DAYS HOUR MINU SECO'
113 infostr =
'SAID SIID FOVN LSQL SAZA SOZA HOLS HMSL SOLAZI BEARAZ'
114 lalostr =
'CLAT CLON'
115 britstr =
'CHNM TMBR'
117 num_report_infile = 0
122 open (unit=iunit, file=trim(filename), &
123 iostat=iost, form=
'unformatted', status=
'old')
125 write(unit=*,fmt=
'(a,i5,a)') &
126 "Error",iost,
" opening BUFR obs file "//trim(filename)
130 call openbf(iunit,
'IN',iunit)
132 call readmg(iunit,subset,idate,iret)
134 if ( iret /= 0 )
then
135 write(unit=*,fmt=
'(A,I5,A)') &
136 "Error",iret,
" reading BUFR obs file "//trim(filename)
142 write(unit=*,fmt=
'(1x,a,i10)') trim(filename)//
' file date is: ', idate
143 write(unit=filedate, fmt=
'(i10)') idate
144 read (filedate(1:10),
'(i4,3i2)') iyear, imonth, iday, ihour
147 if ( .not.
associated(
rhead) )
then
150 nullify (
rhead%next )
153 if ( .not.
associated(
rlink) )
then
156 allocate (
rlink%next )
158 nullify (
rlink%next )
161 msg_loop:
do while (ireadmg(iunit,subset,idate)==0)
163 subset_loop:
do while (ireadsb(iunit)==0)
165 num_report_infile = num_report_infile + 1
167 call ufbint(iunit,timedat,ntime,1,iret,timestr)
169 iyear = nint(timedat(1))
170 imonth = nint(timedat(2))
171 iday = nint(timedat(3))
172 ihour = nint(timedat(4))
173 imin = nint(timedat(5))
174 isec = min(59, nint(timedat(6)))
177 if ( iyear > 1900 .and. iyear < 3000 .and. &
178 imonth >= 1 .and. imonth <= 12 .and. &
179 iday >= 1 .and. iday <= 31 .and. &
180 ihour >= 0 .and. ihour < 24 .and. &
181 imin >= 0 .and. imin < 60 .and. &
182 isec >= 0 .and. isec < 60 )
then
183 write(unit=
rlink%datetime, fmt=
'(i4,a,i2.2,a,i2.2,a,i2.2,a,i2.2,a,i2.2,a)') &
184 iyear,
'-', imonth,
'-', iday,
'T', ihour,
':', imin,
':', isec,
'Z'
186 rlink%dhr = (obs_time + (isec/60.0) - ref_time)/60.0
191 call ufbint(iunit,lalodat,nlalo,1,iret,lalostr)
192 if ( abs(lalodat(1)) > 90.0 .or. abs(lalodat(1)) > 360.0 ) cycle subset_loop
194 call ufbint(iunit,infodat,ninfo,1,iret,infostr)
195 call ufbrep(iunit,data1b8,2,maxchan,nchan,britstr)
197 rlink % nchan = nchan
198 if ( nchan > 0 )
then
199 allocate (
rlink % tb(nchan) )
200 allocate (
rlink % ch(nchan) )
205 if ( lalodat(1) <
r8bfms )
rlink % lat = lalodat(1)
206 if ( lalodat(2) <
r8bfms )
rlink % lon = lalodat(2)
208 rlink % satid = nint(infodat(1))
209 rlink % instid = nint(infodat(2))
211 if ( infodat(3) <
r8bfms )
rlink % scanpos = nint(infodat(3))
212 if ( infodat(4) <
r8bfms )
rlink % landsea = infodat(4)
213 if ( infodat(5) <
r8bfms )
rlink % satzen = infodat(5)
214 if ( infodat(10) <
r8bfms )
rlink % satazi = infodat(10)
215 if ( infodat(6) <
r8bfms )
rlink % solzen = infodat(6)
216 if ( infodat(9) <
r8bfms )
rlink % solazi = infodat(9)
217 if ( infodat(7) <
r8bfms )
rlink % elv = infodat(7)
219 if ( nchan > 0 )
then
221 if ( data1b8(1,i) <
r8bfms )
rlink % ch(i) = nint(data1b8(1,i))
222 if ( data1b8(2,i) <
r8bfms )
rlink % tb(i) = data1b8(2,i)
226 allocate (
rlink%next )
228 nullify (
rlink%next )
236 write(*,
'(1x,a,a,a,i10)')
'num_report_infile ', trim(filename),
' : ', num_report_infile
269 character (len=*),
intent(in) :: filename
270 character (len=10),
intent(out) :: filedate
272 integer(i_kind),
parameter :: n_maxchan = 281
275 integer(i_kind),
parameter :: n_satellitespot_list = 25
276 type satellitespot_list
286 end type satellitespot_list
287 real(
r_double),
dimension(1:N_satellitespot_LIST) :: satellitespot_list_array
290 integer(i_kind),
parameter :: n_sensorspot_list = 12
305 end type sensorspot_list
306 real(
r_double),
dimension(1:N_sensorspot_LIST) :: sensorspot_list_array
309 integer(i_kind),
parameter :: n_sensorchan_list = 4
316 end type sensorchan_list
317 real(
r_double),
dimension(1:N_sensorchan_LIST,1:N_MAXCHAN) :: sensorchan_list_array
320 type(satellitespot_list) :: satellitespot
321 type(sensorspot_list) :: sensorspot
322 type(sensorchan_list) :: sensorchan(n_maxchan)
324 character(len=8) :: subset
325 character(len=8) :: spotname
326 character(len=8) :: channame
327 integer(i_kind) :: ireadmg, ireadsb
328 integer(i_kind) :: nchan
329 integer(i_kind) :: iret
332 integer(i_kind) :: idate
333 integer(i_kind) :: iyear, imonth, iday, ihour, imin, isec
334 real(
r_double) :: ref_time, obs_time
337 integer(i_kind) :: i, ich
338 integer(i_kind) :: iost, iunit
339 integer(i_kind) :: num_report_infile
340 logical :: decode_airs, decode_amsua
343 write(*,*)
'--- reading '//trim(filename)//
' ---'
345 decode_amsua = .false.
346 decode_airs = .false.
350 num_report_infile = 0
355 open (unit=iunit, file=trim(filename), &
356 iostat=iost, form=
'unformatted', status=
'old')
358 write(unit=*,fmt=
'(a,i5,a)') &
359 "Error",iost,
" opening BUFR obs file "//trim(filename)
363 call openbf(iunit,
'IN',iunit)
365 call readmg(iunit,subset,idate,iret)
367 if ( iret /= 0 )
then
368 write(unit=*,fmt=
'(A,I5,A)') &
369 "Error",iret,
" reading BUFR obs file "//trim(filename)
375 write(unit=*,fmt=
'(1x,a,i10)') trim(filename)//
' file date is: ', idate
376 write(unit=filedate, fmt=
'(i10)') idate
377 read (filedate(1:10),
'(i4,3i2)') iyear, imonth, iday, ihour
380 if ( .not.
associated(
rhead) )
then
383 nullify (
rhead%next )
386 if (.not.
associated(
rlink))
then
389 allocate (
rlink%next )
391 nullify (
rlink%next )
394 msg_loop:
do while ( ireadmg(iunit,subset,idate)==0 )
396 subset_loop:
do while ( ireadsb(iunit)==0 )
398 num_report_infile = num_report_infile + 1
401 call ufbseq(iunit,satellitespot_list_array,n_satellitespot_list,1,iret,
'SPITSEQN')
402 satellitespot = satellitespot_list( &
403 satellitespot_list_array(1), &
404 satellitespot_list_array(2), &
405 satellitespot_list_array(3), &
406 satellitespot_list_array(4), &
407 satellitespot_list_array(5), &
408 satellitespot_list_array(6), &
409 satellitespot_list_array(7), &
410 reshape(satellitespot_list_array(8:25), (/2,9/)) )
412 loop_sensor:
do i = 1, 2
414 if ( decode_airs )
then
415 spotname =
'SITPSEQN'
416 channame =
'SCBTSEQN'
420 else if ( i == 2 )
then
421 if ( decode_amsua )
then
422 spotname =
'AMSUSPOT'
423 channame =
'AMSUCHAN'
430 call ufbseq(iunit,sensorspot_list_array,n_sensorspot_list,1,iret,spotname)
432 sensorspot = sensorspot_list( sensorspot_list_array(1), &
433 sensorspot_list_array(2), &
434 sensorspot_list_array(3), &
435 sensorspot_list_array(4), &
436 sensorspot_list_array(5), &
437 sensorspot_list_array(6), &
438 sensorspot_list_array(7), &
439 sensorspot_list_array(8), &
440 sensorspot_list_array(9), &
441 sensorspot_list_array(10), &
442 sensorspot_list_array(11), &
443 sensorspot_list_array(12) )
445 iyear = nint(sensorspot%year)
446 imonth = nint(sensorspot%mnth)
447 iday = nint(sensorspot%days)
448 ihour = nint(sensorspot%hour)
449 imin = nint(sensorspot%minu)
450 isec = nint(sensorspot%seco)
451 if ( iyear > 1900 .and. iyear < 3000 .and. &
452 imonth >= 1 .and. imonth <= 12 .and. &
453 iday >= 1 .and. iday <= 31 .and. &
454 ihour >= 0 .and. ihour < 24 .and. &
455 imin >= 0 .and. imin < 60 .and. &
456 isec >= 0 .and. isec < 60 )
then
457 write(unit=
rlink%datetime, fmt=
'(i4,a,i2.2,a,i2.2,a,i2.2,a,i2.2,a,i2.2,a)') &
458 iyear,
'-', imonth,
'-', iday,
'T', ihour,
':', imin,
':', isec,
'Z'
460 rlink%dhr = (obs_time + (isec/60.0) - ref_time)/60.0
465 if ( abs(sensorspot%clath) > 90.0 .or. abs(sensorspot%clonh) > 360.0 ) cycle subset_loop
468 call ufbseq(iunit,sensorchan_list_array,n_sensorchan_list,n_maxchan,nchan,channame)
470 rlink % nchan = nchan
471 if ( nchan > 0 )
then
472 allocate (
rlink % tb(1:nchan) )
473 allocate (
rlink % ch(1:nchan) )
479 sensorchan(ich) = sensorchan_list( sensorchan_list_array(1,ich), &
480 sensorchan_list_array(2,ich), &
481 sensorchan_list_array(3,ich), &
482 sensorchan_list_array(4,ich) )
483 if ( sensorchan(ich) % tmbr <
r8bfms )
rlink % tb(ich) = sensorchan(ich) % tmbr
484 if ( sensorchan(ich) % chnm <
r8bfms )
rlink % ch(ich) = sensorchan(ich) % chnm
487 if ( sensorspot%clath <
r8bfms )
rlink % lat = sensorspot%clath
488 if ( sensorspot%clonh <
r8bfms )
rlink % lon = sensorspot%clonh
490 if ( sensorspot%fovn <
r8bfms )
rlink % scanpos = nint( sensorspot%fovn )
491 if ( sensorspot%saza <
r8bfms )
rlink % satzen = sensorspot%saza
492 if ( satellitespot%slnm <
r8bfms )
rlink % scanline = nint(satellitespot%slnm)
493 if ( sensorspot%bearaz <
r8bfms )
rlink % satazi = sensorspot%bearaz
494 if ( satellitespot%soza <
r8bfms )
rlink % solzen = satellitespot%soza
495 if ( satellitespot%solazi <
r8bfms )
rlink % solazi = satellitespot%solazi
497 rlink % satid = nint(satellitespot % said)
498 rlink % instid = nint(sensorspot % siid)
500 allocate (
rlink%next )
502 nullify (
rlink%next )
511 write(*,
'(1x,a,a,a,i10)')
'num_report_infile ', trim(filename),
' : ', num_report_infile
521 integer(i_kind) :: i, iv, k
522 integer(i_kind) :: ityp, irec
523 integer(i_kind),
dimension(ninst) :: nrecs
524 integer(i_kind),
dimension(ninst) :: nlocs
525 integer(i_kind),
dimension(ninst) :: nvars
526 integer(i_kind),
dimension(ninst) :: iloc
527 character(len=nstring) :: satellite
528 character(len=nstring) :: sensor
534 write(*,*)
'--- sorting radiance obs...'
539 set_inst_loop:
do while (
associated(
rlink) )
541 if (
rlink%nchan < 1 )
then
548 rlink % inst = trim(sensor)//
'_'//trim(satellite)
553 if (
rlink % inst_idx > 0 )
then
555 nrecs(
rlink%inst_idx) = nrecs(
rlink%inst_idx) + 1
556 nlocs(
rlink%inst_idx) = nlocs(
rlink%inst_idx) + 1
564 write(*,
'(1x,20x,a10)')
'nlocs'
567 write(*,
'(1x,a20,i10)')
inst_list(i), nlocs(i)
573 xdata(i) % nrecs = nrecs(i)
574 xdata(i) % nlocs = nlocs(i)
575 xdata(i) % nvars = nvars(i)
577 if ( nlocs(i) > 0 )
then
585 xdata(i)%xinfo_char (:,:) =
''
588 if ( nvars(i) > 0 )
then
589 allocate (
xdata(i)%xfield(nlocs(i), nvars(i)))
593 allocate (
xdata(i)%var_idx(nvars(i)))
595 xdata(i)%var_idx(iv) = iv
607 reports:
do while (
associated(
rlink) )
609 ityp =
rlink%inst_idx
614 if (
rlink%nchan < 1 )
then
619 iloc(ityp) = iloc(ityp) + 1
624 xdata(ityp)%xinfo_int(iloc(ityp),i) = irec
628 xdata(ityp)%xinfo_float(iloc(ityp),i) =
rlink%dhr
629 else if ( trim(
name_var_info(i)) ==
'station_elevation' )
then
630 xdata(ityp)%xinfo_float(iloc(ityp),i) =
rlink%elv
632 xdata(ityp)%xinfo_float(iloc(ityp),i) =
rlink%lat
634 xdata(ityp)%xinfo_float(iloc(ityp),i) =
rlink%lon
638 xdata(ityp)%xinfo_char(iloc(ityp),i) =
rlink%datetime
640 xdata(ityp)%xinfo_char(iloc(ityp),i) =
rlink%inst
648 xdata(ityp)%xseninfo_float(iloc(ityp),i) =
rlink%scanpos
649 else if ( trim(
name_sen_info(i)) ==
'sensor_zenith_angle' )
then
650 xdata(ityp)%xseninfo_float(iloc(ityp),i) =
rlink%satzen
651 else if ( trim(
name_sen_info(i)) ==
'sensor_azimuth_angle' )
then
652 xdata(ityp)%xseninfo_float(iloc(ityp),i) =
rlink%satazi
653 else if ( trim(
name_sen_info(i)) ==
'solar_azimuth_angle' )
then
654 xdata(ityp)%xseninfo_float(iloc(ityp),i) =
rlink%solzen
655 else if ( trim(
name_sen_info(i)) ==
'sensor_azimuth_angle' )
then
656 xdata(ityp)%xseninfo_float(iloc(ityp),i) =
rlink%solazi
657 else if ( trim(
name_sen_info(i)) ==
'sensor_view_angle' )
then
668 do i = 1, nvars(ityp)
669 xdata(ityp)%xfield(iloc(ityp),i)%val =
rlink%tb(i)
672 xdata(ityp)%xfield(iloc(ityp),i)%qm = 0
680 do while (
associated(
rlink) )
682 if (
allocated (
rlink%tb) )
deallocate (
rlink%tb)
683 if (
allocated (
rlink%ch) )
deallocate (
rlink%ch)
697 type (datalink_radiance),
intent(inout) :: datalink
698 real(r_kind),
intent(in) :: rfill
699 integer(i_kind),
intent(in) :: ifill
704 datalink % lat = rfill
705 datalink % lon = rfill
706 datalink % satid = ifill
707 datalink % instid = ifill
708 datalink % scanpos = rfill
709 datalink % landsea = rfill
710 datalink % satzen = rfill
711 datalink % satazi = rfill
712 datalink % solzen = rfill
713 datalink % solazi = rfill
714 datalink % elv = rfill
715 if (
allocated (datalink % tb) )
then
716 datalink % tb(:) = rfill
718 if (
allocated (datalink % ch) )
then
719 datalink % ch(:) = ifill
730 character(len=*),
intent(in) :: name_inst
731 integer(i_kind),
intent(in) :: ifov
732 real(r_kind),
intent(out) :: view_angle
734 integer(i_kind) :: idx
735 real(r_kind) :: start, step
739 idx = index(name_inst,
'_')
740 select case ( name_inst(1:idx-1) )
742 start = -48.0_r_kind - 1.0_r_kind/3.0_r_kind
743 step = 3.0_r_kind + 1.0_r_kind/3.0_r_kind
745 start = -48.95_r_kind
748 start = -445.0_r_kind/9.0_r_kind
749 step = 10.0_r_kind/9.0_r_kind
751 start = -52.725_r_kind
757 view_angle = start + float(ifov-1) * step
767 integer(i_kind),
intent(in) :: year
768 integer(i_kind),
intent(in) :: month
769 integer(i_kind),
intent(in) :: day
770 integer(i_kind),
intent(in) :: hour
771 integer(i_kind),
intent(in) :: minute
772 real(r_double),
intent(out) :: gstime
774 integer(i_kind) :: iw3jdn, ndays, nmind
776 iw3jdn = day - 32075 &
777 + 1461 * (year + 4800 + (month - 14) / 12) / 4 &
778 + 367 * (month - 2 - (month - 14) / 12 * 12) / 12 &
779 - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
780 ndays = iw3jdn - 2443510
782 nmind = ndays*1440 + hour * 60 + minute
783 gstime = float(nmind)
integer(i_kind), parameter nstring
character(len=nstring), dimension(nvar_info) name_var_info
integer(i_kind), dimension(nsen_info) type_sen_info
subroutine set_name_sensor(instid, sensor)
integer(i_kind), parameter ninst
integer(i_kind), parameter nsen_info
integer(i_kind), parameter missing_i
integer(i_kind), parameter ndatetime
character(len=nstring), dimension(nsen_info) name_sen_info
integer(i_kind), parameter nvar_info
real(r_kind), parameter missing_r
character(len=nstring), dimension(ninst) inst_list
type(xdata_type), dimension(:), allocatable xdata
subroutine set_name_satellite(satid, satellite)
subroutine set_brit_obserr(name_inst, ichan, obserr)
integer(i_kind), dimension(nvar_info) type_var_info
integer, parameter, public i_kind
integer, parameter, public r_kind
integer, parameter, public r_double
subroutine fill_datalink(datalink, rfill, ifill)
type(datalink_radiance), pointer rhead
subroutine, public sort_obs_radiance
subroutine, public read_amsua_amsub_mhs(filename, filedate)
subroutine, public read_airs_colocate_amsua(filename, filedate)
subroutine calc_sensor_view_angle(name_inst, ifov, view_angle)
real(r_kind), parameter r8bfms
type(datalink_radiance), pointer rlink
subroutine get_julian_time(year, month, day, hour, minute, gstime)
integer function, public ufo_vars_getindex(vars, varname)