OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
extract_sub.c
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------
2  File: regen.c
3 
4  Contents:
5  regen - Creates Level1a or level2 data file with
6  the requested subset of the given
7  input data file
8 
9  set_subsc_params - Error checks the given input subscene
10  parameters
11 
12  rdattr - Reads requested attribute
13 
14  getset_gattrs - Reads all the global attributes from the
15  given input file and writes them to the
16  output file
17 
18  dupHDF - Reads given input file and creates skeleton
19  output file with the input file
20  structure
21 
22  set_sds - Reads and writes skeleton SDS in the output
23  file with all the attribute and
24  dimension information
25 
26  write_data - Reads given SDS data, calls subsampling
27  routine to subsample and writes the
28  subsampled data to the output SDS
29 
30  rdslice - Reads requested slice of data from the
31  given named dataset
32 
33  subsample - Calls proper subsampling routine depending
34  upon whether the subsampling is along
35  one dimension or two dimensions
36 
37  update_sds - Updates the specified chunk of data with the
38  given data of the named SDS
39 
40  subsamp_rec - Subsamples data along last dimension
41 
42  subsamp_2D - Subsamples 2D data along two dimensions
43 
44  alloc_nav_buffs - Allocates data buffers
45 
46  get_navdata - Reads sensor metrics from the given input
47  data file
48 
49  alloc_geonav_buffs - Allocates data buffers for geolocation data
50 
51  get_geodata - Calls geonav_ for each subsampled scanline
52  and outputs the geolocation buffers
53 
54  geonav_ - Computes geolocation information for the
55  requested pixels of the given scanline
56 
57  cdata_ - Should be called before geonav_
58 
59  write_coords - Updates scene corordinates info in the
60  output file
61 
62  get_tiltdata - Reads tilt data from the input data file
63 
64  set_tiltdata - Updates the tilt datasets in the output file
65  for the requested subset of data
66 
67  set_l1adata - Processes level 1a data, if the input file
68  is level 1a
69 
70  subsamp_l1adata - Subsamples the given 3D data along last
71  two dimensions ('C' order)
72 
73  set_flags - Accumulates level 2 flags, if the given
74  input file is level 2
75 
76  set_globalattrs - Updates some of the global attributes that
77  depends on the subset
78 
79  free_geonav_buffs - frees buffer space
80 
81  free_nav_buffs - frees buffer space
82 
83  Notes:
84 
85  Other relevant files:
86  regen.h - various #defined constants for level 1a and level 2
87  data, also #includes hdf.h and mfhdf.h
88  regen_proto.h - prototypes of all the functions defined
89 
90 
91  Modification history:
92  Programmer Organization Date Description of change
93  -------------- ------------ -------- ---------------------
94  Lakshmi Kumar Hughes STX 11/22/93 Original development
95  Lakshmi Kumar Hughes STX 12/14/95 Fixed a bug in set_l1adata
96  & a bug in subsamp_l1adata
97  Lakshmi Kumar Hughes STX 02/21/96 Fixed the above bugfix
98  which had some problem
99  Lakshmi Kumar Hughes STX 07/29/96 The variable sun has been
100  renamed as sunref and
101  PROTOTYPE defs have been
102  removed
103  Lakshmi Kumar Hughes STX 02/18/97 Changed variable type of
104  flags from int16 to int32
105 ------------------------------------------------------------------------------*/
106 #include <stdio.h>
107 #include <stdlib.h>
108 #include "hdf.h"
109 #include "mfhdf.h"
110 #include "regen.h"
111 #include "regen_attr.h"
112 #include "regen_proto.h"
113 #include "navigation.h"
114 #include <timeutils.h>
115 
116 #define CHUNK_SZ 500
117 #define L1ADATA "l1a_data"
118 
119 char ERR_MSG[255];
120 
121 /*-----------------------------------------------------------------------------
122  Function: regen
123 
124  Returns: int32 (status)
125  The return code is a negative value if any error occurs, otherwise,
126  returns 0.
127 
128  Description:
129  The function regen regenerates a given level 1a or level2 file.
130  Allows subsampling and subsetting of the data.
131 
132  Parameters: (in calling order)
133  Type Name I/O Description
134  ---- ---- --- -----------
135  char *infile I input file name
136  int32 *ssamp I starting pixel
137  int32 *esamp I ending pixel
138  int32 *srec I starting scan line
139  int32 *erec I ending scan line
140  int32 px_sub I pixel subsampling rate
141  int32 sc_sub I scan subsampling rate
142  char *parm_list I list of parameter names that needs to be
143  subsampled (Optional)
144  char *outfile I output file name
145 
146  Modification history:
147  Programmer Organization Date Description of change
148  -------------- ------------ -------- ---------------------
149  Lakshmi Kumar Hughes STX 03/31/95 Original development
150 ----------------------------------------------------------------------------*/
151 int32
152 regen(char *infile, int32 *ssamp, int32 *esamp, int32 *srec, int32 *erec,
153  int32 px_sub, int32 sc_sub, char *parm_list, char *outfile) {
154  int32 subsc_samps, subsc_recs;
155  int32 ifid, ofid, isdfid, osdfid;
156  int32 xsub = px_sub, ysub = sc_sub;
157  int32 nvgps, nsamp, nrec;
158  int32 max_samp_used, max_rec_used;
159  int32 pix_start, pix_sub;
160  int16 l1aflag;
161  int32 flags[16];
162  char dtype[MAXVAL], title[MAXVAL];
163  NavType nav_rec;
164  GeoType geo_rec;
165  tilt_Type oldtilt_params, newtilt_params;
166  FilemetricsType fm_rec;
167 
168  /*** open the given input HDF file */
169  if ((isdfid = SDstart(infile, DFACC_RDONLY)) < 0) {
170  sprintf(ERR_MSG, "regen: File open unsuccessful");
171  return FAIL;
172  }
173  ifid = Hopen(infile, DFACC_READ, 0);
174  Vstart(ifid);
175 
176  /*** open the given output HDF file */
177  osdfid = SDstart(outfile, DFACC_CREATE);
178  ofid = Hopen(outfile, DFACC_RDWR, 0);
179  Vstart(ofid);
180 
181  /*** find out how many vgroups have been written */
182  if ((nvgps = Hnumber(ifid, DFTAG_VG)) < 0) {
183  sprintf(ERR_MSG, "\n No vgps found\n");
184  return FAIL;
185  }
186 
187  /*** read global attribute "Data Type" */
188  if ((rdattr(isdfid, DTYPE, dtype)) < 0)
189  return FAIL;
190 
191  /*** read global attribute "Title" */
192  if ((rdattr(isdfid, "Title", title)) < 0)
193  return FAIL;
194 
195  /*** read nsamp and nrec */
196  if ((rdattr(isdfid, NSAMP, &nsamp)) < 0)
197  return FAIL;
198 
199  if ((rdattr(isdfid, NREC, &nrec)) < 0)
200  return FAIL;
201 
202  /*** check validity of input paramters and set subscene parameters */
203  set_subsc_params(nsamp, nrec, xsub, ysub, ssamp, esamp, srec, erec,
204  &subsc_samps, &subsc_recs, &max_samp_used,
205  &max_rec_used);
206 
207  /*** set global attributes */
208  if ((getset_gattrs(isdfid, osdfid)) < 0)
209  return FAIL;
210 
211  /*** create vgroups and its objects in the output file */
212  if ((dupHDF(ifid, ofid, isdfid, osdfid, ssamp, esamp, srec, erec,
213  xsub, ysub, subsc_samps, subsc_recs, nvgps, parm_list)) < 0)
214  return FAIL;
215 
216  /*** read sensor metrics */
217  if ((alloc_nav_buffs(nrec, &nav_rec)) < 0)
218  return FAIL;
219 
220  if ((get_navdata(isdfid, nrec, &nav_rec)) < 0)
221  return FAIL;
222 
223  /*** get & update geonavigation datasets and related global attributes */
224  if ((alloc_geonav_buffs(subsc_recs, &geo_rec)) < 0)
225  return FAIL;
226 
227  if ((rdattr(isdfid, PIX_START, &pix_start)) < 0)
228  return FAIL;
229  if ((rdattr(isdfid, PIX_SUB, &pix_sub)) < 0)
230  return FAIL;
231 
232  if ((get_geodata(pix_start, pix_sub, *srec, *ssamp, max_rec_used, subsc_samps,
233  ysub, xsub, dtype, &nav_rec, &geo_rec)) < 0)
234  return FAIL;
235 
236  if ((write_coords(osdfid, subsc_recs, &geo_rec)) < 0)
237  return FAIL;
238 
239  /*** update tilt datasets and related global attributes */
240  if ((get_tiltdata(isdfid, &oldtilt_params)) < 0) return FAIL;
241 
242  if ((set_tiltdata(osdfid, *srec, max_rec_used, ysub, geo_rec.slat,
243  geo_rec.slon, geo_rec.elat, geo_rec.elon,
244  &oldtilt_params, &newtilt_params)) < 0)
245  return FAIL;
246 
247  /*** set pct_flags */
248  if ((strcmp(title, "SeaWiFS Level-2 Data") == 0) ||
249  (strcmp(title, "SeaWiFS Level-2 Q/C Data") == 0)) {
250  if ((set_flags(osdfid, subsc_recs, subsc_samps, flags)) < 0)
251  return FAIL;
252  l1aflag = 0;
253  } else {
254  if ((strcmp(title, "SeaWiFS Level-1A Data")) == 0)
255  l1aflag = 1;
256  else
257  return FAIL;
258  }
259  /*** update l1a_data and related global attributes */
260  if (l1aflag) {
261  if ((set_l1adata(isdfid, osdfid, nrec, nsamp, subsc_recs, subsc_samps,
262  *srec, *ssamp, *erec, *esamp, xsub, ysub, &fm_rec)) < 0)
263  return FAIL;
264  }
265 
266  /*** update required global attributes */
267  if ((set_globalattrs(outfile, osdfid, l1aflag, subsc_recs, subsc_samps,
268  *ssamp, xsub, flags, &geo_rec, &fm_rec)) < 0)
269  return FAIL;
270 
271  /*** free all the allocated buffers */
272  free_geonav_buffs(&geo_rec);
273  free_nav_buffs(&nav_rec);
274 
275  Vend(ifid);
276  SDend(isdfid);
277  Hclose(ifid);
278 
279  Vend(ofid);
280  SDend(osdfid);
281  Hclose(ofid);
282 
283  return SUCCEED;
284 }
285 
286 /*-----------------------------------------------------------------------------
287  Function: set_nparams
288 
289  Returns: None
290 
291  Description:
292  The function set_nparams checks the given input parameters (ssamp,
293  esamp, srec, erec). If any of these parameters are in out of range
294  then the rtn sets proper value to that parameter. Computes
295  subscene dimensions and sets some output paramters
296 
297  Parameters: (in calling order)
298  Type Name I/O Description
299  ---- ---- --- -----------
300  int32 nsamp I number of pixels in the given input file
301  int32 nrec I number of records/scans in the input file
302  int32 *ssamp I starting pixel
303  int32 *esamp I ending pixel
304  int32 *srec I starting scan line
305  int32 *erec I ending scan line
306  int32 *subsc_recs O subscene records
307  int32 *subsc_samps O subscene pixels
308  int32 *max_samp_used O max pixel used in subscene image
309  int32 *max_rec_used O max rec/scanline used in subscece image
310  char *proc_log O processing log
311 
312  Modification history:
313  Programmer Organization Date Description of change
314  -------------- ------------ -------- ---------------------
315  Lakshmi Kumar Hughes STX 04/03/95 Original development
316 ----------------------------------------------------------------------------*/
317 void
318 set_subsc_params(int32 nsamp, int32 nrec, int32 xsub, int32 ysub,
319  int32 *ssamp, int32 *esamp, int32 *srec, int32 *erec,
320  int32 *subsc_samps, int32 *subsc_recs, int32 *max_samp_used,
321  int32 *max_rec_used) {
322 
323  (*ssamp)--;
324  (*esamp)--;
325  (*srec)--;
326  (*erec)--;
327 
328  /*** TODO: make handling of boundary conditions consistent
329  with other extractors; this seems too lenient. ***/
330 
331  if (*ssamp < 0 || *ssamp >= nsamp) {
332  *ssamp = 0;
333  printf("\n***** The given start sample is in error");
334  printf("\n\tresetting ssamp to zero\n\n");
335  }
336 
337  if (*srec < 0 || *srec >= nrec) {
338  *srec = 0;
339  printf("\n***** The given start record is in error");
340  printf("\n\tresetting srec to zero \n\n");
341  }
342 
343  if (*esamp >= nsamp || *esamp < *ssamp) {
344  *esamp = nsamp - 1;
345  printf("\n****** The given end sample is in error ");
346  printf("\n\tresetting esamp to nsamp = %d\n\n", nsamp);
347  }
348 
349  if (*erec >= nrec || *erec < *srec) {
350  *erec = nrec - 1;
351  printf("\n****** The given end record is in error ");
352  printf("\n\tresetting erec to nrec = %d \n\n", nrec);
353  }
354 
355  /*** compute subscene image dimensions */
356 
357  *subsc_recs = ((*erec + 1) - (*srec + 1)) / ysub + 1;
358  *subsc_samps = ((*esamp + 1) - (*ssamp + 1)) / xsub + 1;
359 
360 
361  /*** compute the maximum record and sample numbers used to make the subsampled
362  browse output */
363 
364  *max_rec_used = (*subsc_recs - 1) * ysub + *srec;
365  *max_samp_used = (*subsc_samps - 1) * xsub + *ssamp;
366 }
367 
368 /*-----------------------------------------------------------------------------
369  Function: getset_gattrs
370 
371  Returns: int32 (status)
372  The return code is a negative value if any error occurs, otherwise,
373  returns 0.
374 
375  Description:
376  The function getset_gattrs reads all the global attributes from
377  the given input file and writes them to the output file.
378 
379  Parameters: (in calling order)
380  Type Name I/O Description
381  ---- ---- --- -----------
382  int32 isdfid I SDinterface ID of the input file
383  int32 osdfid I SDinterface ID of the output file
384 
385  Modification history:
386  Programmer Organization Date Description of change
387  -------------- ------------ -------- ---------------------
388  Lakshmi Kumar Hughes STX 04/04/95 Original development
389 ----------------------------------------------------------------------------*/
390 int32 getset_gattrs(int32 isdfid, int32 osdfid) {
391  int32 i, numtype[MAXATTRS], cnt[MAXATTRS];
392  int32 ndatasets, nglobal_attrs;
393  char char_data[MAXVAL], attr_name[MAXATTRS][132];
394 
395  char *charbuf;
396  int32 i32buf[30];
397  int16 i16buf[30];
398  int8 i8buf[30];
399  uint8 ui8buf[30];
400  float32 f32buf[30];
401  float64 f64buf[30];
402 
403  if ((SDfileinfo(isdfid, &ndatasets, &nglobal_attrs)) < 0)
404  return FAIL;
405 
406  for (i = 0; i < nglobal_attrs; i++) {
407  if ((SDattrinfo(isdfid, i, &attr_name[i][0], &numtype[i], &cnt[i])) < 0)
408  return FAIL;
409 
410  switch (numtype[i]) {
411  case DFNT_CHAR:
412  if (cnt[i] > MAXVAL)
413  charbuf = (char *) calloc(cnt[i] + 1, sizeof (char));
414  else
415  charbuf = &char_data[0];
416  if ((SDreadattr(isdfid, i, charbuf)) < 0) {
417  sprintf(ERR_MSG,
418  "get_globalattrs: SDreadattr not successful for attribute %s", attr_name[i]);
419  return FAIL;
420  }
421  if ((SDsetattr(osdfid, attr_name[i], numtype[i], cnt[i],
422  (VOIDP) charbuf)) < 0) {
423  sprintf(ERR_MSG,
424  "get_globalattrs: SDsetattr not successful for attribute %s",
425  attr_name[i]);
426  return FAIL;
427  }
428  if (cnt[i] > MAXVAL)
429  free(charbuf);
430  break;
431  case DFNT_INT32:
432  if ((SDreadattr(isdfid, i, i32buf)) < 0) {
433  sprintf(ERR_MSG,
434  "get_globalattrs: SDreadattr not successful for attribute %s",
435  attr_name[i]);
436  return FAIL;
437  }
438  if ((SDsetattr(osdfid, attr_name[i], numtype[i], cnt[i],
439  (VOIDP) i32buf)) < 0) {
440  sprintf(ERR_MSG,
441  "get_globalattrs: SDsetattr not successful for attribute %s",
442  attr_name[i]);
443  return FAIL;
444  }
445  break;
446  case DFNT_INT16:
447  if ((SDreadattr(isdfid, i, i16buf)) < 0) {
448  sprintf(ERR_MSG,
449  "get_globalattrs:SDreadattr not successful for attribute %s", attr_name[i]);
450  return FAIL;
451  }
452  if ((SDsetattr(osdfid, attr_name[i], numtype[i], cnt[i],
453  (VOIDP) i16buf)) < 0) {
454  sprintf(ERR_MSG,
455  "get_globalattrs: SDsetattr not successful for attribute %s", attr_name[i]);
456 
457  return FAIL;
458  }
459  break;
460  case DFNT_INT8:
461  if ((SDreadattr(isdfid, i, i8buf)) < 0) {
462  sprintf(ERR_MSG,
463  "get_globalattrs: SDreadattr not successful for attribute %s",
464  attr_name[i]);
465  return FAIL;
466  }
467  if ((SDsetattr(osdfid, attr_name[i], numtype[i], cnt[i],
468  (VOIDP) i8buf)) < 0) {
469  sprintf(ERR_MSG,
470  "get_globalattrs: SDsetattr not successful for attribute %s",
471  attr_name[i]);
472  return FAIL;
473  }
474  break;
475  case DFNT_UINT8:
476  if ((SDreadattr(isdfid, i, ui8buf)) < 0) {
477  sprintf(ERR_MSG,
478  "get_globalattrs:SDreadattr unsuccessful for attribute %s",
479  attr_name[i]);
480  return FAIL;
481  }
482  if ((SDsetattr(osdfid, attr_name[i], numtype[i], cnt[i],
483  (VOIDP) ui8buf)) < 0) {
484  sprintf(ERR_MSG,
485  "get_globalattrs:SDsetattr unsuccessful for attribute %s",
486  attr_name[i]);
487  return FAIL;
488  }
489  break;
490  case DFNT_FLOAT32:
491  if ((SDreadattr(isdfid, i, f32buf)) < 0) {
492  sprintf(ERR_MSG,
493  "get_globalattrs: SDreadattr unsuccessful for attr %s",
494  attr_name[i]);
495  return FAIL;
496  }
497  if ((SDsetattr(osdfid, attr_name[i], numtype[i], cnt[i],
498  (VOIDP) f32buf)) < 0) {
499  sprintf(ERR_MSG,
500  "get_globalattrs:SDsetattr unsuccessful for attr %s",
501  attr_name[i]);
502  return FAIL;
503  }
504  break;
505  case DFNT_FLOAT64:
506  if ((SDreadattr(isdfid, i, f64buf)) < 0) {
507  sprintf(ERR_MSG,
508  "get_globalattrs: SDreadattr unsuccessful for attr %s",
509  attr_name[i]);
510  return FAIL;
511  }
512  if ((SDsetattr(osdfid, attr_name[i], numtype[i], cnt[i],
513  (VOIDP) f64buf)) < 0) {
514  sprintf(ERR_MSG,
515  "get_globalattrs:SDsetattr unsuccessful for attr %s",
516  attr_name[i]);
517  return FAIL;
518  }
519  break;
520  default:
521  sprintf(ERR_MSG, "getset_gattrs: Unkown data type - %d\n",
522  numtype[i]);
523  return FAIL;
524  }
525  }
526  /*
527  printf("\n No. of SDSs = %d and global attrs = %d\n", ndatasets,
528  nglobal_attrs);
529  */
530  return SUCCEED;
531 }
532 
533 /*-----------------------------------------------------------------------------
534  Function: dupHDF
535 
536  Returns: int32 (status)
537  The return code is a negative value if any error occurs, otherwise,
538  returns 0.
539 
540  Description:
541  The function dupHDF copies the structure of the given input
542  data file to the given output file
543 
544  Parameters: (in calling order)
545  Type Name I/O Description
546  ---- ---- --- -----------
547  int32 ifid I input file ID
548  int32 ofid I output file ID
549  int32 isdfid I SDinterface ID of input file
550  int32 osdfid I SDinterface ID of output file
551  int32 *ssamp I starting pixel
552  int32 *esamp I ending pixel
553  int32 *srec I starting scan line
554  int32 *erec I ending scan line
555  int32 xsub I pixel subsampling rate
556  int32 ysub I scan subsampling rate
557  int32 subsc_samps I no. of req. subscene samples
558  int32 subsc_recs I no. of req. subscene records
559  int32 nvgps I no. of vgroups present in the input file
560  char *parm_list I list of parameter names that needs to be
561  char *parm_list I list of parameter names that needs to be
562  processed
563 
564  Modification history:
565  Programmer Organization Date Description of change
566  -------------- ------------ -------- ---------------------
567  Lakshmi Kumar Hughes STX 03/31/95 Original development
568 ----------------------------------------------------------------------------*/
569 int32 dupHDF(int32 ifid, int32 ofid, int32 isdfid, int32 osdfid, int32 *ssamp,
570  int32 *esamp, int32 *srec, int32 *erec, int32 xsub,
571  int32 ysub, int32 subsc_samps, int32 subsc_recs, int32 nvgps,
572  char *parm_list) {
573  int32 i, j, n_entries;
574  int32 vref, ivid, ovid;
575  int32 isdsid, osdsid;
576  int32 tag_list[MAXVAL], ref_list[MAXVAL];
577  char vgname[VGNAMELENMAX];
578  char vgclass[VGNAMELENMAX];
579 
580  vref = -1;
581  for (i = 0; i < nvgps; i++) {
582  if ((vref = Vgetid(ifid, vref)) < 0)
583  break;
584  ivid = Vattach(ifid, vref, "r");
585 
586  if ((Vinquire(ivid, &n_entries, vgname)) < 0) {
587  printf("\nError: Vinquire failed for vid = %d\n", ivid);
588  exit(-1);
589  }
590  Vgetclass(ivid, vgclass);
591 
592  if ((strcmp(vgclass, "Dim0.0") != 0) &&
593  (strcmp(vgclass, "Var0.0") != 0) &&
594  (strcmp(vgclass, "CDF0.0") != 0)) {
595  ovid = Vattach(ofid, -1, "w");
596  Vsetclass(ovid, vgclass);
597  Vsetname(ovid, vgname);
598  if ((Vgettagrefs(ivid, tag_list, ref_list, MAXVAL)) < 0)
599  exit(-1);
600  for (j = 0; j < n_entries; j++) {
601  switch (tag_list[j]) {
602  case DFTAG_NDG:
603  case DFTAG_SDG:
604  if ((set_sds(isdfid, osdfid, vgname, ovid, tag_list[j],
605  ref_list[j], subsc_samps, subsc_recs, parm_list,
606  &isdsid, &osdsid)) < 0) return FAIL;
607  if ((write_data(isdfid, osdfid, isdsid, osdsid, *ssamp, *srec,
608  *esamp, *erec, xsub, ysub)) < 0) return FAIL;
609 
610  break;
611  default:
612  printf("\n not processed -- tag = %d", tag_list[j]);
613  break;
614  }
615  }
616  Vdetach(ovid);
617  }
618 
619  Vdetach(ivid);
620  }
621 
622  return SUCCEED;
623 }
624 
625 /*-----------------------------------------------------------------------------
626  Function: set_sds
627 
628  Returns: int32 (status)
629  The return code is a negative value if any error occurs, otherwise,
630  returns 0.
631 
632  Description:
633  The function set_sds reads all the required information of the
634  requested dataset (SDS) from the given input file and creates an
635  SDS with no data in the output file with the same same, attributes
636  and dimensions
637 
638  Parameters: (in calling order)
639  Type Name I/O Description
640  ---- ---- --- -----------
641  int32 isdfid I SDinterface ID of the input file
642  int32 osdfid I SDinterface ID of the output file
643  char *vgname I name of the Vgroup for which the
644  referenced SDS belongs
645  int32 ovid I output file Vgroup ID for which the new
646  SDS should be linked
647  int32 tag I input SDS tag
648  int32 ref I input SDS reference number
649  int32 subsc_samps I no. of output samples/pixels
650  int32 subsc_recs I no. of output records/scans
651  char *parm_list I list of l2 parameters that should be
652  processed
653  int32 *in_sdsid O SDS id of the input file
654  int32 *out_sdsid O SDS id of the output file
655 
656  Modification history:
657  Programmer Organization Date Description of change
658  -------------- ------------ -------- ---------------------
659  Lakshmi Kumar Hughes STX 03/31/95 Original development
660 ----------------------------------------------------------------------------*/
661 int32 set_sds(int32 isdfid, int32 osdfid, char *vgname, int32 ovid,
662  int32 tag, int32 ref, int32 subsc_samps, int32 subsc_recs,
663  char *parm_list, int32 *in_sdsid, int32 *out_sdsid) {
664  int32 i, index, ret;
665  int32 isdsid, osdsid;
666  int32 sdsref, rank, num_type, nattrs, attr_nt;
667  int32 count, idim_id, odim_id, dim_count, dim_num, dim_attrs;
668  int32 olddims[3] = {0, 0, 0}, newdims[3] = {0, 0, 0};
669  int32 start[3] = {0, 0, 0}, edge[3] = {0, 0, 0};
670  int32 found = 0; /* flags */
671  char dim_name[3][MAXVAL], buf[100];
672  char *parm, attr_name[MAXVAL], sdsname[MAXVAL], str[MAXVAL];
673 
674  if ((index = SDreftoindex(isdfid, ref)) < 0)
675  return FAIL;
676  isdsid = SDselect(isdfid, index);
677  if ((ret = SDgetinfo(isdsid, sdsname, &rank, olddims, &num_type, &nattrs)) < 0)
678  return FAIL;
679 
680  if (((strcmp(vgname, "Geophysical Data")) == 0) &&
681  ((strcmp(parm_list, "ALL")) != 0) &&
682  ((strcmp(sdsname, "l2_flags")) != 0)) {
683 
684  strcpy(str, parm_list);
685  parm = strtok(str, " ");
686  while (parm != NULL) {
687  if ((strcmp(parm, sdsname)) == 0) {
688  found = 1;
689  break;
690  }
691  parm = strtok(NULL, " ");
692  }
693 
694  if (!found) {
695  SDendaccess(isdsid);
696  return SUCCEED;
697  }
698  }
699 
700  for (i = 0; i < rank; i++) {
701  newdims[i] = olddims[i];
702  idim_id = SDgetdimid(isdsid, i);
703  if ((ret = SDdiminfo(idim_id, dim_name[i], &dim_count, &dim_num,
704  &dim_attrs)) < 0) return FAIL;
705  /*
706  here "rec" and "nsamp" are kept to be consistent with files created
707  by old (frank's l1agen) G. Fu 12/11/97
708  */
709  if ((strcmp(dim_name[i], "Number of Scan Lines") == 0 ||
710  (strcmp(dim_name[i], "rec")) == 0))
711  newdims[i] = subsc_recs;
712  if ((strcmp(dim_name[i], "Pixels per Scan Line") == 0 ||
713  (strcmp(dim_name[i], "nsamp")) == 0))
714  newdims[i] = subsc_samps;
715  }
716 
717  /*** create SDS with given name and dimensions */
718  if ((osdsid = SDcreate(osdfid, sdsname, num_type, rank, newdims)) < 0)
719  return FAIL;
720 
721  if ((ret = SDwritedata(osdsid, start, NULL, edge, (VOIDP) buf)) < 0)
722  return FAIL;
723 
724  for (i = 0; i < rank; i++) {
725  odim_id = SDgetdimid(osdsid, i);
726  ret = SDsetdimname(odim_id, dim_name[i]);
727  }
728 
729  SDendaccess(isdsid);
730  SDendaccess(osdsid);
731 
732  /*** read attributes of the given sds from the input SeaWiFS file and
733  write them to the output SeaWiFS file */
734  for (ret = 0, i = 0; ret >= 0; i++) {
735  ret = SDattrinfo(isdsid, i, attr_name, &attr_nt, &count);
736  if (ret >= 0) {
737  if ((rdattr(isdsid, attr_name, (VOIDP) str)) < 0) {
738  printf("Error: Unsuccessful reading attribute:%s", attr_name);
739  return FAIL;
740  }
741  if ((SDsetattr(osdsid, attr_name, attr_nt, count, (VOIDP) str)) < 0) {
742  printf("Error: Unsuccessful writing attribute %s", attr_name);
743  return FAIL;
744  }
745  }
746  }
747 
748  /*** link this sds to the given vgruoup ID */
749  if ((sdsref = SDidtoref(osdsid)) < 0) return FAIL;
750  if ((Vaddtagref(ovid, tag, sdsref)) < 0) return FAIL;
751 
752  *in_sdsid = isdsid;
753  *out_sdsid = osdsid;
754 
755  return SUCCEED;
756 }
757 
758 /*-----------------------------------------------------------------------------
759  Function: write_data
760 
761  Returns: int32 (status)
762  The return code is a negative value if any error occurs, otherwise,
763  returns 0.
764 
765  Description:
766  The function write_data reads input SDS, calls subsampling routines
767  and writes it to the output SDS
768 
769  Parameters: (in calling order)
770  Type Name I/O Description
771  ---- ---- --- -----------
772  int32 isdfid I SDinterface ID of input file
773  int32 osdfid I SDinterface ID of output file
774  int32 isdsid I input SDS ID
775  int32 osdsid I output SDS ID
776  int32 ssamp I starting pixel
777  int32 srec I starting scan line
778  int32 esamp I ending pixel
779  int32 erec I ending scan line
780  int32 xsub I pixel subsampling rate
781  int32 ysub I scan subsampling rate
782 
783  Modification history:
784  Programmer Organization Date Description of change
785  -------------- ------------ -------- ---------------------
786  Lakshmi Kumar Hughes STX 03/31/95 Original development
787 ----------------------------------------------------------------------------*/
788 int32 write_data(int32 isdfid, int32 osdfid, int32 isdsid, int32 osdsid,
789  int32 ssamp, int32 srec, int32 esamp, int32 erec,
790  int32 xsub, int32 ysub) {
791 
792  int32 i;
793  int32 rank, num_type, nattrs;
794  int32 idims[3] = {0, 0, 0}, odims[3] = {0, 0, 0};
795  int32 istart[3] = {0, 0, 0}, iedge[3] = {1, 1, 1};
796  int32 ostart[3] = {0, 0, 0}, oedge[3] = {1, 1, 1};
797  char sdsname[MAXVAL];
798  int32 *ii32p, *oi32p;
799  int16 *ii16p, *oi16p;
800  int8 *ii8p, *oi8p;
801  uint8 *iui8p, *oui8p;
802  float32 *if32p, *of32p;
803  float64 *if64p, *of64p;
804  char *icharp, *ocharp;
805 
806  if ((SDgetinfo(isdsid, sdsname, &rank, idims, &num_type, &nattrs)) < 0)
807  return FAIL;
808 
809  if ((SDgetinfo(osdsid, sdsname, &rank, odims, &num_type, &nattrs)) < 0)
810  return FAIL;
811 
812  if (strcmp(sdsname, L1ADATA) == 0)
813  return SUCCEED;
814 
815  for (i = 0; i < rank; i++) {
816  iedge[i] = idims[i];
817  oedge[i] = odims[i];
818  }
819 
820  switch (num_type) {
821  case DFNT_CHAR:
822  if ((icharp = (char *) calloc(iedge[0] * iedge[1] * iedge[2],
823  sizeof (char))) == NULL)
824  return MALLOC_ERR;
825  if ((ocharp = (char *) calloc(oedge[0] * oedge[1] * oedge[2],
826  sizeof (char))) == NULL)
827  return MALLOC_ERR;
828 
829  if ((rdslice(isdfid, sdsname, istart, idims, (VOIDP) icharp)) < 0)
830  return FAIL;
831 
832  if ((idims[0] != odims[0]) || (idims[1] != odims[1])) {
833  subsample(rank, idims, odims, num_type, srec, erec,
834  ssamp, esamp, xsub, ysub, icharp, ocharp);
835 
836  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) ocharp)) < 0)
837  return FAIL;
838  } else
839  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) icharp)) < 0)
840  return FAIL;
841 
842  free(icharp);
843  free(ocharp);
844 
845  break;
846 
847  case DFNT_INT32:
848  if ((ii32p = (int32 *) calloc(iedge[0] * iedge[1] * iedge[2],
849  sizeof (int32))) == NULL)
850  return MALLOC_ERR;
851  if ((oi32p = (int32 *) calloc(oedge[0] * oedge[1] * oedge[2],
852  sizeof (int32))) == NULL)
853  return MALLOC_ERR;
854 
855  if ((rdslice(isdfid, sdsname, istart, idims, (VOIDP) ii32p)) < 0)
856  return FAIL;
857 
858  if ((idims[0] != odims[0]) || (idims[1] != odims[1])) {
859  subsample(rank, idims, odims, num_type, srec, erec,
860  ssamp, esamp, xsub, ysub, ii32p, oi32p);
861 
862  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) oi32p)) < 0)
863  return FAIL;
864  } else
865  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) ii32p)) < 0)
866  return FAIL;
867 
868  free(oi32p);
869  free(ii32p);
870 
871  break;
872 
873  case DFNT_INT16:
874  if ((ii16p = (int16 *) calloc(iedge[0] * iedge[1] * iedge[2],
875  sizeof (int16))) == NULL)
876  return MALLOC_ERR;
877  if ((oi16p = (int16 *) calloc(oedge[0] * oedge[1] * oedge[2],
878  sizeof (int16))) == NULL)
879  return MALLOC_ERR;
880 
881  if ((rdslice(isdfid, sdsname, istart, idims, (VOIDP) ii16p)) < 0)
882  return FAIL;
883 
884  if ((idims[0] != odims[0]) || (idims[1] != odims[1])) {
885  subsample(rank, idims, odims, num_type, srec, erec,
886  ssamp, esamp, xsub, ysub, ii16p, oi16p);
887  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) oi16p)) < 0)
888  return FAIL;
889  } else
890  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) ii16p)) < 0)
891  return FAIL;
892 
893  free(ii16p);
894  free(oi16p);
895  break;
896 
897  case DFNT_INT8:
898  if ((ii8p = (int8 *) calloc(iedge[0] * iedge[1] * iedge[2],
899  sizeof (int8))) == NULL)
900  return MALLOC_ERR;
901  if ((oi8p = (int8 *) calloc(oedge[0] * oedge[1] * oedge[2],
902  sizeof (int8))) == NULL)
903  return MALLOC_ERR;
904 
905  if ((rdslice(isdfid, sdsname, istart, idims, (VOIDP) ii8p)) < 0)
906  return FAIL;
907 
908  if ((idims[0] != odims[0]) || (idims[1] != odims[1])) {
909  subsample(rank, idims, odims, num_type, srec, erec,
910  ssamp, esamp, xsub, ysub, ii8p, oi8p);
911 
912  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) oi8p)) < 0)
913  return FAIL;
914  } else
915  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) ii8p)) < 0)
916  return FAIL;
917  free(ii8p);
918  free(oi8p);
919  break;
920 
921  case DFNT_UINT8:
922  if ((iui8p = (uint8 *) calloc(iedge[0] * iedge[1] * iedge[2],
923  sizeof (uint8))) == NULL)
924  return MALLOC_ERR;
925  if ((oui8p = (uint8 *) calloc(oedge[0] * oedge[1] * oedge[2],
926  sizeof (uint8))) == NULL)
927  return MALLOC_ERR;
928 
929  if ((rdslice(isdfid, sdsname, istart, idims, (VOIDP) iui8p)) < 0)
930  return FAIL;
931 
932  if ((idims[0] != odims[0]) || (idims[1] != odims[1])) {
933  subsample(rank, idims, odims, num_type, srec, erec,
934  ssamp, esamp, xsub, ysub, iui8p, oui8p);
935 
936  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) oui8p)) < 0)
937  return FAIL;
938  } else
939  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) iui8p)) < 0)
940  return FAIL;
941 
942  free(iui8p);
943  free(oui8p);
944  break;
945 
946  case DFNT_FLOAT32:
947  if ((if32p = (float32 *) calloc(iedge[0] * iedge[1] * iedge[2],
948  sizeof (float32))) == NULL)
949  return MALLOC_ERR;
950  if ((of32p = (float32 *) calloc(oedge[0] * oedge[1] * oedge[2],
951  sizeof (float32))) == NULL)
952  return MALLOC_ERR;
953 
954  if ((rdslice(isdfid, sdsname, istart, idims, (VOIDP) if32p)) < 0)
955  return FAIL;
956 
957  if ((idims[0] != odims[0]) || (idims[1] != odims[1])) {
958  subsample(rank, idims, odims, num_type, srec, erec,
959  ssamp, esamp, xsub, ysub, if32p, of32p);
960 
961  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) of32p)) < 0)
962  return FAIL;
963  } else
964  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) if32p)) < 0)
965  return FAIL;
966 
967  free(if32p);
968  free(of32p);
969 
970  break;
971 
972  case DFNT_FLOAT64:
973  if ((if64p = (float64 *) calloc(iedge[0] * iedge[1] * iedge[2],
974  sizeof (float64))) == NULL)
975  return MALLOC_ERR;
976  if ((of64p = (float64 *) calloc(oedge[0] * oedge[1] * oedge[2],
977  sizeof (float64))) == NULL)
978  return MALLOC_ERR;
979 
980  if ((rdslice(isdfid, sdsname, istart, idims, (VOIDP) if64p)) < 0)
981  return FAIL;
982 
983  if ((idims[0] != odims[0]) || (idims[1] != odims[1])) {
984  subsample(rank, idims, odims, num_type, srec, erec,
985  ssamp, esamp, xsub, ysub, if64p, of64p);
986 
987  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) of64p)) < 0)
988  return FAIL;
989  } else
990  if ((update_sds(osdfid, sdsname, ostart, odims, (VOIDP) if64p)) < 0)
991  return FAIL;
992 
993  free(if64p);
994  free(of64p);
995 
996  break;
997  default:
998  sprintf(ERR_MSG,
999  "write_data: sds %s not processed - unkonwn data type - %d",
1000  sdsname, num_type);
1001  return FAIL;
1002  }
1003 
1004  return SUCCEED;
1005 }
1006 
1007 /*-----------------------------------------------------------------------------
1008  Function: subsample
1009 
1010  Returns: int32 (status)
1011  The return code is a negative value if any error occurs, otherwise,
1012  returns 0.
1013 
1014  Description:
1015  The function subsample calls proper subsampling routine depending
1016  upon whether the subsampling is along one dimension or two dimensions
1017 
1018  Parameters: (in calling order)
1019  Type Name I/O Description
1020  ---- ---- --- -----------
1021  int32 rank I no. of dimensions
1022  int32 *idims I input data dimensions
1023  int32 *odims I output data dimensions
1024  int32 num_type I data type
1025  int32 srec I starting scan line
1026  int32 erec I ending scan line
1027  int32 ssamp I starting pixel
1028  int32 esamp I ending pixel
1029  int32 xsub I pixel subsampling rate
1030  int32 ysub I scan subsampling rate
1031  void *ibuf I input data buffer
1032  void *obuf O output data buffer
1033 
1034  Modification history:
1035  Programmer Organization Date Description of change
1036  -------------- ------------ -------- ---------------------
1037  Lakshmi Kumar Hughes STX 03/31/95 Original development
1038 ----------------------------------------------------------------------------*/
1039 int32 subsample(int32 rank, int32 *idims, int32 *odims, int32 num_type,
1040  int32 srec, int32 erec, int32 ssamp, int32 esamp,
1041  int32 xsub, int32 ysub, void *ibuf, void *obuf) {
1042 
1043  int32 subsc_recs;
1044  int32 maxrec;
1045 
1046 
1047  /*** compute subscene image dimensions */
1048 
1049  subsc_recs = ((erec + 1) - (srec + 1)) / ysub + 1;
1050 
1051  /*** compute the last record no. that should be processed*/
1052 
1053  maxrec = (subsc_recs - 1) * ysub + srec;
1054 
1055  if (idims[1] == odims[1]) {
1056  if ((subsamp_rec(srec, maxrec, rank, odims, ysub, num_type, ibuf, obuf))
1057  < 0) return FAIL;
1058  } else
1059  subsamp_2D(ssamp, srec, esamp, erec, idims[1], xsub, ysub, num_type,
1060  ibuf, obuf);
1061 
1062  return SUCCEED;
1063 }
1064 
1065 /*-----------------------------------------------------------------------------
1066  Function: rdattr
1067 
1068  Returns: int32 (status)
1069  The return code is a negative value if any error occurs, otherwise,
1070  returns 0.
1071 
1072  Description:
1073  The function rdattr reads the requested global attribute
1074 
1075  Parameters: (in calling order)
1076  Type Name I/O Description
1077  ---- ---- --- -----------
1078  int32 sdfid I ID req to access HDF SDS interface
1079  char * attr_name I attribute name
1080  void * buf O data buffer
1081 
1082  Modification history:
1083  Programmer Organization Date Description of change
1084  -------------- ------------ -------- ---------------------
1085  Lakshmi Kumar Hughes STX 11/07/94 Original development
1086 ----------------------------------------------------------------------------*/
1087 int32 rdattr(int32 sdfid, char *attr_name, void *buf) {
1088  int32 attrnum;
1089 
1090  attrnum = SDfindattr(sdfid, attr_name);
1091  if ((SDreadattr(sdfid, attrnum, buf)) < 0) {
1092  sprintf(ERR_MSG, "rdattr: SDreadattr not successful for attribute %s",
1093  attr_name);
1094  return FAIL;
1095  }
1096  return SUCCEED;
1097 }
1098 
1099 /*-----------------------------------------------------------------------------
1100  Function: rdslice
1101 
1102  Returns: int32 (sdsid)
1103  The return code is a negative value if any error occurs, otherwise,
1104  returns sdsid.
1105 
1106  Description:
1107  The function rdslice reads requested slice of data from the
1108  given named dataset
1109 
1110  Parameters: (in calling order)
1111  Type Name I/O Description
1112  ---- ---- --- -----------
1113  int32 sdfid I ID req to access HDF SDS interface
1114  char *name I SDS name
1115  int32 *start I start data dimension
1116  int32 *edge I no. of values to be read
1117  void *buf O SDS data buffer
1118 
1119  NOTE:
1120 
1121  Modification history:
1122  Programmer Organization Date Description of change
1123  -------------- ------------ -------- ---------------------
1124  Lakshmi Kumar Hughes STX 11/02/94 Original development
1125 ----------------------------------------------------------------------------*/
1126 int32 rdslice(int32 sdfid, char *name, int32 *start, int32 *edge, void *buf) {
1127  int32 index, sdsid, rank, num_type, nattrs;
1128  char sdsname[MAXVAL];
1129  /*
1130  clock_t val, val2;
1131  */
1132  if ((index = SDnametoindex(sdfid, name)) < 0) {
1133  sprintf(ERR_MSG, "rdslice: Cannot locate sds \"%s\" ", name);
1134  return FAIL;
1135  }
1136  if ((sdsid = SDselect(sdfid, index)) < 0) {
1137  sprintf(ERR_MSG, "rdslice: SDselect failed for sds \"%s\" ", name);
1138  return FAIL;
1139  }
1140 
1141  if (edge[0] == 0 && edge[1] == 0 && edge[2] == 0)
1142  if ((SDgetinfo(sdsid, sdsname, &rank, edge, &num_type, &nattrs)) < 0)
1143  return FAIL;
1144  /*
1145  val = clock();
1146  */
1147  if ((SDreaddata(sdsid, start, NULL, edge, buf)) < 0) {
1148  sprintf(ERR_MSG,
1149  "rdslice: SDreaddata error while reading \"%s\" ", name);
1150  return FAIL;
1151  }
1152  /*
1153  val2 = clock();
1154  printf("\ntime took for %s = %d\n", name, val2-val);
1155  */
1156  SDendaccess(sdsid);
1157  return SUCCEED;
1158 }
1159 
1160 /*-----------------------------------------------------------------------------
1161  Function: update_sds
1162 
1163  Returns: int32 (sdsid)
1164  The return code is a negative value if any error occurs, otherwise,
1165  returns sdsid.
1166 
1167  Description:
1168  The function update_sds writes/overwrites the given data of the
1169  named sds of the given file. The start and edge specifies the
1170  starting location and no. of values that should be overwritten
1171 
1172  Parameters: (in calling order)
1173  Type Name I/O Description
1174  ---- ---- --- -----------
1175  int32 sdfid I SDinterface ID of the input data file
1176  char *name I SDS name
1177  int32 *start I start data dimensions
1178  int32 *edge I no. of values to be read alon each dim.
1179  void *buf O data buffer
1180 
1181  NOTE:
1182 
1183  Modification history:
1184  Programmer Organization Date Description of change
1185  -------------- ------------ -------- ---------------------
1186  Lakshmi Kumar Hughes STX 11/02/94 Original development
1187 ----------------------------------------------------------------------------*/
1188 int32 update_sds(int32 sdfid, char *name, int32 *start, int32 *edge, void *buf) {
1189  int32 sdsid, index;
1190  int32 rank, num_type, nattrs;
1191  char sdsname[MAXVAL];
1192 
1193  if ((index = SDnametoindex(sdfid, name)) < 0) {
1194  sprintf(ERR_MSG, "update_sds: Cannot locate sds \"%s\" ", name);
1195  return FAIL;
1196  }
1197  if ((sdsid = SDselect(sdfid, index)) < 0) {
1198  sprintf(ERR_MSG, "update_sds: SDselect failed for sds \"%s\" ", name);
1199  return FAIL;
1200  }
1201 
1202  if (edge[0] == 0 && edge[1] == 0 && edge[2] == 0)
1203  if ((SDgetinfo(sdsid, sdsname, &rank, edge, &num_type, &nattrs)) < 0)
1204  return FAIL;
1205 
1206  if ((SDwritedata(sdsid, start, NULL, edge, buf)) < 0) {
1207  sprintf(ERR_MSG,
1208  "update_sds: SDwritedata error while writing \"%s\" ", name);
1209  return FAIL;
1210  }
1211  return SUCCEED;
1212 }
1213 
1214 /*-----------------------------------------------------------------------------
1215  Function: alloc_geonav_buffs
1216 
1217  Returns: int32 (status)
1218  The return code is a negative value if any error occurs, otherwise,
1219  returns 0.
1220 
1221  Description:
1222  The function alloc_geonav_buffs allocates buffers for storing
1223  starting, ending and center scene coordinates of each scan line rec
1224 
1225  Parameters: (in calling order)
1226  Type Name I/O Description
1227  ---- ---- --- -----------
1228  int32 nrec I number of records/scanlines
1229  GeoType *geo_rec O structrue to hold allocated buffers
1230 
1231  Modification history:
1232  Programmer Organization Date Description of change
1233  -------------- ------------ -------- ---------------------
1234  Lakshmi Kumar Hughes STX 04/03/95 Original development
1235 ----------------------------------------------------------------------------*/
1236 int32 alloc_geonav_buffs(int32 nrec, GeoType *geo_rec) {
1237 
1238  /*** allocate space for geodata information */
1239  if ((geo_rec->slat = (float32 *) calloc(nrec, sizeof (float32))) == NULL)
1240  return MALLOC_ERR;
1241 
1242  if ((geo_rec->slon = (float32 *) calloc(nrec, sizeof (float32))) == NULL)
1243  return MALLOC_ERR;
1244 
1245  if ((geo_rec->elat = (float32 *) calloc(nrec, sizeof (float32))) == NULL)
1246  return MALLOC_ERR;
1247 
1248  if ((geo_rec->elon = (float32 *) calloc(nrec, sizeof (float32))) == NULL)
1249  return MALLOC_ERR;
1250 
1251  if ((geo_rec->clat = (float32 *) calloc(nrec, sizeof (float32))) == NULL)
1252  return MALLOC_ERR;
1253 
1254  if ((geo_rec->clon = (float32 *) calloc(nrec, sizeof (float32))) == NULL)
1255  return MALLOC_ERR;
1256 
1257  if ((geo_rec->csol_z = (float32 *) calloc(nrec, sizeof (float32))) == NULL)
1258  return MALLOC_ERR;
1259 
1260  return SUCCEED;
1261 }
1262 
1263 /*-----------------------------------------------------------------------------
1264  Function: free_geonav_buffs
1265 
1266  Returns: None
1267 
1268  Description:
1269  The function free_geonav_buffs frees all the scene coordinate buffers
1270 
1271  Parameters: (in calling order)
1272  Type Name I/O Description
1273  ---- ---- --- -----------
1274  GeoType *geo_rec I structrue containing scene coordinates
1275  buffers
1276 
1277  Modification history:
1278  Programmer Organization Date Description of change
1279  -------------- ------------ -------- ---------------------
1280  Lakshmi Kumar Hughes STX 04/03/95 Original development
1281 ----------------------------------------------------------------------------*/
1282 void free_geonav_buffs(GeoType *geo_rec) {
1283  free(geo_rec->slat);
1284  free(geo_rec->slon);
1285  free(geo_rec->elat);
1286  free(geo_rec->elon);
1287  free(geo_rec->clat);
1288  free(geo_rec->clon);
1289  free(geo_rec->csol_z);
1290 }
1291 
1292 /*-----------------------------------------------------------------------------
1293  Function: get_geodata
1294 
1295  Returns: int32 (sdsid)
1296  The return code is a negative value if any error occurs, otherwise,
1297  returns sdsid.
1298 
1299  Description:
1300  The function get_geodata calls cdata_ and geonav_ (Fortran functions)
1301  to get scene coordinates information for the starting, center and
1302  end pixels of each output (subscene) scanline
1303 
1304  Parameters: (in calling order)
1305  Type Name I/O Description
1306  ---- ---- --- -----------
1307  int32 pix_start I LAC pixel start number from the input file
1308  int32 pix_sub I LAC pixel subsampling from the input file
1309  int32 srec I start record number
1310  int32 ssamp I start sample number
1311  int32 max_rec_used I last record number to be processed
1312  int32 subsc_samps I output scene samples
1313  int32 ysub I subsampling rate along Y-axis
1314  int32 xsub I subsampling rate along X-axis
1315  char *dtype I data type (GAC, LAC, etc..)
1316  NavType *nav_rec I sensor metrics data structure
1317  GeoType *geo_rec O scene coordinates data structure
1318 
1319  NOTE:
1320 
1321  Modification history:
1322  Programmer Organization Date Description of change
1323  -------------- ------------ -------- ---------------------
1324  Lakshmi Kumar Hughes STX 11/02/94 Original development
1325 ----------------------------------------------------------------------------*/
1326 int32 get_geodata(int32 pix_start, int32 pix_sub, int32 srec, int32 ssamp,
1327  int32 max_rec_used, int32 subsc_samps, int32 ysub, int32 xsub,
1328  char *dtype, NavType *nav_rec, GeoType *geo_rec) {
1329 
1330  int32 i, j, k, row, col, rec, scan, st_px, px_sub, npix;
1331  float32 xlat[1285], xlon[1285], solz[1285], sola[1285];
1332  float32 senz[1285], sena[1285];
1333  float32 pos[3], smat[3][3], coef[6], sunref[3];
1334 
1335  if (strcmp(dtype, "GAC") == 0) {
1336  st_px = pix_start + ssamp * 4; /* updated by G. Fu 12/5/97 */
1337  px_sub = ((subsc_samps - 1) * xsub * pix_sub) / 2;
1338  } else {
1339  st_px = pix_start + ssamp;
1340  px_sub = ((subsc_samps - 1) * xsub * pix_sub) / 2;
1341  }
1342 
1343  npix = 3;
1344 
1345  /* call cdata.f to initialize global FORTRAN common block data */
1346  cdata_();
1347 
1348  for (scan = 0, rec = srec; rec <= max_rec_used; rec += ysub, scan++) {
1349  for (j = rec * 3, row = 0; row < 3; row++, j++) {
1350  pos[row] = nav_rec->orb_vec[j];
1351  sunref[row] = nav_rec->sun_ref[j];
1352  for (k = j * 3, col = 0; col < 3; col++, k++)
1353  smat[row][col] = nav_rec->sen_mat[k];
1354  }
1355 
1356  for (i = rec * 6, row = 0; row < 6; row++, i++)
1357  coef[row] = nav_rec->scan_ell[i];
1358 
1359  geonav_(pos, (float*) smat, coef, sunref, &st_px, &px_sub, &npix, xlat, xlon,
1360  solz, sola, senz, sena);
1361 
1362  geo_rec->slat[scan] = xlat[0];
1363  geo_rec->slon[scan] = xlon[0];
1364  geo_rec->clat[scan] = xlat[1];
1365  geo_rec->clon[scan] = xlon[1];
1366  geo_rec->elat[scan] = xlat[2];
1367  geo_rec->elon[scan] = xlon[2];
1368  geo_rec->csol_z[scan] = solz[1];
1369  }
1370 
1371  return SUCCEED;
1372 }
1373 
1374 /*-----------------------------------------------------------------------------
1375  Function: write_coords
1376 
1377  Returns: int32 (sdsid)
1378  The return code is a negative value if any error occurs, otherwise,
1379  returns sdsid.
1380 
1381  Description:
1382  The function write_coords
1383 
1384  Parameters: (in calling order)
1385  Type Name I/O Description
1386  ---- ---- --- -----------
1387  int32 sdfid I SDinterface ID of output file
1388  int32 nrec I number of records
1389  GeoType *geo_rec I scene coordinates data structure
1390 
1391  NOTE:
1392 
1393  Modification history:
1394  Programmer Organization Date Description of change
1395  -------------- ------------ -------- ---------------------
1396  Lakshmi Kumar Hughes STX 11/02/94 Original development
1397 ----------------------------------------------------------------------------*/
1398 int32 write_coords(int32 sdfid, int32 nrec, GeoType *geo_rec) {
1399  int32 start[3] = {0, 0, 0}, edge[3] = {0, 0, 0};
1400 
1401  edge[0] = nrec;
1402 
1403  /*** call getdims only once for getting scene coords dimensions */
1404 
1405  if ((update_sds(sdfid, SLAT, start, edge, (VOIDP) geo_rec->slat)) < 0)
1406  return FAIL;
1407  if ((update_sds(sdfid, SLON, start, edge, (VOIDP) geo_rec->slon)) < 0)
1408  return FAIL;
1409  if ((update_sds(sdfid, CLAT, start, edge, (VOIDP) geo_rec->clat)) < 0)
1410  return FAIL;
1411  if ((update_sds(sdfid, CLON, start, edge, (VOIDP) geo_rec->clon)) < 0)
1412  return FAIL;
1413  if ((update_sds(sdfid, ELAT, start, edge, (VOIDP) geo_rec->elat)) < 0)
1414  return FAIL;
1415  if ((update_sds(sdfid, ELON, start, edge, (VOIDP) geo_rec->elon)) < 0)
1416  return FAIL;
1417  if ((update_sds(sdfid, CSOLZ, start, edge, (VOIDP) geo_rec->csol_z)) < 0)
1418  return FAIL;
1419  return SUCCEED;
1420 }
1421 
1422 /*-----------------------------------------------------------------------------
1423  Function: get_tiltdata
1424 
1425  Returns: int32 (sdsid)
1426  The return code is a negative value if any error occurs, otherwise,
1427  returns sdsid.
1428 
1429  Description:
1430  The function get_tiltdata reads tilt datasets from the given input
1431  file
1432 
1433  Parameters: (in calling order)
1434  Type Name I/O Description
1435  ---- ---- --- -----------
1436  int32 sdfid I ID req to access HDF SDS interface
1437  tilt_Type *tiltrec I structure containing tilt data buffers
1438 
1439  NOTE:
1440 
1441  Modification history:
1442  Programmer Organization Date Description of change
1443  -------------- ------------ -------- ---------------------
1444  Lakshmi Kumar Hughes STX 11/02/94 Original development
1445 ----------------------------------------------------------------------------*/
1446 int32 get_tiltdata(int32 sdfid, tilt_Type *tiltrec) {
1447  int32 start[3] = {0, 0, 0}, edge[3];
1448 
1449  edge[0] = edge[1] = edge[2] = 0;
1450  if ((rdslice(sdfid, NTILTS, start, edge, (VOIDP) & tiltrec->ntilts)) < 0)
1451  return FAIL;
1452 
1453  edge[0] = edge[1] = edge[2] = 0;
1454  if ((rdslice(sdfid, TILTFLAGS, start, edge, (VOIDP) tiltrec->tilt_flags)) < 0)
1455  return FAIL;
1456 
1457  edge[0] = edge[1] = edge[2] = 0;
1458  if ((rdslice(sdfid, TILTRANGES, start, edge, (VOIDP) tiltrec->tilt_ranges)) < 0)
1459  return FAIL;
1460 
1461  edge[0] = edge[1] = edge[2] = 0;
1462  if ((rdslice(sdfid, TILTLATS, start, edge, (VOIDP) tiltrec->tilt_lats)) < 0)
1463  return FAIL;
1464 
1465  edge[0] = edge[1] = edge[2] = 0;
1466  if ((rdslice(sdfid, TILTLONS, start, edge, (VOIDP) tiltrec->tilt_lons)) < 0)
1467  return FAIL;
1468 
1469  return SUCCEED;
1470 }
1471 
1472 /*-----------------------------------------------------------------------------
1473  Function: set_tiltdata
1474 
1475  Returns: int32 (sdsid)
1476  The return code is a negative value if any error occurs, otherwise,
1477  returns sdsid.
1478 
1479  Description:
1480  The function set_tiltdata
1481 
1482  Parameters: (in calling order)
1483  Type Name I/O Description
1484  ---- ---- --- -----------
1485  int32 sdfid I ID req to access HDF SDS interface
1486  int32 srec I start record
1487  int32 erec I ending record/scanline
1488  int32 ysub I scan subsampling rate
1489  float32 *slatrec I starting latitude points
1490  float32 *slonrec I starting longitude points
1491  float32 *elatrec I ending latitude points
1492  float32 *elonrec I ending longitude points
1493  tilt_Type *old_tiltrec I structure containing input tilt datasets
1494  tilt_Type *new_tiltrec O structure containing output tilt datasets
1495 
1496  NOTE:
1497 
1498  Modification history:
1499  Programmer Organization Date Description of change
1500  -------------- ------------ -------- ---------------------
1501  Lakshmi Kumar Hughes STX 04/03/95 Original development
1502 ----------------------------------------------------------------------------*/
1503 int32 set_tiltdata(int32 sdfid, int32 srec, int32 erec, int32 ysub,
1504  float32 *slatrec, float32 *slonrec, float32 *elatrec,
1505  float32 *elonrec, tilt_Type *old_tiltrec,
1506  tilt_Type *new_tiltrec) {
1507  int32 i, j, k;
1508  int16 lsrec, oranges[20][2], nranges[20][2];
1509  int32 oi, ni, ontilts, erange, subsc_recs;
1510  int32 slat = 0, elat = 1, sscan = 0, escan = 1;
1511  int32 slon = 0, elon = 1;
1512  int32 edge[3] = {0, 0, 0}, start[3] = {0, 0, 0};
1513 
1514  subsc_recs = ((erec + 1) - (srec + 1)) / ysub + 1;
1515 
1516  new_tiltrec->ntilts = 0;
1517  for (i = 0; i < 20; i++) {
1518  new_tiltrec->tilt_flags[i] = 0;
1519  new_tiltrec->tilt_ranges[i][0] = 0;
1520  new_tiltrec->tilt_ranges[i][1] = 0;
1521  for (j = 0; j < 2; j++) {
1522  for (k = 0; k < 2; k++) {
1523  new_tiltrec->tilt_lats[i][j][k] = 0;
1524  new_tiltrec->tilt_lons[i][j][k] = 0;
1525  }
1526  }
1527  }
1528 
1529  for (i = 0; i < 20; i++)
1530  for (j = 0; j < 2; j++)
1531  oranges[i][j] = nranges[i][j] = 0;
1532 
1533  lsrec = srec + 1;
1534 
1535  ontilts = old_tiltrec->ntilts;
1536 
1537  for (i = 0; i < ontilts; i++)
1538  for (j = 0; j < 2; j++)
1539  oranges[i][j] = old_tiltrec->tilt_ranges[i][j];
1540 
1541  for (ni = 0, oi = 0; ((oi < ontilts) && (lsrec > oranges[oi][1])); oi++)
1542  ;
1543 
1544  nranges[ni][0] = 1;
1545  if (erec <= oranges[oi][1]) {
1546  nranges[ni][1] = subsc_recs;
1547  new_tiltrec->tilt_flags[ni] = old_tiltrec->tilt_flags[oi];
1548  new_tiltrec->ntilts++;
1549  } else {
1550  if (oranges[oi][1] == oranges[oi][0])
1551  nranges[ni][1] = oranges[oi][1];
1552  else
1553  nranges[ni][1] = ((oranges[oi][1] - lsrec) / ysub + 1);
1554  nranges[ni + 1][0] = nranges[ni][1] + 1;
1555  new_tiltrec->tilt_flags[ni] = old_tiltrec->tilt_flags[oi];
1556  new_tiltrec->ntilts++;
1557  for (++ni, ++oi; oi < ontilts; oi++) {
1558  nranges[ni][0] = nranges[ni - 1][1] + 1;
1559  if (erec >= oranges[oi][0]) {
1560  if (erec <= oranges[oi][1]) {
1561  nranges[ni][1] = subsc_recs;
1562  new_tiltrec->tilt_flags[ni] = old_tiltrec->tilt_flags[oi];
1563  new_tiltrec->ntilts++;
1564  ni++;
1565  } else {
1566  erange = (oranges[oi][1] - oranges[oi][0]);
1567  if (erange >= ysub) {
1568  erange = erange / ysub;
1569  nranges[ni][1] = nranges[oi][0] + erange;
1570  new_tiltrec->tilt_flags[ni] = old_tiltrec->tilt_flags[oi];
1571  new_tiltrec->ntilts++;
1572  ni++;
1573  }
1574  }
1575  }
1576  }
1577  }
1578  for (i = 0; i < new_tiltrec->ntilts; i++)
1579  for (j = 0; j < 2; j++)
1580  new_tiltrec->tilt_ranges[i][j] = nranges[i][j];
1581 
1582  for (i = 0; i < new_tiltrec->ntilts; i++) {
1583  new_tiltrec->tilt_lats[i][sscan][slat] = slatrec[nranges[i][0] - 1];
1584  new_tiltrec->tilt_lats[i][sscan][elat] = elatrec[nranges[i][0] - 1];
1585 
1586  new_tiltrec->tilt_lats[i][escan][slat] = slatrec[nranges[i][1] - 1];
1587  new_tiltrec->tilt_lats[i][escan][elat] = elatrec[nranges[i][1] - 1];
1588 
1589  new_tiltrec->tilt_lons[i][sscan][slon] = slonrec[nranges[i][0] - 1];
1590  new_tiltrec->tilt_lons[i][sscan][elon] = elonrec[nranges[i][0] - 1];
1591 
1592  new_tiltrec->tilt_lons[i][escan][slon] = slonrec[nranges[i][1] - 1];
1593  new_tiltrec->tilt_lons[i][escan][elon] = elonrec[nranges[i][1] - 1];
1594  }
1595 
1596  edge[0] = edge[1] = edge[2] = 0;
1597  if ((update_sds(sdfid, NTILTS, start, edge,
1598  (VOIDP) & new_tiltrec->ntilts)) < 0) return FAIL;
1599 
1600  edge[0] = edge[1] = edge[2] = 0;
1601  if ((update_sds(sdfid, TILTFLAGS, start, edge,
1602  (VOIDP) new_tiltrec->tilt_flags)) < 0) return FAIL;
1603 
1604  edge[0] = edge[1] = edge[2] = 0;
1605  if ((update_sds(sdfid, TILTRANGES, start, edge,
1606  (VOIDP) new_tiltrec->tilt_ranges)) < 0) return FAIL;
1607 
1608  edge[0] = edge[1] = edge[2] = 0;
1609  if ((update_sds(sdfid, TILTLATS, start, edge,
1610  (VOIDP) new_tiltrec->tilt_lats)) < 0) return FAIL;
1611 
1612  edge[0] = edge[1] = edge[2] = 0;
1613  if ((update_sds(sdfid, TILTLONS, start, edge,
1614  (VOIDP) new_tiltrec->tilt_lons)) < 0) return FAIL;
1615 
1616  return SUCCEED;
1617 }
1618 
1619 /*-----------------------------------------------------------------------------
1620  Function: get_geodata
1621 
1622  Returns: int32 (sdsid)
1623  The return code is a negative value if any error occurs, otherwise,
1624  returns sdsid.
1625 
1626  Description:
1627  The function set_flags reads l2_flags dataset for calculating the
1628  flag percentages
1629 
1630  Parameters: (in calling order)
1631  Type Name I/O Description
1632  ---- ---- --- -----------
1633  int32 sdfid I SDinterface ID of output file
1634  int32 nrec I number of records
1635  int32 nsamp I number of samples
1636  int32 *flags O count of flags set for each band
1637 
1638  NOTE:
1639 
1640  Modification history:
1641  Programmer Organization Date Description of change
1642  -------------- ------------ -------- ---------------------
1643  Lakshmi Kumar Hughes STX 04/03/95 Original development
1644 ----------------------------------------------------------------------------*/
1645 int32 set_flags(int32 sdfid, int32 nrec, int32 nsamp, int32 *flags) {
1646  int32 i, j, start[3] = {0, 0, 0}, edge[3] = {0, 0, 0};
1647  int16 *l2flags;
1648  int16 masks[16];
1649 
1650  if ((l2flags = (int16 *) calloc(nrec * nsamp, sizeof (int16))) == NULL)
1651  return MALLOC_ERR;
1652 
1653  if ((rdslice(sdfid, L2FLAGS, start, edge, (VOIDP) l2flags)) < 0)
1654  return FAIL;
1655 
1656  for (flags[0] = 0, masks[0] = 1, i = 1; i < 16; i++) {
1657  masks[i] = (masks[i - 1] * 2);
1658  flags[i] = 0;
1659  }
1660 
1661  for (i = 0; i < nrec * nsamp; i++)
1662  for (j = 0; j < 16; j++) {
1663  if ((l2flags[i] & masks[j]) == masks[j])
1664  flags[j]++;
1665  }
1666 
1667  return SUCCEED;
1668 }
1669 
1670 /*-----------------------------------------------------------------------------
1671  Function: alloc_nav_buffs
1672 
1673  Returns: int32 (status)
1674  The return code is a negative value if any error occurs, otherwise,
1675  returns 0.
1676 
1677  Description:
1678  The function alloc_nav_buffs allocates buffers for navigation data
1679 
1680  Parameters: (in calling order)
1681  Type Name I/O Description
1682  ---- ---- --- -----------
1683  int32 nrec I number of records/scanlines
1684  GeoType *nav_rec O structrue to hold allocated buffers
1685 
1686  Modification history:
1687  Programmer Organization Date Description of change
1688  -------------- ------------ -------- ---------------------
1689  Lakshmi Kumar Hughes STX 04/03/95 Original development
1690 ----------------------------------------------------------------------------*/
1691 int32 alloc_nav_buffs(int32 nrec, NavType *nav_rec) {
1692  if ((nav_rec->orb_vec = (float32 *) calloc(nrec * 3, sizeof (float32))) == NULL)
1693  return MALLOC_ERR;
1694 
1695  if ((nav_rec->l_vert = (float32 *) calloc(nrec * 3, sizeof (float32))) == NULL)
1696  return MALLOC_ERR;
1697 
1698  if ((nav_rec->sun_ref = (float32 *) calloc(nrec * 3, sizeof (float32))) == NULL)
1699  return MALLOC_ERR;
1700 
1701  if ((nav_rec->att_ang = (float32 *) calloc(nrec * 3, sizeof (float32))) == NULL)
1702  return MALLOC_ERR;
1703 
1704  if ((nav_rec->sen_mat = (float32 *) calloc(nrec * 3 * 3, sizeof (float32))) == NULL)
1705  return MALLOC_ERR;
1706 
1707  if ((nav_rec->scan_ell = (float32 *) calloc(nrec * 6, sizeof (float32))) == NULL)
1708  return MALLOC_ERR;
1709 
1710  if ((nav_rec->nflag = (int32 *) calloc(nrec * 8, sizeof (int32))) == NULL)
1711  return MALLOC_ERR;
1712 
1713  return SUCCEED;
1714 }
1715 
1716 /*-----------------------------------------------------------------------------
1717  Function: get_navdata
1718 
1719  Returns: int32 (sdsid)
1720  The return code is a negative value if any error occurs, otherwise,
1721  returns sdsid.
1722 
1723  Description:
1724  The function get_navdata reads sensor metrics info from the given
1725  input data file
1726 
1727  Parameters: (in calling order)
1728  Type Name I/O Description
1729  ---- ---- --- -----------
1730  int32 sdfid I SDinterface ID of input file
1731  int32 nrec I number of input data records
1732  NavType *nav_rec O sensor metrics data structure
1733 
1734  NOTE:
1735 
1736  Modification history:
1737  Programmer Organization Date Description of change
1738  -------------- ------------ -------- ---------------------
1739  Lakshmi Kumar Hughes STX 04/03/95 Original development
1740 ----------------------------------------------------------------------------*/
1741 int32 get_navdata(int32 sdfid, int32 nrec, NavType *nav_rec) {
1742  int32 start[3] = {0, 0, 0}, edge[3] = {0, 0, 0};
1743 
1744  edge[0] = nrec;
1745  edge[1] = 3;
1746  edge[2] = 0;
1747  if ((rdslice(sdfid, ORBVEC, start, edge, (VOIDP) nav_rec->orb_vec)) < 0)
1748  return FAIL;
1749 
1750  edge[0] = nrec;
1751  edge[1] = 3;
1752  edge[2] = 0;
1753  if ((rdslice(sdfid, LVERT, start, edge, (VOIDP) nav_rec->l_vert)) < 0)
1754  return FAIL;
1755 
1756  edge[0] = nrec;
1757  edge[1] = 3;
1758  edge[2] = 0;
1759  if ((rdslice(sdfid, SUNREF, start, edge, (VOIDP) nav_rec->sun_ref)) < 0)
1760  return FAIL;
1761 
1762  edge[0] = nrec;
1763  edge[1] = 3;
1764  edge[2] = 0;
1765  if ((rdslice(sdfid, ATTANG, start, edge, (VOIDP) nav_rec->att_ang)) < 0)
1766  return FAIL;
1767 
1768  edge[0] = nrec;
1769  edge[1] = 3;
1770  edge[2] = 3;
1771  if ((rdslice(sdfid, SENMAT, start, edge, (VOIDP) nav_rec->sen_mat)) < 0)
1772  return FAIL;
1773 
1774  edge[0] = nrec;
1775  edge[1] = 6;
1776  edge[2] = 0;
1777  if ((rdslice(sdfid, SCANELL, start, edge, (VOIDP) nav_rec->scan_ell)) < 0)
1778  return FAIL;
1779 
1780  edge[0] = nrec;
1781  edge[1] = 8;
1782  edge[2] = 0;
1783  if ((rdslice(sdfid, NFLAG, start, edge, (VOIDP) nav_rec->nflag)) < 0)
1784  return FAIL;
1785 
1786  return SUCCEED;
1787 }
1788 
1789 /*-----------------------------------------------------------------------------
1790  Function: free_nav_buffs
1791 
1792  Returns: None
1793 
1794  Description:
1795  The function free_nav_buffs frees all the sensor metrics buffers
1796 
1797  Parameters: (in calling order)
1798  Type Name I/O Description
1799  ---- ---- --- -----------
1800  NavType *nav_rec I structrue containing sensor metrics
1801  buffers
1802  NOTE:
1803 
1804  Modification history:
1805  Programmer Organization Date Description of change
1806  -------------- ------------ -------- ---------------------
1807  Lakshmi Kumar Hughes STX 04/03/95 Original development
1808 ----------------------------------------------------------------------------*/
1809 void
1810 #ifdef PRTOTYPE
1811 free_nav_buffs(NavType *nav_rec)
1812 #else
1814 NavType *nav_rec;
1815 #endif
1816 {
1817  free(nav_rec->orb_vec);
1818  free(nav_rec->l_vert);
1819  free(nav_rec->sun_ref);
1820  free(nav_rec->att_ang);
1821  free(nav_rec->sen_mat);
1822  free(nav_rec->scan_ell);
1823  free(nav_rec->nflag);
1824 }
1825 
1826 /*-----------------------------------------------------------------------------
1827  Function: subsamp_rec
1828 
1829  Returns: int32 (sdsid)
1830  The return code is a negative value if any error occurs, otherwise,
1831  returns sdsid.
1832 
1833  Description:
1834  The function subsamp_rec subsamples the given data along the last
1835  dimension ('C' order)
1836 
1837  Parameters: (in calling order)
1838  Type Name I/O Description
1839  ---- ---- --- -----------
1840  int32 srec I starting record
1841  int32 maxrec I last record that should be processed
1842  int32 rank I number of data dimensions
1843  int32 *dims I dimensions of the data
1844  int32 ysub I scanline subsampling rate
1845  int32 nt I number type of data
1846  void *obuf I input data buffer
1847  void *nbuf O output data buffer
1848 
1849  NOTE:
1850 
1851  Modification history:
1852  Programmer Organization Date Description of change
1853  -------------- ------------ -------- ---------------------
1854  Lakshmi Kumar Hughes STX 04/03/95 Original development
1855 ----------------------------------------------------------------------------*/
1856 int32 subsamp_rec(int32 srec, int32 maxrec, int32 rank, int32 *dims,
1857  int32 ysub, int32 nt, void *obuf, void *nbuf) {
1858  int32 i, j, nv, ni, oi;
1859  int32 *i32_obuf, *i32_nbuf;
1860  int16 *i16_obuf, *i16_nbuf;
1861  uint8 *ui8_obuf, *ui8_nbuf;
1862  float32 *f32_obuf, *f32_nbuf;
1863 
1864 
1865  for (nv = 1, i = 1; i < rank; i++)
1866  nv *= dims[i];
1867 
1868  for (ni = 0, oi = nv * srec; oi <= maxrec * nv; oi += ysub * nv) {
1869  if (nt == DFNT_INT32) {
1870  i32_obuf = (int32 *) obuf;
1871  i32_nbuf = (int32 *) nbuf;
1872  for (j = 0; j < nv; j++)
1873  i32_nbuf[ni++] = i32_obuf[oi + j];
1874  } else
1875  if (nt == DFNT_INT16) {
1876  i16_obuf = (int16 *) obuf;
1877  i16_nbuf = (int16 *) nbuf;
1878  for (j = 0; j < nv; j++)
1879  i16_nbuf[ni++] = i16_obuf[oi + j];
1880  } else
1881  if (nt == DFNT_UINT8) {
1882  ui8_obuf = (uint8 *) obuf;
1883  ui8_nbuf = (uint8 *) nbuf;
1884  for (j = 0; j < nv; j++)
1885  ui8_nbuf[ni++] = ui8_obuf[oi + j];
1886  } else
1887  if (nt == DFNT_FLOAT32) {
1888  f32_obuf = (float32 *) obuf;
1889  f32_nbuf = (float32 *) nbuf;
1890  for (j = 0; j < nv; j++)
1891  f32_nbuf[ni++] = f32_obuf[oi + j];
1892  }
1893  }
1894  return SUCCEED;
1895 }
1896 
1897 /*-----------------------------------------------------------------------------
1898  Function: subsamp_2D
1899 
1900  Returns: int32 (sdsid)
1901  The return code is a negative value if any error occurs, otherwise,
1902  returns sdsid.
1903 
1904  Description:
1905  The function subsamp_2D subsamples the given data along x and y
1906 
1907  Parameters: (in calling order)
1908  Type Name I/O Description
1909  ---- ---- --- -----------
1910  int32 spix I start pixel position
1911  int32 sscan I start scan line (y pos) position
1912  int32 epix I ending pixel position
1913  int32 xdim I no. of pixels (x dim of inbuf)
1914  int32 xsub I pixel subsampling rate
1915  int32 ysub I scan line subsampling rate
1916  int32 nt I data type (HDF number type) of data
1917  void *inbuf I input data buffer
1918  void *outbuf O output data buffer (calling routine should
1919  provide proper sized buffer
1920 
1921  NOTE:
1922 
1923  Modification history:
1924  Programmer Organization Date Description of change
1925  -------------- ------------ -------- ---------------------
1926  Lakshmi Kumar Hughes STX 04/03/95 Original development
1927 ----------------------------------------------------------------------------*/
1928 void
1929 subsamp_2D(int32 spix, int32 sscan, int32 epix, int32 escan, int32 xdim,
1930  int32 xsub, int32 ysub, int32 nt, void *inbuf, void *outbuf) {
1931  int32 newrec, rec, px, newpx, newrow, npix = xdim;
1932  int32 max_rec_used, subsc_samps, subsc_recs;
1933  int32 *i32_obuf, *i32_ibuf;
1934  int16 *i16_obuf, *i16_ibuf;
1935  uint8 *ui8_obuf, *ui8_ibuf;
1936  float32 *f32_obuf, *f32_ibuf;
1937 
1938  /*** compute subscene image dimensions */
1939 
1940  subsc_recs = ((escan + 1) - (sscan + 1)) / ysub + 1;
1941  subsc_samps = ((epix + 1) - (spix + 1)) / xsub + 1;
1942 
1943  /*** compute the maximum record and sample numbers used to make the subsampled
1944  browse output */
1945 
1946  max_rec_used = (subsc_recs - 1) * ysub + sscan;
1947 
1948  /*** subsample the data */
1949 
1950  if (nt == DFNT_INT32) {
1951  i32_obuf = (int32 *) outbuf;
1952  i32_ibuf = (int32 *) inbuf;
1953  for (newrec = 0, rec = sscan; rec <= max_rec_used; rec += ysub, newrec++) {
1954  newrow = newrec * subsc_samps;
1955  for (px = rec * npix + (spix), newpx = newrow;
1956  newpx < newrow + subsc_samps; px += xsub, newpx++) {
1957  i32_obuf[newpx] = i32_ibuf[px];
1958  }
1959  }
1960  } else
1961  if (nt == DFNT_INT16) {
1962  i16_obuf = (int16 *) outbuf;
1963  i16_ibuf = (int16 *) inbuf;
1964  for (newrec = 0, rec = sscan; rec <= max_rec_used; rec += ysub, newrec++) {
1965  newrow = newrec * subsc_samps;
1966  for (px = rec * npix + (spix), newpx = newrow;
1967  newpx < newrow + subsc_samps; px += xsub, newpx++) {
1968  i16_obuf[newpx] = i16_ibuf[px];
1969  }
1970  }
1971  } else
1972  if (nt == DFNT_UINT8) {
1973  ui8_obuf = (uint8 *) outbuf;
1974  ui8_ibuf = (uint8 *) inbuf;
1975  for (newrec = 0, rec = sscan; rec <= max_rec_used;
1976  rec += ysub, newrec++) {
1977  newrow = newrec * subsc_samps;
1978  for (px = rec * npix + (spix), newpx = newrow;
1979  newpx < newrow + subsc_samps; px += xsub, newpx++) {
1980  ui8_obuf[newpx] = ui8_ibuf[px];
1981  }
1982  }
1983  } else
1984  if (nt == DFNT_FLOAT32) {
1985  f32_obuf = (float32 *) outbuf;
1986  f32_ibuf = (float32 *) inbuf;
1987  for (newrec = 0, rec = sscan; rec <= max_rec_used;
1988  rec += ysub, newrec++) {
1989  newrow = newrec * subsc_samps;
1990  for (px = rec * npix + (spix), newpx = newrow;
1991  newpx < newrow + subsc_samps; px += xsub, newpx++) {
1992  f32_obuf[newpx] = f32_ibuf[px];
1993  }
1994  }
1995  }
1996 }
1997 
1998 /*-----------------------------------------------------------------------------
1999  Function: set_l1adata
2000 
2001  Returns: int32 (sdsid)
2002  The return code is a negative value if any error occurs, otherwise,
2003  returns sdsid.
2004 
2005  Description:
2006  The function set_l1adata reads level 1a data, gain, and dark_rest
2007  from the given input file, calls subsamp_l1adata to subsample the
2008  data and writes it to the output file
2009 
2010  Parameters: (in calling order)
2011  Type Name I/O Description
2012  ---- ---- --- -----------
2013  int32 isdfid I ID req to access HDF SDS interface
2014  int32 osdfid I SDinterface ID of output file
2015  int32 num_recs I number of input records
2016  int32 num_samps I number of input samples
2017  int32 subsc_recs I number of output records
2018  int32 subsc_samps I number of output samples
2019  int32 srec I starting record
2020  int32 ssamp I starting pixel
2021  int32 erec I ending record
2022  int32 esamp I ending sample
2023  int32 xsub I pixel subsampling rate
2024  int32 ysub I scanline subsampling rate
2025  FilemetricsType *fm_rec I File metrics
2026 
2027  NOTE:
2028 
2029  Modification history:
2030  Programmer Organization Date Description of change
2031  -------------- ------------ -------- ---------------------
2032  Lakshmi Kumar Hughes STX 04/03/95 Original development
2033  Lakshmi Kumar Hughes STX 12/12/95 Fixed a bug wh was trying to write
2034  more than subsc_recs
2035  Lakshmi Kumar Hughes STX 02/21/96 Fixed the above bugfix which had
2036  introduced another bug
2037 ----------------------------------------------------------------------------*/
2038 int32
2039 set_l1adata(int32 isdfid, int32 osdfid, int32 num_recs, int32 num_samps,
2040  int32 subsc_recs, int32 subsc_samps, int32 srec, int32 ssamp,
2041  int32 erec, int32 esamp, int32 xsub, int32 ysub,
2042  FilemetricsType *fm_rec) {
2043  int32 nsamp, nrec, last_rec_used, new_buf_recs;
2044  int32 old_start[3] = {0, 0, 0}, new_start[3] = {0, 0, 0};
2045  int32 old_edge[3], new_edge[3], rd_recs, buf_srec, buf_erec;
2046  int16 nbands = NBANDS, *gain, *dark_rest, *inbuf, *outbuf;
2047  int16 *s_satp, *s_zerop;
2048  int32 start[3] = {0, 0, 0}, edge[3];
2049 
2050  nrec = num_recs;
2051  nsamp = num_samps;
2052 
2053  old_edge[0] = nrec;
2054  old_edge[1] = nsamp;
2055  old_edge[2] = nbands;
2056 
2057  new_edge[0] = subsc_recs;
2058  new_edge[1] = subsc_samps;
2059  new_edge[2] = nbands;
2060 
2061  if ((gain = (int16 *) calloc(subsc_recs * NBANDS, sizeof (int16))) == NULL)
2062  return MALLOC_ERR;
2063 
2064  if ((dark_rest = (int16 *) calloc(subsc_recs * NBANDS, sizeof (int16))) == NULL)
2065  return MALLOC_ERR;
2066 
2067  if ((s_satp = (int16 *) calloc(subsc_recs * NBANDS, sizeof (int16))) == NULL)
2068  return MALLOC_ERR;
2069 
2070  if ((s_zerop = (int16 *) calloc(subsc_recs * NBANDS, sizeof (int16))) == NULL)
2071  return MALLOC_ERR;
2072 
2073  /*** read gain and dark_rest datasets */
2074  edge[0] = edge[1] = edge[2] = 0;
2075  if ((rdslice(osdfid, GAIN, start, edge, (VOIDP) gain)) < 0)
2076  return FAIL;
2077 
2078  edge[0] = edge[1] = edge[2] = 0;
2079  if ((rdslice(osdfid, DARKREST, start, edge, (VOIDP) dark_rest)) < 0)
2080  return FAIL;
2081 
2082  nrec = erec - srec + 1;
2083  old_start[0] = srec;
2084  new_start[0] = -1;
2085  if (nrec > CHUNK_SZ)
2086  rd_recs = CHUNK_SZ;
2087  else
2088  rd_recs = nrec;
2089 
2090  /**** allocate space for l1a buffers */
2091 
2092  if ((inbuf =
2093  (int16 *) calloc(CHUNK_SZ * old_edge[1] * old_edge[2], sizeof (int16))) == NULL) {
2094  sprintf(ERR_MSG, "Calloc error - cannot allocate memory for reading %s",
2095  L1ADATA);
2096  return MALLOC_ERR;
2097  }
2098 
2099  if ((outbuf =
2100  (int16 *) calloc(CHUNK_SZ * new_edge[1] * new_edge[2],
2101  sizeof (int16))) == NULL) {
2102  sprintf(ERR_MSG, "calloc error - cannot allocate memory for writing %s",
2103  L1ADATA);
2104  return MALLOC_ERR;
2105  }
2106 
2107  while (rd_recs > 0) {
2108  old_edge[0] = rd_recs;
2109  if ((rdslice(isdfid, L1ADATA, old_start, old_edge, (VOIDP) inbuf)) < 0)
2110  return FAIL;
2111  buf_srec = 0;
2112  buf_erec = rd_recs - 1;
2113  last_rec_used = subsamp_l1adata(buf_srec, buf_erec, ssamp, esamp, xsub,
2114  ysub, nsamp, gain, dark_rest, fm_rec, inbuf, outbuf,
2115  s_satp, s_zerop, &new_buf_recs);
2116  old_start[0] += ysub + last_rec_used;
2117  nrec -= last_rec_used + ysub;
2118  if (nrec < rd_recs)
2119  rd_recs = nrec;
2120 
2121  if (new_start[0] == -1) {
2122  new_start[0] = 0;
2123  new_edge[0] = new_buf_recs;
2124  } else {
2125  new_start[0] += new_edge[0];
2126  new_edge[0] = new_buf_recs;
2127  }
2128  if ((update_sds(osdfid, L1ADATA, new_start, new_edge, (VOIDP) outbuf)) < 0)
2129  return FAIL;
2130  } /* end while */
2131 
2132  new_start[0] = new_start[1] = new_start[2] = 0;
2133  new_edge[0] = subsc_recs;
2134  new_edge[1] = NBANDS;
2135  new_edge[2] = 0;
2136  if ((update_sds(osdfid, SSATP, new_start, new_edge, (VOIDP) s_satp)) < 0)
2137  return FAIL;
2138  if ((update_sds(osdfid, SZEROP, new_start, new_edge, (VOIDP) s_zerop)) < 0)
2139  return FAIL;
2140 
2141  free(s_satp);
2142  free(s_zerop);
2143  free(gain);
2144  free(dark_rest);
2145  free(inbuf);
2146  free(outbuf);
2147  return SUCCEED;
2148 }
2149 
2150 /*-----------------------------------------------------------------------------
2151  Function: subsamp_l1adata
2152 
2153  Returns: int32 (status)
2154  The return code is a negative value if any error occurs, otherwise,
2155  returns 0.
2156 
2157  Description:
2158  The function subsamp_l1adata subsamples the given level 1a 3D data
2159  and calculates gain1, gain2 saturated and non-saturated pixels, zero
2160  pixels and mean gain1 and mean gain2 radiances
2161 
2162  Parameters: (in calling order)
2163  Type Name I/O Description
2164  ---- ---- --- -----------
2165  int32 srec I starting scan line
2166  int32 erec I ending scan line
2167  int32 ssamp I starting sample
2168  int32 esamp I ending sample
2169  int32 xsub I pixel subsampling rate
2170  int32 ysub I scanline subsampling rate
2171  int32 nsamp I number of samples
2172  int16 *gain I gain dataset
2173  int16 *dark_rest I dark_restore data set
2174  FilemetricsType *fm_rec I File metrics
2175  int16 *inbuf I input level1a data
2176  int16 *outbuf O output level1a data
2177  int32 *new_buf_recs O output buffer records
2178 
2179  Modification history:
2180  Programmer Organization Date Description of change
2181  -------------- ------------ -------- ---------------------
2182  Lakshmi Kumar Hughes STX 04/03/95 Original development
2183  Lakshmi Kumar Hughes STX 12/14/95 Fixed the return value (before
2184  it was returning wrong value)
2185 ----------------------------------------------------------------------------*/
2186 int32
2187 subsamp_l1adata(int32 srec, int32 erec, int32 ssamp, int32 esamp,
2188  int32 xsub, int32 ysub, int32 nsamp, int16 *gain,
2189  int16 *dark_rest, FilemetricsType *fm_rec,
2190  int16 *inbuf, int16 *outbuf, int16 *s_satp,
2191  int16 *s_zerop, int32 *new_buf_recs) {
2192  int32 rec_sz, band, px_index, out_index, rec, rec_index;
2193  int32 subsc_recs, subsc_samps;
2194  int16 radiance, i = 0;
2195  int32 last_rec_used, last_samp_used;
2196  static int32 gn1px[NBANDS], gn2px[NBANDS];
2197  static double gainr1[NBANDS], gainr2[NBANDS];
2198  static int32 first_call = 1, gn_index;
2199 
2200  if (first_call) {
2201  first_call = 0;
2202  gn_index = 0;
2203  for (i = 0; i < NBANDS; i++) {
2204  fm_rec->satg1[i] = fm_rec->satg2[i] = 0;
2205  fm_rec->nsatg1[i] = fm_rec->nsatg2[i] = 0;
2206  fm_rec->zeroes[i] = 0;
2207  fm_rec->meanr1[i] = fm_rec->meanr2[i] = 0;
2208  gn1px[i] = gn2px[i] = 0;
2209  gainr1[i] = gainr2[i] = 0;
2210  }
2211  }
2212 
2213  *new_buf_recs = subsc_recs = ((erec + 1) - (srec + 1)) / ysub + 1;
2214  subsc_samps = ((esamp + 1) - (ssamp + 1)) / xsub + 1;
2215 
2216  last_rec_used = (subsc_recs - 1) * ysub + srec;
2217  last_samp_used = (subsc_samps - 1) * xsub + ssamp;
2218 
2219  rec_sz = nsamp * NBANDS;
2220  for (out_index = 0, rec = srec; rec <= last_rec_used;
2221  rec += ysub, gn_index++) {
2222  rec_index = rec * rec_sz;
2223  for (px_index = rec_index + (ssamp * NBANDS);
2224  px_index <= (rec_index + last_samp_used * NBANDS);
2225  px_index += (xsub * NBANDS)) {
2226  for (band = 0; band < NBANDS; band++) {
2227  radiance = outbuf[out_index++] = inbuf[px_index + band];
2228  if (gain[gn_index + band] == 0) {
2229  gainr1[band] += radiance;
2230  gn1px[band]++;
2231  if (radiance >= 1023) {
2232  s_satp[gn_index * NBANDS + band]++;
2233  fm_rec->satg1[band]++;
2234  } else
2235  fm_rec->nsatg1[band]++;
2236  } else
2237  if (gain[gn_index * NBANDS + band] == 2) {
2238  gainr2[band] += radiance;
2239  gn2px[band]++;
2240  if (radiance >= 1023) {
2241  s_satp[gn_index + band]++;
2242  fm_rec->satg2[band]++;
2243  } else
2244  fm_rec->nsatg2[band]++;
2245  }
2246  if ((radiance - dark_rest[gn_index * NBANDS + band]) <= 2) {
2247  s_zerop[gn_index * NBANDS + band]++;
2248  fm_rec->zeroes[band]++;
2249  }
2250  }
2251  }
2252  }
2253  for (band = 0; band < NBANDS; band++) {
2254  if (gn1px[band] > 0)
2255  fm_rec->meanr1[band] = gainr1[band] / gn1px[band];
2256  if (gn2px[band] > 0)
2257  fm_rec->meanr2[band] = gainr2[band] / gn2px[band];
2258  }
2259 
2260  return last_rec_used;
2261 }
2262 
2263 /*-----------------------------------------------------------------------------
2264  Function: set_globalattrs
2265 
2266  Returns: int32 (sdsid)
2267  The return code is a negative value if any error occurs, otherwise,
2268  returns sdsid.
2269 
2270  Description:
2271  The function set_globalattrs updates data dependent global attributes
2272 
2273  Parameters: (in calling order)
2274  Type Name I/O Description
2275  ---- ---- --- -----------
2276  char *outfile I output file name
2277  int32 sdfid I SDinterface ID of output file
2278  int32 l1aflag I flag indicating l1a or l2 file
2279  int32 nrec I number of records
2280  int32 nsamp I number of samples
2281  int32 ssamp I starting sample
2282  int32 xsub I pixle subsampling rate
2283  char *dtype I data type (GAC, LAC, etc.,)
2284  int16 *flags I level2 flags
2285  GeoType *geo_rec I structure containing scene coordinate data
2286  FilemetricsType *fm_rec I File metrics data structure
2287 
2288  NOTE:
2289 
2290  Modification history:
2291  Programmer Organization Date Description of change
2292  -------------- ------------ -------- ---------------------
2293  Lakshmi Kumar Hughes STX 11/02/94 Original development
2294 ----------------------------------------------------------------------------*/
2295 int32
2296 set_globalattrs(char *outfile, int32 sdfid, int32 l1aflag, int32 nrec,
2297  int32 nsamp, int32 ssamp, int32 xsub, int32 *flags,
2298  GeoType *geo_rec, FilemetricsType *fm_rec) {
2299  uint8 *s_flags;
2300  int16 dday, dyear, syear, sday, eyear, eday;
2301  int16 subsc_syear, subsc_sday, subsc_eyear, subsc_eday;
2302  int32 emsec, smsec, pix_sub, pix_start;
2303  int32 i, rec, cmsec, FSlines = 0;
2304  int32 *msec, cscan, *nflag, xfirst, xlast, xcenter;
2305  int32 start[3] = {0, 0, 0}, edge[3] = {0, 0, 0};
2306  div_t quot1, quot2, quot3;
2307  char string[MAXVAL], ptime[17], *prod_name;
2308  float32 maxlat = -999, minlat = 999, maxlon = -999, minlon = 999;
2309  float32 pct_flags[16];
2310 
2311  /*** read msec dataset and data time */
2312  if ((msec = (int32 *) calloc(nrec, sizeof (int32))) == NULL)
2313  return MALLOC_ERR;
2314 
2315  if ((rdslice(sdfid, MSEC, start, edge, (VOIDP) msec)) < 0)
2316  return FAIL;
2317 
2318  if ((s_flags = (uint8 *) calloc(nrec * 4, sizeof (uint8))) == NULL)
2319  return MALLOC_ERR;
2320 
2321  edge[0] = edge[1] = edge[2] = 0;
2322  if ((rdslice(sdfid, SFLAGS, start, edge, (VOIDP) s_flags)) < 0)
2323  return FAIL;
2324  /*
2325  get nflag information for deciding the start, center, and end scan line that
2326  have the good navigation G.Fu 3/2/98
2327  */
2328  if ((nflag = (int32 *) calloc(nrec * 8, sizeof (int32))) == NULL)
2329  return MALLOC_ERR;
2330 
2331  edge[0] = edge[1] = edge[2] = 0;
2332  if ((rdslice(sdfid, NFLAG, start, edge, (VOIDP) nflag)) < 0)
2333  return FAIL;
2334 
2335  if ((rdattr(sdfid, SYEAR, &syear)) < 0)
2336  return FAIL;
2337  if ((rdattr(sdfid, SDAY, &sday)) < 0)
2338  return FAIL;
2339  if ((rdattr(sdfid, SMSEC, &smsec)) < 0)
2340  return FAIL;
2341  if ((rdattr(sdfid, EYEAR, &eyear)) < 0)
2342  return FAIL;
2343  if ((rdattr(sdfid, EDAY, &eday)) < 0)
2344  return FAIL;
2345  if ((rdattr(sdfid, EMSEC, &emsec)) < 0)
2346  return FAIL;
2347  if ((rdattr(sdfid, PIX_START, &pix_start)) < 0)
2348  return FAIL;
2349  if ((rdattr(sdfid, PIX_SUB, &pix_sub)) < 0)
2350  return FAIL;
2351 
2352  /* Removed, BAF, 12/2002
2353  smsec = msec[0];
2354  emsec = msec[nrec-1];
2355  */
2356  cscan = (nrec + 1) / 2;
2357  cmsec = (msec[cscan - 1]);
2358 
2359 
2360  /*** check if scene crosses day */
2361  if (msec[0] < smsec) {
2362  subsc_syear = eyear;
2363  subsc_sday = eday;
2364  subsc_eyear = eyear;
2365  subsc_eday = eday;
2366  } else {
2367  subsc_syear = syear;
2368  subsc_sday = sday;
2369  if (msec[nrec - 1] < emsec) {
2370  subsc_eyear = eyear;
2371  subsc_eday = eday;
2372  } else {
2373  subsc_eyear = syear;
2374  subsc_eday = sday;
2375  }
2376  }
2377 
2378  /* add 2 lines, BAF, 12/2002 */
2379  smsec = msec[0];
2380  emsec = msec[nrec - 1];
2381 
2382  quot1 = div(smsec, MSECHOUR);
2383  quot2 = div(quot1.rem, MSECMIN);
2384  quot3 = div(quot2.rem, MSECSEC);
2385  sprintf(string, "%4.4d%3.3d%2.2d%2.2d%2.2d%3.3d", subsc_syear,
2386  subsc_sday, quot1.quot, quot2.quot, quot3.quot, quot3.rem);
2387  SDsetattr(sdfid, "Start Time", DFNT_CHAR, strlen(string) + 1,
2388  (VOIDP) string);
2389  quot1 = div(emsec, MSECHOUR);
2390  quot2 = div(quot1.rem, MSECMIN);
2391  quot3 = div(quot2.rem, MSECSEC);
2392  sprintf(string, "%4.4d%3.3d%2.2d%2.2d%2.2d%3.3d", subsc_eyear,
2393  subsc_eday, quot1.quot, quot2.quot, quot3.quot, quot3.rem);
2394  SDsetattr(sdfid, "End Time", DFNT_CHAR, strlen(string) + 1,
2395  (VOIDP) string);
2396 
2397  SDsetattr(sdfid, SYEAR, DFNT_INT16, 1, (VOIDP) & subsc_syear);
2398  SDsetattr(sdfid, SDAY, DFNT_INT16, 1, (VOIDP) & subsc_sday);
2399  SDsetattr(sdfid, SMSEC, DFNT_INT32, 1, (VOIDP) & msec[0]);
2400  SDsetattr(sdfid, EYEAR, DFNT_INT16, 1, (VOIDP) & subsc_eyear);
2401  SDsetattr(sdfid, EDAY, DFNT_INT16, 1, (VOIDP) & subsc_eday);
2402  SDsetattr(sdfid, EMSEC, DFNT_INT32, 1, (VOIDP) & msec[nrec - 1]);
2403 
2404  dyear = subsc_syear;
2405  dday = subsc_sday;
2406  if (subsc_sday != subsc_eday || subsc_syear != subsc_eyear) {
2407  if (cmsec < 43200000) {
2408  dday = subsc_eday;
2409  dyear = subsc_eyear;
2410  }
2411  }
2412  quot1 = div(cmsec, MSECHOUR);
2413  quot2 = div(quot1.rem, MSECMIN);
2414  quot3 = div(quot2.rem, MSECSEC);
2415  sprintf(string, "%4.4d%3.3d%2.2d%2.2d%2.2d%3.3d", dyear, dday,
2416  quot1.quot, quot2.quot, quot3.quot, quot3.rem);
2417  SDsetattr(sdfid, CTIME, DFNT_CHAR, strlen(string) + 1,
2418  (VOIDP) string);
2419 
2420  /*** write Data Quality global attributes */
2421 
2422  SDsetattr(sdfid, NSAMP, DFNT_INT32, 1, (VOIDP) & nsamp);
2423 
2424  SDsetattr(sdfid, NREC, DFNT_INT32, 1, (VOIDP) & nrec);
2425 
2426  pix_start = pix_start + (ssamp * pix_sub);
2427  SDsetattr(sdfid, PIX_START, DFNT_INT32, 1, (VOIDP) & pix_start);
2428 
2429  pix_sub = pix_sub * xsub;
2430  SDsetattr(sdfid, PIX_SUB, DFNT_INT32, 1, (VOIDP) & pix_sub);
2431 
2432  if (!l1aflag) {
2433  for (i = 0; i < 16; i++) {
2434  if (flags[i] > 0)
2435  pct_flags[i] = flags[i] / (nsamp * nrec * 1.0) * 100;
2436  else
2437  pct_flags[i] = 0;
2438  }
2439  SDsetattr(sdfid, PCT_FLAG, DFNT_FLOAT32, 16, (VOIDP) pct_flags);
2440  } else { /* update file metrics */
2441  SDsetattr(sdfid, L1SATG1, DFNT_INT32, 8, (VOIDP) fm_rec->satg1);
2442 
2443  SDsetattr(sdfid, L1SATG2, DFNT_INT32, 8, (VOIDP) fm_rec->satg2);
2444 
2445  SDsetattr(sdfid, L1NSATG1, DFNT_INT32, 8, (VOIDP) fm_rec->nsatg1);
2446 
2447  SDsetattr(sdfid, L1NSATG2, DFNT_INT32, 8, (VOIDP) fm_rec->nsatg2);
2448 
2449  SDsetattr(sdfid, L1ZEROS, DFNT_INT32, 8, (VOIDP) fm_rec->zeroes);
2450 
2451  SDsetattr(sdfid, L1MEANR1, DFNT_FLOAT32, 8, (VOIDP) fm_rec->meanr1);
2452 
2453  SDsetattr(sdfid, L1MEANR2, DFNT_FLOAT32, 8, (VOIDP) fm_rec->meanr2);
2454  }
2455 
2456  /*** write scene coordinates global attributes */
2457  /*
2458  the following global attributes will be decided based on scan lines with
2459  good navigation only (to be consistent with l1agen program 3/2/98 G. Fu
2460  */
2461  xfirst = -1;
2462  xlast = nrec - 1;
2463  xcenter = cscan - 1;
2464  for (i = 0; i < nrec; i++) {
2465  if (nflag[i * 8] == 0) {
2466  if (xfirst < 0)
2467  xfirst = i;
2468  xlast = i;
2469  }
2470  }
2471 
2472  if (xfirst >= 0) {
2473  xcenter = (xlast + xfirst) / 2;
2474  while ((xcenter > xfirst) && (nflag[xcenter * 8]) != 0)
2475  xcenter--;
2476 
2477  xcenter++; /* change to 1-rel */
2478  }
2479  else {
2480  xfirst = 0;
2481  xlast = nrec - 1;
2482  xcenter = (nrec + 1) / 2;
2483  printf("\nWarning - No good navigation record found for the data extracted\n");
2484  }
2485  SDsetattr(sdfid, NCREC, DFNT_INT32, 1, (VOIDP) & xcenter);
2486  SDsetattr(sdfid, SCLAT, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->clat[xcenter - 1]);
2487  SDsetattr(sdfid, SCLON, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->clon[xcenter - 1]);
2488  SDsetattr(sdfid, ULLAT, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->slat[xfirst]);
2489  SDsetattr(sdfid, ULLON, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->slon[xfirst]);
2490  SDsetattr(sdfid, URLAT, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->elat[xfirst]);
2491  SDsetattr(sdfid, URLON, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->elon[xfirst]);
2492  SDsetattr(sdfid, LLLAT, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->slat[xlast]);
2493  SDsetattr(sdfid, LLLON, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->slon[xlast]);
2494  SDsetattr(sdfid, LRLAT, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->elat[xlast]);
2495  SDsetattr(sdfid, LRLON, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->elon[xlast]);
2496 
2497  for (rec = 0; rec < nrec; rec++) {
2498  if (geo_rec->slat[rec] > maxlat)
2499  maxlat = geo_rec->slat[rec];
2500  if (geo_rec->elat[rec] < minlat)
2501  minlat = geo_rec->elat[rec];
2502 
2503  /*** also calculate filled scan lines */
2504  if (s_flags[rec * 4 + 1] > 0)
2505  FSlines++;
2506  }
2507 
2508  /* check if the scene crosses dateline */
2509  if ((geo_rec->slon[0] < 0) && (geo_rec->slon[nrec - 1] >= 0)) {
2510  for (rec = 0; rec < nrec; rec++) { /* find the least +ve no. */
2511  if ((geo_rec->slon[rec] < minlon) && (geo_rec->slon[rec] > 0))
2512  minlon = geo_rec->slon[rec];
2513  if ((geo_rec->elon[rec] > maxlon) && (geo_rec->elon[rec] < 0))
2514  maxlon = geo_rec->elon[rec];
2515  }
2516  } else {
2517  for (rec = 0; rec < nrec; rec++) {
2518  if (geo_rec->slon[rec] < minlon)
2519  minlon = geo_rec->slon[rec];
2520  if (geo_rec->elon[rec] > maxlon)
2521  maxlon = geo_rec->elon[rec];
2522  }
2523  }
2524 
2525  SDsetattr(sdfid, NFREC, DFNT_INT32, 1, (VOIDP) & FSlines);
2526 
2527  SDsetattr(sdfid, NORTHLAT, DFNT_FLOAT32, 1, (VOIDP) & maxlat);
2528 
2529  SDsetattr(sdfid, SOUTHLAT, DFNT_FLOAT32, 1, (VOIDP) & minlat);
2530 
2531  SDsetattr(sdfid, WESTLON, DFNT_FLOAT32, 1, (VOIDP) & minlon);
2532 
2533  SDsetattr(sdfid, EASTLON, DFNT_FLOAT32, 1, (VOIDP) & maxlon);
2534 
2535  SDsetattr(sdfid, BCLAT, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->clat[0]);
2536  SDsetattr(sdfid, BCLON, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->clon[0]);
2537 
2538  SDsetattr(sdfid, ECLAT, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->clat[nrec - 1]);
2539  SDsetattr(sdfid, ECLON, DFNT_FLOAT32, 1, (VOIDP) & geo_rec->clon[nrec - 1]);
2540 
2541  get_time(ptime);
2542 
2543  SDsetattr(sdfid, PTIME, DFNT_CHAR, strlen(ptime) + 1, (VOIDP) ptime);
2544 
2545  if ((prod_name = strrchr(outfile, '/')) != NULL)
2546  prod_name++;
2547  else
2548  prod_name = outfile;
2549  SDsetattr(sdfid, PROD_NAME, DFNT_CHAR, strlen(prod_name) + 1, (VOIDP) prod_name);
2550 
2551  free(msec);
2552  free(s_flags);
2553 
2554  return SUCCEED;
2555 }
int32 get_tiltdata(int32 sdfid, tilt_Type *tiltrec)
Definition: extract_sub.c:1446
#define TILTLONS
Definition: regen.h:32
void free_geonav_buffs(GeoType *geo_rec)
Definition: extract_sub.c:1282
#define BCLON
Definition: regen.h:60
an array had not been initialized Several spelling and grammar corrections were which is read from the appropriate MCF the above metadata values were hard coded A problem calculating the average background DN for SWIR bands when the moon is in the space view port was corrected The new algorithm used to calculate the average background DN for all reflective bands when the moon is in the space view port is now the same as the algorithm employed by the thermal bands For non SWIR changes in the averages are typically less than Also for non SWIR the black body DNs remain a backup in case the SV DNs are not available For SWIR the changes in computed averages were larger because the old which used the black body suffered from contamination by the micron leak As a consequence of the if SV DNs are not available for the SWIR the EV pixels will not be the granule time is used to identify the appropriate tables within the set given for one LUT the first two or last two tables respectively will be used for the interpolation If there is only one LUT in the set of it will be treated as a constant LUT The manner in which Earth View data is checked for saturation was changed Previously the raw Earth View DNs and Space View DNs were checked against the lookup table values contained in the table dn_sat The change made is to check the raw Earth and Space View DNs to be sure they are less than the maximum saturation value and to check the Space View subtracted Earth View dns against a set of values contained in the new lookup table dn_sat_ev The metadata configuration and ASSOCIATEDINSTRUMENTSHORTNAME from the MOD02HKM product The same metatdata with extensions and were removed from the MOD021KM and MOD02OBC products ASSOCIATEDSENSORSHORTNAME was set to MODIS in all products These changes are reflected in new File Specification which users may consult for exact the pow functions were eliminated in Emissive_Cal and Emissive bands replaced by more efficient code Other calculations throughout the code were also made more efficient Aside from a few round off there was no difference to the product The CPU time decreased by about for a day case and for a night case A minor bug in calculating the uncertainty index for emissive bands was corrected The frame index(0-based) was previously being used the frame number(1-based) should have been used. There were only a few minor changes to the uncertainty index(maximum of 1 digit). 3. Some inefficient arrays(Sigma_RVS_norm_sq) were eliminated and some code lines in Preprocess_L1A_Data were moved into Process_OBCEng_Emiss. There were no changes to the product. Required RAM was reduced by 20 MB. Now
char ERR_MSG[255]
Definition: extract_sub.c:119
integer, parameter int16
Definition: cubeio.f90:3
int32 set_globalattrs(char *outfile, int32 sdfid, int32 l1aflag, int32 nrec, int32 nsamp, int32 ssamp, int32 xsub, int32 *flags, GeoType *geo_rec, FilemetricsType *fm_rec)
Definition: extract_sub.c:2296
#define L1ZEROS
Definition: regen.h:72
int16 eday
Definition: l1_czcs_hdf.c:17
#define NFREC
Definition: regen.h:63
#define SLAT
Definition: regen_attr.h:27
int j
Definition: decode_rs.h:73
int32 get_navdata(int32 sdfid, int32 nrec, NavType *nav_rec)
Definition: extract_sub.c:1741
#define LLLON
Definition: regen.h:51
#define EYEAR
Definition: regen.h:37
int32 get_geodata(int32 pix_start, int32 pix_sub, int32 srec, int32 ssamp, int32 max_rec_used, int32 subsc_samps, int32 ysub, int32 xsub, char *dtype, NavType *nav_rec, GeoType *geo_rec)
Definition: extract_sub.c:1326
#define TILTRANGES
Definition: regen.h:30
#define CLON
Definition: regen_attr.h:30
#define ORBVEC
Definition: l1stat.h:50
#define DTYPE
Definition: l1stat.h:26
int16 * gain
Definition: l1_czcs_hdf.c:33
#define MSEC
Definition: regen_attr.h:24
#define SCLON
Definition: regen.h:44
#define WESTLON
Definition: regen.h:56
#define CSOLZ
Definition: regen_attr.h:33
#define SCLAT
Definition: regen.h:43
#define SYEAR
Definition: regen.h:34
#define FAIL
Definition: ObpgReadGrid.h:18
int32 subsample(int32 rank, int32 *idims, int32 *odims, int32 num_type, int32 srec, int32 erec, int32 ssamp, int32 esamp, int32 xsub, int32 ysub, void *ibuf, void *obuf)
Definition: extract_sub.c:1039
#define MAXVAL
Definition: l3stat.h:13
#define NULL
Definition: decode_rs.h:63
#define SDAY
Definition: regen.h:35
#define SENMAT
Definition: l1stat.h:51
int32 update_sds(int32 sdfid, char *name, int32 *start, int32 *edge, void *buf)
Definition: extract_sub.c:1188
MOD_PR01 Production producing one five minute granule of output data in each run It can be configured to produce as many as three five minute granules per run Each execution with one construction record and one date file for each dataset In normal these are created by which splits them out of the hour datasets For LANCE they are created by which merges all session MODIS L0 datasets overlapping the requested time and extracts from the merged data those packets which fall within that time period Each scan of data is stored in the L1A granule that covers the start time of that scan
Definition: MOD_PR01_pr.txt:19
int32 write_data(int32 isdfid, int32 osdfid, int32 isdsid, int32 osdsid, int32 ssamp, int32 srec, int32 esamp, int32 erec, int32 xsub, int32 ysub)
Definition: extract_sub.c:788
#define CHUNK_SZ
Definition: extract_sub.c:116
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 band
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 SUNREF
Definition: l1stat.h:53
int16_t * dark_rest
Definition: l1a_seawifs.c:89
int32 write_coords(int32 sdfid, int32 nrec, GeoType *geo_rec)
Definition: extract_sub.c:1398
#define MSECMIN
Definition: regen.h:13
#define L2FLAGS
Definition: l2stat.h:25
float32 * pos
Definition: l1_czcs_hdf.c:35
#define CTIME
Definition: regen.h:42
int32 * msec
Definition: l1_czcs_hdf.c:31
int16 eyear
Definition: l1_czcs_hdf.c:17
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
#define ECLAT
Definition: regen.h:59
int syear
Definition: l1_czcs_hdf.c:15
#define SCANELL
Definition: l1stat.h:52
#define LLLAT
Definition: regen.h:50
#define MSECSEC
Definition: regen.h:14
#define URLON
Definition: regen.h:49
int32 smsec
Definition: l1_czcs_hdf.c:16
#define ELON
Definition: regen_attr.h:32
int32 rdattr(int32 sdfid, char *attr_name, void *buf)
Definition: extract_sub.c:1087
int32 set_l1adata(int32 isdfid, int32 osdfid, int32 num_recs, int32 num_samps, int32 subsc_recs, int32 subsc_samps, int32 srec, int32 ssamp, int32 erec, int32 esamp, int32 xsub, int32 ysub, FilemetricsType *fm_rec)
Definition: extract_sub.c:2039
#define L1SATG2
Definition: regen.h:69
#define PTIME
Definition: regen.h:33
#define LRLAT
Definition: regen.h:52
#define MAXATTRS
Definition: regen.h:17
int sday
Definition: l1_czcs_hdf.c:15
#define MSECHOUR
Definition: regen.h:12
#define L1SATG1
Definition: regen.h:68
int32 rdslice(int32 sdfid, char *name, int32 *start, int32 *edge, void *buf)
Definition: extract_sub.c:1126
#define NSAMP
Definition: l1stat.h:23
#define SFLAGS
Definition: regen_attr.h:26
int32 regen(char *infile, int32 *ssamp, int32 *esamp, int32 *srec, int32 *erec, int32 px_sub, int32 sc_sub, char *parm_list, char *outfile)
Definition: extract_sub.c:152
#define EMSEC
Definition: regen.h:39
#define SSATP
Definition: regen_attr.h:36
void get_time(char *pr_time)
Definition: get_time.c:28
#define ATTANG
Definition: regen_attr.h:79
#define LRLON
Definition: regen.h:53
#define TILTFLAGS
Definition: regen.h:29
#define LVERT
Definition: regen_attr.h:77
#define SMSEC
Definition: regen.h:36
void cdata_()
#define SZEROP
Definition: regen_attr.h:37
#define L1ADATA
Definition: extract_sub.c:117
#define CLAT
Definition: regen_attr.h:29
void subsamp_2D(int32 spix, int32 sscan, int32 epix, int32 escan, int32 xdim, int32 xsub, int32 ysub, int32 nt, void *inbuf, void *outbuf)
Definition: extract_sub.c:1929
int32 set_sds(int32 isdfid, int32 osdfid, char *vgname, int32 ovid, int32 tag, int32 ref, int32 subsc_samps, int32 subsc_recs, char *parm_list, int32 *in_sdsid, int32 *out_sdsid)
Definition: extract_sub.c:661
#define L1NSATG1
Definition: regen.h:70
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
#define PCT_FLAG
Definition: regen.h:66
#define L1NSATG2
Definition: regen.h:71
#define PIX_START
Definition: regen.h:40
int32 set_tiltdata(int32 sdfid, int32 srec, int32 erec, int32 ysub, float32 *slatrec, float32 *slonrec, float32 *elatrec, float32 *elonrec, tilt_Type *old_tiltrec, tilt_Type *new_tiltrec)
Definition: extract_sub.c:1503
void free_nav_buffs(NavType *nav_rec)
Definition: extract_sub.c:1813
#define L1MEANR2
Definition: regen.h:74
float xlon[LAC_PIXEL_NUM]
Definition: l1a_seawifs.c:93
#define BCLAT
Definition: regen.h:58
#define ELAT
Definition: regen_attr.h:31
int32 subsamp_rec(int32 srec, int32 maxrec, int32 rank, int32 *dims, int32 ysub, int32 nt, void *obuf, void *nbuf)
Definition: extract_sub.c:1856
int32 emsec
Definition: l1_czcs_hdf.c:18
int32 set_flags(int32 sdfid, int32 nrec, int32 nsamp, int32 *flags)
Definition: extract_sub.c:1645
#define DARKREST
Definition: regen_attr.h:65
#define NFLAG
Definition: l1stat.h:54
#define ULLON
Definition: regen.h:47
const char * str
Definition: l1c_msi.cpp:35
int32 getset_gattrs(int32 isdfid, int32 osdfid)
Definition: extract_sub.c:390
#define EDAY
Definition: regen.h:38
#define PIX_SUB
Definition: regen.h:41
flags
Definition: DDAlgorithm.h:22
int32_t nbands
dtype
Definition: DDataset.hpp:31
int32 spix
Definition: l1_czcs_hdf.c:21
Extra metadata that will be written to the HDF4 file l2prod rank
void set_subsc_params(int32 nsamp, int32 nrec, int32 xsub, int32 ysub, int32 *ssamp, int32 *esamp, int32 *srec, int32 *erec, int32 *subsc_samps, int32 *subsc_recs, int32 *max_samp_used, int32 *max_rec_used)
Definition: extract_sub.c:318
#define URLAT
Definition: regen.h:48
#define ECLON
Definition: regen.h:61
#define TILTLATS
Definition: regen.h:31
int32 epix
Definition: l1_czcs_hdf.c:23
#define L1MEANR1
Definition: regen.h:73
for(i=0;i< NROOTS;i++) s[i]
Definition: decode_rs.h:85
#define NREC
Definition: regen.h:28
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
#define PROD_NAME
Definition: regen_attr.h:16
#define GAIN
Definition: regen_attr.h:55
#define EASTLON
Definition: regen.h:57
int i
Definition: decode_rs.h:71
#define SLON
Definition: regen_attr.h:28
#define MALLOC_ERR
Definition: regen.h:19
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int32 alloc_geonav_buffs(int32 nrec, GeoType *geo_rec)
Definition: extract_sub.c:1236
#define NORTHLAT
Definition: regen.h:54
#define SOUTHLAT
Definition: regen.h:55
int32 alloc_nav_buffs(int32 nrec, NavType *nav_rec)
Definition: extract_sub.c:1691
@ NBANDS
Definition: make_L3_v1.1.c:53
int k
Definition: decode_rs.h:73
int32 subsamp_l1adata(int32 srec, int32 erec, int32 ssamp, int32 esamp, int32 xsub, int32 ysub, int32 nsamp, int16 *gain, int16 *dark_rest, FilemetricsType *fm_rec, int16 *inbuf, int16 *outbuf, int16 *s_satp, int16 *s_zerop, int32 *new_buf_recs)
Definition: extract_sub.c:2187
int npix
Definition: get_cmp.c:27
int32 dupHDF(int32 ifid, int32 ofid, int32 isdfid, int32 osdfid, int32 *ssamp, int32 *esamp, int32 *srec, int32 *erec, int32 xsub, int32 ysub, int32 subsc_samps, int32 subsc_recs, int32 nvgps, char *parm_list)
Definition: extract_sub.c:569
#define ULLAT
Definition: regen.h:46
#define NTILTS
Definition: l1stat.h:45
int count
Definition: decode_rs.h:79
#define NCREC
Definition: regen.h:62