# H5Part, the C/C++ API
Keywords: scientific visualization

# The C/C++ Application Programming Interface (API)

- Opening, Closing, and Validating Datafiles
- Setting the Simulation Timestep
- Setting the Number of Particles
- Writing Datasets
- Reading the Number of Time Steps
- Reading the Number of Particles
- Reading Datasets
- Reading the Number and the Names of Datasets
- Attributes Interface
- Writing Additional Attributes
- Reading Attributes

Reference Manual (Doxygen)

## Opening Datafiles

Just like the familiar `FILE*` type for C stdio operations, all H5Part file operations require a file handle. The type of this handle is `(H5PartFile*)`.
`H5PartOpenFile()` is used to open a serial file and `HDFPartOpenFileParallel()` is used to open a file for Parallel I/O (in an MPI program). After you open the file handle you can use the same set of subroutines for operations on the file regardless of whether the file is a parallel or serial I/O file. The libraries manage all of this internally.

C Prototypes

Serial File
`H5PartFile *H5PartOpenFile(const char *filename, unsigned accessmode);`
Parallel File
`H5PartFile *H5PartOpenFileParallel(char *filename,int accessmode,MPI_Comm communicator);`

filename:
  The name of the IEEEIO data file to open. The typical extension for these files is .h5
accessmode:
  The accessmode for the file. This is one of 2 different access modes
  `H5PART_READ` : Opens a file in read-only mode.
  `H5PART_WRITE` : Opens a file in write-only mode. If the file does not exist, it will be created. If it does exist, it will be truncated.
communicator:
  This argument is only available if the program has been compiled with the `PARALLEL_IO` C-preprocessor flag defined. It is used to pass in the communicator that will be used for all collective I/O operations that target the same file on disk.
Returns:
  A new filehandle with an open file or NULL if error.
Example Use

    #include < H5Part.h >
    . . . code . . .
        /* Open an HDF5 file for writing */
        H5PartFile *writer = H5PartOpenFile("datafileout.h5",H5PART_WRITE);
        /* Open an HDF5 file for Parallel I/O */
        H5PartFile *writer = H5PartOpenFileParallel("datafileout.h5",H5PART_WRITE,MPI_COMM_WORLD);
        /* open HDF5 file for reading */
        H5PartFile *reader = H5PartOpenFile("datafilein.h5",H5PART_READ);
        /* open HDF5 file for parallel reads */
        H5PartFile *reader = H5PartOpenFileParallel("datafilein.h5",H5PART_READ,MPI_COMM_WORLD);
    . . . more code . . .

## Closing Datafiles

To close the file, you simply use H5PartCloseFile() for both parallel and serial files. You must call H5PartCloseFile() on any file descriptor created by H5PartFileOpen() regardless of whether the file turns out to be valid or not.

C Prototypes

`void H5PartCloseFile(H5PartFile *fileID);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
Returns:
  void.

Example Use

    #include < H5Part.h >
    H5PartFile *file;
    ... code ...
    file=H5PartOpenFileParallel("parttest.h5",H5PART_WRITE,comm);
    ... more code ...
    H5PartCloseFile(file);

## Validating Datafiles

You can test if the file was opened successfully using the H5PartFileIsValid() function. It returns 1 if valid, 0 if invalid.

C Prototype

`int H5PartFileIsValid(H5PartFile *fileID);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
Returns:
  1 if valid, 0 if invalid.

Example Use

