Opened 4 years ago

Closed 3 years ago

#680 closed task (fixed)

Fix non-reproducible problem with -g or -gi options in ropp2bufr and eum2bufr

Reported by: Ian Culverwell Owned by: Ian Culverwell
Priority: normal Milestone: 11.0
Component: ROPP(all) Version: 9.0
Keywords: Cc: olewis

Description

The user can request GTS routing headers/trailers to be added to the BUFR file output from ropp2bufr and eum2bufr by using the -g or -gi options. (-gi adds a 10-byte leading size/type for GTS IP (FTP) transmission to the headers produced by -g.)

But this doesn't always work. This is because subroutine GetOptions in ropp2bufr_mod.f90 sets RejTimeDiff = DefRejTimeDiff = 1430 if -g or -gi are invoked:

  IF ( GTShdrType /= NOhdrs .AND. &
       RejTimeDiff == 0 ) RejTimeDiff = DefRejTimeDiff

This can then cause the code to fall over in ropp2bufr_ec/mo.f90 because

  IF ( RejTimeDiff > 0 ) THEN
    Offset = (/0,0,0,0,0,RejTimeDiff,0,0/)
    CALL DateTimeOffset ( DT8, "-", Offset )
    CALL TimeSince      ( DT8, MinRej, 1, Base="JM2000" )
    CALL MonthOfYear    ( DT8(IdxMonth), MonthName, 1 )
    WRITE ( outmsg, FMT=DTfmt1 ) DT8(IdxHour),   &
                                 DT8(IdxMinute), &
                                 DT8(IdxDay),    &
                                 MonthName(1:3), &
                                 DT8(IdxYear)
    CALL message ( msg_diag, " Rejecting occultations older than "// &
                             TRIM(outmsg) )
  ELSE
    MinRej = 0.0_dp
  END IF

...

      IF ( MinRej > 0.5_dp ) THEN
        DT8 = (/ROdata%DTocc%Year,   ROdata%DTocc%Month,  &
                ROdata%DTocc%Day,    0,                   &
                ROdata%DTocc%Hour,   ROdata%DTocc%Minute, &
                ROdata%DTocc%Second, 0/)
        CALL TimeSince ( DT8, MinObs, 1, Base="JM2000" )
        IF ( MinObs < MinRej ) THEN
          CALL message ( msg_warn, "Occultation is too old for GTS "// &
                                   "- not encoded." )
          CYCLE
        END IF
      END IF

The point is that DT8 is not initialised before it is called by

    CALL DateTimeOffset ( DT8, "-", Offset )

We can therefore end up with MinRej failing the IF ( MinRej > 0.5_dp ) THEN test, so that the code fails with, for example:

 3: DT8 =  80147 7 19 0 23 49 0 1
 3: MinRej =  4.1101640629000015E+10
... (from ropp2bufr):   Rejecting occultations older than 23:49UT 19-Jul-****
INFO (from ropp2bufr):  Reading  ROPP data from ../data/ropp_test.nc
INFO (from ropp2bufr):  Encoding profile    1 : OC_20090817215807_META_G027_DMI_
 7.1: MinRej =  4.1101640629000015E+10
 7.1: MinObs =  5064358.1166666
 
WARNING (from ropp2bufr):  Occultation is too old for GTS - not encoded.
 
WARNING (from ropp2bufr):  No profiles were encoded or written to the BUFR file

*** Failed to generate a BUFR file from netCDF

Sometimes, however, it works, e.g.:

  3: DT8 =  -29499 -4 -29 0 -22 -57 -59 -999
 3: MinRej =  -1.6567136577999983E+10
... (from ropp2bufr):   Rejecting occultations older than **:**UT **-Apr-****
INFO (from ropp2bufr):  Reading  ROPP data from ../data/ropp_test.nc
INFO (from ropp2bufr):  Encoding profile    1 : OC_20090817215807_META_G027_DMI_
 7.1: MinRej =  -1.6567136577999983E+10
