OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l0cnst_write_modis.c
Go to the documentation of this file.
1 /*----------------------------------------------------------------------
2 Copyright (C) 2000, Space Science and Engineering Center, University
3 of Wisconsin-Madison, Madison WI.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ------------------------------------------------------------------------*/
19 
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <PGS_TD.h>
27 
28 #define buffsize_mb 0.5
29 #define primary_hdr_size 6
30 #define OUTBUFLEN 384
31 
32 #define O_STRING "nf:"
33 
34 #define USAGE "write_constructor_file (%s %s)\n\
35 \
36 Usage: %s [-n] [-f outfile] infile\n\
37 \n\
38 Note:\n\
39 If outfile is not specified, it will be infile.constr\n\
40 \n\
41 -n : do not generate a constructor file but print statistics\n\
42 "
43 
44 void print_usage(char *prog) {
45  printf(USAGE, __DATE__, __TIME__, prog);
46 }
47 
48 int main(int argc, char *argv[]) {
49  int n_packets = 0;
50  int read_cnt;
51  long strm_pos = 0;
52  int packet_length = 0;
53  int buf_pos = 0;
54  int buf_pos_last = 0;
55  int bytes_left;
56  int last_pkt_in_file;
57  int last_pkt_in_buffer;
58  int found_start_time;
59  int buffsize;
60  int n_night = 0;
61  int n_day = 0;
62  int c;
63  int fopt = 0;
64  int nopt = 0;
65  int errflag = 0;
66 
67  static int pkt_len_off = 4;
68  static int time_off = primary_hdr_size;
69  static int time_cnt = 8;
70  static int L0_true = 0;
71  static int L0_false = 1;
72  static int day_pkt_size = 642;
73  static int night_pkt_size = 276;
74  static unsigned char start_time_tag[8];
75  static unsigned char stop_time_tag[8];
76  char *cptr = (char *) &n_packets;
77 
78  double taitime_start;
79  double taitime_stop;
80 
81  unsigned char *buffer, outbuf[OUTBUFLEN];
82 
83  char outfile[FILENAME_MAX];
84  char *infile;
85  int len;
86 
87  FILE *stream, *outfp = NULL;
88 
89  /* For getopt() */
90  extern int optind;
91  extern char *optarg;
92 
93 
94  /*
95  ** Process command-line options
96  */
97  while ((c = getopt(argc, argv, O_STRING)) != -1) {
98  switch (c) {
99  case 'n':
100  nopt++;
101  break;
102  case 'f':
103  len = snprintf(outfile, sizeof (outfile), "%s", optarg);
104  if (strlen(outfile) == len) {
105  fopt++;
106  } else {
107  printf("specified output file name too long!\n");
108  errflag++;
109  }
110  break;
111  default:
112  errflag++;
113  break;
114  ;
115  }
116  }
117 
118 
119  if (optind < argc && !errflag) {
120  printf("write_constructor_file: Version as of %s %s\n", __DATE__, __TIME__);
121 
122  /* Set input file */
123  infile = argv[argc - 1];
124 
125  /* If -n not given and no output file specified, create its name from input file */
126  if (!fopt && !nopt) {
127  len = snprintf(outfile, FILENAME_MAX, "%s.constr", infile);
128  if (strlen(outfile) != len) {
129  printf("derived output file name is too long!\n");
130  errflag++;
131  }
132  }
133 
134  /* Open input file */
135  stream = fopen(infile, "r");
136 
137  if (stream != NULL) {
138  /* Open output file if -n not given */
139  if (!nopt)
140  outfp = fopen(outfile, "w");
141 
142  if (outfp != NULL || nopt) {
143 
144  fseek(stream, (long) 0, SEEK_SET);
145 
146  buffsize = buffsize_mb * 1000000;
147  buffer = (unsigned char *) malloc(buffsize * sizeof (unsigned char));
148  if (buffer == NULL) {
149  fseek(stream, (long) 0, SEEK_SET);
150  return 1;
151  }
152 
153  last_pkt_in_file = L0_false;
154  found_start_time = L0_false;
155 
156  while (last_pkt_in_file == L0_false) {
157  last_pkt_in_buffer = L0_false;
158 
159  read_cnt = fread(buffer, sizeof (char), buffsize, stream);
160  //printf("read_cnt: %d buffsize: %d\n", read_cnt,buffsize);
161 
162  buf_pos = 0;
163  while (last_pkt_in_buffer == L0_false) {
164  bytes_left = read_cnt - buf_pos;
165  if (bytes_left < day_pkt_size) {
166  if (bytes_left == 0) {
167  last_pkt_in_buffer = L0_true;
168  continue;
169  } else if ((bytes_left == night_pkt_size) ||
170  (bytes_left == 2 * night_pkt_size)) {
171  } else if (feof(stream) == 0) {
172  last_pkt_in_buffer = L0_true;
173  fseek(stream, strm_pos, SEEK_SET);
174  continue;
175  } else {
176  printf("Corrupt record found at end of file.\n");
177  free(buffer);
178  fseek(stream, (long) 0, SEEK_SET);
179  return 3;
180  }
181  }
182 
183  packet_length = buffer[buf_pos + (pkt_len_off)]*256 +
184  buffer[buf_pos + pkt_len_off + 1];
185  packet_length += 1;
186  packet_length += primary_hdr_size;
187 
188  if ((packet_length != 642) && (packet_length != 276)) {
189  // utc_str[27] = '\0';
190  if (n_packets > 0) {
191  printf("Packet with invalid length found: (%d).\n", packet_length);
192  }
193  free(buffer);
194  fseek(stream, (long) 0, SEEK_SET);
195  return 3;
196  }
197 
198  if (packet_length == 642) n_day++;
199  if (packet_length == 276) n_night++;
200 
201  if (found_start_time == L0_false) {
202  memcpy(start_time_tag, &buffer[buf_pos + time_off], time_cnt);
203  found_start_time = L0_true;
204  } else {
205  memcpy(stop_time_tag, &buffer[buf_pos_last + time_off], time_cnt);
206  PGS_TD_EOSAMtoTAI(stop_time_tag, &taitime_stop);
207  PGS_TD_TAItoUTC(taitime_stop, (char*) outbuf);
208  /*printf("stoptime =%s\n", outbuf);*/
209  }
210 
211  strm_pos += (long) packet_length;
212  buf_pos_last = buf_pos;
213  buf_pos += packet_length;
214  n_packets++;
215  if ((n_packets % 100000) == 0) {
216  printf("%10d packets read\n", n_packets);
217  }
218  } /* end while ( last_pkt_in_buffer == L0_false ) */
219 
220  if (feof(stream) != 0) {
221  last_pkt_in_file = L0_true;
222  }
223 
224  if (ferror(stream) != 0) {
225  free(buffer);
226  fseek(stream, (long) 0, SEEK_SET);
227  return 2;
228  }
229 
230  } /* end while ( last_pkt_in_file == L0_false ) */
231 
232  free(buffer);
233 
234  printf("%d Total packets read\n", n_packets);
235 
236  printf("%d day packets\n", n_day);
237  printf("%d night packets\n", n_night);
238 
239 
240  /* If -n option not given, write constructor record */
241  if (outfp != NULL) {
242 
243  printf("Writing constuctor record for %s to %s\n", infile, outfile);
244 
245  memset(outbuf, 0, OUTBUFLEN);
246 
247  fseek(outfp, 0, SEEK_SET);
248 
249  memset(&outbuf[0x33], 1, 1);
250 
251  memcpy(&outbuf[0x50], start_time_tag, 8);
252  memcpy(&outbuf[0x58], stop_time_tag, 8);
253 
254  memcpy(&outbuf[0x16c], start_time_tag, 8);
255  memcpy(&outbuf[0x174], stop_time_tag, 8);
256 
257  memcpy(&outbuf[0x74], cptr + 3, 1);
258  memcpy(&outbuf[0x75], cptr + 2, 1);
259  memcpy(&outbuf[0x76], cptr + 1, 1);
260  memcpy(&outbuf[0x77], cptr + 0, 1);
261 
262  memset(&outbuf[0x93], 1, 1);
263  memset(&outbuf[0xa3], 1, 1);
264  memset(&outbuf[0xf7], 2, 1);
265 
266  memset(&outbuf[0x167], 1, 1);
267 
268  if (fwrite(outbuf, OUTBUFLEN, 1, outfp) == 0) {
269  printf("fwrite failed: %s\n", strerror(errno));
270  errflag++;
271  }
272 
273  /* Close output file */
274  fclose(outfp);
275 
276  }
277 
278  /* Close input file */
279  fclose(stream);
280 
281  PGS_TD_EOSAMtoTAI(start_time_tag, &taitime_start);
282  PGS_TD_TAItoUTC(taitime_start, (char*) outbuf);
283  printf("starttime=%s\n", outbuf);
284 
285  PGS_TD_EOSAMtoTAI(stop_time_tag, &taitime_stop);
286  PGS_TD_TAItoUTC(taitime_stop, (char*) outbuf);
287  printf("stoptime =%s\n", outbuf);
288 
289  printf("granule length =%f\n", taitime_stop - taitime_start);
290  } else {
291  /* Failed to open output file */
292  printf("failed to open output file: %s\n", strerror(errno));
293  errflag++;
294  }
295  } else {
296  /* Failed to open input file */
297  printf("failed to open input file: %s\n", strerror(errno));
298  errflag++;
299  }
300  } else {
301  print_usage(argv[0]);
302  }
303 
304  return errflag;
305 }
#define NULL
Definition: decode_rs.h:63
int main(int argc, char *argv[])
#define buffsize_mb
#define O_STRING
#define primary_hdr_size
int errno
#define USAGE
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
void print_usage(char *prog)
#define OUTBUFLEN