Here is an example of validating a newly opened file. Even if the file is invalid, you must use H5PartCloseFile() to reclaim the file handle.

    #include < H5Part.h >
    . . . code . . .
        H5PartFile *fileID = H5PartOpenFile("datafileout.h5",H5PART_WRITE);
        if(!H5PartFileIsValid(fileID)){
           puts("The file you specified does not exist or is not in a
    readable format");
           H5PartClose(fileID); /* must reclaim fileID even if file is invalid */
           . . . do other cleanup . . .
        }
    . . . more code . . .

## Setting the Timestep

When writing data to a file the current time step must be set (even if there is only one). In a file with N time steps, the steps are numbered from 0 to N-1.

C Prototype

`void H5PartSetStep((H5PartFile *fileID,int step);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
step:
  An integer time step.
Returns:
  void.

Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    int timeStep;
    ....
    H5PartSetStep(fileID,timeStep);
    ....

## Setting the Number of Particles

H5PartSetNumParticles: This function's sole purpose is to prevent needless creation of new HDF5 DataSpace handles if the number of particles is invariant throughout the sim. That's its only reason for existence. After you call this subroutine, all subsequent operations will assume this number of particles will be written.

C Prototype

`void H5PartSetNumParticles(H5PartFile *fileID,long long nparticles);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
nparticles:
  A long long integer specifying the number of particles.
Returns:
  void.

Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    long long nparticles;
    ....
    H5PartSetStep(fileID,nparticles);
    ....

## Writing Datasets

After setting the number of particles with H5PartSetNumParticles() and the current timestep using H5PartSetStep(), you can start writing datasets into the file. Each dataset has a name associated with it (chosen by the user) in order to facilitate later retrieval. The writing routines also implicitly store the datatype of the array so that the array can be reconstructed properly on other systems with incompatible type representations. The data is committed to disk before the routine returns. All data that is written after setting the timestep is associated with that timestep. While the number of particles can change for each timestep, you cannot change the number of particles in the middle of a given timestep.

C Prototypes

`int H5PartWriteDataFloat64(H5PartFile *fileID,char *name,double *array);` `int H5PartWriteDataInt64(H5PartFile *fileID,char *name,double *array);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
name:
  A null-terminated string for the name of the array. When retrieving datasets from disk, you ask for them by name. There are no restrictions on naming of arrays, but it is useful to arrive at some common naming convention when sharing data with other groups.
array:
  A buffer containing an array of particle data to commit to disk. The datatype for elements in the buffer is implicit in the name of the subroutine call.
Returns:
  1 on success, 0 on failure.

Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    double *x,*y,*z;
    int timeStep;
    long long nparticles;

    ...

    H5PartSetStep(fileID,timeStep); /* must set the current timestep in file */
    H5PartSetNumParticles(fileID,nparticles); /* then set number of particles to store */

    /* now write different tuples of data into this timestep of the file */
    H5PartWriteDataFloat64(fileID,"x",x);
    H5PartWriteDataFloat64(fileID,"y",y);
    H5PartWriteDataFloat64(file,"z",z);
    ..

## Reading the Number of Time Steps

This reads the number of datasteps that are currently stored in the datafile. It works for both reading and writing of files, but is probably only typically used when you are reading.

C Prototype

`int H5PartGetNumSteps (H5PartFile *fileID);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
Returns:
  The number of timesteps currently stored in the file.

## Reading the Number of Particles

This reads the number of particles that are currently stored in the current time step. It will arbitrarily select a timestep if you haven't already set the timestep with H5PartSetStep().

C Prototype

`long long H5PartGetNumParticles (H5PartFile *fileID);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
Returns:
  The number of particles in current timestep.

Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    int timeStep;
    long long nparticles;

    H5PartSetStep(fileID,0);
    nparticles=H5PartGetNumParticles(fileID);
    ...

## Reading Datasets

After setting the time step and getting the number of particles to allocate the data arrays, you can start to read the data.

C Prototypes

`int H5PartReadDataFloat64(H5PartFile *fileID,char *name,double *array);`
`int H5PartReadDataInt64(H5PartFile *fileID,char *name,long long *array);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
name:
  A null-terminated string for the name of the array. When retrieving datasets from disk, you ask for them by name. There are no restrictions on naming of arrays, but it is useful to arrive at some common naming convention when sharing data with other groups.
array:
  A buffer to which the particle data will be read.i The datatype for elements in the buffer is implicit in the name of the subroutine call.
Returns:
  1 on success, 0 on failure.

Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    double *x,*y,*z;
    int timeStep;
    long long nparticles;

    H5PartSetStep(fileID,0);
    nparticles=H5PartGetNumParticles(fileID);
    ...

    H5PartReadDataFloat64(file,"x",x);
    H5PartReadDataFloat64(file,"y",y);
    H5PartReadDataFloat64(file,"z",z);
    ...

## Reading the Number and Names of Datasets

H5Part provides funtions to find out how many datasets are stored at a particular timestep and what their names are if you don't know what they are a-priori.

C Prototypes

`int H5PartGetNumDatasets(H5PartFile *fileID);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
Returns:
  The number of datasets.

`int H5PartGetDatasetName(H5PartFile *fileID,int index,char *name,int maxlen);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
index:
  integer specifying the index of the dataset. If the number of datasets is nds, the range of index is 0 to nds-1.
name:
  A null-terminated string for the name of the dataset.
maxlen:
  An integer specifying the maximum length of the name array.
Returns:
  1 on success, 0 on failure.

Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    char name[64];
    int index, nds;

    ...
    nds=H5PartGetNumDatasets(fileID);
      for(index=0;index< nds;index++){
        H5PartGetDatasetName(fileID,index,name,64);
        printf("\tDataset[%u] name=[%s]\n", index,name);
      }
    ...

## Attributes Interface

In the current H5Part implemtation there are two types of attributes: file attributes which are bound to the file and step attributes which are bound to the current timestep. You must set the timestep explicitly before writing the attributes (just as you must do when you write a new dataset. Currently there are no attributes that are bound to a particular data array, but this could easily be done if required.

H5PartGetNumStepAttribs and H5PartGetNumFileAttribs return the number of attributes bound to a step and to a file respectively. H5PartGetStepAttribInfo and H5PartGetFileAttribInfo return the name, type and number of elements of type "type" bound to a step and a file respectively.

C Prototypes:
`int H5PartGetNumStepAttribs(H5PartFile *fileID);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
Returns
  The number of step attributes for the current step.

`int H5PartGetNumFileAttribs(H5PartFile *fileID);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
Returns
  The number of file attributes.

`void H5PartGetStepAttribInfo(H5PartFile *fileID,int idx, char *name,size_t maxnamelen,hid_t *type,int *nelem);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
idx:
  Index of the attribute.
name:
  A null-terminated string with the name of the attribute.
maxnamelen
  the length of the name of the attribute.
type:
  One of the following: H5T_NATIVE_DOUBLE H5T_NATIVE_INT64 H5T_NATIVE_CHAR.
nelem:
  Number of elements of type "type".
Returns
  void.

`void H5PartGetFileAttribInfo(H5PartFile *fileID,int idx, char *name,size_t maxnamelen, hid_t *type,int *nelem);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
idx:
  Index of the attribute.
name:
  A null-terminated string with the name of the attribute.
maxnamelen
  the length of the name of the attribute.
type:
  One of the following: H5T_NATIVE_DOUBLE H5T_NATIVE_INT64 H5T_NATIVE_CHAR.
nelem:
  Number of elements of type "type".
Returns
  void.

## Writing Attributes

An attribute can be bound to the file or after setting the time step to this time step.

C Prototypes: Generic Attributes

`int H5PartWriteFileAttrib(H5PartFile *fileID,char *name, hid_t type,void *value,int nelem);`
`int H5PartWriteStepAttrib(H5PartFile *fileID,char *name, hid_t type,void *value,int nelem);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
name:
  A null-terminated string for the name of the array. When retrieving datasets from disk, you ask for them by name. There are no restrictions on naming of arrays, but it is useful to arrive at some common naming convention when sharing data with other groups.
type: One of H5T_NATIVE_DOUBLE, H5T_NATIVE_INT64, H5T_NATIVE_CHAR.
value: value of the attribute.
nelem: number of elements of type "type".
Returns:
  1 on success, 0 on failure.

Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    double actPos;

    ...
    H5PartWriteStepAttrib(file_m,"Spos",H5T_NATIVE_DOUBLE,&actPos,1);
    ...

C Prototypes: String Attributes

`int H5PartWriteStepAttribString(H5PartFile *fileID,char *name, char *attrib);`
`int H5PartWriteFileAttribString(H5PartFile *fileID,char *name, char *attrib);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
name:
  A null-terminated string for the name of the array. When retrieving datasets from disk, you ask for them by name. There are no restrictions on naming of arrays, but it is useful to arrive at some common naming convention when sharing data with other groups.
attrib: the attribute character string.
Returns:
  1 on success, 0 on failure.

Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    char *newattrib;
    char *newname;

    ...
    H5PartWriteFileAttribString(fileID, newname,newattrib);
    ...

## Reading Attributes

As with the writing of attributes, there are two basic reading interfaces one that reads file bound attributes and one that reads step bound attributes. If the step is not set the current one will be used.

C Prototypes

`void H5PartReadStepAttrib(H5PartFile *fileID,char *name,void *value);`
`void H5PartReadAttrib(H5PartFile *fileID,char *name,void *value);`
`int H5PartReadFileAttrib(H5PartFile *fileID,char *name,void *value);`

fileID:
  A FileHandle opened by H5PartOpenFile() or H5PartOpenFileParallel().
name:
  A null-terminated string for the name of the array. When retrieving datasets from disk, you ask for them by name. There are no restrictions on naming of arrays, but it is useful to arrive at some common naming convention when sharing data with other groups.
value: value of the attribute.
Returns:
  1 on success, 0 on failure.

NOTE: H5PartReadAttrib has been superseeded by H5PartSetStep.
Example Use

    #include < H5Part.h >
    H5PartFile *fileID;
    int step;
    char name[MAXNAME];

    ...

    H5PartSetStep(fileID, step);
    if (H5PartReadStepAttrib(file, "filename", &name[0]) == 1){
    	printf("Read step from file: %s\n", name);
    }

    ...