OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
main_l1agen.c
Go to the documentation of this file.
1 /* ==================================================================== */
2 /* */
3 /* SWl01 - converts seawifs level-0 data to level-1 */
4 /* */
5 /* Synopsis: */
6 /* */
7 /* SWl01 input-L0-filename [output-L1-directory] */
8 /* */
9 /* Description: */
10 /* */
11 /* The program reads the input level-0 file and generates one or */
12 /* more level-1a hdf-formatted output files. One file will be */
13 /* generated for each contiguous scene, and for HRPT data there is */
14 /* only one scene. For stored GAC, there is one scene for each */
15 /* orbit, and stored LAC scenes are broken when the data type */
16 /* changes or the time between frames is greater than n seconds. */
17 /* */
18 /* The output file(s) will be named Syyyydddhhmmss.L1A_*, where the */
19 /* trailing suffix will indicate the HRPT station ID, or the stored */
20 /* data type. Each output L1A file will be accompanied by a meta */
21 /* data file with the same name and a ".meta" extension. */
22 /* */
23 /* The processing steps are as follows: */
24 /* */
25 /* 1 Read through input file and generate index of frame content */
26 /* and quality, as well as scene break points. */
27 /* */
28 /* 2 Read selected frames to accumulate raw GPS telemetry, and */
29 /* fit GPS to orbit model to produce filtered orbit vectors for */
30 /* the time period over which the input data extends. */
31 /* */
32 /* 3 For each scene, read the state-of-health and instrument tlm */
33 /* from the "good" quality frames, and generate navigation for */
34 /* every scan. */
35 /* */
36 /* 4 For each scene, read image data from the "good" quality frames,*/
37 /* combine with the navigation information, and write to L1A file.*/
38 /* */
39 /* Written By: */
40 /* */
41 /* Bryan A. Franz */
42 /* General Sciences Corp. */
43 /* 27 September 1997 */
44 /* */
45 /* =====================================================================*/
46 
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <fcntl.h>
50 #include <string.h>
51 #include <errno.h>
52 #include <unistd.h>
53 #include <libgen.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 
57 #include "swl0_proto.h"
58 #include "swl1_hdf.h"
59 
60 #define CMD_ARGS "mhgt:b:s:e:d:n:f:"
61 
62 void usage(char *file) {
63  printf("%s %s (%s %s)\n",
64  file, L01VERSION, __DATE__, __TIME__);
65  if (endianess() == 1)
66  printf(" (byte-swapping on)\n");
67  printf("\nUsage: %s [-%s] level0_filename [output-file-name or dir]\n",
68  file, CMD_ARGS);
69  printf(" -m : turn-off metadata file generation.\n");
70  printf(" -h : force hrpt processing.\n");
71  printf(" -g : force GAC processing.\n");
72  printf(" -t n : limit timetags to +/- n-days around data start time.\n");
73  printf(" -b n : maximum number of bit errors allowed per frame (def=50).\n");
74  printf(" -s n : fix gain setting for HRPT (def=0, -1 to determine from telemetry).\n");
75  printf(" -d n : stop-time delta (seconds).\n");
76  printf(" -e file : timing anomaly update filename, GAC only. (def=NULL)\n");
77  printf(" If not provided, no timing error search will be done.\n");
78  printf(" -n environment : runtime environment: seadas or sdps (def=seadas).\n");
79  printf(" -f file : station info file (def=$HRPT_STATION_IDENTIFICATION_FILE).\n");
80 
81  exit(FATAL_ERROR);
82 }
83 
84 
85 /* -------------------------------------------------------------------- */
86 /* main */
87 
88 /* -------------------------------------------------------------------- */
89 int main(int argc, char* argv[]) {
90  swl0indx indx; /* L0 file content and quality */
91  INT16 nscenes = 0; /* Number of scenes in L0 file */
92  swl1rec l1rec[5]; /* Array of L1 records */
93  INT16 nl1rec; /* Number of L1 recs (1 or 5) */
94  INT16 is; /* Scene number */
95  INT16 iframe; /* Minor frame number */
96  INT16 irec; /* Record number */
97  INT32 sceneScanNum; /* Scan number within scene */
98 
99  INT32 norb; /* Number of orbit input recs */
100  orbit_sType orbit; /* Processed orbit data */
101  INT32 nframes; /* Number of input recs for nav*/
102  navctl_sType navctl; /* Navigation control info */
103  navqc_sType navqc; /* Navigation quality info */
104  INT32 nlines; /* Number of navblk recs */
105  tilt_states_sType tiltblk; /* Tilt states per scene */
106  FLOAT32 xnodel; /* Longitude of dscending node */
107  INT32 tnode; /* Time of node crossing */
108 
109  swl0ctl l0ctl; /* Control str for L0 indexing */
110  char *l0file = NULL; /* Input L0 file path */
111  char l1file[FILENAME_MAX]; /* Output L1A file path */
112  char *outpath = "."; /* Output file dir or path */
113  char *metadir; /* Output metafile directory */
114  char metafile[FILENAME_MAX]; /* Output metafile path */
115  char *outdir; /* Output file dir */
116  char *filename; /* Output L1A filename */
117  unsigned char dataType; /* Flag for file naming */
118  struct stat file_stat; /* File status buffer */
119  char *tmppath; /* Temporary file path */
120  int haveFilename = 0; /* If set, don't create fileame*/
121  int wantMeta = 1; /* Generate meta data by def */
122  char proccon[1024] = ""; /* Store command-line sequence */
123  char proclog[1024] = ""; /* Store processing log */
124  char timefile[FILENAME_MAX]; /* time shift filename */
125  char *updfile = NULL;
126  char stationInfoFile[FILENAME_MAX]; /* station filename */
127 
128  int i;
129  INT32 status = 0;
130 
131  /* These are declared static to force solaris to allocate the full */
132  /* space at load time. Otherwise, the code core dumps at startup */
133 
134  static input_sType orbinp[MAXFRAMES]; /* Input for orbit filtering */
135  static input_sType navinp[MAXFRAMES]; /* Input for navigation */
136  static navblk_sType navblk[MAXFRAMES]; /* Processed navigation data */
137  static swl0scene scene[MAXSCENES]; /* Scene index structure */
138 
139  /* Parameters for getopt() */
140  extern int opterr;
141  extern int optind;
142  extern char *optarg;
143  int c;
144 
145  if (argc > 1 && !strcmp(argv[1], "--version")) {
146  printf("%s %s (compiled %s, %s)\n",
147  argv[0], L01VERSION, __DATE__, __TIME__);
148  if (endianess() == 1)
149  printf(" (byte-swapping on)\n");
150  exit(0);
151  }
152 
153  /* */
154  /* Load telemetry decomm commons used by swfnav library */
155  /* */
156 
157  /* MDM Oct. 15, 2004 */
158  /* due to the linker not including these block data routines, I've put
159  them inline in the one place each of them is used.. therefore they
160  are now completely eliminated and Bryan's calls are no longer req'd */
161  /* acs_block_(); */
162  /* ins_block_(); */
163 
164  /* */
165  /* Enable line buffering for better log-file monitoring */
166  /* */
167  setvbuf(stdout, NULL, _IOLBF, 0);
168 
169  /* */
170  /* Log command-line sequence to process-control string */
171  /* */
172  strcpy(proccon, argv[0]);
173  for (i = 1; i < argc; i++) {
174  strcat(proccon, " ");
175  strcat(proccon, argv[i]);
176  }
177 
178 
179  /* */
180  /* Initialize control structure */
181  /* */
182  l0ctl.fileType = -1; /* Get filetype from header */
183  l0ctl.timerangeFactor = 0; /* Get timerange limits from header */
184  l0ctl.maxBitErrors = 50; /* Max bit errors before tossing frame*/
185  l0ctl.gainSetting = 0; /* Forced gain setting, for HRPT only */
186  l0ctl.stopTimeDelta = 1800; /* Stop-time delta (seconds) */
187  l0ctl.env = SEADAS; /* Environment flag */
188  l0ctl.progname = argv[0]; /* Program name for meta */
189  l0ctl.stationInfoFile = NULL; /* File containing station meta info */
190 
191 
192  /* */
193  /* Process command-line arguments */
194  /* */
195  while ((c = getopt(argc, argv, CMD_ARGS)) != EOF) {
196  switch (c) {
197  case 'm':
198  wantMeta = 0;
199  break;
200  case 'b':
201  l0ctl.maxBitErrors = atoi(optarg);
202  break;
203  case 's':
204  l0ctl.gainSetting = atoi(optarg);
205  break;
206  case 't':
207  l0ctl.timerangeFactor = atoi(optarg);
208  break;
209  case 'd':
210  l0ctl.stopTimeDelta = atoi(optarg);
211  break;
212  case 'h':
213  l0ctl.fileType = HRPT;
214  break;
215  case 'g':
216  l0ctl.fileType = GAC;
217  break;
218  case 'e':
219  strncpy(timefile, optarg, FILENAME_MAX);
220  updfile = timefile;
221  break;
222  case 'n':
223  if (strcmp(optarg, "sdps") == 0)
224  l0ctl.env = SDPS;
225  else
226  l0ctl.env = SEADAS;
227  ;
228  break;
229  case 'f':
230  strncpy(stationInfoFile, optarg, FILENAME_MAX);
231  l0ctl.stationInfoFile = stationInfoFile;
232  break;
233  default:
234  usage(argv[0]);
235  break;
236  }
237  }
238  switch (argc - optind + 1) {
239  case 3:
240  l0file = argv[optind + 0];
241  outpath = argv[optind + 1];
242  break;
243  case 2:
244  l0file = argv[optind + 0];
245  break;
246  default:
247  usage(argv[0]);
248  break;
249  }
250 
251 
252  printf("\nBegin %s Version %s Processing for %s using the ",
253  l0ctl.progname, L01VERSION, l0file);
254  if (l0ctl.env == SEADAS)
255  printf("SeaDAS environment\n\n");
256  else
257  printf("SDPS environment\n\n");
258 
259 
260  /* */
261  /* Extract output directory from full (or partial) path. */
262  /* */
263  if (stat(outpath, &file_stat) == 0 && S_ISDIR(file_stat.st_mode)) {
264  /* output path contains output directory */
265  outdir = strdup(outpath);
266  } else {
267  /* output path contains full directory and filename */
268  haveFilename = 1;
269  tmppath = strdup(outpath);
270  outdir = strdup(dirname(tmppath));
271  free(tmppath);
272  }
273 
274  /* Set metadata output dir */
275  if ((metadir = getenv("L1A_META_DIR")) == NULL) {
276  metadir = strdup(outdir);
277  }
278 
279  /* */
280  /* Get L0 content and quality index */
281  /* */
282  printf("\nGenerating Level-0 file index ...\n");
283  nframes = getl0indx(l0file, &l0ctl, &indx);
284  if (nframes <= 0) {
285  printf("-E- %s: no frames found in %s\n", argv[0], l0file);
286  exit(FATAL_ERROR);
287  }
288  locate_temporal_anomalies(&indx, updfile);
289  printindx(&indx);
290 
291 
292  /* */
293  /* Create scene index */
294  /* */
295  printf("\nGenerating Level-0 scene index ...\n");
296  nscenes = getl0scene(&indx, scene);
297  if (nscenes < 1) {
298  printf("-E- %s: no valid scenes found in %s\n", argv[0], l0file);
299  exit(FATAL_ERROR);
300  }
301  printscene(nscenes, scene);
302 
303 
304  /* */
305  /* Gather telemetry for orbit determination and compute filtered */
306  /* orbit vectors. */
307  /* */
308  printf("\nGathering raw GPS orbit data ...\n");
309  norb = getorbdata(&indx, orbinp);
310  printf("Found %d frames with valid GPS data.\n", norb);
311  if (norb < MINORBVEC) {
312  printf("-E- %s: insufficient GPS telemetry.\n", argv[0]);
313  exit(FATAL_ERROR);
314  }
315  printf("\nGenerating filtered GPS orbit vectors ...\n");
316  initnav_(orbinp, &norb, &navctl, &navqc, &orbit, &status);
317  if (status != 0) {
318  printf("-E- %s: unable to process orbit vectors.\n", argv[0]);
319  exit(FATAL_ERROR);
320  }
321 
322  /* */
323  /* Process each scene */
324  /* */
325  for (is = 0; is < nscenes; is++) {
326 
327  printf("\nProcessing scene %d ...\n", is);
328 
329  /* */
330  /* Construct output filename, or extract from output path. */
331  /* */
332  if (!haveFilename) {
333  if (scene[is].type == HRPT)
334  dataType = 16;
335  else
336  dataType = scene[is].mnftype;
337  filename = L1aFilename(&l0ctl, scene[is].stime, dataType);
338  sprintf(l1file, "%s/%s", outpath, filename);
339  } else {
342  }
343  printf("\nOutput filename is %s\n", filename);
344  printf("Output file dir: %s\n", outdir);
345  printf("Metafile dir: %s\n\n", metadir);
346 
347  /* */
348  /* Load navigation input structure, skip scene if error occurs */
349  /* */
350  printf("Loading navigation data\n");
351  nframes = getnavdata(&scene[is], navinp);
352  if (nframes != scene[is].nrec) {
353  printf("-E- %s: error reading nav data for scene %d\n",
354  argv[0], is);
355  status++;
356  continue;
357  }
358 
359  /* */
360  /* Compute scene navigation. */
361  /* */
362  printf("Navigating scene\n");
363 
364  swfnav_(&navqc, &navctl, navinp, &nframes, &orbit, &nlines,
365  navblk, &tiltblk, &xnodel, &tnode);
366 
367  if (getl0scene_nav(xnodel, tnode, navblk, &tiltblk, &scene[is]) != 0) {
368  printf("-E- %s: no valid navigation for scene %d\n",
369  argv[0], is);
370  status++;
371  continue;
372  }
373  printnav(&scene[is]);
374 
375 
376  /* */
377  /* Write L1A file for this scene */
378  /* */
379  if (CreateL1aFile(l1file, &scene[is], proccon, proclog, &l0ctl) != 0) {
380  printf("-E- %s: error creating L1A file for scene %d\n",
381  argv[0], is);
382  status++;
383  continue;
384  }
385 
386  sceneScanNum = 0;
387  for (iframe = 0; iframe < scene[is].nrec; iframe++) {
388 
389  if ((iframe % 500) == 0)
390  printf("Writing frame %5d of scene %2d\n", iframe, is);
391 
392  nl1rec = getl1rec(iframe, &scene[is], &l0ctl,
393  navinp, navblk, &tiltblk, l1rec);
394 
395  for (irec = 0; irec < nl1rec; irec++) {
396  addL1Metrics(sceneScanNum, &l1rec[irec]);
397  if (WriteScanData(sceneScanNum, &l1rec[irec]) != 0) {
398  printf("-E- %s: error writing to L1A file for scene %d\n",
399  argv[0], is);
400  break;
401  }
402  sceneScanNum++;
403  }
404 
405  /* If an error occurs, end processing for this scene */
406  if (irec != nl1rec) {
407  status++;
408  break;
409  }
410  }
412 
413  /* Write associated metadata file */
414  if (wantMeta) {
415  sprintf(metafile, "%s/%s.meta", metadir, filename);
416  mkmeta(metafile, l1file, &scene[is], &l0ctl);
417  }
418  }
419 
420  printf("\nNumber of scenes processed = %d\n", nscenes);
421  printf("Number of scenes failed = %d\n\n", status);
422 
423  exit(status);
424 
425 }
426 
427 
428 
429 
430 
INT32 getl0indx(char *filename, swl0ctl *l0ctl, swl0indx *indx)
Definition: getl0indx.c:15
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
Definition: l1stat_chk.c:586
int initnav_(input_sType input[], INT32 *nframes, navctl_sType *navctl, navqc_sType *navqc, orbit_sType *orbit, INT32 *status)
int status
Definition: l1_czcs_hdf.c:32
int mkmeta(const char *metaFile, const char *l1aFile, swl0scene *scene, swl0ctl *l0ctl)
Definition: mkmeta.c:37
*********************************************HISTORY FILE for MOD_PR02AQUA **Version ****Point of no algorithm change is made in this so the and when the blackbody temperature is above a threshold Since the LWIR FPA temperature oscillates on orbit
Definition: HISTORY.txt:106
INT32 getnavdata(swl0scene *scene, input_sType navinp[])
Definition: getnavdata.c:8
int WriteScanData(int32 scan, swl1rec *l1rec)
Definition: swl1_hdf.c:672
#define NULL
Definition: decode_rs.h:63
l1met * getL1Metrics(void)
Definition: getmetrics.c:60
read l1rec
int32_t INT32
Definition: elements.h:6
#define MAXFRAMES
Definition: swl0_parms.h:9
#define SEADAS
Definition: swl0_parms.h:53
int swfnav_(navqc_sType *navqc, navctl_sType *navctl, input_sType input[], INT32 *nframes, orbit_sType *orbit, INT32 *nlines, navblk_sType navblk[], tilt_states_sType *tiltblk, FLOAT32 *xnodel, INT32 *tnode)
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that and then aggregated up to Resolved feature request Bug by adding three new int8 SDSs for each high resolution offsets between the high resolution geolocation and a bi linear interpolation extrapolation of the positions This can be used to reconstruct the high resolution geolocation Resolved Bug by delaying cumulation of gflags until after validation of derived products Resolved Bug by setting Latitude and Longitude to the correct fill resolving to support Near Real Time because they may be unnecessary if use of entrained ephemeris and attitude data is turned resolving bug report Corrected to filter out Aqua attitude records with missing status helping resolve bug MOD_PR03 will still correctly write scan and pixel data that does not depend upon the start thereby resolving MODur00108 Changed header guard macro names to avoid reserved name resolving MODur00104 Maneuver list file for Terra satellite was updated to include data from Jecue DuChateu Maneuver list files for both Terra and Aqua were updated to include two maneuvers from recent IOT weekly reports The limits for Z component of angular momentum was and to set the fourth GEO scan quality flag for a scan depending upon whether or not it occurred during one of them Added _FillValue attributes to many and changed the fill value for the sector start times from resolving MODur00072 Writes boundingcoordinate metadata to L1A archived metadata For PERCENT *ECS change to treat rather resolving GSFcd01518 Added a LogReport Changed to create the Average Temperatures vdata even if the number of scans is
Definition: HISTORY.txt:301
#define GAC
Definition: l1stat.h:33
void addL1Metrics(INT32 scanNum, swl1rec *l1rec)
Definition: getmetrics.c:16
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
int endianess(void)
determine endianess
Definition: endianess.c:10
short int INT16
Definition: elements.h:5
void printnav(swl0scene *scene)
Definition: printnav.c:10
#define MINORBVEC
Definition: swl0_parms.h:12
#define HRPT
Definition: l1stat.h:35
char * strdup(const char *)
int CloseL1aFile(l1met *metrics)
Definition: swl1_hdf.c:777
#define CMD_ARGS
Definition: main_l1agen.c:60
void printindx(swl0indx *indx)
Definition: printindx.c:29
#define FATAL_ERROR
Definition: swl0_parms.h:5
INT32 getl1rec(INT16 sceneFrameNum, swl0scene *scene, swl0ctl *l0ctl, input_sType navinp[], navblk_sType navblk[], tilt_states_sType *tiltblk, swl1rec l1rec[])
Definition: getl1rec.c:45
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
float FLOAT32
Definition: elements.h:7
int main(int argc, char *argv[])
Definition: main_l1agen.c:89
#define L01VERSION
Definition: swl0_parms.h:4
int getl0scene_nav(FLOAT32 xnodel, INT32 tnode, navblk_sType navblk[], tilt_states_sType *tiltblk, swl0scene *scene)
void printscene(int nscenes, swl0scene scene[])
Definition: printscene.c:14
char * L1aFilename(swl0ctl *l0ctl, double time, unsigned char dataType)
Definition: swl1_hdf.c:1245
#define basename(s)
Definition: l0chunk_modis.c:29
void usage(char *file)
Definition: main_l1agen.c:62
string outpath
Definition: color_dtdb.py:224
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
int16_t * nscenes
Definition: l2bin.cpp:86
#define MAXSCENES
Definition: swl0_parms.h:10
#define SDPS
Definition: swl0_parms.h:54
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
INT16 getl0scene(swl0indx *indx, swl0scene scene[])
Definition: getl0scene.c:14
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
INT32 getorbdata(swl0indx *indx, input_sType gps[])
Definition: getorbdata.c:9
int CreateL1aFile(char *path, swl0scene *scene, char *proccon, char *proclog, swl0ctl *l0ctl)
Definition: swl1_hdf.c:39
INT32 locate_temporal_anomalies(swl0indx *indx, char *timefile)