Due to the lapse in federal government funding, NASA is not updating this website. We sincerely regret this inconvenience.
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:98
#define ERROR
Definition: ancil.h:24
#define GEOMSIZE
Definition: ancil.h:46