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 #include <iostream>
17 #include <allocate2d.h>
18 //#include <l1c_latlongrid.h>
19 
20 using namespace netCDF;
21 using namespace netCDF::exceptions;
22 
23 /* this function is used when comparing lons to see if the lon is
24  * inside the requested lon range. The lons are rotated such that
25  * the first lon in the range is zero then normalized from -180 to 180 */
26 
27 static float normalizeLon(float lon) {
28  while (lon < -180.0)
29  lon += 360.0;
30  while (lon >= 180.0)
31  lon -= 360.0;
32  return lon;
33 }
34 
35 static float rotateLon(float lon, float ref) {
36  return normalizeLon(lon - ref);
37 }
38 
39 static void fixModisResolution(lonlat2pixline_t *params) {
40  int factor = 1;
41  if (params->resolution == 500) {
42  factor = 2;
43  params->spixl = (params->spixl - 1) * factor + 1;
44  params->epixl = (params->epixl - 1) * factor + 1;
45  params->sline = (params->sline - 1) * factor + 1;
46  params->eline = (params->eline - 1) * factor + 1;
47  } else if (params->resolution == 250) {
48  factor = 4;
49  params->spixl = (params->spixl - 1) * factor + 1;
50  params->epixl = (params->epixl - 1) * factor + 1;
51  params->sline = (params->sline - 1) * factor + 1;
52  params->eline = (params->eline - 1) * factor + 1;
53  }
54 }
55 
62 void check_nc(int status, char *file, int line) {
63  if (status != NC_NOERR) {
64  fprintf(stderr, "-E- %s:%d: %s\n",
65  file, line, nc_strerror(status));
66  exit(EXIT_FAILURE);
67  }
68 }
69 
70 /*
71  * Note that if a MODIS GEO file is given with a resolution of 500 or
72  * 250 the pixl and line could be off by 1 or 3 respectively.
73  */
74 int lonlat2pixline(lonlat2pixline_t *params) {
75 
76  int32_t iscan = 0; /* input scan number */
77  int32_t spix = 0; /* start pixel for subscene process */
78  int32_t epix = -1; /* end pixel for subscene process */
79  int32_t sscan = 0; /* start scan for subscene process */
80  int32_t escan = -1; /* end scan for subscene process */
81 
82  int32_t npix = 0; /* Number of output pixels per scan */
83  int32_t nscan = 0; /* Number of output scans */
84 
85  float cornerlon[2]; /* longitude corners of box */
86  float cornerlat[2]; /* latitude corners of box */
87 
88  float filelon[2] = {1000, -1000}; /* longitude corners of file */
89  float filelat[2] = {1000, -1000}; /* latitude corners of file */
90 
91  int32_t status = 0;
92 
93  l1str *l1rec = nullptr; /* generic level-1b scan structure */
94  filehandle *l1file = nullptr; /* input file handle */
95  l1_input_t* input_save = nullptr;
96  int extra_options_save;
97 
98  int32_t ipix;
99  double lon;
100  double lonMiddle;
101  double lat;
102  double uv[3];
103  double uvpix[3];
104  double maxcos = -1;
105  double dot;
106  float pixlon;
107  float pixlat;
108  float normBoxLon[2];
109  float refBoxLon = 0.0; // set to the middle of the requested box
110 
111  int16_t lonTest;
112  int16_t latTest;
113 
114  int32_t minScan = 2147483647;
115  int32_t maxScan = -1;
116  int32_t minPix = 2147483647;
117  int32_t maxPix = -1;
118  int32_t pixsn = -1;
119  int32_t pixpx = -1;
120 
121  int32_t extract_pix_off = 0;
122 
123  int32_t percentDone;
124  int32_t percentFloor = 0;
125 
126  static l2_prod l2_str;
127 
128  char buffer[1024];
129 
130  file_type type;
131 
132  int32_t sd_id; // HDF4 params for MODISGEO
133  int32_t sds_id_ll[2];
134  int32_t start[3] = {0, 0, 0};
135  int32_t edges[3];
136 
137  int ncid; // NetCDF4 params for VIIRSGEONC
138  int grpid, lonid, latid;
139  size_t ncStart[] = {0, 0};
140  size_t ncCount[] = {1, 1};
141 
142  NcFile ncFile; // NetCDF4 params for OLCIGEO
143  NcVar latVar, lonVar;
144  float latScale, lonScale;
145 
146  float latlon[2][2000];
147  float *lonArray;
148  float *latArray;
149 
150  if (params->pix_srch) {
151 
152  /* Generate corner lon/lat if single pixel search */
153  /* ---------------------------------------------- */
154 
155  cornerlon[0] = params->SWlon - 0.025;
156  cornerlon[1] = params->SWlon + 0.025;
157 
158  cornerlat[0] = params->SWlat - 0.025;
159  cornerlat[1] = params->SWlat + 0.025;
160  if (cornerlat[0] < -90) cornerlat[0] = -89.99;
161  if (cornerlat[1] > +90) cornerlat[1] = +89.99;
162 
163  uvpix[0] = cos(params->SWlat / RADEG) * cos(params->SWlon / RADEG);
164  uvpix[1] = cos(params->SWlat / RADEG) * sin(params->SWlon / RADEG);
165  uvpix[2] = sin(params->SWlat / RADEG);
166  } else {
167  cornerlon[0] = params->SWlon;
168  cornerlon[1] = params->NElon;
169  cornerlat[0] = params->SWlat;
170  cornerlat[1] = params->NElat;
171 
172  if (cornerlat[0] > cornerlat[1]) {
173  printf("-E- lonlat2pixline: SW lat must be south of NE lat\n");
174  exit(1);
175  }
176  }
177 
178  /* normalize to +-180 */
179  cornerlon[0] = normalizeLon(cornerlon[0]);
180  cornerlon[1] = normalizeLon(cornerlon[1]);
181  if (cornerlon[1] < cornerlon[0])
182  cornerlon[1] += 360;
183 
184  // setup initial lon for comparing lons
185  refBoxLon = normalizeLon(cornerlon[0] + (cornerlon[1] - cornerlon[0]) / 2);
186  normBoxLon[0] = rotateLon(cornerlon[0], refBoxLon);
187  normBoxLon[1] = rotateLon(cornerlon[1], refBoxLon);
188 
189  type = getFormatType(params->input_filename);
190 
191  if (type == FT_MODISGEO) {
192  int32_t dims[2];
193  int32_t rank, dtype, nattrs;
194  int32_t attrindx;
195 
196  sd_id = SDstart(params->input_filename, DFACC_RDONLY);
197 
198  if (sd_id == -1) {
199  printf("-E- lonlat2pixline: Error opening %s for reading.\n",
200  params->input_filename);
201  exit(1);
202  }
203 
204  sds_id_ll[0] = SDselect(sd_id, SDnametoindex(sd_id, "Latitude"));
205  if (sds_id_ll[0] == -1) {
206  printf("-E- lonlat2pixline: Error opening Latitude field.\n");
207  exit(1);
208  }
209  status = SDgetinfo(sds_id_ll[0], buffer, &rank, dims, &dtype, &nattrs);
210 
211  nscan = dims[0];
212  npix = dims[1];
213 
214  status = SDreadattr(sd_id, SDfindattr(sd_id, "Max Earth Frames"), &epix);
215 
216  epix--;
217  escan = nscan - 1;
218 
219  sds_id_ll[1] = SDselect(sd_id, SDnametoindex(sd_id, "Longitude"));
220  if (sds_id_ll[1] == -1) {
221  printf("-E- lonlat2pixline: Error opening Longitude field.\n");
222  exit(1);
223  }
224 
225  /* Get extract pixel offset if present */
226  attrindx = SDfindattr(sd_id, "Extract Pixel Offset");
227  if (attrindx != -1)
228  status = SDreadattr(sd_id, attrindx, &extract_pix_off);
229 
230  } else if (type == FT_VIIRSGEONC || type == FT_VIIRSL1A || type == FT_VIIRSL1BNC) {
231  int dimids[] = {-1,-1};
232  size_t dimlen;
233  const char* geoname;
234  if(type == FT_VIIRSGEONC) {
235  geoname = params->input_filename;
236  } else {
237  geoname = params->geo_filename;
238  }
239  if(geoname[0] == 0) {
240  fprintf(stderr, "-E- lonlat2pixline: Must supply a geofile for VIIRS.\n");
241  exit(EXIT_FAILURE);
242  }
243 
244  status = nc_open(geoname, NC_NOWRITE, &ncid);
245  if (status != NC_NOERR) {
246  fprintf(stderr,
247  "-E- lonlat2pixline: Error opening %s for reading.\n",
248  geoname);
249  exit(EXIT_FAILURE);
250  }
251 
252  check_nc(nc_inq_grp_ncid(ncid, "geolocation_data", &grpid),
253  __FILE__, __LINE__);
254  check_nc(nc_inq_varid(grpid, "longitude", &lonid),
255  __FILE__, __LINE__);
256  check_nc(nc_inq_varid(grpid, "latitude", &latid),
257  __FILE__, __LINE__);
258 
259  status = nc_inq_vardimid(grpid, latid, dimids);
260  nc_inq_dimlen(ncid, dimids[0], &dimlen);
261  nscan = dimlen;
262  escan = nscan - 1;
263  nc_inq_dimlen(ncid, dimids[1], &dimlen);
264  npix = dimlen;
265  epix = npix - 1;
266 
267  lonArray = (float *) malloc(npix * sizeof(float));
268  latArray = (float *) malloc(npix * sizeof(float));
269 
270  } else if (type == FT_OLCIGEO) {
271  try {
272  nc_set_chunk_cache(10000000, 23, 1.0); // from l1_olci.c
273  ncFile.open(params->input_filename, NcFile::read);
274  latVar = ncFile.getVar("latitude");
275  lonVar = ncFile.getVar("longitude");
276  latVar.getAtt("scale_factor").getValues(&latScale);
277  lonVar.getAtt("scale_factor").getValues(&lonScale);
278 
279  std::vector<NcDim> dims = latVar.getDims();
280  nscan = dims[0].getSize();
281  escan = nscan - 1;
282  npix = dims[1].getSize();
283  epix = npix - 1;
284 
285  lonArray = (float *) malloc(npix * sizeof(float));
286  latArray = (float *) malloc(npix * sizeof(float));
287  }
288 
289  catch(NcException& e) {
290  printf("-E- %s:%d - Problem reading latitude/longitude from file %s\n",
291  __FILE__, __LINE__, params->input_filename);
292  exit(EXIT_FAILURE);
293  }
294 
295  } else if (type == FT_L2HDF || type == FT_L2NCDF || type == FT_L1BNCDF) {
296 
297  status = openL2(params->input_filename, 0x0, &l2_str);
298  if (status) {
299  printf("-E- lonlat2pixline: Error opening %s for reading.\n",
300  params->input_filename);
301  exit(EXIT_FAILURE);
302  }
303 
304  meta_l2Type meta_l2;
305  status = readL2meta(&meta_l2, l2_str.fileindex);
306  if (status) {
307  printf("-E- lonlat2pixline: Error opening %s for reading.\n",
308  params->input_filename);
309  exit(EXIT_FAILURE);
310  }
311 
312  escan = l2_str.nrec;
313  epix = l2_str.nsamp;
314 
315  filelon[0] = normalizeLon(meta_l2.westlon);
316  filelon[1] = normalizeLon(meta_l2.eastlon);
317  if (filelon[1] < filelon[0])
318  filelon[1] += 360;
319  filelat[0] = meta_l2.southlat;
320  filelat[1] = meta_l2.northlat;
321 
322  escan--;
323  epix--;
324 
325  npix = epix - spix + 1;
326  nscan = escan - sscan + 1;
327 
328  // check if the box totally contains the file
329  if (normBoxLon[0] <= rotateLon(filelon[0], refBoxLon) &&
330  normBoxLon[1] >= rotateLon(filelon[1], refBoxLon) &&
331  cornerlat[0] <= filelat[0] &&
332  cornerlat[1] >= filelat[1]) {
333  params->sline = 1;
334  params->eline = escan + 1;
335  params->spixl = 1;
336  params->epixl = epix + 1;
337 
338  // close resources
339  closeL2(&l2_str, 0);
340  freeL2(&l2_str);
341  freeL2(NULL);
342 
343  status = 120;
344  goto bail;
345  }
346 
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 }
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
Definition: l1stat_chk.c:586
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:2151
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:51
@ FT_MODISGEO
Definition: filetype.h:30
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:1995
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:66
clo_optionList_t * clo_createList()
Definition: clo.c:532
@ FT_VIIRSL1BNC
Definition: filetype.h:53
int32_t openL2(const char *fname, const char *plist, l2_prod *l2_str)
Definition: readL2scan.c:316
void l1_add_options(clo_optionList_t *list)
Definition: l1_options.c:77
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:640
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
Utility functions for allocating and freeing two-dimensional arrays of various types.
clo_optionList_t * optionList
void free_l1(l1str *l1rec)
Definition: alloc_l1.c:7
void closel1(filehandle *l1file)
Definition: l1_io.c:73
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:50
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:255
void l1_read_default_files(clo_optionList_t *list, filehandle *l1file, const char *ifile)
Definition: l1_options.c:200
void clo_deleteList(clo_optionList_t *list)
Definition: clo.c:875
int32 epix
Definition: l1_czcs_hdf.c:23
int32_t alloc_l1(filehandle *l1file, l1str *l1rec)
Definition: alloc_l1.c:18
int clo_getEnableExtraOptions()
Definition: clo.c:439
int lonlat2pixline(lonlat2pixline_t *params)
int openl1(filehandle *l1file)
Definition: l1_io.c:230
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
double dot(const double *vec1, const double *vec2, size_t n)
computes the scalar/dot product of two vectors
Definition: nav.c:15
int32_t freeL2(l2_prod *l2_str)
Definition: readL2scan.c:2083
int npix
Definition: get_cmp.c:28
@ 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:1828