OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l1_ocm_hdf.c
Go to the documentation of this file.
1 /* ============================================================================ */
2 /* module l1_ocm_hdf.c - functions to read OCM L1B for MSL12 */
3 /* */
4 /* Written By: B. Franz, NASA/OBPG, April 2008 . */
5 /* */
6 /* ============================================================================ */
7 
8 #include "l1_ocm_hdf.h"
9 #include <hdf4utils.h>
10 
11 #include <hdf.h>
12 #include <mfhdf.h>
13 
14 /* ----------------------------------------------------------------------------------- */
15 /* openl1_ocm_hdf() - opens a OCM L1B file for reading. */
16 
17 /* ----------------------------------------------------------------------------------- */
18 int openl1_ocm_hdf(filehandle *file) {
19  int32_t npix;
20  int32_t nscan;
21  int32_t sd_id;
22 
23  /* Open the HDF input file */
24  sd_id = SDstart(file->name, DFACC_RDONLY);
25  if (sd_id == FAIL) {
26  fprintf(stderr, "-E- %s line %d: SDstart(%s, %d) failed.\n",
27  __FILE__, __LINE__, file->name, DFACC_RDONLY);
28  exit(1);
29  }
30 
31  /* Get pixel and scan dimensions */
32  if (getHDFattr(sd_id, "Number of Lines", "", (VOIDP) & nscan) != 0) {
33  fprintf(stderr, "-E- %s line %d: error getting dimension info.\n",
34  __FILE__, __LINE__);
35  exit(1);
36  }
37  if (getHDFattr(sd_id, "Number of Pixels", "", (VOIDP) & npix) != 0) {
38  fprintf(stderr, "-E- %s line %d: error getting dimension info.\n",
39  __FILE__, __LINE__);
40  exit(1);
41  }
42 
43  file->npix = npix;
44  file->ndets = 1;
45  file->nscan = nscan;
46  file->sd_id = sd_id;
47  strcpy(file->spatialResolution, "350 m");
48 
49  return (LIFE_IS_GOOD);
50 }
51 
52 
53 /* ----------------------------------------------------------------------------------- */
54 /* readl1_ocm_hdf() - reads 1 line (scan) from an OCM L1B file, loads l1rec. */
55 
56 /* ----------------------------------------------------------------------------------- */
57 int readl1_ocm_hdf(filehandle *file, int32_t scan, l1str *l1rec) {
58  static int firstCall = 1;
59  static int have_ctl = 0;
60  static int32_t nctlpix = 0;
61  static uint16_t *data = NULL;
62  static int32_t *pixnum = NULL;
63  static float *ctlfpix = NULL;
64  static int32_t *ctlpix = NULL;
65  static float *ctllon = NULL;
66  static float *ctllat = NULL;
67  static float *ctlsolz = NULL;
68  static float *ctlsola = NULL;
69  static float *ctlsenz = NULL;
70  static float *ctlsena = NULL;
71  static float *dctllon = NULL;
72  static float *dctllat = NULL;
73  static float *dctlsolz = NULL;
74  static float *dctlsola = NULL;
75  static float *dctlsenz = NULL;
76  static float *dctlsena = NULL;
77  static int16_t factor[8];
78  static char sdsname[32];
79  static int16_t syear = 0;
80  static int16_t sday = 0;
81  static int32_t smsec = 0;
82  static int32_t dmsec = 0;
83 
84  int32_t sd_id = file->sd_id;
85  int32_t npix = file->npix;
86 
87  int32_t ib, ip, ipb;
88 
89  if (firstCall) {
90 
91  firstCall = 0;
92 
93  /* load control-point arrays, if required */
94 
95  if (getHDFattr(sd_id, "Number of Pixel Control Points", "", (VOIDP) & nctlpix) != 0) {
96  fprintf(stderr, "-E- %s line %d: error getting dimension info.\n",
97  __FILE__, __LINE__);
98  exit(1);
99  }
100  if (nctlpix != npix) {
101  printf("Geolocation will be derived from control points.\n");
102  if (
103  (ctlfpix = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
104  (ctlpix = (int32_t *) calloc(nctlpix, sizeof (int32_t))) == NULL ||
105  (ctllon = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
106  (ctllat = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
107  (ctlsolz = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
108  (ctlsola = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
109  (ctlsenz = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
110  (ctlsena = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
111  (dctllon = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
112  (dctllat = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
113  (dctlsolz = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
114  (dctlsola = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
115  (dctlsenz = (float *) calloc(nctlpix, sizeof (float))) == NULL ||
116  (dctlsena = (float *) calloc(nctlpix, sizeof (float))) == NULL) {
117 
118  printf("-E- %s line %d: Error allocating control-point space.\n",
119  __FILE__, __LINE__);
120  return (1);
121  }
122  READ_SDS_ID(sd_id, "ctlpixl", ctlpix, 0, 0, 0, 0, nctlpix, 1, 1, 1);
123  for (ip = 0; ip < nctlpix; ip++) ctlfpix[ip] = (float) ctlpix[ip];
124  have_ctl = 1;
125  }
126 
127  /* get pixel numbers */
128  pixnum = (int32_t *) calloc(npix, sizeof (int32_t));
129  READ_SDS_ID(sd_id, "pixnum", pixnum, 0, 0, 0, 0, npix, 1, 1, 1);
130 
131 
132  /* allocate image data */
133  if ((data = (uint16_t *) calloc(npix * l1rec->l1file->nbands, sizeof (uint16_t))) == NULL) {
134  printf("-E- %s line %d: Error allocating data space.\n",
135  __FILE__, __LINE__);
136  return (1);
137  }
138 
139  /* radiance conversion factors */
140  for (ib = 0; ib < l1rec->l1file->nbands; ib++) {
141  sprintf(sdsname, "band%1d", ib + 1);
142  if (getHDFattr(sd_id, "factor", sdsname, (VOIDP) & factor[ib]) != 0) {
143  fprintf(stderr, "-E- %s line %d: error getting dimension info.\n",
144  __FILE__, __LINE__);
145  exit(1);
146  }
147  }
148 
149  /* get time info */
150  if (getHDFattr(sd_id, "Start Year", "", (VOIDP) & syear) != 0) {
151  fprintf(stderr, "-E- %s line %d: error getting time info.\n",
152  __FILE__, __LINE__);
153  exit(1);
154  }
155  if (getHDFattr(sd_id, "Start Day", "", (VOIDP) & sday) != 0) {
156  fprintf(stderr, "-E- %s line %d: error getting time info.\n",
157  __FILE__, __LINE__);
158  exit(1);
159  }
160  if (getHDFattr(sd_id, "Start Msec", "", (VOIDP) & smsec) != 0) {
161  fprintf(stderr, "-E- %s line %d: error getting time info.\n",
162  __FILE__, __LINE__);
163  exit(1);
164  }
165  if (getHDFattr(sd_id, "Delta Msec", "", (VOIDP) & dmsec) != 0) {
166  fprintf(stderr, "-E- %s line %d: error getting time info.\n",
167  __FILE__, __LINE__);
168  exit(1);
169  }
170 
171  }
172 
173  /* Get position and path geometry */
174  if (have_ctl) {
175 
176  READ_SDS_ID(sd_id, "lon", ctllon, scan, 0, 0, 0, 1, nctlpix, 1, 1);
177  READ_SDS_ID(sd_id, "lat", ctllat, scan, 0, 0, 0, 1, nctlpix, 1, 1);
178  READ_SDS_ID(sd_id, "solz", ctlsolz, scan, 0, 0, 0, 1, nctlpix, 1, 1);
179  READ_SDS_ID(sd_id, "sola", ctlsola, scan, 0, 0, 0, 1, nctlpix, 1, 1);
180  READ_SDS_ID(sd_id, "senz", ctlsenz, scan, 0, 0, 0, 1, nctlpix, 1, 1);
181  READ_SDS_ID(sd_id, "sena", ctlsena, scan, 0, 0, 0, 1, nctlpix, 1, 1);
182 
183  spline(ctlfpix, ctllon, nctlpix, 1e30, 1e30, dctllon);
184  spline(ctlfpix, ctllat, nctlpix, 1e30, 1e30, dctllat);
185  spline(ctlfpix, ctlsolz, nctlpix, 1e30, 1e30, dctlsolz);
186  spline(ctlfpix, ctlsola, nctlpix, 1e30, 1e30, dctlsola);
187  spline(ctlfpix, ctlsenz, nctlpix, 1e30, 1e30, dctlsenz);
188  spline(ctlfpix, ctlsena, nctlpix, 1e30, 1e30, dctlsena);
189 
190  for (ip = 0; ip < npix; ip++) {
191  l1rec->pixnum[ip] = pixnum[ip];
192  splint(ctlfpix, ctllon, dctllon, nctlpix, (float) pixnum[ip], &l1rec->lon[ip]);
193  splint(ctlfpix, ctllat, dctllat, nctlpix, (float) pixnum[ip], &l1rec->lat[ip]);
194  splint(ctlfpix, ctlsolz, dctlsolz, nctlpix, (float) pixnum[ip], &l1rec->solz[ip]);
195  splint(ctlfpix, ctlsola, dctlsola, nctlpix, (float) pixnum[ip], &l1rec->sola[ip]);
196  splint(ctlfpix, ctlsenz, dctlsenz, nctlpix, (float) pixnum[ip], &l1rec->senz[ip]);
197  splint(ctlfpix, ctlsena, dctlsena, nctlpix, (float) pixnum[ip], &l1rec->sena[ip]);
198  }
199 
200  } else {
201  READ_SDS_ID(sd_id, "lon", l1rec->lon, scan, 0, 0, 0, 1, npix, 1, 1);
202  READ_SDS_ID(sd_id, "lat", l1rec->lat, scan, 0, 0, 0, 1, npix, 1, 1);
203  READ_SDS_ID(sd_id, "solz", l1rec->solz, scan, 0, 0, 0, 1, npix, 1, 1);
204  READ_SDS_ID(sd_id, "sola", l1rec->sola, scan, 0, 0, 0, 1, npix, 1, 1);
205  READ_SDS_ID(sd_id, "senz", l1rec->senz, scan, 0, 0, 0, 1, npix, 1, 1);
206  READ_SDS_ID(sd_id, "sena", l1rec->sena, scan, 0, 0, 0, 1, npix, 1, 1);
207  }
208 
209 
210 
211  /* Get radiance data */
212  READ_SDS_ID(sd_id, "band1", &data[0 * npix], scan, 0, 0, 0, 1, npix, 1, 1);
213  READ_SDS_ID(sd_id, "band2", &data[1 * npix], scan, 0, 0, 0, 1, npix, 1, 1);
214  READ_SDS_ID(sd_id, "band3", &data[2 * npix], scan, 0, 0, 0, 1, npix, 1, 1);
215  READ_SDS_ID(sd_id, "band4", &data[3 * npix], scan, 0, 0, 0, 1, npix, 1, 1);
216  READ_SDS_ID(sd_id, "band5", &data[4 * npix], scan, 0, 0, 0, 1, npix, 1, 1);
217  READ_SDS_ID(sd_id, "band6", &data[5 * npix], scan, 0, 0, 0, 1, npix, 1, 1);
218  READ_SDS_ID(sd_id, "band7", &data[6 * npix], scan, 0, 0, 0, 1, npix, 1, 1);
219  READ_SDS_ID(sd_id, "band8", &data[7 * npix], scan, 0, 0, 0, 1, npix, 1, 1);
220 
221  for (ip = 0; ip < npix; ip++) {
222  for (ib = 0; ib < l1rec->l1file->nbands; ib++) {
223  ipb = ip * l1rec->l1file->nbands + ib;
224  l1rec->Lt[ipb] = (float) data[ib * npix + ip] / (float) factor[ib];
225  if (data[ib * npix + ip] == 0 || data[ipb] == 65535) {
226  l1rec->hilt[ip] = 1;
227  l1rec->Lt[ipb] = 1000.0;
228  }
229  }
230  if (l1rec->lon[ip] < -181.0 || l1rec->lon[ip] > 181.0 ||
231  l1rec->lat[ip] < -91.0 || l1rec->lat[ip] > 91.0)
232  l1rec->navfail[ip] = 1;
233  }
234 
235  l1rec->scantime = yds2unix(syear, sday, (double) ((smsec + scan * dmsec) / 1.e3));
236 
237  l1rec->npix = file->npix;
238 
239  return (0);
240 }
241 
242 int closel1_ocm_hdf(filehandle *file) {
243  if (SDend(file->sd_id)) {
244  fprintf(stderr, "-E- %s line %d: SDend(%d) failed for file, %s.\n",
245  __FILE__, __LINE__, file->sd_id, file->name);
246  exit(1);
247  }
248 
249  return (0);
250 }
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
#define FAIL
Definition: ObpgReadGrid.h:18
int readl1_ocm_hdf(filehandle *file, int32_t scan, l1str *l1rec)
Definition: l1_ocm_hdf.c:57
#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 closel1_ocm_hdf(filehandle *file)
Definition: l1_ocm_hdf.c:242
int openl1_ocm_hdf(filehandle *file)
Definition: l1_ocm_hdf.c:18
subroutine spline(s, x, y, n, in, t, il, iu, vl, vu, e, u)
Definition: phs.f:1348
int syear
Definition: l1_czcs_hdf.c:15
int32 nscan
Definition: l1_czcs_hdf.c:19
int32 smsec
Definition: l1_czcs_hdf.c:16
#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
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
int sday
Definition: l1_czcs_hdf.c:15
int getHDFattr(int32_t fileID, const char attrname[], const char sdsname[], void *data)
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
subroutine splint(xa, ya, y2a, n, x, y)
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