OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
lonlat2pixline.cpp
Go to the documentation of this file.
1 #include <netcdf>
2 #include <cstdio>
3 #include "lonlat2pixline.h"
4 
5 #include <readL2scan.h>
6 
7 #include <string.h>
8 #include <math.h>
9 
10 #include <string>
11 #include <vector>
12 
13 #include <hdf.h>
14 #include <mfhdf.h>
15 
16 using namespace netCDF;
17 using namespace netCDF::exceptions;
18 
19 /* this function is used when comparing lons to see if the lon is
20  * inside the requested lon range. The lons are rotated such that
21  * the first lon in the range is zero then normalized from -180 to 180 */
22 
23 static float normalizeLon(float lon) {
24  while (lon < -180.0)
25  lon += 360.0;
26  while (lon >= 180.0)
27  lon -= 360.0;
28  return lon;
29 }
30 
31 static float rotateLon(float lon, float ref) {
32  return normalizeLon(lon - ref);
33 }
34 
35 static void fixModisResolution(lonlat2pixline_t *params) {
36  int factor = 1;
37  if (params->resolution == 500) {
38  factor = 2;
39  params->spixl = (params->spixl - 1) * factor + 1;
40  params->epixl = (params->epixl - 1) * factor + 1;
41  params->sline = (params->sline - 1) * factor + 1;
42  params->eline = (params->eline - 1) * factor + 1;
43  } else if (params->resolution == 250) {
44  factor = 4;
45  params->spixl = (params->spixl - 1) * factor + 1;
46  params->epixl = (params->epixl - 1) * factor + 1;
47  params->sline = (params->sline - 1) * factor + 1;
48  params->eline = (params->eline - 1) * factor + 1;
49  }
50 }
51 
58 void check_nc(int status, char *file, int line) {
59  if (status != NC_NOERR) {
60  fprintf(stderr, "-E- %s:%d: %s\n",
61  file, line, nc_strerror(status));
62  exit(EXIT_FAILURE);
63  }
64 }
65 
66 /*
67  * Note that if a MODIS GEO file is given with a resolution of 500 or
68  * 250 the pixl and line could be off by 1 or 3 respectively.
69  */
70 int lonlat2pixline(lonlat2pixline_t *params) {
71 
72  int32_t iscan = 0; /* input scan number */
73  int32_t spix = 0; /* start pixel for subscene process */
74  int32_t epix = -1; /* end pixel for subscene process */
75  int32_t sscan = 0; /* start scan for subscene process */
76  int32_t escan = -1; /* end scan for subscene process */
77 
78  int32_t npix = 0; /* Number of output pixels per scan */
79  int32_t nscan = 0; /* Number of output scans */
80 
81  float cornerlon[2]; /* longitude corners of box */
82  float cornerlat[2]; /* latitude corners of box */
83 
84  float filelon[2] = {1000, -1000}; /* longitude corners of file */
85  float filelat[2] = {1000, -1000}; /* latitude corners of file */
86 
87  int32_t status = 0;
88 
89  l1str *l1rec = nullptr; /* generic level-1b scan structure */
90  filehandle *l1file = nullptr; /* input file handle */
91  l1_input_t* input_save = nullptr;
92  int extra_options_save;
93 
94  int32_t ipix;
95  double lon;
96  double lonMiddle;
97  double lat;
98  double uv[3];
99  double uvpix[3];
100  double maxcos = -1;
101  double dot;
102  float pixlon;
103  float pixlat;
104  float normBoxLon[2];
105  float refBoxLon = 0.0; // set to the middle of the requested box
106 
107  int16_t lonTest;
108  int16_t latTest;
109 
110  int32_t minScan = 2147483647;
111  int32_t maxScan = -1;
112  int32_t minPix = 2147483647;
113  int32_t maxPix = -1;
114  int32_t pixsn = -1;
115  int32_t pixpx = -1;
116 
117  int32_t extract_pix_off = 0;
118 
119  int32_t percentDone;
120  int32_t percentFloor = 0;
121 
122  static l2_prod l2_str;
123 
124  char buffer[1024];
125 
126  file_type type;
127 
128  int32_t sd_id; // HDF4 params for MODISGEO
129  int32_t sds_id_ll[2];
130  int32_t start[3] = {0, 0, 0};
131  int32_t edges[3];
132 
133  int ncid; // NetCDF4 params for VIIRSGEONC
134  int grpid, lonid, latid;
135  size_t ncStart[] = {0, 0};
136  size_t ncCount[] = {1, 1};
137 
138  NcFile ncFile; // NetCDF4 params for OLCIGEO
139  NcVar latVar, lonVar;
140  float latScale, lonScale;
141 
142  float latlon[2][2000];
143  float *lonArray;
144  float *latArray;
145 
146  if (params->pix_srch) {
147 
148  /* Generate corner lon/lat if single pixel search */
149  /* ---------------------------------------------- */
150 
151  cornerlon[0] = params->SWlon - 0.025;
152  cornerlon[1] = params->SWlon + 0.025;
153 
154  cornerlat[0] = params->SWlat - 0.025;
155  cornerlat[1] = params->SWlat + 0.025;
156  if (cornerlat[0] < -90) cornerlat[0] = -89.99;
157  if (cornerlat[1] > +90) cornerlat[1] = +89.99;
158 
159  uvpix[0] = cos(params->SWlat / RADEG) * cos(params->SWlon / RADEG);
160  uvpix[1] = cos(params->SWlat / RADEG) * sin(params->SWlon / RADEG);
161  uvpix[2] = sin(params->SWlat / RADEG);
162  } else {
163  cornerlon[0] = params->SWlon;
164  cornerlon[1] = params->NElon;
165  cornerlat[0] = params->SWlat;
166  cornerlat[1] = params->NElat;
167 
168  if (cornerlat[0] > cornerlat[1]) {
169  printf("-E- lonlat2pixline: SW lat must be south of NE lat\n");
170  exit(1);
171  }
172  }
173 
174  /* normalize to +-180 */
175  cornerlon[0] = normalizeLon(cornerlon[0]);
176  cornerlon[1] = normalizeLon(cornerlon[1]);
177  if (cornerlon[1] < cornerlon[0])
178  cornerlon[1] += 360;
179 
180  // setup initial lon for comparing lons
181  refBoxLon = normalizeLon(cornerlon[0] + (cornerlon[1] - cornerlon[0]) / 2);
182  normBoxLon[0] = rotateLon(cornerlon[0], refBoxLon);
183  normBoxLon[1] = rotateLon(cornerlon[1], refBoxLon);
184 
185  type = getFormatType(params->input_filename);
186 
187  if (type == FT_MODISL1B && (params->resolution == 500 || params->resolution == 250)) {
188  printf("-E- lonlat2pixline: Can not have resolution of %d with an Ocean Subsetted MODIS file.\n",
189  params->resolution);
190  exit(1);
191  }
192 
193  if (type == FT_MODISGEO) {
194  int32_t dims[2];
195  int32_t rank, dtype, nattrs;
196  int32_t attrindx;
197 
198  sd_id = SDstart(params->input_filename, DFACC_RDONLY);
199 
200  if (sd_id == -1) {
201  printf("-E- lonlat2pixline: Error opening %s for reading.\n",
202  params->input_filename);
203  exit(1);
204  }
205 
206  sds_id_ll[0] = SDselect(sd_id, SDnametoindex(sd_id, "Latitude"));
207  if (sds_id_ll[0] == -1) {
208  printf("-E- lonlat2pixline: Error opening Latitude field.\n");
209  exit(1);
210  }
211  status = SDgetinfo(sds_id_ll[0], buffer, &rank, dims, &dtype, &nattrs);
212 
213  nscan = dims[0];
214  npix = dims[1];
215 
216  status = SDreadattr(sd_id, SDfindattr(sd_id, "Max Earth Frames"), &epix);
217 
218  epix--;
219  escan = nscan - 1;
220 
221  sds_id_ll[1] = SDselect(sd_id, SDnametoindex(sd_id, "Longitude"));
222  if (sds_id_ll[1] == -1) {
223  printf("-E- lonlat2pixline: Error opening Longitude field.\n");
224  exit(1);
225  }
226 
227  /* Get extract pixel offset if present */
228  attrindx = SDfindattr(sd_id, "Extract Pixel Offset");
229  if (attrindx != -1)
230  status = SDreadattr(sd_id, attrindx, &extract_pix_off);
231 
232  } else if (type == FT_VIIRSGEONC || type == FT_VIIRSL1A || type == FT_VIIRSL1BNC) {
233  int dimids[] = {-1,-1};
234  size_t dimlen;
235  const char* geoname;
236  if(type == FT_VIIRSGEONC) {
237  geoname = params->input_filename;
238  } else {
239  geoname = params->geo_filename;
240  }
241  if(geoname[0] == 0) {
242  fprintf(stderr, "-E- lonlat2pixline: Must supply a geofile for VIIRS.\n");
243  exit(EXIT_FAILURE);
244  }
245 
246  status = nc_open(geoname, NC_NOWRITE, &ncid);
247  if (status != NC_NOERR) {
248  fprintf(stderr,
249  "-E- lonlat2pixline: Error opening %s for reading.\n",
250  geoname);
251  exit(EXIT_FAILURE);
252  }
253 
254  check_nc(nc_inq_grp_ncid(ncid, "geolocation_data", &grpid),
255  __FILE__, __LINE__);
256  check_nc(nc_inq_varid(grpid, "longitude", &lonid),
257  __FILE__, __LINE__);
258  check_nc(nc_inq_varid(grpid, "latitude", &latid),
259  __FILE__, __LINE__);
260 
261  status = nc_inq_vardimid(grpid, latid, dimids);
262  nc_inq_dimlen(ncid, dimids[0], &dimlen);
263  nscan = dimlen;
264  escan = nscan - 1;
265  nc_inq_dimlen(ncid, dimids[1], &dimlen);
266  npix = dimlen;
267  epix = npix - 1;
268 
269  lonArray = (float *) malloc(npix * sizeof(float));
270  latArray = (float *) malloc(npix * sizeof(float));
271 
272  } else if (type == FT_OLCIGEO) {
273  try {
274  nc_set_chunk_cache(10000000, 23, 1.0); // from l1_olci.c
275  ncFile.open(params->input_filename, NcFile::read);
276  latVar = ncFile.getVar("latitude");
277  lonVar = ncFile.getVar("longitude");
278  latVar.getAtt("scale_factor").getValues(&latScale);
279  lonVar.getAtt("scale_factor").getValues(&lonScale);
280 
281  std::vector<NcDim> dims = latVar.getDims();
282  nscan = dims[0].getSize();
283  escan = nscan - 1;
284  npix = dims[1].getSize();
285  epix = npix - 1;
286 
287  lonArray = (float *) malloc(npix * sizeof(float));
288  latArray = (float *) malloc(npix * sizeof(float));
289  }
290 
291  catch(NcException& e) {
292  printf("-E- %s:%d - Problem reading latitude/longitude from file %s\n",
293  __FILE__, __LINE__, params->input_filename);
294  exit(EXIT_FAILURE);
295  }
296 
297  } else if (type == FT_L2HDF || type == FT_L2NCDF || type == FT_L1BNCDF) {
298 
299  status = openL2(params->input_filename, 0x0, &l2_str);
300  if (status) {
301  printf("-E- lonlat2pixline: Error opening %s for reading.\n",
302  params->input_filename);
303  exit(EXIT_FAILURE);
304  }
305 
306  meta_l2Type meta_l2;
307  status = readL2meta(&meta_l2, l2_str.fileindex);
308  if (status) {
309  printf("-E- lonlat2pixline: Error opening %s for reading.\n",
310  params->input_filename);
311  exit(EXIT_FAILURE);
312  }
313 
314  escan = l2_str.nrec;
315  epix = l2_str.nsamp;
316 
317  filelon[0] = normalizeLon(meta_l2.westlon);
318  filelon[1] = normalizeLon(meta_l2.eastlon);
319  if (filelon[1] < filelon[0])
320  filelon[1] += 360;
321  filelat[0] = meta_l2.southlat;
322  filelat[1] = meta_l2.northlat;
323 
324  escan--;
325  epix--;
326 
327  npix = epix - spix + 1;
328  nscan = escan - sscan + 1;
329 
330  // check if the box totally contains the file
331  if (normBoxLon[0] <= rotateLon(filelon[0], refBoxLon) &&
332  normBoxLon[1] >= rotateLon(filelon[1], refBoxLon) &&
333  cornerlat[0] <= filelat[0] &&
334  cornerlat[1] >= filelat[1]) {
335  params->sline = 1;
336  params->eline = escan + 1;
337  params->spixl = 1;
338  params->epixl = epix + 1;
339 
340  // close resources
341  closeL2(&l2_str, 0);
342  freeL2(&l2_str);
343  freeL2(NULL);
344 
345  status = 120;
346  goto bail;
347  }
348 
349  } else if (type > 0) {
350 
351 
352  input_save = l1_input;
353  extra_options_save = clo_getEnableExtraOptions();
355 
356  // allocate structures
357  l1file = (filehandle*) malloc(sizeof (filehandle));
358  l1rec = (l1str*) malloc(sizeof (l1str));
359 
361  l1_input_init();
362 
365  l1file->geofile = params->geo_filename;
366  std::string resolutionStr = std::to_string(params->resolution);
367  clo_setString(optionList, "resolution", resolutionStr.c_str(), nullptr);
368 
369  l1_read_default_files(optionList, l1file, params->input_filename);
372 
373  if (openl1(l1file) != 0) {
374  printf("-E- lonlat2pixline: Error opening %s for reading.\n",
375  params->input_filename);
376  exit(1);
377  }
378 
379  /* */
380  /* Allocate memory for L1 scan data */
381  /* */
382  if (alloc_l1(l1file, l1rec) == 0) {
383  printf("-E- lonlat2pixline: Unable to allocate L1 record.\n");
384  exit(FATAL_ERROR);
385  }
386 
387  l1file->epix = l1file->npix - 1;
388  npix = l1file->npix;
389  nscan = l1file->nscan;
390  epix = l1file->npix - 1;
391  escan = l1file->nscan - 1;
392 
393 
394  l1_input->eline = escan;
395  l1_input->epixl = epix;
396 
397  } else {
398  printf("-E- lonlat2pixline: File type not recognized for %s.\n",
399  params->input_filename);
400  exit(-1);
401  }
402 
403  /* */
404  /* Read file scan by scan */
405  /* */
406 
407  // start out assuming whole box is in the file
408  params->box_failed = 0;
409 
410  /* The stderr output is intended for seadas so users can see */
411  /* some progress if they're processing a large MERIS file. (MAR) */
412  if (want_verbose)
413  fprintf(stderr, "\n");
414  for (iscan = sscan; iscan <= escan; iscan++) {
415 
416  if (type == FT_MODISGEO) {
417  start[0] = iscan;
418  start[1] = 0;
419  edges[0] = 1;
420  edges[1] = npix;
421  status = SDreaddata(sds_id_ll[0], start, NULL, edges,
422  (VOIDP) latlon[0]);
423  status = SDreaddata(sds_id_ll[1], start, NULL, edges,
424  (VOIDP) latlon[1]);
425  lonArray = latlon[1];
426  latArray = latlon[0];
427 
428  } else if (type == FT_VIIRSGEONC || type == FT_VIIRSL1A || type == FT_VIIRSL1BNC) {
429  ncStart[0] = iscan;
430  ncStart[1] = 0;
431  ncCount[0] = 1;
432  ncCount[1] = npix;
433  check_nc(nc_get_vara_float(grpid, lonid, ncStart, ncCount, lonArray),
434  __FILE__, __LINE__);
435  check_nc(nc_get_vara_float(grpid, latid, ncStart, ncCount, latArray),
436  __FILE__, __LINE__);
437 
438  } else if (type == FT_OLCIGEO) {
439  try {
440  std::vector<size_t> ncStart = {(size_t)iscan,0};
441  std::vector<size_t> ncCount = {1,(size_t)npix};
442 
443  latVar.getVar(ncStart, ncCount, latArray);
444  lonVar.getVar(ncStart, ncCount, lonArray);
445 
446  for (ipix = 0; ipix < npix; ipix++) {
447  latArray[ipix] *= latScale;
448  lonArray[ipix] *= lonScale;
449  }
450 
451  }
452  catch(NcException& e) {
453  e.what();
454  exit(EXIT_FAILURE);
455  }
456 
457  } else if (type == FT_L2HDF || type == FT_L2NCDF || type == FT_L1BNCDF) {
458  start[0] = iscan;
459  start[1] = 0;
460  edges[0] = 1;
461  edges[1] = npix;
462  readlonlat(&l2_str, 0, start, edges, NULL);
463  lonArray = l2_str.longitude;
464  latArray = l2_str.latitude;
465 
466  } else {
468  lonArray = l1rec->lon;
469  latArray = l1rec->lat;
470  }
471 
472  //read midpoint of line
473  lonMiddle = normalizeLon(lonArray[npix / 2]);
474 
475  // put min max lon into reasonable range if not set by metadata
476  if (filelon[0] == 1000)
477  filelon[0] = lonMiddle;
478  if (filelon[1] == -1000)
479  filelon[1] = lonMiddle;
480 
481  // see if endpoints of scan line are inside the box
482  // this would cause less than a full box to be extracted
483  if (!params->box_failed) {
484  // check whole first and last line
485  if (iscan == sscan || iscan == escan - 1) {
486  for (ipix = 0; ipix < npix; ipix++) {
487  if (normBoxLon[0] < rotateLon(lonArray[ipix], refBoxLon) &&
488  normBoxLon[1] > rotateLon(lonArray[ipix], refBoxLon) &&
489  cornerlat[0] < latArray[ipix] &&
490  cornerlat[1] > latArray[ipix]) {
491  params->box_failed = 1;
492  }
493  }
494  } else {
495  // check first pixel
496  if (normBoxLon[0] < rotateLon(lonArray[0], refBoxLon) &&
497  normBoxLon[1] > rotateLon(lonArray[0], refBoxLon) &&
498  cornerlat[0] < latArray[0] &&
499  cornerlat[1] > latArray[0]) {
500  params->box_failed = 1;
501  }
502  // check last pixel
503  if (normBoxLon[0] < rotateLon(lonArray[npix - 1], refBoxLon) &&
504  normBoxLon[1] > rotateLon(lonArray[npix - 1], refBoxLon) &&
505  cornerlat[0] < latArray[npix - 1] &&
506  cornerlat[1] > latArray[npix - 1]) {
507  params->box_failed = 1;
508  }
509  }
510  }
511 
512 
513  for (ipix = 0; ipix < npix; ipix++) {
514  lat = latArray[ipix];
515  lon = normalizeLon(lonArray[ipix]);
516 
517  // find file min,max lon and lat
518  if (rotateLon(lon, lonMiddle) > 0) {
519  // check against max
520  if (rotateLon(lon, lonMiddle) > rotateLon(filelon[1], lonMiddle)) {
521  filelon[1] = lon;
522  }
523  } else {
524  // check against min
525  if (rotateLon(lon, lonMiddle) < rotateLon(filelon[0], lonMiddle)) {
526  filelon[0] = lon;
527  }
528  }
529 
530  if (lat < filelat[0]) filelat[0] = lat;
531  if (lat > filelat[1]) filelat[1] = lat;
532 
533  latTest = (lat >= cornerlat[0] && lat <= cornerlat[1]);
534  lonTest = (rotateLon(lon, refBoxLon) >= normBoxLon[0] && rotateLon(lon, refBoxLon) <= normBoxLon[1]);
535 
536  if (lonTest && latTest) {
537  if (ipix < minPix) minPix = ipix;
538  if (iscan < minScan) minScan = iscan;
539  if (ipix > maxPix) maxPix = ipix;
540  if (iscan > maxScan) maxScan = iscan;
541  }
542 
543  } // for ipix
544 
545  if (params->pix_srch && minPix != 2147483647 && maxPix != -1) {
546 
547  for (ipix = minPix; ipix <= maxPix; ipix++) {
548  lat = latArray[ipix] / RADEG;
549  lon = lonArray[ipix] / RADEG;
550 
551  uv[0] = cos(lat) * cos(lon);
552  uv[1] = cos(lat) * sin(lon);
553  uv[2] = sin(lat);
554 
555  dot = uv[0] * uvpix[0] + uv[1] * uvpix[1] + uv[2] * uvpix[2];
556  if (dot > maxcos) {
557  maxcos = dot;
558  pixsn = iscan;
559  pixpx = ipix;
560  pixlon = lon * RADEG;
561  pixlat = lat * RADEG;
562  }
563  }
564  } // if pix search
565 
566  /* Moved this down here so that the output from readl1() wouldn't */
567  /* screw up the stderr output. Looks okay now when run both from */
568  /* the unix command-line and seadas. */
569  if (want_verbose) {
570  percentDone = ((float) iscan / (float) escan)*100.0;
571  if (percentDone >= percentFloor) {
572  percentFloor += 5;
573  fprintf(stderr, "\rlonlat2pixline %2.0lf%% done.",
574  ((float) iscan / (float) escan)*100.0);
575  fflush(stderr);
576  }
577  if (iscan % 500 == 0) {
578  fprintf(stderr, " Reading scan: %d out of %d", iscan, escan);
579  fflush(stderr);
580  }
581  }
582  } // for iscan
583 
584  if (want_verbose) {
585  fprintf(stderr, "\n");
586  fflush(stderr);
587  }
588 
589  if (minScan == 2147483647) minScan = -1;
590  if (minPix == 2147483647) minPix = -1;
591 
592  /* If extract_pixel_offset > 0 then subtract from pixel limits */
593  if (extract_pix_off > 0) {
594  minPix -= extract_pix_off;
595  maxPix -= extract_pix_off;
596  }
597 
598  if (params->pix_srch) {
599  if (pixsn != -1) {
600  if (params->want_pixbox == 1) {
601  params->pixLon = pixlon;
602  params->pixLat = pixlat;
603 
604  ((pixsn + 1 - params->ybox) >= 1) ?
605  (params->sline = pixsn + 1 - params->ybox) :
606  (params->sline = 1);
607 
608  ((pixsn + 1 + params->ybox) <= escan) ?
609  (params->eline = pixsn + 1 + params->ybox) :
610  (params->eline = escan+1);
611 
612  ((pixpx + 1 - extract_pix_off - params->xbox) >= 1) ?
613  (params->spixl = pixpx + 1 - extract_pix_off - params->xbox) :
614  (params->spixl = 1);
615 
616  ((pixpx + 1 - extract_pix_off + params->xbox) <= epix) ?
617  (params->epixl = pixpx + 1 - extract_pix_off + params->xbox) :
618  (params->epixl = epix+1);
619  } else {
620  params->pixLon = pixlon;
621  params->pixLat = pixlat;
622  params->sline = params->eline = pixsn + 1;
623  params->spixl = params->epixl = pixpx + 1 - extract_pix_off;
624  }
625  } else {
626  params->pixLon = 0;
627  params->pixLat = 0;
628  params->sline = 0;
629  params->eline = 0;
630  params->spixl = 0;
631  params->epixl = 0;
632  }
633  } else {
634  params->sline = minScan + 1;
635  params->eline = maxScan + 1;
636  params->spixl = minPix + 1;
637  params->epixl = maxPix + 1;
638  }
639 
640  if (type == FT_MODISGEO) {
641  SDendaccess(sds_id_ll[0]);
642  SDendaccess(sds_id_ll[1]);
643  SDend(sd_id);
644 
645  } else if (type == FT_VIIRSGEONC || type == FT_VIIRSL1A || type == FT_VIIRSL1BNC) {
646  nc_close(ncid);
647  free(lonArray);
648  free(latArray);
649 
650  } else if (type == FT_OLCIGEO) {
651  free(lonArray);
652  free(latArray);
653 
654  } else if (type == FT_L2HDF || type == FT_L2NCDF || type == FT_L1BNCDF) {
655  closeL2(&l2_str, 0);
656  freeL2(&l2_str);
657  freeL2(NULL);
658  } else {
659  free_l1(l1rec);
660  free(l1rec);
661  closel1(l1file);
662  free(l1file);
664  free(l1_input);
665  l1_input = input_save;
666  clo_setEnableExtraOptions(extra_options_save);
667  }
668 
669  if (minScan == -1 || maxScan == -1 || minPix == -1 || maxPix == -1) {
670  // if the box is too small to have any points in it try a
671  // pixel search
672  if (!params->pix_srch &&
673  normBoxLon[0] >= rotateLon(filelon[0], refBoxLon) &&
674  normBoxLon[1] <= rotateLon(filelon[1], refBoxLon) &&
675  cornerlat[0] >= filelat[0] &&
676  cornerlat[1] <= filelat[1]) {
677  params->pix_srch = 1;
679  params->pix_srch = 0;
680  goto bail;
681  } else {
682  status = 100;
683  goto bail;
684  }
685  }
686 
687  if (params->want_pixbox) {
688  if (params->pix_srch) {
689  if ((pixsn + 1 - params->ybox) < 1)
690  params->box_failed = 1;
691  if ((pixpx + 1 - extract_pix_off - params->xbox) < 1)
692  params->box_failed = 1;
693  if ((pixsn + 1 + params->ybox) > escan)
694  params->box_failed = 1;
695  if ((pixpx + 1 - extract_pix_off + params->xbox) > epix)
696  params->box_failed = 1;
697  } else {
698  int x, y;
699  int dx = (params->epixl - params->spixl) / 2;
700  int dy = (params->eline - params->sline) / 2;
701  if (dx < params->xbox) {
702  x = params->spixl + dx;
703  params->spixl = x - params->xbox;
704  params->epixl = x + params->xbox;
705  if (params->spixl < 1) {
706  params->spixl = 1;
707  params->box_failed = 1;
708  }
709  if (params->epixl > npix) {
710  params->epixl = npix;
711  params->box_failed = 1;
712  }
713  } // dx too small
714  if (dy < params->ybox) {
715  y = params->sline + dy;
716  params->sline = y - params->ybox;
717  params->eline = y + params->ybox;
718  if (params->sline < 1) {
719  params->sline = 1;
720  params->box_failed = 1;
721  }
722  if (params->eline > nscan) {
723  params->eline = nscan;
724  params->box_failed = 1;
725  }
726  } // dy too small
727  } // not a pixel search
728  } // want a pixbox
729 
730  // check if the file is totally contained in the box
731  if (params->sline == 1 && params->eline == escan + 1 &&
732  params->spixl == 1 && params->epixl == epix + 1) {
733  status = 120;
734  goto bail;
735  }
736 
737  // check if the box limits goes outside of the file limits
738  if (normBoxLon[0] < rotateLon(filelon[0], refBoxLon) ||
739  normBoxLon[1] > rotateLon(filelon[1], refBoxLon) ||
740  cornerlat[0] < filelat[0] ||
741  cornerlat[1] > filelat[1]) {
742  params->box_failed = 1;
743  }
744 
745  // check if the box goes outside of the file
746  if (params->box_failed)
747  status = 110;
748 
749  // yea, goto is ugly, but it does the trick!!!
750 bail:
751 
752  if (type == FT_MODISGEO)
753  fixModisResolution(params);
754 
755  return (status);
756 }
757 
758 int lonlat2pixline1(char *input_filename, char *geo_filename,
759  int32_t resolution, float SWlon, float SWlat, float NElon, float NElat,
760  int32_t *spixl, int32_t *epixl, int32_t *sline, int32_t * eline) {
761  int result;
762  lonlat2pixline_t params;
763 
764  strcpy(params.input_filename, input_filename);
765  strcpy(params.geo_filename, geo_filename);
766  params.resolution = resolution;
767  params.SWlon = SWlon;
768  params.NElon = NElon;
769  params.SWlat = SWlat;
770  params.NElat = NElat;
771  params.pix_srch = 0;
772  params.want_pixbox = 0;
773 
775  if (result == 0 || result == 110 || result == 120) {
776  *spixl = params.spixl;
777  *epixl = params.epixl;
778  *sline = params.sline;
779  *eline = params.eline;
780  }
781  return result;
782 }
783 
784 int lonlat2pixline2(char *input_filename, char *geo_filename,
785  int32_t resolution, float lon, float lat, int32_t dx, int32_t dy,
786  int32_t *spixl, int32_t *epixl, int32_t *sline, int32_t * eline) {
787  int result;
788  lonlat2pixline_t params;
789 
790  strcpy(params.input_filename, input_filename);
791  strcpy(params.geo_filename, geo_filename);
792  params.resolution = resolution;
793  params.SWlon = lon;
794  params.SWlat = lat;
795  params.xbox = dx;
796  params.ybox = dy;
797  params.pix_srch = 1;
798  params.want_pixbox = 1;
799 
801  if (result == 0 || result == 110 || result == 120) {
802  *spixl = params.spixl;
803  *epixl = params.epixl;
804  *sline = params.sline;
805  *eline = params.eline;
806  }
807  return result;
808 }
809 
810 int lonlat2pixline3(char *input_filename, char *geo_filename,
811  int32_t resolution, float lon, float lat,
812  int32_t *pixl, int32_t *line) {
813  int result;
814  lonlat2pixline_t params;
815 
816  strcpy(params.input_filename, input_filename);
817  strcpy(params.geo_filename, geo_filename);
818  params.resolution = resolution;
819  params.SWlon = lon;
820  params.SWlat = lat;
821  params.pix_srch = 1;
822  params.want_pixbox = 0;
823 
825  if (result == 0 || result == 110 || result == 120) {
826  *pixl = params.spixl;
827  *line = params.sline;
828  }
829  return result;
830 }
831 
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
Definition: l1stat_chk.c:586
int32_t openL2(const char *fname, char *plist, l2_prod *l2_str)
Definition: readL2scan.c:296
file_type getFormatType(char *filename)
Definition: filetype.c:187
void l1_input_init()
Definition: l1_options.c:11
@ FT_L1BNCDF
Definition: filetype.h:19
int status
Definition: l1_czcs_hdf.c:32
@ FT_OLCIGEO
Definition: filetype.h:40
#define NULL
Definition: decode_rs.h:63
void filehandle_init(filehandle *file)
int32_t readL2meta(meta_l2Type *meta_l2, int32_t ifile)
Definition: readL2scan.c:2081
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that resolution
Definition: HISTORY.txt:188
read l1rec
@ FT_VIIRSL1A
Definition: filetype.h:50
@ FT_MODISGEO
Definition: filetype.h:30
float * lat
int lonlat2pixline2(char *input_filename, char *geo_filename, int32_t resolution, float lon, float lat, int32_t dx, int32_t dy, int32_t *spixl, int32_t *epixl, int32_t *sline, int32_t *eline)
int clo_setString(clo_optionList_t *list, const char *key, const char *val, const char *source)
Definition: clo.c:1667
int32 nscan
Definition: l1_czcs_hdf.c:19
@ FT_L2NCDF
Definition: filetype.h:23
@ string
int32_t closeL2(l2_prod *l2_str, int32_t ifile)
Definition: readL2scan.c:1936
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
void l1_input_delete(l1_input_t *input)
Definition: l1_options.c:65
clo_optionList_t * clo_createList()
Definition: clo.c:532
@ FT_VIIRSL1BNC
Definition: filetype.h:52
void l1_add_options(clo_optionList_t *list)
Definition: l1_options.c:76
NcFile * ncFile
l1_input_t * l1_input
Definition: l1_options.c:9
#define FATAL_ERROR
Definition: swl0_parms.h:5
int readl1_lonlat(filehandle *l1file, int32_t recnum, l1str *l1rec)
Definition: l1_io.c:587
void check_nc(int status, char *file, int line)
int lonlat2pixline1(char *input_filename, char *geo_filename, int32_t resolution, float SWlon, float SWlat, float NElon, float NElat, int32_t *spixl, int32_t *epixl, int32_t *sline, int32_t *eline)
int want_verbose
#define RADEG
Definition: czcs_ctl_pt.c:5
void free_l1(l1str *l1rec)
Definition: alloc_l1.c:6
void closel1(filehandle *l1file)
Definition: l1_io.c:68
file_type
Definition: filetype.h:11
dtype
Definition: DDataset.hpp:31
void clo_setEnableExtraOptions(int val)
Definition: clo.c:429
@ FT_VIIRSGEONC
Definition: filetype.h:49
int32 spix
Definition: l1_czcs_hdf.c:21
int32_t iscan
Extra metadata that will be written to the HDF4 file l2prod rank
int lonlat2pixline3(char *input_filename, char *geo_filename, int32_t resolution, float lon, float lat, int32_t *pixl, int32_t *line)
void l1_load_options(clo_optionList_t *list, filehandle *l1file)
Definition: l1_options.c:247
clo_optionList_t * optionList
Definition: l2qc_viirs.cpp:39
void l1_read_default_files(clo_optionList_t *list, filehandle *l1file, const char *ifile)
Definition: l1_options.c:192
void clo_deleteList(clo_optionList_t *list)
Definition: clo.c:875
float * lon
int32 epix
Definition: l1_czcs_hdf.c:23
int32_t alloc_l1(filehandle *l1file, l1str *l1rec)
Definition: alloc_l1.c:15
int clo_getEnableExtraOptions()
Definition: clo.c:439
int lonlat2pixline(lonlat2pixline_t *params)
@ FT_MODISL1B
Definition: filetype.h:31
int openl1(filehandle *l1file)
Definition: l1_io.c:207
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int32_t freeL2(l2_prod *l2_str)
Definition: readL2scan.c:2026
int npix
Definition: get_cmp.c:27
@ FT_L2HDF
Definition: filetype.h:22
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