bufr.pm:bufrread.pl

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
bufr.pm:bufrread.pl [2016-04-18 07:50:40]
pals
bufr.pm:bufrread.pl [2023-02-05 10:14:41] (current)
pals
Line 1: Line 1:
 <code perl> <code perl>
-#!/usr/bin/perl -w+#!/usr/bin/perl
  
-# (C) Copyright 2010-2016 MET Norway+# (C) Copyright 2010-2023 MET Norway
 # #
 # This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
Line 22: Line 22:
  
 use strict; use strict;
 +use warnings;
 use Getopt::Long; use Getopt::Long;
 use Pod::Usage qw(pod2usage); use Pod::Usage qw(pod2usage);
 use Geo::BUFR; use Geo::BUFR;
 +
 +# This is actually default in BUFR.pm, but provided here to make it
 +# easier for users to change to 'ECCODES' if preferred
 +use constant DEFAULT_TABLE_FORMAT => 'BUFRDC';
  
 # Will be used if neither --tablepath nor $ENV{BUFR_TABLES} is set # Will be used if neither --tablepath nor $ENV{BUFR_TABLES} is set
-use constant DEFAULT_TABLE_PATH => '/usr/local/lib/bufrtables'; +use constant DEFAULT_TABLE_PATH_BUFRDC => '/usr/local/lib/bufrtables'; 
-# Ought to be your most up-to-date table +use constant DEFAULT_TABLE_PATH_ECCODES => '/usr/local/share/eccodes/definitions/bufr/tables'; 
-use constant DEFAULT_CTABLE => 'C0000000000000023000';+# Ought to be your most up-to-date code table(s) 
 +use constant DEFAULT_CTABLE_BUFRDC => 'C0000000000000037000'; 
 +use constant DEFAULT_CTABLE_ECCODES => '0/wmo/37';
  
 # Parse command line options # Parse command line options
Line 36: Line 43:
            \%option,            \%option,
            'ahl=s',        # Decode BUFR messages with AHL matching <ahl_regexp> only            'ahl=s',        # Decode BUFR messages with AHL matching <ahl_regexp> only
-           'all_operators',# Show all operator descriptors when printing section 4+           'all_operators',# Show replication descriptors and all operator descriptors 
 +                           # when printing section 4
            'bitmap',       # Display bit-mapped values on same line            'bitmap',       # Display bit-mapped values on same line
            'codetables',   # Use code and flag tables to resolve values            'codetables',   # Use code and flag tables to resolve values
Line 49: Line 57:
            'param=s',      # Decode parameters with descriptors in <descriptor file> only            'param=s',      # Decode parameters with descriptors in <descriptor file> only
            'strict_checking=i', # Enable/disable strict checking of BUFR format            'strict_checking=i', # Enable/disable strict checking of BUFR format
 +           'tableformat=s',  # Set BUFR table format
            'tablepath=s',  # Set BUFR table path            'tablepath=s',  # Set BUFR table path
            'verbose=i',    # Set verbose level to n, 0<=n<=6 (default 0)            'verbose=i',    # Set verbose level to n, 0<=n<=6 (default 0)
Line 72: Line 81:
  
 Geo::BUFR->set_show_all_operators($option{all_operators}) if defined $option{all_operators}; Geo::BUFR->set_show_all_operators($option{all_operators}) if defined $option{all_operators};
 +
 +# Set BUFR table format
 +my $tableformat = (defined $option{tableformat}) ? uc $option{tableformat} : DEFAULT_TABLE_FORMAT;
 +Geo::BUFR->set_tableformat($tableformat);
  
 # Set BUFR table path # Set BUFR table path
Line 81: Line 94:
     Geo::BUFR->set_tablepath($ENV{BUFR_TABLES});     Geo::BUFR->set_tablepath($ENV{BUFR_TABLES});
 } else { } else {
-    # If all else fails, use the libbufr bufrtables +    # If all else fails, use the default tablepath in BUFRDC/ECCODES 
-    Geo::BUFR->set_tablepath(DEFAULT_TABLE_PATH);+    if ($tableformat eq 'BUFRDC') { 
 +        Geo::BUFR->set_tablepath(DEFAULT_TABLE_PATH_BUFRDC); 
 +    } elsif ($tableformat eq 'ECCODES'
 +        Geo::BUFR->set_tablepath(DEFAULT_TABLE_PATH_ECCODES); 
 +    }
 } }
  
