eid_t e5_create_file( const char* filename) { eid_t e5_file_id; eid_t e5_group_id; estatus_t status = E5_SUCCESS; e5_info(E5_DEFAULT, "Creating E5 file '%s'\n", filename); e5_file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if(e5_file_id < 0) { status = E5_WRITE_FAILURE; e5_error(e5_file_id, status, "Failed to create '%s' E5 data file\n", filename); return (eid_t)e5_file_id; } e5_group_id = e5_create_group(e5_file_id, E5_EMISSIVITY_GROUP_NAME_ABS); e5_close_group(e5_group_id); return (eid_t)e5_file_id; }
static estatus_t e5_merge_flash_scalars( eid_t e5_file_id, hid_t f5_file_id, const char* f5_list_name, f5_scalar_list_type f5_list_type) { size_t s; hsize_t dimens_1d; hsize_t maxdimens_1d; hid_t string_type; hsize_t f5_scalar_bytes; hid_t f5_dataspace; hid_t f5_memspace; hid_t f5_dataset; hid_t f5_type; void* f5_data; hid_t e5_em_group_id; int hstatus; size_t e5_scalar_bytes; estatus_t estatus = E5_SUCCESS; string_type = H5Tcopy(H5T_C_S1); H5Tset_size(string_type, F5_MAX_STRING_LENGTH); f5_dataset = H5Dopen(f5_file_id, f5_list_name); if (f5_dataset < 0) { estatus = E5_INVALID_DATASET; e5_error(f5_file_id, estatus, "Failed to open dataset '%s'\n", f5_list_name); return estatus; } f5_dataspace = H5Dget_space(f5_dataset); H5Sget_simple_extent_dims(f5_dataspace, &dimens_1d, &maxdimens_1d); e5_em_group_id = e5_open_group(e5_file_id, E5_EMISSIVITY_GROUP_NAME_ABS); switch(f5_list_type) { case F5_SCALAR_LIST_INTEGER: case F5_SCALAR_LIST_LOGICAL: { hid_t f5_int_list_type; f5_int_list_t *f5_int_list; f5_scalar_bytes = dimens_1d * sizeof(f5_int_list_t); f5_int_list = (f5_int_list_t *) e5_malloc(f5_scalar_bytes); if(!f5_int_list) { estatus = E5_OUT_OF_MEMORY; e5_error(f5_file_id, estatus, "Failed to allocate memory for reading '%s' from F5 data file\n", f5_list_name); break; } memset(f5_int_list, 0, f5_scalar_bytes); f5_int_list_type = H5Tcreate(H5T_COMPOUND, sizeof(f5_int_list_t)); H5Tinsert(f5_int_list_type, "name", HOFFSET(f5_int_list_t, name), string_type); H5Tinsert(f5_int_list_type, "value", HOFFSET(f5_int_list_t, value), H5T_NATIVE_INT); f5_memspace = H5Screate_simple(1, &dimens_1d, NULL); hstatus = H5Dread(f5_dataset, f5_int_list_type, f5_memspace, f5_dataspace, H5P_DEFAULT, f5_int_list); if (hstatus < 0) { estatus = E5_READ_FAILURE; e5_error(f5_file_id, estatus, "Failed to read '%s' dataset from data file\n", f5_list_name); break; } f5_data = f5_int_list; f5_type = f5_int_list_type; if(f5_data) { // Add the scalar list as attributes for the top-level Emissivity group e5_scalar_bytes = (dimens_1d + 1) * sizeof(e5_mutable_attr_int); e5_mutable_attr_int* e5_int_scalars = (e5_mutable_attr_int*) e5_malloc(e5_scalar_bytes); memset(e5_int_scalars, 0, e5_scalar_bytes); for(s = 0; s < dimens_1d; s++) { e5_int_scalars[s].value = f5_int_list[s].value; e5_int_scalars[s].name = e5_trim(f5_int_list[s].name, E5_TRUE, E5_TRUE, F5_MAX_STRING_LENGTH); } e5_write_attr_list_int(e5_em_group_id, (e5_attr_int*)e5_int_scalars); e5_free(e5_int_scalars); } break; } case F5_SCALAR_LIST_REAL: { hid_t f5_real_list_type; f5_real_list_t *f5_real_list; f5_scalar_bytes = dimens_1d * sizeof(f5_real_list_t); f5_real_list = (f5_real_list_t *) e5_malloc(f5_scalar_bytes); if(!f5_real_list) { estatus = E5_OUT_OF_MEMORY; e5_error(f5_file_id, estatus, "Failed to allocate memory for reading '%s' from F5 data file\n", f5_list_name); break; } memset(f5_real_list, 0, f5_scalar_bytes); f5_real_list_type = H5Tcreate(H5T_COMPOUND, sizeof(f5_real_list_t)); H5Tinsert(f5_real_list_type, "name", HOFFSET(f5_real_list_t, name), string_type); H5Tinsert(f5_real_list_type, "value", HOFFSET(f5_real_list_t, value), H5T_NATIVE_DOUBLE); f5_memspace = H5Screate_simple(1, &dimens_1d, NULL); hstatus = H5Dread(f5_dataset, f5_real_list_type, f5_memspace, f5_dataspace, H5P_DEFAULT, f5_real_list); if (hstatus < 0) { estatus = E5_READ_FAILURE; e5_error(f5_file_id, estatus, "Failed to read '%s' from F5 data file\n", f5_list_name); break; } f5_data = f5_real_list; f5_type = f5_real_list_type; if(f5_data) { // Add the scalar list as attributes for the top-level Emissivity group e5_scalar_bytes = (dimens_1d + 1) * sizeof(e5_mutable_attr_double); e5_mutable_attr_double* e5_double_scalars = (e5_mutable_attr_double*) e5_malloc(e5_scalar_bytes); memset(e5_double_scalars, 0, e5_scalar_bytes); for(s = 0; s < dimens_1d; s++) { e5_double_scalars[s].value = f5_real_list[s].value; e5_double_scalars[s].name = f5_real_list[s].name; e5_double_scalars[s].name = e5_trim(f5_real_list[s].name, E5_TRUE, E5_TRUE, F5_MAX_STRING_LENGTH); } e5_write_attr_list_double(e5_em_group_id, (e5_attr_double*)e5_double_scalars); e5_free(e5_double_scalars); } break; } case F5_SCALAR_LIST_STRING: { hid_t f5_str_list_type; f5_str_list_t *f5_str_list; f5_scalar_bytes = dimens_1d * sizeof(f5_str_list_t); f5_str_list = (f5_str_list_t *) e5_malloc(f5_scalar_bytes); if(!f5_str_list) { estatus = E5_OUT_OF_MEMORY; e5_error(f5_file_id, estatus, "Failed to allocate memory for reading '%s' from F5 data file\n", f5_list_name); break; } memset(f5_str_list, 0, f5_scalar_bytes); f5_str_list_type = H5Tcreate(H5T_COMPOUND, sizeof(f5_str_list_t)); H5Tinsert(f5_str_list_type, "name", HOFFSET(f5_str_list_t, name), string_type); H5Tinsert(f5_str_list_type, "value", HOFFSET(f5_str_list_t, value), string_type); f5_memspace = H5Screate_simple(1, &dimens_1d, NULL); hstatus = H5Dread(f5_dataset, f5_str_list_type, f5_memspace, f5_dataspace, H5P_DEFAULT, f5_str_list); if (hstatus < 0) { estatus = E5_READ_FAILURE; e5_error(f5_file_id, estatus, "Failed to read '%s' from F5 data file\n", f5_list_name); break; } f5_data = f5_str_list; f5_type = f5_str_list_type; if(f5_data) { // Add the scalar list as attributes for the top-level Emissivity group e5_scalar_bytes = (dimens_1d + 1) * sizeof(e5_mutable_attr_str); e5_mutable_attr_str* e5_str_scalars = (e5_mutable_attr_str*) e5_malloc(e5_scalar_bytes); memset(e5_str_scalars, 0, e5_scalar_bytes); for(s = 0; s < dimens_1d; s++) { char* trimmed = e5_trim(f5_str_list[s].value, E5_TRUE, E5_TRUE, E5_MAX_ATTR_STRING_LENGTH); strncpy( e5_str_scalars[s].value, trimmed, E5_MAX_ATTR_STRING_LENGTH); e5_str_scalars[s].name = e5_trim(f5_str_list[s].name, E5_TRUE, E5_TRUE, F5_MAX_STRING_LENGTH); } e5_write_attr_list_str(e5_em_group_id, (e5_attr_str*)e5_str_scalars); e5_free(e5_str_scalars); } break; } default: { estatus = E5_INVALID_DATASET; e5_error(f5_file_id, estatus, "Unknown scalar list requested '%s' from F5 data file\n", f5_list_name); break; } }; H5Tclose(f5_type); H5Sclose(f5_memspace); H5Sclose(f5_dataspace); H5Dclose(f5_dataset); e5_free(f5_data); e5_close_group(e5_em_group_id); return estatus; }
estatus_t e5_read_data_info_list( eid_t e5_group_id, const char* list_name, e5_data_info* info_list) { int i; int d; int log_scale; int close_group; estatus_t status; hsize_t h5_min_dim[3]; hsize_t h5_max_dim[3]; eid_t e5_list_group_id; eid_t e5_type_id; eid_t e5_dataset_id; eid_t e5_dataspace_id; status = E5_SUCCESS; if(list_name && strlen(list_name)) { e5_list_group_id = e5_create_group(e5_group_id, list_name); close_group = 1; } else { e5_list_group_id = e5_group_id; close_group = 0; } for(i = 0; info_list && info_list[i].name != 0; i++) { e5_data_info* info = &info_list[i]; e5_dataset_id = H5Dopen(e5_list_group_id, info->name); if (e5_dataset_id < 0) { status = E5_INVALID_DATASET; e5_error(e5_list_group_id, status, "Failed to open info for dataset '%s'\n", info->name); return status; } e5_dataspace_id = H5Dget_space(e5_dataset_id); e5_type_id = H5Dget_type(e5_dataset_id); H5Sget_simple_extent_dims(e5_dataspace_id, h5_min_dim, h5_max_dim); info->type = e5_convert_hdf_type(e5_type_id); for(d = 0; d < 3; d++) { info->dim[d] = h5_min_dim[d] >= h5_max_dim[d] ? h5_min_dim[d] : h5_max_dim[d]; info->dim[d] = info->dim[d] < 1 ? 1 : info->dim[d]; } log_scale = 0; if(e5_is_valid_attr(e5_group_id, "log10")) e5_read_attr_int(e5_dataset_id, "log10", &log_scale); info->scale = log_scale ? E5_VALUE_SCALE_LOG10 : E5_VALUE_SCALE_LINEAR; e5_info(e5_group_id, "Read data info [type='%s', name='%s', dim='%u %u %u']\n", e5_typename(info->type), info->name, info->dim[0], info->dim[1], info->dim[2]); H5Sclose(e5_dataspace_id); H5Dclose(e5_dataset_id); H5Tclose(e5_type_id); } if(close_group) e5_close_group(e5_list_group_id); return E5_SUCCESS; }
estatus_t e5_write_grid_list( eid_t e5_group_id, const char* list_name, e5_grid_dataset* grid_list) { int i; int close_group; estatus_t status; eid_t e5_list_group_id; eid_t e5_dataset_id; eid_t e5_dataspace_id; status = E5_SUCCESS; if(list_name && strlen(list_name)) { e5_list_group_id = e5_create_group(e5_group_id, list_name); close_group = 1; } else { e5_list_group_id = e5_group_id; close_group = 0; } for(i = 0; grid_list && grid_list[i].name != 0 && strlen(grid_list[i].name); i++) { e5_grid_dataset* grid = &grid_list[i]; e5_dataspace_id = H5Screate_simple(3, (hsize_t*)(grid->dim), NULL); switch(grid->type) { case E5_TYPE_INT: { e5_info(e5_group_id, "Writing grid [type='int', name='%s', dim='%u %u %u']\n", grid->name, grid->dim[0], grid->dim[1], grid->dim[2]); e5_dataset_id = H5Dcreate(e5_list_group_id, grid->name, H5T_STD_I32LE, e5_dataspace_id, H5P_DEFAULT); status = H5Dwrite(e5_dataset_id, H5T_NATIVE_INT, H5S_ALL, e5_dataspace_id, H5P_DEFAULT, grid->data); if(status < 0) { status = E5_WRITE_FAILURE; e5_error(e5_dataset_id, status, "Failed to write '%s' E5 grid to file\n", grid->name); } break; } case E5_TYPE_FLOAT: { e5_info(e5_group_id, "Writing grid [type='float', name='%s', dim='%u %u %u']\n", grid->name, grid->dim[0], grid->dim[1], grid->dim[2]); e5_dataset_id = H5Dcreate(e5_list_group_id, grid->name, H5T_IEEE_F32LE, e5_dataspace_id, H5P_DEFAULT); status = H5Dwrite(e5_dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, e5_dataspace_id, H5P_DEFAULT, grid->data); if(status < 0) { status = E5_WRITE_FAILURE; e5_error(e5_dataset_id, status, "Failed to write '%s' E5 grid to file\n", grid->name); } break; } case E5_TYPE_DOUBLE: { e5_info(e5_group_id, "Writing grid [type='float', name='%s', dim='%u %u %u']\n", grid->name, grid->dim[0], grid->dim[1], grid->dim[2]); e5_dataset_id = H5Dcreate(e5_list_group_id, grid->name, H5T_IEEE_F64LE, e5_dataspace_id, H5P_DEFAULT); status = H5Dwrite(e5_dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, e5_dataspace_id, H5P_DEFAULT, grid->data); if(status < 0) { status = E5_WRITE_FAILURE; e5_error(e5_dataset_id, status, "Failed to write '%s' E5 grid to file\n", grid->name); } break; } case E5_TYPE_INVALID: default: { status = E5_INVALID_TYPE; e5_error(e5_dataset_id, status, "Invalid type for grid '%s' data\n", grid->name); } break; }; if(grid->scale == E5_VALUE_SCALE_LOG10) e5_write_attr_int(e5_dataset_id, "log10", 1); H5Sclose(e5_dataspace_id); H5Dclose(e5_dataset_id); } if(close_group) e5_close_group(e5_list_group_id); return E5_SUCCESS; }
estatus_t e5_read_grid_list( eid_t e5_group_id, const char* list_name, e5_grid_dataset* grid_list) { int i; int d; int log_scale; int close_group; hsize_t h5_max_dim[3]; hsize_t h5_min_dim[3]; eid_t e5_list_group_id; eid_t e5_type_id; eid_t e5_dataset_id; eid_t e5_dataspace_id; eid_t e5_memspace_id; hid_t h5_status; estatus_t e5_status = E5_SUCCESS; if(list_name && strlen(list_name)) { e5_list_group_id = e5_create_group(e5_group_id, list_name); close_group = 1; } else { e5_list_group_id = e5_group_id; close_group = 0; } for(i = 0; grid_list && grid_list[i].name != 0; i++) { e5_grid_dataset* grid = &grid_list[i]; if(grid->name == 0 || strlen(grid->name) < 1) continue; e5_dataset_id = H5Dopen(e5_list_group_id, grid->name); if (e5_dataset_id < 0) { e5_status = E5_INVALID_DATASET; e5_error(e5_list_group_id, e5_status, "Failed to open grid dataset '%s'\n", grid->name); return e5_status; } if(!grid->data) { e5_status = E5_INVALID_POINTER; e5_error(e5_dataspace_id, e5_status, "Failed to provide pointer for reading '%s' from E5 data file\n", grid->name); break; } e5_dataspace_id = H5Dget_space(e5_dataset_id); e5_type_id = H5Dget_type(e5_dataset_id); H5Sget_simple_extent_dims(e5_dataspace_id, h5_min_dim, h5_max_dim); for(d = 0; d < 3; d++) { grid->dim[d] = h5_min_dim[d] >= h5_max_dim[d] ? h5_min_dim[d] : h5_max_dim[d]; grid->dim[d] = grid->dim[d] < 1 ? 1 : grid->dim[d]; } grid->type = e5_convert_hdf_type(e5_type_id); switch(grid->type) { case E5_TYPE_FLOAT: { e5_info(e5_group_id, "Reading grid [type='float', name='%s', dim='%u %u %u']\n", grid->name, grid->dim[0], grid->dim[1], grid->dim[2]); e5_memspace_id = H5Screate_simple(3, h5_min_dim, h5_max_dim); h5_status = H5Dread(e5_dataset_id, H5T_NATIVE_FLOAT, e5_memspace_id, e5_dataspace_id, H5P_DEFAULT, (grid->data)); if (h5_status < 0) { e5_status = E5_READ_FAILURE; e5_error(e5_dataset_id, e5_status, "Failed to read '%s' from F5 data file\n", grid->name); } H5Sclose(e5_memspace_id); break; } case E5_TYPE_DOUBLE: { e5_info(e5_group_id, "Reading grid [type='double', name='%s', dim='%u %u %u']\n", grid->name, grid->dim[0], grid->dim[1], grid->dim[2]); e5_memspace_id = H5Screate_simple(3, h5_min_dim, h5_max_dim); h5_status = H5Dread(e5_dataset_id, H5T_NATIVE_DOUBLE, e5_memspace_id, e5_dataspace_id, H5P_DEFAULT, (grid->data)); if (h5_status < 0) { e5_status = E5_READ_FAILURE; e5_error(e5_dataset_id, e5_status, "Failed to read '%s' from F5 data file\n", grid->name); } H5Sclose(e5_memspace_id); break; } case E5_TYPE_INVALID: default: { e5_status = E5_INVALID_TYPE; e5_error(e5_dataset_id, e5_status, "Invalid type for grid '%s' data\n", grid->name); break; } }; log_scale = 0; if(e5_is_valid_attr(e5_dataset_id, "log10")) e5_read_attr_int(e5_dataset_id, "log10", &log_scale); grid->scale = log_scale ? E5_VALUE_SCALE_LOG10 : E5_VALUE_SCALE_LINEAR; H5Sclose(e5_dataspace_id); H5Dclose(e5_dataset_id); H5Tclose(e5_type_id); } if(list_name) e5_close_group(e5_list_group_id); return e5_status; }
int main(int argc, char** argv) { eid_t e5_file_id; eid_t e5_group_id; estatus_t status; /* Parse the command line options */ options_t options = {0}; ParseOptions(&options, argc, argv); /* Open the E5 file and main group */ e5_set_notify_func(E5_DEFAULT, notify_func, E5_NOTIFY_LEVEL_MIN, E5_NOTIFY_LEVEL_MAX); e5_file_id = e5_open_file(options.filename); /* Read the grid dimensionality and type info */ if(options.type == OPT_GRID) { e5_grid_dataset grid = { 0 }; grid.name = options.location; status = e5_read_data_info(e5_file_id, grid.name, grid.dim, &grid.type, &grid.scale); E5_EXIT_ON_ERROR(status); /* Allocate memory and read the grid data */ grid.data = malloc(e5_sizeof(grid.type) * grid.dim[0] * grid.dim[1] * grid.dim[2]); status = e5_read_grid(e5_file_id, grid.name, grid.data, grid.dim, &grid.type, &grid.scale); E5_EXIT_ON_ERROR(status); e5_dump_grid(&grid); free(grid.data); } else if (options.type == OPT_ATTR) { int* data = malloc(sizeof(int)); const char* base_name = e5_basename(options.location); size_t offset = base_name - options.location; char* group_name = malloc(offset + 2); snprintf(group_name, offset, "%s", options.location); e5_group_id = e5_open_group(e5_file_id, group_name); e5_attr attr[] = { {base_name, data, E5_TYPE_INT, 0}, {0} }; status = e5_read_attr_list(e5_group_id, attr); E5_EXIT_ON_ERROR(status); printf("ATTR: '%s' -> '%d'\n", options.location, *data); free(data); free(group_name); e5_close_group(e5_group_id); } /* Close the group and the file */ status = e5_close_file(e5_file_id); E5_EXIT_ON_ERROR(status); /* Free the command line options */ free(options.filename); free(options.location); return 0; }
static void e5_export_bov( const char* bov_file, eid_t e5_file_id, e5_grid_dataset* grid) { static const int min_bricklet = 1; static const int max_bricklet = 32; int i; int d; bov_header_t header; e5_bov_attrs_t attrs; memset(&header, 0, sizeof(bov_header_t)); memset(&attrs, 0, sizeof(e5_bov_attrs_t)); size_t len = strlen(bov_file) + 8; char *data_file = malloc(len); snprintf(data_file, len, "%s.data", e5_basename(bov_file)); eid_t e5_group_id = e5_open_group(e5_file_id, "/Emissivity/real scalars"); e5_attr real_scalars_attr[] = { {"time", &(attrs.time), E5_TYPE_DOUBLE, 0}, {0} }; estatus_t status = e5_read_attr_list(e5_group_id, real_scalars_attr); E5_EXIT_ON_ERROR(status); e5_close_group(e5_group_id); e5_group_id = e5_open_group(e5_file_id, "/Emissivity/real runtime parameters"); e5_attr real_param_attr[] = { {"xmin", &(attrs.xmin), E5_TYPE_DOUBLE, 0}, {"xmax", &(attrs.xmax), E5_TYPE_DOUBLE, 0}, {"ymin", &(attrs.ymin), E5_TYPE_DOUBLE, 0}, {"ymax", &(attrs.ymax), E5_TYPE_DOUBLE, 0}, {"zmin", &(attrs.zmin), E5_TYPE_DOUBLE, 0}, {"zmax", &(attrs.zmax), E5_TYPE_DOUBLE, 0}, {0} }; status = e5_read_attr_list(e5_group_id, real_param_attr); E5_EXIT_ON_ERROR(status); e5_close_group(e5_group_id); header.variable = grid->name; header.time = (float)attrs.time; header.data_file = data_file; header.data_size[0] = (int)grid->dim[0]; header.data_size[1] = (int)grid->dim[1]; header.data_size[2] = (int)grid->dim[2]; header.centering = "zonal"; header.data_components = 1; header.brick_origin[0] = (attrs.xmax + attrs.xmin) * 0.5; header.brick_origin[1] = (attrs.ymax + attrs.ymin) * 0.5; header.brick_origin[2] = (attrs.zmax + attrs.zmin) * 0.5; header.brick_size[0] = attrs.xmax - attrs.xmin; header.brick_size[1] = attrs.ymax - attrs.ymin; header.brick_size[2] = attrs.zmax - attrs.zmin; for(i=min_bricklet; i <= max_bricklet; i++) { for(d=0; d<3; d++) header.data_bricklets[d] = ((header.data_size[d] % i) == 0) ? i : header.data_bricklets[d]; } if(grid->type == E5_TYPE_FLOAT) header.data_format = "FLOAT"; else if(grid->type == E5_TYPE_DOUBLE) header.data_format = "DOUBLE"; else if(grid->type == E5_TYPE_INT) header.data_format = "INT"; FILE* fd = CreateTextFile(bov_file); if(!fd) { printf("Failed to create BOV header file '%s'! Exiting...\n", bov_file); exit(EXIT_FAILURE); } printf("Writing header to '%s'...\n", bov_file); fprintf(fd, "TIME: %f\n", header.time); fprintf(fd, "DATA_FILE: %s\n", header.data_file); fprintf(fd, "DATA_SIZE: %d %d %d\n", header.data_size[0], header.data_size[1], header.data_size[2]); fprintf(fd, "DATA_FORMAT: %s\n", header.data_format); fprintf(fd, "VARIABLE: %s\n", header.variable); fprintf(fd, "DATA_ENDIAN: LITTLE\n"); fprintf(fd, "CENTERING: %s\n", header.centering); fprintf(fd, "BRICK_ORIGIN: %f %f %f\n", header.brick_origin[0], header.brick_origin[1], header.brick_origin[2]); fprintf(fd, "BRICK_SIZE: %f %f %f\n", header.brick_size[0], header.brick_size[1], header.brick_size[2]); fprintf(fd, "DIVIDE_BRICK: true\n"); fprintf(fd, "DATA_BRICKLETS: %d %d %d\n", header.data_bricklets[0], header.data_bricklets[1], header.data_bricklets[2]); fprintf(fd, "DATA_COMPONENTS: %d\n", 1); CloseTextFile(fd); snprintf(data_file, len, "%s.data", (bov_file)); fd = CreateRawFile(header.data_file); if(!fd) { printf("Failed to create BOV data file '%s'! Exiting...\n", bov_file); exit(EXIT_FAILURE); } printf("Writing data to '%s'...\n", header.data_file); WriteRaw(fd, grid->data, e5_sizeof(grid->type), grid->dim[0] * grid->dim[1] * grid->dim[2]); CloseRawFile(fd); printf("DONE!\n"); }