2.1.1. Example NeXus C programs using native HDF5 commands¶
C-language code examples are provided for writing and reading NeXus-compliant files using the native HDF5 interfaces. These examples are derived from the simple NAPI examples for writing and reading given in the Introduction chapter. Compare these code examples with Example NeXus programs using NAPI.
2.1.1.1. Writing a simple NeXus file using native HDF5 commands in C¶
Note
This example uses the signal/axes attributes applied to the data field, as described in Associating plottable data by name using the axes attribute. New code should use the method described in Associating plottable data using attributes applied to the NXdata group.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | /**
* This is an example how to write a valid NeXus file
* using the HDF-5 API alone. Ths structure which is
* going to be created is:
*
* scan:NXentry
* data:NXdata
* counts[]
* @signal=1
* two_theta[]
* @units=degrees
*
* WARNING: each of the HDF function below needs to be
* wrapped into something like:
*
* if((hdfid = H5function(...)) < 0){
* handle error gracefully
* }
* I left the error checking out in order to keep the
* code clearer
*
* This also installs a link from /scan/data/two_theta to /scan/hugo
*
* Mark Koennecke, October 2011
*/
#include <hdf5.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 400
int main(int argc, char *argv[])
{
float two_theta[LENGTH];
int counts[LENGTH], i, rank, signal;
/* HDF-5 handles */
hid_t fid, fapl, gid, atts, atttype, attid;
hid_t datatype, dataspace, dataprop, dataid;
hsize_t dim[1], maxdim[1];
/* create some data: nothing NeXus or HDF-5 specific */
for(i = 0; i < LENGTH; i++){
two_theta[i] = 10. + .1*i;
counts[i] = (int)(1000 * ((float)random()/(float)RAND_MAX));
}
dim[0] = LENGTH;
maxdim[0] = LENGTH;
rank = 1;
/*
* open the file. The file attribute forces normal file
* closing behaviour down HDF-5's throat
*/
fapl = H5Pcreate(H5P_FILE_ACCESS);
H5Pset_fclose_degree(fapl,H5F_CLOSE_STRONG);
fid = H5Fcreate("NXfile.h5", H5F_ACC_TRUNC, H5P_DEFAULT,fapl);
H5Pclose(fapl);
/*
* create scan:NXentry
*/
gid = H5Gcreate(fid, (const char *)"scan",0);
/*
* store the NX_class attribute. Notice that you
* have to take care to close those hids after use
*/
atts = H5Screate(H5S_SCALAR);
atttype = H5Tcopy(H5T_C_S1);
H5Tset_size(atttype, strlen("NXentry"));
attid = H5Acreate(gid,"NX_class", atttype, atts, H5P_DEFAULT);
H5Awrite(attid, atttype, (char *)"NXentry");
H5Sclose(atts);
H5Tclose(atttype);
H5Aclose(attid);
/*
* same thing for data:Nxdata in scan:NXentry.
* A subroutine would be nice to have here.......
*/
gid = H5Gcreate(fid, (const char *)"/scan/data",0);
atts = H5Screate(H5S_SCALAR);
atttype = H5Tcopy(H5T_C_S1);
H5Tset_size(atttype, strlen("NXdata"));
attid = H5Acreate(gid,"NX_class", atttype, atts, H5P_DEFAULT);
H5Awrite(attid, atttype, (char *)"NXdata");
H5Sclose(atts);
H5Tclose(atttype);
H5Aclose(attid);
/*
* store the counts dataset
*/
dataspace = H5Screate_simple(rank,dim,maxdim);
datatype = H5Tcopy(H5T_NATIVE_INT);
dataprop = H5Pcreate(H5P_DATASET_CREATE);
dataid = H5Dcreate(gid,(char *)"counts",datatype,dataspace,dataprop);
H5Dwrite(dataid, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, counts);
H5Sclose(dataspace);
H5Tclose(datatype);
H5Pclose(dataprop);
/*
* set the signal=1 attribute
*/
atts = H5Screate(H5S_SCALAR);
atttype = H5Tcopy(H5T_NATIVE_INT);
H5Tset_size(atttype,1);
attid = H5Acreate(dataid,"signal", atttype, atts, H5P_DEFAULT);
signal = 1;
H5Awrite(attid, atttype, &signal);
H5Sclose(atts);
H5Tclose(atttype);
H5Aclose(attid);
H5Dclose(dataid);
/*
* store the two_theta dataset
*/
dataspace = H5Screate_simple(rank,dim,maxdim);
datatype = H5Tcopy(H5T_NATIVE_FLOAT);
dataprop = H5Pcreate(H5P_DATASET_CREATE);
dataid = H5Dcreate(gid,(char *)"two_theta",datatype,dataspace,dataprop);
H5Dwrite(dataid, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, two_theta);
H5Sclose(dataspace);
H5Tclose(datatype);
H5Pclose(dataprop);
/*
* set the units attribute
*/
atttype = H5Tcopy(H5T_C_S1);
H5Tset_size(atttype, strlen("degrees"));
atts = H5Screate(H5S_SCALAR);
attid = H5Acreate(dataid,"units", atttype, atts, H5P_DEFAULT);
H5Awrite(attid, atttype, (char *)"degrees");
H5Sclose(atts);
H5Tclose(atttype);
H5Aclose(attid);
/*
* set the target attribute for linking
*/
atttype = H5Tcopy(H5T_C_S1);
H5Tset_size(atttype, strlen("/scan/data/two_theta"));
atts = H5Screate(H5S_SCALAR);
attid = H5Acreate(dataid,"target", atttype, atts, H5P_DEFAULT);
H5Awrite(attid, atttype, (char *)"/scan/data/two_theta");
H5Sclose(atts);
H5Tclose(atttype);
H5Aclose(attid);
H5Dclose(dataid);
/*
* make a link in /scan to /scan/data/two_theta, thereby
* renaming two_theta to hugo
*/
H5Glink(fid,H5G_LINK_HARD,"/scan/data/two_theta","/scan/hugo");
/*
* close the file
*/
H5Fclose(fid);
}
|
2.1.1.2. Reading a simple NeXus file using native HDF5 commands in C¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | /**
* Reading example for reading NeXus files with plain
* HDF-5 API calls. This reads out counts and two_theta
* out of the file generated by nxh5write.
*
* WARNING: I left out all error checking in this example.
* In production code you have to take care of those errors
*
* Mark Koennecke, October 2011
*/
#include <hdf5.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
float *two_theta = NULL;
int *counts = NULL, rank, i;
hid_t fid, dataid, fapl;
hsize_t *dim = NULL;
hid_t datatype, dataspace, memdataspace;
/*
* Open file, thereby enforcing proper file close
* semantics
*/
fapl = H5Pcreate(H5P_FILE_ACCESS);
H5Pset_fclose_degree(fapl,H5F_CLOSE_STRONG);
fid = H5Fopen("NXfile.h5", H5F_ACC_RDONLY,fapl);
H5Pclose(fapl);
/*
* open and read the counts dataset
*/
dataid = H5Dopen(fid,"/scan/data/counts");
dataspace = H5Dget_space(dataid);
rank = H5Sget_simple_extent_ndims(dataspace);
dim = malloc(rank*sizeof(hsize_t));
H5Sget_simple_extent_dims(dataspace, dim, NULL);
counts = malloc(dim[0]*sizeof(int));
memdataspace = H5Tcopy(H5T_NATIVE_INT32);
H5Dread(dataid,memdataspace,H5S_ALL, H5S_ALL,H5P_DEFAULT, counts);
H5Dclose(dataid);
H5Sclose(dataspace);
H5Tclose(memdataspace);
/*
* open and read the two_theta data set
*/
dataid = H5Dopen(fid,"/scan/data/two_theta");
dataspace = H5Dget_space(dataid);
rank = H5Sget_simple_extent_ndims(dataspace);
dim = malloc(rank*sizeof(hsize_t));
H5Sget_simple_extent_dims(dataspace, dim, NULL);
two_theta = malloc(dim[0]*sizeof(float));
memdataspace = H5Tcopy(H5T_NATIVE_FLOAT);
H5Dread(dataid,memdataspace,H5S_ALL, H5S_ALL,H5P_DEFAULT, two_theta);
H5Dclose(dataid);
H5Sclose(dataspace);
H5Tclose(memdataspace);
H5Fclose(fid);
for(i = 0; i < dim[0]; i++){
printf("%8.2f %10d\n", two_theta[i], counts[i]);
}
}
|