...
... (from EncodeBUFR):     Length of BUFR message :  14741 octets
DEBUG: [GTShdrARH] Lat=51 Lon=-4 A2=A
... (from EncodeBUFR):     Length of GTS bulletin :  14776 octets
... (from EncodeBUFR):   GTS bulletin header (IPH+ARH): 0001477600....001...IUTA14 EKMI 172158...
... (from EncodeBUFR):   No. of bytes written to file : 14786
... (from ropp2bufr):  Writing      8 bytes (for EOF) to bufr_test.bfr
INFO (from ropp2bufr):  Total of  14794 bytes written to bufr_test.bfr
INFO (from ropp2bufr):  Generated 1 GTS bulletin to bufr_test.bfr

It all depends how DT8 is initialised.

A quick fix would be to switch off the setting of RejTimeDiff > 0 if GTShdrType /= NOhdrs. A better fix would be to find out what DT8 is supposed to be, and to set it accordingly.

Change history (11)

comment:1 by Ian Culverwell, 4 years ago

This isn't a problem for ropp2bufr_eccodes or eum2bufr_eccodes, because they always (or nearly always) initialise DT8 to

 3: DT8 =  0 0 0 0 -11 -49 -59 -1000
 3: MinRej =  -1.0519451899999999E+9

which avoids the problem.

But ropp2bufr (built with ECBUFR lib) produces, in five successive runs,

 3: DT8 =  -29499 -4 -29 0 -22 -57 -59 -999
 3: MinRej =  -1.6567136577999983E+10

 3: DT8 =  49380 3 10 0 9 33 0 1
 3: MinRej =  2.4919573533000015E+10

 3: DT8 =  -54103 -1 24 0 -17 -8 -59 -999
 3: MinRej =  -2.9507382308999985E+10

 3: DT8 =  -25332 1 30 0 -22 -45 -59 -999
 3: MinRej =  -1.4375201685999983E+10

 3: DT8 =  87143 12 22 0 23 28 0 1
 3: MinRej =  4.4781405088000015E+10

1, 3 and 4 are OK; 2 and 5 fail the test on MinRej.

I don't understand the reason for this difference in behaviour.

comment:2 by Kent Bækgaard Lauritsen, 4 years ago

Owner: changed from Kent Bækgaard Lauritsen to Stig Syndergaard
Status: newassigned

comment:3 by Ian Culverwell, 4 years ago

Owner: changed from Stig Syndergaard to Ian Culverwell

comment:4 by olewis, 3 years ago

I can confirm that this problem is to do with the DT8 value not being assigned. This then means that when DT8 is first used the array is assigned with random values. These random values are then converted into a date time which is completely random. The differences between compilers is probably due to the way the compilers handle this unassigned array.

Looking at the GBGP code which also has a similar routine for COST2BUFR conversions the DT8 is assigned using the Date_and_Time_UTC routine. This assigns the current date and time. In the current ROPP2BUFr routines the default RejTime is set to 1430 minutes which is 23 hours and 50 minutes. I think the idea of this is to not create GTS heading for data which is older then a day as it is not therefore wanted on the GTS.

comment:5 by olewis, 3 years ago

The array DT8 needs to be assigned and assigned to the current date and time. This is done using CALL Date_and_Time_UTC ( Values=DT8 ). This enables the code to function as intended for a near real time purpose. To enable the bufr code to work for files older then 23 hours and 50 minutes there is a an option when running ropp2bufr -t. This option is a time in minutes to offset the current time by for the bufr creation to not be rejected for being too old.

By making the change to assign DT* the current tests for ropp2bufr will need to be modified to have the -t option set to a large value to avoid he bufr creation being rejected.

comment:6 by olewis, 3 years ago

Setting the -t value to be -t 10000000 sets the rejection time of occultations to be older than 22:12UT 18-Jul-2002.

Running ropp2bufr -gi ropp_io/data/ropp_test.nc -o ropp_g95_test.bfr

---------------------------------------------------------------------
                  ROPP to BUFR (MetDB) Encoder
---------------------------------------------------------------------

  Rejecting occultations older than 09:04UT 22-Jul-2021
INFO (from ropp2bufr):  Reading  ROPP data from ropp_io/data/ropp_test.nc
INFO (from ropp2bufr):  Encoding profile    1 : OC_20090817215807_META_G027_DMI_
   Date of the RO Observations  : 21:58UT 17-Aug-2009                                                             
 
