Using GRIB data to simulate weather
Posted on May 28, 2015, by Richard Knol
For a global sailing simulator we needed a to provide current weather conditions for every location on the planet. Weather services around the world provide most their weather data as downloads in GRIB format. The best location for this the NOAA website. They have a list of all available downloads here
There is a lot of information in these files, that are really not needed for this purpose, so first we made a list of values we really needed. There is no need for forecast data as only the most current situation is needed. NOAA provides analysis data for this. The global sailing simulation needs the most actual data for:
- cloud coverage (divided in 4 layers as our sky simulation object only has 4 layers) (0-1 float value)
- wind direction and strength (degrees and m/s)
- precipitation (rain / snow / fog) (0-1 float value)
- wave heights (meters)
It also doesn't need this data in a very fine grid. One degree latitude/longitude will suffice.
The download that best matches these requirements is "GFS - T1534 Semi-Lagrangian grid" with filename gfs.tCCz.sfluxgrbfFF.grib2. Here's a list of the values you can find inside this grib file
It is updated every 6 hours at 00, 06, 12 and 18 hours UTC. But the reality is that the files are not available until about 3.5 hours later. This means that the "actual" weather conditions or the global sailing simulator are really the weather conditions of 3,5 to 9,5 hours ago. Oh well. Maybe we will use the 6 hour beforehand predictions instead to fix this time gap.
So we wrote a shell script that checks every 15 minutes to see if a new file is available and then downloads it. Unpacking the GRIB file is done with the program WGRIB2
. But before the data is ready to store in the database, there is some more conversion to be done.
The GRIB file only has 3 layers for cloud density, but the cloud visualization software needs a 4th layer to show a big, grey, low overcast. There is a clouds boundary layer in the grib file, but it is mostly identical to the lower clouds layer. So the top 3 layers of the weather simulation are setup with the grib values for TCDC:high cloud layer, TCDC:medium cloud layer and TCDC:low cloud layer. They are extracted to a CSV file and this is then pumped into the database per degree longitude/latitude by a perl script. For the lower overcast layer a fake value is computed, based on the other 3 cloud layers, the precipitation and the wind. This is completely inaccurate of course, but this is only a simulation and as long as the cloud situation is reasonably plausable, it's ok.
The wind direction and strength can be retrieved from UGRD and VGRD which are the U and V components of a wind vector. I used this formula (perl):
my $dir = 57.29578 * (atan2($valueu, $valuev)) + 180;
my $speed = sqrt(($valueu * $valueu) + ($valuev * $valuev));
The precipitation is a bit more difficult to extract from the GRIB files. The simulation needs 4 float values from 0 to 1, but neither of these is provided. For rain there is a booleananalysis value (rain or no rain) and a total for the entire day. So in order to get a 0-1 float value for rain, the CRAIN boolean value from the GRIB file is combined with the cloud coverage to create a usable value. This too is in no way accurate, but for this purpose it has to do. The rain can either fall as rain or snow in the simulation. In the grib file there is a value CPOFP (Probability of Frozen Precipitation [%]). This is used to choose between snow and rain.
There is also no grib value for fog present. But air of a certain temperature can only contain so much water and there are values SPFH (humidity) and TEMP (temperature) available. Wind strength is added to the equasion as well (more wind -> less fog). Again, this computed value for fog is not accurate at all, but has to suffice for this purpose.
There is a download available that contains global wave heights at NOAA but this is in BUFR format. And there is hardly any information available on how to read those files. Neither could a handy tool be founds that reads extracts the data like WGRIB2 does for GRIB files. For now, the wave heights are computed, rather then retrieved from actual data. For this computations the latest and previous wind strength and direction are used. The value is multiplied by a maximum wave height that differs per geographic coordinate (the Pacific Ocean has bigger waves than the North Sea).