OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
swl1_hdf.c
Go to the documentation of this file.
1 /* Norman Kuring 22-Oct-1997 */
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <libgen.h>
7 #include <time.h>
8 #include <math.h>
9 
10 #include <GetStationInfo.h>
11 
12 #include "swl0_proto.h"
13 #include <dfutils.h>
14 #include <timeutils.h>
15 
16 /*
17 These global variables facilitate communication
18 between some of the functions defined in this file.
19  */
20 static idDS ds_id;
21 static int32 numScans, numPixels;
22 static int16 tdi_global[8];
23 static char *hdfFile;
24 static int firstCallThisFile;
25 static char dataTypeString[5];
26 static int16 startYear, startDay, endDay;
27 static int32 startMillisec;
28 static int calibrationAppended = 0;
29 
30 #define SENSOR "Sea-viewing Wide Field-of-view Sensor (SeaWiFS)"
31 #define MISSIONCHAR "Nominal orbit: inclination = 98.2 (Sun-synchronous); node = 12 noon local (descending); eccentricity = <0.002; altitude = 705 km; ground speed = 6.75 km/sec"
32 #define SENSORCHAR "Number of bands = 8; number of active bands = 8; wavelengths per band (nm) = 412, 443, 490, 510, 555, 670, 765, 865; bits per pixel = 10; instantaneous field-of-view = 1.5835 mrad; pixels per scan = 1285; scan rate = 6/sec; sample rate = 7710/sec"
33 
34 /****************************************************************************
35 Create a new HDF file and store some global attributes in it.
36 This function must be called before WriteScanData().
37 CloseL1aFile() should be called to finish up the file.
38  *****************************************************************************/
40  char *path,
41  swl0scene *scene,
42  char *proccon,
43  char *proclog,
44  swl0ctl *l0ctl
45  ) {
46 
47  unsigned char dataType;
48  StationInfo stationInfo;
49  int16 year;
50  int32 millisec;
51  int32 startpix, subsamp;
52 
53  /* for seadas version and meta */
54 
55  if (scene->type == HRPT)
56  dataType = 16;
57  else
58  dataType = scene->mnftype;
59 
60  /* Get some ground station specific information. */
61  PTB(GetStationInfo(l0ctl->stationInfoFile, &stationInfo));
62 
63  /* A few numbers are determined by the data type. */
64  if (dataType == GACTYPE) {
65  numPixels = NPIXGAC;
66  startpix = SPIXGAC;
67  subsamp = IPIXGAC;
68  } else {
69  numPixels = NPIXLAC;
70  startpix = SPIXLAC;
71  subsamp = IPIXLAC;
72  }
73 
74  numScans = scene->nscan; /* Make it global. */
75 
76  /*
77  Copy the output filename to a static global variable.
78  */
79  MALLOC(hdfFile, char, strlen(path) + 1);
80  strcpy(hdfFile, path);
81 
82  /*
83  Make sure the file does not already exist.
84  if(fopen(hdfFile, "rb") != NULL){
85  fprintf(stderr,
86  "-E- %s line %d: File, %s , already exists.\n",
87  __FILE__,__LINE__,hdfFile);
88  return(FILE_ALREADY_EXISTS);
89  }
90  */
91 
92  /*
93  Create the HDF file.
94  */
95  ds_id = startDS(hdfFile, DS_HDF, DS_WRITE, 0);
96  if (ds_id.fid == FAIL) {
97  fprintf(stderr,
98  "-E- %s line %d: Could not create HDF file, %s .\n",
99  __FILE__, __LINE__, hdfFile);
100  return (HDF_FUNCTION_ERROR);
101  }
102 
103  /*
104  Set global variables that are also used
105  in getting calibration data for the scene.
106  */
107  strncpy(dataTypeString, DTypeString(dataType), 4);
108  DecomposeTime(scene->stime, &startYear, &startDay, &startMillisec);
109  DecomposeTime(scene->etime, &year, &endDay, &millisec);
110  firstCallThisFile = 0;
111 
112  /*
113  Write out some global attributes.
114  */
115  PTB(SetChrGA(ds_id, "Product Name", basename(hdfFile)));
116  PTB(SetChrGA(ds_id, "Title", "SeaWiFS Level-1A Data"));
117  PTB(SetChrGA(ds_id, "Data Center", stationInfo.data_center));
118  PTB(SetChrGA(ds_id, "Station Name", stationInfo.station_name));
119  PTB(SetF32GA(ds_id, "Station Latitude", stationInfo.station_latitude));
120  PTB(SetF32GA(ds_id, "Station Longitude", stationInfo.station_longitude));
121  PTB(SetChrGA(ds_id, "Mission", "SeaStar SeaWiFS"));
122  PTB(SetChrGA(ds_id, "Mission Characteristics", MISSIONCHAR));
123  PTB(SetChrGA(ds_id, "Sensor", SENSOR));
124  PTB(SetChrGA(ds_id, "Sensor Characteristics", SENSORCHAR));
125  PTB(SetChrGA(ds_id, "Data Type", DTypeString(dataType)));
126  PTB(SetChrGA(ds_id, "Replacement Flag", "ORIGINAL"));
127  PTB(SetChrGA(ds_id, "Software ID", L01VERSION));
128  PTB(SetChrGA(ds_id, "Processing Time", ydhmsf(now(), 'L')));
129  PTB(SetChrGA(ds_id, "Input Files", scene->l0file));
130  PTB(SetChrGA(ds_id, "Processing Control", proccon));
131  PTB(SetChrGA(ds_id, "Processing Log", proclog));
132  PTB(SetChrGA(ds_id, "Start Time", ydhmsf(scene->stime, 'G')));
133  PTB(SetChrGA(ds_id, "End Time", ydhmsf(scene->etime, 'G')));
134  PTB(SetChrGA(ds_id, "Scene Center Time", ydhmsf(scene->ctime, 'G')));
135  PTB(SetChrGA(ds_id, "Node Crossing Time", ydhmsf(scene->node_time, 'G')));
136  PTB(SetI16GA(ds_id, "Start Year", startYear));
137  PTB(SetI16GA(ds_id, "Start Day", startDay));
138  PTB(SetI32GA(ds_id, "Start Millisec", startMillisec));
139  PTB(SetI16GA(ds_id, "End Year", year));
140  PTB(SetI16GA(ds_id, "End Day", endDay));
141  PTB(SetI32GA(ds_id, "End Millisec", millisec));
142  PTB(SetI32GA(ds_id, "Orbit Number", scene->orbnum));
143  PTB(SetChrGA(ds_id, "Start Node", scene->start_node));
144  PTB(SetChrGA(ds_id, "End Node", scene->end_node));
145  PTB(SetChrGA(ds_id, "NORAD Line 1", ""));
146  PTB(SetChrGA(ds_id, "NORAD Line 2", ""));
147  PTB(SetI32GA(ds_id, "Pixels per Scan Line", numPixels));
148  PTB(SetI32GA(ds_id, "Number of Scan Lines", numScans));
149  PTB(SetI32GA(ds_id, "LAC Pixel Start Number", startpix));
150  PTB(SetI32GA(ds_id, "LAC Pixel Subsampling", subsamp));
151  PTB(SetI32GA(ds_id, "Scene Center Scan Line", scene->center_scan_line));
152  PTB(SetI32GA(ds_id, "Filled Scan Lines", 0));
153  PTB(SetI32GA(ds_id, "FF Missing Frames", 0));
154  PTB(SetI32GA(ds_id, "SDPS Missing Frames", 0));
155  PTB(SetChrGA(ds_id, "Latitude Units", "degrees North"));
156  PTB(SetChrGA(ds_id, "Longitude Units", "degrees East"));
157  PTB(SetF32GA(ds_id, "Scene Center Latitude", scene->center_lat));
158  PTB(SetF32GA(ds_id, "Scene Center Longitude", scene->center_lon));
159  PTB(SetF32GA(ds_id, "Scene Center Solar Zenith", scene->center_solz));
160  PTB(SetF32GA(ds_id, "Upper Left Latitude", scene->upper_left_lat));
161  PTB(SetF32GA(ds_id, "Upper Left Longitude", scene->upper_left_lon));
162  PTB(SetF32GA(ds_id, "Upper Right Latitude", scene->upper_right_lat));
163  PTB(SetF32GA(ds_id, "Upper Right Longitude", scene->upper_right_lon));
164  PTB(SetF32GA(ds_id, "Lower Left Latitude", scene->lower_left_lat));
165  PTB(SetF32GA(ds_id, "Lower Left Longitude", scene->lower_left_lon));
166  PTB(SetF32GA(ds_id, "Lower Right Latitude", scene->lower_right_lat));
167  PTB(SetF32GA(ds_id, "Lower Right Longitude", scene->lower_right_lon));
168  PTB(SetF32GA(ds_id, "Northernmost Latitude", scene->northern_lat));
169  PTB(SetF32GA(ds_id, "Southernmost Latitude", scene->southern_lat));
170  PTB(SetF32GA(ds_id, "Westernmost Longitude", scene->western_lon));
171  PTB(SetF32GA(ds_id, "Easternmost Longitude", scene->eastern_lon));
172  PTB(SetF32GA(ds_id, "Start Center Latitude", scene->start_center_lat));
173  PTB(SetF32GA(ds_id, "Start Center Longitude", scene->start_center_lon));
174  PTB(SetF32GA(ds_id, "End Center Latitude", scene->end_center_lat));
175  PTB(SetF32GA(ds_id, "End Center Longitude", scene->end_center_lon));
176  PTB(SetF32GA(ds_id, "Orbit Node Longitude", scene->node_lon));
177 
178  /* Add the tilt data. */
179  PTB(AddTiltData(scene->ntilts,
180  scene->tilt_flags,
181  scene->tilt_ranges,
182  scene->tilt_lats,
183  scene->tilt_lons));
184 
185  /* Create the scan-line SDSes */
186  PTB(CreateScanData(numScans, numPixels));
187 
188  return (LIFE_IS_GOOD);
189 }
190 
191 /****************************************************************************
192 Create the level-1A SDSes that are to contain the scan-line data in the
193 currently open HDF file.
194  *****************************************************************************/
195 int CreateScanData(int32 ns, int32 np) {
196 
197  PTB(CreateSDS(ds_id.fid,
198  "msec", /* short name */
199  "Scan-line time, milliseconds of day", /* long name */
200  NULL, /* standard name */
201  NULL, /* units */
202  0, 86399999, /* valid range */
203  1.0, 0.0, /* slope,offset */
204  DFNT_INT32, /* HDF number type */
205  1, /* rank */
206  ns, 1, 1, /* dimension sizes */
207  "Number of Scan Lines", NULL, NULL /* dimension names */
208  ));
209 
210  PTB(CreateSDS(ds_id.fid,
211  "eng_qual", /* short name */
212  "Engineering data-out-of-range flags", /* long name */
213  NULL, /* standard name */
214  NULL, /* units */
215  0, 0, /* valid range */
216  1.0, 0.0, /* slope,offset */
217  DFNT_UINT8, /* HDF number type */
218  2, /* rank */
219  ns, 4, 1, /* dimension sizes */
220  "Number of Scan Lines", "4", NULL /* dimension names */
221  ));
222 
223  PTB(CreateSDS(ds_id.fid,
224  "s_flags", /* short name */
225  "Scan-line quality flags", /* long name */
226  NULL, /* standard name */
227  NULL, /* units */
228  0, 0, /* valid range */
229  1.0, 0.0, /* slope,offset */
230  DFNT_UINT8, /* HDF number type */
231  2, /* rank */
232  ns, 4, 1, /* dimension sizes */
233  "Number of Scan Lines", "4", NULL /* dimension names */
234  ));
235 
236  PTB(CreateSDS(ds_id.fid,
237  "s_satp", /* short name */
238  "Number of saturated pixels per band", /* long name */
239  NULL, /* standard name */
240  NULL, /* units */
241  0, 0, /* valid range */
242  1.0, 0.0, /* slope,offset */
243  DFNT_INT16, /* HDF number type */
244  2, /* rank */
245  ns, 8, 1, /* dimension sizes */
246  "Number of Scan Lines", "Number of Bands", NULL /* dimension names */
247  ));
248 
249  PTB(CreateSDS(ds_id.fid,
250  "s_zerop", /* short name */
251  "Number of zero pixels per band", /* long name */
252  NULL, /* standard name */
253  NULL, /* units */
254  0, 0, /* valid range */
255  1.0, 0.0, /* slope,offset */
256  DFNT_INT16, /* HDF number type */
257  2, /* rank */
258  ns, 8, 1, /* dimension sizes */
259  "Number of Scan Lines", "Number of Bands", NULL /* dimension names */
260  ));
261 
262  PTB(CreateSDS(ds_id.fid,
263  "slat", /* short name */
264  "Scan start-pixel latitude", /* long name */
265  NULL, /* standard name */
266  NULL, /* units */
267  -90.0, 90.0, /* valid range */
268  1.0, 0.0, /* slope,offset */
269  DFNT_FLOAT32, /* HDF number type */
270  1, /* rank */
271  ns, 1, 1, /* dimension sizes */
272  "Number of Scan Lines", NULL, NULL /* dimension names */
273  ));
274 
275  PTB(CreateSDS(ds_id.fid,
276  "slon", /* short name */
277  "Scan start-pixel longitude", /* long name */
278  NULL, /* standard name */
279  NULL, /* units */
280  -180.0, 180.0, /* valid range */
281  1.0, 0.0, /* slope,offset */
282  DFNT_FLOAT32, /* HDF number type */
283  1, /* rank */
284  ns, 1, 1, /* dimension sizes */
285  "Number of Scan Lines", NULL, NULL /* dimension names */
286  ));
287 
288  PTB(CreateSDS(ds_id.fid,
289  "clat", /* short name */
290  "Scan center-pixel latitude", /* long name */
291  NULL, /* standard name */
292  NULL, /* units */
293  -90.0, 90.0, /* valid range */
294  1.0, 0.0, /* slope,offset */
295  DFNT_FLOAT32, /* HDF number type */
296  1, /* rank */
297  ns, 1, 1, /* dimension sizes */
298  "Number of Scan Lines", NULL, NULL /* dimension names */
299  ));
300 
301  PTB(CreateSDS(ds_id.fid,
302  "clon", /* short name */
303  "Scan center-pixel longitude", /* long name */
304  NULL, /* standard name */
305  NULL, /* units */
306  -180.0, 180.0, /* valid range */
307  1.0, 0.0, /* slope,offset */
308  DFNT_FLOAT32, /* HDF number type */
309  1, /* rank */
310  ns, 1, 1, /* dimension sizes */
311  "Number of Scan Lines", NULL, NULL /* dimension names */
312  ));
313 
314  PTB(CreateSDS(ds_id.fid,
315  "elat", /* short name */
316  "Scan end-pixel latitude", /* long name */
317  NULL, /* standard name */
318  NULL, /* units */
319  -90.0, 90.0, /* valid range */
320  1.0, 0.0, /* slope,offset */
321  DFNT_FLOAT32, /* HDF number type */
322  1, /* rank */
323  ns, 1, 1, /* dimension sizes */
324  "Number of Scan Lines", NULL, NULL /* dimension names */
325  ));
326 
327  PTB(CreateSDS(ds_id.fid,
328  "elon", /* short name */
329  "Scan end-pixel longitude", /* long name */
330  NULL, /* standard name */
331  NULL, /* units */
332  -180.0, 180.0, /* valid range */
333  1.0, 0.0, /* slope,offset */
334  DFNT_FLOAT32, /* HDF number type */
335  1, /* rank */
336  ns, 1, 1, /* dimension sizes */
337  "Number of Scan Lines", NULL, NULL /* dimension names */
338  ));
339 
340  PTB(CreateSDS(ds_id.fid,
341  "csol_z", /* short name */
342  "Scan center-pixel solar zenith angle", /* long name */
343  NULL, /* standard name */
344  NULL, /* units */
345  0.0, 180.0, /* valid range */
346  1.0, 0.0, /* slope,offset */
347  DFNT_FLOAT32, /* HDF number type */
348  1, /* rank */
349  ns, 1, 1, /* dimension sizes */
350  "Number of Scan Lines", NULL, NULL /* dimension names */
351  ));
352 
353  PTB(CreateSDS(ds_id.fid,
354  "tilt", /* short name */
355  "Tilt angle for scan line", /* long name */
356  NULL, /* standard name */
357  NULL, /* units */
358  -20.1, 20.1, /* valid range */
359  1.0, 0.0, /* slope,offset */
360  DFNT_FLOAT32, /* HDF number type */
361  1, /* rank */
362  ns, 1, 1, /* dimension sizes */
363  "Number of Scan Lines", NULL, NULL /* dimension names */
364  ));
365 
366  PTB(CreateSDS(ds_id.fid,
367  "sc_id", /* short name */
368  "Spacecraft ID", /* long name */
369  NULL, /* standard name */
370  NULL, /* units */
371  0, 0, /* valid range */
372  1.0, 0.0, /* slope,offset */
373  DFNT_INT16, /* HDF number type */
374  2, /* rank */
375  ns, 2, 1, /* dimension sizes */
376  "Number of Scan Lines", "2", NULL /* dimension names */
377  ));
378 
379  PTB(CreateSDS(ds_id.fid,
380  "sc_ttag", /* short name */
381  "Spacecraft time tag", /* long name */
382  NULL, /* standard name */
383  NULL, /* units */
384  0, 0, /* valid range */
385  1.0, 0.0, /* slope,offset */
386  DFNT_INT16, /* HDF number type */
387  2, /* rank */
388  ns, 4, 1, /* dimension sizes */
389  "Number of Scan Lines", "4", NULL /* dimension names */
390  ));
391 
392  PTB(CreateSDS(ds_id.fid,
393  "sc_soh", /* short name */
394  "Spacecraft state-of-health data", /* long name */
395  NULL, /* standard name */
396  NULL, /* units */
397  0, 0, /* valid range */
398  1.0, 0.0, /* slope,offset */
399  DFNT_UINT8, /* HDF number type */
400  2, /* rank */
401  ns, 775, 1, /* dimension sizes */
402  "Number of Scan Lines", "775", NULL /* dimension names */
403  ));
404 
405  PTB(CreateSDS(ds_id.fid,
406  "inst_tlm", /* short name */
407  "SeaWiFS instrument telemetry", /* long name */
408  NULL, /* standard name */
409  NULL, /* units */
410  0, 0, /* valid range */
411  1.0, 0.0, /* slope,offset */
412  DFNT_INT16, /* HDF number type */
413  2, /* rank */
414  ns, 44, 1, /* dimension sizes */
415  "Number of Scan Lines", "44", NULL /* dimension names */
416  ));
417 
418  PTB(CreateSDS(ds_id.fid,
419  "l1a_data", /* short name */
420  "Level-1A data", /* long name */
421  NULL, /* standard name */
422  "radiance counts", /* units */
423  0, 1023, /* valid range */
424  1.0, 0.0, /* slope,offset */
425  DFNT_INT16, /* HDF number type */
426  3, /* rank */
427  ns, np, 8, /* dimension sizes */
428  "Number of Scan Lines", "Pixels per Scan Line", "Number of Bands" /* dimnames */
429  ));
430 
431  PTB(CreateSDS(ds_id.fid,
432  "start_syn", /* short name */
433  "Start-synch pixel", /* long name */
434  NULL, /* standard name */
435  NULL, /* units */
436  0, 0, /* valid range */
437  1.0, 0.0, /* slope,offset */
438  DFNT_INT16, /* HDF number type */
439  2, /* rank */
440  ns, 8, 1, /* dimension sizes */
441  "Number of Scan Lines", "Number of Bands", NULL /* dimension names */
442  ));
443 
444  PTB(CreateSDS(ds_id.fid,
445  "stop_syn", /* short name */
446  "Stop-synch pixel", /* long name */
447  NULL, /* standard name */
448  NULL, /* units */
449  0, 0, /* valid range */
450  1.0, 0.0, /* slope,offset */
451  DFNT_INT16, /* HDF number type */
452  2, /* rank */
453  ns, 8, 1, /* dimension sizes */
454  "Number of Scan Lines", "Number of Bands", NULL /* dimension names */
455  ));
456 
457  PTB(CreateSDS(ds_id.fid,
458  "dark_rest", /* short name */
459  "Dark-restore pixel", /* long name */
460  NULL, /* standard name */
461  NULL, /* units */
462  0, 0, /* valid range */
463  1.0, 0.0, /* slope,offset */
464  DFNT_INT16, /* HDF number type */
465  2, /* rank */
466  ns, 8, 1, /* dimension sizes */
467  "Number of Scan Lines", "Number of Bands", NULL /* dimension names */
468  ));
469 
470  PTB(CreateSDS(ds_id.fid,
471  "gain", /* short name */
472  "Band gain settings", /* long name */
473  NULL, /* standard name */
474  NULL, /* units */
475  0, 3, /* valid range */
476  1.0, 0.0, /* slope,offset */
477  DFNT_INT16, /* HDF number type */
478  2, /* rank */
479  ns, 8, 1, /* dimension sizes */
480  "Number of Scan Lines", "Number of Bands", NULL /* dimension names */
481  ));
482 
483  PTB(CreateSDS(ds_id.fid,
484  "tdi", /* short name */
485  "Band time-delay and integration settings", /* long name */
486  NULL, /* standard name */
487  NULL, /* units */
488  0, 255, /* valid range */
489  1.0, 0.0, /* slope,offset */
490  DFNT_INT16, /* HDF number type */
491  2, /* rank */
492  ns, 8, 1, /* dimension sizes */
493  "Number of Scan Lines", "Number of Bands", NULL /* dimension names */
494  ));
495 
496  PTB(CreateSDS(ds_id.fid,
497  "inst_ana", /* short name */
498  "Instrument analog telemetry", /* long name */
499  NULL, /* standard name */
500  NULL, /* units */
501  0, 0, /* valid range */
502  1.0, 0.0, /* slope,offset */
503  DFNT_FLOAT32, /* HDF number type */
504  2, /* rank */
505  ns, 40, 1, /* dimension sizes */
506  "Number of Scan Lines", "40", NULL /* dimension names */
507  ));
508 
509  PTB(CreateSDS(ds_id.fid,
510  "inst_dis", /* short name */
511  "Instrument discrete telemetry", /* long name */
512  NULL, /* standard name */
513  NULL, /* units */
514  0, 0, /* valid range */
515  1.0, 0.0, /* slope,offset */
516  DFNT_UINT8, /* HDF number type */
517  2, /* rank */
518  ns, 32, 1, /* dimension sizes */
519  "Number of Scan Lines", "32", NULL /* dimension names */
520  ));
521 
522  PTB(CreateSDS(ds_id.fid,
523  "sc_ana", /* short name */
524  "Spacecraft analog telemetry", /* long name */
525  NULL, /* standard name */
526  NULL, /* units */
527  0, 0, /* valid range */
528  1.0, 0.0, /* slope,offset */
529  DFNT_FLOAT32, /* HDF number type */
530  2, /* rank */
531  ns, 40, 1, /* dimension sizes */
532  "Number of Scan Lines", "40", NULL /* dimension names */
533  ));
534 
535  PTB(CreateSDS(ds_id.fid,
536  "sc_dis", /* short name */
537  "Spacecraft discrete telemetry", /* long name */
538  NULL, /* standard name */
539  NULL, /* units */
540  0, 0, /* valid range */
541  1.0, 0.0, /* slope,offset */
542  DFNT_UINT8, /* HDF number type */
543  2, /* rank */
544  ns, 40, 1, /* dimension sizes */
545  "Number of Scan Lines", "40", NULL /* dimension names */
546  ));
547 
548  PTB(CreateSDS(ds_id.fid,
549  "scan_temp", /* short name */
550  "Detector temperature counts", /* long name */
551  NULL, /* standard name */
552  NULL, /* units */
553  0, 255, /* valid range */
554  1.0, 0.0, /* slope,offset */
555  DFNT_INT16, /* HDF number type */
556  2, /* rank */
557  ns, 8, 1, /* dimension sizes */
558  "Number of Scan Lines", "Number of Bands", NULL /* dimension names */
559  ));
560 
561  PTB(CreateSDS(ds_id.fid,
562  "side", /* short name */
563  "Mirror side for scan line", /* long name */
564  NULL, /* standard name */
565  NULL, /* units */
566  0, 1, /* valid range */
567  1.0, 0.0, /* slope,offset */
568  DFNT_INT16, /* HDF number type */
569  1, /* rank */
570  ns, 1, 1, /* dimension sizes */
571  "Number of Scan Lines", NULL, NULL /* dimension names */
572  ));
573 
574  PTB(CreateSDS(ds_id.fid,
575  "orb_vec", /* short name */
576  "Orbit position vector at scan line time", /* long name */
577  NULL, /* standard name */
578  "kilometers", /* units */
579  -7200.0, 7200.0, /* valid range */
580  1.0, 0.0, /* slope,offset */
581  DFNT_FLOAT32, /* HDF number type */
582  2, /* rank */
583  ns, 3, 1, /* dimension sizes */
584  "Number of Scan Lines", "3", NULL /* dimension names */
585  ));
586 
587  PTB(CreateSDS(ds_id.fid,
588  "l_vert", /* short name */
589  "Local vertical vector in ECEF frame", /* long name */
590  NULL, /* standard name */
591  NULL, /* units */
592  -1.0, 1.0, /* valid range */
593  1.0, 0.0, /* slope,offset */
594  DFNT_FLOAT32, /* HDF number type */
595  2, /* rank */
596  ns, 3, 1, /* dimension sizes */
597  "Number of Scan Lines", "3", NULL /* dimension names */
598  ));
599 
600  PTB(CreateSDS(ds_id.fid,
601  "sun_ref", /* short name */
602  "Reference Sun vector in ECEF frame", /* long name */
603  NULL, /* standard name */
604  NULL, /* units */
605  -1.0, 1.0, /* valid range */
606  1.0, 0.0, /* slope,offset */
607  DFNT_FLOAT32, /* HDF number type */
608  2, /* rank */
609  ns, 3, 1, /* dimension sizes */
610  "Number of Scan Lines", "3", NULL /* dimension names */
611  ));
612 
613  PTB(CreateSDS(ds_id.fid,
614  "att_ang", /* short name */
615  "Computed yaw, roll, pitch", /* long name */
616  NULL, /* standard name */
617  NULL, /* units */
618  -180.0, 180.0, /* valid range */
619  1.0, 0.0, /* slope,offset */
620  DFNT_FLOAT32, /* HDF number type */
621  2, /* rank */
622  ns, 3, 1, /* dimension sizes */
623  "Number of Scan Lines", "3", NULL /* dimension names */
624  ));
625 
626  PTB(CreateSDS(ds_id.fid,
627  "sen_mat", /* short name */
628  "ECEF-to-sensor-frame matrix", /* long name */
629  NULL, /* standard name */
630  NULL, /* units */
631  -1.0, 1.0, /* valid range */
632  1.0, 0.0, /* slope,offset */
633  DFNT_FLOAT32, /* HDF number type */
634  3, /* rank */
635  ns, 3, 3, /* dimension sizes */
636  "Number of Scan Lines", "3", "3" /* dimension names */
637  ));
638 
639  PTB(CreateSDS(ds_id.fid,
640  "scan_ell", /* short name */
641  "Scan-track ellipse coefficients", /* long name */
642  NULL, /* standard name */
643  NULL, /* units */
644  0, 0, /* valid range */
645  1.0, 0.0, /* slope,offset */
646  DFNT_FLOAT32, /* HDF number type */
647  2, /* rank */
648  ns, 6, 1, /* dimension sizes */
649  "Number of Scan Lines", "6", NULL /* dimension names */
650  ));
651 
652  PTB(CreateSDS(ds_id.fid,
653  "nflag", /* short name */
654  "Navigation flags", /* long name */
655  NULL, /* standard name */
656  NULL, /* units */
657  0, 0, /* valid range */
658  1.0, 0.0, /* slope,offset */
659  DFNT_INT32, /* HDF number type */
660  2, /* rank */
661  ns, 8, 1, /* dimension sizes */
662  "Number of Scan Lines", "8", NULL /* dimension names */
663  ));
664 
665  return (LIFE_IS_GOOD);
666 }
667 
668 /****************************************************************************
669 Write one scan line's worth of each of the passed in data to the appropriate
670 SDS in the currently open HDF file.
671  *****************************************************************************/
673  int32 scan,
674  swl1rec *l1rec
675  ) {
676 
677  int i;
678  int32 msec = l1rec->msec;
679  uint8 *eng_qual = l1rec->eng_qual;
680  uint8 *s_flags = l1rec->s_flags;
681  int16 *s_satp = l1rec->s_satp;
682  int16 *s_zerop = l1rec->s_zerop;
683  float32 slat = l1rec->slat;
684  float32 slon = l1rec->slon;
685  float32 clat = l1rec->clat;
686  float32 clon = l1rec->clon;
687  float32 elat = l1rec->elat;
688  float32 elon = l1rec->elon;
689  float32 csol_z = l1rec->csol_z;
690  float32 tilt = l1rec->tilt;
691  int16 *sc_id = l1rec->scid;
692  int16 *sc_ttag = l1rec->ttag;
693  uint8 *sc_soh = l1rec->soh;
694  int16 *inst_tlm = l1rec->inst;
695  int16 *l1a_data = &l1rec->data[0][0];
696  int16 *start_syn = l1rec->startpix;
697  int16 *stop_syn = l1rec->stoppix;
698  int16 *dark_rest = l1rec->darkpix;
699  int16 *gain = l1rec->gain;
700  int16 *tdi = l1rec->tdi;
701  float32 *inst_ana = l1rec->inst_ana;
702  uint8 *inst_dis = l1rec->inst_dis;
703  float32 *sc_ana = l1rec->sc_ana;
704  uint8 *sc_dis = l1rec->sc_dis;
705  int16 *scan_temp = l1rec->scan_temp;
706  int16 side = l1rec->side;
707  float32 *orb_vec = l1rec->orb_vec;
708  float32 *l_vert = l1rec->l_vert;
709  float32 *sun_ref = l1rec->sun_ref;
710  float32 *att_ang = l1rec->att_ang;
711  float32 *sen_mat = &l1rec->sen_mat[0][0];
712  float32 *scan_ell = l1rec->scan_ell;
713  int32 *nflag = (int32 *) l1rec->nflag;
714 
715  if (scan >= numScans) {
716  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
717  fprintf(stderr, "WriteScanData() called with scanline number (%d) ", scan);
718  fprintf(stderr, "that is inappropriate to the number of scanlines (%d) ",
719  numScans);
720  fprintf(stderr, "in the current HDF file, %s . Call ignored.\n", hdfFile);
721  return (PROGRAMMER_BOOBOO);
722  }
723 
724  PTB(sd_writedata(ds_id.fid, "msec", &msec, scan, 0, 0, 1, 1, 1));
725  PTB(sd_writedata(ds_id.fid, "eng_qual", eng_qual, scan, 0, 0, 1, 4, 1));
726  PTB(sd_writedata(ds_id.fid, "s_flags", s_flags, scan, 0, 0, 1, 4, 1));
727  PTB(sd_writedata(ds_id.fid, "s_satp", s_satp, scan, 0, 0, 1, 8, 1));
728  PTB(sd_writedata(ds_id.fid, "s_zerop", s_zerop, scan, 0, 0, 1, 8, 1));
729  PTB(sd_writedata(ds_id.fid, "slat", &slat, scan, 0, 0, 1, 1, 1));
730  PTB(sd_writedata(ds_id.fid, "slon", &slon, scan, 0, 0, 1, 1, 1));
731  PTB(sd_writedata(ds_id.fid, "clat", &clat, scan, 0, 0, 1, 1, 1));
732  PTB(sd_writedata(ds_id.fid, "clon", &clon, scan, 0, 0, 1, 1, 1));
733  PTB(sd_writedata(ds_id.fid, "elat", &elat, scan, 0, 0, 1, 1, 1));
734  PTB(sd_writedata(ds_id.fid, "elon", &elon, scan, 0, 0, 1, 1, 1));
735  PTB(sd_writedata(ds_id.fid, "csol_z", &csol_z, scan, 0, 0, 1, 1, 1));
736  PTB(sd_writedata(ds_id.fid, "tilt", &tilt, scan, 0, 0, 1, 1, 1));
737  PTB(sd_writedata(ds_id.fid, "sc_id", sc_id, scan, 0, 0, 1, 2, 1));
738  PTB(sd_writedata(ds_id.fid, "sc_ttag", sc_ttag, scan, 0, 0, 1, 4, 1));
739  PTB(sd_writedata(ds_id.fid, "sc_soh", sc_soh, scan, 0, 0, 1, 775, 1));
740  PTB(sd_writedata(ds_id.fid, "inst_tlm", inst_tlm, scan, 0, 0, 1, 44, 1));
741  PTB(sd_writedata(ds_id.fid, "l1a_data", l1a_data, scan, 0, 0, 1, numPixels, 8));
742  PTB(sd_writedata(ds_id.fid, "start_syn", start_syn, scan, 0, 0, 1, 8, 1));
743  PTB(sd_writedata(ds_id.fid, "stop_syn", stop_syn, scan, 0, 0, 1, 8, 1));
744  PTB(sd_writedata(ds_id.fid, "dark_rest", dark_rest, scan, 0, 0, 1, 8, 1));
745  PTB(sd_writedata(ds_id.fid, "gain", gain, scan, 0, 0, 1, 8, 1));
746  PTB(sd_writedata(ds_id.fid, "tdi", tdi, scan, 0, 0, 1, 8, 1));
747  PTB(sd_writedata(ds_id.fid, "inst_ana", inst_ana, scan, 0, 0, 1, 40, 1));
748  PTB(sd_writedata(ds_id.fid, "inst_dis", inst_dis, scan, 0, 0, 1, 32, 1));
749  PTB(sd_writedata(ds_id.fid, "sc_ana", sc_ana, scan, 0, 0, 1, 40, 1));
750  PTB(sd_writedata(ds_id.fid, "sc_dis", sc_dis, scan, 0, 0, 1, 40, 1));
751  PTB(sd_writedata(ds_id.fid, "scan_temp", scan_temp, scan, 0, 0, 1, 8, 1));
752  PTB(sd_writedata(ds_id.fid, "side", &side, scan, 0, 0, 1, 1, 1));
753  PTB(sd_writedata(ds_id.fid, "orb_vec", orb_vec, scan, 0, 0, 1, 3, 1));
754  PTB(sd_writedata(ds_id.fid, "l_vert", l_vert, scan, 0, 0, 1, 3, 1));
755  PTB(sd_writedata(ds_id.fid, "sun_ref", sun_ref, scan, 0, 0, 1, 3, 1));
756  PTB(sd_writedata(ds_id.fid, "att_ang", att_ang, scan, 0, 0, 1, 3, 1));
757  PTB(sd_writedata(ds_id.fid, "sen_mat", sen_mat, scan, 0, 0, 1, 3, 3));
758  PTB(sd_writedata(ds_id.fid, "scan_ell", scan_ell, scan, 0, 0, 1, 6, 1));
759  PTB(sd_writedata(ds_id.fid, "nflag", nflag, scan, 0, 0, 1, 8, 1));
760 
761  /*
762  The TDI values from the first call to this function are used
763  in the AddCalData() function to retrieve calibration data
764  that is stored in the level-1A file.
765  */
766  if (firstCallThisFile)
767  for (i = 0; i < 8; i++)
768  tdi_global[i] = tdi[i];
769 
770  return (LIFE_IS_GOOD);
771 }
772 
773 /****************************************************************************
774 Finish accesses for the current file. Each call to CreateL1aFile()
775 should have a corresponding call to this function.
776  *****************************************************************************/
777 int CloseL1aFile(l1met *metrics) {
778 
779  /* Write out the file metrics as global attributes. */
780  PTB(sd_setattr(ds_id.fid,
781  "Gain 1 Saturated Pixels", DFNT_INT32, 8, metrics->gain1_satpix));
782  PTB(sd_setattr(ds_id.fid,
783  "Gain 2 Saturated Pixels", DFNT_INT32, 8, metrics->gain2_satpix));
784  PTB(sd_setattr(ds_id.fid,
785  "Gain 1 Non-Saturated Pixels", DFNT_INT32, 8, metrics->gain1_nonsatpix));
786  PTB(sd_setattr(ds_id.fid,
787  "Gain 2 Non-Saturated Pixels", DFNT_INT32, 8, metrics->gain2_nonsatpix));
788  PTB(sd_setattr(ds_id.fid, "Zero Pixels", DFNT_INT32, 8, metrics->zeropix));
789  PTB(sd_setattr(ds_id.fid,
790  "Mean Gain 1 Radiance", DFNT_FLOAT32, 8, metrics->gain1_mean_rad));
791  PTB(sd_setattr(ds_id.fid,
792  "Mean Gain 2 Radiance", DFNT_FLOAT32, 8, metrics->gain2_mean_rad));
793 
794  PTB(AddCalData());
795 
796  PTB(MakeVgroups());
797 
798  if (SDend(ds_id.fid)) {
799  fprintf(stderr, "-E- %s line %d: SDend(%d) failed for file, %s.\n",
800  __FILE__, __LINE__, ds_id.fid, hdfFile);
801  return (HDF_FUNCTION_ERROR);
802  }
803  free(hdfFile);
804  return (LIFE_IS_GOOD);
805 }
806 
807 /****************************************************************************
808 Store tilt information for the scene in the HDF file.
809  *****************************************************************************/
811  int32 ntilts,
812  int16 tilt_flags[20],
813  int16 tilt_ranges[20][2],
814  float32 tilt_lats[20][2][2],
815  float32 tilt_lons[20][2][2]
816  ) {
817 
818  /* Set unused array values to something eye-catching. :=) */
819  /*
820  for(i = ntilts; i < 20; i++){
821  tilt_flags[i] = -9999;
822  for(j = 0; j < 2; j++){
823  tilt_ranges[i][j] = -9999;
824  for(k = 0; k < 2; k++){
825  tilt_lats[i][j][k] = -9999.9;
826  tilt_lons[i][j][k] = -9999.9;
827  }
828  }
829  }
830  */
831 
832 
833  PTB(CreateSDS(ds_id.fid,
834  "ntilts", /* short name */
835  "Number of scene tilt states", /* long name */
836  NULL, /* standard name */
837  NULL, /* units */
838  0, 0, /* valid range */
839  1.0, 0.0, /* slope,offset */
840  DFNT_INT32, /* HDF number type */
841  1, /* rank */
842  1, 1, 1, /* dimension sizes */
843  "1", NULL, NULL /* dimension names */
844  ));
845 
846  PTB(CreateSDS(ds_id.fid,
847  "tilt_flags", /* short name */
848  "Tilt indicators", /* long name */
849  NULL, /* standard name */
850  NULL, /* units */
851  -1, 3, /* valid range */
852  1.0, 0.0, /* slope,offset */
853  DFNT_INT16, /* HDF number type */
854  1, /* rank */
855  20, 1, 1, /* dimension sizes */
856  "20", NULL, NULL /* dimension names */
857  ));
858 
859  PTB(CreateSDS(ds_id.fid,
860  "tilt_ranges", /* short name */
861  "Scan-line number ranges of scene tilt states", /* long name */
862  NULL, /* standard name */
863  NULL, /* units */
864  0, 0, /* valid range */
865  1.0, 0.0, /* slope,offset */
866  DFNT_INT16, /* HDF number type */
867  2, /* rank */
868  20, 2, 1, /* dimension sizes */
869  "20", "2", NULL /* dimension names */
870  ));
871 
872  PTB(CreateSDS(ds_id.fid,
873  "tilt_lats", /* short name */
874  "Latitudes of tilt-range scan line end points", /* long name */
875  NULL, /* standard name */
876  NULL, /* units */
877  -90.0, 90.0, /* valid range */
878  1.0, 0.0, /* slope,offset */
879  DFNT_FLOAT32, /* HDF number type */
880  3, /* rank */
881  20, 2, 2, /* dimension sizes */
882  "20", "2", "2" /* dimension names */
883  ));
884 
885  PTB(CreateSDS(ds_id.fid,
886  "tilt_lons", /* short name */
887  "Longitudes of tilt-range scan line end points", /* long name */
888  NULL, /* standard name */
889  NULL, /* units */
890  -180.0, 180.0, /* valid range */
891  1.0, 0.0, /* slope,offset */
892  DFNT_FLOAT32, /* HDF number type */
893  3, /* rank */
894  20, 2, 2, /* dimension sizes */
895  "20", "2", "2" /* dimension names */
896  ));
897 
898  PTB(sd_writedata(ds_id.fid, "ntilts", &ntilts, 0, 0, 0, 1, 1, 1));
899  PTB(sd_writedata(ds_id.fid, "tilt_flags", tilt_flags, 0, 0, 0, 20, 1, 1));
900  PTB(sd_writedata(ds_id.fid, "tilt_ranges", tilt_ranges, 0, 0, 0, 20, 2, 1));
901  PTB(sd_writedata(ds_id.fid, "tilt_lats", tilt_lats, 0, 0, 0, 20, 2, 2));
902  PTB(sd_writedata(ds_id.fid, "tilt_lons", tilt_lons, 0, 0, 0, 20, 2, 2));
903 
904  return (LIFE_IS_GOOD);
905 }
906 
907 /****************************************************************************
908 Append calibration data to the HDF file. The calibration data is read from
909 another HDF file pointed to by an environment variable.
910  *****************************************************************************/
911 int AddCalData(void) {
912 
913  /*
914  char *envvar = "CAL_HDF_PATH";
915  char *calPath;
916  int16 entry_year, entry_day, ref_year, ref_day, ref_minute;
917  float32 temps[256][8], scan_mod[2][1285], mirror[2][8];
918  float64 t_const[8], t_linear[8], t_quadratic[8];
919  float32 cal_offs[8], counts[8][4][5], rads[8][4][5];
920 
921  calPath = getenv(envvar);
922  if(calPath == NULL){
923  fprintf(stderr,"-W- %s line %d: ",__FILE__,__LINE__);
924  fprintf(stderr,"Environment variable, \"%s\", not set. ", envvar);
925  fprintf(stderr,"Calibration data not appended to file, %s .\n", hdfFile);
926  return(CALDATA_NOT_APPENDED);
927  }
928 
929  if(
930  get_cal(calPath, startYear, startDay, endDay,
931  startMillisec, dataTypeString, tdi_global,
932  &entry_year, &entry_day, &ref_year, &ref_day, &ref_minute,
933  temps, scan_mod, mirror, t_const, t_linear, t_quadratic,
934  cal_offs, counts, rads) < 0
935  ){
936  fprintf(stderr,"-W- %s line %d: ", __FILE__,__LINE__);
937  fprintf(stderr,
938  "get_cal(%s,%hd,%hd,%hd,%d,\"%s\",[%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd], ...) ",
939  calPath,startYear,startDay,endDay,startMillisec,dataTypeString,
940  tdi_global[0],tdi_global[1],tdi_global[2],tdi_global[3],
941  tdi_global[4],tdi_global[5],tdi_global[6],tdi_global[7]);
942  fprintf(stderr,"failed. ");
943  fprintf(stderr,"Calibration data not appended to file, %s .\n", hdfFile);
944  return(CALDATA_NOT_APPENDED);
945  }
946  */
947 
948  PTB(CreateSDS(ds_id.fid,
949  "entry_year", /* short name */
950  "Calibration entry year", /* long name */
951  NULL, /* standard name */
952  NULL, /* units */
953  0, 0, /* valid range */
954  1.0, 0.0, /* slope,offset */
955  DFNT_INT16, /* HDF number type */
956  1, /* rank */
957  1, 1, 1, /* dimension sizes */
958  "1", NULL, NULL /* dimension names */
959  ));
960 
961  PTB(CreateSDS(ds_id.fid,
962  "entry_day", /* short name */
963  "Calibration entry day-of-year", /* long name */
964  NULL, /* standard name */
965  NULL, /* units */
966  0, 0, /* valid range */
967  1.0, 0.0, /* slope,offset */
968  DFNT_INT16, /* HDF number type */
969  1, /* rank */
970  1, 1, 1, /* dimension sizes */
971  "1", NULL, NULL /* dimension names */
972  ));
973 
974  PTB(CreateSDS(ds_id.fid,
975  "ref_year", /* short name */
976  "Calibration reference year", /* long name */
977  NULL, /* standard name */
978  NULL, /* units */
979  0, 0, /* valid range */
980  1.0, 0.0, /* slope,offset */
981  DFNT_INT16, /* HDF number type */
982  1, /* rank */
983  1, 1, 1, /* dimension sizes */
984  "1", NULL, NULL /* dimension names */
985  ));
986 
987  PTB(CreateSDS(ds_id.fid,
988  "ref_day", /* short name */
989  "Calibration reference day-of-year", /* long name */
990  NULL, /* standard name */
991  NULL, /* units */
992  0, 0, /* valid range */
993  1.0, 0.0, /* slope,offset */
994  DFNT_INT16, /* HDF number type */
995  1, /* rank */
996  1, 1, 1, /* dimension sizes */
997  "1", NULL, NULL /* dimension names */
998  ));
999 
1000  PTB(CreateSDS(ds_id.fid,
1001  "ref_minute", /* short name */
1002  "Calibration reference minute-of-day", /* long name */
1003  NULL, /* standard name */
1004  NULL, /* units */
1005  0, 0, /* valid range */
1006  1.0, 0.0, /* slope,offset */
1007  DFNT_INT16, /* HDF number type */
1008  1, /* rank */
1009  1, 1, 1, /* dimension sizes */
1010  "1", NULL, NULL /* dimension names */
1011  ));
1012 
1013  PTB(CreateSDS(ds_id.fid,
1014  "mirror", /* short name */
1015  "Mirror-side correction factors", /* long name */
1016  NULL, /* standard name */
1017  NULL, /* units */
1018  0, 0, /* valid range */
1019  1.0, 0.0, /* slope,offset */
1020  DFNT_FLOAT32, /* HDF number type */
1021  2, /* rank */
1022  2, 8, 1, /* dimension sizes */
1023  "Number of Sides", "Number of Bands", NULL /* dimension names */
1024  ));
1025 
1026  PTB(CreateSDS(ds_id.fid,
1027  "t_const", /* short name */
1028  "Time-dependent correction constant terms", /* long name */
1029  NULL, /* standard name */
1030  NULL, /* units */
1031  0, 0, /* valid range */
1032  1.0, 0.0, /* slope,offset */
1033  DFNT_FLOAT64, /* HDF number type */
1034  1, /* rank */
1035  8, 1, 1, /* dimension sizes */
1036  "Number of Bands", NULL, NULL /* dimension names */
1037  ));
1038 
1039  PTB(CreateSDS(ds_id.fid,
1040  "t_linear", /* short name */
1041  "Time-dependent correction linear coefficients", /* long name */
1042  NULL, /* standard name */
1043  NULL, /* units */
1044  0, 0, /* valid range */
1045  1.0, 0.0, /* slope,offset */
1046  DFNT_FLOAT64, /* HDF number type */
1047  1, /* rank */
1048  8, 1, 1, /* dimension sizes */
1049  "Number of Bands", NULL, NULL /* dimension names */
1050  ));
1051 
1052  PTB(CreateSDS(ds_id.fid,
1053  "t_quadratic", /* short name */
1054  "Time-dependent correction quadratic coefficients", /* long name */
1055  NULL, /* standard name */
1056  NULL, /* units */
1057  0, 0, /* valid range */
1058  1.0, 0.0, /* slope,offset */
1059  DFNT_FLOAT64, /* HDF number type */
1060  1, /* rank */
1061  8, 1, 1, /* dimension sizes */
1062  "Number of Bands", NULL, NULL /* dimension names */
1063  ));
1064 
1065  PTB(CreateSDS(ds_id.fid,
1066  "cal_offs", /* short name */
1067  "Calibration system offsets", /* long name */
1068  NULL, /* standard name */
1069  NULL, /* units */
1070  0, 0, /* valid range */
1071  1.0, 0.0, /* slope,offset */
1072  DFNT_FLOAT32, /* HDF number type */
1073  1, /* rank */
1074  8, 1, 1, /* dimension sizes */
1075  "Number of Bands", NULL, NULL /* dimension names */
1076  ));
1077 
1078  PTB(CreateSDS(ds_id.fid,
1079  "counts", /* short name */
1080  "Digital counts of calibration knees", /* long name */
1081  NULL, /* standard name */
1082  NULL, /* units */
1083  0, 1023, /* valid range */
1084  1.0, 0.0, /* slope,offset */
1085  DFNT_FLOAT32, /* HDF number type */
1086  3, /* rank */
1087  8, 4, 5, /* dimension sizes */
1088  "Number of Bands", "Number of Gains", "Number of Knees" /* dimension names */
1089  ));
1090 
1091  PTB(CreateSDS(ds_id.fid,
1092  "rads", /* short name */
1093  "Radiances of calibration knees", /* long name */
1094  NULL, /* standard name */
1095  NULL, /* units */
1096  0, 0, /* valid range */
1097  1.0, 0.0, /* slope,offset */
1098  DFNT_FLOAT32, /* HDF number type */
1099  3, /* rank */
1100  8, 4, 5, /* dimension sizes */
1101  "Number of Bands", "Number of Gains", "Number of Knees" /* dimension names */
1102  ));
1103 
1104  /*
1105  PTB( sd_writedata("entry_year" , &entry_year , 0, 0, 0, 1, 1, 1) );
1106  PTB( sd_writedata("entry_day" , &entry_day , 0, 0, 0, 1, 1, 1) );
1107  PTB( sd_writedata("ref_year" , &ref_year , 0, 0, 0, 1, 1, 1) );
1108  PTB( sd_writedata("ref_day" , &ref_day , 0, 0, 0, 1, 1, 1) );
1109  PTB( sd_writedata("ref_minute" , &ref_minute , 0, 0, 0, 1, 1, 1) );
1110  PTB( sd_writedata("mirror" , mirror , 0, 0, 0, 2, 8, 1) );
1111  PTB( sd_writedata("t_const" , t_const , 0, 0, 0, 8, 1, 1) );
1112  PTB( sd_writedata("t_linear" , t_linear , 0, 0, 0, 8, 1, 1) );
1113  PTB( sd_writedata("t_quadratic" , t_quadratic , 0, 0, 0, 8, 1, 1) );
1114  PTB( sd_writedata("cal_offs" , cal_offs , 0, 0, 0, 8, 1, 1) );
1115  PTB( sd_writedata("counts" , counts , 0, 0, 0, 8, 4, 5) );
1116  PTB( sd_writedata("rads" , rads , 0, 0, 0, 8, 4, 5) );
1117  */
1118 
1119  calibrationAppended = 1; /* signal to MakeVgroups() */
1120 
1121  return (LIFE_IS_GOOD);
1122 }
1123 
1124 /****************************************************************************
1125 Associate various Scientific Data Sets into Vgroups. I don't know what
1126 useful purpose this serves.
1127  *****************************************************************************/
1128 int MakeVgroups(void) {
1129 
1130  int32 h_id, v_id;
1131 
1132  h_id = Hopen(hdfFile, DFACC_RDWR, 0);
1133  if (h_id == FAIL) {
1134  fprintf(stderr, "-E- %s line %d: Hopen() failed for file, %s.\n",
1135  __FILE__, __LINE__, hdfFile);
1136  return (HDF_FUNCTION_ERROR);
1137  }
1138  Vstart(h_id);
1139 
1140  /* Scan-Line Attributes */
1141  PTB(v_attach(h_id, &v_id));
1142  Vsetclass(v_id, "Per Scan Data");
1143  Vsetname(v_id, "Scan-Line Attributes");
1144  PTB(AddSdsToVgroup(ds_id.fid, v_id, "msec"));
1145  PTB(AddSdsToVgroup(ds_id.fid, v_id, "eng_qual"));
1146  PTB(AddSdsToVgroup(ds_id.fid, v_id, "s_flags"));
1147  PTB(AddSdsToVgroup(ds_id.fid, v_id, "s_satp"));
1148  PTB(AddSdsToVgroup(ds_id.fid, v_id, "s_zerop"));
1149  PTB(AddSdsToVgroup(ds_id.fid, v_id, "slat"));
1150  PTB(AddSdsToVgroup(ds_id.fid, v_id, "slon"));
1151  PTB(AddSdsToVgroup(ds_id.fid, v_id, "clat"));
1152  PTB(AddSdsToVgroup(ds_id.fid, v_id, "clon"));
1153  PTB(AddSdsToVgroup(ds_id.fid, v_id, "elat"));
1154  PTB(AddSdsToVgroup(ds_id.fid, v_id, "elon"));
1155  PTB(AddSdsToVgroup(ds_id.fid, v_id, "csol_z"));
1156  PTB(AddSdsToVgroup(ds_id.fid, v_id, "tilt"));
1157  Vdetach(v_id);
1158 
1159  /* Raw SeaStar Data */
1160  PTB(v_attach(h_id, &v_id));
1161  Vsetclass(v_id, "Per Scan Data");
1162  Vsetname(v_id, "Raw SeaStar Data");
1163  PTB(AddSdsToVgroup(ds_id.fid, v_id, "sc_id"));
1164  PTB(AddSdsToVgroup(ds_id.fid, v_id, "sc_ttag"));
1165  PTB(AddSdsToVgroup(ds_id.fid, v_id, "sc_soh"));
1166  PTB(AddSdsToVgroup(ds_id.fid, v_id, "inst_tlm"));
1167  PTB(AddSdsToVgroup(ds_id.fid, v_id, "l1a_data"));
1168  PTB(AddSdsToVgroup(ds_id.fid, v_id, "start_syn"));
1169  PTB(AddSdsToVgroup(ds_id.fid, v_id, "stop_syn"));
1170  PTB(AddSdsToVgroup(ds_id.fid, v_id, "dark_rest"));
1171  PTB(AddSdsToVgroup(ds_id.fid, v_id, "gain"));
1172  PTB(AddSdsToVgroup(ds_id.fid, v_id, "tdi"));
1173  Vdetach(v_id);
1174 
1175  /* Converted Telemetry */
1176  PTB(v_attach(h_id, &v_id));
1177  Vsetclass(v_id, "Per Scan Data");
1178  Vsetname(v_id, "Converted Telemetry");
1179  PTB(AddSdsToVgroup(ds_id.fid, v_id, "inst_ana"));
1180  PTB(AddSdsToVgroup(ds_id.fid, v_id, "inst_dis"));
1181  PTB(AddSdsToVgroup(ds_id.fid, v_id, "sc_ana"));
1182  PTB(AddSdsToVgroup(ds_id.fid, v_id, "sc_dis"));
1183  PTB(AddSdsToVgroup(ds_id.fid, v_id, "scan_temp"));
1184  PTB(AddSdsToVgroup(ds_id.fid, v_id, "side"));
1185  Vdetach(v_id);
1186 
1187  /* Navigation */
1188  PTB(v_attach(h_id, &v_id));
1189  Vsetclass(v_id, "Per Scan Data");
1190  Vsetname(v_id, "Navigation");
1191  PTB(AddSdsToVgroup(ds_id.fid, v_id, "orb_vec"));
1192  PTB(AddSdsToVgroup(ds_id.fid, v_id, "l_vert"));
1193  PTB(AddSdsToVgroup(ds_id.fid, v_id, "sun_ref"));
1194  PTB(AddSdsToVgroup(ds_id.fid, v_id, "att_ang"));
1195  PTB(AddSdsToVgroup(ds_id.fid, v_id, "sen_mat"));
1196  PTB(AddSdsToVgroup(ds_id.fid, v_id, "scan_ell"));
1197  PTB(AddSdsToVgroup(ds_id.fid, v_id, "nflag"));
1198  Vdetach(v_id);
1199 
1200  /* Sensor Tilt */
1201  PTB(v_attach(h_id, &v_id));
1202  Vsetclass(v_id, "Per File Data");
1203  Vsetname(v_id, "Sensor Tilt");
1204  PTB(AddSdsToVgroup(ds_id.fid, v_id, "ntilts"));
1205  PTB(AddSdsToVgroup(ds_id.fid, v_id, "tilt_flags"));
1206  PTB(AddSdsToVgroup(ds_id.fid, v_id, "tilt_ranges"));
1207  PTB(AddSdsToVgroup(ds_id.fid, v_id, "tilt_lats"));
1208  PTB(AddSdsToVgroup(ds_id.fid, v_id, "tilt_lons"));
1209  Vdetach(v_id);
1210 
1211  /* Calibration */
1212  if (calibrationAppended) {
1213  PTB(v_attach(h_id, &v_id));
1214  Vsetclass(v_id, "Per File Data");
1215  Vsetname(v_id, "Calibration");
1216  PTB(AddSdsToVgroup(ds_id.fid, v_id, "entry_year"));
1217  PTB(AddSdsToVgroup(ds_id.fid, v_id, "entry_day"));
1218  PTB(AddSdsToVgroup(ds_id.fid, v_id, "ref_year"));
1219  PTB(AddSdsToVgroup(ds_id.fid, v_id, "ref_day"));
1220  PTB(AddSdsToVgroup(ds_id.fid, v_id, "ref_minute"));
1221  PTB(AddSdsToVgroup(ds_id.fid, v_id, "mirror"));
1222  PTB(AddSdsToVgroup(ds_id.fid, v_id, "t_const"));
1223  PTB(AddSdsToVgroup(ds_id.fid, v_id, "t_linear"));
1224  PTB(AddSdsToVgroup(ds_id.fid, v_id, "t_quadratic"));
1225  PTB(AddSdsToVgroup(ds_id.fid, v_id, "cal_offs"));
1226  PTB(AddSdsToVgroup(ds_id.fid, v_id, "counts"));
1227  PTB(AddSdsToVgroup(ds_id.fid, v_id, "rads"));
1228  Vdetach(v_id);
1229  }
1230 
1231  Vend(h_id);
1232 
1233  if (Hclose(h_id) != SUCCEED) {
1234  fprintf(stderr, "-E- %s line %d: Hclose(%d) failed for file, %s .\n",
1235  __FILE__, __LINE__, h_id, hdfFile);
1236  return (HDF_FUNCTION_ERROR);
1237  }
1238  return (LIFE_IS_GOOD);
1239 }
1240 
1241 /****************************************************************************
1242 Construct a SeaWiFS level-1A filename from a time value and a data-type
1243 value. Return a pointer to the statically allocated filename string.
1244  *****************************************************************************/
1245 char * L1aFilename(swl0ctl *l0ctl, double time, unsigned char dataType) {
1246 
1247  static char filename[24]; /* "Syyyydddhhmmss.L1A_tttt\0" */
1248  struct tm *t;
1249  time_t itime;
1250  double rint(double);
1251 
1252  itime = (time_t) rint(time); /* Round to nearest second. */
1253  t = gmtime(&itime);
1254 
1255  sprintf(
1256  filename,
1257  "S%4d%03d%02d%02d%02d.L1A_%.4s",
1258  t->tm_year + 1900,
1259  t->tm_yday + 1,
1260  t->tm_hour,
1261  t->tm_min,
1262  t->tm_sec,
1263  DataTypeString(l0ctl, dataType)
1264  );
1265 
1266  return (filename);
1267 }
1268 
1269 /****************************************************************************
1270 Return a three- or four-character string to represent the input data type.
1271 The input argument has the data-type value from the spacecraft ID in the
1272 level-0 data or a value of 16 for HRPT data. Unknown data-type values
1273 cause an empty string, "", to be returned.
1274  *****************************************************************************/
1275 char * DTypeString(unsigned char dataType) {
1276  switch (dataType) {
1277  case 0: return ("LAC");
1278  case 1: return ("LUN");
1279  case 2: return ("SOL");
1280  case 3: return ("IGC");
1281  case 4: return ("TDI");
1282  case 15: return ("GAC");
1283  case 16: return ("HRPT");
1284  default: return ("");
1285  }
1286 }
1287 
1288 /****************************************************************************
1289 This function is essentially the same as DTypeString() except that
1290 it returns "Hsta" when passed a 16, where "sta" is the 3-letter station
1291 code as defined in the HRPT_STATION_IDENTIFICATION_FILE. Unknown data-type
1292 values are converted to an ASCII string and returned.
1293  *****************************************************************************/
1294 char * DataTypeString(swl0ctl *l0ctl, unsigned char dataType) {
1295 
1296  static char type[5];
1297  char *t;
1298  int status;
1299 
1300  t = DTypeString(dataType);
1301  if (strcmp(t, "HRPT") == 0) {
1302  StationInfo stationInfo;
1303  status = GetStationInfo(l0ctl->stationInfoFile, &stationInfo);
1304  if (status != LIFE_IS_GOOD || stationInfo.code[0] == 0) {
1305  /* Code not found in StationInfo file. */
1306  sprintf(type, "Hxxx");
1307  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
1308  fprintf(stderr, "Station code not found; using \"xxx\".\n");
1309  } else {
1310  if (strlen(stationInfo.code) == 3)
1311  sprintf(type, "H%.3s", stationInfo.code);
1312  else
1313  sprintf(type, "%.4s", stationInfo.code);
1314  }
1315  return (type);
1316  } else if (*t == 0) {
1317  sprintf(type, "%03u", dataType);
1318  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
1319  fprintf(stderr, "Unknown data type. ");
1320  fprintf(stderr, "Setting data-type string to \"%s\".\n", type);
1321  return (type);
1322  } else {
1323  return (t);
1324  }
1325 }
1326 
1327 /****************************************************************************
1328 Return the year, day-of-year, and millisecond-of-day of the passed in
1329 number of seconds since 1-Jan-1970 00:00:00.000 GMT .
1330  *****************************************************************************/
1332  double dtime,
1333  int16 *year,
1334  int16 *dayofyear,
1335  int32 *millisec
1336  ) {
1337  time_t itime = (time_t) dtime;
1338  struct tm *ts;
1339  double rint(double);
1340 
1341  ts = gmtime(&itime);
1342  *year = (int16) (ts->tm_year + 1900);
1343  *dayofyear = (int16) (ts->tm_yday + 1);
1344  *millisec = (int32) (floor(1000 * (ts->tm_hour * 3600 +
1345  ts->tm_min * 60 +
1346  ts->tm_sec +
1347  dtime - itime)));
1348 }
char * ydhmsf(double dtime, char zone)
Definition: ydhmsf.c:12
int v_attach(int32_t h_id, int32_t *v_id)
Definition: hdf_utils.c:404
int CreateSDS(int32_t sd_id, const char *sname, const char *lname, const char *standard_name, const char *units, double low, double high, float slope, float offset, int32_t nt, int32_t rank, int32_t d0, int32_t d1, int32_t d2, const char *dn0, const char *dn1, const char *dn2)
Definition: hdf_utils.c:77
int SetF32GA(idDS ds_id, const char *name, float value)
integer, parameter int16
Definition: cubeio.f90:3
data_t t[NROOTS+1]
Definition: decode_rs.h:77
void DecomposeTime(double dtime, int16 *year, int16 *dayofyear, int32 *millisec)
Definition: swl1_hdf.c:1331
int GetStationInfo(char *stationInfoFile, StationInfo *stationInfo)
int status
Definition: l1_czcs_hdf.c:32
int AddTiltData(int32 ntilts, int16 tilt_flags[20], int16 tilt_ranges[20][2], float32 tilt_lats[20][2][2], float32 tilt_lons[20][2][2])
Definition: swl1_hdf.c:810
#define NPIXGAC
Definition: swl0_parms.h:26
int16 * gain
Definition: l1_czcs_hdf.c:33
int WriteScanData(int32 scan, swl1rec *l1rec)
Definition: swl1_hdf.c:672
#define FAIL
Definition: ObpgReadGrid.h:18
#define SPIXGAC
Definition: swl0_parms.h:28
#define NULL
Definition: decode_rs.h:63
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
read l1rec
int AddCalData(void)
Definition: swl1_hdf.c:911
int16_t * l1a_data
Definition: l1a_seawifs.c:84
int16_t * dark_rest
Definition: l1a_seawifs.c:89
#define IPIXGAC
Definition: swl0_parms.h:30
int32 * msec
Definition: l1_czcs_hdf.c:31
float tm[MODELMAX]
char * data_center
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
#define SENSORCHAR
Definition: swl1_hdf.c:32
#define IPIXLAC
Definition: swl0_parms.h:29
character(len=1000) if
Definition: names.f90:13
#define MALLOC(ptr, typ, num)
Definition: bindepths.c:45
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
char code[5]
int sd_setattr(int32_t id, const char *nam, int32_t typ, int32_t cnt, const void *data)
Definition: hdf_utils.c:216
int MakeVgroups(void)
Definition: swl1_hdf.c:1128
string path
Definition: color_dtdb.py:221
#define HRPT
Definition: l1stat.h:35
idDS startDS(const char *filename, ds_format_t format, ds_access_t accessmode, int32_t deflate)
Definition: wrapper.c:561
int CreateScanData(int32 ns, int32 np)
Definition: swl1_hdf.c:195
int CloseL1aFile(l1met *metrics)
Definition: swl1_hdf.c:777
int16_t tdi[BANDS_DIMS_1A]
Definition: l1a_seawifs.c:37
char * DataTypeString(swl0ctl *l0ctl, unsigned char dataType)
Definition: swl1_hdf.c:1294
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
#define L01VERSION
Definition: swl0_parms.h:4
int SetI16GA(idDS ds_id, const char *name, int16_t value)
#define PTB(function)
Definition: passthebuck.h:16
char * L1aFilename(swl0ctl *l0ctl, double time, unsigned char dataType)
Definition: swl1_hdf.c:1245
#define GACTYPE
Definition: swl0_parms.h:19
SENSOR
Definition: DDProcess.h:81
int SetI32GA(idDS ds_id, const char *name, int32_t value)
Definition: wrapper.c:326
#define basename(s)
Definition: l0chunk_modis.c:29
char * DTypeString(unsigned char dataType)
Definition: swl1_hdf.c:1275
@ DS_WRITE
Definition: dfutils.h:25
int16_t * side
Definition: l1a_seawifs.c:88
int SetChrGA(idDS ds_id, const char *name, const char *value)
Definition: wrapper.c:236
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 time
Definition: HISTORY.txt:248
#define NPIXLAC
Definition: swl0_parms.h:25
int scan_ell(float p[3], double sm[3][3], double coef[10])
int32_t fid
Definition: dfutils.h:29
u5 which has been done in the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT production Changes from v6 which may affect scientific the sector rotation may actually occur during one of the scans earlier than the one where it is first reported As a the b1 values are about the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT to fill pixels affected by dead subframes with a special value Output the metadata of noisy and dead subframe Dead Subframe EV and Detector Quality Flag2 Removed the function call of Fill_Dead_Detector_SI to stop interpolating SI values for dead but also for all downstream products for science test only Changes from v5 which will affect scientific to conform to MODIS requirements Removed the Mixed option from the ScanType in the code because the L1A Scan Type is never Mixed Changed for ANSI C compliance and comments to better document the fact that when the HDF_EOS metadata is stricly the and products are off by and in the track respectively Corrected some misspelling of RCS swir_oob_sending_detector to the Reflective LUTs to enable the SWIR OOB correction detector so that if any of the sending detectors becomes noisy or non near by good detectors from the same sending band can be specified as the substitute in the new look up table Code change for adding an additional dimension of mirror side to the Band_21_b1 LUT to separate the coefficient of the two mirror sides for just like other thermal emissive so that the L1B code can calibrate Band scan to scan with mirror side dependency which leads better calibration result Changes which do not affect scientific when the EV data are not provided in this Crosstalk Correction will not be performed to the Band calibration data Changes which do not affect scientific and BB_500m in L1A Logic was added to turn off the or to spatial aggregation processes and the EV_250m_Aggr1km_RefSB and EV_500m_Aggr1km_RefSB fields were set to fill values when SDSs EV_250m and EV_500m are absent in L1A file Logic was added to skip the processing and turn off the output of the L1B QKM and HKM EV data when EV_250m and EV_500m are absent from L1A In this the new process avoids accessing and reading the and L1A EV skips and writing to the L1B and EV omits reading and subsampling SDSs from geolocation file and writing them to the L1B and omits writing metadata to L1B and EV and skips closing the L1A and L1B EV and SDSs Logic was added to turn off the L1B OBC output when the high resolution OBC SDSs are absent from L1A This is accomplished by skipping the openning the writing of metadata and the closing of the L1B OBC hdf which is Bit in the scan by scan bit QA has been changed Until now
Definition: HISTORY.txt:361
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)
@ DS_HDF
Definition: dfutils.h:19
Definition: dfutils.h:28
int AddSdsToVgroup(int32_t sd_id, int32_t v_id, const char *name)
Definition: hdf_utils.c:383
float station_longitude
char * station_name
int sd_writedata(int32_t sd_id, const char *name, const void *data, int32_t s0, int32_t s1, int32_t s2, int32_t e0, int32_t e1, int32_t e2)
Definition: hdf_utils.c:293
float station_latitude
float32 * att_ang
Definition: l1_czcs_hdf.c:34
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
int16_t * tilt
Definition: l2bin.cpp:86
#define MISSIONCHAR
Definition: swl1_hdf.c:31
int i
Definition: decode_rs.h:71
double rint(double)
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define PROGRAMMER_BOOBOO
Definition: passthebuck.h:8
#define HDF_FUNCTION_ERROR
Definition: passthebuck.h:7
int CreateL1aFile(char *path, swl0scene *scene, char *proccon, char *proclog, swl0ctl *l0ctl)
Definition: swl1_hdf.c:39
#define SPIXLAC
Definition: swl0_parms.h:27