FG departures for 2D-OI (2m temperature, relative humidity and snow depth analysis) are calculated in fg2obs.F90. At first, observations are sorted by OBS_RAWTABLE(jpraw_refcoord, jtotal) based on latitude and longitude (prepared in scan_cma_odb.F90).
izlat = int( zlat * 100.0_JPRB) izlon = int( zlon * 100.0_JPRB) i_refcoord = sign(1,izlat) * (abs(izlat) * 100000 + izlon) OBS_RAWTABLE(jpraw_refcoord, jtotal) =& &sign(1,i_refcoord) * (abs(i_refcoord) +& &1 * 0.01_JPRB)
!** Used to compute averages (always in the same order) call KEYSORT(irc, POBS, KLEN,key=jpraw_refcoord,transposed=.TRUE.)
The observations should be sorted in ascending order by latitude because FG departures are calculated in turn from the south pole to the north pole by the following code.
!** (Lat, Lon) of observations jlatN = NDGL + 1 LoopAllObs: do j=1,KLEN iflag = 0 ZOBSLAT = POBS(kplat,j) ZOBSLON = mod(POBS(kplon,j) + 360.0_JPRB, 360.0_JPRB) !** Calculate latitudinal NW-pivot values for each observation (i.e. point#1) WHILE_LOOP: do while (jlatN > 0.and. ZOBSLAT > ALAT(jlatN)) jlatN = jlatN - 1 enddo WHILE_LOOP
However, latitude is rounded down to the second decimal place when OBS_RAWTABLE(jpraw_refcoord, jtotal) is calculated. As a result, the indices are sometimes not in ascending order precisely and the FG departures are not calculated from surrounded 4 model grids. The following table shows an example. ZOBSLAT should be at the latitude between ALAT(jlatN) and ALAT(jlatS) but it is not there (at the south side of ALAT(jlatS)).
StationID | ZOBSLAT | ZOBSLON | Altitude | ALAT(jlatN) | ALAT(jlatS) |
30337 | 56.32 | 107.62 | 330 | 56.55214 | 56.32728 |
I found there are about 200 of snow depth observations and 400 of 2m temperature observations affected by this bug (at 0 UTC on 3 Dec 2020). You can see the list of affected observations in affected_points.xlsx (note that this list comes from a 49r1 experiment including snow DA changes). In order to modify the bug, it seems to be better to sort observations in ascending order by latitude without rounding down.
!** Used to compute averages (always in the same order) !call KEYSORT(irc, POBS, KLEN,key=jpraw_refcoord,transposed=.TRUE.) call KEYSORT(irc, POBS, KLEN,key=kplat,transposed=.TRUE.)