From 9f7a8fbc8bbf8bef5535d2d7adf65687c6c3176a Mon Sep 17 00:00:00 2001 From: tradke Date: Mon, 12 Nov 2007 16:24:14 +0000 Subject: moved driver-independent HDF5 utilities from here to CactusExternal/HDF5 git-svn-id: http://svn.cactuscode.org/arrangements/CactusPUGHIO/IOHDF5/trunk@232 4825ed28-b72c-4eae-9704-e50c059e567d --- doc/documentation.tex | 9 - src/make.configuration.defn | 2 +- src/util/hdf5_double_to_single.c | 342 ------------------------------- src/util/hdf5_extract.c | 420 --------------------------------------- src/util/hdf5_merge.c | 375 ---------------------------------- 5 files changed, 1 insertion(+), 1147 deletions(-) delete mode 100644 src/util/hdf5_double_to_single.c delete mode 100644 src/util/hdf5_extract.c delete mode 100644 src/util/hdf5_merge.c diff --git a/doc/documentation.tex b/doc/documentation.tex index 55ea7d2..645a098 100644 --- a/doc/documentation.tex +++ b/doc/documentation.tex @@ -308,15 +308,6 @@ Thorn \ThisThorn\ provides the following utility programs: \item {\tt hdf5\_convert\_from\_sdf}\\ Converts a datafile created by thorn {\bf CactusIO/IOSDF} or other Cactus-external programs into an HDF5 datafile. Your thornlist must include this thorn in its thornlist in order to build the SDF-to-HDF5 utility program. - \item {\tt hdf5\_merge}\\ - Merges a list of HDF5 input files into a single HDF5 output file. - This can be used to concatenate HDF5 output data created as one file per - timestep. - \item {\tt hdf5\_extract}\\ - Extracts a given list of named objects (groups or datasets) from an HDF5 - input file and writes them into a new HDF5 output file. - This is the reverse operation to what {\tt hdf5\_merge.c} does. Useful eg. - for extracting individual timesteps from a time series HDF5 datafile. \end{itemize} % All utility programs are located in the {\tt src/util/} subdirectory of thorn diff --git a/src/make.configuration.defn b/src/make.configuration.defn index 7e9ca9d..764fd00 100644 --- a/src/make.configuration.defn +++ b/src/make.configuration.defn @@ -2,7 +2,7 @@ # $Header$ # add the recombiner and the IEEEIO converter to the Cactus utitlity tools -ALL_UTILS += hdf5_recombiner hdf5_merge hdf5_extract hdf5_double_to_single hdf5_convert_from_carpetiohdf5 +ALL_UTILS += hdf5_recombiner hdf5_convert_from_carpetiohdf5 ifneq ($(strip $(HAVE_FLEXIO)), ) ALL_UTILS += hdf5_convert_from_ieeeio diff --git a/src/util/hdf5_double_to_single.c b/src/util/hdf5_double_to_single.c deleted file mode 100644 index 67ce10f..0000000 --- a/src/util/hdf5_double_to_single.c +++ /dev/null @@ -1,342 +0,0 @@ - /*@@ - @file hdf5_double_to_single.c - @date Thu 10 Jan 2002 - @author Thomas Radke - @desc - This utility program copies a Cactus HDF5 datafile reverting - double-precision datasets into single-precision. - @enddesc - @version $Id$ - @@*/ - -#include "cctk.h" - -#include -#include -#include -#include -#include "CactusPUGHIO/IOHDF5Util/src/ioHDF5UtilGH.h" - -/* the rcs ID and its dummy function to use it */ -static const char *rcsid = "$Header$"; -CCTK_FILEVERSION(CactusPUGHIO_IOHDF5_util_hdf5_double_to_single_c) - - -/*****************************************************************************/ -/* macro definitions */ -/*****************************************************************************/ -/* uncomment the following to get some debugging output */ -/* #define IOHDF5_DEBUG 1 */ - -/* macro to do an HDF5 call, check its return code, and print a warning - in case of an error */ -#define CHECK_ERROR(hdf5_call) \ - do \ - { \ - int _error_code = hdf5_call; \ - \ - \ - if (_error_code < 0) \ - { \ - fprintf (stderr, "WARNING: line %d: HDF5 call '%s' returned " \ - "error code %d\n", \ - __LINE__, #hdf5_call, _error_code); \ - nerrors++; \ - } \ - } while (0) - - -/*****************************************************************************/ -/* global variables */ -/*****************************************************************************/ -/* NOTE: although it isn't good programming practice - we make these variables global for convenience - since they are accessed from recursively or - indirectly called routines which only get passed - a single user-supplied argument */ -static char *pathname = NULL; /* pathname of the current object */ -static unsigned int nerrors = 0; /* global error counter */ - -/*****************************************************************************/ -/* local function prototypes */ -/*****************************************************************************/ -static herr_t CopyObject (hid_t copy_from, const char *objectname, void *arg); -static herr_t CopyAttribute (hid_t src, const char *attr_name, void *arg); - - - /*@@ - @routine main - @date Thu 10 Jan 2002 - @author Thomas Radke - @desc - Main routine of the HDF5 double-to-single converter - @enddesc - - @calls CopyObject - - @var argc - @vdesc number of command line arguments - @vtype int - @vio in - @endvar - @var argv - @vdesc command line arguments - @vtype char *[] - @vio in - @endvar - - @returntype int - @returndesc - 0 for success, negative return values indicate an error - @endreturndesc -@@*/ -int main (int argc, char *argv[]) -{ - hid_t infile, outfile; - - - /* give some help if called with incorrect number of parameters */ - if (argc != 3) - { - fprintf (stderr, "Usage: %s \n", argv[0]); - fprintf (stderr, " eg, %s alp.h5 alp_single.h5\n\n", argv[0]); - return (0); - } - - H5E_BEGIN_TRY - { - /* open the input file */ - infile = H5Fopen (argv[1], H5F_ACC_RDONLY, H5P_DEFAULT); - if (infile < 0) - { - fprintf (stderr, "ERROR: Cannot open HDF5 input file '%s' !\n\n",argv[1]); - return (-1); - } - - /* create output file */ - outfile = H5Fcreate (argv[2], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - if (outfile < 0) - { - fprintf (stderr, "ERROR: Cannot create HDF5 output file '%s' !\n\n", - argv[2]); - return (-1); - } - } H5E_END_TRY - - printf ("\n --------------------------------------------------\n" - " Cactus 4 HDF5 double-to-single precision Converter\n" - " --------------------------------------------------\n"); - - /* do the copying by iterating over all objects */ - pathname = ""; - CHECK_ERROR (H5Giterate (infile, "/", NULL, CopyObject, &outfile)); - - /* finally, close all open files */ - CHECK_ERROR (H5Fclose (infile)); - CHECK_ERROR (H5Fclose (outfile)); - - /* report status */ - if (nerrors == 0) - { - printf ("\n\n *** All Cactus data successfully converted. ***\n\n"); - } - else - { - fprintf (stderr, "\n\n *** WARNING: %d errors occured during " - "conversion. ***\n\n", nerrors); - } - - return (0); -} - - -/*****************************************************************************/ -/* local routines */ -/*****************************************************************************/ - /*@@ - @routine CopyObject - @date Thu 10 Jan 2002 - @author Thomas Radke - @desc - Iterator recursively called by H5Giterate() for every object - in the input file - @enddesc - - @calls CopyAttribute - - @var from - @vdesc identifier for the group the current object belongs to - @vtype hid_t - @vio in - @endvar - @var objectname - @vdesc name of the current object - @vtype const char * - @vio in - @endvar - @var _to - @vdesc user-supplied argument indicating the output object identifier - @vtype hid_t - @vio in - @endvar - - @returntype int - @returndesc - 0 - continue the iteration for following group objects - 1 - short-curcuit, no further iteration of this group - @endreturndesc -@@*/ -static herr_t CopyObject (hid_t from, - const char *objectname, - void *_to) -{ - hid_t to, datatype, dataspace; - H5G_stat_t objectinfo; - char *current_pathname; - size_t objectsize; - char *data; - - - /* build the full pathname for the current to object to process */ - current_pathname = pathname; - pathname = (char *) malloc (strlen (current_pathname) + - strlen (objectname) + 2); - sprintf (pathname, "%s/%s", current_pathname, objectname); - - /* get the output object identifier */ - to = *(hid_t *) _to; - - /* check the type of the current object */ - CHECK_ERROR (H5Gget_objinfo (from, objectname, 0, &objectinfo)); - if (objectinfo.type == H5G_GROUP) - { - printf (" copying group '%s'\n", pathname); - - CHECK_ERROR (from = H5Gopen (from, objectname)); - CHECK_ERROR (to = H5Gcreate (to, objectname, 0)); - /* iterate over all objects in the (first) input file */ - CHECK_ERROR (H5Giterate (from, ".", NULL, CopyObject, &to)); - CHECK_ERROR (H5Aiterate (from, NULL, CopyAttribute, &to)); - CHECK_ERROR (H5Gclose (to)); - CHECK_ERROR (H5Gclose (from)); - } - else if (objectinfo.type == H5G_DATASET) - { - CHECK_ERROR (from = H5Dopen (from, objectname)); - CHECK_ERROR (dataspace = H5Dget_space (from)); - CHECK_ERROR (datatype = H5Dget_type (from)); - if (H5Tget_class (datatype) == H5T_FLOAT) - { - CHECK_ERROR (H5Tclose (datatype)); - CHECK_ERROR (datatype = H5Tcopy (H5T_NATIVE_FLOAT)); - printf (" converting dataset '%s'\n", pathname); - } - else - { - printf (" copying dataset '%s'\n", pathname); - } - CHECK_ERROR (to = H5Dcreate (to, objectname, datatype, dataspace, - H5P_DEFAULT)); - objectsize = H5Tget_size (datatype); - if (H5Sis_simple (dataspace)) - { - objectsize *= H5Sget_simple_extent_npoints (dataspace); - } - if (objectsize > 0) - { - data = (char *) malloc (objectsize); - CHECK_ERROR (H5Dread (from, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, - data)); - CHECK_ERROR (H5Dwrite (to, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT,data)); - free (data); - } - CHECK_ERROR (H5Aiterate (from, NULL, CopyAttribute, &to)); - CHECK_ERROR (H5Dclose (to)); - CHECK_ERROR (H5Dclose (from)); - CHECK_ERROR (H5Sclose (dataspace)); - CHECK_ERROR (H5Tclose (datatype)); - } - else - { - fprintf (stderr, "WARNING: Found object '%s' which is neither a group " - "nor a dataset ! Object will not be copied.\n", pathname); - nerrors++; - } - - /* reset the pathname */ - free (pathname); - pathname = current_pathname; - - return (0); -} - - - /*@@ - @routine CopyAttribute - @date Thu 10 Jan 2002 - @author Thomas Radke - @desc - Iterator recursively called by H5Aiterate() for every attribute - of an object (dataset or group) - @enddesc - - @var from - @vdesc identifier for the group or dataset to read the attribute from - @vtype hid_t - @vio in - @endvar - @var attrname - @vdesc name of the current attribute - @vtype const char * - @vio in - @endvar - @var _to - @vdesc user-supplied argument indicating the group or dataset - to copy the attribute to - @vtype hid_t - @vio in - @endvar - - @returntype int - @returndesc - 0 - continue the iteration for following attributes - @endreturndesc -@@*/ -static herr_t CopyAttribute (hid_t from, - const char *attrname, - void *_to) -{ - hid_t attr, datatype, dataspace, to; - size_t attrsize; - void *value; - - - /* get the target group/dataset identifier */ - to = *(hid_t *) _to; - - /* open the attribute given by its name, get type, dataspace, and value - and just copy it */ - CHECK_ERROR (attr = H5Aopen_name (from, attrname)); - CHECK_ERROR (datatype = H5Aget_type (attr)); - CHECK_ERROR (dataspace = H5Aget_space (attr)); - attrsize = H5Tget_size (datatype); - if (H5Sis_simple (dataspace) > 0) - { - attrsize *= H5Sget_simple_extent_npoints (dataspace); - } - if (attrsize > 0) - { - value = malloc (attrsize); - CHECK_ERROR (H5Aread (attr, datatype, value)); - CHECK_ERROR (H5Aclose (attr)); - CHECK_ERROR (attr = H5Acreate (to, attrname, datatype, dataspace, - H5P_DEFAULT)); - CHECK_ERROR (H5Awrite (attr, datatype, value)); - free (value); - } - CHECK_ERROR (H5Aclose (attr)); - CHECK_ERROR (H5Sclose (dataspace)); - CHECK_ERROR (H5Tclose (datatype)); - - return (0); -} diff --git a/src/util/hdf5_extract.c b/src/util/hdf5_extract.c deleted file mode 100644 index 4029472..0000000 --- a/src/util/hdf5_extract.c +++ /dev/null @@ -1,420 +0,0 @@ - /*@@ - @file hdf5_extract.c - @date Thu 19 Feb 2002 - @author Thomas Radke - @desc - This utility program extracts objects from an HDF5 file and writes - them into a new one. - @enddesc - @version $Id$ - @@*/ - -#include "cctk.h" - -#include -#include -#include -#include -#include "CactusPUGHIO/IOHDF5Util/src/ioHDF5UtilGH.h" - -/* the rcs ID and its dummy function to use it */ -static const char *rcsid = "$Header$"; -CCTK_FILEVERSION(CactusPUGHIO_IOHDF5_util_hdf5_extract_c) - - -/*****************************************************************************/ -/* macro definitions */ -/*****************************************************************************/ -/* uncomment the following to get some debugging output */ -/* #define IOHDF5_DEBUG 1 */ - -/* macro to do an HDF5 call, check its return code, and print a warning - in case of an error */ -#define CHECK_ERROR(hdf5_call) \ - do \ - { \ - int _error_code = hdf5_call; \ - \ - \ - if (_error_code < 0) \ - { \ - fprintf (stderr, "WARNING: line %d: HDF5 call '%s' returned " \ - "error code %d\n", \ - __LINE__, #hdf5_call, _error_code); \ - nerrors++; \ - } \ - } while (0) - - -/*****************************************************************************/ -/* global variables */ -/*****************************************************************************/ -/* NOTE: although it isn't good programming practice - we make these variables global for convenience - since they are accessed from recursively or - indirectly called routines which only get passed - a single user-supplied argument */ -static char *pathname = NULL; /* pathname of the current object */ -static unsigned int nerrors = 0; /* global error counter */ -static unsigned int check_parents = 0; /* flag to check for parent groups */ - -/*****************************************************************************/ -/* local function prototypes */ -/*****************************************************************************/ -static herr_t CopyObject (hid_t from, const char *objectname, void *_to); -static herr_t CopyAttribute (hid_t src, const char *attr_name, void *arg); - - - /*@@ - @routine main - @date Thu 19 Feb 2002 - @author Thomas Radke - @desc - Main routine of the HDF5 file extractor - @enddesc - - @calls CopyObject - - @var argc - @vdesc number of command line arguments - @vtype int - @vio in - @endvar - @var argv - @vdesc command line arguments - @vtype char *[] - @vio in - @endvar - - @returntype int - @returndesc - 0 for success, negative return values indicate an error - @endreturndesc -@@*/ -int main (int argc, char *argv[]) -{ - char objectname[256]; - FILE *listfile; - hid_t infile, outfile; - - - /* give some help if called with incorrect number of parameters */ - if (argc != 4) - { - fprintf (stderr, "Usage: %s \n", argv[0]); - fprintf (stderr, " where can be created from the output of the h5ls command\n\n"); - fprintf (stderr, " eg, h5ls alp.h5 > listfile\n" - " # now edit listfile to select all datasets to be extracted\n" - " # (don't forget to remove backslashes and the trailing 'Dataset {...}')\n" - " %s extract_list alp.h5 alp_extract.h5\n\n", argv[0]); - - return (0); - } - - /* open the list file */ - listfile = fopen (argv[1], "r"); - if (listfile == NULL) - { - fprintf (stderr, "ERROR: Cannot open list file '%s' !\n\n", argv[1]); - return (-1); - } - - H5E_BEGIN_TRY - { - /* open the input file */ - infile = H5Fopen (argv[2], H5F_ACC_RDONLY, H5P_DEFAULT); - if (infile < 0) - { - fprintf (stderr, "ERROR: Cannot open HDF5 input file '%s' !\n\n",argv[2]); - return (-1); - } - - /* try to open an existing outfile file in append mode, - if this fails create it as a new file */ - outfile = H5Fopen (argv[3], H5F_ACC_RDWR, H5P_DEFAULT); - if (outfile < 0) - { - outfile = H5Fcreate (argv[3], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - } - if (outfile < 0) - { - fprintf (stderr, "ERROR: Cannot create HDF5 output file '%s' !\n\n", - argv[3]); - return (-1); - } - } H5E_END_TRY - - printf ("\n ----------------------------\n" - " Cactus 4 HDF5 File Extractor\n" - " ----------------------------\n"); - - /* do the copying by iterating over all objects */ - while (fgets (objectname, sizeof (objectname), listfile)) - { - /* get rid of the trailing newline */ - objectname[strlen (objectname) - 1] = 0; - pathname = ""; - - check_parents = 1; - CopyObject (infile, objectname, &outfile); - } - - /* finally, close all open files */ - CHECK_ERROR (H5Fclose (infile)); - CHECK_ERROR (H5Fclose (outfile)); - fclose (listfile); - - /* report status */ - if (nerrors == 0) - { - printf ("\n\n *** All objects successfully extracted. ***\n\n"); - } - else - { - fprintf (stderr, "\n\n *** WARNING: %d errors occured during " - "data extraction. ***\n\n", nerrors); - } - - return (0); -} - - -/*****************************************************************************/ -/* local routines */ -/*****************************************************************************/ - /*@@ - @routine CopyObject - @date Thu 19 Feb 2002 - @author Thomas Radke - @desc - Copies an object with given name from the input file into the - output file. - @enddesc - - @calls CopyAttribute - - @var from - @vdesc input group handle - @vtype hid_t - @vio in - @endvar - @var objectname - @vdesc name of the object to extract - @vtype const char * - @vio in - @endvar - @var _to - @vdesc output group handle - @vtype void * - @vio in - @endvar - - @returntype herr_t - @returndesc - 0 - continue the iteration for following group objects - 1 - short-curcuit, no further iteration of this group - @endreturndesc -@@*/ -static herr_t CopyObject (hid_t from, - const char *objectname, - void *_to) -{ - hid_t to, datatype, dataspace, from_group, to_group; - H5G_stat_t objectinfo; - char *current_pathname; - size_t objectsize; - herr_t result; - char *data, *slash; - - - /* get the output object identifier */ - to = *(hid_t *) _to; - - /* check whether the requested object was already extracted */ - H5E_BEGIN_TRY - { - result = H5Gget_objinfo (to, objectname, 0, &objectinfo); - } H5E_END_TRY - if (result >= 0) - { - fprintf (stderr, "WARNING: object '%s' was already extracted\n",objectname); - return (0); - } - - /* check whether the requested object exists */ - H5E_BEGIN_TRY - { - result = H5Gget_objinfo (from, objectname, 0, &objectinfo); - } H5E_END_TRY - if (result < 0) - { - fprintf (stderr, "WARNING: object '%s' will not be extracted (object " - "doesn't exist)\n", objectname); - nerrors++; - return (0); - } - - /* make sure that all parent groups exist */ - if (check_parents) - { - slash = pathname; - /* skip leading slashes */ - while (*slash == '/') - { - slash++; - } - - /* now go through all groups (separated by slashes) */ - while ((slash = strchr (slash, '/')) != NULL) - { - *slash = 0; - - /* try to create the group */ - H5E_BEGIN_TRY - { - to_group = H5Gcreate (to, pathname, 0); - } H5E_END_TRY - if (to_group >= 0) - { - /* copy all attributes */ - CHECK_ERROR (from_group = H5Gopen (from, pathname)); - CHECK_ERROR (H5Aiterate (from_group, NULL, CopyAttribute, &to_group)); - CHECK_ERROR (H5Gclose (from_group)); - CHECK_ERROR (H5Gclose (to_group)); - } - *slash++ = '/'; - } - check_parents = 0; - } - - /* build the full pathname for the current to object to process */ - current_pathname = pathname; - pathname = (char *) malloc (strlen (current_pathname) + - strlen (objectname) + 2); - sprintf (pathname, "%s/%s", current_pathname, objectname); - - /* check the type of the current object */ - if (objectinfo.type == H5G_GROUP) - { - printf (" copying group '%s'\n", pathname); - - CHECK_ERROR (from = H5Gopen (from, objectname)); - CHECK_ERROR (to = H5Gcreate (to, objectname, 0)); - /* iterate over all objects in the (first) input file */ - CHECK_ERROR (H5Giterate (from, ".", NULL, CopyObject, &to)); - CHECK_ERROR (H5Aiterate (from, NULL, CopyAttribute, &to)); - CHECK_ERROR (H5Gclose (to)); - CHECK_ERROR (H5Gclose (from)); - } - else if (objectinfo.type == H5G_DATASET) - { - CHECK_ERROR (from = H5Dopen (from, objectname)); - CHECK_ERROR (dataspace = H5Dget_space (from)); - CHECK_ERROR (datatype = H5Dget_type (from)); - - printf (" copying dataset '%s'\n", pathname); - CHECK_ERROR (to = H5Dcreate (to, objectname, datatype, dataspace, - H5P_DEFAULT)); - objectsize = H5Tget_size (datatype); - if (H5Sis_simple (dataspace)) - { - objectsize *= H5Sget_simple_extent_npoints (dataspace); - } - if (objectsize > 0) - { - data = (char *) malloc (objectsize); - CHECK_ERROR (H5Dread (from, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, - data)); - CHECK_ERROR (H5Dwrite (to, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT,data)); - free (data); - } - CHECK_ERROR (H5Aiterate (from, NULL, CopyAttribute, &to)); - CHECK_ERROR (H5Dclose (to)); - CHECK_ERROR (H5Dclose (from)); - CHECK_ERROR (H5Sclose (dataspace)); - CHECK_ERROR (H5Tclose (datatype)); - } - else - { - fprintf (stderr, "WARNING: Found object '%s' which is neither a group " - "nor a dataset ! Object will not be copied.\n", pathname); - nerrors++; - } - - /* reset the pathname */ - free (pathname); - pathname = current_pathname; - - return (0); -} - - - /*@@ - @routine CopyAttribute - @date Thu 19 Feb 2002 - @author Thomas Radke - @desc - Iterator recursively called by H5Aiterate() for every attribute - of an object (dataset or group) - @enddesc - - @var from - @vdesc identifier for the group or dataset to read the attribute from - @vtype hid_t - @vio in - @endvar - @var attrname - @vdesc name of the current attribute - @vtype const char * - @vio in - @endvar - @var _to - @vdesc user-supplied argument indicating the group or dataset - to copy the attribute to - @vtype hid_t - @vio in - @endvar - - @returntype int - @returndesc - 0 - continue the iteration for following attributes - @endreturndesc -@@*/ -static herr_t CopyAttribute (hid_t from, - const char *attrname, - void *_to) -{ - hid_t attr, datatype, dataspace, to; - size_t attrsize; - void *value; - - - /* get the target group/dataset identifier */ - to = *(hid_t *) _to; - - /* open the attribute given by its name, get type, dataspace, and value - and just copy it */ - CHECK_ERROR (attr = H5Aopen_name (from, attrname)); - CHECK_ERROR (datatype = H5Aget_type (attr)); - CHECK_ERROR (dataspace = H5Aget_space (attr)); - attrsize = H5Tget_size (datatype); - if (H5Sis_simple (dataspace) > 0) - { - attrsize *= H5Sget_simple_extent_npoints (dataspace); - } - if (attrsize > 0) - { - value = malloc (attrsize); - CHECK_ERROR (H5Aread (attr, datatype, value)); - CHECK_ERROR (H5Aclose (attr)); - CHECK_ERROR (attr = H5Acreate (to, attrname, datatype, dataspace, - H5P_DEFAULT)); - CHECK_ERROR (H5Awrite (attr, datatype, value)); - free (value); - } - CHECK_ERROR (H5Aclose (attr)); - CHECK_ERROR (H5Sclose (dataspace)); - CHECK_ERROR (H5Tclose (datatype)); - - return (0); -} diff --git a/src/util/hdf5_merge.c b/src/util/hdf5_merge.c deleted file mode 100644 index 12cd0ec..0000000 --- a/src/util/hdf5_merge.c +++ /dev/null @@ -1,375 +0,0 @@ - /*@@ - @file hdf5_merge.c - @date Thu 10 Jan 2002 - @author Thomas Radke - @desc - This utility program takes a list of Cactus HDF5 datafiles, - merges them at the group hierarchy level and dumps the resulting - tree to a new HDF5 file. - @enddesc - @version $Id$ - @@*/ - -#include "cctk.h" - -#include -#include -#include -#include -#include "CactusPUGHIO/IOHDF5Util/src/ioHDF5UtilGH.h" - -/* the rcs ID and its dummy function to use it */ -static const char *rcsid = "$Header$"; -CCTK_FILEVERSION(CactusPUGHIO_IOHDF5_util_hdf5_merge_c) - - -/*****************************************************************************/ -/* macro definitions */ -/*****************************************************************************/ -/* uncomment the following to get some debugging output */ -/* #define IOHDF5_DEBUG 1 */ - -/* macro to do an HDF5 call, check its return code, and print a warning - in case of an error */ -#define CHECK_ERROR(hdf5_call) \ - do \ - { \ - int _error_code = hdf5_call; \ - \ - \ - if (_error_code < 0) \ - { \ - fprintf (stderr, "WARNING: line %d: HDF5 call '%s' returned " \ - "error code %d\n", \ - __LINE__, #hdf5_call, _error_code); \ - nerrors++; \ - } \ - } while (0) - - -/*****************************************************************************/ -/* global variables */ -/*****************************************************************************/ -/* NOTE: although it isn't good programming practice - we make these variables global for convenience - since they are accessed from recursively or - indirectly called routines which only get passed - a single user-supplied argument */ -static char *pathname = NULL; /* pathname of the current object */ -static unsigned int nerrors = 0; /* global error counter */ - -/*****************************************************************************/ -/* local function prototypes */ -/*****************************************************************************/ -static herr_t CopyObject (hid_t copy_from, const char *objectname, void *arg); -static herr_t CopyAttribute (hid_t src, const char *attr_name, void *arg); - - - /*@@ - @routine main - @date Sat 24 Feb 2001 - @author Thomas Radke - @desc - Main routine of the HDF5 file merger - @enddesc - - @calls CopyObject - - @var argc - @vdesc number of command line arguments - @vtype int - @vio in - @endvar - @var argv - @vdesc command line arguments - @vtype char *[] - @vio in - @endvar - - @returntype int - @returndesc - 0 for success, negative return values indicate an error - @endreturndesc -@@*/ -int main (int argc, char *argv[]) -{ - int i; - hid_t *infiles, outfile; - - - /* give some help if called with incorrect number of parameters */ - if (argc < 3) - { - fprintf (stderr, "Usage: %s [ ...] \n",argv[0]); - fprintf (stderr, " eg, %s alp.time*.h5 alp.h5" - "\n\n", argv[0]); - return (0); - } - - H5E_BEGIN_TRY - { - /* open the input files */ - infiles = (hid_t *) malloc ((argc - 2) * sizeof (hid_t)); - for (i = 0; i < argc - 2; i++) - { - infiles[i] = H5Fopen (argv[i + 1], H5F_ACC_RDONLY, H5P_DEFAULT); - if (infiles[i] < 0) - { - fprintf (stderr, "ERROR: Cannot open HDF5 input file '%s' !\n\n", - argv[i + 1]); - return (-1); - } - } - - /* try to open an existing outfile file in append mode, - if this fails create it as a new file */ - outfile = H5Fopen (argv[argc-1], H5F_ACC_RDWR, H5P_DEFAULT); - if (outfile < 0) - { - outfile = H5Fcreate (argv[argc-1], H5F_ACC_TRUNC, H5P_DEFAULT, - H5P_DEFAULT); - } - if (outfile < 0) - { - fprintf (stderr, "ERROR: Cannot open HDF5 output file '%s' !\n\n", - argv[argc - 1]); - return (-1); - } - } H5E_END_TRY - - printf ("\n -------------------------\n" - " Cactus 4 HDF5 File Merger\n" - " -------------------------\n"); - - /* do the copying by iterating over all objects */ - for (i = 0; i < argc - 2; i++) - { - printf ("\n Merging objects from input file '%s' into output file '%s'\n", - argv[i + 1], argv[argc-1]); - pathname = ""; - CHECK_ERROR (H5Giterate (infiles[i], "/", NULL, CopyObject, &outfile)); - } - - /* finally, close all open files */ - for (i = 0; i < argc - 2; i++) - { - CHECK_ERROR (H5Fclose (infiles[i])); - } - CHECK_ERROR (H5Fclose (outfile)); - free (infiles); - - /* report status */ - if (nerrors == 0) - { - printf ("\n\n *** All input files successfully merged. ***\n\n"); - } - else - { - fprintf (stderr, "\n\n *** WARNING: %d errors occured during " - "file merging. ***\n\n", nerrors); - } - - return (0); -} - - -/*****************************************************************************/ -/* local routines */ -/*****************************************************************************/ - /*@@ - @routine CopyObject - @date Sat 24 Feb 2001 - @author Thomas Radke - @desc - Iterator recursively called by H5Giterate() for every object - in the input file - It copies the current object to the output file if it didn't - already exist there. - @enddesc - - @calls CopyAttribute - - @var from - @vdesc identifier for the group the current object belongs to - @vtype hid_t - @vio in - @endvar - @var objectname - @vdesc name of the current object - @vtype const char * - @vio in - @endvar - @var _to - @vdesc user-supplied argument indicating the output object identifier - @vtype hid_t - @vio in - @endvar - - @returntype int - @returndesc - 0 - continue the iteration for following group objects - 1 - short-curcuit, no further iteration of this group - @endreturndesc -@@*/ -static herr_t CopyObject (hid_t from, - const char *objectname, - void *_to) -{ - int i; - hid_t to, datatype, dataspace; - H5G_stat_t objectinfo; - char *current_pathname; - size_t objectsize; - void *data; - - - /* get the output object identifier */ - to = *(hid_t *) _to; - - /* check whether an object by that name already exists */ - H5E_BEGIN_TRY - { - i = H5Gget_objinfo (to, objectname, 0, &objectinfo) >= 0; - } H5E_END_TRY - if (i) - { - printf (" object '%s/%s' will not be copied (already exists)\n", - pathname, objectname); - return (0); - } - - /* build the full pathname for the current to object to process */ - current_pathname = pathname; - pathname = (char *) malloc (strlen (current_pathname) + - strlen (objectname) + 2); - sprintf (pathname, "%s/%s", current_pathname, objectname); - - /* check the type of the current object */ - CHECK_ERROR (H5Gget_objinfo (from, objectname, 0, &objectinfo)); - if (objectinfo.type == H5G_GROUP) - { - printf (" copying group '%s'\n", pathname); - - CHECK_ERROR (from = H5Gopen (from, objectname)); - CHECK_ERROR (to = H5Gcreate (to, objectname, 0)); - /* iterate over all objects in the (first) input file */ - CHECK_ERROR (H5Giterate (from, ".", NULL, CopyObject, &to)); - CHECK_ERROR (H5Aiterate (from, NULL, CopyAttribute, &to)); - CHECK_ERROR (H5Gclose (to)); - CHECK_ERROR (H5Gclose (from)); - } - else if (objectinfo.type == H5G_DATASET) - { - printf (" copying dataset '%s'\n", pathname); - - CHECK_ERROR (from = H5Dopen (from, objectname)); - CHECK_ERROR (datatype = H5Dget_type (from)); - CHECK_ERROR (dataspace = H5Dget_space (from)); - CHECK_ERROR (to = H5Dcreate (to, objectname, datatype, dataspace, - H5P_DEFAULT)); - objectsize = H5Sget_select_npoints (dataspace) * H5Tget_size (datatype); - if (objectsize > 0) - { - data = malloc (objectsize); - if (data == NULL) - { - fprintf (stderr, "failled to allocate %d bytes of memory, giving up\n", - objectsize); - exit (-1); - } - CHECK_ERROR (H5Dread (from, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, - data)); - CHECK_ERROR (H5Dwrite (to, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT,data)); - free (data); - } - CHECK_ERROR (H5Aiterate (from, NULL, CopyAttribute, &to)); - CHECK_ERROR (H5Dclose (to)); - CHECK_ERROR (H5Dclose (from)); - CHECK_ERROR (H5Sclose (dataspace)); - CHECK_ERROR (H5Tclose (datatype)); - } - else - { - fprintf (stderr, "WARNING: Found object '%s' which is not neither a " - "group nor a dataset ! Object will not be copied.\n", - pathname); - nerrors++; - } - - /* reset the pathname */ - free (pathname); - pathname = current_pathname; - - return (0); -} - - - /*@@ - @routine CopyAttribute - @date Sat 24 Feb 2001 - @author Thomas Radke - @desc - Iterator recursively called by H5Aiterate() for every attribute - of an object (dataset or group) - @enddesc - - @var from - @vdesc identifier for the group or dataset to read the attribute from - @vtype hid_t - @vio in - @endvar - @var attrname - @vdesc name of the current attribute - @vtype const char * - @vio in - @endvar - @var _to - @vdesc user-supplied argument indicating the group or dataset - to copy the attribute to - @vtype hid_t - @vio in - @endvar - - @returntype int - @returndesc - 0 - continue the iteration for following attributes - @endreturndesc -@@*/ -static herr_t CopyAttribute (hid_t from, - const char *attrname, - void *_to) -{ - hid_t attr, datatype, dataspace, to; - size_t attrsize; - void *value; - - - /* get the target group/dataset identifier */ - to = *(hid_t *) _to; - - /* open the attribute given by its name, get type, dataspace, and value - and just copy it */ - CHECK_ERROR (attr = H5Aopen_name (from, attrname)); - CHECK_ERROR (datatype = H5Aget_type (attr)); - CHECK_ERROR (dataspace = H5Aget_space (attr)); - attrsize = H5Tget_size (datatype); - if (H5Sis_simple (dataspace) > 0) - { - attrsize *= H5Sget_simple_extent_npoints (dataspace); - } - if (attrsize > 0) - { - value = malloc (attrsize); - CHECK_ERROR (H5Aread (attr, datatype, value)); - CHECK_ERROR (H5Aclose (attr)); - CHECK_ERROR (attr = H5Acreate (to, attrname, datatype, dataspace, - H5P_DEFAULT)); - CHECK_ERROR (H5Awrite (attr, datatype, value)); - free (value); - } - CHECK_ERROR (H5Aclose (attr)); - CHECK_ERROR (H5Sclose (dataspace)); - CHECK_ERROR (H5Tclose (datatype)); - - return (0); -} -- cgit v1.2.3