Hello,

Thank you everyone for your help. I figured out the problem, I was just
misunderstanding how the functions worked. I was able to successfully read
the dataset into a buffer. I did not realize that a 1D array was
sufficient, I was for some reason thinking that it had to be a contiguous
multidimensional array but it turns out that the functions know how to read
the arrays if you give it the rank and the size of each dimension.

Turns out I have another problem however. I am trying to now write this
buffer into a new file. The error happens when I try to create a new
dataset. When I ran my code, I got errors such as: "H5D.c line 194 in
H5Dcreate2(): unable to create dataset." I looked online and it turns out
that there is a size limit to the buffer and mine most certainly exceeds
that. So the solution is to create a dataset creation property list and set
it to chunk. Even after I have set a reasonable chunk size, I still get the
same errors. I will attach my code and the errors I am receiving. Relevant
code starts at line 122. Thank you SO MUCH for your help, I'm still trying
to learn all of this.

Landon

On Sat, Sep 3, 2016 at 11:45 AM, Michael Jackson <
[email protected]> wrote:

> You can take a look at the following source files. They are mean for C++
> and templates but assuming you know a bit of C++ you can convert them back
> to pure "C" without any issues. The template parameter is on the POD type.
>
> https://github.com/BlueQuartzSoftware/SIMPL/tree/develop/Source/H5Support
>
> Take a look at H5Lite.h and H5Lite.cpp. There are functions in there to
> "readPointerDataset()", writePointerDataSet() and getDatasetInfo().
>
> The basic flow would be the following (using some pure "C").
>
> // Open the file and get the "Location ID"
> hid_t fileId = ...
>
> char* datasetName = ....
> //Since you know it is a 5D array:
> hsize_t_t dims[5];
> H5T_class_t  classType;
> size_t type_size;
> H5Lite::getDatasetInfo(fileId, datasetName, dims, classType, typesize);
>
> // Now loop over all the dim[] values to compute the total number
> // of elements that need to allocate, lets assume they are 32 bit
> // signed ints
> size_t totalElements = dims[0] * dims[1] * dims[2] * dims[3] * dims[4];
> // Allocate the data
> signed int* dataPtr = malloc(totalElements * sizeof(signed int));
>
> herr_t err = H5Lite::readPointerDataset(fileId, datasetName, dataPtr);
> // Check error
> if (err < 0) { ..... }
>
> // Open New file for writing
> hid_t outFileId = ...
> signed int rank = 5;
> err = H5Lite::writePointerDataset(outFileid, datasetName, rank, dims,
> dataPtr);
> // Check error
> if (err < 0) { ..... }
>
> This assumes that you take the code from GitHub and convert the necessary
> functions into pure "C" which should be straight forward to do.
>
> The code referenced above is BSD licensed.
>
> --
> Michael A. Jackson
> BlueQuartz Software, LLC
> [e]: [email protected]
>
>
> Nelson, Jarom wrote:
>
>> You might look at h5copy as a reference, or just use that tool to do the
>> work for you.
>>
>> Jarom
>>
>> *From:*Hdf-forum [mailto:[email protected]] *On
>> Behalf Of *Landon Clipp
>> *Sent:* Friday, September 02, 2016 11:56 AM
>> *To:* [email protected]
>> *Subject:* [Hdf-forum] Best way to repackage a dataset? (C program)
>>
>> Hello everyone,
>>
>> I am working with an HDF5 file that has a 5D dataset. What I'm wanting
>> to do is to create a C program that reads this dataset into memory and
>> then outputs it into a newly created file with only that dataset in it
>> (perhaps at the root directory of the file tree). What I don't
>> understand is how to read this entire 5D array using H5Dread into a 5D
>> buffer that has been previously allocated on the heap (note I cannot use
>> an array allocated on the stack, it would be too large and would create
>> seg faults).
>>
>> What is the general process I need to employ to do such a thing, and is
>> there maybe a more elegant solution to this than reading the entire
>> dataset into memory? This process seems easy to me for a 1 or 2D array
>> but I am lost with larger dimension arrays. Thanks.
>>
>> Regards,
>>
>> Landon
>>
>> _______________________________________________
>> Hdf-forum is for HDF software users discussion.
>> [email protected]
>> http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
>> Twitter: https://twitter.com/hdf5
>>
>
> _______________________________________________
> Hdf-forum is for HDF software users discussion.
> [email protected]
> http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
> Twitter: https://twitter.com/hdf5
>
HDF5-DIAG: Error detected in HDF5 (1.8.17) thread 0:
  #000: H5D.c line 194 in H5Dcreate2(): unable to create dataset
    major: Dataset
    minor: Unable to initialize object
  #001: H5Dint.c line 455 in H5D__create_named(): unable to create and link to 
