MISR Toolkit  1.5.1
MtkReadBlockRange.c
Go to the documentation of this file.
1 /*===========================================================================
2 = =
3 = MtkReadBlockRange =
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 "MisrUtil.h"
19 #include "MisrError.h"
20 #include <stdlib.h>
21 #include <mfhdf.h>
22 #include <HdfEosDef.h>
23 
52  const char *filename,
53  const char *gridname,
54  const char *fieldname,
55  int startblock,
56  int endblock,
57  MTKt_DataBuffer3D *databuf )
58 {
59  MTKt_status status; /* Return status */
60 
61  status = MtkReadBlockRangeNC(filename, gridname, fieldname, startblock, endblock, databuf); // try netCDF
62  if (status != MTK_NETCDF_OPEN_FAILED) return status;
63 
64  return MtkReadBlockRangeHDF(filename, gridname, fieldname, startblock, endblock, databuf); // try HDF
65 }
66 
68  const char *filename,
69  const char *gridname,
70  const char *fieldname,
71  int startblock,
72  int endblock,
73  MTKt_DataBuffer3D *databuf )
74 {
75  MTKt_status status;
76  MTKt_status status_code;
77  int ncid = 0;
78 
79  if (filename == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
80 
81  /* Open file */
82  {
83  int nc_status = nc_open(filename, NC_NOWRITE, &ncid);
85  }
86 
87  /* Read block. */
88  status = MtkReadBlockRangeNcid(ncid, gridname, fieldname,
89  startblock, endblock, databuf);
90  MTK_ERR_COND_JUMP(status);
91 
92  /* Close file */
93  {
94  int nc_status = nc_close(ncid);
96  }
97  ncid = 0;
98 
99  return MTK_SUCCESS;
100 
101  ERROR_HANDLE:
102  if (ncid != 0) nc_close(ncid);
103  return status_code;
104 }
105 
107  const char *filename,
108  const char *gridname,
109  const char *fieldname,
110  int startblock,
111  int endblock,
112  MTKt_DataBuffer3D *databuf )
113 {
114  MTKt_status status; /* Return status */
115  MTKt_status status_code; /* Return code of this function */
116  intn hdfstatus; /* HDF-EOS return status */
117  int32 fid = FAIL; /* HDF-EOS File id */
118 
119  if (filename == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
120 
121  /* Open file. */
122  fid = GDopen((char*)filename, DFACC_READ);
124 
125  /* Read data. */
126  status = MtkReadBlockRangeFid(fid, gridname, fieldname,
127  startblock, endblock, databuf);
128  MTK_ERR_COND_JUMP(status);
129 
130  /* Close file. */
131  hdfstatus = GDclose(fid);
133  fid = FAIL;
134 
135  return MTK_SUCCESS;
136  ERROR_HANDLE:
137  if (fid != FAIL) GDclose(fid);
138  return status_code;
139 }
140 
147  int32 fid,
148  const char *gridname,
149  const char *fieldname,
150  int startblock,
151  int endblock,
152  MTKt_DataBuffer3D *databuf )
153 {
154  MTKt_status status; /* Return status */
155  MTKt_status status_code; /* Return code of this function */
156  intn hdfstatus; /* HDF-EOS return status */
157  int32 gid = FAIL; /* HDF-EOS Grid id */
158  int32 start[10]; /* HDF-EOS start dimension */
159  int32 edge[10]; /* HDF-EOS edge dimension */
160  int32 hdf_datatype; /* HDF-EOS data type */
161  int32 rank; /* HDF-EOS rank */
162  int32 dims[10]; /* HDF-EOS dimensions */
163  char dimlist[80]; /* HDF-EOS dimension name list */
164  char *basefield = NULL; /* Base fieldname */
165  int nextradims; /* Number of extra dimensions */
166  int *extradims = NULL; /* Extra dimension list */
168  /* Temp data buffer */
169  MTKt_DataType datatype; /* Mtk data type */
170  int i; /* Loop index */
171  int nblocks; /* Number of blocks */
172 
173  if (gridname == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
174  if (fieldname == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
175  if (startblock < 1 || startblock > 180) MTK_ERR_CODE_JUMP(MTK_OUTBOUNDS);
176  if (endblock < 1 || endblock > 180) MTK_ERR_CODE_JUMP(MTK_OUTBOUNDS);
177  if (endblock < startblock) MTK_ERR_CODE_JUMP(MTK_OUTBOUNDS);
178 
179  nblocks = endblock - startblock + 1;
180 
181  gid = GDattach(fid, (char*)gridname);
183 
184  status = MtkParseFieldname(fieldname, &basefield, &nextradims, &extradims);
185  if (status != MTK_SUCCESS) MTK_ERR_CODE_JUMP(status);
186 
187  hdfstatus = GDfieldinfo(gid, basefield, &rank, dims, &hdf_datatype, dimlist);
189 
190  if (rank != nextradims + 3) MTK_ERR_CODE_JUMP(MTK_BAD_ARGUMENT);
191 
192  status = MtkHdfToMtkDataTypeConvert(hdf_datatype, &datatype);
193  if (status != MTK_SUCCESS) MTK_ERR_CODE_JUMP(status);
194 
195  status = MtkDataBufferAllocate3D(nblocks, dims[1], dims[2], datatype,
196  &databuf_tmp);
197  if (status != MTK_SUCCESS) MTK_ERR_CODE_JUMP(status);
198 
199  start[0] = startblock-1; /* Subtract 1 because of 1-based blk number */
200  start[1] = 0;
201  start[2] = 0;
202 
203  edge[0] = nblocks;
204  edge[1] = dims[1];
205  edge[2] = dims[2];
206 
207  for (i = 3; i < rank; i++) {
208  start[i] = extradims[i-3];
209  edge[i] = 1;
210  }
211 
212  hdfstatus = GDreadfield(gid, basefield, start, NULL, edge,
213  databuf_tmp.dataptr);
215 
216  hdfstatus = GDdetach(gid);
218 
219  *databuf = databuf_tmp;
220 
221  free(basefield);
222  free(extradims);
223  return MTK_SUCCESS;
224  ERROR_HANDLE:
225  if (gid != FAIL) GDdetach(gid);
226  if (basefield != NULL) free(basefield);
227  if (extradims != NULL) free(extradims);
228  MtkDataBufferFree3D(&databuf_tmp);
229  return status_code;
230 }
231 
233  int ncid,
234  const char *gridname,
235  const char *fieldname,
236  int startblock,
237  int endblock,
238  MTKt_DataBuffer3D *databuf )
239 {
240  MTKt_status status; /* Return status */
241  MTKt_status status_code; /* Return code of this function */
242  char *basefield = NULL; /* Base fieldname */
243  int nextradims; /* Number of extra dimensions */
244  int *extradims = NULL; /* Extra dimension list */
246  /* Temp data buffer */
247  MTKt_DataType datatype; /* Mtk data type */
248  int nblocks; /* Number of blocks */
249 
250  if (gridname == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
251  if (fieldname == NULL) MTK_ERR_CODE_JUMP(MTK_NULLPTR);
252  if (startblock < 1 || startblock > 180) MTK_ERR_CODE_JUMP(MTK_OUTBOUNDS);
253  if (endblock < 1 || endblock > 180) MTK_ERR_CODE_JUMP(MTK_OUTBOUNDS);
254  if (endblock < startblock) MTK_ERR_CODE_JUMP(MTK_OUTBOUNDS);
255 
256  nblocks = endblock - startblock + 1;
257 
258  int group_id;
259  {
260  int nc_status = nc_inq_grp_ncid(ncid, gridname, &group_id);
262  }
263 
264  int block_size_x;
265  int block_size_y;
266  int block_start_x[180]; /* 180 maximum size */
267  int block_start_y[180]; /* 180 maximum size */
268 
269  {
270  int nc_status;
271  nc_status = nc_get_att(group_id, NC_GLOBAL, "block_size_in_lines", &block_size_x);
273  nc_status = nc_get_att(group_id, NC_GLOBAL, "block_size_in_samples", &block_size_y);
275 
276  int bvarid;
277  nc_status = nc_inq_varid(group_id, "Block_Number", &bvarid);
279 
280  int dimid[NC_MAX_DIMS];
281  nc_status = nc_inq_var(group_id, bvarid, NULL, NULL, NULL, dimid, NULL);
283 
284  size_t file_number_block;
285  nc_status = nc_inq_dimlen(group_id, dimid[0], &file_number_block);
287 
288  if (file_number_block > 180) { /* 180 block maximum size */
290  }
291 
292  int file_block_numbers[180]; /* 180 block maximum size */
293  nc_status = nc_get_var_int(group_id, bvarid, file_block_numbers);
295 
296  int xvarid;
297  nc_status = nc_inq_varid(group_id, "Block_Start_X_Index", &xvarid);
299 
300  int start_x[180]; /* 180 block maximum size */
301  nc_status = nc_get_var_int(group_id, xvarid, start_x);
303 
304  int yvarid;
305  nc_status = nc_inq_varid(group_id, "Block_Start_Y_Index", &yvarid);
307 
308  int start_y[180]; /* 180 block maximum size */
309  nc_status = nc_get_var_int(group_id, yvarid, start_y);
311 
312  int found = 0;
313  int start_block_index;
314  for (size_t i = 0 ; i < file_number_block ; i++) {
315  if (file_block_numbers[i] == startblock) {
316  found = 1;
317  start_block_index = i;
318  }
319  }
320  if (found == 0) MTK_ERR_CODE_JUMP(MTK_OUTBOUNDS); // Start block is outside file extent
321 
322  found = 0;
323  for (size_t i = 0 ; i < file_number_block ; i++) {
324  if (file_block_numbers[i] == endblock) {
325  found = 1;
326  }
327  }
328  if (found == 0) MTK_ERR_CODE_JUMP(MTK_OUTBOUNDS); // End block is outside file extent
329 
330  for (int i = 0 ; i < nblocks ; i++) {
331  block_start_x[i] = start_x[start_block_index + i];
332  block_start_y[i] = start_y[start_block_index + i];
333  }
334  }
335 
336  status = MtkParseFieldname(fieldname, &basefield, &nextradims, &extradims);
337  if (status != MTK_SUCCESS) MTK_ERR_CODE_JUMP(status);
338 
339  int rank;
340  nc_type nc_datatype;
341  MTKt_ncvarid var;
342 
343  {
344  int nc_status;
345 
346  status = MtkNCVarId(group_id, basefield, &var);
347  MTK_ERR_COND_JUMP(status);
348 
349  nc_status = nc_inq_varndims(var.gid, var.varid, &rank);
351  nc_status = nc_inq_vartype(var.gid, var.varid, &nc_datatype);
353  }
354 
355  if (rank != nextradims + 2) MTK_ERR_CODE_JUMP(MTK_BAD_ARGUMENT);
356 
357  status = MtkNcToMtkDataTypeConvert(nc_datatype, &datatype);
358  if (status != MTK_SUCCESS) MTK_ERR_CODE_JUMP(status);
359 
360  status = MtkDataBufferAllocate3D(nblocks, block_size_x, block_size_y, datatype,
361  &databuf_tmp);
362  if (status != MTK_SUCCESS) MTK_ERR_CODE_JUMP(status);
363 
364  size_t start[10];
365  size_t count[10];
366  size_t unit_size_bytes = block_size_x * block_size_y * databuf_tmp.datasize;
367  count[0] = block_size_x;
368  count[1] = block_size_y;
369 
370  for (int i = 2; i < rank; i++) {
371  start[i] = extradims[i-2];
372  count[i] = 1;
373  }
374 
375  for (int i = 0 ; i < nblocks ; i++) {
376  start[0] = block_start_x[i];
377  start[1] = block_start_y[i];
378  int nc_status = nc_get_vara(var.gid, var.varid, start, count, (char *)(databuf_tmp.dataptr) + i * unit_size_bytes);
380  }
381 
382  *databuf = databuf_tmp;
383 
384  free(basefield);
385  free(extradims);
386  return MTK_SUCCESS;
387  ERROR_HANDLE:
388  if (basefield != NULL) free(basefield);
389  if (extradims != NULL) free(extradims);
390  MtkDataBufferFree3D(&databuf_tmp);
391 
392  return status_code;
393 }
HDFFCLIBAPI intf intf intf * count
MTKt_status MtkNcToMtkDataTypeConvert(nc_type nc_datatype, MTKt_DataType *datatype)
nc_type
Definition: netcdf.h:253
MTKt_status MtkDataBufferAllocate3D(int nblock, int nline, int nsample, MTKt_DataType datatype, MTKt_DataBuffer3D *databuf)
Allocate 3-dimensional Data Buffer (a buffer stack)
HDFFCLIBAPI _fcd _fcd intf intf * datatype
int32 GDattach(int32, char *)
#define DFACC_READ
Definition: hdf.h:44
char * filename
Definition: cdjpeg.h:133
MTKt_status MtkReadBlockRangeNcid(int ncid, const char *gridname, const char *fieldname, int startblock, int endblock, MTKt_DataBuffer3D *databuf)
intn GDclose(int32)
MTKt_DataType
Definition: MisrUtil.h:36
EXTERNL int nc_get_att(int ncid, int varid, const char *name, void *ip)
HDFFCLIBAPI void intf dims[]
MTKt_status MtkParseFieldname(const char *fieldname, char **basefieldname, int *ndim, int **dimlist)
Parses extra dimensions from fieldnames.
EXTERNL int nc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, int *dimidsp, int *nattsp)
#define MTK_ERR_CODE_JUMP(code)
Definition: MisrError.h:175
#define NC_GLOBAL
Definition: netcdf.h:214
intn GDdetach(int32)
MTKt_status MtkHdfToMtkDataTypeConvert(int32 hdf_datatype, MTKt_DataType *datatype)
Convert HDF data type to MISR Toolkit data type.
#define NC_NOERR
Definition: netcdf.h:313
3-dimensional Data Buffer
Definition: MisrUtil.h:129
MTKt_status MtkReadBlockRange(const char *filename, const char *gridname, const char *fieldname, int startblock, int endblock, MTKt_DataBuffer3D *databuf)
Read range of blocks of data into a 3-dimensional array.
EXTERNL int nc_inq_vartype(int ncid, int varid, nc_type *xtypep)
MTKt_status MtkReadBlockRangeNC(const char *filename, const char *gridname, const char *fieldname, int startblock, int endblock, MTKt_DataBuffer3D *databuf)
EXTERNL int nc_get_var_int(int ncid, int varid, int *ip)
intn GDfieldinfo(int32, char *, int32 *, int32 [], int32 *, char *)
EXTERNL int nc_inq_dimlen(int ncid, int dimid, size_t *lenp)
#define NC_NOWRITE
Definition: netcdf.h:201
MTKt_status MtkReadBlockRangeHDF(const char *filename, const char *gridname, const char *fieldname, int startblock, int endblock, MTKt_DataBuffer3D *databuf)
HDFFCLIBAPI intf intf start[]
#define MTKT_DATABUFFER3D_INIT
Definition: MisrUtil.h:140
#define NC_MAX_DIMS
Definition: netcdf.h:272
EXTERNL int nc_get_vara(int ncid, int varid, const size_t *startp, const size_t *countp, void *ip)
EXTERNL int nc_inq_varid(int ncid, const char *name, int *varidp)
intn GDreadfield(int32, char *, int32 [], int32 [], int32 [], VOIDP)
#define MTK_ERR_COND_JUMP(code)
Definition: MisrError.h:188
EXTERNL int nc_inq_varndims(int ncid, int varid, int *ndimsp)
MTKt_status MtkDataBufferFree3D(MTKt_DataBuffer3D *databuf)
Free 3-dimensional data buffer (a buffer stack)
MTKt_status
Definition: MisrError.h:11
HDFFCLIBAPI intf * rank
int32 GDopen(char *, intn)
EXTERNL int nc_close(int ncid)
MTKt_status MtkNCVarId(int Ncid, const char *Name, MTKt_ncvarid *Var)
Definition: MtkNCVarId.c:21
MTKt_status MtkReadBlockRangeFid(int32 fid, const char *gridname, const char *fieldname, int startblock, int endblock, MTKt_DataBuffer3D *databuf)
Version of MtkReadBlockRange that takes an HDF-EOS file identifier rather than a filename.
EXTERNL int nc_inq_grp_ncid(int ncid, const char *grp_name, int *grp_ncid)
EXTERNL int nc_open(const char *path, int mode, int *ncidp)
#define FAIL
Definition: hdf.h:94

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