MISR Toolkit  1.5.1
MtkReadConv.c
Go to the documentation of this file.
1 /*===========================================================================
2 = =
3 = MtkReadConv =
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 "MisrCoordQuery.h"
19 #include "MisrMapQuery.h"
20 #include "MisrFileQuery.h"
21 #include "MisrUtil.h"
22 #include "MisrError.h"
23 #include <mfhdf.h>
24 #include <HdfEosDef.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <math.h>
28 
38  const char *filename,
39  const char *gridname,
40  const char *fieldname,
41  MTKt_Region region,
42  MTKt_DataBuffer *databuf,
43  MTKt_MapInfo *mapinfo )
44 {
45  MTKt_status status; /* Return status */
46  MTKt_status status_code; /* Return code of this function */
47  int32 fid = FAIL; /* HDF-EOS File id */
48  intn hdfstatus; /* HDF return status */
49 
50  if (filename == NULL) return MTK_NULLPTR;
51 
52  /* Open file. */
53  fid = GDopen((char*)filename, DFACC_READ);
55 
56  /* Read data. */
57  status = MtkReadConvFid(fid, gridname, fieldname, region, databuf, mapinfo);
58  MTK_ERR_COND_JUMP(status);
59 
60  /* Close file. */
61  hdfstatus = GDclose(fid);
63  fid = FAIL;
64 
65  return MTK_SUCCESS;
66  ERROR_HANDLE:
67  if (fid != FAIL) GDclose(fid);
68  return status_code;
69 }
70 
77  int32 fid,
78  const char *gridname,
79  const char *fieldname,
80  MTKt_Region region,
81  MTKt_DataBuffer *databuf,
82  MTKt_MapInfo *mapinfo )
83 {
84  MTKt_status status; /* Return status */
85  MTKt_status status_code; /* Return code of this function */
87  /* Data buffer structure */
89  /* Temp data buffer structure for file */
91  /* Fill buffer structure */
93  /* Map info structure */
95  /* Map info structure for the file */
96  int path; /* Path */
97  int resolution; /* Resolution */
99  /* ULC SOM coordinates */
101  /* LRC SOM coordinates */
102  double x; /* Som X */
103  int ulc_line; /* ULC Line */
104  int ulc_sample; /* ULC Sample */
105  int lrc_line; /* LRC Line */
106  int lrc_sample; /* LRC Sample */
107  float line; /* Line */
108  float sample; /* Sample */
109  int nline; /* Number of line */
110  int nsample; /* Number of sample */
111  int l; /* Line index */
112  int s; /* Sample index */
113  MTKt_DataType datatype; /* Datatype */
114  intn hdfstatus; /* HDF-EOS return status */
115  int32 gid = FAIL; /* HDF-EOS Grid id */
116  int32 start[10]; /* HDF-EOS start dimension */
117  int32 start_copy[10]; /* HDF-EOS start dimension copy*/
118  int32 edge[10]; /* HDF-EOS edge dimension */
119  int32 edge_copy[10]; /* HDF-EOS edge dimension copy */
120  int32 hdf_datatype; /* HDF-EOS data type */
121  int32 rank; /* HDF-EOS rank */
122  int32 dims[10]; /* HDF-EOS dimensions */
123  int32 dims_copy[10]; /* HDF-EOS dimensions copy */
124  char dimlist[80]; /* HDF-EOS dimension name list */
125  char *basefield = NULL; /* Base fieldname */
126  int nextradims; /* Number of extra dimensions */
127  int *extradims = NULL; /* Extra dimension list */
128  int dims_reversed = 0; /* Whether the dims are "reversed"*/
129  int i; /* Loop index */
130  int32 xdimsize; /* X dimension size of file */
131  int32 ydimsize; /* Y dimension size of file */
132  float64 ulc[2]; /* Upper left corner in meters */
133  float64 lrc[2]; /* Lower right corner in meters */
134  char *dataptr; /* Data pointer */
135  int32 HDFfid; /* HDF file identifier (not used) */
136  int32 sid; /* HDF SD identifier */
137 
138  if (gridname == NULL) return MTK_NULLPTR;
139  if (fieldname == NULL) return MTK_NULLPTR;
140 
141  /* Get the HDF SD identifier. */
142  hdfstatus = EHidinfo(fid, &HDFfid, &sid);
143  if (hdfstatus == FAIL)
145 
146  /* Determine path of this file */
147  status = MtkFileToPathFid(sid, &path);
148  MTK_ERR_COND_JUMP(status);
149 
150  /* Determine resolution from file and gridname */
151  status = MtkFileGridToResolutionFid(fid, gridname, &resolution);
152  MTK_ERR_COND_JUMP(status);
153 
154  /* Snap region to som grid for this path */
155  status = MtkSnapToGrid(path, resolution, region, &map);
156  MTK_ERR_COND_JUMP(status);
157 
158  /* Attach to grid */
159  gid = GDattach(fid, (char*)gridname);
161 
162  /* Get grid info */
163  hdfstatus = GDgridinfo(gid, &xdimsize, &ydimsize, ulc, lrc);
165 
166  /* Parse fieldname for extra dimensions */
167  status = MtkParseFieldname(fieldname, &basefield, &nextradims, &extradims);
168  MTK_ERR_COND_JUMP(status);
169 
170  /* Determine rank, dimensions and datatype of the field */
171  hdfstatus = GDfieldinfo(gid, basefield, &rank, dims, &hdf_datatype, dimlist);
173 
174  /* If dimlist doesn't start with an X for XDim, assume dims are from MISR HR */
175  /* Band,Camera,XDim,YDim should be XDim,YDim,Band,Camera */
176  if (dimlist[0] != 'X') {
177  /* XDim */
178  dims_copy[0] = dims[rank - 2];
179  /* YDim */
180  dims_copy[1] = dims[rank - 1];
181  /* Remaining, shifted by two */
182  for (i = 2; i < rank; i++) {
183  dims_copy[i] = dims[i - 2];
184  }
185  for (i = 0; i < rank; i++) {
186  dims[i] = dims_copy[i];
187  }
188  dims_reversed = 1;
189  }
190 
191  /* Check range against extra dimensions */
192  if (rank != nextradims + 2) MTK_ERR_CODE_JUMP(MTK_BAD_ARGUMENT);
193 
194  /* Convert hdf datatype to mtk datatype */
195  status = MtkHdfToMtkDataTypeConvert(hdf_datatype, &datatype);
196  MTK_ERR_COND_JUMP(status);
197 
198  /* Create a map structure for the contents of the file, then we can */
199  /* determine the coordinates of the intersecting map area we need to load */
200  /* Note - ulc y and lrc y are flipped. */
201  mapfile = map;
202  mapfile.nline = dims[0];
203  mapfile.nsample = dims[1];
204  mapfile.som.ulc.x = ulc[0];
205  mapfile.som.ulc.y = lrc[1];
206  mapfile.som.lrc.x = lrc[0];
207  mapfile.som.lrc.y = ulc[1];
208  mapfile.som.ctr.x = mapfile.som.ulc.x +
209  ((mapfile.som.lrc.x - mapfile.som.ulc.x) / 2.0);
210  mapfile.som.ctr.y = mapfile.som.ulc.y +
211  ((mapfile.som.lrc.y - mapfile.som.ulc.y) / 2.0);
212 
213  /* Determine ulc line and sample of intersecting area. */
214  /* If out of bounds then clip to size of file coordinates. */
215  /* The status of this routine can be ignored because we catch */
216  /* out of bounds when line or sample is -1.0. */
217  /* Also, subtract half a pixel to center coordinate. */
218  MtkSomXYToLS(mapfile, map.som.ulc.x, map.som.ulc.y, &line, &sample);
219 
220  line -= 0.5;
221  sample -= 0.5;
222 
223  if (line < 0.0) ulc_line = 0;
224  else ulc_line = (int)line;
225 
226  if (sample < 0.0) ulc_sample = 0;
227  else ulc_sample = (int)sample;
228 
229  /* Determine som x/y coordinates of ulc intersecting coordinate */
230  status = MtkLSToSomXY(mapfile, (float)(ulc_line + 0.5), (float)(ulc_sample + 0.5), &ulc_som.x, &ulc_som.y);
231  MTK_ERR_COND_JUMP(status);
232 
233  /* Determine lrc line and sample of intersecting area */
234  /* If out of bounds then clip to size of file coordinates. */
235  /* The status of this routine can be ignored because we catch */
236  /* out of bounds when line or sample is -1.0. */
237  /* Also, subtract half a pixel to center coordinate. */
238  MtkSomXYToLS(mapfile, map.som.lrc.x, map.som.lrc.y, &line, &sample);
239 
240  line -= 0.5;
241  sample -= 0.5;
242 
243  if (line < 0.0) lrc_line = dims[0] - 1;
244  else lrc_line = (int)line;
245 
246  if (sample < 0.0) lrc_sample = dims[1] - 1;
247  else lrc_sample = (int)sample;
248 
249  /* Determine som x/y coordinates of lrc intersecting coordinate */
250  status = MtkLSToSomXY(mapfile, (float)(lrc_line + 0.5), (float)(lrc_sample + 0.5), &lrc_som.x, &lrc_som.y);
251  MTK_ERR_COND_JUMP(status);
252 
253  /* Determine number of lines and samples of the intersecting area to load */
254  nline = lrc_line - ulc_line + 1;
255  nsample = lrc_sample - ulc_sample + 1;
256 
257  start[0] = ulc_line;
258  start[1] = ulc_sample;
259 
260  edge[0] = nline;
261  edge[1] = nsample;
262 
263  for (i = 2; i < rank; i++) {
264  start[i] = extradims[i-2];
265  edge[i] = 1;
266  }
267 
268  /* Dims didn't start with XDim, assuming MISR HR format */
269  if (dims_reversed) {
270  /* XDim */
271  start_copy[rank - 2] = start[0];
272  edge_copy[rank - 2] = edge[0];
273  /* YDim */
274  start_copy[rank - 1] = start[1];
275  edge_copy[rank - 1] = edge[1];
276  /* Remaining, shifted by two */
277  for (i = 0; i < rank - 2; i++) {
278  start_copy[i] = start[i + 2];
279  edge_copy[i] = edge[i + 2];
280  }
281  for (i = 0; i < rank; i++) {
282  start[i] = start_copy[i];
283  edge[i] = edge_copy[i];
284  }
285  }
286 
287  /* Allocate the temp data buffer */
288  status = MtkDataBufferAllocate(nline, nsample, datatype, &filebuf_tmp);
289  MTK_ERR_COND_JUMP(status);
290 
291  /* Read field data */
292  hdfstatus = GDreadfield(gid, basefield, start, NULL, edge,
293  filebuf_tmp.dataptr);
295 
296  /* Detach from grid */
297  hdfstatus = GDdetach(gid);
299 
300  /* Allocate the data buffer */
301  status = MtkDataBufferAllocate(map.nline, map.nsample, datatype, &buf);
302  MTK_ERR_COND_JUMP(status);
303 
304  /* Get fill value and prefill buffer only if a fill value is defined */
305  status = MtkFillValueGetFid(fid, gridname, fieldname, &fill);
306  if (status == MTK_SUCCESS) {
307  dataptr = (char *)buf.dataptr;
308  for (l = 0; l < map.nline; l++) {
309  for (s = 0; s < map.nsample; s++) {
310  memcpy((void *)dataptr, fill.dataptr, buf.datasize);
311  dataptr += buf.datasize;
312  }
313  }
314  MtkDataBufferFree(&fill);
315  }
316 
317  /* Copy intersecting region to output buffer */
318  i = 0;
319  for (x = ulc_som.x; x <= lrc_som.x; x += map.resolution) {
320  MtkSomXYToLS(map, x, ulc_som.y, &line, &sample);
321  memcpy((void *)&(buf.data.u8[(int)line][(int)sample]),
322  (void *)&(filebuf_tmp.data.u8[i++][0]),
323  nsample * buf.datasize);
324  }
325 
326  free(basefield);
327  free(extradims);
328  MtkDataBufferFree(&filebuf_tmp);
329 
330  *databuf = buf;
331  *mapinfo = map;
332 
333  return MTK_SUCCESS;
334  ERROR_HANDLE:
335  if (gid != FAIL) GDdetach(gid);
336  if (basefield != NULL) free(basefield);
337  if (extradims != NULL) free(extradims);
338  MtkDataBufferFree(&filebuf_tmp);
339  MtkDataBufferFree(&buf);
340  return status_code;
341 }
SOM Coordinates.
Definition: MisrMapQuery.h:33
MTKt_status MtkReadConv(const char *filename, const char *gridname, const char *fieldname, MTKt_Region region, MTKt_DataBuffer *databuf, MTKt_MapInfo *mapinfo)
Reads any grid/field from a MISR conventional product file.
Definition: MtkReadConv.c:37
MTKt_status MtkDataBufferAllocate(int nline, int nsample, MTKt_DataType datatype, MTKt_DataBuffer *databuf)
Allocate Data Buffer.
HDFFCLIBAPI _fcd _fcd intf intf * datatype
int32 GDattach(int32, char *)
#define DFACC_READ
Definition: hdf.h:44
char * filename
Definition: cdjpeg.h:133
MTKt_DataBufferType data
Definition: MisrUtil.h:104
intn GDclose(int32)
MTKt_DataType
Definition: MisrUtil.h:36
#define MTKT_MAPINFO_INIT
Definition: MisrMapQuery.h:79
MTKt_status MtkLSToSomXY(MTKt_MapInfo mapinfo, float line, float sample, double *som_x, double *som_y)
Convert line, sample to SOM X, SOM Y.
Definition: MtkLSToSomXY.c:33
HDFFCLIBAPI void intf dims[]
double ulc[2]
Definition: misr_init.c:9
MTKt_status MtkParseFieldname(const char *fieldname, char **basefieldname, int *ndim, int **dimlist)
Parses extra dimensions from fieldnames.
#define MTK_ERR_CODE_JUMP(code)
Definition: MisrError.h:175
Map Information.
Definition: MisrMapQuery.h:65
intn GDdetach(int32)
2-dimensional Data Buffer
Definition: MisrUtil.h:98
MTKt_status MtkReadConvFid(int32 fid, const char *gridname, const char *fieldname, MTKt_Region region, MTKt_DataBuffer *databuf, MTKt_MapInfo *mapinfo)
Version of MtkReadConv that takes an HDF-EOS file identifier rather than a filename.
Definition: MtkReadConv.c:76
MTKt_status MtkHdfToMtkDataTypeConvert(int32 hdf_datatype, MTKt_DataType *datatype)
Convert HDF data type to MISR Toolkit data type.
#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.
void * dataptr
Definition: MisrUtil.h:106
MTKt_status MtkDataBufferFree(MTKt_DataBuffer *databuf)
Free data buffer.
MTKt_status MtkSomXYToLS(MTKt_MapInfo mapinfo, double som_x, double som_y, float *line, float *sample)
Convert SOM X, SOM Y to line, sample.
Definition: MtkSomXYToLS.c:32
double lrc[2]
Definition: misr_init.c:10
MTKt_uint8 ** u8
Definition: MisrUtil.h:86
intn GDgridinfo(int32, int32 *, int32 *, float64 [], float64 [])
intn GDfieldinfo(int32, char *, int32 *, int32 [], int32 *, char *)
MTKt_status MtkFileToPathFid(int32 sid, int *path)
Version of MtkFileToPath that takes an HDF SD identifier rather than a filename.
#define MTKT_SOMCOORD_INIT
Definition: MisrMapQuery.h:38
intn EHidinfo(int32, int32 *, int32 *)
MTKt_SomCoord lrc
Definition: MisrMapQuery.h:58
HDFFCLIBAPI intf intf start[]
MTKt_SomCoord ctr
Definition: MisrMapQuery.h:57
MTKt_status MtkSnapToGrid(int path, int resolution, MTKt_Region region, MTKt_MapInfo *mapinfo)
Snap a region to a MISR grid based on path number and resolution.
Definition: MtkSnapToGrid.c:40
intn GDreadfield(int32, char *, int32 [], int32 [], int32 [], VOIDP)
#define MTK_ERR_COND_JUMP(code)
Definition: MisrError.h:188
MTKt_status
Definition: MisrError.h:11
MTKt_SomRegion som
Definition: MisrMapQuery.h:74
Region of interest.
Definition: MisrSetRegion.h:41
HDFFCLIBAPI intf * rank
int32 GDopen(char *, intn)
int const JOCTET * dataptr
Definition: jpeglib.h:950
MTKt_status MtkFileGridToResolutionFid(int32 fid, const char *gridname, int *resolution)
Version of MtkFileGridToResolution that takes an HDF-EOS file id rather than a filename.
HDFFCLIBAPI intf * buf
MTKt_SomCoord ulc
Definition: MisrMapQuery.h:56
#define FAIL
Definition: hdf.h:94

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