| Level: Intermediate Nathan Harrington (harrington.nathan@gmail.com), Programmer, IBM
05 Jun 2007 Traditional weather reports will give notice of vague forecasts and severe weather alerts in your general area. The code and tools
presented in this article will allow you to create precise detection zones so you can receive a page, SMS, or e-mail a few minutes before a
precipitation event is likely to occur at the monitored location. Use GD and Perl for image processing of the NOAA WSR-88D radar data to
create your own precipitation alerts for precise areas. Choose your notification method and let users know when the rain will begin and when
it will clear.
The National Oceanic and Atmospheric Administration (NOAA) is a fantastic government agency responsible for the majority of the weather
data in the United States. Using the publicly available and easily accessible reflectivity data from one of the WSR-88D class radar systems, this
article will show you how to choose a location and set up weather-change alerts for a precise geographical area. Please note that this is not a
substitute for severe weather alert systems or designed to produce reliable precipitation forecasts. Rather, this article presents code and
processes for determining if it's likely to rain very soon in a specific area. Conversely, the same code is used to produce alerts when a
no-precipitation window has opened, giving you a handy notice of when it's time to dash inside from your car.
Requirements
Hardware
Any PC manufactured after 2000 should provide plenty of horsepower for compiling and running the code in this article. The code presented
here is a relatively simple image processing algorithm using GD. If you want to monitor multiple locations with subsecond response times,
you'll need a fast processor. The rest of us should be fine with anything Pentium
II® or later.
Software
Perl and GD are a must for this article, although if you have a preferred image processing tool suite, you can modify the algorithms used here
to perform effectively in any number of environments. You'll also need an image-compositing tool, such as The Gimp, to build a geophysical map
of the radar's environment and to choose a set of pixel coordinates specifying your
location. In addition, it's handy to have a good command-line download tool, such as wget. Check Resources
for links.
Image acquisition
The WSR-88D class radar systems have many acquisition modes for developing data on atmospheric precipitation. The most commonly
used form of radar energy return mapping is the Base Reflectivity graph. We will use this graph for the processing of localized precipitation
information. To begin, visit NOAA.gov, and enter your city and state for a forecast. Click the radar
image for your localized area, and you will see an image like that shown below.
Figure 1. Base reflectivity Web page example
The radar image shown is actually composed of layers you can download separately.
Downloading RIDGE Radar Images describes the various layers and how
to download them. For our example, we'll need the topographical, highways, and county maps to accurately identify the precise location to track.
You'll only have to download these layers once, and you'll be able to reuse them later. Listing 1 shows the various images you'll need to
download if you live in central North Carolina. Consult the NOAA documentation to find the radar designation and appropriate URLs for your area.
Listing 1. Radar image overlays Central North Carolina
County Outlines: http://www.srh.noaa.gov/ridge/Overlays/County/Short/RAX_County_Short.gif
Highway: http://www.srh.noaa.gov/ridge/Overlays/Highways/Short/RAX_Highways_Short.gif
Topographical relief: http://www.srh.noaa.gov/ridge/Overlays/Topo/Short/RAX_Topo_Short.jpg
|
With these layers downloaded, you can combine them with the base reflectivity image to produce a more easily readable image map.
Here is the radar image for the central North Carolina area.
Download the equivalent layers and radar return image for your area, and you'll be ready to move on to the next step.
Selecting your location on the map
Fire up The Gimp or your image manipulation tool of choice and combine the overlays you downloaded for your area.
I recommend applying the overlays in the following order: topographical, counties, highways. Do not include the radar base reflectivity image
as it can make precise area location more difficult. Zoom in on your general area and use your mouse to identify the precise location you
want to monitor. Note the pixel coordinates as they will be used as the basis for the
monitoring area in the image-processing code. Figure 2 shows a screenshot from The Gimp window, as the Research Triangle Park area
in central North Carolina is identified. The precise coordinates in this case are shown
in the bottom left-hand corner as 263,258.
Figure 2. Precise location identification
Image artifact considerations
A common occurrence for the base reflectivity data is to show the equivalent of light precipitation where there is in fact clear skies. This
explanation of this behavior is beyond the scope of this article, but we need to deal with these false positives in order to reliably detect when
a precipitation event is likely to occur. Figure 3 shows a sample base reflectivity image on a clear day in central North Carolina.
Figure 3. Clear day base reflectivity false positives
As you can see from the radar data, there appears to be light precipitation within a 30-mile radius of the radar antenna. A quick look outside
shows this is obviously not the case, and the program shown below will compensate for this behavior by only detecting precipitation events
of a certain threshold. Precipitation events in the "Light" classification have a base reflectivity of between 0 and 15 DBZ. This seems to correspond
well to the reflectivity range of the false positives, so the program described below will consider anything of higher reflectivity to be a trackable
precipitation event. Specifically, any pixels that are green, yellow, or red will be considered precipitation events as they pass through the
detection area.
Using GD for simple yellow, green, and red reflectivity acquisition
With your selected pixel coordinates and a single-layer base reflectivity map, the logical process for detecting precipitation near a spot on the
map is straightforward. First, scan the reflectivity data in the immediate area around the detection coordinates, allowing for precipitation front
movement from any direction. If the scanned data indicates reflectivity above "low" (the presence of green, yellow or red pixels), consider the
status to be "raining." If there is no reflectivity above the "low" threshold, consider the status to be "clear." The omni-directionality of the detection
algorithm is important to ensure the capability for detecting precipitation gaps in a developing storm system.
The getPrecipState.pl program shown in Listings 2 and 3 uses Perl and GD to implement
the high-level logical process:
Listing 2. getPrecipState.pl Section 1
#!/usr/bin/perl -w
# getPrecipState.pl - process WSR-88D N0 (base reflectivity) data to indicate
# precipitation status, such as 'raining' or 'clear'
use strict;
use GD;
die "specify file name, X pixel, Y pixel, distance, threshold " unless @ARGV == 5;
my( $fname, $pointX, $pointY, $distance, $threshold ) = @ARGV;
my %colorList =( "2,253,2" => "lightGreen 20DBZ",
"1,197,1" => "mediumGreen 25DBZ",
"0,142,0" => "darkGreen 30DBZ",
"253,248,2" => "lightYellow 35DBZ",
"229,188,0" => "mediumYellow 40DBZ",
"253,139,0" => "darkYellow 45DBZ",
"253,0,0" => "lightGreen 50DBZ",
"212,0,0" => "mediumGreen 55DBZ",
"188,0,0" => "darkGreen 60DBZ",
"248,0,253" => "lightPurple 65DBZ",
"152,84,198" => "mediumPurple 70DBZ",
"253,253,253" => "takeCover! 75DBZ" );
my $radarMap = newFromGif GD::Image( "$fname" ) || die "bad image file $fname";
|
The first section of getPrecipState.pl ensures that the program has the correct number of variables to process. After defining
a simple hash of the colors considered to be valid precipitation, the image specified is loaded from disk. Note that if you want to track strong
reflectivity signals only in the N0 map, simply remove the green and yellow colors from
the colorList hash .
Listing 3. getPrecipState.pl Section 2
my $startCol = $pointX - ($distance/2);
my $startRow = $pointY - ($distance/2);
my $endCol = $pointX + ($distance/2);
my $endRow = $pointY + ($distance/2);
my $colN = $startCol;
my $precipCount = 0;
while( $colN <= $endCol )
{
my $rowN = $startRow;
while( $rowN <= $endRow )
{
my $index = $radarMap->getPixel( $colN, $rowN );
my( $r, $g, $b ) = $radarMap->rgb($index);
if( exists( $colorList{"$r,$g,$b"} ) )
{
$precipCount++;
if( $precipCount >= $threshold ){ $colN = 700; $rowN = 700 }
}
$rowN++;
}#column
$colN++;
}#row
if( $precipCount >= $threshold )
{
print "$fname is raining\n" ;
}else
{
print "$fname is clear \n";
} |
The remainder of the getPrecipState.pl code shown in Section 2 sets up a square detection area bounded
by the start and end Col|Row variables. The next two
while loops simply scan the detection area for precipitation pixels as defined by their color match to those
specified in the colorList hash variable. If enough precipitation pixels have been counted to exceed the threshold
parameter, exit the loops and write the "raining" status. If there are too few precipitation pixels to exceed the threshold parameter, print the
"clear" status.
With your base reflectivity layer downloaded as shown above, run the program with the command
perl getPrecipState.pl <radar_image> <X coord> <Y
Coord> <distance> <threshold> . For example, if your radar image is from the central North Carolina WSR-88D station, your
location coordinates are 263,258 and you want to detect the presence of moderate or greater precipitation within an approximately 5-mile area
around the detection zone, you would specify a command of perl getPrecipState.pl RAX_N0R_0.gif 263 258 10 40 .
State monitor with rules
Now that you have your rain/clear processor completed, you can tie the output to a simple state monitor to produce alerts based on your rules.
For example, let's assume you want an e-mail notification when rain is in the immediate area, and an on-screen notification pop-up after it has
passed. The following configuration file will send an e-mail using mutt for the rain
warning and pop-up a message box to the local display for 10 seconds when the rain has passed.
raining ## mutt -s "rain proximity alert" 919749089?@cingularme.com < /dev/null
clear ## kdialog --passivepopup "The rain has passed" 10
|
To process these notification configuration options correctly, we'll need a program that determines the initial state of the detection zone,
then monitors the zone for changes in status and sends the appropriate output. Listing
4 shows the stateMonitor.pl program.
Listing 4. stateMon.pl Section 1
#!/usr/bin/perl -w
# stateMon.pl - simple monitoring of precipitation state
use strict;
my %cmdHash = ();
my $initialState = "null";
eval
{
open(STATE,notify.state) or die "could not open state file";
$initialState = <STATE>;
close(STATE);
};
if( $@ =~ /could not open state file/ )
{
open(STATE,">notify.state") or die "can't open state file for writing";
print STATE "null";
close(STATE);
}#file not found error
open(CFG,notify.config) or die "can't open notification configuration";
while(<CFG>)
{
my( $keyword, $command ) = split " ##";
$cmdHash{$keyword} = $command;
}
close(CFG);
|
The first section will declare variables and attempt to load the previous configuration from the notify.state file. If the file does not exist (as
determined by the file open error), write the "null" state to the file. The notify.config file is then processed to load the commands to run upon
each state being reached. Listing 5 shows the remainder of the stateMon.pl program.
Listing 5. stateMon.pl Section 2
while(my $status = <STDIN>)
{
open(STATE,">notify.state") or die "can't open state file for writing";
print STATE "$status";
close(STATE);
for my $keyword ( keys %cmdHash )
{
if( $status =~ /$keyword/i )
{
last if( $initialState eq "null" );
if( $initialState !~ /$status/i )
{
my $cmd = `$cmdHash{$keyword}`;
}#if status is not initial state
}#if status and keywork match
}#for each keyword
}#while stdin
|
The standard "while" type loop starts by reading the output from the getPrecipState.pl program. The current state is then written to the notify.state file, which saves the state for the
next read. Each key read from the notify.config file is then processed. If the current status matches a key from the notify.config file as stored in the
%cmdHash variable, continue the processing. If the initialState is "null" (a previous state had not been recorded),
exit the loop. Otherwise, if the current state does not match the recorded state, run the command specified.
Take the following case as an example:
The program starts, and the notify.state file does not exist, so it is created with the contents "null". The "clear" status has been passed in by the
getPrecipState.pl program, so the first section in Listing 5 will write "clear" into the notify.state file. The keys specified
in %cmdHash are processed, but because the initialState was set to "null", the loop is exited, and no commands are run. On the next pass, the
stateMon.pl program will read the "clear" status from the notify.state file, and if the
getPrecipState.pl program passes in a "raining" status, the appropriate notification will be sent to
the specified e-mail address.
To use the stateMon.pl program, simply pipe the output of
the getPrecipState.pl program into the stdin of stateMon.pl , like so:
perl getPrecipState.pl RAX_N0R_0.gif 263 258 10 40 | perl stateMon.pl .
Keep in mind that you can modify the getPrecipState.pl program and the notify.config alert descriptions file to
support any number of events. If you'd like to receive a notice when the notification zone receives a high percentage of rainfall compared to the
surrounding areas, it's a simple matter of changing the processing algorithms of the
getPrecipState.pl program and printing out a different keyword to be matched by the contents of the notify.config file.
Also note that if you want to reset the status of the stateMon.pl operations (such as raining, clear or null), simply
delete the notify.state file or change the contents manually. This will allow you to reset the status of the detection system based on other factors,
such as wind speed or computed cloud cover.
Full precipitation monitoring configuration
With your selected radar image, geographical coordinates in pixel (X,Y) form, and the programs described above, you can create a simple
precipitation and alert-clearing system. A basic configuration approach is to use wget
(available for UNIX® and Windows®) and a scheduler, such as cron, to automatically download the WSR-88D base reflectivity
image for your area every 5 minutes. Use the same scheduler to run the getPrecipState.pl command with the most recent image and pipe the
output to the stateMon.pl program. Just like that, you'll receive messages as precipitation events approach, as well
as when the rain will clear. Very handy if you want to know when to run outside to put the top up on your convertible or when a break in the rain
will allow you to run out and check your snail mail without getting drenched.
This approach to radar image processing is useful for precipitation related messages,
as well as developing data on various weather-related events. You can use slightly modified versions of this code to track precipitation trends over
a broad time range. Another option is to change the bounding areas to provide simple rain gate monitor, in order to find out if it has rained on
your favorite park bench in the past few hours, before you head for the picnic.
Download Description | Name | Size | Download method |
---|
Sample code | os-weathermaps-radarProc_0.1.zip | 1.5KB | HTTP |
---|
Resources Learn
-
The National Oceanic and Atmospheric Administration explains the WSR-88D radar system.
-
CPAN hosts the GD Image Processing Perl module.
-
For automated file downloads, try wget for UNIX variants and Windows.
-
To determine your pixel coordinates in a layered radar image, try The Gimp.
-
"
Enable C++ applications for Web services using XML-RPC" is a step-by-step guide to exposing C++ methods as services.
-
Browse all the open source content on developerWorks.
-
To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
-
Stay current with developerWorks' Technical events and webcasts.
-
Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
-
Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
-
Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
Get products and technologies
-
Innovate your next open source development project with IBM trial software, available for download or on DVD.
-
Download IBM product evaluation versions, and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
About the author | | | Nathan Harrington is a programmer at IBM currently working with Linux and resource-locating technologies. |
Rate this page
| |