dataset
    major: Dataset
    minor: Unable to initialize object
  #002: H5L.c line 1638 in H5L_link_object(): unable to create new link to 
object
    major: Links
    minor: Unable to initialize object
  #003: H5L.c line 1882 in H5L_create_real(): can't insert link
    major: Symbol table
    minor: Unable to insert object
  #004: H5Gtraverse.c line 861 in H5G_traverse(): internal path traversal failed
    major: Symbol table
    minor: Object not found
  #005: H5Gtraverse.c line 755 in H5G_traverse_real(): component not found
    major: Symbol table
    minor: Object not found
HDF5-DIAG: Error detected in HDF5 (1.8.17) thread 0:
  #000: H5D.c line 415 in H5Dclose(): not a dataset
    major: Invalid arguments to routine
    minor: Inappropriate type
#include <stdio.h>
#include <hdf5.h>		// default HDF5 library
#include <stdlib.h>


#define DATASETNAME "HDFEOS/SWATHS/MOP01/Data Fields/MOPITTRadiances"
#define MOPITT_RANK 5

/*
	NOTE: argv[1] = INPUT_FILE
		  argv[2] = OUTPUT_FILE
*/

/*********************
 *FUNCTION PROTOTYPES*
 *********************/
 
float getElement5D( float *array, hsize_t dimSize[5], int *position );	// note, this function is used for testing. It's temporary