WARNING (from ropp2bufr):  Occultation is too old for GTS - not encoded.
 
WARNING (from ropp2bufr):  No profiles were encoded or written to the BUFR file 

With -t set to 10000000 gives

---------------------------------------------------------------------
                  ROPP to BUFR (MetDB) Encoder
---------------------------------------------------------------------

  Rejecting occultations older than 22:16UT 18-Jul-2002
INFO (from ropp2bufr):  Reading  ROPP data from ropp_io/data/ropp_test.nc
INFO (from ropp2bufr):  Encoding profile    1 : OC_20090817215807_META_G027_DMI_
   Date of the RO Observations  : 21:58UT 17-Aug-2009                                                             
INFO (from ropp2bufr):  Total of  14795 bytes written to ropp_g95_test.bfr
INFO (from ropp2bufr):  Generated 1 GTS bulletin to ropp_g95_test.bfr

comment:7 by olewis, 3 years ago

This change also requires a change to the ropp2bufr_mod.f90 file in the ropp_io/bufr directory. This change is to the RejTime value input. Currently it has hh:mm as hours and minutes but this is currently limited to only two characters to a maximum of 99 hours. To make this simpler we can change it to only be in minutes with a larger character intake and so the reject time can be set to a more distance date.

I will need to update the documentation for the routine to highlight that it will no longer be hh:mm but minutes for the ropp2bufr code.

comment:8 by Ian Culverwell, 3 years ago

Cc: olewis added

eum2bufr and ropp2bufr tools updated at r6863.

comment:9 by Ian Culverwell, 3 years ago

Checking it out.

Control

gfortran always seem to nullify DT8 by default. Running

../tools/ropp2bufr -gi ../data/ropp_test.nc  -o bufr_test.bfr

gives

 RejTimeDiff =         1430
 DT8 =            0           0           0           0           0           0           0           0
 MinRej =   -1051945189.9999999     

which bypasses the test on MinRej and therefore generates a BUFR file. So the irreproducible errors seen before appear depend on the compiler (or compiler options). But if I hardwire DT8 to one of the earlier, randomly generated, problematic dates, I get

 RejTimeDiff =         1430
 DT8 =        49380           3          10           0           9          33           0           1
 MinRej =    24919572103.000031     

and therefore

WARNING (from ropp2bufr):  Occultation is too old for GTS - not encoded.

as expected.

But

../tools/ropp2bufr -gi ../data/ropp_test.nc  -t -1:00 -o bufr_test.bfr

gives

 RejTimeDiff =          -60
 DT8 =        49380           3          10           0           9          33           0           1
 MinRej =    0.0000000000000000     

and therefore an output file is produced.

Test

../tools/ropp2bufr -gi ../data/ropp_test.nc  -o bufr_test.bfr

gives

 RejTimeDiff =         1430
 DT8 =         2021           8           4           0          10          55          11         163
 MinRej =    11355065.186049342     

WARNING (from ropp2bufr):  Occultation is too old for GTS - not encoded.
 
WARNING (from ropp2bufr):  No profiles were encoded or written to the BUFR file

But

../tools/ropp2bufr -gi ../data/ropp_test.nc  -t -1:00 -o bufr_test.bfr

gives

 RejTimeDiff =          -60
 DT8 =         2021           8           4           0          10          56           9         964
 MinRej =    0.0000000000000000     

and produces an output file, as in the control.

So on the face of it we should just recommend the use of -t -1:00 in the existing code. However:

  • Users might want to prevent profiles older than 23h 50m old being disseminated over the GTS (this is what GBGP does for ground-based obs), and in fact this is the original intention behind the code. Witness the ropp2bufr man page (ropp2bufr.1), which says
    -g also sets the default for the -t option to 23:50 on the 
    assumption that the resulting bulletins are destined for NRT 
    dissemination via GTS/RMDCN.
    
  • The original code is unreliable (the fail/pass behaviour seems to depend on the compiler), and depends on the value of an unitialised variable, DT8, which is never a good idea;
  • Setting -t -1:00 gets around age-rejection in the new and old code. Again, this is current advice (ropp2bufr man page again):
    Hint: should GTS routing headers be required but with no cut-off 
    applied, use, for instance:
                   > ropp2bufr -gi -t -1:00
    
  • So if ropp2bufr -gi currently works (sometimes...) for old profiles without the -t -1:00 option, then that looks like a mistake, which this change addresses. Needs to be spelled out in the Change Log, however.

