The level-3 products produced by NASA's Ocean Biology processing Group comprise level-2 data that have been spatially and temporally aggregated after being filtered to exclude unwanted values. Here follows a description of the spatial aggregation — or binning — method that we currently use.
Our level-3 binning scheme is based on the sinusoidal map projection. A modification of that projection is used to divide the Earth into bins of roughly equal area. The area of the bins is usually chosen based on the characteristics of the data set that is being binned. (If an orbiting sensor has an instantaneous field of view that is nearly 100 kilometers across, then it may not make much sense to group pixels into bins that are only 5 kilometers across, for example.)
For the purposes of this explanation, let us choose a bin size such that each bin spans ten degrees of latitude from south to north. The bins of such a scheme — shown in Figure 1 — are much larger than those we use for any of the data sets in our archive, but that makes them big enough to see in a small map of the world, and the basic construction of the bins is the same as for higher-resolution / smaller-bin arrangements.
The above figure shows the sinusoidal nature of our chosen binning scheme in that the number of bins in each row is reduced by the cosine of the latitude as one moves north or south of the equator. Where it differs from a straight sinusoidal projection is in the rounding that occurs when determining how many bins a given row should be divided into. This rounding is necessary to avoid fractional bins at the ends of rows, but it does introduce a small departure from area equality among bins from different rows. A further small departure from area equality is introduced by the fact that we assume a spherical Earth instead of using a more precise ellipsoidal model when we lay out our bin boundaries.
Figure 2, below, provides a polar view of the layout of level-3 bins.
The level-3 bin files that we currently distribute come in one of three resolutions. As hinted at before, the chosen resolution depends somewhat on the mission. The following table summarizes our level-3 resolutions.
Approximate Linear Dimension (km) | Approximate Angular Dimension | Average Bin Area (km^{2})^{*} | Number of Latitudinal Rows | Total Number of Bins | Missions Using This Resolution |
---|---|---|---|---|---|
111 | 1 degree | 12,392 | 180 | 41,252 | SAC-D/Aquarius |
9.28 | 5 minutes | 86 | 2160 | 5,940,422 | OrbView-2/SeaWiFS ADEOS/OCTS |
4.64 | 2.5 minutes | 21.5 | 4320 | 23,761,676 | Nimbus-7/CZCS Terra/MODIS Aqua/MODIS Suomi-NPP/VIIRS Envisat/MERIS |
One degree (or 111 kilometers) is the bin dimension chosen for the Aquarius mission. This binning scheme has 180 rows. Figure 3 shows the size and orientation of these bins over the northwestern Atlantic Ocean.
We divide the Earth up into 2160 latitudinal rows for the SeaWiFS mission. For our spherical Earth having a radius of 6378.145 kilometers, this results in an average bin width of 9.28 kilometers. Figure 4 shows the size and orientation of these bins over New Zealand's Cook Strait.
Double the number of latitudinal rows to 4320, and you get the 4.64-kilometer bin size that we use for the MODIS missions. Figure 5 shows the size and orientation of such bins around the Strait of Messina.
Note that computer rounding errors can become significant at higher bin resolutions (smaller bin sizes). You can get different bin numbers for the same geographic coordinates if you perform your computations using 32-bit arithmetic and then repeat the computation using 64-bit arithmetic. 64-bit arithmetic was used in the preparation of the above figures.
The binning scheme described on this page is applied to level-2 data; specifically, the location of the center of each valid level-2 pixel determines which bin that pixel gets thrown into. Similarly, when it is time to make an image of the level-3 data, the data from the level-3 bins need to be interpolated into a regular grid of level-3 pixels that are suitable for display. Figure 6 shows the relationships between these bins and pixels using a sample MODIS scene of the north coast of Iceland. (More of the imaged area is available in our image gallery.)
A set of Perl subroutines are provided below as an illustration of the steps needed to convert back and forth between geographic coordinates and level-3 bin numbers. The variable names used are similar to those given in Appendix A of NASA Technical Memorandum 104566, Vol. 32.
To use the following subroutines, one would call initbin
once with the number of rows in the desired bin resolution. Then one
could call latlon2bin
or bin2latlon
as often
as needed to convert a latitude/longitude pair to a bin number or a
bin number to a center latitude/longitude. The bin2bounds
subroutine will return the bounding latitudes and longitudes for any
given bin number should you wish to plot bin outlines as in the above
figures.
my $pi = 4*atan2(1,1);
my ($numrows, @basebin, @latbin, @numbin);
############################################
# #
# Insert the rest of your code here. #
# #
############################################
# The following functions are based on the pseudocode found in Appendix A of:
#
# Campbell, J.W., J.M. Blaisdell, and M. Darzi, 1995:
# Level-3 SeaWiFS Data Products: Spatial and Temporal Binning Algorithms.
# NASA Tech. Memo. 104566, Vol. 32,
# S.B. Hooker, E.R. Firestone, and J.G. Acker, Eds.,
# NASA Goddard Space Flight Center, Greenbelt, Maryland
sub initbin {
$numrows = shift;
$basebin[0] = 1;
for(my $row=0; $row<$numrows; $row++){
$latbin[$row] = (($row + 0.5)*180.0/$numrows) - 90.0;
$numbin[$row] = int(2*$numrows*cos($latbin[$row]*$pi/180.0) + 0.5);
if($row > 0){
$basebin[$row] = $basebin[$row - 1] + $numbin[$row - 1];
}
}
$totbins = $basebin[$numrows - 1] + $numbin[$numrows - 1] - 1;
}
sub lat2row {
my $lat = shift;
my $row = int((90 + $lat)*$numrows/180.0);
if($row >= $numrows){
$row = $numrows - 1;
}
$row;
}
sub rowlon2bin {
my ($row,$lon) = @_;
$lon = constrain_lon($lon);
my $col = int(($lon + 180.0)*$numbin[$row]/360.0);
if($col >= $numbin[$row]){
$col = $numbin[$row] - 1;
}
$basebin[$row] + $col;
}
sub latlon2bin {
my ($lat,$lon) = @_;
$lat = constrain_lat($lat);
$lon = constrain_lon($lon);
my $row = lat2row($lat);
my $col = int(($lon + 180.0)*$numbin[$row]/360.0);
if($col >= $numbin[$row]){
$col = $numbin[$row] - 1;
}
$basebin[$row] + $col;
}
sub bin2latlon {
my $bin = shift;
my $row = $numrows - 1;
if($bin < 1){
$bin = 1;
}
while($bin < $basebin[$row]){
$row--;
}
my $clat = $latbin[$row];
my $clon = 360.0*($bin - $basebin[$row] + 0.5)/$numbin[$row] - 180.0;
($clat,$clon);
}
sub bin2bounds {
my $bin = shift;
my $row = $numrows - 1;
if($bin < 1){
$bin = 1;
}
while($bin < $basebin[$row]){
$row--;
}
my $north = $latbin[$row] + 90.0/$numrows;
my $south = $latbin[$row] - 90.0/$numrows;
my $lon = 360.0*($bin - $basebin[$row] + 0.5)/$numbin[$row] - 180.0;
my $west = $lon - 180.0/$numbin[$row];
my $east = $lon + 180.0/$numbin[$row];
($north,$south,$west,$east);
}
sub constrain_lat {
my $lat = shift;
$lat = 90 if($lat > 90);
$lat = -90 if($lat < -90);
$lat;
}
sub constrain_lon {
my $lon = shift;
$lon += 360 while($lon < -180);
$lon -= 360 while($lon > 180);
$lon;
}