OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
ANCroutines.c
Go to the documentation of this file.
1 #include <mfhdf.h>
2 #include "ancil.h"
3 #include "ancnrt_proto.h"
4 
5 /*********************************************************************
6  * NAME: startHDF
7  *
8  * PURPOSE: open HDF file structure using SDstart and Hopen routines
9  *
10  * ARGS:
11  * outfile - output filename
12  * sdfid - SD file id
13  * fid - HDF file id
14  * mode - DFACC_RDONLY, DFACC_CREATE, DFACC_RDWR
15  *
16  * OUTPUTS: returns a SD structure ID and a File ID.
17  *
18  * EFFECTS: opens HDF file structures
19  *
20  * RETURNS: status flag
21  * Mods: BDS 2/10/94 ver 3.3, (pg: SD32) does not use DFAAC_WRITE so
22  * its removed here as an option arg.
23  * 8/21/96 BDS - renamed 'perror' to 'pexit' to avoid HDF4.0 conflict.
24  *********************************************************************/
25 
26 int startHDF(outfile, sdfid, fid, mode)
27 char *outfile;
28 int32 *sdfid, *fid, mode;
29 {
30  int32 lsdfid, lfid;
31 
32  if ((lsdfid = SDstart(outfile, mode)) < 0) return FAIL;
33  if ((lfid = Hopen(outfile, DFACC_RDONLY, 0)) < 0) return FAIL;
34  Vstart(lfid);
35 
36  *sdfid = lsdfid;
37  *fid = lfid;
38 
39  return SUCCESS;
40 
41 } /* startHDF */
42 
43 /*********************************************************************
44  * setupGrid
45  *
46  * create and HDF Vgroup grid and name it with passed arguments
47  *
48  *********************************************************************/
49 
50 int32 setupGrid(fid, grpname)
51 int32 fid;
52 char *grpname;
53 {
54  int32 gridid;
55 
56  gridid = Vattach(fid, -1, "w");
57  /* Vsetclass(gridid, vgroupclass); */
58  Vsetname(gridid, grpname);
59 
60  return gridid;
61 }
62 
63 /*********************************************************************
64  * gridToGrid
65  *
66  * attach inner grid to outer grid: nested Vgroups
67  *
68  *********************************************************************/
69 
70 int32 gridToGrid(outergridid, innergridid)
71 int32 outergridid, innergridid;
72 {
73  int32 groupref;
74 
75  groupref = VQueryref(innergridid);
76  if (groupref < 0) return -1;
77 
78  Vaddtagref(outergridid, DFTAG_VG, groupref);
79 
80  return 0;
81 }
82 
83 /*********************************************************************
84  * writeGeom
85  *
86  * write HDF geometry Vdata using SeaWiFS defined geometry structure
87  *
88  * return geometry ID
89  *
90  *********************************************************************/
91 
92 int32_t writeGeom(int32_t fid, int32_t gridid, char *geomname, int32_t bin_meth, int32_t registration,
93  float vsize, float hsize, float max_north, float max_south, float max_west, float max_east)
94 {
95  int32 geomid, geomref, *i32;
96  int result;
97  float32 *f32;
98  unsigned char arrhold[GEOMSIZE];
99 
100  /*
101  * --- Write geometry struct for data array and QC data array ----
102  */
103 
104  geomid = VSattach(fid, -1, "w");
105  result = VSfdefine(geomid, "bin_meth", DFNT_INT32, 1);
106  result = VSfdefine(geomid, "registration", DFNT_INT32, 1);
107  result = VSfdefine(geomid, "vsize", DFNT_FLOAT32, 1);
108  result = VSfdefine(geomid, "hsize", DFNT_FLOAT32, 1);
109  result = VSfdefine(geomid, "max_north", DFNT_FLOAT32, 1);
110  result = VSfdefine(geomid, "max_south", DFNT_FLOAT32, 1);
111  result = VSfdefine(geomid, "max_west", DFNT_FLOAT32, 1);
112  result = VSfdefine(geomid, "max_east", DFNT_FLOAT32, 1);
113 
114  VSsetclass(geomid, GEOMCLASS);
115  VSsetname(geomid, geomname);
116 
117  result = VSsetfields(geomid,
118  "bin_meth,registration,vsize,hsize,max_north,max_south,max_west,max_east");
119 
120  i32 = (void *) &arrhold[0];
121  *i32 = bin_meth;
122  i32 = (void *) &arrhold[4];
123  *i32 = registration;
124 
125  f32 = (void *) &arrhold[8];
126  *f32 = vsize;
127  f32 = (void *) &arrhold[12];
128  *f32 = hsize;
129  f32 = (void *) &arrhold[16];
130  *f32 = max_north;
131  f32 = (void *) &arrhold[20];
132  *f32 = max_south;
133  f32 = (void *) &arrhold[24];
134  *f32 = max_west;
135  f32 = (void *) &arrhold[28];
136  *f32 = max_east;
137 
138  result = VSwrite(geomid, arrhold, 1, FULL_INTERLACE);
139  VSdetach(geomid);
140 
141  /*
142  * get geometry reference and add to vgroup
143  */
144 
145  geomref = VSQueryref(geomid);
146  Vaddtagref(gridid, DFTAG_VH, geomref);
147 
148  if (result < 0)
149  return ERROR;
150  else
151  return geomid;
152 
153 } /* writeGeom */
154 
155 /*********************************************************************
156  * findGeomId
157  *
158  * find existing HDF geometry ID
159  *
160  *********************************************************************/
161 
162 int32_t findGeomId(fid, geomname)
163 int32_t fid;
164 char *geomname;
165 {
166  int32 geomid, vsid;
167 
168  if ((vsid = VSfind(fid, geomname)) < 0)
169  pexit("getting geom vsid");
170 
171  if ((geomid = VSattach(fid, vsid, "r")) < 0)
172  pexit("attaching geom vsid");
173 
174  return geomid;
175 
176 } /* findGeomId */
177 
178 /*********************************************************************
179  * linkGeom
180  *
181  * link to existing HDF geometry Vdata
182  * get geometry reference and add to vgroup
183  *
184  *********************************************************************/
185 
186 int32 linkGeom(gridid, geomid)
187 int32 gridid, geomid;
188 {
189  int32 geomref, result;
190 
191  geomref = VSQueryref(geomid);
192  result = Vaddtagref(gridid, DFTAG_VH, geomref);
193 
194  return result;
195 
196 } /* linkGeom */
197 
198 /*********************************************************************
199  * detachGeom
200  *
201  * detach Geometry ID
202  *
203  *********************************************************************/
204 
205 int32_t detachGeom(geomid)
206 int32_t geomid;
207 {
208 
209  VSdetach(geomid);
210 
211  return 0;
212 
213 } /* detachGeom */
214 
215 /*********************************************************************
216  * addAttr
217  *
218  * add an attribute to an existing SDS
219  *
220  *********************************************************************/
221 
222 int addAttr(sdsid, dataattr, datatype, dataunit)
223 int32_t sdsid;
224 char *dataattr;
225 int32_t datatype;
226 char *dataunit;
227 {
228  int result;
229 
230  if ((result = SDsetattr(sdsid, dataattr, datatype, strlen(dataunit) + 1,
231  dataunit)) != 0) return (-1);
232 
233  return result;
234 
235 } /* addAttr */
236 
237 /*********************************************************************
238  * setSDSref
239  *
240  * get and SDS reference number and add it to an existing Vgroup
241  * end SDS access
242  *
243  *********************************************************************/
244 
245 int setSDSref(sdsid, gridid)
246 int32_t sdsid, gridid;
247 {
248  int32 sdsref;
249  int result;
250 
251  if ((sdsref = (int32) SDidtoref(sdsid)) < 0) return (-1);
252 
253  Vaddtagref(gridid, DFTAG_NDG, sdsref);
254  if ((result = SDendaccess(sdsid)) < 0) return result;
255 
256  return 0;
257 
258 } /* setSDSref */
259 
260 /*********************************************************************
261  * deattachHDFgrid
262  *
263  * make HDF grid structure inactive
264  *
265  *********************************************************************/
266 
267 int deattachHDFgrid(gridid)
268 int32_t gridid;
269 {
270  return Vdetach(gridid);
271 
272 } /* deattachHDFgrid */
273 
274 /*********************************************************************
275  * closeHDFstructs
276  *
277  * close HDF file structures
278  *
279  *********************************************************************/
280 
281 int closeHDFstructs(sdfid, fid)
282 int32_t sdfid, fid;
283 {
284  int result;
285 
286  if ((result = Vend(fid)) < 0) {
287  printf("Vend: result: %d\n", result);
288  return (-1);
289  }
290 
291  if ((result = SDend(sdfid)) < 0) {
292  printf("SDend: result: %d\n", result);
293  return (-1);
294  }
295 
296  if ((result = Hclose(fid)) < 0) {
297  printf("Error on Hclose(); stack follows:\n");
298  HEprint(stderr, 0);
299  printf("Stack complete\n");
300  return (-1);
301  }
302 
303  return result;
304 
305 } /* closeHDFstructs */
306 
307 /*****************************************************************
308  * File: wrtsds
309  *
310  * Purpose: write an SDS file
311  *
312  * Description: writes an SDS given labels, formats, units, and a
313  * data block.
314  *
315  * Input parms:
316  * char *sdsfid - file id
317  * int rank - number of dimensions in SDS
318  * int32 shape[] - dimension sizes for each dimension
319  * int32 datatype - HDF datatype of data block
320  * char *datalabel - label descriptor for SDS
321  * char *dataunit - unit descriptor for SDS
322  * char *datafmt - format descriptor for SDS
323  * void *data - array of data values
324  *
325  * Output parms: none
326  *
327  * Returns: 0 on success, non-zero on failure
328  *
329  * Local vars:
330  * int result - HDF routine return value
331  *
332  * Subs called: HDF library routines SDcreate, SDwritedata
333  *
334  * History: none
335  *
336  * Note: uses "ancil.h"
337  *
338  * Author: Brian D. Schieber, GSC, 2/93
339  *
340  * Modification history:
341  * BDS, 9/3/93 - modified for new HDF interface
342  * JMG, 09/22/11 - Change start[2] to start[3] to handle profiles
343  *
344  *****************************************************************/
345 
346 int32_t wrtsds(sdfid, rank, shape, datatype, datalabel, data)
347 
348 int32_t sdfid, shape[], datatype;
349 int rank;
350 char *datalabel;
351 void *data;
352 {
353  int result = 0;
354  int32 sdsid;
355  static int32 start[3] = {0, 0, 0};
356 
357  if ((sdsid = SDcreate(sdfid, datalabel, datatype, rank, shape)) < 0)
358  return sdsid;
359 
360  if ((result = SDwritedata(sdsid, start, NULL, shape, data)) < 0)
361  return result;
362 
363  return sdsid;
364 
365 } /* wrtsds */
366 
367 /*****************************************************************
368  * File: rewrtsds
369  *
370  * Purpose: overwrite an SDS file
371  *
372  * Description: overwrite an SDS given prior sdsid, data shape, and
373  * data block.
374  *
375  * Input parms:
376  * char *sdsid - sds id
377  * int32 shape[] - dimension sizes for each dimension
378  * void *data - array of data values
379  *
380  * Output parms: none
381  *
382  * Returns: 0 on success, non-zero on failure
383  *
384  * Local vars:
385  * int result - HDF routine return value
386  *
387  * Subs called: HDF library routines SDwritedata
388  *
389  * History: none
390  *
391  * Note: uses "ancil.h"
392  *
393  * Author: Brian D. Schieber, GSC, 2/93
394  *
395  * Modification history:
396  * BDS, 9/3/93 - modified for new HDF interface
397  *
398  *****************************************************************/
399 
400 int32_t rewrtsds(sdsid, shape, data)
401 int32_t sdsid, shape[];
402 void *data;
403 {
404  int result = 0;
405  static int32 start[2] = {0, 0};
406 
407  printf("rewrtsds sdsid %d, shape[0] %d, shape[1] %d\n",
408  sdsid, shape[0], shape[1]);
409 
410  result = SDwritedata(sdsid, start, NULL, shape, data);
411  printf("rewrtsds SDwritedata result: %d\n", result);
412 
413  result += SDendaccess(sdsid);
414  printf("rewrtsds SDendaccess result: %d\n", result);
415 
416  return result;
417 
418 } /* rewrtsds */
419 
420 /*****************************************************************
421  * File: rdsds
422  *
423  * Purpose: read HDF Scientific Data Set (SDS)
424  *
425  * Description: read HDF Scientific Data Set (SDS) and return
426  * descriptors and data values. Reads one SDS at a time.
427  *
428  * Input parameters:
429  * char *filename - HDF base name (no ext)
430  * char *vgname - name of vgroup where SDS exists
431  * char *sdsname - name of SDS data grid
432  *
433  * Output parameters:
434  * int32 dimsizes[] - size of each dimension
435  * void *inData - array of data
436  *
437  * Returns: -1 on failure, 0 on success
438  *
439  * Local variables:
440  * int result - counters, return value
441  *
442  * Subroutines called: HDF library routines
443  *
444  * History: none
445  *
446  * Note: arrays returned from this routine must 'fit' the variables
447  * allocated space in the calling routine. Any dimension, any size
448  * SDS can be returned. The 'dimsizes' returned should be verified
449  * to determine the SDS size retreived.
450  *
451  * Author: Brian D. Schieber, GSC, 4/93
452  *
453  * Modification history:
454  * modified for the new HDF formats 10/8/93, BDS, GSC/SAIC
455  * BDS, 8/14/95 Mods per OAPS spec 2.7
456  *****************************************************************/
457 
458 int rdsds(filename, vgname, sdsname, dimsizes, inData)
459 char *filename, *sdsname;
460 char *vgname;
461 int32_t dimsizes[];
462 void *inData;
463 {
464  int result;
465  int j;
466  int32 sdfid, fid, vid, vg;
467  int32 sdsindex, sdsid;
468  int32 rank, numbertype;
469  int32 start[2];
470  int32 tagarray1[255], refarray1[255], nrefs1, nattrs1;
471  char lname[MAXNAMELNG];
472 
473  /*
474  * Default settings for SDreaddata
475  */
476 
477  start[0] = 0;
478  start[1] = 0;
479 
480  /*
481  * ---- Open data file ------------
482  */
483 
484  if ((result = startHDF(filename, &sdfid, &fid, DFACC_RDONLY)) != 0) {
485  pwarning("Fatal error starting HDF file");
486  return (ERROR);
487  }
488 
489  /*
490  * Traverse down to the correct SDS
491  */
492 
493  /* Open the Vgroup by name and fileid, attach to it and get the number
494  * and tag type (SDG, VH, etc) in it, loop over each item and find
495  * the ones that match the desired SDS and then use the SDS reference
496  * and extract the SDS array to the calling procedure.
497  */
498 
499  if ((vid = Vfind(fid, vgname)) <= 0) return (ERROR);
500  vg = Vattach(fid, vid, "r");
501  nrefs1 = Vntagrefs(vg);
502  nattrs1 = nrefs1;
503  Vgettagrefs(vg, tagarray1, refarray1, nattrs1);
504 
505  for (j = 0; j < nrefs1; j++) {
506  if ((tagarray1[j] == DFTAG_NDG) ||
507  (tagarray1[j] == DFTAG_SD)) { /* SDS found */
508  sdsindex = SDreftoindex(sdfid, refarray1[j]);
509  sdsid = SDselect(sdfid, sdsindex);
510  SDgetinfo(sdsid, lname, &rank, dimsizes, &numbertype, &nattrs1);
511  if (!strcmp(sdsname, lname)) {
512  if ((SDreaddata(sdsid, start, (int32 *) NULL, dimsizes, inData)) != 0) {
513  pwarning("Fatal error reading SDS data array");
514  return (ERROR);
515  }
516  Vdetach(vg);
517  return (0); /* SUCCESS */
518  } /* if (!strcmp(vgname, lname)) */
519  } /* tagarray1[k] */
520  } /* for j */
521  Vdetach(vg);
522  pwarning("Fatal error: Case 1 SDS data array not found");
523  return (ERROR);
524 
525  /*
526  * ---- Close data file ------------
527  */
528 
529  if ((closeHDFstructs(sdfid, fid)) < 0) {
530  pwarning("Fatal error closing SDS: closeHDFstructs");
531  return (ERROR);
532  }
533 
534  return (result);
535 
536 } /* rdsds */
537 
538 /**********************************************************************
539  * SUBROUTINE: SDSinFile
540  *
541  * PURPOSE: assign attributes, add to Vgroup and deattach SDS
542  *
543  * AUTHOR: B.D.Schieber, GSC, 10/93
544  * Mods: BDS 5/19/95 Support SeaWiFS Specs 2.7
545  **********************************************************************/
546 
547 int32_t SDSinFile(sdsname, longname, units, datafmt,
548  datatype, sdfid, rank, shape, data, gridid)
549 char *sdsname, *longname, *units, *datafmt;
550 int32_t sdfid, datatype, rank, shape[], gridid;
551 void *data;
552 {
553  int result;
554  int32 sdsid;
555 
556  /*
557  * write SDS array
558  */
559 
560  if ((sdsid = wrtsds(sdfid, rank, shape, datatype, sdsname, data)) < 0) {
561  pwarning("wrtsds");
562  return (ERROR);
563  }
564 
565  /*
566  * set SDS attributes
567  */
568 
569  if ((result = addAttr(sdsid, "long_name", DFNT_CHAR, longname)) != 0) {
570  pwarning("addAttr");
571  return (ERROR);
572  }
573 
574  if (strlen(units) > 0) /* don't write "" attributes */
575  if ((result = addAttr(sdsid, "units", DFNT_CHAR, units)) != 0) {
576  pwarning("addAttr");
577  return (ERROR);
578  }
579 
580  /*
581  * add SDS to Vgroup and deattach SDS
582  */
583 
584  if ((result = setSDSref(sdsid, gridid)) != 0) {
585  pwarning("setSDSref");
586  return (ERROR);
587  }
588 
589  return 0;
590 
591 } /* SDSinFile */
592 
593 /*****************************************************************
594  * File: wrtattr
595  *
596  * Purpose: write DAAC style global attributes to an HDF file
597  *
598  * Description: string arrays of label/value pairs written to HDF
599  * header file.
600  *
601  * Input parms:
602  * dfile - HDF file id
603  * num - number of strings
604  *
605  * Output parms:none
606  *
607  * Returns: -1 on failure, 0 on success
608  *
609  * Local vars:
610  * int i - counter
611  * char outlabel[MAXLABLEN+1] - local label string
612  * char outdescr[MAXDESCLEN+1] - local description string
613  * int32 dfile - file id number
614  * int32 result - return value for HDF calls
615  *
616  * Subs called: HDF library routines
617  *
618  * Note: uses header (ancil.h) definitions for label length,
619  * description length, and name length
620  * uses argument setting for numannarr
621  *
622  * History: based on DAAC "Metadata Submission Guide" 2/93
623  *
624  * Author: Brian D. Schieber, GSC, 2/93
625  *
626  * Mod history:
627  * BDS, 8/30/93 - modified to work with new HDF design.
628  *
629  *****************************************************************/
630 
631 int wrtattr(dfile, lannot, numannarr)
632 int32_t dfile;
633 struct annotation *lannot;
634 /* struct annotation *annot; */
635 int numannarr;
636 {
637 
638  /*
639  * local variables
640  */
641 
642  char outlabel[MAXLABLEN + 1], outchar[MAXDESCLEN + 1];
643  int16 outint16[1];
644  int32 outint32[1];
645  float32 outfloat32[1];
646  int i = 0;
647  int32 result = 0;
648 
649  /*
650  * Place each label/description pair into HDF header
651  */
652 
653  for (i = 0; i < numannarr; i++) {
654 
655  strcpy(outlabel, lannot[i].label);
656 
657  switch (lannot[i].type) {
658  case (DFNT_CHAR8):
659  strcpy(outchar, lannot[i].descr);
660  result = SDsetattr(dfile, outlabel, DFNT_CHAR8,
661  strlen(outchar) + 1, outchar);
662  break;
663 
664  case (DFNT_INT16):
665  sscanf(lannot[i].descr, "%hd", &outint16[0]);
666 
667  result = SDsetattr(dfile, outlabel, DFNT_INT16, 1, outint16);
668  break;
669 
670  case (DFNT_INT32):
671  sscanf(lannot[i].descr, "%d", &outint32[0]);
672  result = SDsetattr(dfile, outlabel, DFNT_INT32, 1, outint32);
673  break;
674 
675  case (DFNT_FLOAT32):
676  sscanf(lannot[i].descr, "%f", &outfloat32[0]);
677  result = SDsetattr(dfile, outlabel, DFNT_FLOAT32, 1, outfloat32);
678  break;
679 
680  default:
681  printf("Error in function WRTATTR, default CASE encountered\n");
682  return (-1);
683  break;
684 
685  } /* end switch */
686  if (result) printf("Error in writing header annotations\n");
687  }
688  return (result);
689 } /* wrtattr */
690 
int closeHDFstructs(int32_t sdfid, int32_t fid)
Definition: ANCroutines.c:281
integer, parameter int16
Definition: cubeio.f90:3
#define SUCCESS
Definition: ObpgReadGrid.h:15
int addAttr(int32_t sdsid, char *dataattr, int32_t datatype, char *dataunit)
Definition: ANCroutines.c:222
int j
Definition: decode_rs.h:73
int32_t wrtsds(int32_t sdfid, int rank, shape, int32_t datatype, char *datalabel, void *data)
Definition: ANCroutines.c:346
#define GEOMCLASS
Definition: ancil.h:45
int32 gridToGrid(int32 outergridid, int32 innergridid)
Definition: ANCroutines.c:70
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
int32 setupGrid(int32 fid, char *grpname)
Definition: ANCroutines.c:50
int32_t rewrtsds(int32_t sdsid, shape, void *data)
Definition: ANCroutines.c:400
#define MAXDESCLEN
Definition: ancil.h:42
README for MOD_PR02AQUA(AQUA) Version to set to For disabling creating and output data sets when in night mode
Definition: README.txt:96
int pwarning(char *string)
Definition: pexit.c:21
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
int32_t detachGeom(int32_t geomid)
Definition: ANCroutines.c:205
int32 linkGeom(int32 gridid, int32 geomid)
Definition: ANCroutines.c:186
char descr[MAXDESCLEN]
Definition: ancil.h:72
int deattachHDFgrid(int32_t gridid)
Definition: ANCroutines.c:267
int wrtattr(int32_t dfile, struct annotation *lannot, int numannarr)
Definition: ANCroutines.c:631
int32_t writeGeom(int32_t fid, int32_t gridid, char *geomname, int32_t bin_meth, int32_t registration, float vsize, float hsize, float max_north, float max_south, float max_west, float max_east)
Definition: ANCroutines.c:92
int32_t findGeomId(int32_t fid, char *geomname)
Definition: ANCroutines.c:162
#define MAXLABLEN
Definition: ancil.h:41
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
void pexit(char *string)
Definition: pexit.c:10
Extra metadata that will be written to the HDF4 file l2prod rank
int startHDF(char *outfile, int32 *sdfid, int32 *fid, int32 mode)
Definition: ANCroutines.c:26
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
int setSDSref(int32_t sdsid, int32_t gridid)
Definition: ANCroutines.c:245
#define MAXNAMELNG
Definition: ancil.h:43
int rdsds(char *filename, char *vgname, char *sdsname, dimsizes, void *inData)
Definition: ANCroutines.c:458
int i
Definition: decode_rs.h:71
int32_t SDSinFile(char *sdsname, char *longname, char *units, char *datafmt, int32_t datatype, int32_t sdfid, int32_t rank, shape, void *data, int32_t gridid)
Definition: ANCroutines.c:547
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
float32 f32
Definition: l2bin.cpp:104
#define ERROR
Definition: ancil.h:24
#define GEOMSIZE
Definition: ancil.h:46