OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1_ocia.c
Go to the documentation of this file.
1 /* ============================================================================ */
2 /* module l1_ocia.c - functions to read OCIA (coastal color) for MSL12 */
3 /* Written By: Rick Healy GSFC SAIC, July, 2016. */
4 /* */
5 /* ============================================================================ */
6 
7 #include "l1.h"
8 
9 #include <netcdf.h>
10 #include <stdlib.h>
11 
12 static int16_t nline, npix;
13 
14 static int32_t spix = 0;
15 static double starttime;
16 static double *scan_start_tai, *scan_stop_tai;
17 static double time_interval;
18 static float *alt;
19 
20 int openl1_ocia(filehandle * file) {
21 
22  size_t source_w, source_h, source_b;
23  int32_t nscan;
24  int fileID, xid, yid, band_id, retval, grp_id, sds_id;
25  double stoptime;
26  size_t start[3], count[3];
27 
28  // Open the netcdf4 input file
29  retval = nc_open(file->name, NC_NOWRITE, &fileID);
30  if (retval != NC_NOERR) {
31  fprintf(stderr, "-E- %s line %d: nc_open(%s) failed.\n",
32  __FILE__, __LINE__, file->name);
33  return (1);
34  }
35 
36  // Get pixel and scan dimensions
37  retval = nc_inq_dimid(fileID, "number_of_scans", &yid);
38  retval = nc_inq_dimid(fileID, "number_of_pixels", &xid);
39  retval = nc_inq_dimid(fileID, "number_of_bands", &band_id);
40  retval = nc_inq_dimlen(fileID, xid, &source_w);
41  retval = nc_inq_dimlen(fileID, yid, &source_h);
42  retval = nc_inq_dimlen(fileID, band_id, &source_b);
43 
44  if (want_verbose) {
45  printf("OCIA L1B Npix :%d Nscans:%d\n", (int) source_w,
46  (int) source_h);
47  } // want_verbose
48  npix = (int32_t) source_w;
49  nscan = (int32_t) source_h;
50  nline = nscan;
51 
52  file->sd_id = fileID;
53  file->npix = npix;
54  file->nscan = nscan;
55  file->nbands = source_b;
56  strcpy(file->spatialResolution, "750 m");
57 
58  scan_start_tai = (double *) calloc(nscan, sizeof (double));
59  scan_stop_tai = (double *) calloc(nscan, sizeof (double));
60  alt = (float *) calloc(nscan, sizeof (float));
61 
62  start[0] = 0;
63  start[1] = 0;
64  start[2] = 0;
65  count[0] = nscan;
66  count[1] = 0;
67  count[2] = 0;
68 
69  nc_inq_ncid(file->sd_id, "scan_line_attributes", &grp_id);
70 
71  retval = nc_inq_varid(grp_id, "altitude", &sds_id);
72  retval = nc_get_vara_float(grp_id, sds_id, start, count, alt);
73  if (retval != NC_NOERR) {
74  fprintf(stderr,
75  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
76  __FILE__, __LINE__, file->name, "altitude");
77  return (1);
78  }
79 
80  retval = nc_inq_varid(grp_id, "scan_start_time", &sds_id);
81  retval = nc_get_vara_double(grp_id, sds_id, start, count, scan_start_tai);
82  if (retval != NC_NOERR) {
83  fprintf(stderr,
84  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
85  __FILE__, __LINE__, file->name, "scan_start_time");
86  return (1);
87  }
88 
89  int iscan = 0, i1, i2;
90  starttime = 9999;
91  while (iscan < nscan) {
92  if (scan_start_tai[iscan] > 0) {
93  if (starttime > scan_start_tai[iscan])starttime = scan_start_tai[iscan];
94  }
95  iscan++;
96  }
97  i1 = iscan;
98 
99  //starttime = scan_start_tai[0];
100 
101  // nc_inq_varid(grp_id,"scan_end_time",&sds_id);
102  // nc_get_vara_double(grp_id, sds_id, start, count, scan_stop_tai);
103  iscan = nscan - 1;
104  stoptime = -9999;
105  while (iscan > 0) {
106  if (scan_start_tai[iscan] > 0) {
107  if (stoptime < scan_start_tai[iscan])stoptime = scan_start_tai[iscan];
108  }
109  iscan--;
110  }
111  i2 = iscan;
112  //stoptime = scan_start_tai[nscan];
113 
114  time_interval = (stoptime - starttime) / ((i2 - i1) + 1); /* in sec */
115 
116  /*
117  retval = navigation_meris(fileID);
118  */
119  start[0] = 0;
120  count[0] = source_b;
121  return (LIFE_IS_GOOD);
122 }
123 
124 int readl1_ocia(filehandle *file, int32_t scan, l1str *l1rec) {
125  static int firstCall = 1;
126  int retval;
127  float *lon, *lat, *senz, *sena, *solz, *sola;
128 
129  int32_t ip, ib, ipb, Ibp;
130  int32_t nbands = l1rec->l1file->nbands;
131  size_t start[3], count[3];
132  int band_id, grp_id;
133  float *rad_data;
134 
135  if (firstCall) {
136  if (want_verbose)
137  printf("file->nbands = %d, l1rec->nbands = %d\n",
138  (int) file->nbands, (int) l1rec->l1file->nbands);
139  firstCall = 0;
140 
141  for (ip = 0; ip < npix; ip++) {
142  l1rec->pixnum[ip] = ip;
143  l1rec->flags[ip] = 0;
144  }
145 
146  }
147 
148 
149  // set time for this scan - if scan_start_time value not properly set, estimate from scene start time.
150  // printf("RJH: scan_start_tai=%f\n",scan_start_tai[scan]);
151  // if (scan_start_tai[scan] > 0){
152  // lastvalidtime = scan_start_tai[scan]+tai2unixoffset;
153  // lastvalidscan = scan;
154  // unix2yds(lastvalidtime, &scan_year, &scan_day, &msec);
155  // } else {
156  // unix2yds(lastvalidtime+(time_interval * (scan-lastvalidscan)),&scan_year,&scan_day, &msec);
157  // }
158  // msec -= leapseconds_since_1993(lastvalidtime-tai2unixoffset)*1000;
159  // l1rec->scantime = yds2unix(scan_year, scan_day, (double) (msec / 1.e3));
160  l1rec->scantime = scan_start_tai[scan];
161 
162  retval = nc_inq_ncid(file->sd_id, "geolocation_data", &grp_id);
163  if (retval != NC_NOERR) {
164  fprintf(stderr,
165  "-E- %s line %d: nc_inq_ncid failed for file, %s group, %s.\n",
166  __FILE__, __LINE__, file->name, "geolocation_data");
167  return (1);
168  }
169 
170  start[0] = scan;
171  start[1] = 0;
172  start[2] = 0;
173  count[0] = 1;
174  count[1] = npix;
175  count[2] = 0;
176 
177  lon = (float *) calloc(npix, sizeof (float));
178  lat = (float *) calloc(npix, sizeof (float));
179  senz = (float *) calloc(npix, sizeof (float));
180  sena = (float *) calloc(npix, sizeof (float));
181  solz = (float *) calloc(npix, sizeof (float));
182  sola = (float *) calloc(npix, sizeof (float));
183 
184  retval = nc_inq_varid(grp_id, "longitude", &band_id);
185  if (retval != NC_NOERR) {
186  fprintf(stderr,
187  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
188  __FILE__, __LINE__, file->name, "longitude");
189  return (1);
190  }
191  retval = nc_get_vara_float(grp_id, band_id, start, count, lon);
192  if (retval != NC_NOERR) {
193  fprintf(stderr,
194  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
195  __FILE__, __LINE__, file->name, "longitude");
196  return (1);
197  }
198  retval = nc_inq_varid(grp_id, "latitude", &band_id);
199  if (retval != NC_NOERR) {
200  fprintf(stderr,
201  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
202  __FILE__, __LINE__, file->name, "latitude");
203  return (1);
204  }
205  retval = nc_get_vara_float(grp_id, band_id, start, count, lat);
206  if (retval != NC_NOERR) {
207  fprintf(stderr,
208  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
209  __FILE__, __LINE__, file->name, "latitude");
210  return (1);
211  }
212  //until geolocation is read, set fill values -
213  for (ip = spix; ip < npix; ip++) {
214  l1rec->lon[ip] = lon[ip];
215  l1rec->lat[ip] = lat[ip];
216  l1rec->solz[ip] = -999; //solz[scan * npix + ip];
217  l1rec->sola[ip] = -999; //sola[scan * npix + ip];
218  l1rec->senz[ip] = -999; //senz[scan * npix + ip];
219  l1rec->sena[ip] = -999; //sena[scan * npix + ip];
220  }
221 
222  retval = nc_inq_varid(grp_id, "sensor_azimuth", &band_id);
223  retval = nc_get_vara_float(grp_id, band_id, start, count, sena);
224  if (retval != NC_NOERR) {
225  fprintf(stderr,
226  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
227  __FILE__, __LINE__, file->name, "sensor_azimuth");
228  return (1);
229  }
230  retval = nc_inq_varid(grp_id, "sensor_zenith", &band_id);
231  retval = nc_get_vara_float(grp_id, band_id, start, count, senz);
232  if (retval != NC_NOERR) {
233  fprintf(stderr,
234  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
235  __FILE__, __LINE__, file->name, "sensor_zenith");
236  return (1);
237  }
238  retval = nc_inq_varid(grp_id, "solar_azimuth", &band_id);
239  retval = nc_get_vara_float(grp_id, band_id, start, count, sola);
240  if (retval != NC_NOERR) {
241  fprintf(stderr,
242  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
243  __FILE__, __LINE__, file->name, "solar_azimuth");
244  return (1);
245  }
246  retval = nc_inq_varid(grp_id, "solar_zenith", &band_id);
247  retval = nc_get_vara_float(grp_id, band_id, start, count, solz);
248  if (retval != NC_NOERR) {
249  fprintf(stderr,
250  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
251  __FILE__, __LINE__, file->name, "solar_zenith");
252  return (1);
253  }
254 
255  for (ip = spix; ip < npix; ip++) {
256  l1rec->lon[ip] = lon[ip];
257  l1rec->lat[ip] = lat[ip];
258  l1rec->solz[ip] = solz[ip];
259  l1rec->sola[ip] = sola[ip];
260  l1rec->senz[ip] = senz[ip];
261  l1rec->sena[ip] = sena[ip];
262  }
263 
264  // read in radiance data
265  rad_data = (float *) calloc(npix*nbands, sizeof (float));
266 
267  start[0] = 0;
268  start[1] = scan;
269  start[2] = 0;
270  count[0] = nbands;
271  count[1] = 1;
272  count[2] = npix;
273 
274  nc_inq_ncid(file->sd_id, "observation_data", &grp_id);
275 
276  retval = nc_inq_varid(grp_id, "Lt", &band_id);
277  retval = nc_get_vara_float(grp_id, band_id, start, count, rad_data);
278  if (retval != NC_NOERR) {
279  fprintf(stderr,
280  "-E- %s line %d: nc_get_vara_float failed for file, %s field, %s.\n",
281  __FILE__, __LINE__, file->name, "Lt_visnir");
282  return (1);
283  }
284 
285  for (ib = 0; ib < nbands; ib++) {
286 
287  // copy to Lt record.
288  for (ip = spix; ip < npix; ip++) {
289  ipb = ip * nbands + ib;
290  Ibp = ib * npix + ip;
291  l1rec->Lt[ipb] = rad_data[Ibp];
292 
293  // mark negative input data as HILT
294  // navfail commented out for Lt < 0 - too limiting for hyperspectral - RJH
295  if (l1rec->Lt[ipb] < 0.0) {
296  l1rec->Lt[ipb] = 0.0001;
297  // l1rec->navfail[ip] = 1;
298  }
299  }
300  } // for ib
301 
302  l1rec->alt = alt[scan] / 1000.; //convert to km
303 
304  free(rad_data);
305  free(lat);
306  free(lon);
307  free(solz);
308  free(sola);
309  free(senz);
310  free(sena);
311 
312  l1rec->l1file->sensorID = file->sensorID;
313  l1rec->npix = file->npix;
314 
315  return (LIFE_IS_GOOD);
316 }
317 
318 int closel1_ocia(filehandle *file) {
319  int retval;
320 
321  retval = nc_close(file->sd_id);
322  if (retval != NC_NOERR) {
323  fprintf(stderr, "-E- %s line %d: nc_close failed for file, %s.\n",
324  __FILE__, __LINE__, file->name);
325  return (1);
326  }
327  free(scan_start_tai);
328 
329  return (LIFE_IS_GOOD);
330 }
331 
int readl1_ocia(filehandle *file, int32_t scan, l1str *l1rec)
Definition: l1_ocia.c:124
int16_t fileID
int closel1_ocia(filehandle *file)
Definition: l1_ocia.c:318
MOD_PR01 Production producing one five minute granule of output data in each run It can be configured to produce as many as three five minute granules per run Each execution with one construction record and one date file for each dataset In normal these are created by which splits them out of the hour datasets For LANCE they are created by which merges all session MODIS L0 datasets overlapping the requested time and extracts from the merged data those packets which fall within that time period Each scan of data is stored in the L1A granule that covers the start time of that scan
Definition: MOD_PR01_pr.txt:19
read l1rec
float * lat
int32 nscan
Definition: l1_czcs_hdf.c:19
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
int want_verbose
int32_t nbands
int32 spix
Definition: l1_czcs_hdf.c:21
int32_t iscan
float * lon
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int npix
Definition: get_cmp.c:27
int openl1_ocia(filehandle *file)
Definition: l1_ocia.c:20
int count
Definition: decode_rs.h:79