OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
czcs_l1_write.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <libgen.h>
3 #include "hdf.h"
4 #include "mfhdf.h"
5 
6 #include "l1czcs.h" /* local include file */
7 
8 int czcs_l1_write(char *ofile, l1_data_struc l1_data, gattr_struc gattr)
9 /*******************************************************************
10 
11  czcs_l1_write
12 
13  purpose: Write the CZCS L1A dataset
14 
15  Returns type: int 0 is good
16 
17  Parameters: (in calling order)
18  Type Name I/O Description
19  ---- ---- --- -----------
20  char * ofile I output file name
21  l1_data_struc l1_data I data counts, lat, lon
22  gattr_struc gattr I file attributes
23 
24  Modification history:
25  Programmer Date Description of change
26  ---------- ---- ---------------------
27  W. Robinson 9-Mar-2004 adapted from seadas version
28  by removing global attributes:
29  Area Code, Circle Parameters
30  adding global attributes:
31  Slope, Intercept, Roll, Pitch, Yaw
32 
33  *******************************************************************/ {
34  int32 sdfid, fid, raw_vid, nav_vid, sl_attr_vid;
35  int iret, tot_line, tot_pixel;
36  char *file;
37 
38  /*
39  * get count array size from structure
40  */
41  tot_line = gattr.scan_lines;
42  tot_pixel = gattr.pix_per_scan;
43 
44  /*
45  * open output file
46  */
47  if ((sdfid = SDstart(ofile, DFACC_CREATE)) < 0) {
48  fprintf(stderr, "[czcs_l1_write] Error: SDstart failed on %s\n", ofile);
49  return FAIL;
50  }
51 
52  if ((fid = Hopen(ofile, DFACC_RDWR, 0)) < 0) {
53  fprintf(stderr, "[czcs_l1_write] Error: Hopen failed on %s\n", ofile);
54  return FAIL;
55  }
56 
57  /* create global attributes */
58 
59  file = basename(ofile);
60  iret = create_global_attribute(file, sdfid, gattr);
61 
62  Vstart(fid);
63 
64  /* create all the vgroups */
65 
66  sl_attr_vid = Vattach(fid, -1, "w");
67  Vsetname(sl_attr_vid, "Scan-Line Attributes");
68 
69  raw_vid = Vattach(fid, -1, "w");
70  Vsetname(raw_vid, "Raw CZCS Data");
71 
72  nav_vid = Vattach(fid, -1, "w");
73  Vsetname(nav_vid, "Navigation");
74 
75  /* create all bands SDSs */
76 
77  iret = FAIL;
78  if (create_band_sds(sdfid, raw_vid, l1_data.counts, tot_pixel,
79  tot_line) >= 0) {
80  /* add the quality per line data */
81  if (wrt_czcs_qual(sdfid, raw_vid, tot_line, l1_data)
82  == SUCCEED) {
83  /* create navigation SDS */
84  if (set_czcs_ctl_data(sdfid, nav_vid, gattr, l1_data)
85  >= 0) {
86  if (wrt_czcs_sla(sdfid, sl_attr_vid, tot_line, l1_data)
87  == SUCCEED)
88  iret = SUCCEED;
89  }
90  }
91  }
92  Vdetach(raw_vid);
93  Vdetach(nav_vid);
94  Vdetach(sl_attr_vid);
95  Vend(fid);
96  SDend(sdfid);
97  Hclose(fid);
98 
99  return iret;
100 }
101 
102 int create_global_attribute(char *file, int sdfid, gattr_struc gattr) {
103 #define TITLE "Title"
104 #define TITLE_VAL "CZCS Level-1A Data"
105 #define SENSOR_VAL "Coastal Zone Color Scanner (CZCS)"
106 #define MISSION "Mission"
107 #define MISSION_VAL "Nimbus CZCS"
108 #define MISSIONCHAR "Mission Characteristics"
109 #define MISSIONCHAR_VAL "Nominal orbit: inclination = 99.3 (Sun-Synchronous); node = 11:52 AM local (ascending); eccentricity =< 0.0009; altitude = 955km; ground speed = 6.4km/sec"
110 #define SENSOR "Sensor"
111 #define SENSOR_VAL "Coastal Zone Color Scanner (CZCS)"
112 #define SENSORCHAR "Sensor Characteristics"
113 #define SENSORCHAR_VAL "Number of bands = 6; number of active bands = 6; wavelengths per band (nm) = 443, 520, 550, 670, 750, 11500; bits per pixel = 8; instantaneous field-of-view = .865 mrad; pixels per scan = 1968; scan rate = 8.08/sec"
114 #define REPL_FLG "ORIGINAL"
115 
116  int cl;
117 
118  /*** write Product Name and "Title" */
119  if ((SDsetattr(sdfid, "Product Name", DFNT_CHAR, strlen(file) + 1,
120  (VOIDP) file)) < 0)
121  return FAIL;
122 
123  if ((SDsetattr(sdfid, TITLE, DFNT_CHAR, strlen(TITLE_VAL) + 1,
124  (VOIDP) TITLE_VAL)) < 0)
125  return FAIL;
126 
127  /*** write "Data type" */
128  if ((SDsetattr(sdfid, "Data Type", DFNT_CHAR, strlen(gattr.datatype) + 1,
129  (VOIDP) gattr.datatype)) < 0)
130  return FAIL;
131 
132  if ((SDsetattr(sdfid, "Replacement Flag", DFNT_CHAR, strlen(REPL_FLG) + 1,
133  (VOIDP) REPL_FLG)) < 0)
134  return FAIL;
135 
136  /*** write "Data Center" */
137  if ((SDsetattr(sdfid, "Data Center", DFNT_CHAR, strlen(gattr.datacenter) + 1,
138  (VOIDP) gattr.datacenter)) < 0)
139  return FAIL;
140 
141  /*** write "Station Name" */
142  if ((SDsetattr(sdfid, "Station Name", DFNT_CHAR, strlen(gattr.stn_name) + 1,
143  (VOIDP) gattr.stn_name)) < 0)
144  return FAIL;
145 
146  if ((SDsetattr(sdfid, "Station Latitude", DFNT_FLOAT32, 1,
147  (VOIDP) & gattr.stn_lat)) < 0)
148  return FAIL;
149 
150  if ((SDsetattr(sdfid, "Station Longitude", DFNT_FLOAT32, 1,
151  (VOIDP) & gattr.stn_lon)) < 0)
152  return FAIL;
153 
154  /*** write "Mission" */
155  if ((SDsetattr(sdfid, MISSION, DFNT_CHAR, strlen(MISSION_VAL) + 1,
156  (VOIDP) MISSION_VAL)) < 0)
157  return FAIL;
158 
159  /*** write "Mission Characteristics" */
160  if ((SDsetattr(sdfid, MISSIONCHAR, DFNT_CHAR, strlen(MISSIONCHAR_VAL) + 1,
161  (VOIDP) MISSIONCHAR_VAL)) < 0)
162  return FAIL;
163 
164  /*** write "Sensor" */
165  if ((SDsetattr(sdfid, SENSOR, DFNT_CHAR, strlen(SENSOR_VAL) + 1,
166  (VOIDP) SENSOR_VAL)) < 0)
167  return FAIL;
168 
169  if ((SDsetattr(sdfid, SENSORCHAR, DFNT_CHAR, strlen(SENSORCHAR_VAL) + 1,
170  (VOIDP) SENSORCHAR_VAL)) < 0)
171  return FAIL;
172 
173  /*** write "Software ID" */
174  if ((SDsetattr(sdfid, "Software ID", DFNT_CHAR,
175  strlen(gattr.soft_id) + 1, (VOIDP) gattr.soft_id)) < 0)
176  return FAIL;
177 
178  /*** write "Processing Time" */
179  if ((SDsetattr(sdfid, "Processing Time", DFNT_CHAR,
180  strlen(gattr.process_time) + 1, (VOIDP) gattr.process_time)) < 0)
181  return FAIL;
182 
183  /*** write "Input Files" */
184  if ((SDsetattr(sdfid, "Input Files", DFNT_CHAR,
185  strlen(gattr.input_files) + 1, (VOIDP) gattr.input_files)) < 0)
186  return FAIL;
187 
188  /*** write "Processing Control" */
189  if ((SDsetattr(sdfid, "Processing Control", DFNT_CHAR,
190  strlen(gattr.proc_ctl) + 1, (VOIDP) gattr.proc_ctl)) < 0)
191  return FAIL;
192 
193  if ((SDsetattr(sdfid, "Pixels per Scan Line", DFNT_INT32, 1,
194  (VOIDP) & gattr.pix_per_scan)) < 0)
195  return FAIL;
196 
197  if ((SDsetattr(sdfid, "Number of Scan Lines", DFNT_INT32, 1,
198  &gattr.scan_lines)) < 0)
199  return FAIL;
200 
201  if ((SDsetattr(sdfid, "Number of Pixel Control Points", DFNT_INT32, 1,
202  &gattr.n_ctl_pt)) < 0)
203  return FAIL;
204 
205  if ((SDsetattr(sdfid, "Number of Scan Control Points", DFNT_INT32, 1,
206  &gattr.scan_lines)) < 0)
207  return FAIL;
208 
209  if ((SDsetattr(sdfid, "LAC Pixel Start Number", DFNT_INT32, 1,
210  &gattr.lac_pixl_start_no)) < 0)
211  return FAIL;
212 
213  if ((SDsetattr(sdfid, "LAC Pixel Subsampling", DFNT_INT32, 1,
214  &gattr.lac_pixl_subsample)) < 0)
215  return FAIL;
216 
217  cl = gattr.scan_lines / 2 + 1;
218  if ((SDsetattr(sdfid, "Scene Center Scan Line", DFNT_INT32, 1, &cl)) < 0)
219  return FAIL;
220 
221  if ((SDsetattr(sdfid, "Filled Scan Lines", DFNT_INT32, 1,
222  &gattr.scan_lines)) < 0)
223  return FAIL;
224 
225  if ((SDsetattr(sdfid, "Start Time", DFNT_CHAR, strlen(gattr.start_time) + 1,
226  &gattr.start_time)) < 0)
227  return FAIL;
228 
229  if ((SDsetattr(sdfid, "End Time", DFNT_CHAR, strlen(gattr.end_time) + 1,
230  &gattr.end_time)) < 0)
231  return FAIL;
232 
233  if ((SDsetattr(sdfid, "Scene Center Time", DFNT_CHAR,
234  strlen(gattr.center_time) + 1, &gattr.center_time)) < 0)
235  return FAIL;
236 
237  if ((SDsetattr(sdfid, "Start Year", DFNT_INT16, 1,
238  &gattr.start_year)) < 0)
239  return FAIL;
240 
241  if ((SDsetattr(sdfid, "Start Day", DFNT_INT16, 1,
242  &gattr.start_day)) < 0)
243  return FAIL;
244 
245  if ((SDsetattr(sdfid, "Start Millisec", DFNT_INT32, 1,
246  &gattr.start_msec)) < 0)
247  return FAIL;
248 
249  if ((SDsetattr(sdfid, "End Year", DFNT_INT16, 1,
250  &gattr.end_year)) < 0)
251  return FAIL;
252 
253  if ((SDsetattr(sdfid, "End Day", DFNT_INT16, 1,
254  &gattr.end_day)) < 0)
255  return FAIL;
256 
257  if ((SDsetattr(sdfid, "End Millisec", DFNT_INT32, 1,
258  &gattr.end_msec)) < 0)
259  return FAIL;
260 
261  if ((SDsetattr(sdfid, "Start Node", DFNT_CHAR,
262  strlen("Ascending") + 1, "Ascending")) < 0)
263  return FAIL;
264 
265  if ((SDsetattr(sdfid, "End Node", DFNT_CHAR,
266  strlen("Ascending") + 1, "Ascending")) < 0)
267  return FAIL;
268 
269  if ((SDsetattr(sdfid, "Orbit Number", DFNT_INT32, 1,
270  &gattr.orbit)) < 0)
271  return FAIL;
272 
273  if ((SDsetattr(sdfid, "Sensor Tilt", DFNT_FLOAT32, 1,
274  &gattr.tilt)) < 0)
275  return FAIL;
276 
277  if ((SDsetattr(sdfid, "Scene Gain", DFNT_INT32, 1,
278  &gattr.gain)) < 0)
279  return FAIL;
280 
281  if ((SDsetattr(sdfid, "Thresh", DFNT_INT32, 1,
282  &gattr.thresh)) < 0)
283  return FAIL;
284 
285  if ((SDsetattr(sdfid, "Latitude Units", DFNT_CHAR,
286  strlen("degrees North") + 1, "degrees North")) < 0)
287  return FAIL;
288 
289  if ((SDsetattr(sdfid, "Longitude Units", DFNT_CHAR,
290  strlen("degrees East") + 1, "degrees East")) < 0)
291  return FAIL;
292 
293  if ((SDsetattr(sdfid, "Scene Center Latitude",
294  DFNT_FLOAT32, 1, (VOIDP) & gattr.center_lat)) < 0)
295  return FAIL;
296 
297  if ((SDsetattr(sdfid, "Scene Center Longitude",
298  DFNT_FLOAT32, 1, (VOIDP) & gattr.center_lon)) < 0)
299  return FAIL;
300 
301  if ((SDsetattr(sdfid, "Scene Center Solar Zenith",
302  DFNT_FLOAT32, 1, (VOIDP) & gattr.cntr_sol_zen)) < 0)
303  return FAIL;
304 
305  if ((SDsetattr(sdfid, "Upper Left Latitude",
306  DFNT_FLOAT32, 1, (VOIDP) & gattr.up_lft_lat)) < 0)
307  return FAIL;
308 
309  if ((SDsetattr(sdfid, "Upper Left Longitude",
310  DFNT_FLOAT32, 1, (VOIDP) & gattr.up_lft_lon)) < 0)
311  return FAIL;
312 
313  if ((SDsetattr(sdfid, "Upper Right Latitude",
314  DFNT_FLOAT32, 1, (VOIDP) & gattr.up_rgt_lat)) < 0)
315  return FAIL;
316 
317  if ((SDsetattr(sdfid, "Upper Right Longitude",
318  DFNT_FLOAT32, 1, (VOIDP) & gattr.up_rgt_lon)) < 0)
319  return FAIL;
320 
321  if ((SDsetattr(sdfid, "Lower Left Latitude",
322  DFNT_FLOAT32, 1, (VOIDP) & gattr.lo_lft_lat)) < 0)
323  return FAIL;
324 
325  if ((SDsetattr(sdfid, "Lower Left Longitude",
326  DFNT_FLOAT32, 1, (VOIDP) & gattr.lo_lft_lon)) < 0)
327  return FAIL;
328 
329  if ((SDsetattr(sdfid, "Lower Right Latitude",
330  DFNT_FLOAT32, 1, (VOIDP) & gattr.lo_rgt_lat)) < 0)
331  return FAIL;
332 
333  if ((SDsetattr(sdfid, "Lower Right Longitude",
334  DFNT_FLOAT32, 1, (VOIDP) & gattr.lo_rgt_lon)) < 0)
335  return FAIL;
336 
337  if ((SDsetattr(sdfid, "Start Center Latitude",
338  DFNT_FLOAT32, 1, (VOIDP) & gattr.start_cntr_lat)) < 0)
339  return FAIL;
340 
341  if ((SDsetattr(sdfid, "Start Center Longitude",
342  DFNT_FLOAT32, 1, (VOIDP) & gattr.start_cntr_lon)) < 0)
343  return FAIL;
344 
345  if ((SDsetattr(sdfid, "End Center Latitude",
346  DFNT_FLOAT32, 1, (VOIDP) & gattr.end_cntr_lat)) < 0)
347  return FAIL;
348 
349  if ((SDsetattr(sdfid, "End Center Longitude",
350  DFNT_FLOAT32, 1, (VOIDP) & gattr.end_cntr_lon)) < 0)
351  return FAIL;
352 
353  if ((SDsetattr(sdfid, "Northernmost Latitude", DFNT_FLOAT32, 1,
354  (VOIDP) & gattr.limits[0])) < 0)
355  return FAIL;
356 
357  if ((SDsetattr(sdfid, "Southernmost Latitude", DFNT_FLOAT32, 1,
358  (VOIDP) & gattr.limits[1])) < 0)
359  return FAIL;
360 
361  if ((SDsetattr(sdfid, "Westernmost Longitude", DFNT_FLOAT32, 1,
362  (VOIDP) & gattr.limits[2])) < 0)
363  return FAIL;
364 
365  if ((SDsetattr(sdfid, "Easternmost Longitude", DFNT_FLOAT32, 1,
366  (VOIDP) & gattr.limits[3])) < 0)
367  return FAIL;
368 
369  /*
370  * also output the slope, intercept, roll, pitch and yaw
371  */
372  if ((SDsetattr(sdfid, "Calibration Slope", DFNT_FLOAT32, 6,
373  (VOIDP) & gattr.slope)) < 0)
374  return FAIL;
375 
376  if ((SDsetattr(sdfid, "Calibration Intercept", DFNT_FLOAT32, 6,
377  (VOIDP) & gattr.intercept)) < 0)
378  return FAIL;
379 
380  if ((SDsetattr(sdfid, "Center Roll", DFNT_FLOAT32, 1, (VOIDP) & gattr.roll)) < 0)
381  return FAIL;
382 
383  if ((SDsetattr(sdfid, "Center Pitch", DFNT_FLOAT32, 1,
384  (VOIDP) & gattr.pitch)) < 0)
385  return FAIL;
386 
387  if ((SDsetattr(sdfid, "Center Yaw", DFNT_FLOAT32, 1, (VOIDP) & gattr.yaw)) < 0)
388  return FAIL;
389 
390  if ((SDsetattr(sdfid, "ILT Flags", DFNT_UINT8, 1,
391  (VOIDP) & gattr.ilt_flags)) < 0)
392  return FAIL;
393 
394  if ((SDsetattr(sdfid, "Parameter Presence Code", DFNT_UINT8, 1,
395  (VOIDP) & gattr.parm_presence)) < 0)
396  return FAIL;
397 
398  if ((SDsetattr(sdfid, "Number of Missing Scan Lines", DFNT_INT16, 1,
399  (VOIDP) & gattr.n_miss_scans)) < 0)
400  return FAIL;
401 
402  if ((SDsetattr(sdfid, "Number of Scans with Missing Channels",
403  DFNT_INT16, 6, (VOIDP) & gattr.n_scan_mis_chan)) < 0)
404  return FAIL;
405 
406  if ((SDsetattr(sdfid, "Number of HDT Sync Losses", DFNT_INT16, 1,
407  (VOIDP) & gattr.n_hdt_sync_loss)) < 0)
408  return FAIL;
409 
410  if ((SDsetattr(sdfid, "Number of HDT Parity Errors", DFNT_INT16, 1,
411  (VOIDP) & gattr.n_hdt_parity_err)) < 0)
412  return FAIL;
413 
414  if ((SDsetattr(sdfid, "Number of WBVT Sync Losses", DFNT_INT16, 1,
415  (VOIDP) & gattr.n_wbvt_sync_loss)) < 0)
416  return FAIL;
417 
418  if ((SDsetattr(sdfid, "Number of WBVT Slip Occurrences", DFNT_INT16, 1,
419  (VOIDP) & gattr.n_wbvt_slips)) < 0)
420  return FAIL;
421 
422  return SUCCEED;
423 }
424 
425 int create_band_sds(int sdfid, int raw_vid, unsigned char *counts[],
426  int tot_pixel, int tot_line) {
427  int32 create_sds(int32, char *, int32, int32, int32 *, int32, VOIDP *);
428  int32 set_dim_names(int32, char *, char *, char *);
429  int dims[3] = {0, 0, 0}, sdsid;
430  char *band_name[6] = {"band1", "band2", "band3", "band4", "band5", "band6"};
431  unsigned char *tmp_ptr;
432  char sds_attr[128];
433  int i, iret;
434 
435  dims[0] = tot_line;
436  dims[1] = tot_pixel;
437 
438  for (i = 0; i < 6; i++) {
439  tmp_ptr = (unsigned char *) (counts[i]);
440  if ((sdsid = create_sds(sdfid, band_name[i], DFNT_UINT8, 2,
441  (int32 *) dims, raw_vid, (VOIDP) tmp_ptr)) < 0) {
442  fprintf(stderr, "create_band_sds: create_sds failed on %s\n",
443  band_name[i]);
444  return FAIL;
445  }
446 
447 
448  if ((iret =
449  set_dim_names(sdsid, "Number of Scan Lines", "Pixels per Scan Line", NULL))
450  < 0) {
451  fprintf(stderr, "create_band_sds: set_dim_names failed on %s\n", band_name[i]);
452  return FAIL;
453  }
454 
455  sprintf(sds_attr, "Level-1A %s data", band_name[i]);
456  if ((iret = SDsetattr(sdsid, "long_name", DFNT_CHAR, strlen(sds_attr) + 1,
457  (VOIDP) sds_attr)) < 0) {
458  fprintf(stderr, "create_band_sds: SDsetattr failed on %s\n", band_name[i]);
459  return FAIL;
460  };
461  strcpy(sds_attr, "radiance counts");
462  if ((iret = SDsetattr(sdsid, "units", DFNT_CHAR, strlen(sds_attr) + 1,
463  (VOIDP) sds_attr)) < 0) {
464  fprintf(stderr, "create_band_sds: SDsetattr failed on %s\n", band_name[i]);
465  return FAIL;
466  };
467 
468  }
469 
470  return SUCCEED;
471 }
#define SENSORCHAR
#define MISSIONCHAR_VAL
float32 intercept
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
int czcs_l1_write(char *ofile, l1_data_struc l1_data, gattr_struc gattr)
Definition: czcs_l1_write.c:8
uint8 * counts
Definition: l1_czcs_hdf.c:30
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
int32 set_dim_names(int32 sds_id, char *d0, char *d1, char *d2)
Definition: set_dim_names.c:29
#define REPL_FLG
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
#define TITLE_VAL
int create_global_attribute(char *file, int sdfid, gattr_struc gattr)
#define SENSOR_VAL
float32 slope
int32 set_czcs_ctl_data(int32, int32, gattr_struc, l1_data_struc)
#define TITLE
int32 create_sds(int32 sdfid, char *sdsname, int32 nt, int32 rank, int32 *dims, int32 vid, VOIDP *data)
Definition: create_sds.c:10
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
SENSOR
Definition: DDProcess.h:81
int wrt_czcs_qual(int32, int32, int, l1_data_struc)
Definition: wrt_czcs_qual.c:6
#define basename(s)
Definition: l0chunk_modis.c:29
#define MISSIONCHAR
int create_band_sds(int sdfid, int raw_vid, unsigned char *counts[], int tot_pixel, int tot_line)
int wrt_czcs_sla(int32, int32, int, l1_data_struc)
Definition: wrt_czcs_sla.c:6
#define SENSORCHAR_VAL
#define MISSION_VAL
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define MISSION