[Dart-dev] [3853] DART/trunk/ncep_obs/real_obs_mod.f90: Most important - add/ subtract a tiny epsilon value to lats directly at

nancy at ucar.edu nancy at ucar.edu
Wed May 6 14:58:34 MDT 2009


An HTML attachment was scrubbed...
URL: http://mailman.ucar.edu/pipermail/dart-dev/attachments/20090506/9d469f89/attachment.html 
-------------- next part --------------
Modified: DART/trunk/ncep_obs/real_obs_mod.f90
===================================================================
--- DART/trunk/ncep_obs/real_obs_mod.f90	2009-05-06 20:57:02 UTC (rev 3852)
+++ DART/trunk/ncep_obs/real_obs_mod.f90	2009-05-06 20:58:33 UTC (rev 3853)
@@ -75,6 +75,7 @@
    revision = "$Revision$", &
    revdate  = "$Date$"
 
+
 logical, save :: module_initialized = .false.
 ! set this to true if you want to print out the current time
 ! after each N observations are processed, for benchmarking.
@@ -106,9 +107,26 @@
 integer :: days, seconds
 integer :: day0, sec0
 integer :: hour, imin, sec
-integer :: obs_num, calender_type, iskip
+integer :: obs_num, calender_type
 type(time_type) :: current_day, next_day
 
+integer, parameter :: num_fail_kinds = 6
+integer :: iskip(num_fail_kinds)
+integer, parameter :: fail_3Z        = 1
+integer, parameter :: fail_timerange = 2
+integer, parameter :: fail_badloc    = 3
+integer, parameter :: fail_areabox   = 4
+integer, parameter :: fail_badkind   = 5
+integer, parameter :: fail_notwanted = 6
+character(len=32) :: skip_reasons(num_fail_kinds) = (/ &
+                     'time too early (exactly 03Z)    ', &
+                     'time outside bin range          ', &
+                     'bad observation location        ', &
+                     'observation outside lat/lon box ', &
+                     'unrecognized observation kind   ', &
+                     'obs type not on select list     ' /)
+
+
 integer :: obs_unit
 integer :: obs_prof, obs_kind, obs_kind_gen, which_vert, iqc, obstype, pc
 real (r8) :: obs_err, lon, lat, lev, zob, time, pre_time, rcount, zob2
@@ -174,7 +192,7 @@
 !print*, 'ncep obsdates = ', obsdate
 
 obs_num = 0
-iskip   = 0
+iskip(:) = 0
 
 !  loop over all observations within the file
 !------------------------------------------------------------------------------
@@ -191,13 +209,13 @@
 !   (obs at 03Z the next day have a time of 27.)
 !------------------------------------------------------------------------------
    if(time == 3.0_r8) then
-      iskip = iskip + 1
+      iskip(fail_3Z) = iskip(fail_3Z) + 1
       cycle obsloop 
    endif 
 
    !  select the obs for the time window
    if(time < bin_beg .or. time > bin_end) then
-      iskip = iskip + 1
+      iskip(fail_timerange) = iskip(fail_timerange) + 1
       cycle obsloop
    endif
 
@@ -205,17 +223,34 @@
    if((lon > 360.0_r8) .or. (lon <   0.0_r8) .or.  &
       (lat >  90.0_r8) .or. (lat < -90.0_r8)) then
       write(*,*) 'invalid location.  lon,lat = ', lon, lat
-      iskip = iskip + 1
+      iskip(fail_badloc) = iskip(fail_badloc) + 1
       cycle obsloop
    endif
 
    ! reject observations outside the bounding box
    if(lat < lat1 .or. lat > lat2 .or. & 
      .not. is_longitude_between(lon, lon1, lon2)) then
-     iskip = iskip + 1
+     iskip(fail_areabox) = iskip(fail_areabox) + 1
      cycle obsloop
    endif
 
+   ! it seems when a machine writes out a number and then reads it back in
+   ! you should at least get consistent round-off errors.  perhaps it is more
+   ! complex than it seems, but on the ibm xlf compiler, values of exactly
+   ! 90.0 and -90.0 are written out as (binary) doubles and when they are
+   ! read back in and compared to 90 and -90, they are not equal anymore.
+   ! the difference is in a very small but apparently significant digit,
+   ! so we error out in our 3d sphere locations module.  this hack is a try
+   ! at adjusting the numbers by a small enough value that the location is
+   ! still the pole but isn't going to round out of range.
+   if      (lat >=  89.9999_r8) then
+     lat = lat - 1.0e-12_r8
+     !print *, 'lat adjusted down, now ', lat
+   else if (lat <= -89.9999_r8) then
+     lat = lat + 1.0e-12_r8
+     !print *, 'lat adjusted   up, now ', lat
+   endif
+
    obs_prof = rcount/1000000
 
 
@@ -280,13 +315,13 @@
    endif
 
    if (obs_kind < 0) then
-      ! the "real" fix here if the record type is not found might actually be to
-      ! accept all record types here within valid ranges, and depend on the first
+      ! the "real" fix if the record type is not found might actually be to
+      ! accept all record types within valid ranges, and depend on the first
       ! preprocessing steps (in the prepbufr converter) to remove obs record
       ! types which are not desired.  for now, avoid giving them the wrong type
       ! and quietly loop.
       !print *, 'unrecognized obs_prof or obstype, skipping', obs_prof, obstype
-      iskip = iskip + 1
+      iskip(fail_badkind) = iskip(fail_badkind) + 1
       cycle obsloop 
    endif
 
@@ -323,7 +358,7 @@
      
       ! if pass is still true, we want to ignore this obs.
       if(pass) then
-         iskip = iskip + 1
+         iskip(fail_notwanted) = iskip(fail_notwanted) + 1
          cycle obsloop 
       endif
 
@@ -421,8 +456,11 @@
 
 close(obs_unit)
 
-print*, 'date ', obsdate, ' obs used = ', obs_num, ' obs skipped = ', iskip
-!print*, 'obs_num= ',obs_num,' skipped= ',obsdate,iskip
+print*, 'date ', obsdate
+print*, 'num obs used = ', obs_num, ' total obs skipped = ', sum(iskip)
+do i=1, num_fail_kinds
+  if (iskip(i) >  0) print *, iskip(i), 'skipped because ', skip_reasons(i)
+enddo
 
 end function real_obs_sequence
 


More information about the Dart-dev mailing list