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 , 4 years ago
comment:2 by , 4 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 4 years ago
Owner: | changed from | to
---|
comment:4 by , 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 , 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 , 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 , 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:9 by , 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 , 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 , 3 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
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.
This isn't a problem for ropp2bufr_eccodes or eum2bufr_eccodes, because they always (or nearly always) initialise DT8 to
which avoids the problem.
But ropp2bufr (built with ECBUFR lib) produces, in five successive runs,
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.