OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
readL2scan.c
Go to the documentation of this file.
1 /*
2  Modification history:
3  Programmer Organization Date Description of change
4  -------------- ------------ -------- ---------------------
5  Joel Gales Futuretech 01/31/00 Original Development
6  Bryan Franz GSC 03/01/00 Add reading of LAC
7  pix start & subsamp to
8  readL2meta
9  Joel Gales Futuretech 03/03/00 Change nflag in l2_str
10  from byte to int32
11  Fix allocation
12  problem with prodlist
13 
14  Joel Gales Futuretech 03/14/00 Add "getL3units" routine
15 
16  Joel Gales Futuretech 05/25/00 Fix isalpha (Linux) bug
17  Joel Gales Futuretech 06/14/00 Fix case where there are
18  no L2 products (flags only)
19  Joel Gales Futuretech 06/15/00 Fix units problem for flag
20  products
21  Joel Gales Futuretech 06/20/00 Add read support for FLOAT32
22  data products
23  Ewa Kwiatkowska SAIC 07/28/04 Made prodtype file-dependent
24  what enables reading L2 files
25  from different sensors
26  Joel Gales Futuretech 08/26/07 Increase buffer in openL2 to
27  read "Processing_Control"
28  attribute.
29  Do not read "eng_qual",
30  "s_flags", "nflag" fields if
31  they do not exist
32  Joel Gales Futuretech 08/31/09 Check scaled value for bad
33  value.
34  Set to NaN if bad.
35  Implemented for INT16 only.
36 
37  Joel Gales Futuretech 03/14/11 Add n_cntl_pnts readjustment
38  for bad latitude control pnts
39 
40  Joel Gales Futuretech 07/30/12 Only allocate data products
41  cache at beginning or if
42  number of data products
43  increased.
44  Joel Gales Futuretech 06/14/13 Add support for NETCDF4
45  Joel Gales Futuretech 07/23/13 Fix incomplete idDS structure
46  for pixnum, eng_qual, s_flags,
47  nflag.
48 
49  Joel Gales Futuretech 02/11/14 Clear bufnum buffer in
50  getL3units before reading
51  units attribute
52  */
53 
54 #include <stdlib.h>
55 #include <stdio.h>
56 #include <ctype.h>
57 #include <time.h>
58 #include <netcdf.h>
59 #include <genutils.h>
60 #include "readL2scan.h"
61 #include "navigation.h"
62 #include <sensorInfo.h>
63 #include <timeutils.h>
64 #include <nc4utils.h>
65 
66 #include <hdf.h>
67 #include <mfhdf.h>
68 
69 
70 #define TITLE "title"
71 #define TITLE_OLD "Title"
72 #define INFILES "input_sources"
73 #define INFILES_OLD "Input Files"
74 #define SENNME "instrument"
75 #define SENNME_OLD "Sensor Name"
76 #define DCENTER "project"
77 #define DCENTER_OLD "Data Center"
78 #define NFREC "Filled Scan Lines"
79 #define PCTFLAG "flag_percentages"
80 #define PCTFLAG_OLD "Flag Percentages"
81 #define NTIME "equatorCrossingDateTime"
82 #define NTIME_OLD "Node Crossing Time"
83 #define SNODE "startDirection"
84 #define SNODE_OLD "Start Node"
85 #define ENODE "endDirection"
86 #define ENODE_OLD "End Node"
87 #define MISSION "platform"
88 #define MISSION_OLD "Mission"
89 #define MSNCHAR "Mission Characteristics"
90 #define SENSOR "Sensor"
91 #define SNSCHAR "Sensor Characteristics"
92 #define ORBNUM "orbit_number"
93 #define ORBNUM_OLD "Orbit Number"
94 #define NLAT "northernmost_latitude"
95 #define NLAT_OLD "Northernmost Latitude"
96 #define SLAT "southernmost_latitude"
97 #define SLAT_OLD "Southernmost Latitude"
98 #define WLON "westernmost_longitude"
99 #define WLON_OLD "Westernmost Longitude"
100 #define ELON "easternmost_longitude"
101 #define ELON_OLD "Easternmost Longitude"
102 #define STCLAT "start_center_latitude"
103 #define STCLAT_OLD "Start Center Latitude"
104 #define STCLON "start_center_longitude"
105 #define STCLON_OLD "Start Center Longitude"
106 #define ENDCLAT "end_center_latitude"
107 #define ENDCLAT_OLD "End Center Latitude"
108 #define ENDCLON "end_center_longitude"
109 #define ENDCLON_OLD "End Center Longitude"
110 #define NODEL "equatorCrossingLongitude"
111 #define NODEL_OLD "Orbit Node Longitude"
112 #define LAC_PX_ST "LAC Pixel Start Number"
113 #define LAC_PX_SUBSAMP "LAC Pixel Subsampling"
114 
115 typedef struct cache_struct {
116  int32_t bscan;
117  int32_t escan;
118  int32_t dataSize;
119  void* data;
120 } cache_str;
121 
122 // #define NON_CACHED 1
123 
124 
125 static int32_t n_files_open = 0;
126 
127 typedef idDS ds_id_prod_t[1000];
128 static ds_id_prod_t *ds_id_prod;
129 
130 typedef int32_t prodtype_t[1000];
131 static prodtype_t *prodtype;
132 
133 typedef float slope_t[1000];
134 static slope_t *slope;
135 static slope_t *intercept;
136 
137 typedef idDS ds_id_ll_t[3];
138 static ds_id_ll_t *ds_id_ll;
139 static ds_id_ll_t *ds_id_date;
140 
141 typedef idDS ds_id_geonav_t[6];
142 static ds_id_geonav_t *ds_id_geonav;
143 
144 typedef int32_t grp_id_t[6];
145 static grp_id_t *grp_id;
146 
147 static idDS *ds_id_l2_flags;
148 static idDS *ds_id_eng_qual;
149 static idDS *ds_id_s_flags;
150 static idDS *ds_id_nflag;
151 static idDS *ds_id_pixnum;
152 static idDS *ds_id_file;
153 static idDS *ds_id_wave;
154 
155 static int32_t *nsta;
156 static int32_t *ninc;
157 
158 static int databufSize = 0;
159 static unsigned char *databuf = NULL;
160 static char **prodlist;
161 
162 static int32_t n_cntl_pnts;
163 static int32_t prev_n_cntl_pnts = -1;
164 
165 static float geonav[6][9];
166 
167 static int32_t one = 1;
168 static int32_t zero32 = 0;
169 static int32_t l2_flags_type;
170 
171 static int32_t bandsPerPixel = 1;
172 
173 static cache_str cache_l2_flags;
174 static cache_str cache_eng_qual;
175 static cache_str cache_s_flags;
176 static cache_str cache_nflag;
177 static cache_str cache_pixnum;
178 static cache_str cache_longitude;
179 static cache_str cache_latitude;
180 static int32_t cache_nprod;
181 static cache_str **cache_l2_data;
182 
184  enum L2PixelMode_t mode; // 0=off, 1=pixel corners, 2=pixel deltas
185  int32_t lastLine; // if -1 the last line does not have good lat/lon
186 
187  int32_t nsamp;
188  float* lastLat;
189  float* lastLon;
190 };
191 static struct pixelAreaInfo_t pixelAreaInfo;
192 
194  pixelAreaInfo.mode = val;
195  pixelAreaInfo.lastLine = -1;
196 
197  pixelAreaInfo.nsamp = 0;
198  if(pixelAreaInfo.lastLat) {
199  free(pixelAreaInfo.lastLat);
200  free(pixelAreaInfo.lastLon);
201  }
202  pixelAreaInfo.lastLat = NULL;
203  pixelAreaInfo.lastLon = NULL;
204 }
205 
211 int32_t get_dtype(int32_t dtype, ds_format_t fileformat) {
212 
213  if (fileformat == DS_NCDF) {
214  if (dtype == DFNT_INT8)
215  dtype = NC_BYTE;
216  else if (dtype == DFNT_UINT8)
217  dtype = NC_UBYTE;
218  else if (dtype == DFNT_INT16)
219  dtype = NC_SHORT;
220  else if (dtype == DFNT_UINT16)
221  dtype = NC_USHORT;
222  else if (dtype == DFNT_INT32)
223  dtype = NC_INT;
224  else if (dtype == DFNT_UINT32)
225  dtype = NC_UINT;
226  else if (dtype == DFNT_FLOAT32)
227  dtype = NC_FLOAT;
228  else if (dtype == DFNT_FLOAT64)
229  dtype = NC_DOUBLE;
230  }
231  return dtype;
232 }
233 //----------------------------------------------------------------
234 // free cache
235 
237  int i;
238 
239  cache_l2_flags.bscan = -1;
240  cache_eng_qual.bscan = -1;
241  cache_s_flags.bscan = -1;
242  cache_nflag.bscan = -1;
243  cache_pixnum.bscan = -1;
244  cache_longitude.bscan = -1;
245  cache_latitude.bscan = -1;
246 
247  cache_l2_flags.escan = -1;
248  cache_eng_qual.escan = -1;
249  cache_s_flags.escan = -1;
250  cache_nflag.escan = -1;
251  cache_pixnum.escan = -1;
252  cache_longitude.escan = -1;
253  cache_latitude.escan = -1;
254 
255  for (i = 0; i < cache_nprod; i++) {
256  cache_l2_data[i]->bscan = -1;
257  cache_l2_data[i]->escan = -1;
258  }
259 }
260 
261 
262 /* init the cache structures */
263 
264 /* -------------------------- */
266  cache_str tmp_cache;
267 
268  tmp_cache.bscan = -1;
269  tmp_cache.escan = -1;
270  tmp_cache.dataSize = 0;
271  tmp_cache.data = NULL;
272 
273  cache_l2_flags = tmp_cache;
274  cache_eng_qual = tmp_cache;
275  cache_s_flags = tmp_cache;
276  cache_nflag = tmp_cache;
277  cache_pixnum = tmp_cache;
278  cache_longitude = tmp_cache;
279  cache_latitude = tmp_cache;
280 }
281 
282 
283 void allocateDatabuf(l2_prod *l2_str, int maxThirdDim) {
284  int newSize = l2_str->nsamp * maxThirdDim * 8;
285  if(databufSize < newSize) {
286  if(databuf)
287  free(databuf);
288  databufSize = newSize;
289  databuf = (unsigned char *) malloc(databufSize);
290  }
291 }
292 
293 
294 //----------------------------------------------------------------
295 
296 int32_t openL2(const char *fname, char *plist, l2_prod *l2_str) {
297  int32_t i;
298  int32_t sds_id;
299  int32_t len;
300  int32_t dims[8];
301  int32_t n_l2flags;
302  int32_t tilt_start[2] = {0, 0};
303  int32_t tilt_edges[2] = {20, 2};
304  int16_t t_ranges[2 * 20];
305  int status;
306  int32_t listlen = 0;
307  int32_t fileindex;
308  idDS ds_id;
309  int dim_id;
310  size_t tmpSizet;
311 
312  char buffer[2048 * 8];
313  char *tmpStr;
314  char *numstr[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10",
315  "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
316  "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
317  "31", "32", "33"};
318 
319  static int32_t first = 1;
320 
321  ds_format_t fileformat;
322 
323  if (Hishdf(fname) == 1) {
324  fileformat = DS_HDF;
325  } else {
326  fileformat = DS_NCDF;
327  }
328 
329  /* Copy filename and product list into L2 structure */
330  /* ------------------------------------------------ */
331  if (l2_str->nrec == 0) {
332  strcpy(l2_str->filename, fname);
333  n_files_open++;
334  fileindex = n_files_open - 1;
335  l2_str->fileindex = fileindex;
336  } else {
337  fileindex = l2_str->fileindex;
338  }
339 
340  if (first) {
341  ds_id_prod = (ds_id_prod_t*) allocateMemory(MAXNFILES * sizeof (ds_id_prod_t), "ds_id_prod");
342  prodtype = (prodtype_t*) allocateMemory(MAXNFILES * sizeof (prodtype_t), "prodtype");
343  slope = (slope_t*) allocateMemory(MAXNFILES * sizeof (slope_t), "slope");
344  intercept = (slope_t*) allocateMemory(MAXNFILES * sizeof (slope_t), "intercept");
345  ds_id_ll = (ds_id_ll_t*) allocateMemory(MAXNFILES * sizeof (ds_id_ll_t), "ds_id_ll");
346  ds_id_date = (ds_id_ll_t*) allocateMemory(MAXNFILES * sizeof (ds_id_ll_t), "ds_id_date");
347  ds_id_geonav = (ds_id_geonav_t*) allocateMemory(MAXNFILES * sizeof (ds_id_geonav_t), "ds_id_geonav");
348  grp_id = (grp_id_t*) allocateMemory(MAXNFILES * sizeof (grp_id_t), "grp_id");
349 
350  ds_id_l2_flags = (idDS*) allocateMemory(MAXNFILES * sizeof (idDS), "ds_id_l2_flags");
351  ds_id_eng_qual = (idDS*) allocateMemory(MAXNFILES * sizeof (idDS), "ds_id_eng_qual");
352  ds_id_s_flags = (idDS*) allocateMemory(MAXNFILES * sizeof (idDS), "ds_id_s_flags");
353  ds_id_nflag = (idDS*) allocateMemory(MAXNFILES * sizeof (idDS), "ds_id_nflag");
354  ds_id_pixnum = (idDS*) allocateMemory(MAXNFILES * sizeof (idDS), "ds_id_pixnum");
355  ds_id_file = (idDS*) allocateMemory(MAXNFILES * sizeof (idDS), "ds_id_file");
356  ds_id_wave = (idDS*) allocateMemory(MAXNFILES * sizeof (idDS), "ds_id_wave");
357 
358  nsta = (int32_t*) allocateMemory(MAXNFILES * sizeof (int32_t), "nsta");
359  ninc = (int32_t*) allocateMemory(MAXNFILES * sizeof (int32_t), "ninc");
360 
361  prodlist = (char **) allocateMemory(MAXNFILES * sizeof (char *), "prodlist");
362 
363  for (i = 0; i < MAXNFILES; i++) prodlist[i] = NULL;
364  }
365 
366  /* Generate prodlist */
367  /* ----------------- */
368  if (plist != 0x0) {
369  prodlist[fileindex] = (char *) calloc(strlen(plist) + 1, sizeof (char));
370  strcpy(prodlist[fileindex], plist);
371  } else {
372  getProdlist(fname, &prodlist[fileindex], &l2_flags_type);
373  }
374 
375 
376  /* Parse Product list */
377  /* ------------------ */
378  l2_str->nprod = 1;
379  l2_str->prodname[0] = &prodlist[fileindex][0];
380  len = strlen(prodlist[fileindex]);
381  for (i = 0; i < len; i++) {
382  if (prodlist[fileindex][i] == ':') {
383  l2_str->prodname[l2_str->nprod] = prodlist[fileindex] + i + 1;
384  l2_str->nprod++;
385  prodlist[fileindex][i] = 0;
386  }
387  }
388  /* No L2 products in L2 file (flags only) */
389  if (strlen(prodlist[fileindex]) == 0) l2_str->nprod = 0;
390  /* Start DS interface */
391  /* ------------------ */
392  ds_id = startDS(l2_str->filename, fileformat, DS_READ, 0);
393 
394  ds_id_file[fileindex] = ds_id;
395 
396  if (fileformat == DS_NCDF) {
397  nc_inq_ncid(ds_id.fid, "sensor_band_parameters", &grp_id[fileindex][0]);
398  nc_inq_ncid(ds_id.fid, "sensor_tilt", &grp_id[fileindex][1]);
399  nc_inq_ncid(ds_id.fid, "scan_line_attributes", &grp_id[fileindex][2]);
400  nc_inq_ncid(ds_id.fid, "geophysical_data", &grp_id[fileindex][3]);
401  nc_inq_ncid(ds_id.fid, "navigation_data", &grp_id[fileindex][4]);
402  nc_inq_ncid(ds_id.fid, "processing_control", &grp_id[fileindex][5]);
403  }
404 
405  /* Get # of scans and # of pixels */
406  /* ------------------------------ */
407  if (fileformat == DS_NCDF) {
408  status = nc_inq_dimid(ds_id.fid, "number_of_lines", &dim_id);
409  if (status) {
410  status = nc_inq_dimid(ds_id.fid, "Number_of_Scan_Lines", &dim_id);
411  if(status) {
412  printf("-E- %s:%d - openL2 - could not find number_of_lines.\n",
413  __FILE__, __LINE__);
414  exit(EXIT_FAILURE);
415  }
416  }
417  nc_inq_dimlen(ds_id.fid, dim_id, &tmpSizet);
418  l2_str->nrec = tmpSizet;
419  status = nc_inq_dimid(ds_id.fid, "pixels_per_line", &dim_id);
420  if (status) {
421  status = nc_inq_dimid(ds_id.fid, "Pixels_per_Scan_Line", &dim_id);
422  if(status) {
423  printf("-E- %s:%d - openL2 - could not find pixels_per_line.\n",
424  __FILE__, __LINE__);
425  exit(EXIT_FAILURE);
426  }
427  }
428  nc_inq_dimlen(ds_id.fid, dim_id, &tmpSizet);
429  l2_str->nsamp = tmpSizet;
430 
431  status = nc_inq_dimid(ds_id.fid, "bands_per_pixel", &dim_id);
432  if (status == 0) {
433  nc_inq_dimlen(ds_id.fid, dim_id, &tmpSizet);
434  bandsPerPixel = tmpSizet;
435  }
436  l2_str->bandsPerPixel = bandsPerPixel;
437 
438  } else {
439  readAttr(ds_id, "Number of Scan Lines", (void*) & l2_str->nrec);
440  readAttr(ds_id, "Pixels per Scan Line", (void*) & l2_str->nsamp);
441  }
442 
443  /* Get start & end times, orbit number and data type */
444  /* ------------------------------------------------- */
445  if (fileformat == DS_NCDF) {
446  int32_t yr, dy, sc;
447  status = readAttr(ds_id, "orbit_number", (void*) & l2_str->orbit);
448  // not checking the return status here as there are real live cases of
449  // orbit number NOT existing in the L2 metadata (e.g. GOCI)
450 
451  tmpStr = readAttrStr(ds_id, "time_coverage_start");
452  if(!tmpStr) {
453  printf("-E- %s:%d - openL2 - could not find time_coverage_start.\n",
454  __FILE__, __LINE__);
455  exit(EXIT_FAILURE);
456  }
457  isodate2ydmsec(tmpStr, &yr, &dy, &sc);
458  free(tmpStr);
459 
460  l2_str->syear = (int16_t) yr;
461  l2_str->sday = (int16_t) dy;
462  l2_str->smsec = sc;
463  // l2_str->smsec = 1000 * ((int32_t) scs);
464 
465  tmpStr = readAttrStr(ds_id, "time_coverage_end");
466  if(!tmpStr) {
467  printf("-E- %s:%d - openL2 - could not find time_coverage_end.\n",
468  __FILE__, __LINE__);
469  exit(EXIT_FAILURE);
470  }
471  isodate2ydmsec(tmpStr, &yr, &dy, &sc);
472  free(tmpStr);
473 
474  l2_str->eyear = (int16_t) yr;
475  l2_str->eday = (int16_t) dy;
476  // l2_str->emsec = 1000 * ((int32_t) scs);
477  l2_str->emsec = sc;
478  } else {
479  readAttr(ds_id, "Start Year", (void*) & l2_str->syear);
480  readAttr(ds_id, "Start Day", (void*) & l2_str->sday);
481  readAttr(ds_id, "Start Millisec", (void*) & l2_str->smsec);
482  readAttr(ds_id, "End Year", (void*) & l2_str->eyear);
483  readAttr(ds_id, "End Day", (void*) & l2_str->eday);
484  readAttr(ds_id, "End Millisec", (void*) & l2_str->emsec);
485  readAttr(ds_id, "Orbit Number", (void*) & l2_str->orbit);
486  readAttr(ds_id, "Data Type", (void*) & l2_str->dtype);
487  }
488 
489  /* Allocate geoloc (lon/lat) arrays */
490  /* -------------------------------- */
491  l2_str->latitude = (float *) calloc(l2_str->nsamp, sizeof (float));
492  l2_str->longitude = (float *) calloc(l2_str->nsamp, sizeof (float));
493  if(pixelAreaInfo.mode != L2PixelOff) {
494  l2_str->lat1 = (float *) malloc((l2_str->nsamp+1) * sizeof (float));
495  l2_str->lon1 = (float *) malloc((l2_str->nsamp+1) * sizeof (float));
496  if(pixelAreaInfo.mode == L2PixelCorner) {
497  l2_str->lat2 = (float *) malloc((l2_str->nsamp+1) * sizeof (float));
498  l2_str->lon2 = (float *) malloc((l2_str->nsamp+1) * sizeof (float));
499  }
500  }
501 
502  /* Get longitude, latitude, & date sds ids */
503  /* --------------------------------------- */
504  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][4];
505  ds_id_ll[fileindex][0] = (idDS){ds_id.fid,
506  selectDS(ds_id, "longitude"),
507  ds_id.fftype};
508  ds_id_ll[fileindex][1] = (idDS){ds_id.fid,
509  selectDS(ds_id, "latitude"),
510  ds_id.fftype};
511  ds_id_ll[fileindex][2] = (idDS){ds_id.fid, -1, ds_id.fftype};
512 
513  getDimsDS(ds_id, "longitude", dims);
514 
515  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][2];
516  ds_id_date[fileindex][0] = (idDS){ds_id.fid,
517  selectDS(ds_id, "year"),
518  ds_id.fftype};
519  ds_id_date[fileindex][1] = (idDS){ds_id.fid,
520  selectDS(ds_id, "day"),
521  ds_id.fftype};
522  ds_id_date[fileindex][2] = (idDS){ds_id.fid,
523  selectDS(ds_id, "msec"),
524  ds_id.fftype};
525 
526  l2_str->geointerp = 0;
527 
528  // Read wavelength field
529  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][0];
530  ds_id_wave[fileindex] = (idDS){ds_id.fid,
531  selectDS(ds_id, "wavelength"),
532  ds_id.fftype};
533  if (ds_id_wave[fileindex].sid != -1) {
534  readDS(ds_id_wave[fileindex], "wavelength", &zero32, NULL,
535  &bandsPerPixel, l2_str->wavelength);
536  endaccessDS(ds_id_wave[fileindex]);
537  }
538 
539  /* Test if full-size lon/lat SDS */
540  /* ----------------------------- */
541  if (dims[0] != l2_str->nrec || dims[1] != l2_str->nsamp ||
542  ds_id_ll[fileindex][0].sid == -1) {
543 
544  l2_str->geointerp = 1;
545 
546  /* Test for geonav arrays (SeaWIFS) */
547  /* -------------------------------- */
548  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][4];
549  ds_id_geonav[fileindex][0] = (idDS){ds_id.fid,
550  selectDS(ds_id, "orb_vec"),
551  ds_id.fftype};
552  ds_id_geonav[fileindex][1] = (idDS){ds_id.fid,
553  selectDS(ds_id, "sen_mat"),
554  ds_id.fftype};
555  ds_id_geonav[fileindex][2] = (idDS){ds_id.fid,
556  selectDS(ds_id, "scan_ell"),
557  ds_id.fftype};
558  ds_id_geonav[fileindex][3] = (idDS){ds_id.fid,
559  selectDS(ds_id, "sun_ref"),
560  ds_id.fftype};
561  // ds_sid_geonav[fileindex][4] = selectDS(ds_id, "l_vert");
562  ds_id_geonav[fileindex][4].sid = -1;
563  ds_id_geonav[fileindex][5] = (idDS){ds_id.fid,
564  selectDS(ds_id, "att_ang"),
565  ds_id.fftype};
566 
567  ds_id = ds_id_file[fileindex];
568  nsta[fileindex] = -1;
569  ninc[fileindex] = -1;
570  readAttr(ds_id_file[fileindex], "LAC Pixel Start Number",
571  (void*) & nsta[fileindex]);
572  readAttr(ds_id_file[fileindex], "LAC Pixel Subsampling",
573  (void*) & ninc[fileindex]);
574 
575  if (ds_id_geonav[fileindex][0].sid != -1 &&
576  ds_id_geonav[fileindex][1].sid != -1 &&
577  ds_id_geonav[fileindex][2].sid != -1 &&
578  ds_id_geonav[fileindex][3].sid != -1 &&
579  nsta[fileindex] != -1 && ninc[fileindex] != -1) {
580 
581  l2_str->geointerp = 2;
582 
583  for (i = 0; i < 6; i++) l2_str->geonav[i] = geonav[i];
584  } else {
585 
586  /* Get # of control points */
587  /* ----------------------- */
588  if (fileformat == DS_NCDF) {
589  status = nc_inq_dimid(ds_id_file[fileindex].fid, "pixel_control_points", &dim_id);
590  if (status) {
591  printf("-E- %s:%d - openL2 - Could not find the dimension pixel_control_points.\n",
592  __FILE__, __LINE__);
593  exit(EXIT_FAILURE);
594  }
595  status = nc_inq_dimlen(ds_id_file[fileindex].fid, dim_id, &tmpSizet);
596  if (status) {
597  printf("-E- %s:%d - openL2 - Could not read the dimension pixel_control_points\n",
598  __FILE__, __LINE__);
599  exit(EXIT_FAILURE);
600  }
601  n_cntl_pnts = tmpSizet;
602  } else
603  readAttr(ds_id_file[fileindex], "Number of Pixel Control Points",
604  (void*) & n_cntl_pnts);
605 
606  /* Check that all L2 files have same number of control points */
607  /* ---------------------------------------------------------- */
608  if (prev_n_cntl_pnts != -1 && prev_n_cntl_pnts != n_cntl_pnts) {
609  printf("L2 file #:%4d has %d control points.\n", fileindex,
610  prev_n_cntl_pnts);
611  printf("L2 file #:%4d has %d control points.\n", fileindex + 1,
612  n_cntl_pnts);
613  printf("These must be identical.\n");
614  exit(-1);
615  }
616  prev_n_cntl_pnts = n_cntl_pnts;
617 
618 
619  /* Allocate arrays needed for lon/lat interpolation */
620  /* ------------------------------------------------ */
621  l2_str->lon_cntl = (float *) calloc(n_cntl_pnts, sizeof (float));
622  l2_str->lat_cntl = (float *) calloc(n_cntl_pnts, sizeof (float));
623  l2_str->cntl_pnts = (float *) calloc(n_cntl_pnts, sizeof (float));
624  l2_str->cntl_pnts_cache = (float *) calloc(n_cntl_pnts, sizeof (float));
625  l2_str->spline_arr = (float *) calloc(n_cntl_pnts, sizeof (float));
626 
627  /* Get control point sds id */
628  /* ------------------------ */
629  ds_id_ll[fileindex][2].sid = selectDS(ds_id, "cntl_pt_cols");
630 
631  /* Read control points array if first time through */
632  /* ----------------------------------------------- */
633  int32_t *tmpPtr = (int32_t*) l2_str->cntl_pnts;
634  readDS(ds_id_ll[fileindex][2], "cntl_pt_cols",
635  &zero32, NULL, &n_cntl_pnts, tmpPtr);
636  endaccessDS(ds_id);
637  ds_id_ll[fileindex][2].sid = -1;
638 
639  /* Convert cntl pnts from I32 to F32 */
640  /* --------------------------------- */
641  for (i = 0; i < n_cntl_pnts; i++) {
642  l2_str->cntl_pnts_cache[i] = tmpPtr[i];
643  }
644 
645  }
646  }
647 
648  /* Store data products info in L2 structure */
649  /* ---------------------------------------- */
650  if (fileformat == DS_NCDF)
651  ds_id.fid = grp_id[fileindex][3];
652  for (i = 0; i < l2_str->nprod; i++) {
653  sds_id = selectDS(ds_id, l2_str->prodname[i]);
654 
655  if (sds_id != -1) {
656  getTypeDS(ds_id, l2_str->prodname[i], &(prodtype[fileindex][i]));
657 
658  /* Read scaling slope and intercept */
659  /* -------------------------------- */
660  idDS ds_id0 = {-ds_id.fid, sds_id, ds_id.fftype};
661 
662  if (fileformat == DS_NCDF) {
663  if (prodtype[fileindex][i] != NC_FLOAT && prodtype[fileindex][i] != NC_DOUBLE) {
664  status = readAttr(ds_id0, "scale_factor", (void*) &(slope[fileindex][i]));
665  if (status) {
666  slope[fileindex][i] = 1.0;
667  }
668  readAttr(ds_id0, "add_offset", (void*) &(intercept[fileindex][i]));
669  if (status) {
670  intercept[fileindex][i] = 0.0;
671  }
672  } else {
673  slope[fileindex][i] = 1.0;
674  intercept[fileindex][i] = 0.0;
675  }
676  readAttr(ds_id0, "_FillValue", (void*) (&l2_str->bv_scaled[i]));
677  } else {
678  readAttr(ds_id0, "slope", (void*) &(slope[fileindex][i]));
679  readAttr(ds_id0, "intercept", (void*) &(intercept[fileindex][i]));
680  if (slope[fileindex][i] == 0.0)
681  slope[fileindex][i] = 1.0;
682 
683  if (findAttr(ds_id0, "bad_value_unscaled") != -1)
684  readAttr(ds_id0, "bad_value_unscaled", (void*) (&l2_str->bv_unscaled[i]));
685  else
686  l2_str->bv_unscaled[i] = -1e30;
687 
688  if (findAttr(ds_id0, "bad_value_scaled") != -1)
689  readAttr(ds_id0, "bad_value_scaled", (void*) (&l2_str->bv_scaled[i]));
690  else
691  l2_str->bv_scaled[i] = -32768;
692  }
693 
694  ds_id_prod[fileindex][i] = (idDS){ds_id.fid, sds_id, ds_id.fftype};
695 
696  int32_t fldDims[8]={0,0,0,0,0,0,0,0};
697  getDimsDS(ds_id, l2_str->prodname[i], fldDims);
698  if (fldDims[2] == bandsPerPixel)
699  l2_str->thirdDim[i] = bandsPerPixel;
700  else
701  l2_str->thirdDim[i] = 1;
702 
703  } else {
704  printf("Data Product: \"%s\" not found.\n", l2_str->prodname[i]);
705  exit(1);
706  }
707  }
708 
709  /* Allocate cache for products */
710  /* --------------------------- */
711  // Allocate cache for data products if NULL
712  if (cache_l2_data == NULL) {
713  cache_nprod = l2_str->nprod;
714  cache_l2_data = (cache_str**) malloc(sizeof (cache_str*) * cache_nprod);
715  for (i = 0; i < cache_nprod; i++) {
716  cache_l2_data[i] = (cache_str*) malloc(sizeof (cache_str));
717  cache_l2_data[i]->bscan = -1;
718  cache_l2_data[i]->escan = -1;
719  cache_l2_data[i]->dataSize = 0;
720  cache_l2_data[i]->data = NULL;
721  }
722  } else if (cache_nprod < l2_str->nprod) {
723  // Allocate cache for data products if number of products increases
724 
725  for (i = 0; i < cache_nprod; i++) free(cache_l2_data[i]);
726  free(cache_l2_data);
727 
728  cache_nprod = l2_str->nprod;
729  cache_l2_data = (cache_str**) malloc(sizeof (cache_str*) * cache_nprod);
730  for (i = 0; i < cache_nprod; i++) {
731  cache_l2_data[i] = (cache_str*) malloc(sizeof (cache_str));
732  cache_l2_data[i]->bscan = -1;
733  cache_l2_data[i]->escan = -1;
734  cache_l2_data[i]->dataSize = 0;
735  cache_l2_data[i]->data = NULL;
736  }
737  }
738 
739  /* Allocate L2 data array */
740  /* ---------------------- */
741  int maxThirdDim = 1;
742  l2_str->l2_data = (float**) malloc(l2_str->nprod * sizeof (float*));
743  for (i = 0; i < l2_str->nprod; i++) {
744  l2_str->l2_data[i] = (float*) malloc(l2_str->nsamp*l2_str->thirdDim[i]*sizeof(float));
745  if(l2_str->thirdDim[i] > maxThirdDim)
746  maxThirdDim = l2_str->thirdDim[i];
747  }
748 
749  /* Allocate databuf data array */
750  /* --------------------------- */
751  allocateDatabuf(l2_str, maxThirdDim);
752 
753  /* Allocate pixnum (if applicable) */
754  /* ------------------------------- */
755  if ((ds_id_pixnum[fileindex].sid = selectDS(ds_id, "pixnum")) != -1) {
756  l2_str->pixnum = (int32_t *) calloc(l2_str->nsamp, sizeof (int32_t));
757  } else {
758  l2_str->pixnum = NULL;
759  }
760  ds_id_pixnum[fileindex].fid = ds_id.fid;
761  ds_id_pixnum[fileindex].fftype = ds_id.fftype;
762 
763  /* Read mside, detnum (if applicable) */
764  /* ---------------------------------- */
765  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][2];
766  if ((ds_id.sid = selectDS(ds_id, "mside")) != -1) {
767  l2_str->mside = (byte *) calloc(l2_str->nrec, sizeof (byte));
768  if (ds_id.fftype == DS_NCDF) {
769  readDS(ds_id, "mside", &zero32, NULL, &l2_str->nrec,
770  (void*) l2_str->mside);
771  } else {
772  int32_t rank;
773  int32_t dimsizes[3];
774  int32_t ntype;
775  int32_t num_attrs;
776 
777  SDgetinfo(ds_id.sid, NULL, &rank, dimsizes, &ntype, &num_attrs);
778  if (ntype == DFNT_INT8) {
779  readDS(ds_id, "mside", &zero32, NULL, &l2_str->nrec,
780  (void*) l2_str->mside);
781  } else {
782  int i;
783  int32_t junk[l2_str->nrec];
784 
785  readDS(ds_id, "mside", &zero32, NULL, &l2_str->nrec, (void*) junk);
786  for (i = 0; i < l2_str->nrec; i++)
787  l2_str->mside[i] = (byte) junk[i];
788  }
789  }
790  endaccessDS(ds_id);
791  } else {
792  l2_str->mside = NULL;
793  }
794 
795  if ((ds_id.sid = selectDS(ds_id, "detnum")) != -1) {
796  l2_str->detnum = (byte *) calloc(l2_str->nrec, sizeof (byte));
797  if (ds_id.fftype == DS_NCDF) {
798  readDS(ds_id, "detnum", &zero32, NULL, &l2_str->nrec,
799  (void*) l2_str->detnum);
800  } else {
801  int32_t rank;
802  int32_t dimsizes[3];
803  int32_t ntype;
804  int32_t num_attrs;
805 
806  SDgetinfo(ds_id.sid, NULL, &rank, dimsizes, &ntype, &num_attrs);
807  if (ntype == DFNT_INT8) {
808  readDS(ds_id, "detnum", &zero32, NULL, &l2_str->nrec,
809  (void*) l2_str->detnum);
810  } else {
811  int i;
812  int32_t junk[l2_str->nrec];
813 
814  readDS(ds_id, "detnum", &zero32, NULL, &l2_str->nrec, (void*) junk);
815  for (i = 0; i < l2_str->nrec; i++)
816  l2_str->detnum[i] = (byte) junk[i];
817  }
818  }
819  endaccessDS(ds_id);
820  } else {
821  l2_str->detnum = NULL;
822  }
823 
824 
825  /* Read tilt data (if applicable) */
826  /* ------------------------------ */
827  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][1];
828  if (selectDS(ds_id, "ntilts") != -1) {
829  ds_id.sid = selectDS(ds_id, "ntilts");
830  readDS(ds_id, "ntilts", tilt_start, NULL, &one,
831  (void*) & l2_str->ntilts);
832  ds_id.sid = selectDS(ds_id, "tilt_flags");
833  readDS(ds_id, "tilt_flags", tilt_start, NULL, tilt_edges,
834  (void*) l2_str->tilt_flags);
835  ds_id.sid = selectDS(ds_id, "tilt_ranges");
836  readDS(ds_id, "tilt_ranges", tilt_start, NULL, tilt_edges,
837  (void*) t_ranges);
838 
839  for (i = 0; i < l2_str->ntilts; i++) {
840  l2_str->tilt_ranges[0][i] = t_ranges[i * 2];
841  l2_str->tilt_ranges[1][i] = t_ranges[i * 2 + 1];
842  }
843  }
844 
845 
846 
847  /* Open L2 flags SDS */
848  /* ----------------- */
849  if (fileformat == DS_NCDF) {
850  ds_id.fid = grp_id[fileindex][3];
851  ds_id_l2_flags[fileindex] = (idDS){
852  ds_id.fid,
853  selectDS(ds_id, "l2_flags"),
854  ds_id.fftype
855  };
856  idDS temp_ds_id = ds_id_l2_flags[fileindex];
857  temp_ds_id.fid *= -1;
858 
859  if (ds_id_l2_flags[fileindex].sid != -1) {
860  l2_str->l2_flags = (int32_t *) calloc(l2_str->nsamp, sizeof (int32_t));
861  l2_str->flagnames = readAttrStr(temp_ds_id, "flag_meanings");
862  if(!l2_str->flagnames) {
863  printf("-E- %s:%d - openL2 - could not find flag_meanings.\n",
864  __FILE__, __LINE__);
865  exit(EXIT_FAILURE);
866  }
867  for (i = 0; i < strlen(l2_str->flagnames); i++) {
868  if (l2_str->flagnames[i] == ' ')
869  l2_str->flagnames[i] = ',';
870  }
871  } else {
872  l2_str->l2_flags = 0x0;
873  }
874  } else {
875 
876  // old HDF4 flag names
877  ds_id_l2_flags[fileindex] = (idDS){
878  ds_id.fid,
879  selectDS(ds_id, "l2_flags"),
880  ds_id.fftype
881  };
882 
883  if (ds_id_l2_flags[fileindex].sid != -1) {
884  l2_str->l2_flags = (int32_t *) calloc(l2_str->nsamp, sizeof (int32_t));
885 
886  /* Read L2 flagnames */
887  /* ----------------- */
888  n_l2flags = 0;
889  listlen = 0;
890  idDS temp_ds_id = ds_id_l2_flags[fileindex];
891  temp_ds_id.fid *= -1;
892  while (1) {
893  sprintf(buffer, "f%s_name", numstr[n_l2flags]);
894  if (findAttr(temp_ds_id, buffer) != -1) {
895  tmpStr = readAttrStr(temp_ds_id, buffer);
896  listlen += strlen(tmpStr) + 1;
897  free(tmpStr);
898  n_l2flags++;
899  } else
900  break;
901  }
902  l2_str->flagnames = (char *) calloc(listlen, sizeof (char));
903  for (i = 0; i < n_l2flags; i++) {
904  sprintf(buffer, "f%s_name", numstr[i]);
905  tmpStr = readAttrStr(temp_ds_id, buffer);
906  strcat(l2_str->flagnames, tmpStr);
907  free(tmpStr);
908  if (i < n_l2flags - 1)
909  strcat(l2_str->flagnames, ",");
910  }
911  } else {
912  l2_str->l2_flags = 0x0;
913  }
914  }
915 
916  /* Open eng_qual SDS */
917  /* ----------------- */
918  if (checkDS(ds_id_file[fileindex], "eng_qual") != -1) {
919  ds_id_eng_qual[fileindex].sid = selectDS(ds_id, "eng_qual");
920  ds_id_eng_qual[fileindex].fid = ds_id.fid;
921  ds_id_eng_qual[fileindex].fftype = ds_id.fftype;
922  } else {
923  ds_id_eng_qual[fileindex].sid = -1;
924  }
925 
926  /* Open s_flags SDS */
927  /* ---------------- */
928  if (checkDS(ds_id_file[fileindex], "s_flags") != -1) {
929  ds_id_s_flags[fileindex].sid = selectDS(ds_id, "s_flags");
930  ds_id_s_flags[fileindex].fid = ds_id.fid;
931  ds_id_s_flags[fileindex].fftype = ds_id.fftype;
932  } else {
933  ds_id_s_flags[fileindex].sid = -1;
934  }
935 
936  /* Open nflag SDS */
937  /* -------------- */
938  if (checkDS(ds_id_file[fileindex], "nflag") != -1) {
939  ds_id_nflag[fileindex].sid = selectDS(ds_id, "nflag");
940  ds_id_nflag[fileindex].fid = ds_id.fid;
941  ds_id_nflag[fileindex].fftype = ds_id.fftype;
942  } else {
943  ds_id_nflag[fileindex].sid = -1;
944  }
945 
946  /* Read cached date fields */
947  /* ----------------------- */
948  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][2];
949  if (ds_id_date[fileindex][0].sid != -1) {
950  l2_str->year_cache = (int32_t*) malloc(sizeof (int32_t) * l2_str->nrec);
951  readDS(ds_id_date[fileindex][0], "year", &zero32, NULL,
952  &(l2_str->nrec), l2_str->year_cache);
953  endaccessDS(ds_id_date[fileindex][0]);
954  }
955 
956  if (ds_id_date[fileindex][1].sid != -1) {
957  l2_str->day_cache = (int32_t*) malloc(sizeof (int32_t) * l2_str->nrec);
958  readDS(ds_id_date[fileindex][1], "day", &zero32, NULL,
959  &(l2_str->nrec), l2_str->day_cache);
960  endaccessDS(ds_id_date[fileindex][1]);
961  }
962 
963  if (ds_id_date[fileindex][2].sid != -1) {
964  l2_str->msec_cache = (int32_t*) malloc(sizeof (int32_t) * l2_str->nrec);
965  readDS(ds_id_date[fileindex][2], "msec", &zero32, NULL,
966  &(l2_str->nrec), l2_str->msec_cache);
967  endaccessDS(ds_id_date[fileindex][2]);
968  }
969 
970  first = 0;
971 
972  return 0;
973 }
974 
975 int32_t reopenL2(int32_t fileindex, l2_prod *l2_str) {
976  int32_t i;
977  //int32_t sd_id;
978  idDS ds_id;
979 
980  ds_format_t fileformat;
981  if (Hishdf(l2_str->filename) == 1) {
982  fileformat = DS_HDF;
983  } else {
984  fileformat = DS_NCDF;
985  }
986 
987  ds_id = startDS(l2_str->filename, fileformat, DS_READ, 0);
988  ds_id_file[fileindex] = ds_id;
989 
990  if (fileformat == DS_NCDF) {
991  nc_inq_ncid(ds_id.fid, "sensor_band_parameters", &grp_id[fileindex][0]);
992  nc_inq_ncid(ds_id.fid, "sensor_tilt", &grp_id[fileindex][1]);
993  nc_inq_ncid(ds_id.fid, "scan_line_attributes", &grp_id[fileindex][2]);
994  nc_inq_ncid(ds_id.fid, "geophysical_data", &grp_id[fileindex][3]);
995  nc_inq_ncid(ds_id.fid, "navigation_data", &grp_id[fileindex][4]);
996  nc_inq_ncid(ds_id.fid, "processing_control", &grp_id[fileindex][5]);
997  }
998 
999  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][4];
1000  ds_id_ll[fileindex][0] = (idDS){ds_id.fid,
1001  selectDS(ds_id, "longitude"),
1002  ds_id.fftype};
1003  ds_id_ll[fileindex][1] = (idDS){ds_id.fid,
1004  selectDS(ds_id, "latitude"),
1005  ds_id.fftype};
1006 
1007  if (l2_str->geointerp == 2) {
1008  ds_id_geonav[fileindex][0] = (idDS){ds_id.fid,
1009  selectDS(ds_id, "orb_vec"),
1010  ds_id.fftype};
1011  ds_id_geonav[fileindex][1] = (idDS){ds_id.fid,
1012  selectDS(ds_id, "sen_mat"),
1013  ds_id.fftype};
1014  ds_id_geonav[fileindex][2] = (idDS){ds_id.fid,
1015  selectDS(ds_id, "scan_ell"),
1016  ds_id.fftype};
1017  ds_id_geonav[fileindex][3] = (idDS){ds_id.fid,
1018  selectDS(ds_id, "sun_ref"),
1019  ds_id.fftype};
1020  ds_id_geonav[fileindex][5] = (idDS){ds_id.fid,
1021  selectDS(ds_id, "att_ang"),
1022  ds_id.fftype};
1023  }
1024 
1025  if (fileformat == DS_NCDF) ds_id.fid = grp_id[fileindex][3];
1026  for (i = 0; i < l2_str->nprod; i++) {
1027  ds_id_prod[fileindex][i] = (idDS){ds_id.fid,
1028  selectDS(ds_id, l2_str->prodname[i]),
1029  ds_id.fftype};
1030  }
1031 
1032  ds_id_l2_flags[fileindex] = (idDS){ds_id.fid,
1033  selectDS(ds_id, "l2_flags"),
1034  ds_id.fftype};
1035 
1036  ds_id_eng_qual[fileindex] = (idDS){ds_id.fid,
1037  selectDS(ds_id, "eng_qual"),
1038  ds_id.fftype};
1039 
1040  ds_id_s_flags[fileindex] = (idDS){ds_id.fid,
1041  selectDS(ds_id, "s_flags"),
1042  ds_id.fftype};
1043 
1044  ds_id_nflag[fileindex] = (idDS){ds_id.fid,
1045  selectDS(ds_id, "nflag"),
1046  ds_id.fftype};
1047 
1048  ds_id_pixnum[fileindex] = (idDS){ds_id.fid,
1049  selectDS(ds_id, "pixnum"),
1050  ds_id.fftype};
1051 
1052  return 0;
1053 }
1054 
1055 //----------------------------------------------------------------
1056 // function to cache the read data
1057 // Note: make sure there is a terminating 0 at the end of scan_in_rowgroup
1058 
1059 int32_t readdata_cached(idDS ds_id, char *name,
1060  int32_t *start, int32_t *stride, int32_t *edges,
1061  void* data, unsigned char *scan_in_rowgroup,
1062  cache_str *cache, int32_t dtype) {
1063  int32_t start2[3];
1064  int32_t edges2[3];
1065  int32_t bscan;
1066  int32_t escan;
1067  int32_t nscans;
1068  int32_t size;
1069  size_t recSize = hdf_sizeof(dtype) * edges[1];
1070  char* ptr;
1071  int32_t status;
1072 
1073 #ifdef NON_CACHED
1074  status = readDS(ds_id, name, start, stride, edges, data);
1075 #else
1076 
1077  if (ds_id.fftype == DS_NCDF) {
1078  status = nc_inq_type(ds_id.fid, dtype, NULL, &recSize);
1079  check_err(status, __LINE__, __FILE__);
1080  recSize *= edges[1];
1081  if (edges[2] != 1) {
1082  recSize *= edges[2];
1083  edges2[2] = edges[2];
1084  start2[2] = 0;
1085  }
1086  }
1087 
1088  status = 0;
1089  // see if scan line is in the cache
1090  if ((start[0] < cache->bscan) || (start[0] > cache->escan)) {
1091 
1092  // find out how many lines to cache. Note: scan_in_rowgroup was
1093  // allocated with an extra 0 at the end to mark the end of lines
1094  bscan = escan = start[0];
1095  while (scan_in_rowgroup[escan] != 0)
1096  escan++;
1097  escan--;
1098  nscans = escan - bscan + 1;
1099  size = nscans * recSize;
1100  if (size > cache->dataSize) {
1101  cache->dataSize = size;
1102  if (cache->data)
1103  free(cache->data);
1104  cache->data = malloc(size);
1105  }
1106  cache->bscan = bscan;
1107  cache->escan = escan;
1108  start2[0] = bscan;
1109  start2[1] = start[1];
1110  start2[2] = start[2];
1111  edges2[0] = nscans;
1112  edges2[1] = edges[1];
1113  edges2[2] = edges[2];
1114  status = readDS(ds_id, name, start2, stride, edges2, cache->data);
1115  } // cache miss
1116 
1117  ptr = (char*) (cache->data) + (start[0] - cache->bscan) * recSize;
1118  memcpy(data, ptr, recSize);
1119 #endif
1120 
1121  return status;
1122 }
1123 
1124 void clampDeltaLon(float *deltaLon) {
1125  if(*deltaLon > 90) {
1126  if(*deltaLon > 270)
1127  *deltaLon -= 360.0;
1128  else
1129  *deltaLon -= 180.0;
1130  } else if(*deltaLon < -90) {
1131  if(*deltaLon < -270)
1132  *deltaLon += 360.0;
1133  else
1134  *deltaLon += 180.0;
1135  }
1136 }
1137 
1150 void interpolatePixelCorners(float* lat0, float* lon0,
1151  float* lat1, float* lon1,
1152  float* latOut, float* lonOut,
1153  int32_t numPoints) {
1154 
1155  // calc the delta for first point
1156  float dLat = (lat1[0] - lat0[0] + lat0[1] - lat0[0]) / 2.0;
1157  float dLon = (lon1[0] - lon0[0] + lon0[1] - lon0[0]) / 2.0;
1158  clampDeltaLon(&dLon);
1159 
1160  // first calc 0 point
1161  latOut[0] = lat1[0] - dLat;
1162  lonOut[0] = lon1[0] - dLon;
1163 
1164  // calc the rest of the points
1165  for(int i=0; i<numPoints-1; i++) {
1166  dLat = (lat1[i] - lat0[i] + lat0[i+1] - lat0[i]) / 2.0;
1167  dLon = (lon1[i] - lon0[i] + lon0[i+1] - lon0[i]) / 2.0;
1168  clampDeltaLon(&dLon);
1169 
1170  latOut[i+1] = lat0[i] + dLat;
1171  lonOut[i+1] = lon0[i] + dLon;
1172  }
1173 
1174  // calc last point
1175  latOut[numPoints] = lat0[numPoints-1] + dLat;
1176  lonOut[numPoints] = lon0[numPoints-1] + dLon;
1177 }
1178 
1191 void extrapolatePixelCorners(float* lat0, float* lon0,
1192  float* lat1, float* lon1,
1193  float* latOut, float* lonOut,
1194  int32_t numPoints) {
1195 
1196  // calc the delta for first point
1197  float dLat = (lat1[1] - lat1[0] + lat0[0] - lat1[0]) / 2.0;
1198  float dLon = (lon1[1] - lon1[0] + lon0[0] - lon1[0]) / 2.0;
1199  clampDeltaLon(&dLon);
1200 
1201  // first calc 0 point
1202  latOut[0] = lat1[0] - dLat;
1203  lonOut[0] = lon1[0] - dLon;
1204 
1205  // calc the rest of the points
1206  for(int i=0; i<numPoints-1; i++) {
1207  dLat = (lat1[i] - lat0[i] + lat0[i+1] - lat0[i]) / 2.0;
1208  dLon = (lon1[i] - lon0[i] + lon0[i+1] - lon0[i]) / 2.0;
1209  clampDeltaLon(&dLon);
1210 
1211  latOut[i+1] = lat1[i] + dLat;
1212  lonOut[i+1] = lon1[i] + dLon;
1213  }
1214 
1215  // calc last point
1216  latOut[numPoints] = lat1[numPoints-1] + dLat;
1217  lonOut[numPoints] = lon1[numPoints-1] + dLon;
1218 }
1219 
1231 void calculatePixelDeltas(float* lat0, float* lon0,
1232  float* lat1, float* lon1,
1233  float* latOut, float* lonOut,
1234  int32_t numPoints) {
1235 
1236  // calc all points except the last one
1237  for(int i=0; i<numPoints-1; i++) {
1238  latOut[i] = fabsf(lat0[i] - lat1[i]) / 2.0;
1239  lonOut[i] = fabsf(lon0[i] - lon0[i+1]) / 2.0;
1240  if(lonOut[i] > 90) {
1241  lonOut[i] = 180.0 - lonOut[i];
1242  }
1243  }
1244 
1245  // calc last point
1246  latOut[numPoints-1] = latOut[numPoints-2];
1247  lonOut[numPoints-1] = lonOut[numPoints-2];
1248 }
1249 
1250 int32_t readL2(l2_prod *l2_str, int32_t ifile, int32_t recnum, int32_t iprod,
1251  unsigned char *scan_in_rowgroup) {
1252  int32_t i;
1253  int32_t start[3] = {0, 0, 0};
1254  int32_t edges[3] = {1, 1, 1};
1255  int32_t ipix;
1256  int32_t ptype;
1257  int32_t status;
1258 
1259  float slp;
1260  float itp;
1261 
1262  int32_t flag_edges[2] = {1, 4};
1263  int32_t nflag_edges[2] = {1, 8};
1264 
1265  float nan = __builtin_nanf("");
1266  float* tmpFloat;
1267 
1268  start[0] = recnum;
1269  start[1] = 0;
1270  edges[0] = 1;
1271  edges[1] = l2_str->nsamp;
1272 
1273  /* Read L2 flags */
1274  /* ------------- */
1275  if (ds_id_l2_flags[ifile].sid != -1) {
1276  if (scan_in_rowgroup == NULL) {
1277  status = readDS(ds_id_l2_flags[ifile], "l2_flags", start, NULL, edges,
1278  (void*) l2_str->l2_flags);
1279  } else {
1280  status = readdata_cached(ds_id_l2_flags[ifile], "l2_flags",
1281  start, NULL, edges,
1282  (void*) l2_str->l2_flags, scan_in_rowgroup,
1283  &cache_l2_flags, l2_flags_type);
1284  }
1285 
1286  /* If INT16 array then convert to INT32 */
1287  /* ------------------------------------ */
1288  if (l2_flags_type == DFNT_INT16) {
1289  int16_t *ptr16 = (int16_t*) l2_str->l2_flags;
1290  for (i = l2_str->nsamp - 1; i >= 0; i--)
1291  l2_str->l2_flags[i] = ptr16[i];
1292  }
1293  }
1294 
1295 
1296  /* Read eng_qual */
1297  /* ------------- */
1298  if (ds_id_eng_qual[ifile].sid != -1) {
1299  if (scan_in_rowgroup == NULL) {
1300  status = readDS(ds_id_eng_qual[ifile], "eng_qual",
1301  start, NULL, flag_edges,
1302  (void*) l2_str->eng_qual);
1303  } else {
1304  status = readdata_cached(ds_id_eng_qual[ifile], "eng_qual",
1305  start, NULL, flag_edges,
1306  (void*) l2_str->eng_qual, scan_in_rowgroup,
1307  &cache_eng_qual, get_dtype(DFNT_INT8, ds_id_eng_qual[ifile].fftype));
1308  }
1309  }
1310 
1311  /* Read s_flags */
1312  /* ------------ */
1313  if (ds_id_s_flags[ifile].sid != -1) {
1314  if (scan_in_rowgroup == NULL) {
1315  status = readDS(ds_id_s_flags[ifile], "s_flags",
1316  start, NULL, flag_edges,
1317  (void*) l2_str->s_flags);
1318  } else {
1319  status = readdata_cached(ds_id_s_flags[ifile], "s_flags",
1320  start, NULL, flag_edges,
1321  (void*) l2_str->s_flags, scan_in_rowgroup,
1322  &cache_s_flags, get_dtype(DFNT_INT8, ds_id_s_flags[ifile].fftype));
1323  }
1324  }
1325 
1326  /* Read nflag */
1327  /* ---------- */
1328  if (ds_id_nflag[ifile].sid != -1) {
1329  if (scan_in_rowgroup == NULL) {
1330  status = readDS(ds_id_nflag[ifile], "nflag",
1331  start, NULL, nflag_edges,
1332  (void*) l2_str->nflag);
1333  } else {
1334  status = readdata_cached(ds_id_nflag[ifile], "nflag",
1335  start, NULL, nflag_edges,
1336  (void*) l2_str->nflag, scan_in_rowgroup,
1337  &cache_nflag, get_dtype(DFNT_INT32, ds_id_nflag[ifile].fftype));
1338  }
1339  }
1340 
1341  /* Read pixnum (if applicable) */
1342  /* --------------------------- */
1343  if (ds_id_pixnum[ifile].sid != -1) {
1344  if (scan_in_rowgroup == NULL) {
1345  status = readDS(ds_id_pixnum[ifile], "pixnum",
1346  start, NULL, edges,
1347  (void*) l2_str->pixnum);
1348  } else {
1349  status = readdata_cached(ds_id_pixnum[ifile], "pixnum",
1350  start, NULL, edges,
1351  (void*) l2_str->pixnum, scan_in_rowgroup,
1352  &cache_pixnum, get_dtype(DFNT_INT32, ds_id_pixnum[ifile].fftype));
1353  }
1354  }
1355 
1356  /* Read date fields */
1357  /* ---------------- */
1358  l2_str->year = l2_str->year_cache[recnum];
1359  l2_str->day = l2_str->day_cache[recnum];
1360  l2_str->msec = l2_str->msec_cache[recnum];
1361 
1362 
1363  /* Main product loop */
1364  /* ----------------- */
1365  for (i = 0; i < l2_str->nprod; i++) {
1366 
1367  if ((iprod != -1) && (i != iprod)) continue;
1368 
1369 
1370  slp = slope[ifile][i];
1371  itp = intercept[ifile][i];
1372  edges[2] = l2_str->thirdDim[i];
1373 
1374  /* Read into data buffer */
1375  /* --------------------- */
1376  if (scan_in_rowgroup == NULL) {
1377  status = readDS(ds_id_prod[ifile][i], l2_str->prodname[i],
1378  start, NULL, edges,
1379  (void*) databuf);
1380  } else {
1381  status = readdata_cached(ds_id_prod[ifile][i], l2_str->prodname[i],
1382  start, NULL, edges,
1383  (void*) databuf, scan_in_rowgroup,
1384  cache_l2_data[i], prodtype[ifile][i]);
1385  }
1386 
1387  if (status != 0) {
1388  printf("Read Error: %d (%s) %d\n",
1389  ifile, l2_str->filename, i);
1390  exit(-1);
1391  }
1392 
1393 
1394  if (ds_id_file[ifile].fftype == DS_HDF) {
1395  ptype = prodtype[ifile][i];
1396  } else {
1397  switch (prodtype[ifile][i]) {
1398  case NC_UBYTE:
1399  ptype = DFNT_UINT8;
1400  break;
1401  case NC_BYTE:
1402  case NC_CHAR:
1403  ptype = DFNT_INT8;
1404  break;
1405  case NC_SHORT:
1406  ptype = DFNT_INT16;
1407  break;
1408  case NC_FLOAT:
1409  ptype = DFNT_FLOAT32;
1410  break;
1411  };
1412  }
1413 
1414 
1415  /* Convert to proper data type (unscale) */
1416  /* ------------------------------------- */
1417  switch (ptype) {
1418 
1419  case DFNT_UINT8: {
1420  uint8* tmp = (uint8*) databuf;
1421  float* result = l2_str->l2_data[i];
1422  for (ipix = 0; ipix < l2_str->nsamp; ipix++) {
1423  if (*tmp == l2_str->bv_scaled[i]) {
1424  *result = nan;
1425  } else {
1426  *result = *tmp * slp + itp;
1427  }
1428  tmp++;
1429  result += l2_str->thirdDim[i];
1430  }
1431  }
1432  break;
1433 
1434  case DFNT_INT8: {
1435  int8* tmp = (int8*) databuf;
1436  float* result = l2_str->l2_data[i];
1437  for (ipix = 0; ipix < l2_str->nsamp; ipix++) {
1438  if (*tmp == l2_str->bv_scaled[i]) {
1439  *result = nan;
1440  } else {
1441  *result = *tmp * slp + itp;
1442  }
1443  tmp++;
1444  result += l2_str->thirdDim[i];
1445  }
1446  }
1447  break;
1448 
1449  case DFNT_INT16: {
1450  int16_t* tmp = (int16_t*) databuf;
1451  float* result = l2_str->l2_data[i];
1452  for (ipix = 0; ipix < l2_str->nsamp; ipix++) {
1453  if (*tmp == l2_str->bv_scaled[i]) {
1454  *result = nan;
1455  } else {
1456  if (*tmp <= -32767)
1457  *result = -32767;
1458  else
1459  *result = *tmp * slp + itp;
1460  }
1461  tmp++;
1462  result += l2_str->thirdDim[i];
1463  }
1464  }
1465  break;
1466 
1467  case DFNT_FLOAT32: {
1468  float* tmp = (float*) databuf;
1469  float* result = l2_str->l2_data[i];
1470  for (ipix = 0; ipix < l2_str->nsamp; ipix++) {
1471  *result = *tmp;
1472  tmp++;
1473  result += l2_str->thirdDim[i];
1474  }
1475  }
1476  break;
1477 
1478  }; /* end switch */
1479 
1480  } /* product loop */
1481 
1482  // reset to a 2D product
1483  edges[2] = 1;
1484 
1485  if(pixelAreaInfo.mode != L2PixelOff) {
1486  if(pixelAreaInfo.nsamp != l2_str->nsamp) {
1487  pixelAreaInfo.nsamp = l2_str->nsamp;
1488  if(pixelAreaInfo.lastLat) {
1489  free(pixelAreaInfo.lastLat);
1490  free(pixelAreaInfo.lastLon);
1491  }
1492  pixelAreaInfo.lastLat = (float *) malloc(l2_str->nsamp * sizeof (float));
1493  pixelAreaInfo.lastLon = (float *) malloc(l2_str->nsamp * sizeof (float));
1494  }
1495 
1496  // if there is no previous line, try to read it now
1497  if(pixelAreaInfo.lastLine == -1) {
1498  if(recnum > 0) {
1499  pixelAreaInfo.lastLine = recnum - 1;
1500  scan_in_rowgroup[pixelAreaInfo.lastLine] = 1;
1501  start[0] = pixelAreaInfo.lastLine;
1502  status = readlonlat(l2_str, ifile, start, edges, scan_in_rowgroup);
1503  if (status == 1) {
1504  return 5;
1505  }
1506  start[0] = recnum;
1507  }
1508  }
1509 
1510  // save lat/lon from last line
1511  tmpFloat = pixelAreaInfo.lastLat;
1512  pixelAreaInfo.lastLat = l2_str->latitude;
1513  l2_str->latitude = tmpFloat;
1514  tmpFloat = pixelAreaInfo.lastLon;
1515  pixelAreaInfo.lastLon = l2_str->longitude;
1516  l2_str->longitude = tmpFloat;
1517  }
1518 
1519  /* Read lon/lat fields */
1520  /* ----------------------------------------------------- */
1521  status = readlonlat(l2_str, ifile, start, edges, scan_in_rowgroup);
1522  if (status == 1) {
1523  return 5;
1524  }
1525 
1526  /* Check whether lon/lat values are within range */
1527  /* --------------------------------------------- */
1528  for (i = 0; i < l2_str->nsamp; i++) {
1529  if ((l2_str->longitude[i] > 180 || l2_str->longitude[i] < -180) &&
1530  ((l2_str->l2_flags[i] & 33554432) == 0)) {
1531  printf("Scheme: %d\n", l2_str->geointerp);
1532  printf("Pixel Longitude %d out of range (%f) for scan %d in %s.\n",
1533  i, l2_str->longitude[i], recnum, l2_str->filename);
1534  exit(-1);
1535  }
1536 
1537 
1538 
1539  if ((l2_str->latitude[i] > 180 || l2_str->latitude[i] < -180) &&
1540  ((l2_str->l2_flags[i] & 33554432) == 0)) {
1541  printf("Scheme: %d\n", l2_str->geointerp);
1542  printf("Pixel Latitude %d out of range (%f) for scan %d in %s.\n",
1543  i, l2_str->latitude[i], recnum, l2_str->filename);
1544  exit(-1);
1545  }
1546  }
1547 
1548 
1549  if(pixelAreaInfo.mode != L2PixelOff) {
1550  // last line had valid lat/lon
1551  if(pixelAreaInfo.lastLine != -1) {
1552 
1553  // check that the line number increased by 1
1554  if(recnum - pixelAreaInfo.lastLine == 1) {
1555 
1556  // check the detector num to see if we need to invalidate the previous line
1557  // OK if detnum never allocated
1558  // OK if detnum is the same. ie only one detector
1559  // OK if last detnum is 1 different from the current detnum
1560  if(l2_str->detnum &&
1561  (l2_str->detnum[pixelAreaInfo.lastLine] != l2_str->detnum[recnum]) &&
1562  (abs(l2_str->detnum[pixelAreaInfo.lastLine] - l2_str->detnum[recnum]) != 1)) {
1563  pixelAreaInfo.lastLine = -1;
1564  }
1565 
1566  } else {
1567  l2_str->lat2Valid = 0;
1568 
1569  // read the previous line
1570  if(recnum > 0) {
1571  pixelAreaInfo.lastLine = recnum - 1;
1572 
1573  // check detnum
1574  if(l2_str->detnum &&
1575  (l2_str->detnum[pixelAreaInfo.lastLine] != l2_str->detnum[recnum]) &&
1576  (abs(l2_str->detnum[pixelAreaInfo.lastLine] - l2_str->detnum[recnum]) != 1)) {
1577  pixelAreaInfo.lastLine = -1;
1578  }
1579 
1580  if(pixelAreaInfo.lastLine != -1) {
1581 
1582  // save current lat/lon
1583  tmpFloat = pixelAreaInfo.lastLat;
1584  pixelAreaInfo.lastLat = l2_str->latitude;
1585  l2_str->latitude = tmpFloat;
1586  tmpFloat = pixelAreaInfo.lastLon;
1587  pixelAreaInfo.lastLon = l2_str->longitude;
1588  l2_str->longitude = tmpFloat;
1589 
1590  // read the next line
1591  start[0] = pixelAreaInfo.lastLine;
1592  start[1] = 0;
1593  edges[0] = 1;
1594  edges[1] = l2_str->nsamp;
1595  status = readlonlat(l2_str, ifile, start, edges, scan_in_rowgroup);
1596 
1597  // swap lat/lon so latitude/longitude point to the correct line
1598  tmpFloat = pixelAreaInfo.lastLat;
1599  pixelAreaInfo.lastLat = l2_str->latitude;
1600  l2_str->latitude = tmpFloat;
1601  tmpFloat = pixelAreaInfo.lastLon;
1602  pixelAreaInfo.lastLon = l2_str->longitude;
1603  l2_str->longitude = tmpFloat;
1604 
1605  }
1606  } else {
1607  pixelAreaInfo.lastLine = -1;
1608  }
1609 
1610  }
1611  }
1612 
1613  // check if we need to read the next line to calc deltas
1614  if(pixelAreaInfo.lastLine == -1) {
1615  // if next line's detector is not the same or the next detector we need to bail.
1616  if(l2_str->detnum &&
1617  (l2_str->detnum[recnum+1] != l2_str->detnum[recnum]) &&
1618  (abs(l2_str->detnum[recnum+1] - l2_str->detnum[recnum]) != 1)) {
1619  printf("ERROR - %s:%d - the detector number of the next line is not from the next detector.\n", __FILE__, __LINE__);
1620  printf(" Can not do area weighting on file=%s, line=%d\n", l2_str->filename, recnum);
1621  exit(EXIT_FAILURE);
1622  }
1623 
1624  // make sure we can read the next line
1625  if(recnum+1 >= l2_str->nrec) {
1626  printf("ERROR - %s:%d - the previous line was invalid and there are no more lines to read.\n", __FILE__, __LINE__);
1627  printf(" Can not do area weighting on file=%s, line=%d\n", l2_str->filename, recnum);
1628  exit(EXIT_FAILURE);
1629  }
1630 
1631  // save current lat/lon
1632  tmpFloat = pixelAreaInfo.lastLat;
1633  pixelAreaInfo.lastLat = l2_str->latitude;
1634  l2_str->latitude = tmpFloat;
1635  tmpFloat = pixelAreaInfo.lastLon;
1636  pixelAreaInfo.lastLon = l2_str->longitude;
1637  l2_str->longitude = tmpFloat;
1638 
1639  // read the next line
1640  start[0] = recnum+1;
1641  start[1] = 0;
1642  edges[0] = 1;
1643  edges[1] = l2_str->nsamp;
1644  status = readlonlat(l2_str, ifile, start, edges, scan_in_rowgroup);
1645 
1646  // swap lat/lon so latitude/longitude point to the correct line
1647  tmpFloat = pixelAreaInfo.lastLat;
1648  pixelAreaInfo.lastLat = l2_str->latitude;
1649  l2_str->latitude = tmpFloat;
1650  tmpFloat = pixelAreaInfo.lastLon;
1651  pixelAreaInfo.lastLon = l2_str->longitude;
1652  l2_str->longitude = tmpFloat;
1653 
1654  if(pixelAreaInfo.mode == L2PixelCorner) {
1655  extrapolatePixelCorners(pixelAreaInfo.lastLat, pixelAreaInfo.lastLon,
1656  l2_str->latitude, l2_str->longitude,
1657  l2_str->lat1, l2_str->lon1,
1658  l2_str->nsamp);
1659  interpolatePixelCorners(l2_str->latitude, l2_str->longitude,
1660  pixelAreaInfo.lastLat, pixelAreaInfo.lastLon,
1661  l2_str->lat2, l2_str->lon2,
1662  l2_str->nsamp);
1663  } else {
1664  calculatePixelDeltas(l2_str->latitude, l2_str->longitude,
1665  pixelAreaInfo.lastLat, pixelAreaInfo.lastLon,
1666  l2_str->lat1, l2_str->lon1,
1667  l2_str->nsamp);
1668  }
1669  } else {
1670 
1671  if(pixelAreaInfo.mode == L2PixelCorner) {
1672  // see if we can use lat1/lon1 from lat2/lon2
1673  if(l2_str->lat2Valid) {
1674  //move lat2/lon2 into lat1/lon1
1675  tmpFloat = l2_str->lat1;
1676  l2_str->lat1 = l2_str->lat2;
1677  l2_str->lat2 = tmpFloat;
1678  tmpFloat = l2_str->lon1;
1679  l2_str->lon1 = l2_str->lon2;
1680  l2_str->lon2 = tmpFloat;
1681  } else {
1682  interpolatePixelCorners(pixelAreaInfo.lastLat, pixelAreaInfo.lastLon,
1683  l2_str->latitude, l2_str->longitude,
1684  l2_str->lat1, l2_str->lon1,
1685  l2_str->nsamp);
1686  }
1687  extrapolatePixelCorners(pixelAreaInfo.lastLat, pixelAreaInfo.lastLon,
1688  l2_str->latitude, l2_str->longitude,
1689  l2_str->lat2, l2_str->lon2,
1690  l2_str->nsamp);
1691  } else {
1692  calculatePixelDeltas(l2_str->latitude, l2_str->longitude,
1693  pixelAreaInfo.lastLat, pixelAreaInfo.lastLon,
1694  l2_str->lat1, l2_str->lon1,
1695  l2_str->nsamp);
1696  }
1697 
1698 
1699  }
1700 
1701 // int i = 0;
1702 // printf("lat%d = %f\n", i, l2_str->latitude[i]);
1703 // printf("lon%d = %f\n", i, l2_str->longitude[i]);
1704 // printf("lat = [%f, %f, %f, %f]\n", l2_str->lat2[i+1], l2_str->lat2[i], l2_str->lat1[i], l2_str->lat1[i+1]);
1705 // printf("lon = [%f, %f, %f, %f]\n", l2_str->lon2[i+1], l2_str->lon2[i], l2_str->lon1[i], l2_str->lon1[i+1]);
1706 // printf("plt.plot(lon%d, lat%d, \"ro\")\n", i, i);
1707 // printf("plt.plot(lon, lat)\n\n");
1708 //
1709 // i = 1;
1710 // printf("lat%d = %f\n", i, l2_str->latitude[i]);
1711 // printf("lon%d = %f\n", i, l2_str->longitude[i]);
1712 // printf("lat = [%f, %f, %f, %f]\n", l2_str->lat2[i+1], l2_str->lat2[i], l2_str->lat1[i], l2_str->lat1[i+1]);
1713 // printf("lon = [%f, %f, %f, %f]\n", l2_str->lon2[i+1], l2_str->lon2[i], l2_str->lon1[i], l2_str->lon1[i+1]);
1714 // printf("plt.plot(lon%d, lat%d, \"ro\")\n", i, i);
1715 // printf("plt.plot(lon, lat)\n\n");
1716 
1717 
1718 // i = l2_str->nsamp - 2;
1719 // printf("lat%d = %f\n", i, l2_str->latitude[i]);
1720 // printf("lon%d = %f\n", i, l2_str->longitude[i]);
1721 // printf("lat = [%f, %f, %f, %f]\n", l2_str->lat2[i+1], l2_str->lat2[i], l2_str->lat1[i], l2_str->lat1[i+1]);
1722 // printf("lon = [%f, %f, %f, %f]\n", l2_str->lon2[i+1], l2_str->lon2[i], l2_str->lon1[i], l2_str->lon1[i+1]);
1723 // printf("plt.plot(lon%d, lat%d, \"ro\")\n", i, i);
1724 // printf("plt.plot(lon, lat)\n\n");
1725 //
1726 // i++;
1727 // printf("lat%d = %f\n", i, l2_str->latitude[i]);
1728 // printf("lon%d = %f\n", i, l2_str->longitude[i]);
1729 // printf("lat = [%f, %f, %f, %f]\n", l2_str->lat2[i+1], l2_str->lat2[i], l2_str->lat1[i], l2_str->lat1[i+1]);
1730 // printf("lon = [%f, %f, %f, %f]\n", l2_str->lon2[i+1], l2_str->lon2[i], l2_str->lon1[i], l2_str->lon1[i+1]);
1731 // printf("plt.plot(lon%d, lat%d, \"ro\")\n", i, i);
1732 // printf("plt.plot(lon, lat)\n\n");
1733 //
1734 //
1735 // if(recnum > 19)
1736 // exit(0);
1737 
1738  l2_str->lat2Valid = 1;
1739  pixelAreaInfo.lastLine = recnum;
1740  }
1741 
1742  return 0;
1743 }
1744 
1745 int32_t readlonlat(l2_prod *l2_str, int32_t ifile, int32_t *start, int32_t *edges,
1746  unsigned char *scan_in_rowgroup) {
1747  int32_t i;
1748  int32_t geo_edge[6] = {3, 3, 6, 3, 3, 3};
1749  int32_t edges2[3];
1750 
1751  int32_t n_cntl_pnts_removed;
1752 
1753  float delta;
1754  float *cntl_pnt_buf1;
1755  float *cntl_pnt_buf2;
1756  float lon_lat_lim = 0.1;
1757 
1758  char *geonav_name[6] = {"orb_vec", "sen_mat", "scan_ell",
1759  "sun_ref", "l_vert", "att_ang"};
1760 
1761 
1762  switch (l2_str->geointerp) {
1763 
1764  case 0:
1765 
1766  /* Read full-size lon/lat fields */
1767  /* ----------------------------- */
1768  if (scan_in_rowgroup == NULL) {
1769  readDS(ds_id_ll[ifile][0], "longitude", start, NULL, edges,
1770  (void*) l2_str->longitude);
1771  readDS(ds_id_ll[ifile][1], "latitude", start, NULL, edges,
1772  (void*) l2_str->latitude);
1773  } else {
1774  readdata_cached(ds_id_ll[ifile][0], "longitude",
1775  start, NULL, edges,
1776  (void*) l2_str->longitude, scan_in_rowgroup,
1777  &cache_longitude, DFNT_FLOAT32);
1778  readdata_cached(ds_id_ll[ifile][1], "latitude",
1779  start, NULL, edges,
1780  (void*) l2_str->latitude, scan_in_rowgroup,
1781  &cache_latitude, DFNT_FLOAT32);
1782  }
1783  break;
1784 
1785 
1786  case 1:
1787 
1788  /* Read subsampled lon/lat fields */
1789  /* ------------------------------ */
1790  edges2[0] = edges[0];
1791  edges2[1] = n_cntl_pnts;
1792  if (scan_in_rowgroup == NULL) {
1793  readDS(ds_id_ll[ifile][0], "longitude", start, NULL, edges2,
1794  (void*) l2_str->lon_cntl);
1795  readDS(ds_id_ll[ifile][1], "latitude", start, NULL, edges2,
1796  (void*) l2_str->lat_cntl);
1797  } else {
1798  readdata_cached(ds_id_ll[ifile][0], "longitude",
1799  start, NULL, edges2,
1800  (void*) l2_str->lon_cntl, scan_in_rowgroup,
1801  &cache_longitude, DFNT_FLOAT32);
1802  readdata_cached(ds_id_ll[ifile][1], "latitude",
1803  start, NULL, edges2,
1804  (void*) l2_str->lat_cntl, scan_in_rowgroup,
1805  &cache_latitude, DFNT_FLOAT32);
1806  }
1807 
1808  /* Setup buffers used to remove bad control points */
1809  /* ----------------------------------------------- */
1810  cntl_pnt_buf1 = (float *) calloc(n_cntl_pnts, sizeof (float));
1811  cntl_pnt_buf2 = (float *) calloc(n_cntl_pnts, sizeof (float));
1812 
1813 
1814  /* Interpolate Latitude */
1815  /* -------------------- */
1816 
1817  /* Remove bad lat from lat_cntl & cntl_pnts */
1818  n_cntl_pnts_removed = 0;
1819  for (i = 0; i < n_cntl_pnts; i++) {
1820  if (l2_str->lat_cntl[i] < -91 || l2_str->lat_cntl[i] > +91) {
1821  n_cntl_pnts_removed++;
1822  } else {
1823  cntl_pnt_buf1[i - n_cntl_pnts_removed] = l2_str->lat_cntl[i];
1824  cntl_pnt_buf2[i - n_cntl_pnts_removed] = l2_str->cntl_pnts_cache[i];
1825  }
1826  }
1827 
1828  if (((float) n_cntl_pnts_removed) / n_cntl_pnts > lon_lat_lim) {
1829  fprintf(stderr, "%s (Latitude failure)\n", l2_str->filename);
1830  fprintf(stderr, "More that 10%% failure.\n");
1831 
1832  return 1;
1833  }
1834 
1835  n_cntl_pnts -= n_cntl_pnts_removed;
1836 
1837  for (i = 0; i < n_cntl_pnts; i++) {
1838  l2_str->lat_cntl[i] = cntl_pnt_buf1[i];
1839  l2_str->cntl_pnts[i] = cntl_pnt_buf2[i];
1840  }
1841 
1842  spline(l2_str->cntl_pnts, l2_str->lat_cntl, n_cntl_pnts,
1843  1e30, 1e30, l2_str->spline_arr);
1844  for (i = 0; i < l2_str->nsamp; i++) {
1845  splint(l2_str->cntl_pnts, l2_str->lat_cntl,
1846  l2_str->spline_arr, n_cntl_pnts,
1847  i + 1.0, &l2_str->latitude[i]);
1848  }
1849 
1850  // Added JMG 03/14/11
1851  n_cntl_pnts += n_cntl_pnts_removed;
1852 
1853  /* Interpolate Longitude */
1854  /* --------------------- */
1855 
1856  /* Remove bad lon from lon_cntl & cntl_pnts */
1857  n_cntl_pnts_removed = 0;
1858  for (i = 0; i < n_cntl_pnts; i++) {
1859  if (l2_str->lon_cntl[i] < -181 || l2_str->lon_cntl[i] > +181) {
1860  n_cntl_pnts_removed++;
1861  } else {
1862  cntl_pnt_buf1[i - n_cntl_pnts_removed] = l2_str->lon_cntl[i];
1863  cntl_pnt_buf2[i - n_cntl_pnts_removed] = l2_str->cntl_pnts_cache[i];
1864  }
1865  }
1866 
1867  if (((float) n_cntl_pnts_removed) / n_cntl_pnts > lon_lat_lim) {
1868  fprintf(stderr, "%s (Longitude failure)\n", l2_str->filename);
1869  fprintf(stderr, "More that 10%% failure.\n");
1870  return 1;
1871  }
1872 
1873  n_cntl_pnts -= n_cntl_pnts_removed;
1874 
1875  for (i = 0; i < n_cntl_pnts; i++) {
1876  l2_str->lon_cntl[i] = cntl_pnt_buf1[i];
1877  l2_str->cntl_pnts[i] = cntl_pnt_buf2[i];
1878  }
1879 
1880 
1881  /* Remove any dateline discontinuity in the longitudes */
1882  /* --------------------------------------------------- */
1883  for (i = 1; i < n_cntl_pnts; i++) {
1884  delta = l2_str->lon_cntl[i] - l2_str->lon_cntl[i - 1];
1885  if (delta < -180) l2_str->lon_cntl[i] += 360;
1886  else if (delta > 180) l2_str->lon_cntl[i] -= 360;
1887  }
1888 
1889  spline(l2_str->cntl_pnts, l2_str->lon_cntl, n_cntl_pnts,
1890  1e30, 1e30, l2_str->spline_arr);
1891 
1892  for (i = 0; i < l2_str->nsamp; i++) {
1893  splint(l2_str->cntl_pnts, l2_str->lon_cntl, l2_str->spline_arr,
1894  n_cntl_pnts,
1895  i + 1.0, &l2_str->longitude[i]);
1896 
1897  /* Put the longitudes back in the [-180,180] range */
1898  /* ----------------------------------------------- */
1899  while (l2_str->longitude[i] > 180)
1900  l2_str->longitude[i] -= 360;
1901  while (l2_str->longitude[i] < -180)
1902  l2_str->longitude[i] += 360;
1903  }
1904 
1905  n_cntl_pnts += n_cntl_pnts_removed;
1906 
1907  free(cntl_pnt_buf1);
1908  free(cntl_pnt_buf2);
1909 
1910  break;
1911 
1912  case 2:
1913  edges2[0] = edges[0];
1914  edges2[2] = 3;
1915  for (i = 0; i < 4; i++) {
1916  edges2[1] = geo_edge[i];
1917  if (ds_id_geonav[ifile][i].sid != -1) {
1918  readDS(ds_id_file[ifile], geonav_name[i], start, NULL, edges2,
1919  (void*) geonav[i]);
1920  }
1921  }
1922 
1923 
1924  geonav_(geonav[0], geonav[1], geonav[2], geonav[3], (int32_t*) & nsta[ifile],
1925  (int32_t*) & ninc[ifile], (int32_t*) & l2_str->nsamp, l2_str->latitude,
1926  l2_str->longitude, (float *) databuf,
1927  (float *) databuf, (float *) databuf,
1928  (float *) databuf);
1929 
1930  break;
1931  }
1932 
1933  return 0;
1934 }
1935 
1936 int32_t closeL2(l2_prod *l2_str, int32_t ifile) {
1937  int32_t i;
1938  int32_t status;
1939 
1940  for (i = 0; i < l2_str->nprod; i++) {
1941  if (ds_id_prod[ifile][i].sid != -1) {
1942  status = endaccessDS(ds_id_prod[ifile][i]);
1943  if (status != 0) {
1944  printf("Error ending access to product sds: %d for file: %d\n",
1945  i, ifile);
1946  exit(-1);
1947  }
1948  }
1949  }
1950 
1951  for (i = 0; i < 3; i++) {
1952  if (ds_id_ll[ifile][i].sid != -1) {
1953  ds_id_file[ifile].sid = ds_id_ll[ifile][i].sid;
1954  status = endaccessDS(ds_id_file[ifile]);
1955  if (status != 0) {
1956  printf("Error ending access to ll sds: %d for file: %d\n", i, ifile);
1957  exit(-1);
1958  }
1959  }
1960  }
1961 
1962  if (l2_str->geointerp == 2) {
1963  for (i = 0; i < 6; i++) {
1964  ds_id_file[ifile].sid = ds_id_geonav[ifile][i].sid;
1965  if (ds_id_geonav[ifile][i].sid != -1)
1966  status = endaccessDS(ds_id_file[ifile]);
1967  if (status != 0) {
1968  printf("Error ending access to geonav sds: %d for file: %d\n",
1969  i, ifile);
1970  exit(-1);
1971  }
1972  }
1973  }
1974 
1975  if (ds_id_l2_flags[ifile].sid != -1) {
1976  status = endaccessDS(ds_id_l2_flags[ifile]);
1977  if (status != 0) {
1978  printf("Error ending access to l2_flags sds for file: %d\n", ifile);
1979  exit(-1);
1980  }
1981  }
1982 
1983 
1984  if (ds_id_eng_qual[ifile].sid != -1) {
1985  status = endaccessDS(ds_id_eng_qual[ifile]);
1986  if (status != 0) {
1987  printf("Error ending access to eng_qual sds for file: %d\n", ifile);
1988  exit(-1);
1989  }
1990  }
1991 
1992 
1993  if (ds_id_s_flags[ifile].sid != -1) {
1994  status = endaccessDS(ds_id_s_flags[ifile]);
1995  if (status != 0) {
1996  printf("Error ending access to s_flags sds for file: %d\n", ifile);
1997  exit(-1);
1998  }
1999  }
2000 
2001  if (ds_id_nflag[ifile].sid != -1) {
2002  status = endaccessDS(ds_id_nflag[ifile]);
2003  if (status != 0) {
2004  printf("Error ending access to n_flag sds for file: %d\n", ifile);
2005  exit(-1);
2006  }
2007  }
2008 
2009  if (ds_id_pixnum[ifile].sid != -1) {
2010  status = endaccessDS(ds_id_pixnum[ifile]);
2011  if (status != 0) {
2012  printf("Error ending access to pixnum sds for file: %d\n", ifile);
2013  exit(-1);
2014  }
2015  }
2016 
2017  status = endDS(ds_id_file[ifile]);
2018  if (status != 0) {
2019  printf("Error ending access to file: %d\n", ifile);
2020  exit(-1);
2021  }
2022 
2023  return 0;
2024 }
2025 
2026 int32_t freeL2(l2_prod *l2_str) {
2027  int32_t i;
2028 
2029  if (l2_str == NULL) {
2030 
2031  for (i = 0; i < MAXNFILES; i++) {
2032  if (prodlist[i] != NULL) free(prodlist[i]);
2033  }
2034 
2035  } else {
2036 
2037  if (l2_str->geointerp == 1) {
2038  free(l2_str->lon_cntl);
2039  free(l2_str->lat_cntl);
2040  free(l2_str->spline_arr);
2041  free(l2_str->cntl_pnts);
2042  }
2043 
2044  for(i = 0; i < l2_str->nprod; i++) {
2045  free(l2_str->l2_data[i]);
2046  }
2047  free(l2_str->l2_data);
2048  free(l2_str->latitude);
2049  free(l2_str->longitude);
2050 
2051  if (l2_str->l2_flags) free(l2_str->l2_flags);
2052  if (l2_str->flagnames) free(l2_str->flagnames);
2053  if (l2_str->pixnum) free(l2_str->pixnum);
2054  if (l2_str->mside) free(l2_str->mside);
2055  if (l2_str->detnum) free(l2_str->detnum);
2056  if (l2_str->year_cache) free(l2_str->year_cache);
2057  if (l2_str->day_cache) free(l2_str->day_cache);
2058  if (l2_str->msec_cache) free(l2_str->msec_cache);
2059 
2060  // free area weighting variables
2061  if(l2_str->lat1) free(l2_str->lat1);
2062  if(l2_str->lon1) free(l2_str->lon1);
2063  if(l2_str->lat2) free(l2_str->lat2);
2064  if(l2_str->lon2) free(l2_str->lon2);
2065 
2066  }
2067 
2068  return 0;
2069 }
2070 
2071 int32_t findprod(l2_prod *l2_str, char* prodname) {
2072  int32_t i;
2073 
2074  for (i = 0; i < l2_str->nprod; i++) {
2075  if (strcmp(l2_str->prodname[i], prodname) == 0) return i;
2076  }
2077 
2078  return -1;
2079 }
2080 
2081 int32_t readL2meta(meta_l2Type *meta_l2, int32_t ifile) {
2082  int32_t dtype;
2083  int32_t count;
2084  idDS ds_id;
2085  int status;
2086  char* titleStr;
2087  char* infilesStr;
2088  char* sennmeStr;
2089  char* dcenterStr;
2090  char* ntimeStr;
2091  char* snodeStr;
2092  char* enodeStr;
2093  char* missionStr;
2094  char* orbnumStr;
2095  char* nlatStr;
2096  char* slatStr;
2097  char* elonStr;
2098  char* wlonStr;
2099  char* stclatStr;
2100  char* stclonStr;
2101  char* endclatStr;
2102  char* endclonStr;
2103  char* nodelStr;
2104 
2105  ds_id = ds_id_file[ifile];
2106 
2107  meta_l2->title = NULL;
2108  meta_l2->infiles = NULL;
2109  meta_l2->sensor_name = NULL;
2110  meta_l2->data_center = NULL;
2111  meta_l2->ctime = NULL;
2112  meta_l2->ntime = NULL;
2113  meta_l2->snode = NULL;
2114  meta_l2->enode = NULL;
2115  meta_l2->mission = NULL;
2116  meta_l2->mission_char = NULL;
2117  meta_l2->sensor = NULL;
2118  meta_l2->sensor_char = NULL;
2119 
2120  // fill up metadata names
2121  if (ds_id.fftype == DS_NCDF) {
2122  titleStr = TITLE;
2123  infilesStr = INFILES;
2124  sennmeStr = SENNME;
2125  dcenterStr = DCENTER;
2126  ntimeStr = NTIME;
2127  snodeStr = SNODE;
2128  enodeStr = ENODE;
2129  missionStr = MISSION;
2130  orbnumStr = ORBNUM;
2131  nlatStr = NLAT;
2132  slatStr = SLAT;
2133  elonStr = ELON;
2134  wlonStr = WLON;
2135  stclatStr = STCLAT;
2136  stclonStr = STCLON;
2137  endclatStr = ENDCLAT;
2138  endclonStr = ENDCLON;
2139  nodelStr = NODEL;
2140  } else {
2141  titleStr = TITLE_OLD;
2142  infilesStr = INFILES_OLD;
2143  sennmeStr = SENNME_OLD;
2144  dcenterStr = DCENTER_OLD;
2145  ntimeStr = NTIME_OLD;
2146  snodeStr = SNODE_OLD;
2147  enodeStr = ENODE_OLD;
2148  missionStr = MISSION_OLD;
2149  orbnumStr = ORBNUM_OLD;
2150  nlatStr = NLAT_OLD;
2151  slatStr = SLAT_OLD;
2152  elonStr = ELON_OLD;
2153  wlonStr = WLON_OLD;
2154  stclatStr = STCLAT_OLD;
2155  stclonStr = STCLON_OLD;
2156  endclatStr = ENDCLAT_OLD;
2157  endclonStr = ENDCLON_OLD;
2158  nodelStr = NODEL_OLD;
2159  }
2160 
2161  status = infoAttr(ds_id, titleStr, &dtype, &count);
2162  if (status != 0) {
2163  printf("Error - Could not find global attribute \"%s\" in file: %d\n", titleStr, ifile);
2164  exit(-1);
2165  }
2166  meta_l2->title = readAttrStr(ds_id, titleStr);
2167 
2168  if (ds_id.fftype == DS_NCDF)
2169  ds_id.fid = grp_id[ifile][5];
2170  if (findAttr(ds_id, infilesStr) != -1) {
2171  meta_l2->infiles = readAttrStr(ds_id, infilesStr);
2172  } else {
2173  if (findAttr(ds_id, "source") != -1) {
2174  meta_l2->infiles = readAttrStr(ds_id, "source");
2175  }
2176  }
2177  if (ds_id.fftype == DS_NCDF)
2178  ds_id = ds_id_file[ifile];
2179 
2180  if (findAttr(ds_id, dcenterStr) != -1) {
2181  meta_l2->data_center = readAttrStr(ds_id, dcenterStr);
2182  }
2183 
2184  if (findAttr(ds_id, NFREC) != -1)
2185  readAttr(ds_id, NFREC, (void*) & meta_l2->nfrec);
2186 
2187  if (findAttr(ds_id, PCTFLAG_OLD) != -1)
2188  readAttr(ds_id, PCTFLAG_OLD, (void*) meta_l2->flags_pc);
2189 
2190  if (findAttr(ds_id, ntimeStr) != -1) {
2191  meta_l2->ntime = readAttrStr(ds_id, ntimeStr);
2192  }
2193 
2194  if (findAttr(ds_id, snodeStr) != -1) {
2195  meta_l2->snode = readAttrStr(ds_id, snodeStr);
2196  }
2197 
2198  if (findAttr(ds_id, enodeStr) != -1) {
2199  meta_l2->enode = readAttrStr(ds_id, enodeStr);
2200  }
2201 
2202  if (ds_id.fftype == DS_HDF) {
2203  if (findAttr(ds_id, sennmeStr) != -1) {
2204  meta_l2->sensor_name = readAttrStr(ds_id, sennmeStr);
2205  }
2206 
2207  if (findAttr(ds_id, missionStr) != -1) {
2208  meta_l2->mission = readAttrStr(ds_id, missionStr);
2209  }
2210 
2211  int sensorID = sensorName2SensorId(meta_l2->sensor_name);
2212  if(sensorID < 0)
2213  meta_l2->sensor = NULL;
2214  else
2215  meta_l2->sensor = strdup(sensorId2InstrumentName(sensorID));
2216  } else {
2217  if (findAttr(ds_id, sennmeStr) != -1) {
2218  meta_l2->sensor = readAttrStr(ds_id, sennmeStr);
2219  }
2220 
2221  if (findAttr(ds_id, missionStr) != -1) {
2222  meta_l2->mission = readAttrStr(ds_id, missionStr);
2223  }
2224 
2225  meta_l2->sensor_name = strdup(instrumentPlatform2SensorName(meta_l2->sensor, meta_l2->mission));
2226  }
2227 
2228  if (findAttr(ds_id, MSNCHAR) != -1) {
2229  meta_l2->mission_char = readAttrStr(ds_id, MSNCHAR);
2230  }
2231 
2232  if (findAttr(ds_id, SNSCHAR) != -1) {
2233  meta_l2->sensor_char = readAttrStr(ds_id, SNSCHAR);
2234  }
2235 
2236  readAttr(ds_id, orbnumStr, (void*) & meta_l2->orbnum);
2237  readAttr(ds_id, nlatStr, (void*) & meta_l2->northlat);
2238  readAttr(ds_id, slatStr, (void*) & meta_l2->southlat);
2239  readAttr(ds_id, wlonStr, (void*) & meta_l2->westlon);
2240  readAttr(ds_id, elonStr, (void*) & meta_l2->eastlon);
2241  readAttr(ds_id, stclatStr, (void*) & meta_l2->startclat);
2242  readAttr(ds_id, stclonStr, (void*) & meta_l2->startclon);
2243  readAttr(ds_id, endclatStr, (void*) & meta_l2->endclat);
2244  readAttr(ds_id, endclonStr, (void*) & meta_l2->endclon);
2245  readAttr(ds_id, nodelStr, (void*) & meta_l2->nodel);
2246 
2247  if (findAttr(ds_id, LAC_PX_ST) != -1)
2248  readAttr(ds_id, LAC_PX_ST, (void*) & meta_l2->pix_start);
2249  if (findAttr(ds_id, LAC_PX_SUBSAMP) != -1)
2250  readAttr(ds_id, LAC_PX_SUBSAMP, (void*) & meta_l2->pix_sub);
2251 
2252  return 0;
2253 }
2254 
2255 int32_t freeL2meta(meta_l2Type *meta_l2) {
2256 #define FREE(ptr) if((ptr) != 0x0) free(ptr);
2257 
2258  FREE(meta_l2->title);
2259  FREE(meta_l2->infiles);
2260  FREE(meta_l2->sensor_name);
2261  FREE(meta_l2->data_center);
2262  FREE(meta_l2->ctime);
2263  FREE(meta_l2->ntime);
2264  FREE(meta_l2->snode);
2265  FREE(meta_l2->enode);
2266  FREE(meta_l2->mission);
2267  FREE(meta_l2->mission_char);
2268  FREE(meta_l2->sensor);
2269  FREE(meta_l2->sensor_char);
2270 
2271  return 0;
2272 }
2273 
2274 int32_t getL3units(l2_prod *l2_str, int32_t ifile, char *l3b_prodname, char *units) {
2275  intn i;
2276 
2277  char bufnum[128];
2278  char bufden[128];
2279  char* char_ptr;
2280  char* tmpStr;
2281 
2282  char_ptr = strchr(l3b_prodname, '/');
2283  if (char_ptr != NULL) *char_ptr = 0;
2284 
2285  memset(bufnum, 0, 128);
2286  memset(bufden, 0, 128);
2287  for (i = 0; i < l2_str[ifile].nprod; i++) {
2288  if (strcmp(l3b_prodname, l2_str[ifile].prodname[i]) == 0) {
2289  idDS ds_id0 = {-ds_id_prod[ifile][i].fid,
2290  ds_id_prod[ifile][i].sid,
2291  ds_id_prod[ifile][i].fftype};
2292  tmpStr = readAttrStr(ds_id0, "units");
2293  if(tmpStr) {
2294  strncpy(bufnum, tmpStr, 127);
2295  free(tmpStr);
2296  } else
2297  strcpy(bufnum, "undefined");
2298  break;
2299  }
2300  }
2301 
2302  if (char_ptr != NULL) {
2303  for (i = 0; i < l2_str[ifile].nprod; i++) {
2304  if (strcmp(char_ptr + 1, l2_str[ifile].prodname[i]) == 0) {
2305  idDS ds_id0 = {-ds_id_prod[ifile][i].fid,
2306  ds_id_prod[ifile][i].sid,
2307  ds_id_prod[ifile][i].fftype};
2308  tmpStr = readAttrStr(ds_id0, "units");
2309  if(tmpStr) {
2310  strncpy(bufden, tmpStr, 127);
2311  free(tmpStr);
2312  } else
2313  strcpy(bufden, "undefined");
2314  break;
2315  }
2316  }
2317 
2318  if (strcmp(bufnum, bufden) == 0) {
2319  if(strcmp(bufnum, "undefined") == 0)
2320  strcpy(units, "undefined");
2321  else
2322  strcpy(units, "dimensionless");
2323  } else if (strcmp(bufnum, "dimensionless") == 0) {
2324  strcpy(units, "1 / ");
2325  strcat(units, bufden);
2326  } else if (strcmp(bufden, "dimensionless") == 0) {
2327  strcpy(units, bufnum);
2328  } else {
2329  strcpy(units, bufnum);
2330  strcat(units, " / ");
2331  strcat(units, bufden);
2332  }
2333 
2334  *char_ptr = '_';
2335  } else {
2336  strcpy(units, bufnum);
2337  }
2338 
2339  return 0;
2340 }
2341 
@ L2PixelOff
Definition: readL2scan.h:154
@ DS_READ
Definition: dfutils.h:24
int32_t openL2(const char *fname, char *plist, l2_prod *l2_str)
Definition: readL2scan.c:296
#define SLAT
Definition: readL2scan.c:96
#define ELON_OLD
Definition: readL2scan.c:101
int32_t readdata_cached(idDS ds_id, char *name, int32_t *start, int32_t *stride, int32_t *edges, void *data, unsigned char *scan_in_rowgroup, cache_str *cache, int32_t dtype)
Definition: readL2scan.c:1059
int32_t reopenL2(int32_t fileindex, l2_prod *l2_str)
Definition: readL2scan.c:975
#define NTIME
Definition: readL2scan.c:81
int getDimsDS(idDS ds_id, const char sdsname[], int32_t dims[])
#define NFREC
Definition: readL2scan.c:78
void allocateDatabuf(l2_prod *l2_str, int maxThirdDim)
Definition: readL2scan.c:283
int status
Definition: l1_czcs_hdf.c:32
int infoAttr(idDS ds_id, const char *nam, int32_t *dtype, int32_t *count)
Definition: wrapper.c:191
#define NODEL_OLD
Definition: readL2scan.c:111
void check_err(const int stat, const int line, const char *file)
Definition: nc4utils.c:35
#define NODEL
Definition: readL2scan.c:110
int32_t lastLine
Definition: readL2scan.c:185
#define PCTFLAG_OLD
Definition: readL2scan.c:80
#define LAC_PX_SUBSAMP
Definition: readL2scan.c:113
int32_t selectDS(idDS ds_id, const char *l2_prod_names)
Definition: wrapper.c:438
int32_t hdf_sizeof(int32_t dtype)
return the sizeof dtype in bytes
Definition: hdf_utils.c:28
@ L2PixelCorner
Definition: readL2scan.h:154
#define ENDCLON
Definition: readL2scan.c:108
void * allocateMemory(size_t numBytes, const char *name)
Definition: allocateMemory.c:7
enum L2PixelMode_t mode
Definition: readL2scan.c:184
int32_t prodtype_t[1000]
Definition: readL2scan.c:130
#define NULL
Definition: decode_rs.h:63
#define ENODE_OLD
Definition: readL2scan.c:86
int32_t escan
Definition: readL2scan.c:117
int32_t readL2meta(meta_l2Type *meta_l2, int32_t ifile)
Definition: readL2scan.c:2081
#define STCLON
Definition: readL2scan.c:104
#define ENDCLAT_OLD
Definition: readL2scan.c:107
#define SNSCHAR
Definition: readL2scan.c:91
int geonav_(FLOAT32 pos[3], FLOAT32 rm[3][3], FLOAT32 coef[6], FLOAT32 sunref[3], INT32 *spix, INT32 *ipix, INT32 *npix, FLOAT32 lat[], FLOAT32 lon[], FLOAT32 solz[], FLOAT32 sola[], FLOAT32 senz[], FLOAT32 sena[])
#define NLAT
Definition: readL2scan.c:94
#define WLON_OLD
Definition: readL2scan.c:99
int sensorName2SensorId(const char *name)
Definition: sensorInfo.c:268
int getTypeDS(idDS ds_id, const char sdsname[HDF4_UTILS_MAX_NAME], int32_t *dtype)
subroutine spline(s, x, y, n, in, t, il, iu, vl, vu, e, u)
Definition: phs.f:1348
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
int32_t freeL2meta(meta_l2Type *meta_l2)
Definition: readL2scan.c:2255
#define ENDCLON_OLD
Definition: readL2scan.c:109
int32_t readL2(l2_prod *l2_str, int32_t ifile, int32_t recnum, int32_t iprod, unsigned char *scan_in_rowgroup)
Definition: readL2scan.c:1250
ds_format_t fftype
Definition: dfutils.h:31
#define DCENTER
Definition: readL2scan.c:76
int32_t closeL2(l2_prod *l2_str, int32_t ifile)
Definition: readL2scan.c:1936
#define LAC_PX_ST
Definition: readL2scan.c:112
#define SNODE
Definition: readL2scan.c:83
int readAttr(idDS ds_id, const char *nam, void *data)
#define ORBNUM_OLD
Definition: readL2scan.c:93
int endaccessDS(idDS ds_id)
Definition: wrapper.c:627
int32_t bscan
Definition: readL2scan.c:116
void init_rowgroup_cache()
Definition: readL2scan.c:265
#define MISSION_OLD
Definition: readL2scan.c:88
def cache(filename, recache=False)
Definition: utils.py:145
void enableL2PixelArea(enum L2PixelMode_t val)
Definition: readL2scan.c:193
data_t tmp
Definition: decode_rs.h:74
#define WLON
Definition: readL2scan.c:98
read recnum
char * readAttrStr(idDS ds_id, const char *name)
Definition: wrapper.c:102
idDS ds_id_geonav_t[6]
Definition: readL2scan.c:141
#define NLAT_OLD
Definition: readL2scan.c:95
#define SNODE_OLD
Definition: readL2scan.c:84
#define NTIME_OLD
Definition: readL2scan.c:82
int32_t get_dtype(int32_t dtype, ds_format_t fileformat)
Definition: readL2scan.c:211
int getProdlist(const char *fname, char **prodlist, int32_t *l2_flags_type)
Definition: wrapper.c:721
char * strdup(const char *)
idDS startDS(const char *filename, ds_format_t format, ds_access_t accessmode, int32_t deflate)
Definition: wrapper.c:561
float slope_t[1000]
Definition: readL2scan.c:133
float32 slope[]
Definition: l2lists.h:30
int8_t findAttr(idDS ds_id, const char *nam)
Definition: wrapper.c:49
void free_rowgroup_cache()
Definition: readL2scan.c:236
int32_t checkDS(idDS ds_id, const char *l2_prod_name)
Definition: wrapper.c:455
#define TITLE_OLD
Definition: readL2scan.c:71
#define SLAT_OLD
Definition: readL2scan.c:97
const double delta
#define MISSION
Definition: readL2scan.c:87
#define ORBNUM
Definition: readL2scan.c:92
#define DCENTER_OLD
Definition: readL2scan.c:77
idDS ds_id_prod_t[1000]
Definition: readL2scan.c:127
float32 intercept[]
Definition: l2lists.h:44
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
float * lastLon
Definition: readL2scan.c:189
void isodate2ydmsec(char *date, int32_t *year, int32_t *day, int32_t *msec)
Definition: date2ydmsec.c:20
@ DS_NCDF
Definition: dfutils.h:20
#define MAXNFILES
Definition: l3bin.cpp:20
int readDS(idDS ds_id, const char *name, int32_t *start, int32_t *stride, int32_t *count, void *data)
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
int32_t sid
Definition: dfutils.h:30
L2PixelMode_t
Definition: readL2scan.h:154
float * lastLat
Definition: readL2scan.c:188
idDS ds_id_ll_t[3]
Definition: readL2scan.c:137
#define TITLE
Definition: readL2scan.c:70
#define INFILES
Definition: readL2scan.c:72
#define STCLON_OLD
Definition: readL2scan.c:105
int32_t dataSize
Definition: readL2scan.c:118
dtype
Definition: DDataset.hpp:31
void calculatePixelDeltas(float *lat0, float *lon0, float *lat1, float *lon1, float *latOut, float *lonOut, int32_t numPoints)
Definition: readL2scan.c:1231
#define SENNME
Definition: readL2scan.c:74
int32_t fid
Definition: dfutils.h:29
Extra metadata that will be written to the HDF4 file l2prod rank
void clampDeltaLon(float *deltaLon)
Definition: readL2scan.c:1124
const char * sensorId2InstrumentName(int sensorId)
Definition: sensorInfo.c:212
subroutine splint(xa, ya, y2a, n, x, y)
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
@ DS_HDF
Definition: dfutils.h:19
Definition: dfutils.h:28
#define ELON
Definition: readL2scan.c:100
#define ENODE
Definition: readL2scan.c:85
for(i=0;i< NROOTS;i++) s[i]
Definition: decode_rs.h:85
#define STCLAT
Definition: readL2scan.c:102
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
ds_format_t
Definition: dfutils.h:18
void * data
Definition: readL2scan.c:119
int32_t getL3units(l2_prod *l2_str, int32_t ifile, char *l3b_prodname, char *units)
Definition: readL2scan.c:2274
void extrapolatePixelCorners(float *lat0, float *lon0, float *lat1, float *lon1, float *latOut, float *lonOut, int32_t numPoints)
Definition: readL2scan.c:1191
int endDS(idDS ds_id)
Definition: wrapper.c:634
#define SENNME_OLD
Definition: readL2scan.c:75
#define abs(a)
Definition: misc.h:90
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
const char * instrumentPlatform2SensorName(const char *instrument, const char *platform)
Definition: sensorInfo.c:357
int32_t sensorID[MAXNFILES]
Definition: l2bin.cpp:97
int32_t freeL2(l2_prod *l2_str)
Definition: readL2scan.c:2026
#define INFILES_OLD
Definition: readL2scan.c:73
#define ENDCLAT
Definition: readL2scan.c:106
void interpolatePixelCorners(float *lat0, float *lon0, float *lat1, float *lon1, float *latOut, float *lonOut, int32_t numPoints)
Definition: readL2scan.c:1150
int32_t grp_id_t[6]
Definition: readL2scan.c:144
#define MSNCHAR
Definition: readL2scan.c:89
int32_t findprod(l2_prod *l2_str, char *prodname)
Definition: readL2scan.c:2071
#define STCLAT_OLD
Definition: readL2scan.c:103
#define FREE(ptr)
int count
Definition: decode_rs.h:79
int32_t readlonlat(l2_prod *l2_str, int32_t ifile, int32_t *start, int32_t *edges, unsigned char *scan_in_rowgroup)
Definition: readL2scan.c:1745