int main( int argc, char* argv[] )
{
	if ( argc != 3 )
	{
		
		fprintf( stderr, "\nError! Program expects format: %s [input HDF5 file] [output HDF5 file]\n\n", argv[0] );
		return EXIT_FAILURE;
	
	}
	
	hid_t file;									// file ID
	hid_t dataset;								// dataset ID
	hid_t filespace;							// filespace ID
	hid_t memspace;								// memoryspace ID
	hid_t dcpl_id;
	
	hsize_t MOPITTdims[MOPITT_RANK]; 			// size of each MOPITT dimension
	hsize_t MOPITTmaxsize[MOPITT_RANK];			// maximum allowed size of each dimension in MOPITTdims
	hsize_t MOPITTChunkSize[MOPITT_RANK];
	
	herr_t status_n, status;
	
	
	/*
	 * Open the file and do error checking
	 */
	 
	file = H5Fopen( argv[1], H5F_ACC_RDONLY, H5P_DEFAULT );
	
	
	if ( file < 0 )
	{
		fprintf( stderr, "\nError! Could not open HDF5 file. Exiting program.\n\n" );
		return EXIT_FAILURE;
	}
	
	/*
	 * open radiance dataset and do error checking
	 */
	 
	dataset = H5Dopen( file, DATASETNAME, H5F_ACC_RDONLY );
	
	if ( dataset < 0 )
	{
		fprintf( stderr, "\nError! Could not open dataset. Exiting program.\n\n" );
		return EXIT_FAILURE;
	}
	
	/*
	 * Get dataset dimension
	 */
	 
	filespace = H5Dget_space(dataset);
	status_n  = H5Sget_simple_extent_dims(filespace, MOPITTdims, MOPITTmaxsize );
	
	/*
	 * Create a data_out buffer using the dimensions of the dataset specified by MOPITTdims
	 */

	//float *****data_out = allocateMOPITTBuffer( MOPITTdims );
	
	float *data_out = malloc( sizeof(float ) * MOPITTdims[0] * MOPITTdims[1] * MOPITTdims[2] *  MOPITTdims[3] * MOPITTdims[4]);
	
	
	/*
	 * get memory space
	 */
	
	memspace = H5Screate_simple( MOPITT_RANK, MOPITTdims, NULL );
	
	/*
	 * Now read dataset into data_out buffer
	 * H5T_NATIVE_FLOAT is specifying that we are reading floating points
	 * H5S_ALL specifies that we are reading the entire dataset instead of just a portion
	 */

	status = H5Dread( dataset, H5T_NATIVE_FLOAT, memspace, filespace, H5P_DEFAULT, data_out );
	
	
	
	/* Free all memory associated with the input data */
	H5Sclose(memspace);
	H5Sclose(filespace);
	H5Dclose(dataset);
	H5Fclose(file);
	
	/*******************************************************************************************
	 *Reading the dataset is now complete. We have freed all related memory for the input data *
	 *(except of course the data_out array) and can now work on writing this data to a new file*
	 *******************************************************************************************/
	 
	/* Create a file. H5F_ACC_TRUNC says to overwrite if file already exists, H5P_DEFAULT
	 * says to create with default properties. 
	 */
	 
	file = H5Fcreate( argv[2], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
	
	/* Because dataset is large, we need to use chunking. Create dataset creation property list,
	 * set to use chunking.
	 */
	
	MOPITTChunkSize[0] = 100;
	MOPITTChunkSize[1] = MOPITTdims[1];
	MOPITTChunkSize[2] = MOPITTdims[2];
	MOPITTChunkSize[3] = MOPITTdims[3];
	MOPITTChunkSize[4] = MOPITTdims[4];
	
	/* set dataspace creation property list to chunk */
	dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
	H5Pset_chunk(dcpl_id, MOPITT_RANK, MOPITTChunkSize);
	
	memspace = H5Screate_simple( MOPITT_RANK, MOPITTdims, NULL );
	
	dataset = H5Dcreate( file, "/MOPITT/Data Fields/MOPITT Radiances", H5T_NATIVE_FLOAT, memspace, 
						 H5P_DEFAULT, dcpl_id, H5P_DEFAULT );
	
	
	
	
	
	
	/* Free all remaining memory */
	H5Dclose(dataset);
	H5Sclose(memspace);
	H5Pclose(dcpl_id);
	H5Fclose(file);
	free(data_out);
	
	return 0;

}

/*
	DESCRIPTION:
		This function returns the value specified by the dimensions given to it in the array
	ARGUMENTS:
		1. float array
		2. Size of each dimension (given by a 5 element 1D array. Elements 0-4 specify size of dimensions 0-4).
		3. Requested position in the array (given by a 5 element 1D array. Elements 0-4 specify which position in each dimension)
	EFFECTS:
		None. Does not write anything.
	RETURN:
		Value stored at specified dimension
		
	array[dim0][dim1][dim2][dim3][dim4]
*/
		
float getElement5D( float *array, hsize_t dimSize[5], int position[5] )
{
	if ( position[0] < 0 || position[0] >= dimSize[0] ||
		 position[1] < 0 || position[1] >= dimSize[1] ||
		 position[2] < 0 || position[2] >= dimSize[2] ||
		 position[3] < 0 || position[3] >= dimSize[3] ||
		 position[4] < 0 || position[4] >= dimSize[3] )
	{
		fprintf( stderr, "\ngetElement5D: Error! Invalid position. Check that dimSize and position arguments are correct.\n");
		exit (-1);
	}
	
	return array[ (position[0] * dimSize[1] * dimSize[2] * dimSize[3] * dimSize[4]) + 
				  (position[1] * dimSize[2] * dimSize[3] * dimSize[4]) +
				  (position[2] * dimSize[3] * dimSize[4]) +
				  (position[3] * dimSize[4]) +
				   position[4] ];

}












_______________________________________________
Hdf-forum is for HDF software users discussion.
[email protected]
http://lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org
Twitter: https://twitter.com/hdf5

Reply via email to