OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1_ocmdb_hdf.c
Go to the documentation of this file.
1 
2 /* ============================================================================ */
3 /* module l1_ocmdb_hdf.c - functions to read OCM L1B (NRL HDF) for MSL12 */
4 /* Written By: Paul Martinolich, Naval Research Laboratory */
5 /* ============================================================================ */
6 
7 #include "l1_ocmdb_hdf.h"
8 #include "l1.h"
9 #include <hdf4utils.h>
10 
11 #include <hdf.h>
12 #include <mfhdf.h>
13 
14 static int32_t fileID;
15 static int32_t spix = 0;
16 static int32_t year, day, msec;
17 
18 /* ----------------------------------------------------------------------------- */
19 /* openl1_ocmdb_hdf() - opens an OCM L1B file for reading. */
20 
21 /* ----------------------------------------------------------------------------- */
22 
23 int openl1_ocmdb_hdf(filehandle *file) {
24  int32_t npix;
25  int32_t nscan;
26  int32_t sds_id;
27  int32_t rank;
28  int32_t dims[3];
29  int32_t type;
30  int32_t numattr;
31  int itmp;
32  double itmp2;
33  char date[16];
34 
35  /* Open the HDF input file */
36  fileID = SDstart(file->name, DFACC_RDONLY);
37  if (fileID == FAIL) {
38  fprintf(stderr, "-E- %s line %d: SDstart(%s, %d) failed.\n",
39  __FILE__, __LINE__, file->name, DFACC_RDONLY);
40  return (HDF_FUNCTION_ERROR);
41  }
42 
43  /* Get pixel and scan dimensions */
44  sds_id = SDselect(fileID, SDnametoindex(fileID, ("ocm_ch1")));
45  if (SDgetinfo(sds_id, NULL, &rank, dims, &type, &numattr) == -1) {
46  fprintf(stderr, "-E- %s line %d: error getting dimension info.\n",
47  __FILE__, __LINE__);
48  return (HDF_FUNCTION_ERROR);
49  }
50  npix = dims[1];
51  nscan = dims[0];
52 
53  getHDFattr(fileID, "pass_date", "", (VOIDP) & itmp);
54  getHDFattr(fileID, "start_time", "", (VOIDP) & itmp2);
55  sprintf(date, "%d%g", itmp, itmp2);
56  printf("%s\n", date);
57  date2ydmsec(date, &year, &day, &msec);
58 
59  /*
60  rgb_map = get_bindx_rgb( file->input );
61  if ( rgb_map )
62  printf("OCM rgb bands: red %d nm (#%d), green %d nm (#%d), blue %d nm (#%d)\n",
63  file->input->rgb_wave[0], rgb_map[0],
64  file->input->rgb_wave[1], rgb_map[1],
65  file->input->rgb_wave[2], rgb_map[2]);
66  */
67 
68  file->npix = npix;
69  file->nscan = nscan;
70  file->nbands = 8;
71  file->sd_id = fileID;
72  strcpy(file->spatialResolution, "350 m");
73 
74  return (LIFE_IS_GOOD);
75 }
76 
77 
78 /* ----------------------------------------------------------------------------- */
79 /* readl1_ocmdb_hdf() - reads 1 line (scan) from an OCM L1B file, loads l1rec. */
80 
81 /* ----------------------------------------------------------------------------- */
82 int readl1_ocmdb_hdf(filehandle *file, int32_t scan, l1str *l1rec) {
83  static int firstCall = 1;
84 
85  static uint16 **dataarr;
86  static float **scanarr;
87 
88  static double *m;
89  static double *b;
90  static uint16 **valid_range;
91  static uint16 *FillValue;
92 
93  static char *names[] = {"ocm_ch1", "ocm_ch2", "ocm_ch3", "ocm_ch4",
94  "ocm_ch5", "ocm_ch6", "ocm_ch7", "ocm_ch8"};
95 
96  int32_t npix = (int32_t) file->npix;
97  int32_t ip, ib, ipb;
98 
99  if (firstCall) {
100 
101  firstCall = 0;
102 
103  printf("OCM has %d bands\n", l1rec->l1file->nbands);
104 
105  dataarr = (uint16 **) calloc(1, l1rec->l1file->nbands * sizeof (uint16*));
106  scanarr = (float **) calloc(1, l1rec->l1file->nbands * sizeof (float*));
107 
108  m = (double *) calloc(1, l1rec->l1file->nbands * sizeof (double));
109  b = (double *) calloc(1, l1rec->l1file->nbands * sizeof (double));
110 
111  valid_range = (uint16 **) calloc(1, l1rec->l1file->nbands * sizeof (uint16*));
112  FillValue = (uint16 *) calloc(1, l1rec->l1file->nbands * sizeof (uint16));
113 
114  for (ib = 0; ib < l1rec->l1file->nbands; ib++) {
115  if ((dataarr[ib] = (uint16 *) calloc(npix, sizeof (uint16))) == NULL) {
116  printf("-E- %s line %d: Error allocating data space.\n",
117  __FILE__, __LINE__);
118  return (1);
119  }
120  if ((scanarr[ib] = (float *) calloc(npix, sizeof (float))) == NULL) {
121  printf("-E- %s line %d: Error allocating scan space.\n",
122  __FILE__, __LINE__);
123  return (1);
124  }
125  if ((valid_range[ib] = (uint16 *) calloc(2, sizeof (uint16))) == NULL) {
126  printf("-E- %s line %d: Error allocating scan space.\n",
127  __FILE__, __LINE__);
128  return (1);
129  }
130  if (getHDFattr(fileID, "scale_factor", names[ib], (VOIDP) & m[ib]) != 0) {
131  printf("-E- %s line %d: Error reading reflectance scale attribute.\n",
132  __FILE__, __LINE__);
133  return (1);
134  }
135  if (getHDFattr(fileID, "add_offset", names[ib], (VOIDP) & b[ib]) != 0) {
136  printf("-E- %s line %d: Error reading reflectance scale attribute.\n",
137  __FILE__, __LINE__);
138  return (1);
139  }
140  if (getHDFattr(fileID, "_FillValue", names[ib], (VOIDP) & FillValue[ib]) != 0) {
141  printf("-E- %s line %d: Error reading reflectance scale attribute.\n",
142  __FILE__, __LINE__);
143  return (1);
144  }
145  if (getHDFattr(fileID, "valid_range", names[ib], (VOIDP) valid_range[ib]) != 0) {
146  printf("-E- %s line %d: Error reading reflectance scale attribute.\n",
147  __FILE__, __LINE__);
148  return (1);
149  }
150  printf("OCM Channel %s\n", names[ib]);
151  printf("\tscale_factor %g, add_offset %g\n", m[ib], b[ib]);
152  printf("\t_FillValue %d\n", (int) FillValue[ib]);
153  printf("\tvalid_range [%d,%d]\n", (int) valid_range[ib][0], (int) valid_range[ib][1]);
154  }
155 
156  }
157  l1rec->scantime = yds2unix(year, day, (double) (msec / 1.e3));
158 
159  /* Get position and path geometry */
160 
161  READ_SDS_ID(fileID, "latitude", l1rec->lat, scan, spix, 0, 0, 1, npix, 1, 1);
162  READ_SDS_ID(fileID, "longitude", l1rec->lon, scan, spix, 0, 0, 1, npix, 1, 1);
163  READ_SDS_ID(fileID, "sun_zenith", l1rec->solz, scan, spix, 0, 0, 1, npix, 1, 1);
164  READ_SDS_ID(fileID, "rel_azimuth", l1rec->sola, scan, spix, 0, 0, 1, npix, 1, 1);
165  READ_SDS_ID(fileID, "sat_zenith", l1rec->senz, scan, spix, 0, 0, 1, npix, 1, 1);
166  READ_SDS_ID(fileID, "scatter_phase", l1rec->sena, scan, spix, 0, 0, 1, npix, 1, 1);
167 
168  for (ip = 0; ip < npix; ip++) {
169 
170  l1rec->pixnum[ip] = spix + ip;
171 
172  if (l1rec->lon[ip] < -181.0 || l1rec->lon[ip] > 181.0 ||
173  l1rec->lat[ip] < -91.0 || l1rec->lat[ip] > 91.0)
174  l1rec->navfail[ip] = 1;
175  }
176 
177  // read in the data and apply scaling
178 
179  for (ib = 0; ib < l1rec->l1file->nbands; ib++) {
180  READ_SDS_ID(fileID, names[ib], &dataarr[ib][0], scan, spix, 0, 0, 1, npix, 1, 1);
181  for (ip = 0; ip < npix; ip++) {
182  scanarr[ib][ip] = (float) dataarr[ib][ip] * m[ib] + b[ib];
183  }
184  }
185 
186  /* copy over to l1rec */
187 
188  for (ip = 0; ip < npix; ip++) {
189  for (ib = 0; ib < l1rec->l1file->nbands; ib++) {
190 
191  // ipb = ip*l1rec->nbands + ib;
192  ipb = ip * l1rec->l1file->nbands + ib;
193  l1rec->Lt[ipb] = scanarr[ib][ip];
194 
195  if (dataarr[ib][ip] < valid_range[ib][0] || dataarr[ib][ip] > valid_range[ib][1]) {
196  l1rec->hilt[ip] = 1;
197  l1rec->Lt[ipb] = 1000.0;
198  }
199  if (dataarr[ib][ip] == FillValue[ib]) {
200  l1rec->hilt[ip] = 1;
201  l1rec->Lt[ipb] = 1000.0;
202  }
203  if (dataarr[ib][ip] == 0) {
204  l1rec->hilt[ip] = 1;
205  l1rec->Lt[ipb] = 1000.0;
206  }
207  }
208 
209  // copy over Lt_rgb bands if band-mapping defined
210  /*
211  if ( rgb_map )
212  for (ib = 0; ib < 3; ib++ )
213  l1rec->Lt_rgb[ip*3+ib] = l1rec->Lt[ip*l1rec->nbands+rgb_map[ib]];
214  */
215  }
216 
217  l1rec->npix = file->npix;
218 
219  return (LIFE_IS_GOOD);
220 }
221 
222 int closel1_ocmdb_hdf(filehandle *file) {
223  if (SDend(fileID)) {
224  fprintf(stderr, "-E- %s line %d: SDend(%d) failed for file, %s.\n",
225  __FILE__, __LINE__, fileID, file->name);
226  return (HDF_FUNCTION_ERROR);
227  }
228 
229  return (LIFE_IS_GOOD);
230 }
int32_t day
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
int16_t fileID
int closel1_ocmdb_hdf(filehandle *file)
Definition: l1_ocmdb_hdf.c:222
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
int openl1_ocmdb_hdf(filehandle *file)
Definition: l1_ocmdb_hdf.c:23
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
int32 * msec
Definition: l1_czcs_hdf.c:31
int32 nscan
Definition: l1_czcs_hdf.c:19
#define READ_SDS_ID(sd_id, nam, ptr, s0, s1, s2, s3, e0, e1, e2, e3)
Definition: hdf4utils.h:109
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
character(len=1000) if
Definition: names.f90:13
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
int getHDFattr(int32_t fileID, const char attrname[], const char sdsname[], void *data)
data_t b[NROOTS+1]
Definition: decode_rs.h:77
Definition: names.f90:1
int32 spix
Definition: l1_czcs_hdf.c:21
Extra metadata that will be written to the HDF4 file l2prod rank
void date2ydmsec(char *date, int32_t *year, int32_t *day, int32_t *msec)
Definition: date2ydmsec.c:4
int readl1_ocmdb_hdf(filehandle *file, int32_t scan, l1str *l1rec)
Definition: l1_ocmdb_hdf.c:82
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int npix
Definition: get_cmp.c:27
#define HDF_FUNCTION_ERROR
Definition: passthebuck.h:7