Line 89: Line 106:
     eval { $ahl_regexp = qr/$option{ahl}/ };     eval { $ahl_regexp = qr/$option{ahl}/ };
     die "Argument to --ahl is not a valid Perl regular expression: $@" if $@;     die "Argument to --ahl is not a valid Perl regular expression: $@" if $@;
-    # When filtering on ahl we assume file is composed of GTS bulletins only 
-    Geo::BUFR->reuse_current_ahl(); 
 } }
  
Line 108: Line 123:
  
 # Arrays over filter criteria, used if option --filter is set # Arrays over filter criteria, used if option --filter is set
-my @fid;      # Filter descriptors, .e.g. $fid[1] = [ 001001, 001002 ]+my @fid;      # Filter descriptors, e.g. $fid[1] = [ 001001, 001002 ]
 my @fiv;      # Filter values, e.g. $fiv[1] = [ [ 3, 895 ], [ 6 252 ] ] my @fiv;      # Filter values, e.g. $fiv[1] = [ [ 3, 895 ], [ 6 252 ] ]
 my @num_desc; # Number of filter descriptors for each criterion, e.g. $num_desc[1] = 2 my @num_desc; # Number of filter descriptors for each criterion, e.g. $num_desc[1] = 2
Line 162: Line 177:
         if ($@) {         if ($@) {
             $current_ahl = $bufr->get_current_ahl() || '';             $current_ahl = $bufr->get_current_ahl() || '';
-            next READLOOP if $option{ahl} && $current_ahl !~ $ahl_regexp; +            next READLOOP if $option{ahl} && $current_ahl !~ $ahl_regexp;
  
             warn $@;             warn $@;
Line 186: Line 201:
             # instead.             # instead.
             my $table_version = $bufr->get_table_version();             my $table_version = $bufr->get_table_version();
-            $bufr->load_Ctable("C$table_version", DEFAULT_CTABLE);+            my $tableformat = Geo::BUFR->get_tableformat(); 
 +            if ($tableformat eq 'BUFRDC') { 
 +                $bufr->load_Ctable("C$table_version", DEFAULT_CTABLE_BUFRDC); 
 +            } elsif ($tableformat eq 'ECCODES'
 +                $bufr->load_Ctable("$table_version", DEFAULT_CTABLE_ECCODES); 
 +            }
         }         }
  
