OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
bindepths.c
Go to the documentation of this file.
1 /*
2 
3 Norman Kuring 28-Jul-1999
4 I modified map_octs_to_box.c to produce this code.
5 
6 Norman Kuring 15-Feb-2000
7 I modified swmapdepth.c to produce this code.
8 
9 Norman Kuring 04-Oct-2002
10 Change in input file format. Depth is now represented as a floating point.
11 
12  */
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <math.h>
17 #include <mfhdf.h>
18 #include <genutils.h>
19 
20 #define USAGE "\
21 Usage: %s filename\n\
22 where: filename is the full path to a SeaWiFS level-2 file that contains\n\
23  computed depth data.\n\
24 This program maps SeaWiFS level-2 depth data to bins of a Plate Carree\n\
25 projection that extends from 35 North to 35 South and from 180 West\n\
26 to 180 East. The results are written to standard output as a series\n\
27 of ASCII text records. Each output record contains a bin number and\n\
28 pixel value separated by whitespace. Each bin represents one 0.01 by\n\
29 0.01 degree subregion of the aforementioned area. Bins are numbered\n\
30 from 0 to 251,999,999. Depths are expressed in meters.\n"
31 
32 #define FILENAME argv[1]
33 #define LAC_PIXEL_INSET 200
34 #define SCALE 100
35 
36 #define READ_GLBL_ATTR(nam,ptr) { \
37  if(SDreadattr(sd_id,SDfindattr(sd_id,(nam)),(VOIDP)(ptr))){ \
38  fprintf(stderr, \
39  "-E- %s line %d: Could not get global attribute, %s, from file, %s.\n", \
40  __FILE__,__LINE__,(nam),FILENAME); \
41  return(EXIT_FAILURE); \
42  } \
43 }
44 
45 #define MALLOC(ptr,typ,num) { \
46  (ptr) = (typ *)malloc((num) * sizeof(typ)); \
47  if((ptr) == NULL){ \
48  fprintf(stderr,"-E- %s line %d: Memory allocation failure.\n", \
49  __FILE__,__LINE__); \
50  exit(EXIT_FAILURE); \
51  } \
52 }
53 
54 #define READ_SDS(nam,ptr,s0,s1,s2,e0,e1,e2) { \
55  int32 start[3],edge[3]; \
56  edge[0]=(e0); edge[1]=(e1); edge[2]=(e2); \
57  start[0]=(s0); start[1]=(s1); start[2]=(s2); \
58  if(SDreaddata(SDselect(sd_id, SDnametoindex(sd_id, (nam))), \
59  start, NULL, edge, (VOIDP)(ptr)) == FAIL){ \
60  fprintf(stderr,"-E- %s line %d: Could not read SDS, %s.\n", \
61  __FILE__,__LINE__,(nam)); \
62  exit(EXIT_FAILURE); \
63  } \
64 }
65 
66 void get_scan_coords(int32, int32, int32, float32 **, float32 **);
67 
68 static int32 sd_id;
69 
70 int main(int argc, char *argv[]) {
71 
72  int32 npix, nscans, num_cntl_pts, lacstart, lacsub;
73  int32 pix_0, pix_n;
74  float32 *lat, *lon;
75  float32 *data;
76  int32 nflag[8];
77  int s, bin, x, y;
78 
79  if (argc < 2) {
80  fprintf(stderr, USAGE, argv[0]);
81  return (EXIT_FAILURE);
82  }
83 
84  /* Open the HDF file */
85  sd_id = SDstart(FILENAME, DFACC_RDONLY);
86  if (sd_id == FAIL) {
87  fprintf(stderr, "-E- %s line %d: SDstart failed for file, %s.\n",
88  __FILE__, __LINE__, FILENAME);
89  return (EXIT_FAILURE);
90  }
91 
92  /* Read the file dimensions. */
93  READ_GLBL_ATTR("Pixels per Scan Line", &npix);
94  READ_GLBL_ATTR("Number of Scan Lines", &nscans);
95  READ_GLBL_ATTR("Number of Pixel Control Points", &num_cntl_pts);
96  READ_GLBL_ATTR("LAC Pixel Start Number", &lacstart);
97  READ_GLBL_ATTR("LAC Pixel Subsampling", &lacsub);
98  if (lacsub == 1) {
99  if (lacstart - 1 + npix < LAC_PIXEL_INSET
100  || lacstart - 1 > 1284 - LAC_PIXEL_INSET) {
101  fprintf(stderr,
102  "-E- %s line %d: Input pixels are too close to the edge of the swath.\n",
103  __FILE__, __LINE__);
104  return (EXIT_FAILURE);
105  }
106  pix_0 = LAC_PIXEL_INSET - lacstart + 1;
107  pix_n = 1285 - lacstart - LAC_PIXEL_INSET;
108  } else if (lacsub == 4) {
109  if (lacstart - 1 + 4 * npix < LAC_PIXEL_INSET
110  || lacstart - 1 > 1284 - LAC_PIXEL_INSET) {
111  fprintf(stderr,
112  "-E- %s line %d: Input pixels are too close to the edge of the swath.\n",
113  __FILE__, __LINE__);
114  return (EXIT_FAILURE);
115  }
116  pix_0 = (LAC_PIXEL_INSET - lacstart + 1) / 4 + 0.5;
117  pix_n = 247 - (int) ((lacstart - 1 + LAC_PIXEL_INSET) / 4 + 0.5);
118  } else {
119  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
120  fprintf(stderr,
121  "Unexpected number of pixels per scanline (%d) in file, %s.\n",
122  npix, FILENAME);
123  return (EXIT_FAILURE);
124  }
125  if (pix_0 < 0) pix_0 = 0;
126  if (pix_n >= npix) pix_n = npix - 1;
127  if (nscans <= 0) {
128  fprintf(stderr,
129  "-E- %s line %d: Bad scene dimension: nscans=%d in file, %s.\n",
130  __FILE__, __LINE__, nscans, FILENAME);
131  return (EXIT_FAILURE);
132  }
133 
134  /* Allocate some memory for the per-scanline data. */
135  MALLOC(data, float32, npix);
136 
137  /* For each scan line ... */
138  for (s = 0; s < nscans; s++) {
139 
140  int32 p;
141 
142  /*
143  Read the navigation flags and skip scans having invalid navigation.
144  Also skip scans that were collected while the sensor tilt was changing.
145  */
146  READ_SDS("nflag", nflag, s, 0, 0, 1, 8, 1);
147  if (nflag[0] == 1) continue; /* Invalid navigation */
148  if (nflag[6] == 2) continue; /* Tilt is changing */
149 
150  /* Read the data and their coordinates. */
151  READ_SDS("depth", data, s, 0, 0, 1, npix, 1);
152  get_scan_coords(s, npix, num_cntl_pts, &lat, &lon);
153 
154  /* For each pixel excluding the limbs ... */
155  for (p = pix_0; p <= pix_n; p++) {
156 
157  /* Skip pixels outside of the 35 North to 35 South range. */
158  if (lat[p] > 35 || lat[p] <= -35) continue;
159 
160  /* Plate Carree projection */
161  x = (int) ((lon[p] + 180) * SCALE);
162  y = (int) ((35 - lat[p]) * SCALE);
163 
164  /* Compute the bin number for this pixel. */
165  bin = y * 36000 + x;
166 
167  /* Print out the bin number and pixel value. */
168  printf("%d %g\n", bin, data[p]);
169 
170  }
171  }
172 
173  free(lat);
174  free(lon);
175  free(data);
176 
177  if (SDend(sd_id) == FAIL) {
178  fprintf(stderr, "-W- %s line %d: SDend failed for file, %s.\n",
179  __FILE__, __LINE__, FILENAME);
180  }
181  return (EXIT_SUCCESS);
182 }
183 
184 void
186  int32 s, /* (in) scan line number */
187  int32 npix, /* (in) number of pixels per scan */
188  int32 nctl, /* (in) number of control points per scan */
189  float32 **lat, /* (out) latitude for each pixel in the scan */
190  float32 **lon /* (out) longitude for each pixel in the scan */
191  ) {
192  static float32 *lati = NULL, *longi = NULL, *latitude = NULL, *longitude = NULL;
193  static float32 *cntl_pts, *spl2nderiv;
194  static int32 np, nc;
195 
196  if (latitude == NULL) {
197  /* Execute this block of code only the 1st time this function is called. */
198  np = npix;
199  nc = nctl;
200  MALLOC(latitude, float32, nc);
201  MALLOC(longitude, float32, nc);
202  if (nc != np) {
203  /*
204  If there is not a lat/lon pair for each pixel we must interpolate.
205  Read the pixel control point indices, and then convert them to
206  floats because that is what the spline and splint functions expect.
207  */
208  int32 p, *cntl_pt_cols;
209  MALLOC(cntl_pt_cols, int32, nc);
210  READ_SDS("cntl_pt_cols", cntl_pt_cols, 0, 0, 0, nc, 0, 0);
211  MALLOC(cntl_pts, float32, nc);
212  for (p = 0; p < nc; p++) {
213  cntl_pts[p] = (float32) cntl_pt_cols[p];
214  }
215  free(cntl_pt_cols);
216  MALLOC(spl2nderiv, float32, nc);
217  MALLOC(lati, float32, np);
218  MALLOC(longi, float32, np);
219  } else {
220  /* No interpolation needed. */
221  lati = latitude;
222  longi = longitude;
223  }
224  }
225 
226  /* Read the coordinates for the specified scan. */
227  READ_SDS("latitude", latitude, s, 0, 0, 1, nc, 1);
228  READ_SDS("longitude", longitude, s, 0, 0, 1, nc, 1);
229 
230  if (nc != np) { /* Interpolation required */
231  int p;
232 
233  /* Remove any dateline discontinuity in the longitudes. */
234  for (p = 1; p < nc; p++) {
235  float delta;
236  delta = longitude[p] - longitude[p - 1];
237  if (delta < -180) longitude[p] += 360;
238  else if (delta > 180) longitude[p] -= 360;
239  }
240 
241  /*
242  Interpolate to provide a latitude and longitude for each pixel
243  in the scan. I assume here that the pixel control points stored
244  in the HDF file are one-based.
245  */
246  spline(cntl_pts, latitude, nc, 1e30, 1e30, spl2nderiv);
247  for (p = 0; p < np; p++) {
248  splint(cntl_pts, latitude, spl2nderiv, nc, p + 1, &lati[p]);
249  }
250  spline(cntl_pts, longitude, nc, 1e30, 1e30, spl2nderiv);
251  for (p = 0; p < np; p++) {
252  splint(cntl_pts, longitude, spl2nderiv, nc, p + 1, &longi[p]);
253  /* Put the longitudes back in the [-180,180] range. */
254  while (longi[p] >= 180) longi[p] -= 360;
255  while (longi[p] < -180) longi[p] += 360;
256  }
257  }
258 
259  *lat = lati;
260  *lon = longi;
261 }
#define SCALE
Definition: bindepths.c:34
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
void get_scan_coords(int32, int32, int32, float32 **, float32 **)
Definition: bindepths.c:185
real(single), dimension(:,:), allocatable longitude
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
real(single), dimension(:,:), allocatable latitude
subroutine spline(s, x, y, n, in, t, il, iu, vl, vu, e, u)
Definition: phs.f:1348
float * lat
#define MALLOC(ptr, typ, num)
Definition: bindepths.c:45
#define USAGE
Definition: bindepths.c:20
const double delta
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
subroutine splint(xa, ya, y2a, n, x, y)
float * lon
#define READ_SDS(nam, ptr, s0, s1, s2, e0, e1, e2)
Definition: bindepths.c:54
data_t s[NROOTS]
Definition: decode_rs.h:75
#define LAC_PIXEL_INSET
Definition: bindepths.c:33
#define FILENAME
Definition: bindepths.c:32
int main(int argc, char *argv[])
Definition: bindepths.c:70
int npix
Definition: get_cmp.c:27
float p[MODELMAX]
Definition: atrem_corl1.h:131
#define READ_GLBL_ATTR(nam, ptr)
Definition: bindepths.c:36