https://github.com/geodynamics/citcoms
Revision 7f010dc7da1be608224a65895765bc0511621189 authored by Luis Armendariz on 10 October 2006, 07:29:28 UTC, committed by Luis Armendariz on 10 October 2006, 07:29:28 UTC
2. Wrapped most calls to set_attribute() to avoid using addresses as arguments 3. Added set_attribute_{int,float,double}_vector() functions
1 parent 24fcb93
Tip revision: 7f010dc7da1be608224a65895765bc0511621189 authored by Luis Armendariz on 10 October 2006, 07:29:28 UTC
1. Added PID to metadata to make it easier to identify the corresponding .cfg file
1. Added PID to metadata to make it easier to identify the corresponding .cfg file
Tip revision: 7f010dc
h5tocap.c
/*
* h5tocap.c by Luis Armendariz.
* Copyright (C) 2006, California Institute of Technology.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "hdf5.h"
typedef struct cap_t
{
int id;
char name[8];
hid_t group;
} cap_t;
typedef struct field_t
{
const char *name;
int rank;
hsize_t *dims;
hsize_t *maxdims;
hsize_t *offset;
hsize_t *count;
int n;
float *data;
} field_t;
static herr_t read_steps(hid_t file_id, int **steps, int *numsteps);
static cap_t *open_cap(hid_t file_id, int capid);
static herr_t close_cap(cap_t *cap);
static field_t *open_field(cap_t *cap, const char *name);
static herr_t read_field(cap_t *cap, field_t *field, int frame);
static herr_t close_field(field_t *field);
static herr_t get_attribute_str(hid_t obj_id, const char *attr_name, char **data);
static herr_t get_attribute_int(hid_t input, const char *name, int *val);
static herr_t get_attribute(hid_t obj_id, const char *attr_name, hid_t mem_type_id, void *data);
static herr_t get_attribute_mem(hid_t obj_id, const char *attr_name, hid_t mem_type_id, void *data);
static herr_t get_attribute_disk(hid_t loc_id, const char *attr_name, void *attr_out);
static herr_t get_attribute_info(hid_t obj_id, const char *attr_name, hsize_t *dims, H5T_class_t *type_class, size_t *type_size, hid_t *type_id);
int main(int argc, char *argv[])
{
FILE *file;
char filename[100];
char *datafile;
hid_t h5file;
hid_t input;
herr_t status;
int id;
int caps;
cap_t **cap;
int t;
int n, i, j, k;
int nodex, nodey, nodez;
int step;
int *steps;
int numsteps;
int frame;
int *frames;
int timesteps;
char *endptr;
field_t *coord;
field_t *velocity;
field_t *temperature;
field_t *viscosity;
/************************************************************************
* Parse command-line parameters. *
************************************************************************/
/*
* HDF5 file must be specified as first argument.
*/
if (argc < 2)
{
fprintf(stderr, "Usage: %s file.h5 [frame1 [frame2 [...]]]\n", argv[0]);
return EXIT_FAILURE;
}
/*
* Recognize help arguments.
*/
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
{
fprintf(stderr, "Usage: %s file.h5 [frame1 [frame2 [...]]]\n", argv[0]);
return EXIT_FAILURE;
}
/*
* Open HDF5 file (read-only). Complain if invalid.
*/
h5file = H5Fopen(argv[1], H5F_ACC_RDONLY, H5P_DEFAULT);
if (h5file < 0)
{
fprintf(stderr, "Could not open HDF5 file \"%s\"\n", argv[1]);
return EXIT_FAILURE;
}
/*
* Read steps from file
*/
status = read_steps(h5file, &steps, &numsteps);
if (argc == 2)
{
printf("Found %d frames in the file \"%s\"\n\n", numsteps, argv[1]);
printf("Usage: %s file.h5 [frame1 [frame2 [...]]]\n", argv[0]);
printf("\tPlease specify frames in the range [0,%d]\n", numsteps-1);
status = H5Fclose(h5file);
free(steps);
return EXIT_FAILURE;
}
/*
* Read frame(s) from argv[2:]
*/
/* Allocate at least one step (we know argc > 2) */
timesteps = argc-2;
frames = (int *)malloc(timesteps * sizeof(int));
/* Convert argv[2:] into int array */
for(n = 2; n < argc; n++)
{
frames[n-2] = (int)strtol(argv[n], &endptr, 10);
if (!(argv[n][0] != '\0' && *endptr == '\0'))
{
fprintf(stderr, "Error: Could not parse step \"%s\"\n", argv[n]);
status = H5Fclose(h5file);
return EXIT_FAILURE;
}
}
/* Validate frames */
for(t = 0; t < timesteps; t++)
{
if (frames[t] >= numsteps)
{
fprintf(stderr, "Error: Requested frame %d is not in range "
"[0,%d]\n", frames[t], numsteps-1);
status = H5Fclose(h5file);
return EXIT_FAILURE;
}
}
/************************************************************************
* Get mesh parameters. *
************************************************************************/
/* Read input group */
input = H5Gopen(h5file, "input");
if (input < 0)
{
fprintf(stderr, "Could not open /input group in \"%s\"\n", argv[1]);
status = H5Fclose(h5file);
return EXIT_FAILURE;
}
status = get_attribute_str(input, "datafile", &datafile);
status = get_attribute_int(input, "nproc_surf", &caps);
status = get_attribute_int(input, "nodex", &nodex);
status = get_attribute_int(input, "nodey", &nodey);
status = get_attribute_int(input, "nodez", &nodez);
/* Release input group */
status = H5Gclose(input);
/************************************************************************
* Open all available cap groups. *
************************************************************************/
cap = (cap_t **)malloc(caps * sizeof(cap_t *));
for(id = 0; id < caps; id++)
cap[id] = open_cap(h5file, id);
/************************************************************************
* Create fields using cap00 datasets as a template. *
************************************************************************/
coord = open_field(cap[0], "coord");
velocity = open_field(cap[0], "velocity");
temperature = open_field(cap[0], "temperature");
viscosity = open_field(cap[0], "viscosity");
/************************************************************************
* Output requested data. *
************************************************************************/
/* Iterate over timesteps */
for(t = 0; t < timesteps; t++)
{
/* Determine step */
frame = frames[t];
step = steps[frames[t]];
/* Iterate over caps */
for(id = 0; id < caps; id++)
{
snprintf(filename, (size_t)99, "%s.cap%02d.%d", datafile, id, step);
fprintf(stderr, "Writing %s\n", filename);
file = fopen(filename, "w");
fprintf(file, "%d x %d x %d\n", nodex, nodey, nodez);
/* Read data from HDF5 file. */
read_field(cap[id], coord, 0);
read_field(cap[id], velocity, frame);
read_field(cap[id], temperature, frame);
read_field(cap[id], viscosity, frame);
/* Traverse data in Citcom order */
n = 0;
for(j = 0; j < nodey; j++)
{
for(i = 0; i < nodex; i++)
{
for(k = 0; k < nodez; k++)
{
fprintf(file, "%g %g %g %g %g %g %g %g\n",
coord->data[3*n+0],
coord->data[3*n+1],
coord->data[3*n+2],
velocity->data[3*n+0],
velocity->data[3*n+1],
velocity->data[3*n+2],
temperature->data[n],
viscosity->data[n]);
n++; /* n = k + i*nodez + j*nodez*nodex */
}
}
}
fclose(file);
}
}
/* Release resources. */
for(id = 0; id < caps; id++)
status = close_cap(cap[id]);
free(cap);
status = close_field(coord);
status = close_field(velocity);
status = close_field(temperature);
status = close_field(viscosity);
status = H5Fclose(h5file);
free(steps);
free(frames);
return EXIT_SUCCESS;
}
static herr_t read_steps(hid_t file_id, int **steps, int *numsteps)
{
int rank;
hsize_t dims;
hid_t typeid;
hid_t dataspace;
hid_t dataset;
herr_t status;
dataset = H5Dopen(file_id, "time");
dataspace = H5Dget_space(dataset);
typeid = H5Tcreate(H5T_COMPOUND, sizeof(int));
status = H5Tinsert(typeid, "step", 0, H5T_NATIVE_INT);
rank = H5Sget_simple_extent_dims(dataspace, &dims, NULL);
*numsteps = (int)dims;
*steps = (int *)malloc(dims * sizeof(int));
status = H5Dread(dataset, typeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, *steps);
status = H5Tclose(typeid);
status = H5Sclose(dataspace);
status = H5Dclose(dataset);
return 0;
}
static cap_t *open_cap(hid_t file_id, int capid)
{
cap_t *cap;
cap = (cap_t *)malloc(sizeof(cap_t));
cap->id = capid;
snprintf(cap->name, (size_t)7, "cap%02d", capid);
cap->group = H5Gopen(file_id, cap->name);
if (cap->group < 0)
{
free(cap);
return NULL;
}
return cap;
}
static herr_t close_cap(cap_t *cap)
{
herr_t status;
if (cap != NULL)
{
cap->id = -1;
cap->name[0] = '\0';
status = H5Gclose(cap->group);
free(cap);
}
return 0;
}
static field_t *open_field(cap_t *cap, const char *name)
{
hid_t dataset;
hid_t dataspace;
herr_t status;
int d;
int rank;
field_t *field;
if (cap == NULL)
return NULL;
/* Allocate field and initialize. */
field = (field_t *)malloc(sizeof(field_t));
field->name = name;
field->rank = 0;
field->dims = NULL;
field->maxdims = NULL;
field->n = 0;
dataset = H5Dopen(cap->group, name);
if(dataset < 0)
{
free(field);
return NULL;
}
dataspace = H5Dget_space(dataset);
if (dataspace < 0)
{
free(field);
return NULL;
}
/* Calculate shape of field. */
rank = H5Sget_simple_extent_ndims(dataspace);
field->rank = rank;
field->dims = (hsize_t *)malloc(rank * sizeof(hsize_t));
field->maxdims = (hsize_t *)malloc(rank * sizeof(hsize_t));
status = H5Sget_simple_extent_dims(dataspace, field->dims, field->maxdims);
/* DEBUG
printf("Field %s shape (", name);
for(d = 0; d < rank; d++)
printf("%d,", (int)(field->dims[d]));
printf(")\n");
// */
/* Allocate memory for hyperslab selection parameters. */
field->offset = (hsize_t *)malloc(rank * sizeof(hsize_t));
field->count = (hsize_t *)malloc(rank * sizeof(hsize_t));
/* Allocate enough memory for a single time-slice buffer. */
field->n = 1;
if (field->maxdims[0] == H5S_UNLIMITED)
for(d = 1; d < rank; d++)
field->n *= field->dims[d];
else
for(d = 0; d < rank; d++)
field->n *= field->dims[d];
field->data = (float *)malloc(field->n * sizeof(float));
/* Release resources. */
status = H5Sclose(dataspace);
status = H5Dclose(dataset);
return field;
}
static herr_t read_field(cap_t *cap, field_t *field, int frame)
{
hid_t dataset;
hid_t filespace;
hid_t memspace;
herr_t status;
int d;
if (cap == NULL || field == NULL)
return -1;
dataset = H5Dopen(cap->group, field->name);
if (dataset < 0)
return -1;
for(d = 0; d < field->rank; d++)
{
field->offset[d] = 0;
field->count[d] = field->dims[d];
}
if (field->maxdims[0] == H5S_UNLIMITED)
{
field->offset[0] = frame;
field->count[0] = 1;
}
/* DEBUG
printf("Reading frame %d on field %s with offset (", frame, field->name);
for(d = 0; d < field->rank; d++) printf("%d,", (int)(field->offset[d]));
printf(") and count (");
for(d = 0; d < field->rank; d++) printf("%d,", (int)(field->count[d]));
printf(")\n");
// */
filespace = H5Dget_space(dataset);
status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
field->offset, NULL, field->count, NULL);
memspace = H5Screate_simple(field->rank, field->count, NULL);
status = H5Dread(dataset, H5T_NATIVE_FLOAT, memspace,
filespace, H5P_DEFAULT, field->data);
status = H5Sclose(filespace);
status = H5Sclose(memspace);
status = H5Dclose(dataset);
return 0;
}
static herr_t close_field(field_t *field)
{
if (field != NULL)
{
free(field->dims);
free(field->maxdims);
free(field->offset);
free(field->count);
free(field->data);
free(field);
}
return 0;
}
static herr_t get_attribute_str(hid_t obj_id,
const char *attr_name,
char **data)
{
hid_t attr_id;
hid_t attr_type;
size_t type_size;
herr_t status;
*data = NULL;
attr_id = H5Aopen_name(obj_id, attr_name);
if (attr_id < 0)
return -1;
attr_type = H5Aget_type(attr_id);
if (attr_type < 0)
goto out;
/* Get the size */
type_size = H5Tget_size(attr_type);
if (type_size < 0)
goto out;
/* malloc enough space for the string, plus 1 for trailing '\0' */
*data = (char *)malloc(type_size + 1);
status = H5Aread(attr_id, attr_type, *data);
if (status < 0)
goto out;
/* Set the last character to '\0' in case we are dealing with
* null padded or space padded strings
*/
(*data)[type_size] = '\0';
status = H5Tclose(attr_type);
if (status < 0)
goto out;
status = H5Aclose(attr_id);
if (status < 0)
return -1;
return 0;
out:
H5Tclose(attr_type);
H5Aclose(attr_id);
if (*data)
free(*data);
return -1;
}
static herr_t get_attribute_int(hid_t input, const char *name, int *val)
{
hid_t attr_id;
hid_t type_id;
H5T_class_t type_class;
size_t type_size;
herr_t status;
char *strval;
attr_id = H5Aopen_name(input, name);
type_id = H5Aget_type(attr_id);
type_class = H5Tget_class(type_id);
type_size = H5Tget_size(type_id);
H5Tclose(type_id);
H5Aclose(attr_id);
switch(type_class)
{
case H5T_STRING:
status = get_attribute_str(input, name, &strval);
if (status < 0) return -1;
*val = atoi(strval);
free(strval);
return 0;
case H5T_INTEGER:
status = get_attribute(input, name, H5T_NATIVE_INT, val);
if (status < 0) return -1;
return 0;
}
return -1;
}
static herr_t get_attribute(hid_t obj_id,
const char *attr_name,
hid_t mem_type_id,
void *data)
{
herr_t status;
status = get_attribute_mem(obj_id, attr_name, mem_type_id, data);
if (status < 0)
return -1;
return 0;
}
static herr_t get_attribute_mem(hid_t obj_id,
const char *attr_name,
hid_t mem_type_id,
void *data)
{
hid_t attr_id;
herr_t status;
attr_id = H5Aopen_name(obj_id, attr_name);
if (attr_id < 0)
return -1;
status = H5Aread(attr_id, mem_type_id, data);
if (status < 0)
{
H5Aclose(attr_id);
return -1;
}
status = H5Aclose(attr_id);
if (status < 0)
return -1;
return 0;
}
static herr_t get_attribute_disk(hid_t loc_id,
const char *attr_name,
void *attr_out)
{
hid_t attr_id;
hid_t attr_type;
herr_t status;
attr_id = H5Aopen_name(loc_id, attr_name);
if (attr_id < 0)
return -1;
attr_type = H5Aget_type(attr_id);
if (attr_type < 0)
goto out;
status = H5Aread(attr_id, attr_type, attr_out);
if (status < 0)
goto out;
status = H5Tclose(attr_type);
if (status < 0)
goto out;
status = H5Aclose(attr_id);
if (status < 0)
return -1;
return 0;
out:
H5Tclose(attr_type);
H5Aclose(attr_id);
return -1;
}
static herr_t get_attribute_info(hid_t obj_id,
const char *attr_name,
hsize_t *dims,
H5T_class_t *type_class,
size_t *type_size,
hid_t *type_id)
{
hid_t attr_id;
hid_t space_id;
herr_t status;
int rank;
/* Open the attribute. */
attr_id = H5Aopen_name(obj_id, attr_name);
if (attr_id < 0)
return -1;
/* Get an identifier for the datatype. */
*type_id = H5Aget_type(attr_id);
/* Get the class. */
*type_class = H5Tget_class(*type_id);
/* Get the size. */
*type_size = H5Tget_size(*type_id);
/* Get the dataspace handle */
space_id = H5Aget_space(attr_id);
if (space_id < 0)
goto out;
/* Get dimensions */
rank = H5Sget_simple_extent_dims(space_id, dims, NULL);
if (rank < 0)
goto out;
/* Terminate access to the dataspace */
status = H5Sclose(space_id);
if (status < 0)
goto out;
/* End access to the attribute */
status = H5Aclose(attr_id);
if (status < 0)
goto out;
return 0;
out:
H5Tclose(*type_id);
H5Aclose(attr_id);
return -1;
}
Computing file changes ...