ocssw  1.0
/disk01/web/ocssw/build/src/libbin/bin_csub.c (r8096/r5806)
Go to the documentation of this file.
00001 /*
00002     This file contains all subroutines for the seawifs level 3 binning
00003 */
00004 
00005 
00006 #include <sys/types.h>
00007 #include <math.h>
00008 #include <stdlib.h>
00009 
00010 #include <seaproto.h>
00011 
00012 #define     PI  3.141592653589793
00013 
00014 /* 
00015    global variables only used inside this file, the call to 'bin_init'
00016    may pass these variables to the calling routine
00017 
00018     NUMROWS :  total number of rows for binning 
00019     *NUMBIN :  no. of bin in each row 
00020     *BASEBIN:  1st bin of each row 
00021     TOTBINS:   total bin numbers 
00022     *LATBIN:   center latitude of each row 
00023 */
00024 
00025 int32 *NUMBIN, *BASEBIN;
00026 float *LATBIN;
00027 int32 TOTBINS;
00028 int32 NUMROWS;
00029 float SEAM_LON;
00030 
00031 /*
00032     bin_init: given the total row number, this subroutine returns 
00033               above variables.
00034 
00035 */
00036 
00037 void bin_init(int32 nrow, int32 **nbin, int32 **bbin, float **lbin, int32 *tbin)
00038 {
00039   int i;
00040   double radfac;
00041   static int first=1;
00042 
00043   if (nrow == -1)   /* free the memory if not the first call */
00044   {
00045     free(NUMBIN);
00046     free(BASEBIN);
00047     free(LATBIN);
00048     first = 1;
00049     return;
00050   }
00051 
00052   //  if (!first) return; // remove JMG 03/19/09
00053   first = 0;
00054 
00055 
00056   SEAM_LON = -180.0;      /*  this value should be passed in  */
00057   NUMROWS = nrow;
00058 
00059   NUMBIN = (int32 *) calloc(NUMROWS, sizeof(int32));
00060   BASEBIN = (int32 *) calloc(NUMROWS, sizeof(int32));
00061   LATBIN = (float *) calloc(NUMROWS, sizeof(float));
00062 
00063   radfac = PI / 180.0;
00064 
00065   for (i=0; i<NUMROWS; i++)
00066   {
00067     *(LATBIN+i) = (i + 0.5) * (180.0 / NUMROWS) - 90.0;
00068     *(NUMBIN+i) = (int32) (cos(*(LATBIN+i)*radfac) * (2.0 * NUMROWS) + 0.5);
00069   }
00070 
00071   *BASEBIN = 1;
00072 
00073   for (i=1; i<NUMROWS; i++)
00074     *(BASEBIN+i) = *(BASEBIN+i-1) + *(NUMBIN+i-1);
00075 
00076   TOTBINS = *(BASEBIN+NUMROWS-1) + *(NUMBIN+NUMROWS-1) - 1;
00077 
00078   *nbin = NUMBIN;      /* pass pointer back to the calling routine */
00079   *bbin = BASEBIN;
00080   *lbin = LATBIN;
00081   *tbin = TOTBINS;
00082 } 
00083 
00084 
00085 
00086 
00087 /* 
00088    given a bin number, return the center lat/lon of that bin number 
00089    heuristic and binary search algorithm is used
00090 */
00091 void bin2ll(int32 bin, float *lat, float *lon)
00092 {
00093   int32   row, rlow, rhi, rmid;
00094   static int32 old_row=0;    /* 1-relative */
00095 
00096   if (old_row > 0 && *(BASEBIN+old_row-1) <= bin && *(BASEBIN+old_row) > bin)
00097   {
00098     row = old_row;
00099   }
00100   else
00101   {
00102     if (bin < 1)
00103       bin = 1;             /* south pole */
00104     if (bin > TOTBINS)
00105       bin = TOTBINS;       /* north pole */
00106  
00107     /* binary search for row in range [1..NUMROWS] */
00108     rlow = 1;            /* 1-relative */
00109     rhi = NUMROWS;       /* 1-relative */
00110     while (1)
00111     {
00112       rmid = (rlow + rhi - 1) / 2;     /* 0-relative */
00113       if (*(BASEBIN+rmid) > bin)
00114         rhi = rmid;      
00115       else
00116         rlow = rmid + 1;
00117 
00118       if (rlow == rhi)
00119       {
00120         row = rlow;
00121         break;
00122       }
00123     }
00124     old_row = row;
00125   }
00126 
00127   *lat = *(LATBIN+row-1);
00128   *lon = 360.0 * (bin - *(BASEBIN+row-1) + 0.5) / *(NUMBIN+row-1);
00129   *lon = *lon + SEAM_LON;  /* note, *lon returned here may be in 0 to 360 */
00130 }
00131 
00132 
00133 
00134 /* 
00135    given the lat/lon, return the bin number 
00136    lon has to be in the range of -180.0 to 180.0
00137 */
00138 void ll2bin(float lat, float lon, int32 *bin)
00139 {
00140   int32 row, col;       /* 0-relative */
00141 
00142   row = (int32) ((90.0 + lat) * (float) NUMROWS / 180.0);  
00143   col = (int32) ((float) (*(NUMBIN+row)) * (lon - SEAM_LON) / 360.0);
00144   *bin = *(BASEBIN+row) + col;
00145 }
00146 
00147 
00148 
00149 
00150 /* 
00151    given the lat/lon, return the row, column 
00152    lon has to be in the range of -180.0 to 180.0
00153 
00154    6/96. Cast double in order to get same bin #'s for SeaWiFS smap9
00155          and SeaDAS smigen.
00156 */
00157 void ll2rc(float lat, float lon, int32 *row, int32 *col)
00158 {
00159   *row = (int32) ((90.0 + (double) lat) * (double) NUMROWS / 180.0);  
00160   *col = (int32) ((double) (*(NUMBIN + (*row))) * ((double) lon - SEAM_LON) / 360.0);
00161   *row = *row + 1;
00162   *col = *col + 1; 
00163 }
00164 
00165 
00166 
00167 
00168 /*
00169    given row/column, return lat/lon
00170 */
00171 void rc2ll(int32 row, int32 col, float *lat, float *lon)
00172 {
00173   *lat = *(LATBIN+row-1);
00174   *lon = SEAM_LON + (360.0 * (col - 0.5) / *(NUMBIN+row-1));
00175 }
00176 
00177 
00178 
00179 
00180 /* 
00181    given a row/column number, return the bin number (1-relative) 
00182 */
00183 void rc2bin(int32 row, int32 col, int32 *bin)
00184 {
00185   *bin = *(BASEBIN+row-1) + col - 1;
00186 }
00187 
00188 
00189 
00190 /* 
00191    given a bin number, return the row and column (both are 1-relative) 
00192    heuristic and binary search algorithm is used
00193 */
00194 void bin2rc(int32 bin, int32 *row, int32 *col)
00195 {
00196   int32   rlow, rhi, rmid;
00197   static int32 old_row=0;    /* 1-relative */
00198 
00199   if (old_row > 0 && *(BASEBIN+old_row-1) <= bin && *(BASEBIN+old_row) > bin)
00200   {
00201     *row = old_row;
00202   }
00203   else
00204   {
00205     if (bin < 1)
00206       bin = 1;             /* south pole */
00207     if (bin > TOTBINS)
00208       bin = TOTBINS;       /* north pole */
00209  
00210     /* binary search for row in range [1..NUMROWS] */
00211     rlow = 1;            /* 1-relative */
00212     rhi = NUMROWS;       /* 1-relative */
00213     while (1)
00214     {
00215       rmid = (rlow + rhi - 1) / 2;     /* 0-relative */
00216       if (*(BASEBIN+rmid) > bin)
00217         rhi = rmid;      
00218       else
00219         rlow = rmid + 1;
00220 
00221       if (rlow == rhi)
00222       {
00223         *row = rlow;
00224         break;
00225       }
00226     }
00227     old_row = *row;
00228   }
00229 
00230   *col = bin - *(BASEBIN + (*row) - 1) + 1;
00231 }
00232 
00233 
00234 
00235 /* 
00236    given a bin number, return the center lat/lon of that bin number 
00237    no heuristic or binary search algorithm is used
00238    this routine is very slow due to the array reference (I think)
00239 */
00240 
00241 /*
00242 void old_bin2ll(bin, lat, lon)
00243 int32 bin;
00244 float *lat, *lon;
00245 {
00246   int32 row;
00247 
00248   row = NUMROWS-1;
00249 
00250   while (bin < BASEBIN[row])
00251     row--;
00252 
00253   *lat = LATBIN[row];
00254   *lon = 360.0 * (bin - BASEBIN[row] + 0.5) / NUMBIN[row];
00255 }
00256 
00257 */
00258 
00259 
00260 /*  update version, much faster than using array reference */
00261 
00262 void old_bin2ll(int32 bin, float *lat, float *lon)
00263 {
00264   int32 row;
00265   int32 *tmpptr;
00266 
00267   row = NUMROWS - 1;
00268   tmpptr = BASEBIN + NUMROWS - 1;
00269 
00270   while (bin < *tmpptr--)
00271     row--;
00272 
00273   *lat = LATBIN[row];
00274   *lon = 360.0 * (bin - BASEBIN[row] + 0.5) / NUMBIN[row];
00275 }
00276