OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
read_crtt.c
Go to the documentation of this file.
1 #include <libgen.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "l1czcs.h"
6 #include "navigation.h"
7 
8 #define CTL_PT_INC 8 /* control point incriment (fixed for now) */
9 #define N_ANCHOR 77
10 
11 int read_crtt(char *crtt_file, gattr_struc *gattr, l1_data_struc *l1_data)
12 /*******************************************************************
13 
14  read_crtt
15 
16  purpose: read the needed data from the CRTT raw data file
17 
18  Returns type: int - 0 no problems, else file open, read problems
19 
20  Parameters: (in calling order)
21  Type Name I/O Description
22  ---- ---- --- -----------
23  char * crtt_file I name of the raw file
24  gattr_struc * gattr O structure with final
25  attributes
26  l1_data_struc * l1_data O arrays data counts, lat, lons
27 
28  Modification history:
29  Programmer Date Description of change
30  ---------- ---- ---------------------
31  W. Robinson 10-Mar-2004 Original development, based on
32  read_l1_czcs program
33  W. Robinson 2-Dec-2005 add capability to use Nimbus 7 orbit
34  data, calling fill_orb_dat
35 
36  *******************************************************************/ {
37  char *get_file_specifier();
38  char *get_file_name();
39  char *file_name;
40  int yr, doy;
41  int i = 0, j, n_ctl, n_ctl_pt;
42  FILE *fptr;
43  /* def of the cal_czcs */
44  void cal_czcs(int, gattr_struc *, l1_data_struc *);
45 
46  HEADER1_TYPE header1;
47  HEADER2_TYPE header2;
48  DATA_REC_TYPE data;
49 
50  short header2_size, /* size of header 2 record in blocks */
51  data_rec_size, /* size of data record in blocks */
52  offset_header, /* offset to first header record in blocks */
53  offset_data, /* offset to first data record in blocks */
54  num_of_data_recs;
55 
56  /* get file name: */
57  file_name = basename(crtt_file);
58 
59  sscanf(file_name, "%2d%3d", &yr, &doy);
60  yr = yr + 1900;
61  fptr = fopen(crtt_file, "r");
62  if (!(fptr = fopen(crtt_file, "r"))) {
63  printf("File \"%s\" not found.\n", crtt_file);
64  exit(-1);
65  }
66 
67  /* read VAX header and get record info from it: */
68 
69  if (fread(&header1, sizeof ( header1), 1, fptr))
70  get_record_info(header1, &header2_size, &data_rec_size,
71  &offset_header, &offset_data, &num_of_data_recs);
72  else {
73  printf("Could not read VAX header.\nProgram terminated.");
74  return -1;
75  }
76 
77  /*
78  * seek, read and print first document record:
79  * Nothing is used from here, but keep for now
80  */
81 
82  fseek(fptr, offset_header * 1024, 0); /* ie, look for document */
83  /* rec at a displacement of */
84  /* offset_header - 1 * 512 bytes*/
85  /* from begining of file */
86  if (fread(&header2, header2_size * 512, 1, fptr)) {
87 #ifdef __DEC_MACHINE
88  convert_header_rec_to_dec(&header2);
89 #endif
90  hdr_2_gattr(header2, gattr);
91  } else {
92  printf("\nNote: could not read first documentation record.\n");
93  return -1;
94  }
95 
96  /* seek, read and print trailing document record: */
97 
98  fseek(fptr, (offset_data * 512) +
99  (num_of_data_recs * data_rec_size * 512), 0);
100  if (fread(&header2, header2_size * 512, 1, fptr)) {
101 #ifdef __DEC_MACHINE
102  convert_header_rec_to_dec(&header2);
103 #endif
104  hdr_2_gattr(header2, gattr);
105  } else {
106  printf("\nError: Could not read trailing documentation record.\n");
107  return -1;
108  }
109  /*
110  * compute the # of control points
111  */
112  n_ctl = 1 + (NCZCS_PIX - 1) / CTL_PT_INC;
113  if ((n_ctl - 1) * CTL_PT_INC == NCZCS_PIX + 1)
114  n_ctl_pt = n_ctl;
115  else
116  n_ctl_pt = n_ctl + 1;
117 
118  gattr->n_ctl_pt = n_ctl_pt;
119  gattr->ctl_pt_incr = CTL_PT_INC;
120  /*
121  * The gattr->scan_lines can be wrong and != num_of_data_recs
122  * So, for now, if not =, note and use num_of_data_recs
123  * (if num_of_data_recs wrong, it couldn't get trailing header and would die)
124  */
125  if (num_of_data_recs != gattr->scan_lines) {
126  printf("\nWarning, # scan lines in trailing header incorrect\nUsing VAX header value\n");
127  gattr->scan_lines = num_of_data_recs;
128  }
129 
130  /*
131  * set up space for all the data arrays and set the control point
132  * column values
133  */
134  cz_dat_alloc(num_of_data_recs, n_ctl_pt, 0, l1_data);
135 
136  for (j = 0; j < n_ctl_pt; j++) {
137  l1_data->ctl_pt_cols[ j ] = j * CTL_PT_INC + 1;
138  if (j == (n_ctl_pt - 1)) l1_data->ctl_pt_cols[ j ] = NCZCS_PIX;
139  }
140  /*
141  * initialize some nav values needed in ftn calls in czcs_ctl_pt
142  */
143  cdata_();
144 
145  for (i = 0; i < num_of_data_recs; i++) {
146  l1_data->ctl_pt_rows[i] = i + 1;
147  fseek(fptr, (offset_data + (data_rec_size * i)) * 512, 0);
148  if (fread(&data, data_rec_size * 512, 1, fptr)) {
149 #ifdef __DEC_MACHINE
150  convert_data_rec_to_dec(&data);
151 #endif
152  /*
153  * deposit the line of counts
154  * this will make pixel, line, band organization with pixel the fastest
155  */
156  for (j = 0; j < 6; j++) {
157  memcpy(l1_data->counts[j] + NCZCS_PIX * i,
158  *(data.radiance_cnts) + j * NCZCS_PIX, NCZCS_PIX);
159  }
160  /*
161  * set up the times needed from the data records
162  * (needs to be used in czcs_ctl_pt)
163  */
164  l1_data->msec[i] = data.msec_of_day;
165  /*
166  * take the anchor points from the file, correct them and
167  * make an evenly spaced control point grid
168  */
169  czcs_ctl_pt(data, gattr, i, l1_data);
170  /*
171  * set up the quality data
172  */
173  l1_data->cal_sum[ i * 5 ] = data.info.qstnble_ephemeris;
174  l1_data->cal_sum[ i * 5 + 1 ] = data.info.qstnble_attitude;
175  l1_data->cal_sum[ i * 5 + 2 ] = data.info.channel_not_present;
176  l1_data->cal_sum[ i * 5 + 3 ] = data.info.cal_outside_range;
177  l1_data->cal_sum[ i * 5 + 4 ] = data.info.volt_outside_range;
178 
179  for (j = 0; j < 6; j++)
180  l1_data->cal_scan[ i * 6 + j ] = data.cal_qual[j];
181 
182  /*
183  * if enabled, calibrate the counts
184  */
185 #ifdef GEOM_CAL
186  cal_czcs(i, gattr, l1_data);
187 #endif
188  } else {
189  printf("Error: Could not read data record # %d.\n", i);
190  return -1;
191  }
192  }
193  /*
194  * the last data record provides the end time
195  */
196  time_str(data.year, data.doy, data.msec_of_day, gattr->end_time);
197  gattr->end_year = data.year;
198  gattr->end_day = data.doy;
199  gattr->end_msec = data.msec_of_day;
200  /*
201  * Set up some lat, lon info using improved control points
202  * and set line-by-line info from ctl pts and global attrs
203  * Also, get orbit info in using SMMR-derived Nimbus 7 orbit
204  */
205  cz_ll_upd(l1_data, gattr);
206  cz_sd_set(l1_data, gattr);
207  if (fill_orb_dat(l1_data, gattr) != 0) return -1;
208  return 0;
209 }
210 
211 float fixed_pt_2_floating_pt(int num, int position)
212 
213 /* returns the floating point value of a fixed pt #. The MSB indicates
214 the sign, and the parameter "position" is the position of the decimal pt
215 (0 means to the right of the LSB, 1 means between the LSB and second to
216 the least most significant bit).
217  */
218  {
219 
220  int divisor = 1;
221 
222  divisor = divisor << position;
223 
224  return ((float) /*(1 - (2 * ((num & 0x80000000) != 0))) **/ num / divisor);
225 }
226 
227 void get_record_info(HEADER1_TYPE header1, short *hdrsz, short *datarecsz,
228  short *offsethdr, short *offsetdata, short *numrecs)
229 
230 /*
231 Get the following quantities from the VAX header recorder:
232  document record size (hdrsz)
233  data record size
234  offset to the first document record (offsethdr)
235  offset to the first data record
236  number of data records (numrecs).
237 If __DEC_MACHINE is not defined, reverse the byte order of the 2-byte
238 words.
239  */
240  {
241 #ifdef __DEC_MACHINE
242  *hdrsz = (header1.doc_rec_len / 512) +
243  ((header1.doc_rec_len % 512) != 0);
244 
245  *datarecsz = (header1.data_rec_len / 512) +
246  ((header1.data_rec_len % 512) != 0);
247 
248  *offsethdr = header1.header_rec_offset;
249  *offsetdata = header1.offset_1st_data_rec;
250  *numrecs = header1.num_of_data_recs;
251 #else /* reverse byte order */
252  short temp;
253  temp = header1.doc_rec_len;
254  temp = reverse_short_int(temp);
255  *hdrsz = (temp / 512) + ((temp % 512) != 0);
256 
257  temp = header1.data_rec_len;
258  temp = reverse_short_int(temp);
259  *datarecsz = (temp / 512) + ((temp % 512) != 0);
260 
261  *offsethdr = reverse_short_int(header1.header_rec_offset);
262  *offsetdata = reverse_short_int(header1.offset_1st_data_rec);
263  *numrecs = reverse_short_int(header1.num_of_data_recs);
264 #endif
265 }
266 
267 short reverse_short_int(short num)
268 /* returns the parameter passed with the byte positions reversed. */ {
269 
270  union {
271  unsigned short i;
272  char c[2];
273  } short_struct;
274  char temp;
275 
276  short_struct.i = num;
277  temp = short_struct.c[0];
278  short_struct.c[0] = short_struct.c[1];
279  short_struct.c[1] = temp;
280 
281  return (short_struct.i);
282 }
283 
284 int32_t reverse_long_int(int32_t num)
285 /* returns the parameter passed with the byte positions reversed. */ {
286 
287  union {
288  int i;
289  char c[4];
290  } long_struct;
291  char temp;
292 
293  long_struct.i = num;
294  temp = long_struct.c[0];
295  long_struct.c[0] = long_struct.c[3];
296  long_struct.c[3] = temp;
297  temp = long_struct.c[1];
298  long_struct.c[1] = long_struct.c[2];
299  long_struct.c[2] = temp;
300 
301  return (long_struct.i);
302 }
303 
304 
305 #ifdef __DEC_MACHINE
306 
307 void convert_data_rec_to_dec(DATA_REC_TYPE *rec)
308 /* converts integers in data record to dec format--ie, reverses
309 byte order.
310  */
311  {
312  int i;
313 
314  union {
315  BIT_FLD_2_TYPE bit_struct;
316  unsigned short words[2];
317  int i;
318  } u;
319 
320  u.bit_struct = rec->info;
321  u.words[0] = reverse_short_int(u.words[0]);
322  rec->info.p_rec_num = u.words[0] >> 4;
323  rec->info.sp1 = u.words[0] & 0x00f;
324 
325  rec->seq_no = reverse_short_int(rec->seq_no);
326  rec->year = reverse_short_int(rec->year);
327  rec->doy = reverse_short_int(rec->doy);
328  rec->subcommuted_data_val_cnt =
329  reverse_short_int(rec->subcommuted_data_val_cnt);
330  for (i = 0; i < 6; i++)
331  rec->cal_lamp_rad[i] = reverse_short_int(rec->cal_lamp_rad[i]);
332  rec->blk_bdy_tmp_cnt = reverse_short_int(rec->blk_bdy_tmp_cnt);
333  rec->wbvt_bit_slips_summary =
334  reverse_short_int(rec->wbvt_bit_slips_summary);
335  rec->hdt_sync_losses = reverse_short_int(rec->hdt_sync_losses);
336  rec->hdt_parity_errs = reverse_short_int(rec->hdt_parity_errs);
337  rec->wbvt_bit_slips = reverse_short_int(rec->wbvt_bit_slips);
338  rec->pxl_no_nadir = reverse_short_int(rec->pxl_no_nadir);
339 
340  rec->msec_of_day = reverse_long_int(rec->msec_of_day);
341  for (i = 0; i < 77; i++)
342  rec->lat_anchr_pts[i] = reverse_long_int(rec->lat_anchr_pts[i]);
343  for (i = 0; i < 77; i++)
344  rec->long_anchr_pts[i] = reverse_long_int(rec->long_anchr_pts[i]);
345  for (i = 0; i < 28; i++)
346  rec->spare3[i] = reverse_long_int(rec->spare3[i]);
347 
348 }
349 #endif
350 
351 
352 #ifdef __DEC_MACHINE
353 
354 void convert_header_rec_to_dec(HEADER2_TYPE *rec)
355 /*
356  * Revision history:
357  * W. Robinson, SAIC, 7 Jun 2004 fix setting of the no_of_missing_scans
358  * value so {1] - [5] is correct
359  */
360 /* converts integers in header record to dec format--ie, reverses
361 byte order.
362  */
363  {
364  int i;
365 
366  union {
367  BIT_FLD_1_TYPE bit_struct;
368  unsigned short words[2];
369  int i;
370  } u;
371 
372  u.bit_struct = rec->file_info;
373  u.words[0] = reverse_short_int(u.words[0]);
374  rec->file_info.p_rec_num = u.words[0] >> 4;
375  rec->file_info.sp1 = u.words[0] & 0x00f;
376 
377  rec->tape_seq_no = reverse_long_int(rec->tape_seq_no);
378  rec->film_frame_no = reverse_long_int(rec->film_frame_no);
379  rec->starting_yr = reverse_short_int(rec->starting_yr);
380  rec->starting_day = reverse_short_int(rec->starting_day);
381 
382  rec->start_msec = reverse_long_int(rec->start_msec);
383  rec->inc_in_msec = reverse_long_int(rec->inc_in_msec);
384 
385  rec->orbit = reverse_short_int(rec->orbit);
386  rec->no_of_scans = reverse_short_int(rec->no_of_scans);
387  rec->lat_cntr = reverse_short_int(rec->lat_cntr);
388  rec->long_cntr = reverse_short_int(rec->long_cntr);
389  rec->lat_crnr_fitl = reverse_short_int(rec->lat_crnr_fitl);
390  rec->long_crnr_fitl = reverse_short_int(rec->long_crnr_fitl);
391  rec->lat_crnr_fitr = reverse_short_int(rec->lat_crnr_fitr);
392  rec->long_crnr_fitr = reverse_short_int(rec->long_crnr_fitr);
393  rec->lat_crnr_litl = reverse_short_int(rec->lat_crnr_litl);
394  rec->long_crnr_litl = reverse_short_int(rec->long_crnr_litl);
395  rec->lat_crnr_litr = reverse_short_int(rec->lat_crnr_litr);
396  rec->long_crnr_litr = reverse_short_int(rec->long_crnr_litr);
397  rec->no_of_missing_scans_all =
398  reverse_short_int(rec->no_of_missing_scans_all);
399 
400  for (i = 0; i < 6; i++)
401  rec->no_of_missing_scans[i] =
402  reverse_short_int(rec->no_of_missing_scans[i]);
403  rec->decom_run_no = reverse_long_int(rec->decom_run_no);
404  rec->decom_reel_no = reverse_long_int(rec->decom_reel_no);
405 
406  rec->no_of_hdt_sync_losses = reverse_short_int(rec->no_of_hdt_sync_losses);
407  rec->no_of_hdt_parity_errs = reverse_short_int(rec->no_of_hdt_parity_errs);
408  rec->no_of_wbvt_sync_losses = reverse_short_int(rec->no_of_wbvt_sync_losses);
409  rec->no_of_wbvt_bit_slips = reverse_short_int(rec->no_of_wbvt_bit_slips);
410  for (i = 0; i < 32; i++)
411  rec->ave_subcomputed_data[i] =
412  reverse_short_int(rec->ave_subcomputed_data[i]);
413  rec->baseplate_temp = reverse_short_int(rec->baseplate_temp);
414  rec->tilt = reverse_short_int(rec->tilt);
415 
416  for (i = 0; i < 134; i++)
417  rec->spare4[i] = reverse_long_int(rec->spare4[i]);
418 
419  rec->scene_cntr_yr = reverse_short_int(rec->scene_cntr_yr);
420  rec->scene_cntr_doy = reverse_short_int(rec->scene_cntr_doy);
421  rec->scene_cntr_msec = reverse_long_int(rec->scene_cntr_msec);
422 
423  rec->solar_el_cntr = reverse_short_int(rec->solar_el_cntr);
424  rec->solar_az_cntr = reverse_short_int(rec->solar_az_cntr);
425  rec->cntr_roll = reverse_short_int(rec->cntr_roll);
426  rec->cntr_pitch = reverse_short_int(rec->cntr_pitch);
427  rec->cntr_yaw = reverse_short_int(rec->cntr_yaw);
428  rec->top_lft_tick_label = reverse_short_int(rec->top_lft_tick_label);
429  rec->top_rgt_tick_label = reverse_short_int(rec->top_rgt_tick_label);
430  rec->bot_lft_tick_label = reverse_short_int(rec->bot_lft_tick_label);
431  rec->bot_rgt_tick_label = reverse_short_int(rec->bot_rgt_tick_label);
432  rec->lft_top_tick_label = reverse_short_int(rec->lft_top_tick_label);
433  rec->lft_bot_tick_label = reverse_short_int(rec->lft_bot_tick_label);
434  rec->rgt_top_tick_label = reverse_short_int(rec->rgt_top_tick_label);
435  rec->rgt_bot_tick_label = reverse_short_int(rec->rgt_bot_tick_label);
436 
437  for (i = 0; i < 27; i++)
438  rec->top_tick_loc[i] = reverse_short_int(rec->top_tick_loc[i]);
439  for (i = 0; i < 27; i++)
440  rec->bot_tick_loc[i] = reverse_short_int(rec->bot_tick_loc[i]);
441  for (i = 0; i < 27; i++)
442  rec->lft_tick_loc[i] = reverse_short_int(rec->lft_tick_loc[i]);
443  for (i = 0; i < 27; i++)
444  rec->rgt_tick_loc[i] = reverse_short_int(rec->rgt_tick_loc[i]);
445 
446  for (i = 0; i < 6; i++) {
447  rec->chan_line[i].slope = reverse_long_int(rec->chan_line[i].slope);
448  rec->chan_line[i].intercept =
449  reverse_long_int(rec->chan_line[i].intercept);
450  }
451 
452  for (i = 0; i < 256; i++)
453  rec->conversion_tab_chan6[i] =
454  reverse_short_int(rec->conversion_tab_chan6[i]);
455 
456  for (i = 0; i < 6; i++) {
457  rec->enhancement_eqs[i].slope =
458  reverse_short_int(rec->enhancement_eqs[i].slope);
459  rec->enhancement_eqs[i].intercept =
460  reverse_short_int(rec->enhancement_eqs[i].intercept);
461  }
462  for (i = 0; i < 2; i++)
463  rec->spare5[i] = reverse_long_int(rec->spare5[i]);
464  for (i = 0; i < 945; i++)
465  rec->czcs_1lt[i] = reverse_long_int(rec->czcs_1lt[i]);
466 
467 }
468 #endif
#define CTL_PT_INC
Definition: read_crtt.c:8
void get_record_info(HEADER1_TYPE header1, short *hdrsz, short *datarecsz, short *offsethdr, short *offsetdata, short *numrecs)
Definition: read_crtt.c:227
int j
Definition: decode_rs.h:73
void cz_ll_upd(l1_data_struc *l1_data, gattr_struc *gattr)
Definition: cz_ll_upd.c:3
void hdr_2_gattr(HEADER2_TYPE header2, gattr_struc *gattr)
Definition: hdr_2_gattr.c:4
int cz_dat_alloc(int nscans, int n_ctl_pt, int r_mode, l1_data_struc *l1_data)
Definition: cz_dat_alloc.c:3
int fill_orb_dat(l1_data_struc *l1_data, gattr_struc *gattr)
Definition: fill_orb_dat.c:27
int time_str(short, short, int, char *)
Definition: time_str.c:3
float fixed_pt_2_floating_pt(int num, int position)
Definition: read_crtt.c:211
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 words
Definition: HISTORY.txt:232
void czcs_ctl_pt(DATA_REC_TYPE data, gattr_struc *gattr, int line, l1_data_struc *l1_data)
Definition: czcs_ctl_pt.c:7
void cdata_()
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define basename(s)
Definition: l0chunk_modis.c:29
int32_t reverse_long_int(int32_t num)
Definition: read_crtt.c:284
data_t u
Definition: decode_rs.h:74
short reverse_short_int(short num)
Definition: read_crtt.c:267
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 cz_sd_set(l1_data_struc *l1_data, gattr_struc *gattr)
Definition: cz_sd_set.c:3
int i
Definition: decode_rs.h:71
#define NCZCS_PIX
Definition: l1czcs.h:23
int read_crtt(char *crtt_file, gattr_struc *gattr, l1_data_struc *l1_data)
Definition: read_crtt.c:11