Line 311: Line 331:
 # Read in contents of $filter_file into variables @fid, @fiv, # Read in contents of $filter_file into variables @fid, @fiv,
 # @num_desc, @num_val and $num_criteria, which are defined above. # @num_desc, @num_val and $num_criteria, which are defined above.
 +# Note that index 0 of the arrays is not used.
 sub read_filter_file { sub read_filter_file {
     my $filter_file = shift;     my $filter_file = shift;
Line 336: Line 357:
         } else {         } else {
             my @values = split;             my @values = split;
 +            # Check that value line contains correct number of values
 +            die "Number of values doesn't match number of descriptors"
 +                . " for line $. in filter file '$filter_file'"
 +                if scalar @values != scalar @{$fid[$num_criteria]};
             # Remove leading 0's in numerical values (to prepare for string comparison)             # Remove leading 0's in numerical values (to prepare for string comparison)
             for $_ (@values) { s/^0+(\d+)$/$1/ };             for $_ (@values) { s/^0+(\d+)$/$1/ };
Line 354: Line 379:
     my ($data, $descriptors) = @_;     my ($data, $descriptors) = @_;
  
-    my $num_ordinary_criteria = @fid - $num_required_criteria;+    my $num_ordinary_criteria = $#fid - $num_required_criteria;
     my $num_success_req_criteria = 0; # Number of required criteria successfully fulfilled     my $num_success_req_criteria = 0; # Number of required criteria successfully fulfilled
     my $num_success_ord_criteria = 0; # Number of ordinary criteria successfully fulfilled     my $num_success_ord_criteria = 0; # Number of ordinary criteria successfully fulfilled
Line 412: Line 437:
                                                  or $num_success_ord_criteria > 0)) {                                                  or $num_success_ord_criteria > 0)) {
                                             return 0; # Don't filter this observation                                             return 0; # Don't filter this observation
 +                                        } else {
 +                                            next DESC;
                                         }                                         }
                                     } else {                                     } else {
Line 460: Line 487:
       [--param <descriptor file>]       [--param <descriptor file>]
       [--strict_checking n]       [--strict_checking n]
 +      [--tableformat <BUFRDC|ECCODES>]
       [--tablepath <path to BUFR tables>]       [--tablepath <path to BUFR tables>]
       [--verbose n]       [--verbose n]
Line 478: Line 506:
    --ahl <ahl_regexp>    --ahl <ahl_regexp>
                    Decode BUFR messages with AHL matching <ahl_regexp> only                    Decode BUFR messages with AHL matching <ahl_regexp> only
-   --all_operators Show all operator descriptors when printing section 4+   --all_operators Show replication descriptors and all operator descriptors 
 +                   when printing section 4
    --bitmap        Display bit-mapped values on same line    --bitmap        Display bit-mapped values on same line
    --codetables    Use code and flag tables to resolve values when unit    --codetables    Use code and flag tables to resolve values when unit
Line 502: Line 531:
                        n=2 Croak if (recoverable) error in BUFR format.                        n=2 Croak if (recoverable) error in BUFR format.
                            Nothing more in this message/subset will be decoded.                            Nothing more in this message/subset will be decoded.
 +   --tableformat   Currently supported are BUFRDC and ECCODES (default is BUFRDC)
    --tablepath <path to BUFR tables>    --tablepath <path to BUFR tables>
                    Set path to BUFR tables (overrides ENV{BUFR_TABLES})                    Set path to BUFR tables (overrides ENV{BUFR_TABLES})
Line 514: Line 544:
 set the environment variable BUFR_TABLES to the directory where your set the environment variable BUFR_TABLES to the directory where your
 BUFR tables are located (unless the default path provided by BUFR tables are located (unless the default path provided by
-bufrread.pl works for you).+bufrread.pl works for you). For tableformat ECCODES, se 
 +L<http://search.cpan.org/dist/Geo-BUFR/lib/Geo/BUFR.pm#BUFR-TABLE-FILES> 
 +for more info on how to set C<--tablepath> (or BUFR_TABLES).
  
 For option C<--ahl> the <ahl_regexp> should be a Perl regular For option C<--ahl> the <ahl_regexp> should be a Perl regular
-expression. E.g. C<--ahl 'ISS... ENMI'> will decode only BUFR SHIP+expression. E.g. C<--ahl "ISS... ENMI"> will decode only BUFR SHIP
 (ISS) from CCCC=ENMI. This is the only case where a little knowledge (ISS) from CCCC=ENMI. This is the only case where a little knowledge
-of Perl might be required for using the utility programs included in +of Perl might possibly be required when using the utility programs 
-Geo::BUFR.+included in Geo::BUFR.
  
 For option C<--param> each line in <descriptor file> should start with For option C<--param> each line in <descriptor file> should start with
Line 527: Line 559:
  
 Using C<--filter> will decode only those observations that meet one of Using C<--filter> will decode only those observations that meet one of
-the criteria in <filter file> (and all of those criteria marked +the criteria in <filter file> marked D: and all of those criteria 
-D!). Comments (starting with #) are ignored. An example of a filter +marked D!:. Comments (starting with #) are ignored. An example of a 
-file is+filter file is
  
   D: 001001   D: 001001
Line 573: Line 605:
 =head1 COPYRIGHT =head1 COPYRIGHT
  
-Copyright (C) 2010-2016 MET Norway+Copyright (C) 2010-2023 MET Norway
  
 =cut =cut
 </code> </code>
  • bufr.pm/bufrread.pl.1460965840.txt.gz
  • Last modified: 2022-05-31 09:23:11
  • (external edit)