comment:10 by Ian Culverwell, 3 years ago

Test eum2bufr (built on ECBUFR libs) too.

Control

../tools/eum2bufr ../data/eum_test.n4 -gi -o eum_test_l.bfr

---------------------------------------------------------------------
                  EUMETSAT to BUFR (ecbufr) Encoder
---------------------------------------------------------------------

 RejTimeDiff =         1430
 DT8 =            0           0           0           0           0           0           0           0
 MinRej =   -1051945189.9999999     

INFO (from eum2bufr):  Generated 1 GTS bulletin to eum_test_l.bfr

or

../tools/eum2bufr ../data/eum_test.n4 -gi -o eum_test_l.bfr         

---------------------------------------------------------------------
                  EUMETSAT to BUFR (ecbufr) Encoder
---------------------------------------------------------------------

 RejTimeDiff =         1430
 DT8 =        49380           3          10           0           9          33           0           1
 MinRej =    24919572103.000031     
INFO (from eum2bufr):  Reading EUM data from ../data/eum_test.n4
INFO (from ropp_io_read_eumdata):  Format Version 11.0
INFO (from eum2bufr):  Encoding profile    1 : OC_20120909000057_META_G015_EUME
 
WARNING (from eum2bufr):  Occultation is too old for GTS - not encoded.
 
WARNING (from eum2bufr):  No profiles were encoded or written to the BUFR file

if we hardwire DT8, and

../tools/eum2bufr ../data/eum_test.n4 -gi -t -1:00 -o eum_test_l.bfr

---------------------------------------------------------------------
                  EUMETSAT to BUFR (ecbufr) Encoder
---------------------------------------------------------------------

 RejTimeDiff =          -60
 DT8 =            0           0           0           0           0           0           0           0
 DT8 =        49380           3          10           0           9          33           0           1
 MinRej =    0.0000000000000000     

INFO (from eum2bufr):  Generated 1 GTS bulletin to eum_test_l.bfr

if we apply -t. As expected.

Test

../tools/eum2bufr ../data/eum_test.n4 -gi -o eum_test_l.bfr

---------------------------------------------------------------------
                  EUMETSAT to BUFR (ecbufr) Encoder
---------------------------------------------------------------------

 RejTimeDiff =         1430
 DT8 =         2021           8           4           0          15          46          33           7
 MinRej =    11355356.550116390     

WARNING (from eum2bufr):  Occultation is too old for GTS - not encoded.
 
WARNING (from eum2bufr):  No profiles were encoded or written to the BUFR file

and

../tools/eum2bufr ../data/eum_test.n4 -gi -t -1:00 -o eum_test_l.bfr

---------------------------------------------------------------------
                  EUMETSAT to BUFR (ecbufr) Encoder
---------------------------------------------------------------------

 RejTimeDiff =          -60
 DT8 =         2021           8           4           0          15          47           1         258
 MinRej =    0.0000000000000000     

INFO (from eum2bufr):  Generated 1 GTS bulletin to eum_test_l.bfr

if we apply -t. As expected.

comment:11 by Ian Culverwell, 3 years ago

Resolution: fixed
Status: assignedclosed

Strictly speaking, we should test ropp2bufr_eccodes, eum2bufr_eccodes and ropp2bufr_mo, but the same change has been applied to all of them (at r6863), so I think we can probably rule this one off. (They all compile OK, so the relevant modules are in place.) Enough is enough.

ropp_io/bufr/ropp2bufr_mod.f90 no longer needs updating.

None of the test scripts actually test the -gi option, as I mistakenly thought, so they don't need updating with a -t -1:00 option.

ropp2bufr and eum2bufr man pages tidied up at r6864.

Owen wanted a comment added to ropp_io/ropp/ropp_io_read_ncdf_get.f90; do this at r6865.

That's enough. Closing ticket.

Note: See TracTickets for help on using tickets.