NCSA National Center for Supercomputing Applications NCSA HDF Vset Version 2.0 November 1990 University of Illinois at Urbana-Champaign NCSA HDF Vset Version 2.0 source code and documentation are in the public domain. Specifically, we give to the public domain all rights for future licensing, resale, and publication. We ask, but do not require, that the following message be included in all derived works: Portions developed at the National Center for Supercomputing Applications at the University of Illinois at Urbana-Champaign. READ ME NOW If you want to see more software like NCSA HDF Vset, please send us a letter, email or U.S. mail, telling us what you are doing with the package. We need to know: (1) What science you are working on--an abstract of your work would be fine; and (2) How the package has helped you, for example, by increasing your productivity or allowing you to do things you could not do before. We encourage you to cite the use of NCSA HDF Vset, and any other NCSA software you have used, in your publications. A bibliography of your work would be extremely helpful. NOTE: This is a new kind of shareware. You share your science and successes with us, and we can get resources to share more software like NCSA HDF Vset with you. NCSA Contacts Mail user feedback, bugs, and Send communications via software and manual suggestions to: electronic mail to one one of the following: NCSA Software Tools Group Bug Reports HDF Vset bugs@ncsa.uiuc.edu 152 Computing Applications Bldg. bugs@ncsavms.bitnet 605 E. Springfield Ave. Champaign, IL 61820 All Other Communications softdev@ncsa.uiuc.edu softdev@ncsavms.bitnet Or contact Jason Ng directly by email to jng@ncsa.uiuc.edu, or call (217) 244-8524. Disclaimer THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESS OR IMPLIED, FOR THE SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. Trademark Acknowledgments Alliant is a registered trademark and CONCENTRIX is a trademark of Alliant Computer Systems Corporation. CRAY and UNICOS are registered trademarks and CRAY-2 and CFT77 are trademarks of Cray Research Inc. IBM PC is a registered trademark of International Business Machines Corporation. Macintosh is a registered trademark and Macintosh II is a trademark of Apple Computer Inc. Model One/80 and Model One/380 are trademarks of Raster Technologies, an Alliant Company. MS-DOS is a registered trademark of Microsoft Corporation. Sun is a registered trademark and Sun Workstation and Sun System 3 are trademarks of Sun Microsystems Inc. UNIX is a registered trademark of AT&T. Table of Contents Introduction Overview ix What Is an HDF Vset? ix Uses of HDF Vsets ix New Features in HDF Vset 2.0 x System Requirements xi Use of This Manual xi Manual Contents xi Form of Presentation xii Further Reading xiii Chapter 1 NCSA HDF Vset Basics Chapter Overview 1.1 Understanding HDF Vset 1.1 Deciding on a Vset Scheme 1.2 Examining the HDF Vset Interface 1.5 Using Examples 1.5 Example 1: Writing Data 1.5 Example 2: Reading Data 1.7 Example 3: Using Meshes and Connectivity Lists 1.9 Example 4: Linking Vset Elements 1.12 Using the HDF Vset Routines 1.14 Naming Vgroups and Vdatas 1.15 Chapter 2 Vdatas Chapter Overview 2.1 Interlacing 2.1 Working with Interlacing 2.1 HDF Data Format 2.3 Vdata Options 2.4 Selecting Random-Access Reads 2.4 Writing Fields of Mixed Types 2.4 Specifying Read Fields 2.6 Inquiring About a Vdata 2.7 Using Searching Strategies 2.8 Accessing Vdatas Simultaneously 2.10 Chapter 3 Vset Utilities Chapter Overview 3.1 vshow 3.1 Synopsis 3.1 vshow Description 3.1 Bugs 3.1 vmake 3.2 Synopsis 3.2 vmake Description 3.2 Creating New Vgroups 3.2 Creating New Vdata 3.2 Creating Links 3.3 Bugs 3.3 Chapter 4 Vgroup Routine Descriptions Chapter Overview 4.1 Vattach 4. 1 Vdetach 4.1 Vgetclass 4.2 Vgetid 4.2 Vgetname 4.2 Vgetnext 4.2 Vinquire 4.3 Vinsert 4.3 Visvg 4.3 Visvs 4.4 Vlone 4.4 Vsetclass 4.4 Vsetname 4.5 Chapter 5 Vdata Routine Descriptions Chapter Overview 5.1 VSattach 5.1 VSdetach 5.1 VSfdefine 5.2 VSfexist 5.3 VSgetclass 5.3 VSgetid 5.3 VSgetname 5.3 VSinquire 5.4 VSlone 5.4 VSread 5.5 VSseek 5.5 VSsetclass 5.6 VSsetfields 5.6 VSsetinterlace 5.7 VSsetname 5.7 VSwrite 5.7 Chapter 6 HDF Vset FORTRAN Interface Chapter Overview 6.1 Vgroup Level Calls 6.1 Vdata Level Calls 6.1 Vgroup FORTRAN Routines 6.2 VFATCH 6.2 VFDTCH 6.2 VFGCLS 6.2 VFGID 6.2 VFGNAM 6.3 VFGNXT 6.3 VFINQ 6.3 VFINSRT 6.3 VFISVG 6.3 VFISVS 6.3 VFLONE 6.4 VFSCLS 6.4 VFSNAM 6.4 Vdata FORTRAN Routines 6.5 VSFATCH 6.5 VSFDTCH 6.5 VSFFDEF 6.5 VSFEX 6.6 VSFGCLS 6.6 VSFGID 6.6 VSFGNAM 6.6 VSFINQ 6.6 VSFLONE 6.7 VSFREAD 6.7 VSFSEEK 6.7 VSFSFLD 6.8 VSFSINT 6.8 VSFSNAM 6.8 VSFWRIT 6.8 FORTRAN Example 6.9 Appendix A NCSA HDF Vset Calls at a Glance Overview A.1 Vgroup calls A.1 Vdata calls A.1 Appendix B NCSA HDF Vset Calls Summary Overview B.1 Calling Sequences B.1 Appendix C Pre-defined Fieldnames Overview C.1 Appendix D Source Files Overview D.1 Source Files D.1 Appendix E Compatibility Information for 1.0 Users Overview E.1 Source Files E.1 Appendix F Obtaining NCSA Software Overview F.1 Obtaining NCSA Software F.1 FTP F.1 Archive Server F.2 Mail F.3 Figures and Tables Figure 1.1 Analogy Between the HDF Vset and the UNIX File System 1.1 Figure 1.2 Sharing Data Among Vsets 1.2 Figure 1.3 Vset Schemes 1.3 Figure 1.4 HDF File with Three Vsets 1.4 Figure 1.5 Writing to a Vset Data 1.5 Figure 1.6 Reading Data from a Vset 1.7 Figure 1.7 Mesh and Connectivity List 1.10 Figure 1.8 Storing a Connectivity List 1.11 Figure 1.9 Linking Vgroups and Vdatas 1.12 Figure 2.1 Interlacing Within Vdatas 2.3 Figure 2.2 Structure Array Vs. Packed Array 2.5 Figure 2.3 Packing Data 2.6 Figure 2.4 Searching for a Vgroup 2.8 Figure 2.5 Searching for a Vdata 2.8 Figure 2.6 Hierarchical Searching 2.9 Figure 2.7 Search Using Fieldnames 2.10 Figure 2.8 Accessing Vdatas Simultaneously 2.10 Table 1.1 Vset Routines 1.5 Table B.1 Calling Sequence Variables B.1 Table B.2 Vset Calls Summary B.2 Table C.1 Predefined Fieldnames C.1 Introduction Overview This introduction provides an overview of NCSA Hierarchical Data Format (HDF) Vset capabilities on the Cray, Alliant, Sun, Iris, Macintosh, and IBM PC. The organization and use of this manual are described and notational conventions explained. What Is an HDF Vset? The HDF Vset is a new storage scheme that allows more than raster images, palettes, scientific datasets and annotations to be stored in the HDF file. It is a versatile storage scheme that introduces two new and useful features. 1. Storage of multi-variate data fields Applications may now define and store data from fields of different types together within the HDF file and then access data from all or some of the fields. 2. Hierarchical grouping of related datasets Applications may explicitly link related datasets within the HDF file to form logically-related groups called vsets. The HDF Vset enables applications with the following capabilities inherent to HDF: (1) a means of defining data fields and types (2) a means of specifying data layout in the HDF file, and (3) greater control over data access. Uses of HDF Vsets The HDF Vset is especially targeted towards applications that manipulate mesh, polygonal, or any connectivity data. Among the applications that could benefit by using this storage scheme are finite-element analysis, surface modeling, and sparse matrices. Using HDF Vset you can group simulation data for animation, as well as store and view images with original data for more meaningful data interpretation. NCSA developers originally designed the HDF Vset to store irregularly-gridded and multi-variate graphical and scientific data, and to facilitate data exchange among the research community. It has since evolved into a general and simple interface for storing almost any large non-uniform datasets. Consistent with existing HDF goals, vset data is self-describing and portable. In addition, provision exists for attaching annotations and textual descriptions. New Features in HDF Vset 2.0 NCSA HDF Vset 2.0 offers several new features and improvements including memory allocation, long integer support, a new secondary name field, and multiple file access. Memory Allocation HDF Vset allocates memory for vgroups and vdatas dynamically. Therefore, there is no upper limit on how many vgroups or vdatas that may be accessed by an application. Long Integer Support HDF Vset now allows storage of long integers in a vdata. Integer datasets greater than 65353 must be stored as long integers or they will be truncated. Each long integer will be stored in 4 bytes within a vdata. The routine VSfdefine now recognizes the field type constant LOCAL_LONGTYPE. Use this constant to define a field to be of type long. VSwrite expects data corresponding to that field to be stored in a long array. Similarly, vsread expects to be passed a long array into which long integers will be retrieved and returned. New Secondary Name Field Each vgroup or vdata now has a secondary name field. This field, called the class field of the vgroup or vdata, is just another text field like the vgname or vsname. Its purpose is to provide another key with which that vgroup or vdata may be classified. It is analogous to the file-extension in a filename, e.g., "DAT" in the filename "TEST1. DAT". Usage of the class field is optional, and is application-dependent. The routines Vsetclass and VSsetclass set this class field for a vgroup and a vdata, respectively. Similarly, the routines Vgetclass and VSgetclass return the class fieldname of a vgroup and a vdata, respectively. ultiple File Access HDF Vset now allows several HDF files to be opened for reading and writing Vsets simultaneously. This feature only works when the Vset library is used with release 3.1 or later of the base HDF library. No new routines are needed. Open as many files as needed using DFopen, and then use the file pointers as usual in the Vset routines. Upon completion, each opened file must be properly closed by a call to DFclose. NOTE: Please see Appendix E, "Compatibility Information for 1.0 Users" for important compatibility information for release 1.0 users. System Requirements The HDF Vset library is available for any of the following computer systems: Cray/UNICOS, SGI/UNIX, Sun/UNIX, Alliant/CONCENTRIX, VAX/Ultrix, Vax/VMS, Macintosh/MacOS, and IBM PC/MS-DOS. Use of This Manual This manual is designed for users whose applications access vsets from HDF files. Manual Contents he manual is organized into the following chapters: Chapter 1, "NCSA HDF Vset Basics," describes HDF Vsets and gives simple examples on using it. Chapter 2, "Vdatas," describes in detail the organization of data within vdatas and techniques for manipulating the data. Chapter 3, "Vset Utilities," describes in detail the utilities for manipulating Vsets. Chapter 4, "Vgroup Routine Descriptions," describes in detail the routines that manipulate vgroups. Chapter 5, "Vdata Routine Descriptions," describes in detail the routines that manipulate vdatas. Chapter 6, "HDF Vset FORTRAN Interface," describes Vset calling sequences from FORTRAN. Appendix A, "NCSA HDF Vset. Calls at a Glance," allows quick referencing of all present Vset Calls. Appendix B, "NCSA HDF Vset Calls Summary," lists all HDF Vset routines. Appendix C, "Pre-defined Fieldnames," lists all HDF predefined fieldnames. Appendix D, "Source Files," lists the source files needed for HDF Vsets and describes how to compile and create applications that use the HDF Vset. Appendix E, "Compatibility Information for 1.0 Users," offers important compatibility information for NCSA HDF Vset 1.0 users. Appendix F, "Obtaining NCSA Software," outlines the procedures for obtaining NCSA software. Form of Presentation The material in this manual is presented in text, screen displays, or command line notation. Text In explaining various features and commands, this manual often presents a word within a paragraph in italics to indicate tha the word is defined within the paragraph, or that it is a significant term that should be noted and/or is being mentioned for the first time. So that they are more easily identifiable within this manuscript, utilities, variables, integer arguments, routine names, etc. have been presented in 10 point courier style. Portions of this manual refer to other portions of the manual where the other portions explain related topics. These cross references usually mention the title of sections or chapter enclosed in quotation marks, such as, see Chapter 1, "NCSA HDF Vset Basics." Command Line Format Notation Throughout this manual, many explanations instruct you to make entries by typing on the keyboard. These entry instructions are printed in courier bold type and appear within a paragraph or on a separate line. The command lines in this manual are normally shown in lowercase, except in rare instances where uppercase is required. When it is necessary for you to press a key that is labeled with more than one character (such as the RETURN key), this manual identifies the key with all capital (uppercase) letters. Keys to be entered are printed in bold type. Keys that are pressed simultaneously or in succession are linked with a hyphen. For example, press CONTROL-A. Further Reading Detailed information about the basic HDF structure and its calling interface can be found in NCSA HDF Specifications and also NCSA HDF Calling Interfaces and Utilities which you may download via FTP, an archive server, or via U.S. mail. Refer to Appendix F, "Obtaining NCSA Software," for more details. Chapter 1 NCSA HDF Vset Basics Chapter Overview Understanding NCSA HDF Vset Deciding on a Vset Scheme Examining the HDF Vset Interface Using Examples Example 1: Writing Data Example 2: Reading Data Example 3: Using Meshes and Connectivity Lists Example 4: Linking Vset Elements Using the HDF Vset Routines Naming Vgroups and Vdatas Chapter Overview This chapter introduces the NCSA HDF Vset and presents several examples on reading and writing data using the vset interface Understanding NCSA HDF Vset An HDF Vset is a logical grouping of diverse, but related data items within an HDF file. Data organization within the file resembles the UNIX file system. Only two basic types of storage elements exist in a vset: vgroups and vdatas. A vgroup is like a directory or subdirectory, while a vdata is like a file. Thus, a vdata may only contain data, while a vgroup only contains references to vdatas or to other vgroups. The entire vset may be viewed as a directory tree with vgroups as nodes and vdatas as leaves. Figure 1.1 shows a vset with data stored in five vdatas while Figure 1.2 shows two vsets in an open file. Note that several vgroups may point to the same vgroup or vdata. Vdatas only store data. The data is organized into fields within each vdata. Each field is identified by a unique fieldname. The type of each field may be either integer, character or float. Fields of different types may exist within a vdata. ED. NOTE: Figures are not available in this plain text version of the specification. Figure 1.1 Analogy Between the HDF Vset and the UNIX File System GROUPS contain only references to vdatas and other vgroups. DATAS contain only data. *** INSERT FIGURE HERE *** Figure 1.2 Sharing Data Among Vsets Deciding on a Vset Scheme The HDF Vset is a versatile hierarchical storage scheme for grouping simple or multi-dimensional datasets. Multi-variable datasets are conveniently stored as vsets by first identifying the fields in the datasets. As many fields as needed may be defined for storing data in a vset. There are many ways of organizing these fields. At one extreme, all the fields are organized in one huge vdata (vset C in Figure 1.3). At the other extreme, data for one field is stored in one vdata (vset B in Figure 1.3). Usually, closely related fields are organized together in one vdata (vset A in Figure 1.3). After all the fields are organized into vdatas, vgroups should always be used to group the vdatas in a hierarchical manner. Vdatas that are related should be grouped together. Since it is possible for several vdatas to point to one vgroup or vdata, a wellchosen grouping saves on file storage by avoiding duplication of data. Figure 1.4 shows an HDF file containing three vsets. The three vsets have one vdata in common. *** INSERT FIGURE HERE *** Figure 1.3 Vset Schemes (PX,PY) TMP Results from a simulation yielding temperature values(TMP) for 1000 points (px,py). 1 (2.3,-1.5) 23.55 2 (3.4,-5.7) 3.77 This data set contains 1000 triplets; i.e., an x-value, a y-value, and 3 (-O.5,3.5) 0.092 a temperature-value per triplet. This ... ... dataset may be stored as a vset in an HDF 1000(2.7--0.9) -3.23 file. Each vset comprises one vgroup and one or more vdata. Vsets A, B, and C are three ways the same data can be stored. ***INSERT FIGURE HERE *** Figure 1.4 HDF File with Three Vsets (PX, PY) TMP1 TMP2 TMP3 Results from a simulation yielding temperature values(TMP) for 1000 points(px,py). Results are taken for three different times. 1 (2.3,-1.5) 23.55 23.568 23.50 2 (3.4,-5.7) 3.77 -2.111 8.03 Results from the three different times are stored as three distinct vsets in one HDF file. 3 (-O.5,3.5) 0.092 0.022 1.22 Only the temperature is changing ... ... ... ... temperature is changing during the different times, but not the 100( (2.7.-0.9) -3.23 -3.23 0.00 positions. Hence, only one vdata is needed to store the (px, py) values. In this file, three vsets exist, each consisting of one vgroup referencing two vdatas. The vgroups are named "result 1," "result 2," and "result 3," respectively. Since the positional values do not change during the simulation, only one vdata, defined to contain the fields "PX, PY," is needed. The three vsets then "share" this vdata. On the other hand, the temperature values, different for each time, are stored as three separate vdatas, each defined to contain the field "TMP" for temperature. Examining the HDF Vset Interface The HDF Vset interface is a library of routines for the definition, organization, and manipulation of vgroups and vdatas, as well as for data access. The routines are classified accordin to the action they perform: Table 1.1 Vset Routines * access grants or terminates access to vgroups or vdatas. * inquiry returns information about vgroups or vdatas. * search searches and locates specific vgroups or vdatas. * specify sets up specification for data access. * read/write retrieves/stores data from/in vdatas. * linkage links vgroups and vdatas to form vsets. Using Examples The following examples demonstrate the ease in reading and writing data using the vset interface routines. (See Appendix D "Source Files," on compiling and creating executables.) Example 1: Writing Data Figure 1.5 shows a simple program that stores data as a vset in an HDF file. It takes pxy, a 2D array (float) of 1000 points (x, y values), and pv, an array (float) of 1000 temperature values, and stores them as two vdatas linked to a vgroup (vset A in Figure 1.3). One vdata is defined to contain one field, "TMP," for temperature, while the other is defined to contain two fields, "PX, PY," for the positional values. The vgroup is named "mypoints." Figure 1.5 Storing Vset Data #include "vg.h" main() { VGROUP *vg; VDATA *vs; DF *f; float pxy[1000][2], temp[1000]; /* (x,y) temperature values */ f = DFopen("myfile.hdf", DFACC_ALL,0); /* open HDF file with full access */ /* create a vgroup with write access, then name it "mypoints" */ vg = (VGROUP*) Vattach(f, -1,"w"); Vsetname(vg,"mypoints"); /* create a vdata to store x,y values */ vs = (VDATA*) VSattach(f, -1, "w"); VSsetfields(vs, "PX,PY"); VSwrite(vs, pxy, 1000, FULL_INTERLACE); Vinsert(vg, vs); VSdetach(vs); /* creace a vdata to store temperature values */ vs = (VDATA*) VSattach(f, -1, "w"); VSfdefine (vs, "TMP", LOCAL_FLOATTYPE,1); VSsetfields(vs, "TMP"); VSwrite(vs, tmp, 1000, FULL_INTERLACE); Vinsert(vg, vs); VSdetach(vs); Vdetach(vg); DFclose(f); } The program in Figure 1.5 does the following: 1. The HDF file is opened. 2. A new vgroup is created by calling vattach with an id argument of -1. This vgroup is then named "mypoint." 3. A new vdata is created by vsattach with an id of -1. 4. VSsetfields specifies that the vdata will contain two float fields "Px, Py". 5. VSwrite writes out the data as 1,000 pairs of x, y values. 6. Vinsert establishes a link from the vgroup "mypoints" to this vdata. 7. Access to the vdata is terminated with VSdetach. 8. A similar sequence of calls creates a second vdata, specifies that it contains the field "TMP," writes out the temperature values, links the same vgroup to the vdata, and detaches the vdata. 9. Finally the vgroup itself is detached, and the HDF file is closed. The fieldnames "PX" and "PY" are names pre-defined by the interface to represent x and y float values. However, the fieldname "TMP" is not pre-defined and it must first be defined with a VSfdefine call specifying that "TMP" is a field of one float value. (See Appendix C "Pre-defined Fieldnames," for a list of all predefined fieldnames.) Each call to vattach and VSattach returns a pointer to a vgroup and vdata, respectively. The other routines then manipulate the vgroups and vdatas through these pointers. The fourth argument to VSwrite is the buffer interlace, a parameter that tells vswrite how data in the buffer is laid out. A value of NO_INTERLACE specifies that all the data values for one field are contiguous, while a value of FULL_INTERLACE specifies that one data value of a field is immediately followed by one data value of another field. The vdata in the file also has its own interlace, called file interlace, which equals FULL_INTERLACE by default. Chapter 2, "Vdatas," describes buffer and file interlacing in detail. Example 2: Reading Data The program in Figure 1.6 reads the data from the HDF file created by the program in Figure 1.5. Assume it is known that a vgroup exists named "mypoints" in the HDF file, and that this vgroup contains (x, y) coordinate values in its first vdata and temperature values in its second vdata; but, it is not known how many vertices exist (vset A in Figure 1.3). Figure 1.6 Reading Data from a Vset #include "vg.h" main () { VGROUP *vg; VDATA *vs; DF *f; float (*pxy)[2]; /* pointer to an array of 2 floats (x,y coords) */ float *temp; /* poiner to an array of floats (temperature) */ int nvertices, vsize, interlace; char vsname[50], vgname[50], fields(50]; int vsid, vgid; f = DFopen("myfile.hdf", DFACC_ALL,0); /* open HDF file with full access */ /* first , locate that vgroup. set vgid to -1 to begin search */ vgid = -1; while ((vgid=Vgetid(f, vgid)) != -1) { vg = Vattach(f, vgid, "r"); /* attach with read access */ Vgetname(vg, vgname); if (!strcmp(vgname,"mypoints")) { found = 1; break; } /* found the vgroup */ Vdetach(vg); } if (found == 0) perror ("did not find vgroup. exit"); /* next, extract the (x,y coords) from the 1st vdata */ vsid = -1; vsid = Vgetnext(vg, vsid); vs = (VDATA*) VSattach(f, vsid, "r"); VSinquire(vs, &nvertices, &interlace, fields, &vsize, vsname); pxy = (float*) malloc(nvertices * sizeof(float) * 2); VSsetfields(vs,"PX,PY"); VSread(vs, pxy,nvertices, FULL_INTERLACE); VSdetach(vs); /* finally extract the temperature values from the 2nd vdata */ vsid = Vgetnext(vg, vs id); vs = (VDATA*) VSattach(f, vsid, "r"); VSinquire(vs, &nverticeb, &interlace, fields, &vsize, vsname); temp = (float*) malloc,(nvertices * sizeof(float)); Vsetfields(vs,"TMP"); VSread(vs, temp, nvertices, FULL_INTERLACE); VSdetach(vs); Vdetach (vg); DFclose(f); ... free(pxy); free(temp); } The above program illustrates the following: (1) searching for a specific vgroup, (2) performing inquiries, and (3) determining the amount of memory space to allocate. The program does the following: 1. The HDF file is first opened. 2. It searches the HDF file for a vgroup named "mypoints" by sequencing through all vgroups in a loop. The search is initiated by setting the vgid argument to -1 in the call to Vgetid. 3. The call returns an id of a vgroup or -1 if none exists. Whenever a vgroup id is returned, an attach is done to that vgroup, and its name, as returned by Vgetname, is checked. A flag is set if the vgroup is found. 4. Once the vgroup is found, its first vdata is attached. The call to VSattach requires an id, which is obtained by a call to Vgetnext. Vgetnext returns the id of the first vdata, if its id argument is -1. 5. VSinquire returns, among other information, the number of elements stored in that vdata. This number multiplied by the size of an element (two floats) gives the size of the allocated space. 6. VSsetfields then specifies that the data fields "PX, PY" in that vdata will be accessed. 7. VSread reads the data into the allocated space, pxy. 8. The vdata is detached when reading is completed. 9. A similar sequence of calls extracts the temperature values from the second vdata into the allocated space, temp. Note the use of vgetnext, which is being passed the id of the first vdata. This call returns the id of the next entity after the first vdata. Example 3: Using Meshes and Connectivity Lists Many scientific and graphic applications use meshes to describe surfaces and objects as well as their properties. The shape of the surfaces and objects are defined as a set of connected points or nodes. The properties of the mesh are values attached to each node or group of nodes within the mesh. The HDF Vset allows the mesh description to be stored together with its associated values. One way to represent and store meshes in an HDF file is to define a vertex-set. A vertex-set is an instance of an HDF Vset that, minimally, consists of the three following component datasets: 1. A set containing the coordinates of the nodes in the mesh 2. A set that describes how the nodes are connected to each other to form the shape of the mesh 3. One or more sets of data values that correspond to each of the nodes or polygons The second dataset is a matrix called a connectivity list. Each element in a connectivity list describes a polygon within the mesh. Each polygon is a list of all the nodes that form the polygon. The connectivity list, then, is a set of polygons that form the mesh. Each of the above component sets may be stored as a separate vdata. These vdatas should then be grouped together with other descriptive or annotative information under a vgroup. As an example, assume that the 1000 nodes in Figure 1.3 actually form a mesh of 400 triangles (Figure 1.7). (Each node has a node number in addition to its coordinate position.) The connectivity of the mesh is described by an array of node numbers, in the array mesh. Every three numbers in one row of the table define a triangle. This information can be stored as a connectivity list in another vdata, as the user-defined field "PLIST" (polygon list). The data can then be related to the position and temperature values by linking the vdata to the existing vgroup (of vset A in Figure 1.3). *** INSERT FIGURE HERE *** Figure 1.7 Mesh and Connectivity List The program in Figure 1.5 is easily modified to write a vertex-set into an HDF file by adding code to store the connectivity list in the same vset. The following code segment (Figure 1.8) stores the connectivity list (i.e., the array mesh) into the vset A in Figure 1.3, thereby creating the mesh vset as shown in Figure 1.7. Figure 1.8 Storing a Connectivity List int mesh[400][3]; ..... /* create a vdata to store mesh */ vs = (VDATA*) VSattach(f, -1, "w"); VSfdefine (vs, "PLIST", LOCAL_INTTYPE, 3); VSsetfields(vs, "PLIST"); VSwrite(vs, mesh, 400, FULL_INTERLACE); Vinsert(vg, vs); VSdetach(vs); ..... This code segment should be inserted just before the vdetach(vg) statement in the program in Figure 1.5. The connectivity list is stored in a new vdata that is then linked to the vgroup of vset A. Creating and storing connectivity information to a vdata is no different than the storing position and temperature values in the program. (See the outlined steps below.) 1. The code creates a new vdata. 2. VSfdefine defines "PLIST" as one field comprising three integers. This step is necessary because "PLIST" is not a predefined fieldname. VSsetfields then sets up the vdata to contain this field. 3. VSwrite writes out the connectivity data for 400 triangles from the array mesh into the vdata. 4. Vinsert links this vdata to the same vgroup. 5. VSdetach terminates access to this vdata. The resulting configuration is shown in Figure 1.7. Note that "PLIST" is a single field comprising three integers; hence, the call to VSfdefine with the fourth argument equal to 3. This argument specifies the order of the field. "PLIST", as defined for this vertex-set, is a single field of order 3. Although one "PLIST" element comprises three integers, these three integer values can only be accessed together. Thus the following code segment writes out three integer values; i.e., mesh [0] [0], mesh [0] [1] and mesh [0] [2]. (The numbers of the three nodes form the first mesh triangle.) VSsetfields(vs, "PLIST"); VSwrite (vs, mesh, 1, interlace); Similarly in the code segment below, the call to read one "PLIST" element from the vdata returns three integers (the numbers of the three nodes forming this first mesh triangle) in the array x: int x[3]; ... Vssetfields(vs, "PLIST"); VSread (vs, x, 1, interlace); Example 4: Linking Storage Elements in Vsets The program segment in Figure 1.9 illustrates the use of the routine Vinsert. This routine allows several vgroups to refer to one vdata in the HDF file, and hence, "share" data within the vdata. The dataset comprises pxy, a 2D array (float) of 1000 points (x, y coordinates) and three arrays t1, t2, and t3, each an array (float) of 1000 temperature values taken from a simulation at three different times. The points remain constant at all times. This dataset is best represented by three vsets, each representing the simulation at a different time (vset B in Figure 1.3). Thus, four vdatas exist, one for each temperature dataset and the fourth for the points (x, y coordinates). Figure 1.9 Linking Vgroups and Vdatas #include "vg.h" main() { VGROUP *vg1, *vg2, *vg3; VDATA *vs; DF *f; int b,n; float pxy[1000][2]; /* (x,y) values */ float t1[1000], t2[1000], t3[1000]; /* temperature values */ /* open HDF file */ f = (DF*) DFopen("myfile.hdf", DFACC_ALL,0); /* attach a 3 new vgroups with write access */ vg1 = (VGROUP*) Vattach(f, -1,"w"); Vsetname(vg1, "result1"); /* name it "result1" (optional) */ vg2 = (VGROUP*) Vattach(f, -1,"w"); Vsetname(vg2, "result2"); name it "result2" (optional) */ vg3 = (VGROUP*) Vattach(f, -1,"w"); Vsetname(vg3, "result3"); name it "result3" (optional) */ /* attach a new vdata to store temperature values t1. Insert into vg1. */ vs = (VDATA*) VSattach(f, -1, "w"); b = VSfdefine (vs, "TMP", LOCAL_FLOATTYPE, 1); b = VSsetfields(vs,"TMP"); n = VSwrite(vs, t1, 1000, FULL_INTERLACE); Vinsert(vg1, vs); VSdetach(vs); /* attach a new vdata to store temperature values t2. Insert into vg2. */ vs = (VDATA*) VSattach(f, -1, "w"); b = VSfdefine (vs, "TMP", LOCAL_FLOATTYPE, 1); b = VSsetfields(vs,"TMP"); n = VSwrite(vs, t2,1000, FULL_INTERLACE); Vinsert(vg2, vs); VSdetach(vs); /* attach a new vdata to store temperature values t3. Insert into vg3. */ vs = (VDATA*) VSattach(f, -1, "w"); b = VSfdefine (vs, "TMP", LOCAL_FLOATTYPE, 1); b = VSsetfields(vs,"TMP"); n = VSwrite(vs, t3,1000, FULL_INTERLACE); Vinsert(vg3, vs); VSdetach(vs); /* attach a new vdata to store (x,y) values */ /* This vdata will be shared by the three vgroups */ vs = (VDATA*) VSattach(f, -1, "w"); b = VSsetfields(vs,"PX,PY"); n = VSwrite(vs, pxy,1000, FULL_INTERLACE); /* Insert vs into vgroups vg1, vg2, and vg3, then detach it. */ b = Vinsert(vg1, vs); b = Vinsert(vg2, vs); b = Vinsert(vg3, vs); VSdetach(vs); /* done, detach all vgroups */ Vdetach(vg1); Vdetach(vg2); Vdetach(vg3); DFclose(f); } The above code segment does the following: 1. The HDF file is opened. 2. Three new vgroups are created and attached. 3. Three separate vdatas are created and attached. Separate sets of temperature data from t1, t2, and t3 are then written to each vdata. 4. Each vdata is then linked to the respective vgroups using vinsert. After this step, the three vdatas are then detached. 5. A fourth vdata is created and attached for storing positional data. Immediately after data is written to it, the three calls to Vinsert each create a link from each of the three vgroups to this vdata. The vdata is then detached. 6. All vgroups are detached and the file is closed. After the insertions, each vgroup logically owns two vdatas. Note that the shared vdata may be accessed by accessing any of the vgroups--the vdata now belongs equally to all three vgroups. Vinsert may also be used to insert one vgroup into another vgroup in a similar manner. Using the HDF Vset Routines All the vset routines require that the HDF file be opened using DFopen with the access-mode DFACC_ALL. The routines provide six basic functions: search, access, inquiry, specify, read/write, and linkage: * Search routines provide a systematic way of searching through the HDF file for vgroups and vdatas. * Access routines attach, or grant access to, vgroups or vdatas before any data transfer can occur. They also detach, or properly terminate access to, vgroups or vdatas when data transfer is completed. * Inquiry routines return information about existing vgroups or vdatas. They are useful for searching through the file for a specific vgroup or vdata, and for determining the fields and data sizes of vdatas. * Specify routines define and set up parameters that dictate the format and amount of data to be read or written. They are also used to define new fields and to assign names to vgroups and vdatas. * Read/Write routines perform the actual data transfer between the file and the calling program. They are always preceded by the appropriate access and specify routines. * Linkage routines link vgroups with vdatas or other vgroups into a hierarchy that is the vset. The examples in this chapter are typical of the order for calling the routines. In most cases, you will use the routines in the following order: * Search for a vgroup. * Attach a vgroup, a procedure that returns a pointer to a vgroup. * Sequence through that vgroup and search for the desired vdata. Vgroups that are attached to the vgroup should be similarly searched. * Attach the desired vdata when found. * Execute inquiry calls at any time, to get information about existing vgroups or vdatas (e.g., its name, fieldnames, element size, interlace, etc). * Perform a series of specify calls on the vdatas to establish the fields to be accessed and the type of interlace used. The specify calls must be performed before any data transfer can occur. For more information on interlace, see Chapter 2, "Vdatas." * Execute a series of read/write calls to read or write data. * Link newly created vgroups or vdata into new or existing vgroups or vdatas. * Perform a detach to terminate access to every vdata or vgroup that was attached when linkage is completed. * Use the access routine VSseek, if necessary, for random-access reads within a vdata. (NOTE: Random-access writes are forbidden.) * Close the HDF file by calling DFclose. Naming Vgroups and Vdatas When there is more than one vgroup or vdata within a file, a problem arises: How can one uniquely identify or refer to a particular vgroup or vdata? One way to solve the problem is to always name each vgroup or vdata. (Using Vsetname and VSsetname). Assigning a unique name enables you to easily identify vgroups or vdatas in the future. The routines vgetname and vsgetname each return the name of a vgroup or vdata, respectively. Thus, rather than guessing which vgroup or vdata to use, you use its name for searching. Naming vgroups or vdatas is optional. Vgroups or vdatas may also be located if their identifiers are known. The identifiers are unique, and are actually the reference component of their HDF tag-ref identifiers. They are values used and returned by the search routines (Vgetid, VSgetid, Vgetnext). 1. Pass an identifier of -1 to the search routine. The routine then returns the identifier of the first vgroup or vdata. 2. Pass the returned identifier back to the routine. This will then return the identifier of the next vgroup or vdata. No more vgroups or vdatas are found if the routine returns -1. 3. Use the valid returned identifier in an attach call in order to access that vgroup or vdata. Within a vgroup, there may he vdatas and other vgroups. The identifier itself does not identify if an entity is a vdata or vgroup. The inquiry routines Visvg and Visvs respectively test if an id refers to a vgroup or vdata, respectively. Searching is illustrated in Figure 1.6 in the section example, "Reading Data." Chapter 2 Vdatas Chapter Overview Interlacing Working with Interlacing HDF Data Format Vdata Options Selecting Random-Access Reads Writing Fields of Mixed Types Specifying Read Fields Inquiring About a Vdata Using Searching Strategies Accessing Vdatas Simultaneously Chapter Overview This section points out some properties of vdatas that might not be obvious from earlier examples. The section covers important concepts and ideas on which the HDF Vset is based. It also gives a better idea of how the vdata's properties and various routines may be used to gain greater control over data organization and access. Interlacing Data for all the fields with a vdata are stored according to a non-interlaced or fully-interlaced scheme. The concept of interlacing is simple but important--it describes how data of one field is related to data of another in a storage area (whether in memory or in a vdata in the file). Note that interlacing applies only to fields. In a non-interlaced scheme, all data values for one field are stored together contiguously. Think of all the data values for one field forming one data chunk, and all the data values for another field forming another chunk. Such an interlace scheme emphasizes keeping all data values for one field close together. Figure 2.1a shows a vdata with non-interlaced fields. In a fully-interlaced scheme, all data values for one field are never located contiguously. Each data value of one field is immediately followed by one data value of another field, until a data value is taken for all fields. In other words, data values from different fields are intertwined together as aggregates, where each aggregate comprises exactly one data value from each of the fields. Such an interlace scheme emphasizes keeping related data values from different fields together. Figure 2.1b shows a vdata with fully-interlaced fields. When talking about interlacing, a distinction is made between when data is in memory and when data resides in a vdata in a file. The layout of data in memory is its buffer interlace, whereas the layout of data within a vdata in the file is the vdata's file interlace. Working with Interlacing Data as it appears in the file may or may not have the same interlace as the data appears in memory. This feature allows applications to extract data interlaced in the manner most useful to it, independent of the file interlace. In the same way, data may be stored in the file with an interlace different from how it appears in memory. The HDF Vset interface always requires that the buffer interlace be specified in any data transfer. However, it does not require the file interlace be specified. By default, this buffer interlace is always set to FULL_INTERLACE for every newly created vdata. Thus, fields in a vdata are always fully-interlaced by default. You may change the interlace for any particular vdata to NO_INTERLACE with the routine vssetinterlace. Vdatas within an HDF file may be set to different file interlaces if so desired. However, note that the file interlace of existing vdatas cannot be changed. The buffer interlace must be specified when reading or writing data. Both the read/write routines, vsread and VSwrite, require the buffer interlace to be specified as the fourth argument. When reading data, the buffer interlace tells the read routine how the returned data should be interlaced in the read buffer. When writing data, the buffer interlace informs the write routine how data in the write buffer is interlaced. Finally, note that when only one field is read or written, or when there is only one field in a vdata or in memory, interlacing is not relevant. In such cases, specifying FULL_INTERLACE or NO_INTERLACE yields identical results. *** INSERT FIGURE HERE *** Figure 2.1 Interlacing Within Vdatas HDF Data Format Data stored in a vdata is in IEEE 32-bit floating-point format. When data is read or written, the calling interface always convert from IEEE format to the correct data format and byte length for that particular machine, and vice versa. For instance, 4-byte floats created on a VMS machine are stored as 4-byte IEEE floats in the vset in the HDF file. Later when a Cray (running UNICOS) reads the data, the 4-byte float value is converted to an 8-byte Cray float value. The data stored within a vdata is always contiguous; i.e., the vdata does not contain any non-data spaces or holes. This is true for both fully-interlaced and non-interlaced data. Consequently, any call to VSread always returns data that is contiguous, and any call to VSwrite expects data to be contiguous. Vdata Options Selecting Random-Access Reads The access routine vsseek is used together with a VSread to affect a random-access read within a vdata. vsseek requires an argument that specifies the element location within that vdata. This value will be an integer, with 0 for the first element position, 1 as the second element position, etc. Thus, the following code segment seeks to the 51st element in the vdata vs, and then reads data for four elements according to the fields specified by the last VSsetfields call: VSseek(vs,50); VSread(vs,buf,4,interlace); Writing Fields of Mixed Types The fields within one vdata need not all be of the same type. You may store fields of integer, float, and character types together within one vdata. Assume that the fields "F1", "F2", "I1" and "C1" represent data fields of float, float, character, and integer types of order 1, respectively. The code segment below first defines these fields, and then specifies that the data from buffer buf be written contiguously into the vdata vs according to the format "F1,I1,F2,C1". ... VSfdefine (vs, "F1", LOCAL_FLOATTYPE, 1) ; VSfdefine (vs, "I1", LOCAL_INTTYPE, 1) ; VSfdefine (vs, "F2", LOCAL_FLOATTYPE, 1) ; VSfdefine (vs, "C1", LOCAL_CHARTYPE, 1) ; VSsetfields (vs, "F1, I1, F2, C1") ; VSwrite(vs,buf,nvertices,interlace); The data in buf must also be contiguous. There must be no padding or alignment, or non-data spaces. Storing mixed field types within a vdata is very efficient, and is useful to applications that use structures. Such usage intuitively associates a structure in memory to a vdata in the file. However, in general, structures contain padding or alignment bytes (Figure 2.2) and as such, may not be directly written out into a vdata with a vswrite call. The data from such a structure must first be packed into an array so that the array does not contain holes or non-data spaces. This packed array may then be written out into one vdata using VSwrite. *** INSERT FIGURE HERE *** Figure 2.2 Structure Array Vs. Packed Array The following code segment (Figure 2.3) illustrates packing data in the fields from a structure array s s into a contiguous array pp, and then writing the array pp into a vdata. Figure 2.3 Packing Data #define NVERTICES 500 main() { struct { float F1; int I1; float F2; char C1; } ss[NVERTICES]; unsigned char *pp, *p; int i; ... pp = (unsigned char*) malloc( NVERTICES* (2*sizeof(float) + sizeof(char) + sizeof(int)) ); p = pp; for(i=O;i text.file will create an ASCII file containing formatted ASCII data from the vdata with reference number 4. Bugs For full vdata dump, you must specify only one vdata or all vdatas. vmake vmake creates vgroups, and vdatas and links them in an HDF file. Synopsis * vmake file vgroup-name creates a vgroup. * vmake file vdata-name format creates a vdata. * vmake file -1 vgroup-ref ref1 ref2... refn links vgroups and vdatas. vmake Description vmake is a general utility for generating vsets in an HDF file. You may use vmake in three different ways: (1) for creating new vgroups, (2) for storing data into new vdatas, and (3) for creating links among vgroups and vdatas. Invoking vmake with no arguments provides help. Return value: If vmake is successful it prints a positive number; otherwise, a negative number is printed. Creating New Vgroups vmake creates a new vgroup, named vgroup-name in the HDF file file. This new vgroup will not overwrite any information within the file, if that file exists. If it doesn't, vmake creates a new file. Upon successful creation, the program prints the reference number of that vgroup. Creating New Vdatas vmake creates a new vdata, named vdata-name in the HDF file file, and converts and stores ASCII data *from standard input* in the vdata according to field specifications in format. format has the form field1=conv, field2=conv,... where field1, field2 denotes fields you would define for that vdata (e.g., PX for floating-point x-values, PLIST for connectivity data). conv is a single character specifying the field type. Thus, it is one of the following: f - float d - integer l - long c - character. Each field type may be optionally preceded by a repetition-number, i.e., the number of data items of the same type that together comprise one instance of the field. For example, the repetition number "3" in PLIST=3d specifies that each instance of the field called PLIST will consist of 3 integers. Note that a stream of ASCII data from standard input is expected. Examples: vmake vset.hdf "coordinates" "PX=f, PY=f, PZ=f" < pos.dat will create a vdata named "coordinates" containing 3 fields "PX","PY" and "PZ", each of type float. In this case, a stream of ASCII floating-point numbers is read from the ASCII file pos.dat. myprog | vmake vset.hdf "simulation5" "DENSITY=f" will create a vdata named simulation5 containing a single field of type float named DENSITY. In this case, the output from the program myprog (a stream of ASCII floating-point numbers) is piped into vmake. Creating Links vmake in this context allows one or several vdatas or vgroups to be inserted (linked) to a vgroup. All vgroups and vdata are identified by their reference numbers. vgroup-ref is the reference number of the vgroup into which the other vgroups or vdatas are to be inserted. ref1 ref2 ... refn are the reference numbers of those vgroups or vdatas to be inserted. Reference numbers of existing vgroups and vdatas can be displayed using vshow. vmake permits the creation of empty vgroups, but not empty vdatas. Vgroups and vdatas may be created in any order by the user. However, to perform linking, the vgroups and vdatas involved must already exist. Bugs vmake does not check for cycles, and will happily allow you to insert a vgroup into itself. It is legal to create multiple vgroups or vdatas with identical names. Chapter 4 Vgroup Routine Descriptions Chapter Overview Vattach Vdetach Vgetclass Vgetid Vgetname Vgetnext Vinquire Vinsert Visvg Visvs Vlone Vsetclass Vsetname Chapter Overview This chapter describes the vgroup routines in the C library in detail. Vattach (VGROUP*) Vattach ( f, vgid, access) DF *f; int vgid; char *access; [either "r" or "w"] Purpose: This access routine attaches to a vgroup having id vgid, and then returns a pointer to that group. Specifies: f is a pointer to an opened HDF file. vgid specifies which vgroup in the HDF file to attach to: * if vgid = -1, a new vgroup is created. * if vgid is +ve, the vgroup corresponding to the vgid is attached. (The access argument currently is not used; all vgroups are attached with both read and write access.) Return value: Upon a successful attach, a vgroup pointer is returned. Otherwise, NULL is returned. Vdetach (void) Vdetach (vg) VGROUP *vg; Purpose: This access routine detaches vg, the vgroup that was currently attached, terminating further access to that vgroup. Specifies: All space associated with that vgroup will be freed. All vgroups should be detached using this routine before closing the file. vdetach also updates the vgroup information in the HDF file if any changes occur. Return value: None. Vgetclass (void) Vgetclass (vg,vgclass) VDATA *vs; char *vsclass; Purpose: This specify routine retuns, in the variable vgclass, the class field name (if any) of the vdata vg. Return value: None. Vgetid int Vgetid (f, vgid) DF *f; int vgid; Purpose: This search routine searches through the HDF file and returns the id of the next VGROUP following the vgroup that has id vgid. Specifics: To initiate a search, call this routine with a value of -1 for vgid. This will return the id of the first vdata in the file. Return value: Upon success, the id (O or the integer) of the next vdata is returned; on error, or when there are no more vgroups, -1 is returned. Vgetname (void) Vgetname (vg, vgname) VGROUP *vg; char *vgname; Purpose: This inquiry routine returns, in the variable vgname, the name of the vgroup vg. Return value: None. Vgetnext int Vgetnext (vg, id) VGROUP *vg; int id; Purpose: This search routine is used to sequence through a vgroup. It searches the vgroup vg and returns the id of the next entity (vgroup or vdata) after the entity that has id, id. Specifics: Note that the entity may be either a vdata or another vgroup. To initiate a search, call this routine with -1 as argument for id. This action will return the id of the first entity in vg. Return value: Upon success, the id of the vgroup or vdata is returned. If there is an error, or when there are no more entities in that vgroup, -1 is returned. Vinquire Vinquire (vs, nentries, vgname) VGROUP *vg; char *vgname; int *nentries; Purpose: This is the general vgroup inquiry routine. Specifics: Given a vgroup vg, vinquire returns the following: * nentries the number of entries (i.e., the total number of vgroups and vdatas) in this vgroup. * Vgname the name (if any) of the vgroup. Otherwise, NULL is returned. Return value: Upon success, 1 is returned; otherwise, -1. Vinsert int Vinsert (vg, v) VGROUP *vg; VDATA *V; [or VGROUP *v;] int n; Purpose: This linkage routine establishes a link from the vgroup vg to either another vgroup or to a vdata v. Specifics: Essentially, vinsert allows vgroups or vdatas to belong to a vgroup. The routine does not check for any cycles that may result. Return value: Upon success, the position of the inserted entity (vgroup or vdata) within the vgroup vg is returned (0 or a +ve integer); upon error, -1. Visvg int Visvg (vg, id) VGROUP *vg; int id; Purpose: This inquiry routine tests whether an entity (vgroup or vdata) having id, id in a vgroup vg is a vgroup. Id is any valid id returned by vgetnext. Return value: If id indeed refers to a vgroup within the vgroup vg, 1 is returned; otherwise, 0 is returned. Visvs int Visvs (vg, id) VGROUP *vg; int id; Purpose: This inquiry routine tests whether an entity (vgroup or vdata) having id, id in a vgroup vg is a vdata. Id is any valid id returned by VSgetnext. Return value: If id indeed refers to a vdata within the vgroup vg, 1 is returned; otherwise 0 is returned. Vlone int vlone (f, idarray, asize) DF *f; int idarray []; int asize; Purpose: This inquiry routine returns an array of reference numbers of all vgroups that are not linked to any vgroup in the HDF file. Specifics: You must provide the integer array idarray, and you must specify the integer size of the array in the argument asize. The return value from this function will be the total number of VGROUPS that are not linked to any vgroup in the file. But at most asize reference numbers will be returned in idarray. An array size of 65000 integers for idarray will be usually more than adequate. To use dynamic memory instead, first call vlone with a small value (e.g. 0 or 1) for asize, and then use the returned value to allocate memory for idarray to be passed to a subsequent call to Vlone. Return value: If there is an error, the return value is -1. Otherwise, it returns the total number of all vgroups in the file that are not linked to any vgroup. Vsetclass (void) Vsetclass (vg,vgclass) VGROUP *vg; char *vgclass; Purpose: This specify routine associates the class fieldname vgclass with the vdata vg. Specifics: Vgroups initially have a class name of NULL. The class name may be set more than once. Return value: None. Vsetname (void) Vgetname (vg, vgname) VGROUP *vg; char *vgname; Purpose: This specify routine associates the vgroup vg with the name vgname. Specifics: Vgroups each initially have a vgname of NULL, and may be renamed more than once. Note that the routine does NOT check for uniqueness of vgroup names. Return values: None. Chapter 5 Vdata Routine Descriptions Chapter Overview VSattach VSdetach VSfdefine VSfexist VSgetclass VSgetid VSgetname VSinquire VSlone VSread VSseek VSsetclass VSsetfields VSsetinterlace VSsetname VSwrite Chapter Overview This chapter describes the vdata routines in the C library in detail. VSattach (VDATA*) VSattach (f, vsid, access) VGROUP *vg; int vsid; character *access; Purpose: This access routine attaches to the vdata that bas id vsid within the opened HDF file (pointer f) and then returns a pointer to that vdata. Specifics: Access is either "r" (read) or "w" (write). Currently, you may only write to a new vdata (by specifying vsid = -1). You may not attach to any existing vdata for writing or appending new data to it. The default interlace for a vdata attached with "w" access is FULL_INTERLACE (Use VSsetinterlace to modify the interlace). If access is "r", vsid must be a valid id of an existing vdata as returned from any of the search routines (Vgetnext or VSgetid). Return value: If the attach is successful, a vdata pointer is returned; otherwise, NULL is returned. VSdetach (void) VSdetach (vs) VDATA *vs; Purpose: This access routine detaches vs, the vdata that was currently attached, terminating further access to that vdata. Specifies: vsdetach updates the vdata information in the HDF file if there are any changes. All memory used for that vdata is freed. The pointer vs should not be used after that vdata is detached. Return value: None. VSfdefine int VSfdefine (vs, field, fieldtype, order) VDATA *vs; char *field; int fieldtype; int order; Purpose: This specify routine is used to define a new, or unsupported field for which you have data to be written to that vdata. (See the description of VSsetf ields for more details about such fields.) Specifies: VSfdefine is used only on a vdata that has "w" access. You specify a field by naming it as a character string in field, its type in fieldtype, and its order in order. The type may be one of the following: LOCAL_FLOATTYPE for float type LOCAL_INTTYPE for integer type LOCAL_BYTETYPE for byte type LOCAL_LONGTYPE for long integer type Note that an integer is stored as 2 bytes in the HDF file while a long integer is stored as 4 bytes. A float is stored as 4 bytes. The order of a field is the number of units of data type (float, int, byte, or long) it comprises. For instance, a field called VECTOR comprising 3 floats may be defined by the call as follows: VSfdefine(vs,VECTOR,LOCAL_FLOATTYPE,3); Only one field may be defined per call. NOTE: Defining a field using VSfdefine does not prepare the storage format of the vdata. To do so, use vssetfields. Return value: Upon success, 1 is returned; otherwise, -1 is returned. VSfexist int VSfexist (vs, fields) VDATA *vs; char *fields; Purpose: This inquiry routine checks whether all the field(s) specified in fields exists in the vdata vs. Specifics: The fields argument is a string of comma-separated fieldnames (e.g., PX, PY, PZ). Return value: A value of 1 is returned if all field(s) exist; otherwise -1 is returned VSgetclass (void) VSgetclass (vs,vsclass) VDATA *vs; char *vsclass; Purpose: This inquiry routine returns in vsclass the class field name (if any) of the vdata Return value: None. VSgetid int VSgetid (f, vsid) DF *f; int vsid; Purpose: This search routine searches through the HDF file and returns the id of the next vdata after the vdata that has id vsid. Specifics: To initiate a search, call this routine with a value of -1 for vsid. Doing so returns the id of the first vdata in the file. Return value: Upon success, the id (0 or the integer) if the next vdata is returned. On error, or when there are no more vdatas, -1 is returned. VSgetname (void) VSgetname (vs, vsname) VDATA *vs; char *vsname; Purpose: This inquiry routine returns in vsname the name (if any) of the vdata vs. Return value: None. VSinquire int VSinquire (vs, nelements, interlace, fields, vasize, vaname) VDATA *vs; char *fields; char *vsname; int *vsize; int *interlace; int *nelements; Purpose: VSinquire is the general vdata inquiry routine. Specifics: Given a vdata vs, vsinquire returns the following information about that vdata: * nelements the number of elements in vs * interlace the type of interlace: FULL_INTERLACE or NO_INTERLACE * vsize the size in bytes of an element in vs * fields a comma-separated string listing all fields in vs (e.g., "PX, PY, PZ") * vsname the name (if any) of vs Return value: Upon success, 1 is returned; otherwise, -1. VSlone int VSlone (f, idarray, asize) DF *f; int idarray int asize; Purpose: This inquiry routine returns an array of reference numbers of all vdatas that are not linked to any vgroup in the HDF file. Specifics: You must provide the integer array idarray, and you must specify the integer size of the array in the argument asize. The return value from this function will be the total number of vdatas that are not linked to any vgroup in the file. But at most asize reference numbers will be returned in idarray. An array size of 65000 integers for idarray will be usually more than adequate. To use dynamic memory instead, first call vslone with a small value (e.g., 0 or 1) for asize, and then use the returned value to allocate memory for idarray to be passed to a subsequent call to vslone. Return value: If there is an error, the return value is -1. Otherwise, it returns the total number of all vdatas in the file that are not linked to any vgroup. VSread int VSread (vs, databuf, nelements, interlace) VDATA *vs; int interlace; int nelements; unsigned char *databuf; Purpose: VSread is the only read routine of the HDF Vset interface. Specifics: Given a vdata vs (with "r" access), and a buffer, databuf, this routine returns the data read from that vdata in the buffer. You must specify in nelements the number of elements' worth of data to be read, and the buffer interlace in interlace. (Specify either NO_INTERLACE or FULL_INTERLACE). If the call is successful, the data returned in databuf is laid out as specified by interlace, and the data fields appear in the order specified in the last call to vssetfields for that vdata. It is an error to read from a vdata without first calling VSsetfields on that vdata. Return value: The routine returns the number of elements read, if successful; otherwise -1 is returned. VSseek int VSseek (vs, element) VDATA *vs; int element; Purpose: This access routine moves the read pointer within the vdata vs to the element specified by vertex. The next VS read begins at this element position. For instance, specify element = 0 to seek to the first element; element = 1 to seek the second element, etc. Specifics: vsseek provides a mechanism for random-access reads within a vdata. Each seek is constrained to an element boundary within the vdata. The routine works for both fully- and non-interlaced vdatas. NOTE: This routine may only be used with a vdata attached with "r" access. Return value: The element position (i.e., zero or a positive integer) is returned if the seek is successful. Otherwise, -1 is returned. VSsetclass (void) VSsetclass (vs, vsclass) VDATA *vs; char *vsclass; Purpose: This specify routine associates the class field name vsclass with the vdata vs. Specifics: Vdatas initially have a class name of NULL. The class name may be reset more than once. Return value: None. VSsetfields int VSsetfields (vs, fields) VDATA *vs; char *fields; Purpose: This specify routine establishes the fields to be accessed within the vdata vs by any subsequent read or write routine (VSread or VSwrite). The fields are specified by the string argument fields, a comma-separated list of fieldnames (e.g. "PX, PY, PZ"). Specifics: The fieldnames allowed depends on the access of the vdata: * If access is "r", the fieldnames must be one of the names of the fields that already existed for that vdata. * If access is "w", the fieldnames can be one of the following: (1) Pre-defined fieldnames (See Appendix C "Pre-defined Fieldnames," for a list of pre-defined fieldnames.) (2) Any fieldname that has been user-defined. New or not pre-defined fieldnames should first be defined for a vdata by calling the specify routine VSfdefine. Return value: Upon success, 1 is returned; otherwise -1. VSsefinterlace int VSsetinterlace (vs, interlace) VDATA *vs; int interlace; Purpose: This specify routine sets the interlace type as specified by the argument interlace for the vdata vs. Specifies: The interlace may be one of FULL_INTERLACE or NO_INTERLACE. This routine applies only to new vdatas attached with " w" access. The data is formatted and stored in that vdata according to interlace. Return value: Upon success, 1 is returned; otherwise -1. VSsetname (void) VSsetname (vs, vsname) VDATA *vs; char *vsname; Purpose: This specify routine associates the name vsname with the vdata vs. Specifics: Vdatas initially have NULL names, and may be renamed more than once. Note that the routine does NOT check for uniqueness of vdata names. Return value: None. VSwrite int VSwrite (vs, databuf, nelements, interlace) VDATA *vs; int interlace; int nelements; unsigned char *databuf; Purpose: This is the only write routine of the HDF Vset interface. Specifics: Given a vdata vs (with "w" access), and a buffer, databuf, containing data to be written, this routine will write the data from the buffer out to the vdata. You must specify in nelements, the number of elements' worth of data to be written, and in interlace the buffer interlace. (Specify either NO_INTERLACE or FULL_INTERLACE). The data in databuf to be written is assumed to be laid out as specified by interlace, and has the exact data fields (and order) as specified in the last call to vssetfields for that vdata. It is an error to read from a vdata without first calling VSsetfields on that vdata. Note that interlace specifies how the data exists within the user's buffer, databuf. If that data is to be stored in a vdata with an interlace different from that of the buffer, VSsetinterlace must be called prior to vswrite. Return value: The routine returns the number of elements read, if successful; otherwise, -1 is returned. Chapter 6 HDF Vset FORTRAN Interface Chapter Overview Vgroup Level Calls Vdata Level Calls Vgroup FORTRAN Routines VFATCH VFDTCH VFGCLS VFGID VFGNAM VFGNXT VFINQ VFINSRT VFISVG VFISVS VFLONE VFSCLS VFSNAM Vdata FORTRAN Routines VSFATCH VSFDTCH VSFFDEF VSFEX VSFGCLS VSFGID VSFGNAM VSFLONE VSFREAD VSFSCLS VSFSEEK VSFSFLD VSFSINT VSFSNAM VSFWRIT FORTRAN Example Chapter Overview This chapter briefly discusses the vgroup and vdata routines available for use with FORTRAN. In the three succeeding tables below, use the function names in the first column in FORTRAN applications. Vgroup level Calls Name C equivalent VFATCH (f, vsid, access) Vattach VFDTCH (vg) Vdetach VFGCLS (vg, vgclass) Vgetclass VFGID (f , vgid) Vgetid VFGNAM (vg, vgname) Vgetname VFGNXT (vg, id) Vgetnext VFINQ (vg, nentries, vgname) Vinquire VFINSRT (vg, vs) Vinsert VFISVG (vg, id) Visvg VFISVS (vg, id) Visvs VFLONE (f, idarray, asize) Vlone VFSCLS (vg, vgclass) Vsetclass VFSNAM (vg, vgname) Vsetname Vdata Level Calls Name C equivalent VSFATCH (f, vsid, access) VSattach VSFDTCH (vs) VSdetach VSFFDEF (vs, field, fieldtype, order) VSfdefine VSFEX (vs, fields) VSfexist VSFGCLS (vs, vsclass) VSgetclass VSFGID (f, vsid) VSgetid VSFGNAM (vs, vsname) VSgetname VSFINO (vs, nelements, interlace, fields, vsize, vsname) VSinquire VFSLONE (f, idarray, asize) VSlone VSFREAD (vs, buf, nelements, interlace) VSread VSFSCLS (vs, vsclass) VSsetclass VSFSEEK (vs, element) VSseek VSFSFLD (vs, fields) Vgsetfields VSFSINT (vs, interlace) VSsetinterlace VSFSNAM (vs, vsname) VSsetname VSFWRIT (vs, buf, nelements, interlace) VSwrite Vgroup FORTRAN Routines The following section briefly describes the vgroup routines available for use in FORTRAN. The FORTRAN routines appear in the right-hand column. Refer to Chapter 4, "Vgroup Routine Descriptions," for a more detailed discussion of these routines. VFATCH integer function VFATCH (f,vsid,access) integer f integer vsid character*1 access ('r' or 'w') Purpose: Attaches to a vgroup. Return value: Upon success, id of the vgroup (positive integer); otherwise, - 1 . VFDTCH subroutine VFDTCH (vg) integer vg Purpose: Detaches a vgroup. Return value: None. VFGCLS subroutine VFGCLS (vg,vgclass) integer vg character*(*) vgclass Purpose: Returns the class name of the vgroup. Return value: None. VFGID integerfunction VFGID (f,vgid) integer f integer vgid Purpose: Returns the id of the next vgroup in the file. Return value: Upon success, id of next vgroup (0 or positive integer); otherwise, -1. VFGNAM subroutine VFGNAM (vg, vgname) integer vg character*(*) vgname Purpose: Returns the name of a vgroup. Return value: None. VFGNXT integerfunction VFGNXT (vg,id) integer vg integer id Purpose: Returns the id of the next entry from the vgroup. Return value: Upon success, id of next entry (0 or positive integer); otherwise, -1. VFINQ integerfunction VFINQ (vg,nentries,vgname) integer vg integer nentries character*(*) vgname Purpose: Performs a general inquiry on a vgroup. Return value: Upon success, 1; otherwise, -1. VFINSRT integerfunction VFINSRT (vg,v) integer vg integer v Purpose: Inserts a vgroup or vdata to the given vgroup. Return value: Upon success, the position in vgroup where entry is inserted (0 or positive integer); if error, -1. VFISVG integer function VFISVG (vg, id) integer vg integer id Purpose: Determines if an id in a vgroup refers to a vgroup. Return value: If it refers to a vgroup, 1; otherwise 0. VFISVS integer function VFISVS (vg, id) integer vg integer id Purpose: Determines if an id in a vgroup refers to a vdata. Return value: If it refers to a vdata, 1; otherwise 0. VFLONE integer function VFLONE (f, idarray, asize) integer f integer idarray(*) integer asize Purpose: Returns an array of reference numbers of vgroups that are not linked to any other vgroup. Return value: Upon success, the total number of such vgroups in the file; otherwise, -1. VFSCLS subroutine VRSCLS (vg, vgclass) integer vg character*(*) vgclass Purpose: Sets the class name for the vgroup. Return value: None. VFSNAM subroutine VFSNAM (vg, vgname) integer vg character*(*) vgname Purpose: Sets the name of the vgroup. Current limitation: The name string cannot contain blank spaces. Return value: None. Vdata FORTRAN Routines The following section briefly describes the vdata routines available for use in FORTRAN. Refer to Chapter 5, "Vdata Routine Descriptions," for a more detailed discussion of these routines. VSFATCH integer function VSFATCH (f,vsid,access) integer f integer vsid character*(1) access ('r' or 'w') Purpose: Attaches to a vdata. Return value: Upon success, id of vdata (positive integer); otherwise, -1 . VSFDTCH subroutine VSFDTCH (vs) integer vs Purpose: Detaches from a vdata. Return value: None. VSFFDEF integerfunction VSFFDEF (vs,field,fieldtype, order) integer vs character*(*) field integer fieldtype integer order Purpose: Defines a new field to be used in the vdata. Return value: Upon success, 1; otherwise, -1. VSFEX integerfunction VSFEX (vs,fields) integer vs character*(*) fields Purpose: Tests if given fields exist in the data. Return value: If the field(s) exist, 1; otherwise, -1 VSFGCLS subroutine VSFGCLS (vs, vsclass) integer vs character*(*) vsclass Purpose: Returns the class name of the vdata. Return value: None. VSFGID integerfunction VSFGID (f,vsid) integer f integer vsid Purpose: Returns the id of the next vdata from the file. Return value: Upon success, id of vdata (0 or positive integer); otherwise, -1 if error or no more vdatas exist. VSFGNAM subroutine VSFGNAM (vs, vsname) integer vs character*(*) vsname Purpose: Returns the name of the vdata. Return value: None. VSFINQ integer function VSFINQ (vs,nelements,interlace,fields,vsize,vsname) integer vs integer nelements integer interlace integer vsize character*(*) fields character*(*) vsname Purpose: Performs a general inquiry on the vdata. Return value: If the vdata is ok, 1 is returned; if an error exists, -1 is returned. VSFLONE integer function VSFLONE (f, idarray, asize) integer f integer idarray(*) integer asize Purpose: Returns an array of reference numbers of vdatas that are not linked to any other vgroup. Return value: Upon success, the total number of such vdatas in the file; otherwise, -1. VSFREAD integer function VSFREAD (vs, buf, nelements, interlace) integer vs character*(*) buf integer nelements integer interlace Purpose: Reads from a vdata. Return value: Upon success, the number of elements read (positive integer); otherwise, -1. VSFSCLS subroutine VSFSCLS (vs, vsclass) integer vs character*(*) vsclass Purpose: Sets the class name for the vdata. Return value: None. VSFSEEK integer function VSFSEEK (vs, element) integer vs integer element Purpose: Moves to an element's location in a vdata. Return value: Upon success, the element number (0 or positive integer); otherwise, -1 VSFSFLD integer function VSFSFLD (vs, fields) integer vs character*(*) fields Purpose: Sets the fields in a vdata for reading or writing. Return value: Upon success, 1; otherwise, -1. VSFSINT subroutine VSFSINT (vs,interlace) integer vs integer interlace Purpose: Sets the file interlace for a vdata. Return value: Upon success, 1; otherwise, -1. VSFSNAM subroutine VSFSNAM (vs,vsname) integer vs character*(*) vsname Purpose: Sets the name of the vdata. Current limitation: vsname cannot contain blank spaces. Return value: None. VSFWRIT integer function VSFWRIT (vs, buf, nelements, interlace) integer vs character*(*) buf integer nelements integer interlace Purpose: Writes to a vdata. Return value: Upon success, the number of elements written(positive integer); otherwise, -1. FORTRAN Example Figure 6.1 shows an example FORTRAN program which stores a dataset as a vset of one vgroup and two vdatas. Figure 6.1 FORTRAN Example c ================================================== c c EG1.F c HDF VSET Sample Program c c Creates a vset of 1 vgroup and 2 vdatas into the file 'eg1.hdf'. c c compile and link c compile to get the object file 'eg1.o' c link 'eg1.o' with the libraries 'libvg.a' and 'libdf.a' c c What this program do: step by step. c c --- (A) ---- c --- open HDF file, attach to new vgroup c --- name the vgroup 'my_fortran_vgroup' c c --- (B) ---- c --- attach to new (1st) vdata, name it 'the_fortune_500_vdata' c --- write out 20 integers from buf as the predefined field 'IY' c --- tell VSFWRIT your data is fully-interlaced. c --- insert the vdata into the above vgroup c --- when done, detach the vdata. c c --- (C) --- c --- attach to new (2nd) vdata, name it 'the_famous_sevens' c --- define your own new field 'SIEBEN' type integer. c --- write out 70 integers from buf as the field 'SIEBEN' c --- tell VSFWRIT your data is fully-interlaced. c --- insert the vdata into the above vgroup c --- when done, detach the vdata. c c --- (D) --- c --- finally detach the vgroup and close the file c ===================================================== program SAMPLE integer buf(100), sbuf(100), i,n integer f external DFOPEN, DFCLOSE external VSFATCH, VSFDTCH, VSFSFLD, VSFSNAM, VSFWRIT external VSFFDEF external VFATCH, VFDTCH, VFSNAM, VFINSRT integer DFOPEN integer VSFATCH, VSFSFLD, VSFWRIT, VSFFDEF integer VFATCH, VFINSRT integer vs, vg c some defined constants. see "vg.h" integer INTTYPE parameter (INTTYPE=2) integer FINTRLACE parameter (FINTRLACE=O) integer FULLACC parameter (FULLACC=7) c ------ generate data ------- do 111 i=1,100 buf(i) = i+500 sbuf(i) = i+7000 111 continue c ------ write to vset ------- c --- (A) ---- f DFOPEN ('eg1.hdf', FULLACC, 0) vg VFATCH (f, -1,'w') call VFSNAM(vg, 'my_fortran_group') c --- (B) ---- vs = VSFATCH (f, -1,'w') call VSFSNAM(vs, 'the_fortune_500_vdata') n = VSFSFLD (vs, 'IY') n = VSFWRIT (vs, buf,20, FINTRLACE) n = VFINSRT (vg, vs) call VSFDTCH (vs) c --- (C) --- vs = VSFATCH (f, -1,'w') call VSFSNAM(vs, 'the_famous_sevens') n = VSFFDEF (vs, 'SIEBEN',INTTYPE,1) n = VSFSFLD (vs, 'SIEBEN') n = VSFWRIT (vs, sbuf,70, FINTRLACE) n = VFINSRT (vg, vs) call VSFDTCH (vs) c --- (D) --- call VFDTCH (vg) call DFCLOSE (f) end Appendix A NCSA HDF Vset Calls at a Glance Overview This appendix is a quick reference guide for using HDF Vset 2.0 calls. Vgroup Calls C FORTRAN Vattach begins access to a vgroup. VFATCH Vdetach terminates access to a vgroup. VFDTCH Vgetclass returns the vgroup's class name. VFGCLS Vgetid returns the id of the next vgroup in the file. VFGID Vgetname returns the vgroup's name. VFGNAM Vgetnext returns the id of the next entry of a vgroup. VFGNXT Vinquire returns information about a vgroup VFFINQ Vinsert inserts a vdata (or vgroup) into a vgroup. VFINSRT Visvg tests if an element in a vgroup is a vgroup. VFISVG Visvs tests if an element in a vgroup is a vdata. VFISVS Vlone returns the references of all lone vgroups. VFLONE Vsetclass assigns a class name to a vgroup. VFSCLS Vsetname assigns a name to a vgroup. VFSNAM Vdata Calls C FORTRAN VSattach begins access to a vdata. VSFATCH VSdetach terminates access to a vdata. VSFDTCH VSfdefine defines a new field for a vdata. VSFFDEF VSfexist tests for the existence of field(s) in a vdata. VSFEX VSgetelass returns the vdata's class name. VSFGCLS VSgetid returns the id of the next vdata in the file. VSFGID VSgetname returns the vdata's name. VSFGNAM VSinquire returns information about a vdata. VSFINQ VSlone returns the references of all lone vdatas. VSFLONE VSread reads from a vdata. VSFREAD VSseek seeks to an element position in a vdata. VSFSEEK VSsetclass assigns a class name to a vdata. VSFSCLS VSsetfields specifies the fields to be accessed in a vdata. VSFSFLD VSsetinterlace sets the interlace in a vdata. VSFSINT VSsetname assigns a name to a vdata. VSFSNAM VSwrite writes to a vdata. VSFWRIT Appendix B NCSA HDF Vset Calls Summary Overview This appendix lists all the routines in the HDF Vset interface. Detailed information about each routine can be found in Chapter 4, "Vgroup Routine Descriptions," and Chapter 5, "Vdata Routine Descriptions.' Call Sequences Table B.1 defines HDF Vset arguments and return values. In Table B.2, italicized items represent arguments in which values are returned. Table B.1 Arguments and Returned Values unsigned char *buf; DF *f; int vgid, vsid, id,n,b; int nentries, nvertices, interlace, vsize, order, fieldtype, asize, idarray[]; char *access, *vgname, *vsname, *fields, *vgclass, *vsclass; VGROUP *vg; VDATA *vs; Table B.2 Vset Calls Summary VGROUP LEVEL CALLS Return Values Functions Arguments Class vg = Vattach (f, vgid, access) access void Vdetach (vg) access void Vgetclass (vg, vgclass) inquiry vgid = Vgetid (f, vgid) search void Vgetname (vg, vgname) inquiry id = Vgetnext (vg, id) search b = Vinquire (vg, nentries, vgname) inquiry n = Vinsert (vg, vs) linkage b = Visvg (vg, id) inquiry b = Visvs (vg, id) inquiry int = Vlone (f, idarray, asize) inquiry void Vsetclass (vg, vgclass) specify void Vsetname (vg, vgname) specify vs = VSattach (f, vsid,access) access void VSdetach (vs) access b = VSfdefine (vs, field, fieldtype, order) specify b = VSfexist (vs, fields) inquiry void VSgetclass (vs, vsclass) inquiry vsid = VSgetid (f, vsid) search void VSgetname (vs, vsname) inquiry b = VSinquire (vs, nvertices, interlace, fields, vsize, vsname) inquiry int = VSlone (f, idarray, asize) inquiry n = VSread (vs, buf, nvertices, interlace) read n = VSseek (vs,nvertices) access void VSsetclass (vs, vsclass) specify n = VSsetfields (vs, fields) specify b = VSsetinterlace (vs, interlace) specify void VSsetname (vs, vsname) specify n = VSwrite (vs, buf, nvertices, interlace) write Appendix C Pre-defined Fieldnames Overview This appendix lists the pre-defined fieldnames known to the HDF Vset interlace. Table C.1 Pre-defined Fieldnames Pre-defined Description Data Type Fieldname PX x-coord float PY y-coord float PZ z-coord float IX x-coord integer IY y-coord integer IZ z-coord integer NX normal x-component float NY normal y-component float NZ normal z-component float Appendix D Source Files Overview This appendix lists the source files needed to create the HDF Vset library. Source Files In addition to your existing HDF library, libdf.a (release 3.0 or later), as well as existing include-files df.h and dfi.h, you need the following source files for the HDF Vset: vg. c vsetf.c vrw. c vio. c vconv. c vparse.c vsetf.c vgp. c vg. h Use the file makefile (in the same directory) to create the HDF Vset library, libvg.a. Remember to set the machine type in the makefile (e.g., "MACHINE=SUN"). You may also simply compile the C source files and then create the library from the object files. For example, on the Sun workstation running UNIX, create the library as outlined below. 1. To create the object files, compile the C source files by entering: cc -c vg.c vsetf.c vrw.c vio.c vconv.c vparse.c vsetf.c vgp.c -D 2. To create the library from the object files, enter: ar -r libvg.a vg.o vsetf.o vrw.o vio.o vconv.o vparse.o vsetf.o vgp.o ranlib libvg.a Note that this library only contains HDF Vset routines. 3. To create an executable, compile and link your application source with the vertex-set library (libvg. a) and the basic HDF library (libdf.a). Enter: cc myprog.c libvg.a libdf.a -o myproy For example, if you name your program plane, you would enter: cc plane.c libvg.a libdf.a -o plane Appendix E Compatibility Information for 1.0 Users Overview This appendix explains how to convert HDF Vset 1.0 files so they will be compatible with HDF Vset 2.0. Source Files Since the release of HDF Vset 1.0, the data structures associated with Vsets (ie HDF representations of vgroups and vdatas) have been revised to allow new features to be incorporated in future. Thus files created by release 2.0 cannot be read by applications that use the earlier 1.0 release of the HDF Vset library. The conversion program, vcompat, should be used to convert an existing HDF Vset file (that was created using release 1.0 ) so that it is compatible with this and future releases. This program is included in this release as a C-source file. The conversion merely creates new data description elements in the same file. As a result, that same file may still be used with existing applications (that uses the release 1.0 Vset library) as well as new applications (that uses the release 2.0 library). Note that after the conversion, the original file will become slightly bigger. Existing applications may link to the release 2.0 Vset library with no modifications needed. vcompat may be created as follows: cc vcompat.c -o vcompat libdf.a libvg.a To convert an existing HDF Vset file, type: vcompat vcompat will not convert a HDF file that is already compatible with release 2.0. Appendix F Obtaining NCSA Software Overview This appendix uses NCSA HDF to outline the procedures for obtaining NCSA software via FTP, an archive server, or by regular mail. Obtaining NCSA Software FTP If you are connected to Internet (NSFNET, ARPANET, MILNET, etc.) you can download HDF software and documentation at no charge from an anonymous file transfer protocol (FTP) server at NCSA. The steps you should follow to do so are enumerated below. If you have any questions regarding the connection or procedure, consult your local system administrator or network expert. 1. Log on to a host at your site that is connected to Internet and is running software supporting the FTP command. 2. Invoke FTP on most systems by entering the Internet address of the server: % ftp ftp.ncza.uiuc.edu or % ftp 128.174.20.50 3. Log in by entering anonymous for the name. 4. Enter your name for the password. 5. Enter get README. FIRST to transfer the instructions file (ASCII) to your local host. 6. Enter quit to exit FTP and return to your local host. 7. Review the README.FIRST file for complete instructions concerning the organization of the FTP directories and the procedures you should follow to download the README files specific to the application you want. Your login session should resemble the following sample, where the remote user's name is smith and user entries are indicated in boldface type. harriet_51% ftp ftp.ncsa.uiuc.edu Connected to zaphod. 220 zaphod FTP server (Version 4.173 Tue Jan 31 08:29:00 CST 1989) ready. Name (ftp.ncsa.uiuc.edu: smith): anonymous 331 Guest login ok, send ident as password. Password: smith 230 Guest login ok, access restrictions apply. ftp> get README.FIRST 200 PORT command successful. 150 Opening ASCII mode data connection for README.FIRST (10283 bytes). 226 Transfer complete. local: README.FIRST remote: README.FIRST 11066 bytes received in .34 seconds (32 Kbytes/s) ftp> quit 221 Goodbye. harriet_52% The README.FIRST file instructs you to copy the HDF README file to your directory and read it before proceeding. Your FTP session should resemble the one listed below: ftp> cd HDF 250 CWD command successful. ftp> get README 200 PORT command successful. 150 Opening ASCII mode data connection for README (10283 bytes) 226 Transfer complete. local: README remote: README 2080 bytes received in .14 seconds (15 Kbytes/s) ftp> quit 221 Goodbye. harriet_52% The HDF README file explains how to copy the contents of the HDF directory to your home directory via remote login or anonymous FTP. The precise file transfer procedure varies according to the type of operating system under which you will use HDF-UNICOS or other. Archive Server To obtain NCSA software via an archive server: 1. E-mail a request to: archive-server@ncsa.uiuc.edu 2. Include in the subject or message line, the word "help." 3. Press RETURN. 4. Send another e-mail request to: archive-server@ncsa.uiuc.edu 5. Include in the subject or message line, the word "index." 6. Press RETURN. For example, if you use the UNIX mailing system, your login session should resemble the following sample, where user entries are indicated in boldface type. yoyodyne_51% mail archive-server@ncsa.uiuc.edu Subject: help EOT Null message body; hope that's ok yoyodyne_52% mail archive-server@ncsa.uiuc.edu Subject: index . EOT Null message body; hope that's ok The information you receive from both the help and index commands will give you further instructions on obtaining NCSA software. This controlled-access server will e-mail the distribution to you one segment at a time. Mail HDF software and manuals are available for purchase--either individually or as part of the anonymous FTP reel or cartridge tapes-through the NCSA Technical Resources Catalog. Orders can only be processed if accompanied by a check in U.S. dollars made out to the University of Illinois. To obtain a catalog, contact: NCSA Documentation Orders 152 Computing Applications Building 605 East Springfield Avenue Champaign, IL 61820 (217) 244-0072 Bugs and Suggestions Please notify us of any bugs you have found in our software and any suggestions you have for future releases or products. Using the report form below, mail user feedback, bugs, or software suggestions via U.S. mail to: NCSA Software Development 152 Computing Applications Bldg. 605 East Springfield Avenue Champaign, IL 61820 Send reports regarding bugs via electronic mail to: bugs@ncsa.uiuc.edu bugs@ncsavmsa.bitnet Send reports regarding software suggestions or comments via electronic mail to: softdev@ncsa.uiuc.edu softdev@ncsavmsa.bitnet Or contact Jason Ng at (217) 244-8524 email: jng@ncsa.uiuc.edu Name: Institution: Address (Electronic): Address (U.S. Mail): Telephone: ( ) - Version of NCSA HDF Vset Type of machine: Version of system software: Suggestion or description of problem: NCSA Software Development HDF Vset 152 Computing Applications Building 605 East Springfield Avenue Champaign, IL 61820