MISR Toolkit  1.5.1
MtkReadL1B2.c
Go to the documentation of this file.
1 /*===========================================================================
2 = =
3 = MtkReadL1B2 =
4 = =
5 =============================================================================
6 
7  Jet Propulsion Laboratory
8  MISR
9  MISR Toolkit
10 
11  Copyright 2005, California Institute of Technology.
12  ALL RIGHTS RESERVED.
13  U.S. Government Sponsorship acknowledged.
14 
15 ============================================================================*/
16 
17 #include "MisrReadData.h"
18 #include "MisrFileQuery.h"
19 #include "MisrUtil.h"
20 #include "MisrError.h"
21 #include <string.h>
22 #include <ctype.h>
23 /* M_PI is not defined in math.h in Linux unless __USE_BSD is defined */
24 /* and you can define it at the gcc command-line if -ansi is set */
25 #ifndef __USE_BSD
26 # define __USE_BSD
27 #endif
28 #include <math.h>
29 #include <hdf.h>
30 #include <HdfEosDef.h>
31 
42  const char *filename,
43  const char *gridname,
44  const char *fieldname,
45  MTKt_Region region,
46  MTKt_DataBuffer *databuf,
47  MTKt_MapInfo *mapinfo )
48 {
49  MTKt_status status; /* Return status */
50  MTKt_status status_code; /* Return status code for error macros */
51  int32 fid = FAIL; /* HDF-EOS File id */
52  intn hdfstatus; /* HDF return status */
53 
54  if (filename == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
55 
56  /* Open file. */
57  fid = GDopen((char*)filename, DFACC_READ);
59 
60  /* Read data. */
61  status = MtkReadL1B2Fid(fid, gridname, fieldname, region, databuf, mapinfo);
62  MTK_ERR_COND_JUMP(status);
63 
64  /* Close file. */
65  hdfstatus = GDclose(fid);
67  fid = FAIL;
68 
69  return MTK_SUCCESS;
70  ERROR_HANDLE:
71  if (fid != FAIL) GDclose(fid);
72  return status_code;
73 }
74 
82  int32 fid,
83  const char *gridname,
84  const char *fieldname,
85  MTKt_Region region,
86  MTKt_DataBuffer *databuf,
87  MTKt_MapInfo *mapinfo )
88 {
89  MTKt_status status; /* Return status */
90  MTKt_status status_code; /* Return status code for error macros */
91  MTKt_FileType filetype; /* File type */
93  /* Temp Map info structure */
95  /* Map info structure */
97  /* Data buffer structure */
99  /* Radiance/RDQI Data buffer structure */
101  /* Brf conversion factor */
103  /* Radiance scale factor */
105  /* Radiance fill_value */
106  MTKt_DataBuffer solar_irradiance = MTKT_DATABUFFER_INIT;
107  /* Solar Irradiance */
108  MTKt_DataBuffer sun_distance_au = MTKT_DATABUFFER_INIT;
109  /* Sun distance in AU */
110  double sun_distance_au_squared; /* Sun distance squared (AU) */
111  char grid[MAXSTR]; /* Grid to read */
112  char field[MAXSTR]; /* Field to read */
113  char fieldstr[MAXSTR]; /* Field string */
114  char *fieldarr[2]; /* Field array */
115  char *sp; /* Pointer to string */
116  int lf; /* Line index scale factor */
117  int sf; /* Sample index scale factor */
118  int l; /* Line index */
119  int s; /* Sample index */
120 
121  if (gridname == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
122  if (fieldname == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
123 
124  /* ---------------------------------------------------------- */
125  /* Parse fieldname to determine unpacking or unscaling method */
126  /* ---------------------------------------------------------- */
127 
128  /* Make a working copy of fieldname */
129  strncpy(fieldstr, fieldname, MAXSTR);
130  fieldarr[0] = fieldstr;
131 
132  /* Separate band from base field, point fieldarr[1] to null terminator */
133  /* of fieldstr if there are now spaces in fieldstr, else just fail */
134  if ((sp = strchr(fieldstr, ' ')) != NULL) {
135  *sp = '\0';
136  fieldarr[1] = ++sp;
137 
138  /* Convert to lower case for comparison */
139  while (*sp != '\0') {
140  *sp = (char)tolower((int)*sp);
141  sp++;
142  }
143  } else if ((sp = strchr(fieldstr, '\0')) != NULL) {
144  fieldarr[1] = sp;
145  } else {
147  }
148 
149  /* ------------------------------------------------------- */
150  /* Determine which unpacking or unscaling method and do it */
151  /* ------------------------------------------------------- */
152 
153  if (strncmp(fieldarr[1], "radiance", MAXSTR) == 0) {
154 
155  /* Radiance */
156 
157  field[0] = '\0';
158  strncat(field, fieldarr[0], MAXSTR);
159  strncat(field, " ", MAXSTR);
160  strncat(field, "Radiance/RDQI", MAXSTR);
161 
162  status = MtkReadRawFid(fid, gridname, field, region, &radrdqi, &map);
163  MTK_ERR_COND_JUMP(status);
164 
165  status = MtkFillValueGetFid(fid, gridname, field, &fill_value);
166  MTK_ERR_COND_JUMP(status);
167 
168  /* If filetype is TERRAIN adjust fill value to account for obscured by
169  topography flag. */
170  status = MtkFileTypeFid(fid, &filetype);
171  MTK_ERR_COND_JUMP(status);
172  if (filetype == MTK_GRP_TERRAIN_GM || filetype == MTK_GRP_TERRAIN_LM)
173  fill_value.data.u16[0][0] -= 4;
174 
175  status = MtkDataBufferAllocate(radrdqi.nline, radrdqi.nsample, MTKe_float,
176  &buf);
177  MTK_ERR_COND_JUMP(status);
178 
179  status = MtkGridAttrGetFid(fid, gridname, "Scale factor", &scale_factor);
180  MTK_ERR_COND_JUMP(status);
181 
182  for (l = 0; l < buf.nline; l++) {
183  for (s = 0; s < buf.nsample; s++) {
184  if (radrdqi.data.u16[l][s] < fill_value.data.u16[0][0]) {
185  buf.data.f[l][s] = (MTKt_float)((radrdqi.data.u16[l][s] >> 2) *
186  scale_factor.data.d[0][0]);
187  } else {
188  buf.data.f[l][s] = 0.0;
189  }
190  }
191  }
192 
193  MtkDataBufferFree(&radrdqi);
194  MtkDataBufferFree(&scale_factor);
195  MtkDataBufferFree(&fill_value);
196 
197  } else if (strncmp(fieldarr[1], "scaled radiance", MAXSTR) == 0 ||
198  strncmp(fieldarr[1], "dn", MAXSTR) == 0) {
199 
200  /* Scaled Radiance (DN) */
201 
202  field[0] = '\0';
203  strncat(field, fieldarr[0], MAXSTR);
204  strncat(field, " ", MAXSTR);
205  strncat(field, "Radiance/RDQI", MAXSTR);
206 
207  status = MtkReadRawFid(fid, gridname, field, region, &buf, &map);
208  MTK_ERR_COND_JUMP(status);
209 
210  status = MtkFillValueGetFid(fid, gridname, field, &fill_value);
211  MTK_ERR_COND_JUMP(status);
212 
213  /* If filetype is TERRAIN adjust fill value to account for obscured by
214  topography flag. */
215  status = MtkFileTypeFid(fid, &filetype);
216  MTK_ERR_COND_JUMP(status);
217  if (filetype == MTK_GRP_TERRAIN_GM || filetype == MTK_GRP_TERRAIN_LM)
218  fill_value.data.u16[0][0] -= 4;
219 
220  for (l = 0; l < buf.nline; l++) {
221  for (s = 0; s < buf.nsample; s++) {
222  if (buf.data.u16[l][s] < fill_value.data.u16[0][0]) {
223  buf.data.u16[l][s] = buf.data.u16[l][s] >> 2;
224  } else {
225  buf.data.u16[l][s] = 0;
226  }
227  }
228  }
229 
230  MtkDataBufferFree(&fill_value);
231 
232  } else if (strncmp(fieldarr[1], "rdqi", MAXSTR) == 0) {
233 
234  /* RDQI */
235 
236  field[0] = '\0';
237  strncat(field, fieldarr[0], MAXSTR);
238  strncat(field, " ", MAXSTR);
239  strncat(field, "Radiance/RDQI", MAXSTR);
240 
241  status = MtkReadRawFid(fid, gridname, field, region, &radrdqi, &map);
242  MTK_ERR_COND_JUMP(status);
243 
244  status = MtkDataBufferAllocate(radrdqi.nline, radrdqi.nsample, MTKe_uint8,
245  &buf);
246  MTK_ERR_COND_JUMP(status);
247 
248  for (l = 0; l < buf.nline; l++) {
249  for (s = 0; s < buf.nsample; s++) {
250  buf.data.u8[l][s] = (MTKt_uint8)(radrdqi.data.u16[l][s] & 0x0003);
251  }
252  }
253 
254  MtkDataBufferFree(&radrdqi);
255 
256  } else if (strncmp(fieldarr[1], "equivalent reflectance", MAXSTR) == 0) {
257 
258  /* Equivalent Reflectance */
259 
260  field[0] = '\0';
261  strncat(field, fieldarr[0], MAXSTR);
262  strncat(field, " ", MAXSTR);
263  strncat(field, "Radiance/RDQI", MAXSTR);
264 
265  status = MtkReadRawFid(fid, gridname, field, region, &radrdqi, &map);
266  MTK_ERR_COND_JUMP(status);
267 
268  status = MtkFillValueGetFid(fid, gridname, field, &fill_value);
269  MTK_ERR_COND_JUMP(status);
270 
271  /* If filetype is TERRAIN adjust fill value to account for obscured by
272  topography flag. */
273  status = MtkFileTypeFid(fid, &filetype);
274  MTK_ERR_COND_JUMP(status);
275  if (filetype == MTK_GRP_TERRAIN_GM || filetype == MTK_GRP_TERRAIN_LM)
276  fill_value.data.u16[0][0] -= 4;
277 
278  status = MtkDataBufferAllocate(radrdqi.nline, radrdqi.nsample, MTKe_float,
279  &buf);
280  MTK_ERR_COND_JUMP(status);
281 
282  status = MtkGridAttrGetFid(fid, gridname, "Scale factor", &scale_factor);
283  MTK_ERR_COND_JUMP(status);
284 
285  status = MtkGridAttrGetFid(fid, gridname, "std_solar_wgted_height",
286  &solar_irradiance);
287  MTK_ERR_COND_JUMP(status);
288 
289  status = MtkGridAttrGetFid(fid, gridname, "SunDistanceAU",
290  &sun_distance_au);
291  MTK_ERR_COND_JUMP(status);
292 
293  sun_distance_au_squared = sun_distance_au.data.d[0][0] *
294  sun_distance_au.data.d[0][0];
295 
296  for (l = 0; l < buf.nline; l++) {
297  for (s = 0; s < buf.nsample; s++) {
298  if (radrdqi.data.u16[l][s] < fill_value.data.u16[0][0]) {
299  buf.data.f[l][s] = (MTKt_float)(M_PI * sun_distance_au_squared *
300  ((radrdqi.data.u16[l][s] >> 2) *
301  scale_factor.data.d[0][0]) /
302  solar_irradiance.data.f[0][0]);
303  } else {
304  buf.data.f[l][s] = 0.0;
305  }
306  }
307  }
308 
309  MtkDataBufferFree(&radrdqi);
310  MtkDataBufferFree(&scale_factor);
311  MtkDataBufferFree(&fill_value);
312  MtkDataBufferFree(&solar_irradiance);
313  MtkDataBufferFree(&sun_distance_au);
314 
315  } else if (strncmp(fieldarr[1], "brf", MAXSTR) == 0) {
316 
317  /* Brf */
318 
319  field[0] = '\0';
320  strncat(field, fieldarr[0], MAXSTR);
321  strncat(field, " ", MAXSTR);
322  strncat(field, "Radiance/RDQI", MAXSTR);
323 
324  status = MtkReadRawFid(fid, gridname, field, region, &radrdqi, &map);
325  MTK_ERR_COND_JUMP(status);
326 
327  status = MtkFillValueGetFid(fid, gridname, field, &fill_value);
328  MTK_ERR_COND_JUMP(status)
329 
330  /* If filetype is TERRAIN adjust fill value to account for obscured by
331  topography flag. */
332  status = MtkFileTypeFid(fid, &filetype);
333  MTK_ERR_COND_JUMP(status);
334  if (filetype == MTK_GRP_TERRAIN_GM || filetype == MTK_GRP_TERRAIN_LM)
335  fill_value.data.u16[0][0] -= 4;
336 
337  grid[0] = '\0';
338  strncat(grid, "BRF Conversion Factors", MAXSTR);
339  field[0] = '\0';
340  strncat(field, fieldarr[0], MAXSTR);
341  strncat(field, "ConversionFactor", MAXSTR);
342 
343  status = MtkReadRawFid(fid, grid, field, region, &conv_factor, &tmpmap);
344  MTK_ERR_COND_JUMP(status);
345 
346  status = MtkDataBufferAllocate(radrdqi.nline, radrdqi.nsample, MTKe_float,
347  &buf);
348  MTK_ERR_COND_JUMP(status);
349 
350  status = MtkGridAttrGetFid(fid, gridname, "Scale factor", &scale_factor);
351  MTK_ERR_COND_JUMP(status)
352 
353  lf = radrdqi.nline / conv_factor.nline;
354  sf = radrdqi.nsample / conv_factor.nsample;
355  for (l = 0; l < buf.nline; l++) {
356  for (s = 0; s < buf.nsample; s++) {
357  if (radrdqi.data.u16[l][s] < fill_value.data.u16[0][0] &&
358  conv_factor.data.f[l/lf][s/sf] > 0.0) {
359  buf.data.f[l][s] = (MTKt_float)((radrdqi.data.u16[l][s] >> 2) *
360  scale_factor.data.d[0][0] *
361  conv_factor.data.f[l/lf][s/sf]);
362  } else {
363  buf.data.f[l][s] = 0.0;
364  }
365  }
366  }
367 
368  MtkDataBufferFree(&radrdqi);
369  MtkDataBufferFree(&conv_factor);
370  MtkDataBufferFree(&scale_factor);
371  MtkDataBufferFree(&fill_value);
372 
373  } else {
374 
375  /* Native Radiance/RDQI or Geometric Parameters */
376 
377  status = MtkReadRawFid(fid, gridname, fieldname, region, &buf, &map);
378  MTK_ERR_COND_JUMP(status);
379 
380  }
381 
382  *databuf = buf;
383  *mapinfo = map;
384 
385  return MTK_SUCCESS;
386  ERROR_HANDLE:
387  MtkDataBufferFree(&radrdqi);
388  MtkDataBufferFree(&conv_factor);
389  MtkDataBufferFree(&scale_factor);
390  MtkDataBufferFree(&fill_value);
391  MtkDataBufferFree(&buf);
392  MtkDataBufferFree(&solar_irradiance);
393  MtkDataBufferFree(&sun_distance_au);
394  return status_code;
395 }
MTKt_double ** d
Definition: MisrUtil.h:94
MTKt_status MtkDataBufferAllocate(int nline, int nsample, MTKt_DataType datatype, MTKt_DataBuffer *databuf)
Allocate Data Buffer.
#define DFACC_READ
Definition: hdf.h:44
char * filename
Definition: cdjpeg.h:133
MTKt_DataBufferType data
Definition: MisrUtil.h:104
MTKt_status MtkReadL1B2(const char *filename, const char *gridname, const char *fieldname, MTKt_Region region, MTKt_DataBuffer *databuf, MTKt_MapInfo *mapinfo)
Reads, unpacks and unscales any L1B2 grid/field from a MISR L1B2 product file.
Definition: MtkReadL1B2.c:41
intn GDclose(int32)
char int scale_factor
Definition: cdjpeg.h:133
#define MTKT_MAPINFO_INIT
Definition: MisrMapQuery.h:79
#define MTK_ERR_CODE_JUMP(code)
Definition: MisrError.h:175
MTKt_FileType
Definition: MisrFileQuery.h:24
Map Information.
Definition: MisrMapQuery.h:65
2-dimensional Data Buffer
Definition: MisrUtil.h:98
MTKt_float ** f
Definition: MisrUtil.h:93
#define MTKT_DATABUFFER_INIT
Definition: MisrUtil.h:109
MTKt_status MtkFillValueGetFid(int32 fid, const char *gridname, const char *fieldname, MTKt_DataBuffer *fillbuf)
Version of MtkFillValueGet that takes an HDF-EOS file ID rather than a filename.
MTKt_status MtkDataBufferFree(MTKt_DataBuffer *databuf)
Free data buffer.
MTKt_uint8 ** u8
Definition: MisrUtil.h:86
u_int8_t MTKt_uint8
Definition: MisrUtil.h:69
MTKt_status MtkGridAttrGetFid(int32 fid, const char *gridname, const char *attrname, MTKt_DataBuffer *attrbuf)
Version of MtkFileGridAttrGet that takes an HDF-EOS file ID rather than a filename.
MTKt_uint16 ** u16
Definition: MisrUtil.h:88
MTKt_status MtkReadL1B2Fid(int32 fid, const char *gridname, const char *fieldname, MTKt_Region region, MTKt_DataBuffer *databuf, MTKt_MapInfo *mapinfo)
Version of MtkReadL1B2 that takes an HDF-EOS file identifier rather than a filename. MISR L1B2 product file.
Definition: MtkReadL1B2.c:81
MTKt_status MtkReadRawFid(int32 fid, const char *gridname, const char *fieldname, MTKt_Region region, MTKt_DataBuffer *databuf, MTKt_MapInfo *mapinfo)
Version of MtkReadRaw that takes an HDF-EOS file identifier rather than a filename.
Definition: MtkReadRaw.c:141
float MTKt_float
Definition: MisrUtil.h:76
#define MAXSTR
Definition: MisrUtil.h:28
#define MTK_ERR_COND_JUMP(code)
Definition: MisrError.h:188
MTKt_status
Definition: MisrError.h:11
Region of interest.
Definition: MisrSetRegion.h:41
int32 GDopen(char *, intn)
MTKt_status MtkFileTypeFid(int32 Fid, MTKt_FileType *filetype)
Version of MtkFileType that takes an HDF-EOS file identifier rather than a filename.
Definition: MtkFileType.c:119
HDFFCLIBAPI _fcd field
HDFFCLIBAPI intf * buf
#define FAIL
Definition: hdf.h:94

MISR Toolkit - Copyright © 2005 - 2020 Jet Propulsion Laboratory
Generated on Fri Jun 19 2020 22:49:51