Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
bufr.pm:bufrdump.pl_source [2011-09-15 09:34:23] pals |
bufr.pm:bufrdump.pl_source [2022-05-31 09:29:31] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | <code perl> | + | <code perl bufrdump.pl> |
# | # | ||
Line 35: | Line 35: | ||
' | ' | ||
' | ' | ||
- | ' | + | ' |
' | ' | ||
' | ' | ||
- | ' | + | ' |
+ | ' | ||
' | ' | ||
' | ' | ||
Line 70: | Line 71: | ||
# ECMWF software requires trailing '/' | # ECMWF software requires trailing '/' | ||
$ENV{BUFR_TABLES} .= '/' | $ENV{BUFR_TABLES} .= '/' | ||
+ | |||
+ | die " | ||
+ | if ! -d $ENV{BUFR_TABLES}; | ||
my $obstype = $option{obstype} ? " | my $obstype = $option{obstype} ? " | ||
- | my $filter | + | my $filt = $option{filter} ? " |
my $lon1 = $option{lon1} ? " | my $lon1 = $option{lon1} ? " | ||
my $lat1 = $option{lat1} ? " | my $lat1 = $option{lat1} ? " | ||
my $lon2 = $option{lon2} ? " | my $lon2 = $option{lon2} ? " | ||
my $lat2 = $option{lat2} ? " | my $lat2 = $option{lat2} ? " | ||
+ | my $del = $option{delimiter} ? " | ||
+ | my $delimiter = $option{delimiter} ? " | ||
# Any filter criteria provided? | # Any filter criteria provided? | ||
- | my $criteria_ref = read_filter_file($option{filter}); | + | my ($filter, |
# Any specific stations requested? | # Any specific stations requested? | ||
Line 89: | Line 95: | ||
my $csv = $option{csv} ? 1 : 0; | my $csv = $option{csv} ? 1 : 0; | ||
# First line in CSV should be the parameters | # First line in CSV should be the parameters | ||
- | print join(',' | + | print join($del, @$params_ref) . " |
# Any transformations of units specified? | # Any transformations of units specified? | ||
Line 107: | Line 113: | ||
# Dump the content of the BUFR file using the Fortran program $BUFRDUMP | # Dump the content of the BUFR file using the Fortran program $BUFRDUMP | ||
- | my $dump = `$BUFRDUMP | + | my $fortran_options |
+ | my $dump = `$BUFRDUMP $fortran_options | ||
die if $?; # Reason for bufrdump failing should have been printed to STDERR | die if $?; # Reason for bufrdump failing should have been printed to STDERR | ||
Line 122: | Line 129: | ||
my %msg; # Hash with parameter name as key, parameter value as value | my %msg; # Hash with parameter name as key, parameter value as value | ||
- | LINE:while (defined(my $line = shift @lines)) { | + | LINE: |
+ | | ||
# Each new message starts with a blank line | # Each new message starts with a blank line | ||
if ($line !~ /^\s*$/) { | if ($line !~ /^\s*$/) { | ||
# Skip error messages from libbufr, which should start with space(s) | # Skip error messages from libbufr, which should start with space(s) | ||
- | next if $line =~ /^\s+/; | + | next LINE if $line =~ /^\s+/; |
# Build up the message to be (possibly) printed | # Build up the message to be (possibly) printed | ||
my ($param, $value) = ($line =~ / | my ($param, $value) = ($line =~ / | ||
+ | # Know only of one case where next check is necessary: if | ||
+ | # a CCITT IA5 value contains new line (\n) | ||
+ | next LINE if !defined $value; | ||
if ($transform_file && $transform_ref-> | if ($transform_file && $transform_ref-> | ||
# Replace value with transformed value | # Replace value with transformed value | ||
Line 144: | Line 155: | ||
if ($line =~ /^\s*$/ or @lines == 0) { | if ($line =~ /^\s*$/ or @lines == 0) { | ||
# A full message has been completed. Should it be printed? | # A full message has been completed. Should it be printed? | ||
- | if ($filter | + | if ($filt && filter_obs(\%msg, |
# Skip this message | # Skip this message | ||
} elsif ($req_id && filter_station(\%msg, | } elsif ($req_id && filter_station(\%msg, | ||
Line 156: | Line 167: | ||
foreach my $name (@$params_ref) { | foreach my $name (@$params_ref) { | ||
if (exists $msg{$name}) { | if (exists $msg{$name}) { | ||
- | $txt .= $csv ? $msg{$name} . ',' | + | $txt .= $csv ? $msg{$name} . $del : " |
} elsif ($forced_params_ref-> | } elsif ($forced_params_ref-> | ||
- | $txt .= $csv ? ' | + | $txt .= $csv ? ' |
} elsif ($csv) { | } elsif ($csv) { | ||
- | $txt .= ',' | + | $txt .= $del; |
} | } | ||
} | } | ||
Line 169: | Line 180: | ||
} | } | ||
} | } | ||
- | | + | if ($csv) { |
+ | | ||
+ | for (1 .. length($del)) { | ||
+ | chop $txt; | ||
+ | } | ||
+ | } | ||
if ($txt) { | if ($txt) { | ||
if ($sort) { | if ($sort) { | ||
- | # Sort wmonr before call sign before buoy_id before aircraft | + | # Sort wmonr before nationalnr |
+ | # buoy_id before aircraft | ||
if ($msg{wmonr}) { | if ($msg{wmonr}) { | ||
$stnid = ' | $stnid = ' | ||
+ | } elsif ($msg{nationalnr}) { | ||
+ | $stnid = ' | ||
} elsif ($msg{call_sign}) { | } elsif ($msg{call_sign}) { | ||
- | $stnid = '10_' . $msg{call_sign}; | + | $stnid = '20_' . $msg{call_sign}; |
} elsif ($msg{buoy_id}) { | } elsif ($msg{buoy_id}) { | ||
- | $stnid = '10_' . $msg{buoy_id}; | + | $stnid = '30_' . $msg{buoy_id}; |
} elsif ($msg{aircraft}) { | } elsif ($msg{aircraft}) { | ||
- | $stnid = '10_' . $msg{aircraft}; | + | $stnid = '40_' . $msg{aircraft}; |
+ | } elsif ($msg{icao_id}) { | ||
+ | $stnid = ' | ||
+ | } elsif ($msg{wigosid}) { | ||
+ | $stnid = ' | ||
} else { | } else { | ||
# Skip observation if no station identification found | # Skip observation if no station identification found | ||
Line 189: | Line 212: | ||
my $key = $stnid . ' | my $key = $stnid . ' | ||
$data_of{$key} = exists $data_of{$key} | $data_of{$key} = exists $data_of{$key} | ||
- | | + | |
} else { | } else { | ||
$data_of{$stnid} = exists $data_of{$stnid} | $data_of{$stnid} = exists $data_of{$stnid} | ||
- | | + | |
} | } | ||
} elsif ($sort_on) { | } elsif ($sort_on) { | ||
my $val = exists $msg{$sort_on} ? $msg{$sort_on} : ''; | my $val = exists $msg{$sort_on} ? $msg{$sort_on} : ''; | ||
$data_of{$val} = exists $data_of{$val} | $data_of{$val} = exists $data_of{$val} | ||
- | | + | |
} else { | } else { | ||
# No sorting. We can print the line immediately | # No sorting. We can print the line immediately | ||
Line 228: | Line 251: | ||
} | } | ||
print $data_of_missing_value if $data_of_missing_value; | print $data_of_missing_value if $data_of_missing_value; | ||
+ | } | ||
+ | |||
+ | |||
+ | # Read the filter conditions (if any). Return the filter option to be | ||
+ | # used by bufrdump, the found criteria (if any) as well as the number | ||
+ | # of succeeding alternatives for each criterium | ||
+ | sub get_filter_conditions { | ||
+ | my $filt = shift; | ||
+ | return ('' | ||
+ | |||
+ | my $fortran_filter = ''; | ||
+ | my @f; | ||
+ | if ($filt =~ /,/) { | ||
+ | # Argument to --filter is a comma separated list | ||
+ | @f = split /,/, $filt; | ||
+ | } else { | ||
+ | # Argument to --filter is a file | ||
+ | $fortran_filter = " | ||
+ | open my $FILTER, '<', | ||
+ | or die " | ||
+ | # Skip the criteria meant for Fortran parsing, i.e. proceed to | ||
+ | # first line following a blank line | ||
+ | while (< | ||
+ | last if $_ =~ /^\s*$/; | ||
+ | } | ||
+ | @f = < | ||
+ | close $FILTER or die " | ||
+ | } | ||
+ | return ($fortran_filter) if !@f; # BUFR descriptor criteria only | ||
+ | |||
+ | my @allowed_operators = | ||
+ | (' | ||
+ | '<', | ||
+ | '< | ||
+ | '>', | ||
+ | '> | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | my @criteria; | ||
+ | my @num_alt; # Number of alternative criteria following this, | ||
+ | # i.e. if line is '< | ||
+ | # corresponding values in @num_alt will be 2,1,0 | ||
+ | |||
+ | # Read the filter criteria meant for Perl parsing, skipping blank | ||
+ | # lines and comment lines | ||
+ | FILTERLINE: | ||
+ | foreach my $line (@f) { | ||
+ | $line =~ s/^\s+//; | ||
+ | $line =~ s/\s+$//; | ||
+ | next FILTERLINE if !$line || $line =~ /^#/; | ||
+ | my @crit = split /\|/, $line; | ||
+ | my $num = scalar @crit; | ||
+ | foreach my $criterium (@crit) { | ||
+ | $criterium =~ s/^\s+//; | ||
+ | $criterium =~ s/\s+$//; | ||
+ | if ($criterium ne '' | ||
+ | push @criteria, $criterium; | ||
+ | push @num_alt, --$num; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | return ($fortran_filter) if !@criteria; | ||
+ | |||
+ | # Check that the criteria are properly formatted | ||
+ | foreach my $criterium (@criteria) { | ||
+ | # Naked parameter possibly preceded by ' | ||
+ | next if $criterium =~ /^!?\w+$/; | ||
+ | |||
+ | my $op = (split / +/, $criterium)[1]; | ||
+ | if (!defined($op) or grep(/ | ||
+ | or !grep(/ | ||
+ | print "Error in $filt: | ||
+ | . " or operator not supported: | ||
+ | exit 1; | ||
+ | } | ||
+ | } | ||
+ | return ($fortran_filter, | ||
} | } | ||
Line 244: | Line 346: | ||
my @p = split /,/, $params; | my @p = split /,/, $params; | ||
foreach my $name (@p) { | foreach my $name (@p) { | ||
+ | $name =~ s/^\s+//; | ||
+ | $name =~ s/\s+$//; | ||
if ($name =~ /^!/) { | if ($name =~ /^!/) { | ||
$name = substr $name, 1; | $name = substr $name, 1; | ||
Line 284: | Line 388: | ||
$line =~ s/^\s+//; | $line =~ s/^\s+//; | ||
$line =~ s/\s+$//; | $line =~ s/\s+$//; | ||
- | next if !$line || $line =~ /^#/; | + | |
my ($param, $transform) = split /=/, $line, 2; | my ($param, $transform) = split /=/, $line, 2; | ||
die " | die " | ||
Line 292: | Line 396: | ||
$transform_of{$param} = $transform; | $transform_of{$param} = $transform; | ||
} | } | ||
+ | close $TRANSFORM or die " | ||
return \%transform_of; | return \%transform_of; | ||
} | } | ||
- | sub read_filter_file | + | # Return true (1) if observation is to be filtered, i.e. does not |
- | my $filter_file | + | # comply with at least one line in filter file, where each line is one |
- | return | + | # or more alternatives < |
+ | sub filter_obs | ||
+ | my $msg_ref | ||
+ | my $criteria_ref = shift; | ||
+ | my $num_alt_ref = shift; # gives the number of alternative | ||
+ | # criteria still to be checked | ||
+ | return | ||
- | my @allowed_operators | + | my @ascii_params |
- | | + | |
- | '<', | + | |
- | '< | + | |
- | '>', | + | |
- | '> | + | |
- | ' | + | |
- | ); | + | |
- | my @criteria; | + | |
- | | + | |
- | | + | for (my $i=0; $i < @{$criteria_ref}; |
- | # Skip the criteria meant for Fortran parsing, i.e. proceed to | + | |
- | # first line following a blank line | + | |
- | while (<$FILTER>) { | + | |
- | | + | |
- | } | + | |
- | | + | |
- | # lines and comment lines | + | if (substr($f_param, |
- | | + | $f_param |
- | $line =~ s/^\s+//; | + | # If parameter is present, criterium is not fullfilled |
- | $line =~ s/\s+$//; | + | if (exists |
- | next if !$line || $line =~ /^#/; | + | next if $num_alt; # More alternatives to check |
- | push @criteria, $line; | + | |
- | } | + | |
- | | + | |
- | | + | # check. This observation should be filtered away |
- | # Naked parameter is ok | + | return 1; |
- | next if $criterium =~ /^\w+$/; | + | } else { |
+ | # Criterium fulfilled. No need to check alternative criteria | ||
+ | $i += $num_alt if $num_alt; | ||
+ | next; | ||
+ | } | ||
+ | } | ||
- | | + | |
- | if (!defined($op) or grep(/ | + | if (not exists |
- | | + | |
- | . " or operator not supported: | + | |
- | | + | |
} | } | ||
- | } | ||
- | return \@criteria; | ||
- | } | ||
- | # Return true (1) if observation is to be filtered, i.e. does not | + | my $msg_value = $msg_ref-> |
- | # comply with at least one of the < | + | |
- | # < | + | # present |
- | sub filter_obs { | + | if (not defined $f_operator) { |
- | my $msg_ref | + | if ($num_alt) { |
- | my $criteria_ref = shift; | + | # No need to check the alternative |
+ | $i += $num_alt; | ||
+ | } | ||
+ | next; | ||
+ | } | ||
- | my @ascii_params = qw(aircraft call_sign icao_id name obstime type); | ||
- | |||
- | foreach my $criterium (@$criteria_ref) { | ||
- | my ($f_param, $f_operator, | ||
- | return 1 unless exists $msg_ref-> | ||
- | next if not defined $f_operator; | ||
- | # present, so criterium fulfilled | ||
chomp $f_value; | chomp $f_value; | ||
- | if ($f_operator eq ' | + | |
+ | | ||
+ | || $f_operator eq '< | ||
+ | || $f_operator eq '>' | ||
+ | || $f_operator eq '> | ||
+ | || $f_operator eq ' | ||
+ | || $f_operator eq ' | ||
+ | $op = $f_operator; | ||
+ | } elsif ($f_operator eq ' | ||
+ | || $f_operator eq '!=') { | ||
if (grep {$_ eq $f_param} @ascii_params) { | if (grep {$_ eq $f_param} @ascii_params) { | ||
- | $msg_ref-> | + | $msg_value |
- | | + | $op = ($f_operator |
} else { | } else { | ||
- | | + | $op = ($f_operator eq '=') ? '==' : ' |
} | } | ||
- | } elsif ($f_operator eq '<' | + | } else { |
- | | + | |
- | } elsif ($f_operator eq '<=') { | + | } |
- | | + | |
- | } elsif ($f_operator | + | # Some parameters might need special massaging |
- | | + | if ($f_operator |
- | } elsif ($f_operator | + | if ($f_param |
- | | + | # Make non octal by removing leading 0 |
- | } elsif ($f_operator | + | |
- | if (grep {$_ eq $f_param} @ascii_params) { | + | |
- | | + | } elsif ($f_param |
- | | + | # Convert to a pure numerical value (float). For 001101 |
- | } else { | + | # State id only numbers between 100 and 699 are operational |
- | | + | |
+ | | ||
+ | } elsif ($f_param | ||
+ | # Convert to a pure numerical value (float) | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | $f_value =~ s/ +$//; | ||
+ | $f_value =~ s/ /./; | ||
+ | | ||
+ | # Add or correct quoting to "" | ||
+ | $msg_value = '"' | ||
+ | $f_value = lc $f_value; | ||
+ | | ||
+ | $f_value | ||
+ | $f_value | ||
+ | } | ||
+ | | ||
+ | | ||
+ | } | ||
} | } | ||
} | } | ||
+ | |||
+ | my $condition = " | ||
+ | # Some values should be string values | ||
+ | if ($f_operator =~ /~/) { | ||
+ | $condition = " | ||
+ | } elsif (grep {$_ eq $f_param} @ascii_params) { | ||
+ | $condition = " | ||
+ | } | ||
+ | |||
+ | # Finally, do the criterium check | ||
+ | if (eval $condition) { | ||
+ | # No need to check the remaining alternative criteria | ||
+ | $i += $num_alt if $num_alt; | ||
+ | next; | ||
+ | } else { | ||
+ | next if $num_alt; | ||
+ | return 1; | ||
+ | } | ||
} | } | ||
Line 385: | Line 529: | ||
} | } | ||
+ | # Return the type of station requested, and the station | ||
+ | # identifications. Leave some leeway for how to list wmonr and | ||
+ | # nationalnr (leading 0's might be omitted - added here) | ||
sub get_requested_stations { | sub get_requested_stations { | ||
my $req_stations = shift; | my $req_stations = shift; | ||
return if !$req_stations; | return if !$req_stations; | ||
- | die " | + | die " |
- | . "' | + | . "' |
- | unless $req_stations =~ / | + | unless $req_stations |
+ | | ||
my ($id, $rest) = split /=/, $req_stations; | my ($id, $rest) = split /=/, $req_stations; | ||
Line 401: | Line 549: | ||
$station += 1000 if $station < 1000; | $station += 1000 if $station < 1000; | ||
$station = sprintf(" | $station = sprintf(" | ||
+ | push @req_stn, $station; | ||
+ | } | ||
+ | return ($id, \@req_stn); | ||
+ | } elsif ($id eq ' | ||
+ | my @req_stn; | ||
+ | foreach my $station (@stations) { | ||
+ | # Turn national station number into 10 digits | ||
+ | my ($state_id, $national_id) = split /_/, $station; | ||
+ | die " | ||
+ | if !defined $national_id or $national_id eq ''; | ||
+ | $station = $state_id . ' | ||
push @req_stn, $station; | push @req_stn, $station; | ||
} | } | ||
Line 440: | Line 599: | ||
} | } | ||
- | my @ascii_params = qw(aircraft call_sign icao_id obstime name type); | + | my @ascii_params = qw(aircraft call_sign icao_id obstime name type wigosid); |
my $lexical_sort = grep {$_ eq $sort_on} @ascii_params; | my $lexical_sort = grep {$_ eq $sort_on} @ascii_params; | ||
Line 498: | Line 657: | ||
bufrdump.pl <bufr file(s)> | bufrdump.pl <bufr file(s)> | ||
- | [--filter <filter file>] | + | [--filter <filter file | filter list>] |
- | [--param < | + | [--param < |
[--sort] | [--sort] | ||
[--sort_on < | [--sort_on < | ||
[--station <station list>] | [--station <station list>] | ||
[--transform < | [--transform < | ||
- | [--lon1 x1] | + | [--lon1 |
- | [--lat1 y1] | + | [--lat1 |
- | [--lon2 x2] | + | [--lon2 |
- | [--lat2 | + | [--lat2 |
- | [--obstype < | + | [--obstype < |
[--tablepath <path to BUFR tables>] | [--tablepath <path to BUFR tables>] | ||
[--help] | [--help] | ||
Line 527: | Line 686: | ||
- | --filter <filter file> | + | --filter <filter file | filter list> |
- | Decode observations meeting criteria in <filter file> only | + | Decode observations meeting criteria in filter file or |
- | --param < | + | filter list only |
- | Print parameters in parameter file or comma separated | + | --param < |
- | list (e.g. wmonr,TA) only, in same order as they occur | + | Print parameters in parameter file or comma |
- | | + | |
- | | + | |
+ | followed by --delimiter <del>, the parameters vill | ||
+ | | ||
+ | | ||
--sort | --sort | ||
- | first stations with wmonr, then stations with call sign, | + | first stations with wmonr, then stations with nationalnr, |
- | buoy_id | + | |
+ | | ||
--sort_on < | --sort_on < | ||
- | values of <parameter>, or decreasing values if a ' | + | values of parameter, or decreasing values if a ' |
follows the parameter name. E.g. --sort_on TA- will | follows the parameter name. E.g. --sort_on TA- will | ||
sort on decreasing temperatures. Observations not | sort on decreasing temperatures. Observations not | ||
Line 544: | Line 707: | ||
except when --sort_on is combined with --sort (in which | except when --sort_on is combined with --sort (in which | ||
case sorting is done firstly on station identification, | case sorting is done firstly on station identification, | ||
- | secondly on <parameter> with missing values printed first) | + | secondly on parameter with missing values printed first) |
--station <station list> | --station <station list> | ||
Print observations for stations in station list only, | Print observations for stations in station list only, | ||
Line 550: | Line 713: | ||
--transform < | --transform < | ||
Do the transformations of parameter values listed in | Do the transformations of parameter values listed in | ||
- | | + | transformation file |
- | --lon1 x1 | + | --lon1 |
- | --lat1 y1 | + | --lat1 |
- | --lon2 x2 | + | --lon2 |
- | --lat2 y2 | + | --lat2 |
x1,y1,x2,y2 should be decimal degrees | x1,y1,x2,y2 should be decimal degrees | ||
- | --obstype < | + | --obstype < |
Force observation type. If this option is not set, | Force observation type. If this option is not set, | ||
- | | + | |
- | on metadata in section 1 of each BUFR message | + | |
--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 568: | Line 731: | ||
To avoid having to use the C< | To avoid having to use the C< | ||
- | set the invironment | + | set the environment |
BUFR tables are located (unless the default path provided by | BUFR tables are located (unless the default path provided by | ||
bufrdump.pl works for you). | bufrdump.pl works for you). | ||
Line 577: | Line 740: | ||
temperature to be printed for a BUFR SYNOP file, either supply | temperature to be printed for a BUFR SYNOP file, either supply | ||
- | wmonr, | + | wmonr,nationalnr, |
as argument to --params, or supply a < | as argument to --params, or supply a < | ||
Line 583: | Line 746: | ||
wmonr | wmonr | ||
+ | nationalnr | ||
call_sign | call_sign | ||
TA | TA | ||
Line 603: | Line 767: | ||
listing may for example start like | listing may for example start like | ||
- | wmonr,call_sign,TA | + | wmonr; |
- | 01001,,-1.5 | + | 01001;;;-1.5 |
- | | + | |
+ | |||
+ | You can choose another delimiter than semicolon by use of option | ||
+ | --delimiter < | ||
Using --filter will decode only those observations that meet at least | Using --filter will decode only those observations that meet at least | ||
Line 611: | Line 778: | ||
in <filter file>, where the BUFR descriptor criteria should come first | in <filter file>, where the BUFR descriptor criteria should come first | ||
in filter file followed by a blank line, then comes the parameter | in filter file followed by a blank line, then comes the parameter | ||
- | criteria which should match < | + | criteria which should match < |
- | where operator is one of =, !=, <, <=, > and >=. An example filter | + | < |
- | file is | + | follows =~ and !~ should be a Perl match regular expression. The parameter |
+ | criteria may be phrased as alternatives by separating them with ' | ||
+ | a single line. An example filter file is | ||
D: 001001 I2.2 | D: 001001 I2.2 | ||
Line 630: | Line 799: | ||
which decodes all observations with block number 01, two other | which decodes all observations with block number 01, two other | ||
- | specific wmo stations and one specific ship, being manned | + | specific wmo stations and one specific ship, where stations |
- | having | + | manned and have cloud cover with a value different from 8, and have |
- | message) | + | temperature between 5 and 9.5 degrees Celsius, and contain |
- | containing | + | precipitation for last 24 hours. Comment lines starting with # will be |
- | with # will be ignored. | + | ignored. |
- | Another example: the simple | + | Another example: the filter file (starting with a blank line!) |
- | wmonr | + | |
+ | obstime >= ' | ||
+ | HW | HWA | PW | PWA | ||
+ | FF > 10 | FG_010 > 10 | ||
+ | |||
+ | will print only those ship observations for which the 4 character | ||
+ | call_sign starts with 2 letters in the interval LA-LN, and having | ||
+ | obstime larger or equal to the datetime given, and containing wave | ||
+ | data (specifically: | ||
+ | automatically measured), and with wind or 10 minutes gust more than 10 | ||
+ | m/s. | ||
+ | |||
+ | For convenience, | ||
+ | provide the filter criteria on the command line. Example: | ||
+ | |||
+ | --filter 'wmonr,TA > 0,RR_12 | RR_24, !FF' | ||
- | will print only those observations | + | will decode |
- | ships). | + | and containing precipitation for 12 or 24 hours and not reporting |
+ | wind. If (like for --param) the filter list consists of one criterium | ||
+ | only, a comma must be appended. | ||
To avoid the need of creating a filter file when observations for some | To avoid the need of creating a filter file when observations for some | ||
few stations are requested, you can provide the stations in a comma | few stations are requested, you can provide the stations in a comma | ||
- | separated list after option --station. | + | separated list after option --station. |
--station wmonr=01001, | --station wmonr=01001, | ||
+ | --station nationalnr=614_0050410003, | ||
--station call_sign=LF5U | --station call_sign=LF5U | ||
--station buoyid=64607, | --station buoyid=64607, | ||
--station aircraft=EU3421, | --station aircraft=EU3421, | ||
+ | --station icao_id=ENGM, | ||
+ | --station wigosid=0-376-0-511, | ||
You cannot mix different kinds of stations this way (before ' | You cannot mix different kinds of stations this way (before ' | ||
- | must choose either wmonr, call_sign, buoy_id | + | must choose either wmonr, nationalnr, call_sign, buoy_id, aircraft, |
- | that providing the stations in the BUFR descriptor part (first part) | + | icao_id or wigosid). Note also that providing the stations in the BUFR |
- | of the filter file will speed up execution time considerably, | + | descriptor part (first part) of the filter file will speed up |
- | to using option --station. It is possible to combine --filter with | + | execution time considerably, |
- | --station if done with some care, e.g, specifying WMO block 01 and the | + | possible to combine --filter with --station if done with some care, |
- | required parameters in filter file, then the requested stations in | + | e.g. specifying WMO block 01 and the required parameters in filter |
- | station list. | + | file, then the requested stations in station list. |
The --transform option is provided mainly to be able to use other | The --transform option is provided mainly to be able to use other | ||
Line 683: | Line 872: | ||
is to be applied for sky not all covered by clouds, you should use NN | is to be applied for sky not all covered by clouds, you should use NN | ||
!= 100 instead of NN != 8 in filter file. | != 100 instead of NN != 8 in filter file. | ||
+ | |||
+ | The --obstype option might be handy in some special cases, like when | ||
+ | you are interested only in the surface part of oceanographic data | ||
+ | (then use ' | ||
+ | with vss>0 in high resolution radiosonde data (then use ' | ||
+ | sounding-' | ||
+ | BUFR messages have unusual values. | ||
=head1 AUTHOR | =head1 AUTHOR |