OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
bin_csub.c
Go to the documentation of this file.
1 /*
2  This file contains all subroutines for the seawifs level 3 binning
3  */
4 
5 #include <sys/types.h>
6 #include <math.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 
10 #include <seaproto.h>
11 
12 #define PI 3.141592653589793
13 
14 /*
15  global variables only used inside this file, the call to 'bin_init'
16  may pass these variables to the calling routine
17  */
18 static int64_t *BASEBIN; // 1st bin of each row
19 static int64_t *NUMBIN; // no. of bin in each row
20 static double *LATBIN; // center latitude of each row
21 static int64_t TOTBINS; // total bin numbers
22 static int32_t NUMROWS; // total number of rows for binning
23 static float SEAM_LON;
24 
25 /*
26  bin_init: given the total row number, this subroutine returns
27  above variables.
28  */
29 
30 void bin_init(int32_t nrow, int64_t **nbin, int64_t **bbin, double **lbin,
31  int64_t *tbin) {
32  int i;
33  double radfac;
34 
35  if (nrow == -1) /* free the memory if not the first call */ {
36  free(NUMBIN);
37  free(BASEBIN);
38  free(LATBIN);
39  NUMROWS = 0;
40  NUMBIN = NULL;
41  BASEBIN = NULL;
42  LATBIN = NULL;
43  return;
44  }
45 
46  if(NUMROWS == 0) {
47  SEAM_LON = -180.0; /* this value should be passed in */
48  NUMROWS = nrow;
49 
50  NUMBIN = (int64_t *) calloc(NUMROWS, sizeof (int64_t));
51  BASEBIN = (int64_t *) calloc(NUMROWS, sizeof (int64_t));
52  LATBIN = (double *) calloc(NUMROWS, sizeof (double));
53 
54  radfac = PI / 180.0;
55 
56  for (i = 0; i < NUMROWS; i++) {
57  *(LATBIN + i) = (i + 0.5) * (180.0 / NUMROWS) - 90.0;
58  *(NUMBIN + i) = (int64_t) (cos(*(LATBIN + i) * radfac) * (2.0 * NUMROWS)
59  + 0.5);
60  }
61 
62  *BASEBIN = 1;
63 
64  for (i = 1; i < NUMROWS; i++)
65  *(BASEBIN + i) = *(BASEBIN + i - 1) + *(NUMBIN + i - 1);
66 
67  TOTBINS = *(BASEBIN + NUMROWS - 1) + *(NUMBIN + NUMROWS - 1) - 1;
68 
69  } else {
70  if(nrow != NUMROWS) {
71  printf("-E- %s:%d - bin_init - num rows (%d) not equal to previous num rows (%d)\n",
72  __FILE__, __LINE__, nrow, NUMROWS);
73  exit(EXIT_FAILURE);
74  }
75  }
76 
77  *nbin = NUMBIN; /* pass pointer back to the calling routine */
78  *bbin = BASEBIN;
79  *lbin = LATBIN;
80  *tbin = TOTBINS;
81 }
82 
83 /*
84  given a bin number, return the center lat/lon of that bin number
85  heuristic and binary search algorithm is used
86  */
87 void bin2ll(int64_t bin, double *lat, double *lon) {
88  int32_t row, rlow, rhi, rmid;
89  static int32_t old_row = 0; /* 1-relative */
90 
91  if (old_row > 0 && *(BASEBIN + old_row - 1) <= bin
92  && *(BASEBIN + old_row) > bin) {
93  row = old_row;
94  } else {
95  if (bin < 1)
96  bin = 1; /* south pole */
97  if (bin > TOTBINS)
98  bin = TOTBINS; /* north pole */
99 
100  /* binary search for row in range [1..NUMROWS] */
101  rlow = 1; /* 1-relative */
102  rhi = NUMROWS; /* 1-relative */
103  while (1) {
104  rmid = (rlow + rhi - 1) / 2; /* 0-relative */
105  if (*(BASEBIN + rmid) > bin)
106  rhi = rmid;
107  else
108  rlow = rmid + 1;
109 
110  if (rlow == rhi) {
111  row = rlow;
112  break;
113  }
114  }
115  old_row = row;
116  }
117 
118  *lat = *(LATBIN + row - 1);
119  *lon = 360.0 * (bin - *(BASEBIN + row - 1) + 0.5) / *(NUMBIN + row - 1);
120  *lon = *lon + SEAM_LON; /* note, *lon returned here may be in 0 to 360 */
121 }
122 
123 /*
124  given the lat/lon, return the bin number
125  lon has to be in the range of -180.0 to 180.0
126  */
127 void ll2bin(double lat, double lon, int64_t *bin) {
128  int64_t row, col; /* 0-relative */
129 
130  row = (int64_t) ((90.0 + lat) * (double) NUMROWS / 180.0);
131  col = (int64_t) ((double) (*(NUMBIN + row)) * (lon - SEAM_LON) / 360.0);
132  *bin = *(BASEBIN + row) + col;
133 }
134 
135 /*
136  given the lat/lon, return the row, column
137  lon has to be in the range of -180.0 to 180.0
138 
139  6/96. Cast double in order to get same bin #'s for SeaWiFS smap9
140  and SeaDAS smigen.
141  */
142 void ll2rc(double lat, double lon, int32_t *row, int32_t *col) {
143  *row = (int32_t) ((90.0 + (double) lat) * (double) NUMROWS / 180.0);
144  *col = (int32_t) ((double) (*(NUMBIN + (*row))) * ((double) lon - SEAM_LON)
145  / 360.0);
146  *row = *row + 1;
147  *col = *col + 1;
148 }
149 
150 /*
151  given row/column, return lat/lon
152  */
153 void rc2ll(int32_t row, int32_t col, double *lat, double *lon) {
154  *lat = *(LATBIN + row - 1);
155  *lon = SEAM_LON + (360.0 * (col - 0.5) / *(NUMBIN + row - 1));
156 }
157 
158 /*
159  given a row/column number, return the bin number (1-relative)
160  */
161 void rc2bin(int32_t row, int32_t col, int64_t *bin) {
162  *bin = *(BASEBIN + (int64_t) row - 1) + (int64_t) col - 1;
163 }
164 
165 /*
166  given a bin number, return the row and column (both are 1-relative)
167  heuristic and binary search algorithm is used
168  */
169 void bin2rc(int64_t bin, int32_t *row, int32_t *col) {
170  int32_t rlow, rhi, rmid;
171  static int32_t old_row = 0; /* 1-relative */
172 
173  if (old_row > 0 && *(BASEBIN + old_row - 1) <= bin
174  && *(BASEBIN + old_row) > bin) {
175  *row = old_row;
176  } else {
177  if (bin < 1)
178  bin = 1; /* south pole */
179  if (bin > TOTBINS)
180  bin = TOTBINS; /* north pole */
181 
182  /* binary search for row in range [1..NUMROWS] */
183  rlow = 1; /* 1-relative */
184  rhi = NUMROWS; /* 1-relative */
185  while (1) {
186  rmid = (rlow + rhi - 1) / 2; /* 0-relative */
187  if (*(BASEBIN + rmid) > bin)
188  rhi = rmid;
189  else
190  rlow = rmid + 1;
191 
192  if (rlow == rhi) {
193  *row = rlow;
194  break;
195  }
196  }
197  old_row = *row;
198  }
199 
200  *col = bin - *(BASEBIN + (*row) - 1) + 1;
201 }
void bin2rc(int64_t bin, int32_t *row, int32_t *col)
Definition: bin_csub.c:169
#define NULL
Definition: decode_rs.h:63
float * lat
void bin_init(int32_t nrow, int64_t **nbin, int64_t **bbin, double **lbin, int64_t *tbin)
Definition: bin_csub.c:30
void rc2bin(int32_t row, int32_t col, int64_t *bin)
Definition: bin_csub.c:161
void bin2ll(int64_t bin, double *lat, double *lon)
Definition: bin_csub.c:87
integer, parameter double
void ll2rc(double lat, double lon, int32_t *row, int32_t *col)
Definition: bin_csub.c:142
void ll2bin(double lat, double lon, int64_t *bin)
Definition: bin_csub.c:127
void rc2ll(int32_t row, int32_t col, double *lat, double *lon)
Definition: bin_csub.c:153
float * lon
#define PI
Definition: bin_csub.c:12
int i
Definition: decode_rs.h:71