HL-HDF
|
When creating your own HDF5 product, there is one header files that should be included (hlhdf.h).
If you are going to create your own compound datatype, then include hlhdf_compound_utils.h as well.
When compiling a binary, there are three libraries that must be linked in; these are libhlhdf.a, libhdf5.a and libz.a. It is also possible to link the shared library libhdf5.so instead of libhdf5.a.
The HL-HDF package was installed with a hldef.mk file that can be included in your own Makefile in order to get the correct paths to both the zlib and the hdf5 library. It also contains information on which C++-compiler the HL-HDF package was compiled with and some other goodies.
A simple Makefile could look like this:
include /usr/local/hlhdf/mkf/hldef.mk HLHDF_INCDIR = -I/usr/local/hlhdf/include HLHDF_LIBDIR = -L/usr/local/hlhdf/lib CFLAGS = $(OPTS) $(DEFS) -I. $(ZLIB_INCDIR) $(HDF5_INCDIR) \ $(HLHDF_INCDIR) LDFLAGS = -L. $(ZLIB_LIBDIR) $(HDF5_LIBDIR) $(HLHDF_LIBDIR) LIBS = -lhlhdf -lhdf5 -lz -lm TARGET=myTestProgram SOURCES=test_program.c OBJECTS=$(SOURCES:.c=.o) all: $(TARGET) $(TARGET): $(OBJECTS) $(CC) -o $@ $(LDFLAGS) $(OBJECTS) $(LIBS) clean: @\rm -f *.o *~ so_locations core distclean: clean @\rm -f $(TARGET) distribution: @echo "Would bring the latest revision upto date" install: @$(HL_INSTALL) -f -o -C $(TARGET) ${MY_BIN_PATH}/$(TARGET)
Now, when the Makefile has been created, it might be a good idea to write your own HDF5 product. The following example will create a dataset with a two-dimensional array of integers, and two attributes connected to this dataset. It will also create a group containing one attribute.
#include <hlhdf.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { HL_NodeList* aList=NULL; HL_Node* aNode=NULL; HL_Compression compression; int* anArray=NULL; int anIntValue; float aFloatValue; hsize_t dims[]={10,10}; int npts=100; int i; HL_init(); /* Initialize the HL-HDF library */ HL_setDebugMode(2); /* Activate debugging */ if(!(aList = HLNodeList_new())) { fprintf(stderr,"Failed to allocate nodelist"); goto fail; } if(!(anArray = malloc(sizeof(int)*npts))) { fprintf(stderr,"Failed to allocate memory for array."); goto fail; } for(i=0;i<npts;i++) anArray[i]=i; HLNodeList_addNode(aList,(aNode = HLNode_newGroup("/group1"))); HLNodeList_addNode(aList,(aNode = HLNode_newAttribute("/group1/attribute1"))); anIntValue=10; HLNode_setScalarValue(aNode,sizeof(anIntValue),(unsigned char*)&anIntValue,"int",-1); HLNodeList_addNode(aList,(aNode = HLNode_newDataset("/dataset1"))); HLNode_setArrayValue(aNode,sizeof(int),2,dims,(unsigned char*)anArray,"int",-1); HLNodeList_addNode(aList,(aNode = HLNode_newAttribute("/dataset1/attribute2"))); anIntValue=20; HLNode_setScalarValue(aNode,sizeof(anIntValue),(unsigned char*)&anIntValue,"int",-1); HLNodeList_addNode(aList,(aNode = HLNode_newAttribute("/dataset1/attribute3"))); aFloatValue=99.99; HLNode_setScalarValue(aNode,sizeof(aFloatValue),(unsigned char*)&aFloatValue, "float",-1); HLNodeList_setFileName(aList,"written_hdffile.hdf"); HLCompression_init(&compression, CT_ZLIB); compression.level = 6; HLNodeList_write(aList,NULL,&compression); HLNodeList_free(aList); exit(0); return 0; /* Won't come here */ fail: HLNodeList_free(aList); exit(1); return 1; /* Won't come here */ }
When you have created your own HDF5 product, it might be a good idea to create some code for reading this file and checking its contents.
#include <hlhdf.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char** argv) { HL_NodeList* aList=NULL; HL_Node* aNode=NULL; int* anArray=NULL; int anIntValue; float aFloatValue; int npts; int i; HL_init(); /* Initialize the HL-HDF library */ HL_setDebugMode(2); /* Activate debugging */ if(!(aList = HLNodeList_read("written_hdffile.hdf"))) { fprintf(stderr,"Failed to read nodelist\n"); goto fail; } HLNodeList_selectAllNodes(aList); /* Select everything for retrival */ HLNodeList_fetchMarkedNodes(aList); if((aNode = HLNodeList_getNodeByName(aList,"/group1"))) printf("%s exists\n",HLNode_getName(aNode)); if((aNode = HLNodeList_getNodeByName(aList,"/group1/attribute1"))) { memcpy(&anIntValue, HLNode_getData(aNode), HLNode_getDataSize(aNode)); printf("%s exists and have value %d\n",HLNode_getName(aNode),anIntValue); } if((aNode = HLNodeList_getNodeByName(aList,"/dataset1"))) { anArray = (int*)HLNode_getData(aNode); npts = 1; for(i=0;i<HLNode_getRank(aNode);i++) npts*=HLNode_getDimension(aNode, i); printf("%s exists and has the values:\n",HLNode_getName(aNode)); for(i=0;i<npts;i++) { printf("%d ", anArray[i]); if((i%HLNode_getDimension(aNode, 0))==0) { printf("\n"); } } printf("\n"); } if((aNode = HLNodeList_getNodeByName(aList,"/dataset1/attribute2"))) { memcpy(&anIntValue,HLNode_getData(aNode),HLNode_getDataSize(aNode)); printf("%s exists and have the value %d\n",HLNode_getName(aNode),anIntValue); } if((aNode = HLNodeList_getNodeByName(aList,"/dataset1/attribute3"))) { memcpy(&aFloatValue,HLNode_getData(aNode),HLNode_getDataSize(aNode)); printf("%s exists and have the value %f\n",HLNode_getName(aNode),aFloatValue); } HLNodeList_free(aList); exit(0); return 0; /* Never reached */ fail: HLNodeList_free(aList); exit(1); return 1; /* Never reached */ }
A small example on how to reroute the error messages is shown below, currently there is no similar functionality for the _pyhl module.
#include <hlhdf.h> #include <hlhdf_debug.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> void hlhdf_error_handler(char* filename, int lineno, HL_Debug lvl, const char* fmt, ...) { va_list alist; char errbuff[512]; va_start(alist,fmt); fprintf(stdout,"<hlhdferror>\n"); fprintf(stdout," <filename>%s</filename>\n",filename); fprintf(stdout," <linenumber>%d</linenumber>\n",lineno); fprintf(stdout," <level>%d</level>\n",lvl); vsprintf(errbuff,fmt,alist); fprintf(stdout," <message>%s</message>\n",errbuff); fprintf(stdout,"</hlhdferror>\n"); } void hdf5_error_handler(unsigned n, const H5E_error_t* rowmsg) { fprintf(stdout,"<hdf5error>\n"); fprintf(stdout," <filename>%s</filename>\n",rowmsg->file_name); fprintf(stdout," <linenumber>%d</linenumber>\n",rowmsg->line); fprintf(stdout," <funcname>%s</funcname>\n",rowmsg->func_name); fprintf(stdout," <desc>%s</desc>\n",rowmsg->desc); fprintf(stdout,"</hdf5error>\n"); } int main(int argc, char** argv) { HL_NodeList* nodelist; HL_init(); /* Initialize the HL-HDF library */ HL_enableErrorReporting(); HL_setDebugFunction(hlhdf_error_handler); HL_setHdf5ErrorFunction(hdf5_error_handler); nodelist = HLNodeList_read("thisdoesnotexist.xxx"); return 0; }