OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
raw2L0.c
Go to the documentation of this file.
1 /* ============================================================================ */
2 /* */
3 /* raw2L0 - converts raw (10-bit, 13860 byte) SeaWifs frames to Level-0 */
4 /* */
5 /* Synopsis: */
6 /* */
7 /* raw2L0 -f input-raw-filename -o output-L0-filename -l reclen */
8 /* raw2L0 < input-raw-filename > output-L0-filename -l reclen */
9 /* */
10 /* Description: */
11 /* */
12 /* The program reads raw SeaWiFS minor frames in 10-bit, 13860-byte format, */
13 /* from standard input, and writes the corresponding L0 file to standard */
14 /* output. Thus, it can be used as a filter. It will handle HRPT frames */
15 /* as well, provided they are truncated to 13860 bytes from there original */
16 /* 13862.5-byte form (or, better yet, the 20-bit pad is removed). */
17 /* */
18 /* Code now has option to define record length. Try 13864 for some HRPT. */
19 /* */
20 /* See Also: */
21 /* */
22 /* neb2raw */
23 /* */
24 /* */
25 /* Written By: */
26 /* */
27 /* Bryan A. Franz */
28 /* General Sciences Corp. */
29 /* 4 June 1996 */
30 /* */
31 /* Original version was blowup.f by Fred Patt */
32 /* */
33 /* ============================================================================ */
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <fcntl.h>
38 #include <string.h>
39 #include <errno.h>
40 #include <unistd.h>
41 #include "genutils.h"
42 
43 typedef unsigned char BYTE;
44 typedef short int INT16;
45 typedef int32_t INT32;
46 
47 #define CMD_ARGS "f:o:l:s:" /* Valid commandline options */
48 
49 #define MAXRECLEN 13864
50 #define INRECLEN 13860 /* # Bytes in raw minor frame */
51 #define OUTRECLEN 21504 /* # Bytes in level-0 record */
52 #define OUTHDRLEN 512 /* # Bites in level-0 header */
53 
54 
55 void bit10toi2(BYTE bit10[], INT16 ints[]);
56 
57 int main(int argc, char* argv[]) {
58  BYTE inrec [MAXRECLEN];
59  BYTE outrec[OUTRECLEN];
60  BYTE outhdr[OUTHDRLEN];
61  INT16 intbuf[4];
62 
63  FILE *infp = stdin;
64  FILE *outfp = stdout;
65 
66  INT32 inRecNum = 0L;
67  INT32 outRecNum = 0L;
68  INT32 i;
69 
70  INT32 reclen = INRECLEN;
71  INT32 startrec = 1;
72 
73  extern int opterr; /* used by getopt() */
74  extern int optind; /* used by getopt() */
75  extern char *optarg; /* used by getopt() */
76  int c; /* used by getopt() */
77 
78  /* */
79  /* Process command-line inputs */
80  /* */
81  while ((c = getopt(argc, argv, CMD_ARGS)) != EOF) {
82  switch (c) {
83  case 'f':
84  if ((infp = fopen(optarg, "r")) == NULL) {
85  fprintf(stderr, "%s: Error opening %s for reading.\n", argv[0], optarg);
86  exit(1);
87  }
88  break;
89  case 'o':
90  if ((outfp = fopen(optarg, "w")) == NULL) {
91  fprintf(stderr, "%s: Error opening %s for writing.\n", argv[0], optarg);
92  exit(1);
93  }
94  break;
95  case 'l':
96  reclen = atoi(optarg);
97  break;
98  case 's':
99  startrec = atoi(optarg);
100  break;
101  default:
102  fprintf(stderr, "Usage: %s [-f input-nebula-filename]\n", argv[0]);
103  fprintf(stderr, " [-o output-raw-filename]\n");
104  fprintf(stderr, " [-l reclen (13860 or 13864)]\n");
105  fprintf(stderr, " [-s start rec number (>1)]\n");
106  break;
107  }
108  }
109 
110  /* */
111  /* Initialize */
112  /* */
113  memset(outrec, 0, OUTRECLEN);
114  memset(outhdr, 0, OUTHDRLEN);
115 
116  /* */
117  /* Write L0 file header to standard out */
118  /* */
119  memcpy(outhdr, "CWIF", 5);
120  if (fwrite(outhdr, OUTHDRLEN, 1, outfp) != 1) {
121  printf("Error writing output file at record %d\n", outRecNum);
122  exit(1);
123  }
124 
125 
126  /* */
127  /* Read through end of input file */
128  /* */
129  while (fread(inrec, reclen, 1, infp) == 1) {
130 
131  inRecNum++;
132 
133  if (inRecNum < startrec) continue;
134 
135  /* */
136  /* Copy S/C ID */
137  /* */
138  bit10toi2(&inrec[5], intbuf);
139  memcpy(&outrec[3], &intbuf[2], 4);
140 
141  /* */
142  /* Copy Timetag */
143  /* */
144  bit10toi2(&inrec[10], intbuf);
145  memcpy(&outrec[7], intbuf, 8);
146 
147  /* */
148  /* Copy SOH block (no conversion required) */
149  /* */
150  memcpy(&outrec[15], &inrec[15], 775);
151 
152  /* */
153  /* Copy rest of frame (Inst., Scan, G&TDI) */
154  /* */
155  for (i = 0; i < 2589; i++) {
156  bit10toi2(&inrec[790 + i * 5], intbuf);
157  memcpy(&outrec[790 + i * 8], intbuf, 8);
158  }
159 
160  /* */
161  /* Write L0 record to standard output */
162  /* */
163  if (fwrite(outrec, OUTRECLEN, 1, outfp) != 1) {
164  printf("Error writing output file at record %d\n", outRecNum);
165  exit(1);
166  } else
167  outRecNum++;
168 
169  }
170 
171 
172  /* */
173  /* Check for error on input stream */
174  /* */
175  if (ferror(infp)) {
176  fprintf(stderr, "Error reading input file at record %d\n", inRecNum);
177  fclose(infp);
178  exit(1);
179  }
180 
181  /* */
182  /* Normal Termination */
183  /* */
184  fprintf(stderr, "End of file reached.\n");
185  fprintf(stderr, "Number of input records = %d\n", inRecNum);
186  fprintf(stderr, "Number of output records = %d\n", outRecNum);
187  fclose(infp);
188  fclose(outfp);
189 
190  return (0);
191 
192 }
193 
194 
195 /* ---------------------------------------------------------------------------- */
196 /* Unpacks a 5-element byte array into a 4-element I*2 array, using the 10 */
197 /* least significant bits of each integer. */
198 
199 /* ---------------------------------------------------------------------------- */
200 void bit10toi2(BYTE bit10[], INT16 ints[]) {
201  ints[0] = (((INT16) bit10[1] & 0xC0) >> 6) + (((INT16) bit10[0] & 0xFF) << 2);
202  ints[1] = (((INT16) bit10[2] & 0xF0) >> 4) + (((INT16) bit10[1] & 0x3F) << 4);
203  ints[2] = (((INT16) bit10[3] & 0xFC) >> 2) + (((INT16) bit10[2] & 0x0F) << 6);
204  ints[3] = (((INT16) bit10[4] & 0xFF) >> 0) + (((INT16) bit10[3] & 0x03) << 8);
205 
206  if (endianess() == 1) {
207  swapc_bytes((char *) ints, 2, 4);
208  }
209 }
unsigned char BYTE
Definition: raw2L0.c:43
#define L(lambda, T)
Definition: PreprocessP.h:185
#define NULL
Definition: decode_rs.h:63
#define OUTHDRLEN
Definition: raw2L0.c:52
int32_t INT32
Definition: elements.h:6
#define INRECLEN
Definition: raw2L0.c:50
void bit10toi2(BYTE bit10[], INT16 ints[])
Definition: raw2L0.c:200
int endianess(void)
determine endianess
Definition: endianess.c:10
int swapc_bytes(char *in, int nbyte, int ntime)
Definition: swapc_bytes.c:4
unsigned char BYTE
Definition: elements.h:4
short int INT16
Definition: elements.h:5
#define MAXRECLEN
Definition: raw2L0.c:49
int main(int argc, char *argv[])
Definition: raw2L0.c:57
short int INT16
Definition: raw2L0.c:44
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
int i
Definition: decode_rs.h:71
#define CMD_ARGS
Definition: raw2L0.c:47
int32_t INT32
Definition: raw2L0.c:45
#define OUTRECLEN
Definition: raw2L0.c:51