XMDF  2.2
TestXmdf.cpp

TestXmdf.cpp provides C++ code examples for many XMDF APIs.

// This file has functions that can be used to test reading and writing of
// datasets using HDF5. This code is intended to be used as tests for the
// XMDF library as well as sample code for distribution.
#include "stdafx.h"
#include <xmdf/Xmdf.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include "TestDatasets.h"
#define DATASETS_LOCATION "Datasets"
#define SCALAR_A_LOCATION "Scalars/ScalarA"
#define SCALAR_B_LOCATION "Scalars/ScalarB"
#define VECTOR2D_A_LOCATION "Vectors/Vector2D_A"
#define VECTOR2D_B_LOCATION "Vectors/Vector2D_B"
void tdiDatasetArray (double a_dMin, double a_dMax, int a_nCycle,
int a_SeedMultiplier, int a_nValues, float *a_Array);
double tdiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed);
int tdiReadScalar (xid a_xScalarId, FILE *a_fp);
int tdiReadVector (xid a_xVectorId, FILE *a_fp);
// ---------------------------------------------------------------------------
// FUNCTION tdEditScalarAValues
// PURPOSE
// NOTES
// ---------------------------------------------------------------------------
int tdEditScalarAValues (LPCSTR a_Filename, int a_Compression)
{
int nStatus = NONE;
xid xFileId = 0, xScalarId = 0;
const char * DATASET_PATH = "Datasets/Scalars/ScalarA";
nStatus = tdWriteScalarA(a_Filename, a_Compression);
if (nStatus < 0) {
return nStatus;
}
// open the file and edit the values
nStatus = xfOpenFile(a_Filename, &xFileId, XFALSE);
if (nStatus < 0) {
return -1;
}
nStatus = xfOpenGroup(xFileId, DATASET_PATH, &xScalarId);
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// Edit values in timestep 1, make index 1 = 4, index 5 = 40,
// and index 10 = 400
int editTimestep = 1;
const int editNumValues = 3;
int indices[editNumValues];
indices[0] = 1;
indices[1] = 5;
indices[2] = 10;
float new_values[editNumValues];
new_values[0] = 4.0;
new_values[1] = 40.0;
new_values[2] = 400.0;
nStatus = xfChangeScalarValuesTimestepFloat(xScalarId, editTimestep, editNumValues,
indices, new_values);
if (nStatus < 0) {
xfCloseGroup(xScalarId);
xfCloseFile(xFileId);
return -1;
}
// Edit values in timestep 2, make index 2 = 6, index 3 = 60, and
// index 9 = 600
editTimestep = 2;
indices[0] = 2;
indices[1] = 3;
indices[2] = 9;
new_values[0] = -6.0;
new_values[1] = 60.0;
new_values[2] = 6000.0;
nStatus = xfChangeScalarValuesTimestepFloat(xScalarId, editTimestep, editNumValues,
indices, new_values);
if (nStatus < 0) {
xfCloseGroup(xScalarId);
xfCloseFile(xFileId);
return -1;
}
xfCloseGroup(xScalarId);
xfCloseFile(xFileId);
return nStatus;
} // tdEditScalarAValues
// --------------------------------------------------------------------------
// FUNCTION tdReadDatasets
// PURPOSE Read a dataset group from an XMDF file and output information to
// to a text file
// NOTES
// --------------------------------------------------------------------------
int tdReadDatasets (xid a_xGroupId, FILE *a_fp)
{
int nPaths=0, nMaxPathLength=0, nMultiDatasets=0;
char *Paths = NULL, *IndividualPath = NULL;
int nStatus, i, j;
xid xScalarId = NONE, xVectorId = NONE, xMultiId = NONE;
// Look for scalar datasets
nStatus = xfGetScalarDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
if (nStatus >= 0) {
Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
xfGetScalarDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
}
if (nStatus < 0) {
return -1;
}
// Output number and paths to scalar datasets
fprintf(a_fp, "Number of Scalars %d\n", nPaths);
for (i = 0; i < nPaths; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(a_fp, "Reading scalar: %s\n", IndividualPath);
nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xScalarId);
if (nStatus < 0) {
return -1;
}
nStatus = tdiReadScalar(xScalarId, a_fp);
xfCloseGroup(xScalarId);
if (nStatus < 0) {
printf("Error reading scalar dataset.");
return -1;
}
}
if (Paths) {
free(Paths);
Paths = NULL;
}
// Look for vector datasets
nStatus = xfGetVectorDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
if (nStatus >= 0 && nPaths > 0) {
Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
xfGetVectorDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
}
if (nStatus < 0) {
return -1;
}
// Output number and paths to scalar datasets
fprintf(a_fp, "Number of Vectors %d\n", nPaths);
for (i = 0; i < nPaths; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(a_fp, "Reading Vector: %s\n", IndividualPath);
nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xVectorId);
if (nStatus < 0) {
return -1;
}
nStatus = tdiReadVector(xVectorId, a_fp);
xfCloseGroup(xVectorId);
if (nStatus < 0) {
printf("Error reading vector dataset.");
return -1;
}
}
// find multidataset folders
nStatus = xfGetGroupPathsSizeForMultiDatasets(a_xGroupId, &nMultiDatasets,
&nMaxPathLength);
if (nStatus >= 0 && nMultiDatasets > 0) {
Paths = (char *)malloc(nMultiDatasets*nMaxPathLength*sizeof(char));
nStatus = xfGetAllGroupPathsForMultiDatasets(a_xGroupId, nMultiDatasets,
nMaxPathLength, Paths);
if (nStatus < 0) {
return -1;
}
// Output number and paths to multidatasets
fprintf(a_fp, "Number of Multidatasets: %d\n", nMultiDatasets);
for (i=0; i<nMultiDatasets; i++) {
IndividualPath = "";
for (j=0; j<nMaxPathLength-1; j++) {
IndividualPath = &Paths[i*nMaxPathLength];
}
fprintf(a_fp, "Reading multidataset: %s\n", IndividualPath);
nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xMultiId);
if (nStatus < 0) {
return -1;
}
nStatus = tdReadDatasets(xMultiId, a_fp);
nStatus = xfCloseGroup(xMultiId);
if (nStatus < 0) {
printf("Error reading multidatasets.");
return -1;
}
}
}
if (Paths) {
free(Paths);
Paths = NULL;
}
return 1;
} // tdReadDatasets
// --------------------------------------------------------------------------
// FUNCTION tdReadActivityScalarAIndex
// PURPOSE Read all timestep values for a particular index
// NOTES
// --------------------------------------------------------------------------
int tdReadActivityScalarAIndex (LPCSTR a_Filename, int a_Index)
{
int status;
xid xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
int nTimesteps;
xmbool *bActive;
// open the file
status = xfOpenFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// open the dataset group
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status >= 0) {
status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
}
if (status < 0) {
return status;
}
// Find out the number of timesteps in the file
status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
if (status < 0) {
return status;
}
if (nTimesteps < 1) {
return -1;
}
// Read the values for the index
bActive = new xmbool[nTimesteps];
status = xfReadActivityValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
bActive);
// output the data
printf("\nReading activity for scalar A slice at index: %d\n", a_Index);
for (int i = 0; i < nTimesteps; i++) {
printf("%d ", bActive[i]);
}
printf("\n");
delete [] bActive;
return status;
} // tdReadActivityScalarAtIndex
// --------------------------------------------------------------------------
// FUNCTION tdReadScalarAIndex
// PURPOSE Read all timestep values for a particular index
// NOTES
// --------------------------------------------------------------------------
int tdReadScalarAIndex (LPCSTR a_Filename, int a_Index)
{
int status;
xid xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
int nTimesteps;
float *fValues;
// open the file
status = xfOpenFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// open the dataset group
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status >= 0) {
status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
}
if (status < 0) {
return status;
}
// Find out the number of timesteps in the file
status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
if (status < 0) {
return status;
}
if (nTimesteps < 1) {
return -1;
}
// Read the values for the index
fValues = new float[nTimesteps];
status = xfReadScalarValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
fValues);
// output the data
printf("\nReading scalar A slice at index: %d\n", a_Index);
for (int i = 0; i < nTimesteps; i++) {
printf("%f ", fValues[i]);
}
printf("\n");
delete [] fValues;
return status;
} // tdReadScalarAtIndex
// ---------------------------------------------------------------------------
// FUNCTION tdReadScalarAIndices
// PURPOSE
// NOTES
// ---------------------------------------------------------------------------
int tdReadScalarAIndices (LPCSTR a_Filename, int a_nIndices, int *a_indices)
{
int status;
xid xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
int nTimesteps;
float *fValues;
int nValues = 0;
// open the file
status = xfOpenFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// open the dataset group
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status >= 0) {
status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
}
if (status < 0) {
return status;
}
// Find out the number of timesteps in the file
status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
if (status < 0) {
return status;
}
if (nTimesteps < 1) {
return -1;
}
// Read the values for the index
nValues = nTimesteps*a_nIndices;
fValues = new float[nValues];
status = xfReadScalarValuesAtIndicesFloat(xScalarAId, a_nIndices, a_indices, 1,
nTimesteps, fValues);
if (status < 0) {
return status;
}
// output the data
printf("\nReading scalar A indices\n");
int id = 0;
for (int i = 0; i < nTimesteps; i++) {
printf("Timestep: %d\n", i+1);
for (int j = 0; j < a_nIndices; j++) {
printf("index: %d value: %f \n", a_indices[j], fValues[id]);
id++;
}
}
printf("\n");
delete [] fValues;
return status;
} // tdReadScalarAIndices
// ---------------------------------------------------------------------------
// FUNCTION tdReadVectorAIndices
// PURPOSE
// NOTES
// ---------------------------------------------------------------------------
int tdReadVectorAIndices (LPCSTR a_Filename, int a_nIndices, int *a_indices)
{
int status;
xid xFileId = NONE, xDsetsId = NONE, xVectorAId = NONE;
int nTimesteps;
float *fValues;
int nValues = 0;
// open the file
status = xfOpenFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// open the dataset group
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status >= 0) {
status = xfOpenGroup(xDsetsId, VECTOR2D_A_LOCATION, &xVectorAId);
}
if (status < 0) {
return status;
}
// Find out the number of timesteps in the file
status = xfGetDatasetNumTimes(xVectorAId, &nTimesteps);
if (status < 0) {
return status;
}
if (nTimesteps < 1) {
return -1;
}
// Read the values for the index
nValues = nTimesteps*a_nIndices;
fValues = new float[nValues*2];
status = xfReadVectorValuesAtIndicesFloat(xVectorAId, a_nIndices, a_indices, 1,
nTimesteps, 2, fValues);
if (status < 0) {
return status;
}
// output the data
printf("\nReading vector A indices\n");
int id = 0;
for (int i = 0; i < nTimesteps; i++) {
printf("Timestep: %d\n", i+1);
for (int j = 0; j < a_nIndices; j++) {
printf("index: %d value comp1: %f value comp2 %f\n",
a_indices[j], fValues[id], fValues[id+1]);
id += 2;
}
}
printf("\n");
delete [] fValues;
return status;
} // tdReadVectorAIndices
// --------------------------------------------------------------------------
// FUNCTION tdWriteScalarA
// PURPOSE Write scalar Dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// This dataset is dynamic concentrations (mg/L) with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// reads/writes a reference time in julian days
// --------------------------------------------------------------------------
int tdWriteScalarA (LPCSTR a_Filename, int a_Compression)
{
xid xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
int nValues = 10, nTimes = 3, nActive = 8;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[10]; // nValues
xmbool bActivity[10]; // activity
int status, iHpgnZone;
double dJulianReftime;
int nErrors = 0, i = 0;
char **Errors = NULL;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
bActivity[iActive] = XTRUE;
}
bActivity[5] = XFALSE;
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group where we will put all the datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// uncomment next line to test error handling function
// xfCloseGroup(xDsetsId);
// Create the scalar A dataset group
status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
"mg/L", TS_HOURS, a_Compression,
&xScalarAId);
if (status < 0) {
// print the error stack
xfGetNumErrorMessages(&nErrors);
if (nErrors > 0) {
Errors = new char*[nErrors];
for (i = 0; i < nErrors; i++) {
Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
}
status = xfGetErrorMessages(nErrors, Errors);
if (status > 0) {
for (i = 0; i < nErrors; i++) {
printf("%s\n", Errors[i]);
}
}
for (i = 0; i < nErrors; i++) {
delete Errors[i];
}
delete Errors;
}
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
// Add in a reftime. This is a julian day for:
// noon July 1, 2003
dJulianReftime = 2452822.0;
status = xfDatasetReftime(xScalarAId, dJulianReftime);
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
fValues[0] = (float)dTime;
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*2.5);
}
// write the dataset array values
status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
// Write Coordinate file - for ScalarA, we will set the coordinate system
// to be Geographic HPGN, with HPGN settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// set HPGN Zone for test
iHpgnZone = 29; // Utah
// Write Coordinate Information to file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetHPGNArea(xCoordId, iHpgnZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return 1;
} // tdWriteScalarA
// --------------------------------------------------------------------------
// FUNCTION tdWriteScalarAPieces
// PURPOSE Write scalar Dataset to an HDF5 File
// NOTES This tests writing scalar datasets in parts
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// reads/writes a reference time in julian days
// --------------------------------------------------------------------------
int tdWriteScalarAPieces (LPCSTR a_Filename, int a_Compression)
{
xid xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
int nValues = 10, nTimes = 3, nActive = 8;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[10]; // nValues
xmbool bActivity[10]; // activity
int status, iHpgnZone;
double dJulianReftime;
int nErrors = 0, i = 0;
char **Errors = NULL;
const int numValuesPerWrite = 2;
float minvalue, maxvalue;
hsize_t timestepId;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
bActivity[iActive] = XTRUE;
}
bActivity[5] = XFALSE;
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group where we will put all the datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// uncomment next line to test error handling function
// xfCloseGroup(xDsetsId);
// Create the scalar A dataset group
status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
"mg/L", TS_HOURS, a_Compression,
&xScalarAId);
if (status < 0) {
// print the error stack
xfGetNumErrorMessages(&nErrors);
if (nErrors > 0) {
Errors = new char*[nErrors];
for (i = 0; i < nErrors; i++) {
Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
}
status = xfGetErrorMessages(nErrors, Errors);
if (status > 0) {
for (i = 0; i < nErrors; i++) {
printf("%s\n", Errors[i]);
}
}
for (i = 0; i < nErrors; i++) {
delete Errors[i];
}
delete Errors;
}
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
// Add in a reftime. This is a julian day for:
// noon July 1, 2003
dJulianReftime = 2452822.0;
status = xfDatasetReftime(xScalarAId, dJulianReftime);
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
float minvalue = 9999.9;
float maxvalue = -9999.9;
fValues[0] = (float)dTime;
minvalue = maxvalue = fValues[0];
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*2.5);
minvalue = min(minvalue, fValues[i]);
maxvalue = max(maxvalue, fValues[i]);
}
// we will write the values as pairs
status = xfInitializeScalarTimestep(xScalarAId, dTime, nValues, minvalue,
maxvalue, &timestepId);
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
for (i = 0; i < nValues; i += numValuesPerWrite) {
status = xfWriteScalarTimestepPortion(xScalarAId, timestepId,
numValuesPerWrite, i+1, &fValues[i]);
}
if (status >= 0) {
// write activity array
xfInitializeActivityTimestep(xScalarAId, nActive, &timestepId);
for (i = 0; i < nActive; i += 2) {
status = xfWriteActivityTimestepPortion(xScalarAId, timestepId, 2,
i+1, &bActivity[i]);
}
}
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
// Write Coordinate file - for ScalarA, we will set the coordinate system
// to be Geographic HPGN, with HPGN settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// set HPGN Zone for test
iHpgnZone = 29; // Utah
// Write Coordinate Information to file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetHPGNArea(xCoordId, iHpgnZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return 1;
} // tdWriteScalarAPieces
// --------------------------------------------------------------------------
// FUNCTION tdWriteScalarAPiecesAltMinMax
// PURPOSE Write scalar Dataset to an HDF5 File
// NOTES This tests writing scalar datasets in parts
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// reads/writes a reference time in julian days
// --------------------------------------------------------------------------
int tdWriteScalarAPiecesAltMinMax (LPCSTR a_Filename, int a_Compression)
{
xid xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
int nValues = 10, nTimes = 3, nActive = 8;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[10]; // nValues
xmbool bActivity[10]; // activity
int status, iHpgnZone;
double dJulianReftime;
int nErrors = 0, i = 0;
char **Errors = NULL;
const int numValuesPerWrite = 2;
float minvalue, maxvalue;
hsize_t timestepId;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
bActivity[iActive] = XTRUE;
}
bActivity[5] = XFALSE;
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group where we will put all the datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// uncomment next line to test error handling function
// xfCloseGroup(xDsetsId);
// Create the scalar A dataset group
status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
"mg/L", TS_HOURS, a_Compression,
&xScalarAId);
if (status < 0) {
// print the error stack
xfGetNumErrorMessages(&nErrors);
if (nErrors > 0) {
Errors = new char*[nErrors];
for (i = 0; i < nErrors; i++) {
Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
}
status = xfGetErrorMessages(nErrors, Errors);
if (status > 0) {
for (i = 0; i < nErrors; i++) {
printf("%s\n", Errors[i]);
}
}
for (i = 0; i < nErrors; i++) {
delete Errors[i];
}
delete Errors;
}
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
// Add in a reftime. This is a julian day for:
// noon July 1, 2003
dJulianReftime = 2452822.0;
status = xfDatasetReftime(xScalarAId, dJulianReftime);
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
float minvalue = 9999.9;
float maxvalue = -9999.9;
fValues[0] = (float)dTime;
minvalue = maxvalue = fValues[0];
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*2.5);
minvalue = min(minvalue, fValues[i]);
maxvalue = max(maxvalue, fValues[i]);
}
// we will write the values as pairs
status = xfInitializeScalarTimestep(xScalarAId, dTime, nValues, minvalue,
maxvalue, &timestepId);
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
for (i = 0; i < nValues; i += numValuesPerWrite) {
status = xfWriteScalarTimestepPortion(xScalarAId, timestepId,
numValuesPerWrite, i+1, &fValues[i]);
}
// Set the min to 0.1111*timestepId
// Set the max to 1111*timestepId
minvalue = 0.1111*(float)timestepId;
maxvalue = 1111*(float)timestepId;
status = xfSetDatasetTimestepMinMax(xScalarAId, timestepId,
minvalue, maxvalue);
if (status >= 0) {
// write activity array
xfInitializeActivityTimestep(xScalarAId, nActive, &timestepId);
for (i = 0; i < nActive; i += 2) {
status = xfWriteActivityTimestepPortion(xScalarAId, timestepId, 2,
i+1, &bActivity[i]);
}
}
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
// Write Coordinate file - for ScalarA, we will set the coordinate system
// to be Geographic HPGN, with HPGN settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// set HPGN Zone for test
iHpgnZone = 29; // Utah
// Write Coordinate Information to file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetHPGNArea(xCoordId, iHpgnZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return 1;
} // tdWriteScalarAPiecesAltMinMax
// --------------------------------------------------------------------------
// FUNCTION tdWriteScalarB
// PURPOSE Write scalar Dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// This dataset is dynamic concentrations (mg/L) with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// reads/writes a reference time in julian days
// --------------------------------------------------------------------------
int tdWriteScalarB (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
{
xid xFileId, xDsetsId, xScalarBId, xCoordId = NONE;
int nValues = 10, nTimes = 3, nActive = 8;
double dTime = 0.0, dJulianReftime;
int iTimestep, iActive;
float fValues[10]; // nValues
xmbool bActivity[10]; // activity
int status, nErrors = 0, i = 0;
char **Errors = NULL;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
bActivity[iActive] = XTRUE;
}
bActivity[5] = XFALSE;
if (a_Overwrite) {
// open the already-existing file
status = xfOpenFile(a_Filename, &xFileId, XFALSE);
if (status < 0) {
return -1;
}
// open the group where we have all the datasets
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return -1;
}
}
else {
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return -1;
}
// create the group where we will put all the datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return -1;
}
}
// uncomment next line to test error handling function
// xfCloseGroup(xDsetsId);
// Create/Overwrite the scalar B dataset group
status = xfCreateScalarDataset(xDsetsId, SCALAR_B_LOCATION,
"mg/L", TS_HOURS, a_Compression,
&xScalarBId);
if (status < 0) {
// print the error stack
xfGetNumErrorMessages(&nErrors);
if (nErrors > 0) {
Errors = new char*[nErrors];
for (i = 0; i < nErrors; i++) {
Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
}
status = xfGetErrorMessages(nErrors, Errors);
if (status > 0) {
for (i = 0; i < nErrors; i++) {
printf("%s\n", Errors[i]);
}
}
for (i = 0; i < nErrors; i++) {
delete Errors[i];
}
delete Errors;
}
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// Add in a reftime. This is a julian day for:
// noon July 1, 2003
dJulianReftime = 2452822.0;
status = xfDatasetReftime(xScalarBId, dJulianReftime);
if (status < 0) {
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
if (!a_Overwrite) {
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
fValues[0] = (float)dTime;
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*2.5);
}
// write the dataset array values
status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
}
else {
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 1.5 hour timestep
dTime = (iTimestep + 1) * 1.5;
fValues[0] = (float)dTime;
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*1.5);
}
// write the dataset array values
status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
}
if (!a_Overwrite) {
// Write Coordinate file
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// For ScalarB, we will set the coordinate system
// to be UTM, with UTM Zone settings written to the file.
// Write Coord Info to file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information - we'll use the max value for this test
xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
xfCloseGroup(xCoordId);
xCoordId = 0;
}
// close the dataset
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return 1;
} // tdWriteScalarB
// --------------------------------------------------------------------------
// FUNCTION tdWriteCoordsToMulti
// PURPOSE Write coordinate system to a multidataset file
// NOTES
// --------------------------------------------------------------------------
int tdWriteCoordsToMulti (xid a_xFileId)
{
xid xCoordId = NONE;
int status;
// Write Coordinate file - for Multidatasets, we will set the coordinate system
// to be UTM, with UTM Zone settings written to the file.
status = xfCreateCoordinateGroup(a_xFileId, &xCoordId);
if (status <= 0) {
return -1;
}
// Write Coord Info to file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information - we'll use the max value for this test
xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
xfCloseGroup(xCoordId);
xCoordId = 0;
return XTRUE;
} // tdWriteCoordsToMulti
// --------------------------------------------------------------------------
// FUNCTION tdWriteScalarAToMulti
// PURPOSE Write scalar Dataset to a multidataset
// NOTES This tests dynamic data sets, and activity
// This dataset is dynamic concentrations (mg/L) with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// reads/writes a reference time in julian days
// --------------------------------------------------------------------------
int tdWriteScalarAToMulti (xid a_GroupId)
{
xid xScalarAId;
int nValues = 10, nTimes = 3, nActive = 8;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[10]; // nValues
xmbool bActivity[10]; // activity
int status;
double dJulianReftime;
int i = 0;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
bActivity[iActive] = XTRUE;
}
bActivity[5] = XFALSE;
// Create the scalar A dataset group
status = xfCreateScalarDataset(a_GroupId, SCALAR_A_LOCATION,
"mg/L", TS_HOURS, NONE,
&xScalarAId);
// Add in a reftime. This is a julian day for:
// noon July 1, 2003
dJulianReftime = 2452822.0;
status = xfDatasetReftime(xScalarAId, dJulianReftime);
if (status < 0) {
xfCloseGroup(xScalarAId);
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
fValues[0] = (float)dTime;
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*2.5);
}
// write the dataset array values
status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xScalarAId);
}
}
// close the dataset
xfCloseGroup(xScalarAId);
return FALSE;
} // tdWriteScalarAToMulti
// --------------------------------------------------------------------------
// FUNCTION tdReadVector2DAIndex
// PURPOSE Read all timestep values for a particular index
// NOTES
// --------------------------------------------------------------------------
int tdReadVector2DAIndex (LPCSTR a_Filename, int a_Index)
{
int status;
xid xFileId = NONE, xDsetsId = NONE, xVector2DA = NONE;
int nTimesteps;
float *fValues;
// open the file
status = xfOpenFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// open the dataset group
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status >= 0) {
status = xfOpenGroup(xDsetsId, VECTOR2D_A_LOCATION, &xVector2DA);
}
if (status < 0) {
return status;
}
// Find out the number of timesteps in the file
status = xfGetDatasetNumTimes(xVector2DA, &nTimesteps);
if (status < 0) {
return status;
}
if (nTimesteps < 1) {
return -1;
}
// Read the values for the index
fValues = new float[nTimesteps*2];
status = xfReadVectorValuesAtIndex(xVector2DA, a_Index, 1, nTimesteps, 2,
fValues);
// output the data
printf("\nReading vector 2D A slice at index: %d\n", a_Index);
for (int i = 0; i < nTimesteps; i++) {
printf("%f %f \n", fValues[i*2], fValues[i*2 + 1]);
}
printf("\n");
delete [] fValues;
return status;
} // tdReadVector2DAIndex
// --------------------------------------------------------------------------
// FUNCTION tdWriteVector2D_A
// PURPOSE Write 2D vector dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// Add reftime when it is completed
// This dataset is dynamic water velocities with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// --------------------------------------------------------------------------
int tdWriteVector2D_A (LPCSTR a_Filename, int a_Compression)
{
xid xFileId, xDsetsId, xVectorA, xCoordId = NONE;
int nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[100*2]; // nValues*nComponents
xmbool bActivity[75]; // activity
// double dMin = 0.5, dMax = 3.5;
// int nSeedMultiplier = 138592;
int i, j, status;
int iHpgnZone;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
if (iActive % 3 == 0) {
bActivity[iActive] = XFALSE;
}
else {
bActivity[iActive] = XTRUE;
}
}
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store all datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// Create the scalar A dataset group
status = xfCreateVectorDataset(xDsetsId, VECTOR2D_A_LOCATION, "ft/s",
TS_SECONDS, a_Compression, &xVectorA);
if (status < 0) {
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
// // generate values array using random numbers between dMin and dMax
// tdiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
// nValues*nComponents, fValues);
// write the dataset array values
status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorA, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
// Write Coordinate file - for Vector2D_A, we will set the coordinate system
// to be Geographic HPGN, with HPGN settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// set HPGN info for test
iHpgnZone = 29; // Utah
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetHPGNArea(xCoordId, iHpgnZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
} // tdWriteVector2D_A
// --------------------------------------------------------------------------
// FUNCTION tdWriteVector2D_A_Pieces
// PURPOSE Write 2D vector dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// Add reftime when it is completed
// This dataset is dynamic water velocities with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// --------------------------------------------------------------------------
int tdWriteVector2D_A_Pieces (LPCSTR a_Filename, int a_Compression)
{
xid xFileId, xDsetsId, xVectorA, xCoordId = NONE;
int nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[100*2]; // nValues*nComponents
xmbool bActivity[75]; // activity
int i, j, status;
int iHpgnZone;
hsize_t timestepId = 0;
int nValuesToWrite = 2;
int nComponentsToWrite = 2;
int startIndex = 1;
int startComponent = 1;
float minvalue, maxvalue;
float mag;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
if (iActive % 3 == 0) {
bActivity[iActive] = XFALSE;
}
else {
bActivity[iActive] = XTRUE;
}
}
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store all datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// Create the scalar A dataset group
status = xfCreateVectorDataset(xDsetsId, VECTOR2D_A_LOCATION, "ft/s",
TS_SECONDS, a_Compression, &xVectorA);
if (status < 0) {
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
minvalue = MAX_FLOAT;
maxvalue = 0.0;
for (i = 0; i < nValues; i++) {
mag = 0.0;
for (j = 0; j < nComponents; j++) {
mag += pow((double)fValues[i*nComponents + j], 2.0);
}
mag = sqrt(mag);
minvalue = min(minvalue, mag);
maxvalue = max(maxvalue, mag);
}
// write the dataset array values
status = xfInitializeVectorTimestep(xVectorA, dTime, nValues, nComponents,
minvalue, maxvalue, &timestepId);
// write both components at once
nValuesToWrite = 2;
nComponentsToWrite = 2;
startIndex = 1;
startComponent = 1;
for (int i = 0; i < nValues; i+=2) {
status = xfWriteVectorTimestepPortion(xVectorA, timestepId,
nValuesToWrite, nComponentsToWrite, i + 1, startComponent,
&fValues[2*i]);
}
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorA, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
// Write Coordinate file - for Vector2D_A, we will set the coordinate system
// to be Geographic HPGN, with HPGN settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// set HPGN info for test
iHpgnZone = 29; // Utah
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetHPGNArea(xCoordId, iHpgnZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
} // tdWriteVector2D_A_Pieces
// --------------------------------------------------------------------------
// FUNCTION tdWriteVector2D_B
// PURPOSE Write 2D vector dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// Add reftime when it is completed
// This dataset is dynamic water velocities with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// --------------------------------------------------------------------------
int tdWriteVector2D_B (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
{
xid xFileId, xDsetsId, xVectorB, xCoordId = NONE;
int nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[100*2]; // nValues*nComponents
xmbool bActivity[75]; // activity
// double dMin = 0.5, dMax = 3.5;
// int nSeedMultiplier = 138592;
int i, j, status;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
if (iActive % 3 == 0) {
bActivity[iActive] = XFALSE;
}
else {
bActivity[iActive] = XTRUE;
}
}
if (a_Overwrite) {
//open the already-existing file
status = xfOpenFile(a_Filename, &xFileId, XFALSE);
if (status < 0) {
return -1;
}
// open the group where we have all the datasets
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return -1;
}
}
else {
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store all datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
}
// Create the Vector B dataset group
status = xfCreateVectorDataset(xDsetsId, VECTOR2D_B_LOCATION, "ft/s",
TS_SECONDS, a_Compression, &xVectorB);
if (status < 0) {
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
if (!a_Overwrite) {
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
// write the dataset array values
status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorB, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorB);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
}
else {
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 1.5 hour timestep
dTime = (iTimestep + 1) * 1.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
// write the dataset array values
status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorB, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorB);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
}
// Write Coordinate file - for ScalarB, we will set the coordinate system
// to be UTM, with UTM Zone settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xVectorB);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// write the coordinate data to the file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information - we'll use the max UTM zone for the test
xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xVectorB);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return 1;
} // tdWriteVector2D_B
// --------------------------------------------------------------------------
// FUNCTION tdWriteVector2DAToMulti
// PURPOSE Write 2D vector dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// Add reftime when it is completed
// This dataset is dynamic water velocities with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// --------------------------------------------------------------------------
int tdWriteVector2DAToMulti (xid a_GroupId)
{
xid xVectorA;
int nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[100*2]; // nValues*nComponents
xmbool bActivity[75]; // activity
// double dMin = 0.5, dMax = 3.5;
// int nSeedMultiplier = 138592;
int i, j, status;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
if (iActive % 3 == 0) {
bActivity[iActive] = XFALSE;
}
else {
bActivity[iActive] = XTRUE;
}
}
// Create the scalar A dataset group
status = xfCreateVectorDataset(a_GroupId, VECTOR2D_A_LOCATION, "ft/s",
TS_SECONDS, NONE, &xVectorA);
if (status < 0) {
return FALSE;
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
// // generate values array using random numbers between dMin and dMax
// tdiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
// nValues*nComponents, fValues);
// write the dataset array values
status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorA, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorA);
}
}
// close the dataset
xfCloseGroup(xVectorA);
return FALSE;
} // tdWriteVector2DAToMulti
// --------------------------------------------------------------------------
// FUNCTION tdiRandomNumberInRange
// PURPOSE generate Psuedo Random numbers. We use the same seeds every
// time so we end up with consistent values for testing purposes.
// --------------------------------------------------------------------------
double tdiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed)
{
int nRandom;
double dValue;
srand(a_nSeed);
nRandom = rand();
dValue = a_dMin + ((double)(nRandom)*(a_dMax - a_dMin))/RAND_MAX;
return dValue;
} // tdiRandomNumberInRange
// --------------------------------------------------------------------------
// FUNCTION tdDatasetArray
// PURPOSE Get dataset data to use in a dataset
// NOTES Generates random numbers between a range to fill in the array
// --------------------------------------------------------------------------
void tdiDatasetArray (double a_dMin, double a_dMax, int a_nCycle,
int a_SeedMultiplier, int a_nValues, float *a_Array)
{
int i, nSeedBase;
for (i = 0; i < a_nValues; i++) {
nSeedBase = a_nCycle*a_nValues + i;
a_Array[i] = (float)tdiRandomNumberInRange(a_dMin, a_dMax,
nSeedBase*a_SeedMultiplier);
}
} // tdDatasetArray
// --------------------------------------------------------------------------
// FUNCTION tdiReadScalar
// PURPOSE Read a scalar from an XMDF file and output information to
// to a text file
// NOTES
// --------------------------------------------------------------------------
int tdiReadScalar (xid a_xScalarId, FILE *a_fp)
{
int nTimes = NONE, nValues = NONE, nActive = NONE;
int nStatus = TRUE, iTime, iVal, iActive;
char TimeUnits[100], Units[100];
double *Times = NULL;
float *Values = NULL, *Mins = NULL, *Maxs = NULL;
xmbool *Active = NULL;
xmbool bUseReftime;
double Reftime;
// read the time units
nStatus = xfGetDatasetTimeUnits(a_xScalarId, TimeUnits);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "Time units: %s\n", TimeUnits);
// see if we are using a reftime
nStatus = xfUseDatasetReftime(a_xScalarId, &bUseReftime);
if (nStatus < 0) {
return nStatus;
}
if (bUseReftime) {
nStatus = xfReadDatasetReftime(a_xScalarId, &Reftime);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "Reftime: %f\n", Reftime);
}
// read the units
nStatus = xfGetDatasetUnits(a_xScalarId, Units);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "units: %s\n", Units);
// read in the number of values and number of active values
nStatus = xfGetDatasetNumVals(a_xScalarId, &nValues);
if (nStatus >= 0) {
nStatus = xfGetDatasetNumActive(a_xScalarId, &nActive);
}
if (nStatus < 0) {
return nStatus;
}
if (nValues <= 0) {
printf("No data to read in.");
return -1;
}
// read in the number of times
nStatus = xfGetDatasetNumTimes(a_xScalarId, &nTimes);
if (nStatus < 0) {
return nStatus;
}
// Read in the individual time values
Times = (double *)malloc(nTimes*sizeof(double));
if (Times == NULL) {
printf("Out of memory");
return -1;
}
nStatus = xfGetDatasetTimes(a_xScalarId, nTimes, Times);
if (nStatus < 0) {
return nStatus;
}
// Read in the minimum and maximum values
Mins = (float *)malloc(nTimes*sizeof(float));
Maxs = (float *)malloc(nTimes*sizeof(float));
if (Mins == NULL || Maxs == NULL) {
free(Times);
printf("Out of memory");
return -1;
}
nStatus = xfGetDatasetMins(a_xScalarId, nTimes, Mins);
if (nStatus >= 0) {
nStatus = xfGetDatasetMaxs(a_xScalarId, nTimes, Maxs);
}
if (nStatus < 0) {
free(Times);
free(Mins);
free(Maxs);
return nStatus;
}
Values = (float *)malloc(nValues*sizeof(float));
if (nActive > 0) {
Active = (xmbool *)malloc(nActive*sizeof(xmbool));
}
fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
fprintf(a_fp, "Number Values: %d\n", nValues);
fprintf(a_fp, "Number Active: %d\n", nActive);
// loop through the timesteps, read the values and active values and write
// them to the text file
for (iTime = 0; iTime < nTimes; iTime++) {
// indices should be 1 based
nStatus = xfReadScalarValuesTimestep(a_xScalarId, iTime + 1,
nValues, Values);
if (nStatus >= 0 && nActive > 0) {
// indices should be 1 based
nStatus = xfReadActivityTimestep(a_xScalarId, iTime + 1, nActive, Active);
}
// Write the time, min, max, values and active values to the text output
// file.
fprintf(a_fp, "\nTimestep at %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n",
Times[iTime], Mins[iTime], Maxs[iTime]);
fprintf(a_fp, "Values:\n");
// print 5 values per line
for (iVal = 0; iVal < nValues; iVal++) {
fprintf(a_fp, "%6.3f ", Values[iVal]);
if ((iVal + 1) % 5 == 0) {
fprintf(a_fp, "\n");
}
}
fprintf(a_fp, "\n");
fprintf(a_fp, "Activity:\n");
// print 5 values per line
for (iActive = 0; iActive < nActive; iActive++) {
fprintf(a_fp, "%4d ", (int)Active[iActive]);
if ((iActive + 1) % 5 == 0) {
fprintf(a_fp, "\n");
}
}
fprintf(a_fp, "\n\n");
}
if (Times) {
free(Times);
Times = NULL;
}
if (Mins) {
free(Mins);
Mins = NULL;
}
if (Maxs) {
free(Maxs);
Maxs = NULL;
}
if (Values) {
free(Values);
Values = NULL;
}
if (Active) {
free(Active);
Active = NULL;
}
return TRUE;
} // tdiReadScalar
// --------------------------------------------------------------------------
// FUNCTION tdiReadVector
// PURPOSE Read a vector from an XMDF file and output information to
// to a text file
// NOTES
// --------------------------------------------------------------------------
int tdiReadVector (xid a_xVectorId, FILE *a_fp)
{
int nTimes = NONE, nValues = NONE, nComponents = NONE, nActive = NONE;
int nStatus = TRUE, iTime, iVal, iActive;
char TimeUnits[100];
double *Times = NULL;
float *Values = NULL, *Mins = NULL, *Maxs = NULL;
xmbool *Active = NULL;
xmbool bUseReftime;
double Reftime;
// read the time units
nStatus = xfGetDatasetTimeUnits(a_xVectorId, TimeUnits);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "Time units: %s\n", TimeUnits);
// see if we are using a reftime
nStatus = xfUseDatasetReftime(a_xVectorId, &bUseReftime);
if (nStatus < 0) {
return nStatus;
}
if (bUseReftime) {
nStatus = xfReadDatasetReftime(a_xVectorId, &Reftime);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "Reftime: %f", Reftime);
}
// read in the number of values and number of active values
nStatus = xfGetDatasetNumVals(a_xVectorId, &nValues);
if (nStatus >= 0) {
nStatus = xfGetDatasetVecNumComponents(a_xVectorId, &nComponents);
if (nStatus >= 0) {
nStatus = xfGetDatasetNumActive(a_xVectorId, &nActive);
}
}
if (nStatus < 0) {
return nStatus;
}
if (nValues <= 0) {
printf("No data to read in.");
return -1;
}
// read in the number of times
nStatus = xfGetDatasetNumTimes(a_xVectorId, &nTimes);
if (nStatus < 0) {
return nStatus;
}
// Read in the individual time values
Times = (double *)malloc(nTimes*sizeof(double));
if (Times == NULL) {
printf("Out of memory");
return -1;
}
nStatus = xfGetDatasetTimes(a_xVectorId, nTimes, Times);
if (nStatus < 0) {
return nStatus;
}
// Read in the minimum and maximum values
Mins = (float *)malloc(nTimes*sizeof(float));
Maxs = (float *)malloc(nTimes*sizeof(float));
if (Mins == NULL || Maxs == NULL) {
free(Times);
printf("Out of memory");
return -1;
}
nStatus = xfGetDatasetMins(a_xVectorId, nTimes, Mins);
if (nStatus >= 0) {
nStatus = xfGetDatasetMaxs(a_xVectorId, nTimes, Maxs);
}
if (nStatus < 0) {
free(Times);
free(Mins);
free(Maxs);
return nStatus;
}
Values = (float *)malloc(nValues*nComponents*sizeof(float));
if (nActive > 0) {
Active = (xmbool *)malloc(nActive*sizeof(xmbool));
}
fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
fprintf(a_fp, "Number Values: %d\n", nValues);
fprintf(a_fp, "Number Components: %d\n", nComponents);
fprintf(a_fp, "Number Active: %d\n", nActive);
// loop through the timesteps, read the values and active values and write
// them to the text file
for (iTime = 0; iTime < nTimes; iTime++) {
nStatus = xfReadVectorValuesTimestep(a_xVectorId, iTime + 1,
nValues, nComponents, Values);
if (nStatus >= 0 && nActive > 0) {
nStatus = xfReadActivityTimestep(a_xVectorId, iTime + 1, nActive, Active);
}
// Write the time, min, max, values and active values to the text output
// file.
fprintf(a_fp, "\nTimestep at %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n",
Times[iTime], Mins[iTime], Maxs[iTime]);
fprintf(a_fp, "Values:\n");
// print a set of vector values per line
for (iVal = 0; iVal < nValues; iVal++) {
fprintf(a_fp, "%6.3f %6.3f\n", Values[iVal*nComponents],
Values[(iVal*nComponents) + 1]);
}
fprintf(a_fp, "\n");
fprintf(a_fp, "Activity:\n");
// print 5 values per line
for (iActive = 0; iActive < nActive; iActive++) {
fprintf(a_fp, "%4d ", (int)Active[iActive]);
if ((iActive + 1) % 5 == 0) {
fprintf(a_fp, "\n");
}
}
fprintf(a_fp, "\n\n");
}
if (Times) {
free(Times);
Times = NULL;
}
if (Mins) {
free(Mins);
Mins = NULL;
}
if (Maxs) {
free(Maxs);
Maxs = NULL;
}
if (Values) {
free(Values);
Values = NULL;
}
if (Active) {
free(Active);
Active = NULL;
}
return TRUE;
} // tdiReadVector

TestDatasets.cpp tests datasets

#include "stdafx.h"
#include <xmdf/Xmdf.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include "TestGeomPaths.h"
/* tmReadTestPaths */
int tmReadTestPaths(LPCSTR Filename, LPCSTR OutFilename)
{
int nGroups, nMaxPathLength, nDims, nPaths, nTimes, i, j;
int PathIndices[2];
char *Paths = NULL, *IndividualPath = NULL;
double *times, *locs, NullVal = 0;
xid xFileId = NONE, xGroupId = NONE;
int nStatus;
FILE *fp = NULL;
// open the XMDF file
nStatus = xfOpenFile(Filename, &xFileId, TRUE);
if (nStatus < 0) {
printf("Unable to open XMDF file tmReadTestPaths.");
return nStatus;
}
// open the Output file
fp = fopen(OutFilename, "w");
if (fp == NULL) {
printf("Unable to open output file tmReadTestPaths.");
return nStatus;
}
// find the geomotric path groups
// Get the number and paths of datasets in the file.
nStatus = xfGetGroupPathsSizeForGeomPaths(xFileId, &nGroups,
&nMaxPathLength);
if (nStatus >= 0) {
Paths = (char *)malloc(nMaxPathLength*nGroups*sizeof(char));
nStatus = xfGetGroupPathsForGeomPaths(xFileId, nGroups,
nMaxPathLength, Paths);
}
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// Report the number and paths to individual geom paths groups in the file.
fprintf(fp, "Number of geometric paths in file: %d\n", nGroups);
fprintf(fp, "Paths:\n");
for (i = 0; i < nGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, " %s\n", IndividualPath);
}
fprintf(fp, "\n");
// Open each geometric path group
for (i = 0; i < nGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, "Reading geom paths in group: %s\n", IndividualPath);
nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
if (nStatus >= 0) {
// read the dimensionality of the paths
nStatus = xfGetPathDimensionality(xGroupId, &nDims);
if (nStatus >= 0) {
fprintf(fp, "Group dimensionality: %d\n", nDims);
// read the number of paths
nStatus = xfGetNumberOfPaths(xGroupId, &nPaths);
if (nStatus >= 0) {
fprintf(fp, "Number of paths in group: %d\n", nPaths);
// read the number of timesteps
nStatus = xfGetNumberOfTimes(xGroupId, &nTimes);
if (nStatus >= 0) {
fprintf(fp, "Number of timesteps in group: %d\n", nTimes);
// allocate times array
times = (double *)malloc(nTimes*sizeof(double));
if (times != NULL) {
nStatus = xfGetPathTimesArray(xGroupId, nTimes, times);
if (nStatus >= 0) {
// get space for the data location values
locs = (double *)malloc(nPaths*nDims*sizeof(double));
if (locs != NULL) {
// read null value
nStatus = xfGetPathNullVal(xGroupId, &NullVal);
if (nStatus >= 0) {
fprintf(fp, "Null value: %lf\n", NullVal);
for (i=0; i<nTimes; ++i) {
fprintf(fp, "Timestep: %lf\n", times[i]);
// read the data for this timestep
nStatus = xfReadPathLocationsAtTime(xGroupId, i+1,
1, nPaths, locs);
if (nStatus >= 0) {
// write the data for this timestep
fprintf(fp, " X Y");
if (nDims == 3) {
fprintf(fp, " Z");
}
fprintf(fp, "\n");
for (j=0; j<nPaths; ++j) {
if (locs[j*nDims] == NullVal) {
fprintf(fp, "Particle not active yet\n");
}
else {
fprintf(fp, "%lf %lf", locs[j*nDims],
locs[j*nDims+1]);
if (nDims == 3) {
fprintf(fp, " %lf", locs[j*nDims+2]);
}
fprintf(fp, "\n");
}
} // Loop through the points
}
} // Loop through timesteps
}
free(locs);
}
// get space for the data location values - 1 particle
// all times
locs = (double *)malloc(nTimes*nDims*sizeof(double));
if (locs != NULL) {
for (i=0; i<nPaths; ++i) {
// read the values for this particle for all timesteps
nStatus = xfReadPathLocationsForParticle(xGroupId, i+1,
1, nTimes, locs);
if (nStatus >= 0) {
// write the data for this path
fprintf(fp, "Time X Y");
if (nDims == 3) {
fprintf(fp, " Z");
}
fprintf(fp, "\n");
for (j=0; j<nTimes; ++j) {
if (locs[j*nDims] != NullVal) {
fprintf(fp, "%lf %lf %lf", times[j], locs[j*nDims],
locs[j*nDims+1]);
if (nDims == 3) {
fprintf(fp, " %lf", locs[j*nDims+2]);
}
fprintf(fp, "\n");
}
} // Loop through the times
}
} // Loop through the paths
free(locs);
}
// get space for the data location values - 2 particle
// all times
locs = (double *)malloc(nTimes*nDims*2*sizeof(double));
if (locs != NULL) {
PathIndices[0] = 1;
PathIndices[1] = nPaths;
nStatus = xfReadPathLocationsForParticles(xGroupId, 2,
PathIndices, 1, nTimes, locs);
if (nStatus >= 0) {
// write the data for these 2 paths
if (nDims == 3) {
fprintf(fp, "Timestep X1 Y1 Z1 Xn Yn Zn\n");
}
else {
fprintf(fp, "Timestep X1 Y1 Xn Yn\n");
}
for (j=0; j<nTimes; ++j) {
if (nDims == 3) {
fprintf(fp, "%lf %lf %lf %lf %lf %lf %lf\n", times[j],
locs[j*2*nDims], locs[j*2*nDims+1],
locs[j*2*nDims+2], locs[j*2*nDims+3],
locs[j*2*nDims+4], locs[j*2*nDims+5]);
}
else {
fprintf(fp, "%lf %lf %lf %lf %lf\n", times[j],
locs[j*2*nDims], locs[j*2*nDims+1],
locs[j*2*nDims+2], locs[j*2*nDims+3]);
}
} // Loop through the times
}
free(locs);
}
}
free(times);
}
}
}
}
xfCloseGroup(xGroupId);
}
if (nStatus < 0) {
printf("Error reading geometric paths..\n");
}
}
// free the paths
if (Paths) {
free(Paths);
Paths = NULL;
}
// close the files
fclose(fp);
xfCloseFile(xFileId);
return nStatus;
} /* tmReadTestPaths */
/* tmWriteTestPaths */
int tmWriteTestPaths(LPCSTR Filename, int Compression)
{
int nPaths = 0;
double pLocs[6];
float pSpeeds[2], NullVal = (float)-99999.9;
xid xFileId = NONE, xPathGroupId = NONE, xSpeedId = NONE,
xPropGroupId = NONE;
int status;
/* create the file */
status = xfCreateFile(Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
/* create the group to store the particle paths */
status = xfCreateGeometricPathGroup(xFileId, "particles",
"abcdefglasdfjoaieur", Compression,
&xPathGroupId, -99999.9);
if (status < 0) {
return FALSE;
}
/* create the data set to store the speed */
status = xfCreateScalarDatasetExtendable(xPathGroupId, "Vmag", "m/s",
TS_SECONDS, NullVal, Compression, &xSpeedId);
if (status < 0) {
return -1;
}
if (xfCreatePropertyGroup(xSpeedId, &xPropGroupId) < 0) {
xfCloseGroup(xSpeedId);
return -1;
}
xfWritePropertyFloat(xPropGroupId, PROP_NULL_VALUE, 1, &NullVal, -1);
xfCloseGroup(xPropGroupId);
// Setup the arrays for the path group at timestep 0
// particle location at the first timestep
nPaths = 1;
pLocs[0] = 1.0; pLocs[1] = 2.0; pLocs[2] = 3.0;
// store the particles for the first timestep
status = xfWriteParticleTimestep(xPathGroupId, 3, 0.0, nPaths, pLocs);
if (status < 0) {
return FALSE;
}
// set up and store the speed at timestep 0
pSpeeds[0] = (float)(1.1);
status = xfWriteScalarTimestep(xSpeedId, 0.0, 1, pSpeeds);
if (status < 0) {
return FALSE;
}
// Setup the arrays for the path group at timestep 1
// particle location at the first timestep
pLocs[0] = 4.0; pLocs[1] = 5.0; pLocs[2] = 6.0;
// store the particles for the first timestep
status = xfWriteParticleTimestep(xPathGroupId, 3, 1.0, nPaths, pLocs);
if (status < 0) {
return FALSE;
}
// set up and store the speed at timestep 1
pSpeeds[0] = (float)(1.2);
status = xfWriteScalarTimestep(xSpeedId, 1.0, 1, pSpeeds);
if (status < 0) {
return FALSE;
}
// Setup the arrays for the path group at timestep 2-add a particle
// particle location at the first timestep
nPaths = 2;
pLocs[0] = 7.0; pLocs[1] = 8.0; pLocs[2] = 9.0;
pLocs[3] = -1.0; pLocs[4] = -2.0; pLocs[5] = -3.0;
// store the particles for the timestep 2
status = xfWriteParticleTimestep(xPathGroupId, 3, 2.0, nPaths, pLocs);
if (status < 0) {
return FALSE;
}
// extend the data set for speed
status = xfExtendScalarDataset(xSpeedId, 2);
if (status < 0) {
return FALSE;
}
// set up and store the speed at timestep 2
pSpeeds[0] = (float)1.3;
pSpeeds[1] = (float)2.1;
status = xfWriteScalarTimestep(xSpeedId, 2.0, 2, pSpeeds);
if (status < 0) {
return FALSE;
}
// Setup the arrays for the path group at timestep 3-inactive particle(static)
// particle location at the first timestep
pLocs[0] = 7.0; pLocs[1] = 8.0; pLocs[2] = 9.0;
pLocs[3] = -4.0; pLocs[4] = -5.0; pLocs[5] = -6.0;
// store the particles for timestep 3
status = xfWriteParticleTimestep(xPathGroupId, 3, 3.0, nPaths, pLocs);
if (status < 0) {
return FALSE;
}
// set up and store the speed at timestep 3
pSpeeds[0] = NullVal;
pSpeeds[1] = (float)2.2;
status = xfWriteScalarTimestep(xSpeedId, 3.0, 2, pSpeeds);
if (status < 0) {
return FALSE;
}
// close the resources
xfCloseGroup(xSpeedId);
xfCloseGroup(xPathGroupId);
xfCloseFile(xFileId);
return TRUE;
}

TestGeomPaths.cpp tests geometry paths

#include "stdafx.h"
#include <xmdf/Xmdf.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#define GRID_CART2D_GROUP_NAME "Grid Cart2D Group"
#define GRID_CURV2D_GROUP_NAME "Grid Curv2D Group"
#define GRID_CART3D_GROUP_NAME "Grid Cart3D Group"
// ---------------------------------------------------------------------------
// FUNCTION tgReadGrid
// PURPOSE Read a grid and write data to a text file
// NOTES
// ---------------------------------------------------------------------------
int tgReadGrid (xid a_Id, FILE *a_Outfile)
{
int nGridType = 0, nExtrudeType = 0, nDims = 0, nCellsI = 0, nCellsJ = 0;
int nCellsK = 0, nLayers = 0, nOrientation = 0, nValsI = 0, nValsJ = 0;
int nValsK = 0, nExtrudeVals = 0, nCompOrigin = 1, nUDir = 1;
char strGridType[256], strExtrudeType[256];
xmbool bDefined = XFALSE;
double dOrigin[3], dBearing = 0.0, dDip = 0.0, dRoll =0.0;
double *dExtrudeVals = NULL, *dCoordI = NULL, *dCoordJ = NULL;
double *dCoordK = NULL;
int i = 0, error = 1;
// Grid type
error = xfGetGridType(a_Id, &nGridType);
if (error < 0) {
return error;
}
switch (nGridType) {
case GRID_TYPE_CARTESIAN:
strcpy(strGridType, "Cartesian");
break;
case GRID_TYPE_CURVILINEAR:
strcpy(strGridType, "Curvilinear");
break;
case GRID_TYPE_CARTESIAN_EXTRUDED:
strcpy(strGridType, "Cartesian extruded");
break;
case GRID_TYPE_CURVILINEAR_EXTRUDED:
strcpy(strGridType, "Curvilinear extruded");
break;
default:
printf("Invalid grid type.");
return -1;
break;
}
fprintf(a_Outfile, "The grid type is: %s\n", strGridType);
// Number of dimensions
error = xfGetNumberOfDimensions(a_Id, &nDims);
if (error < 0) {
return error;
}
if (nDims == 2) {
fprintf(a_Outfile, "The grid is two-dimensional\n");
}
else if (nDims == 3) {
fprintf(a_Outfile, "The grid is three-dimensional\n");
}
else {
printf("The grid dimensions are invalid.");
return -1;
}
// Extrusion type if applicable
if (nGridType == GRID_TYPE_CARTESIAN_EXTRUDED ||
nGridType == GRID_TYPE_CURVILINEAR_EXTRUDED) {
error = xfGetExtrusionType(a_Id, &nExtrudeType);
if (error < 0) {
return error;
}
switch(nExtrudeType) {
case EXTRUDE_SIGMA:
strcpy(strExtrudeType, "Sigma stretch");
break;
case EXTRUDE_CARTESIAN:
strcpy(strExtrudeType, "Cartesian");
break;
case EXTRUDE_CURV_AT_CORNERS:
strcpy(strExtrudeType, "Curvilinear at Corners");
break;
case EXTRUDE_CURV_AT_CELLS:
strcpy(strExtrudeType, "Curvilinear at Cells");
break;
}
fprintf(a_Outfile, "The grid is extruding using: %s\n", strExtrudeType);
}
// Origin
error = xfOriginDefined(a_Id, &bDefined);
if (error < 0) {
return error;
}
if (bDefined) {
error = xfGetOrigin(a_Id, &dOrigin[0], &dOrigin[1], &dOrigin[2]);
if (error < 0) {
return error;
}
fprintf(a_Outfile, "The grid origin is %lf %lf %lf\n", dOrigin[0],
dOrigin[1], dOrigin[2]);
}
// Orientation
error = xfGetOrientation(a_Id, &nOrientation);
if (error < 0) {
return error;
}
if (nOrientation == ORIENTATION_RIGHT_HAND) {
fprintf(a_Outfile, "The grid has a right hand orientation\n");
}
else if (nOrientation == ORIENTATION_LEFT_HAND) {
fprintf(a_Outfile, "The grid has a left hand orientation\n");
}
else {
printf("Invalid grid orientation.");
return -1;
}
// Bearing
error = xfBearingDefined(a_Id, &bDefined);
if (error < 0) {
return error;
}
if (bDefined) {
error = xfGetBearing(a_Id, &dBearing);
if (error < 0) {
return error;
}
fprintf(a_Outfile, "The grid bearing is %lf\n", dBearing);
}
// Dip
error = xfDipDefined(a_Id, &bDefined);
if (error < 0) {
return error;
}
if (bDefined) {
error = xfGetDip(a_Id, &dDip);
if (error < 0) {
return error;
}
fprintf(a_Outfile, "The grid Dip is %lf\n", dDip);
}
if (nDims == 3) {
// Roll
error = xfRollDefined(a_Id, &bDefined);
if (error < 0) {
return error;
}
if (bDefined) {
error = xfGetRoll(a_Id, &dRoll);
if (error < 0) {
return error;
}
fprintf(a_Outfile, "The grid Roll is %lf\n", dRoll);
}
}
// Computational origin
error = xfComputationalOriginDefined(a_Id, &bDefined);
if (error < 0) {
return error;
}
if (bDefined) {
error = xfGetComputationalOrigin(a_Id, &nCompOrigin);
if (error < 0) {
return error;
}
fprintf(a_Outfile, "The grid Computational Origin is %d\n", nCompOrigin);
}
else {
fprintf(a_Outfile, "The grid Computational Origin is not defined\n");
}
// U Direction
error = xfGetUDirectionDefined(a_Id, &bDefined);
if (error < 0) {
return error;
}
if (bDefined) {
error = xfGetUDirection(a_Id, &nUDir);
if (error < 0) {
return error;
}
fprintf(a_Outfile, "The grid U Direction is %d\n", nUDir);
}
else {
fprintf(a_Outfile, "The grid U Direction is not defined\n");
}
// number of cells in each direction
error = xfGetNumberCellsInI(a_Id, &nCellsI);
if (error >= 0) {
error = xfGetNumberCellsInJ(a_Id, &nCellsJ);
if (error >= 0 && nDims == 3) {
error = xfGetNumberCellsInK(a_Id, &nCellsK);
}
}
if (error < 0) {
return error;
}
fprintf(a_Outfile, "Number of cells in I %d\n", nCellsI);
fprintf(a_Outfile, "Number of cells in J %d\n", nCellsJ);
if (nDims == 3) {
fprintf(a_Outfile, "Number of cells in K %d\n", nCellsK);
}
// Grid coordinates
switch (nGridType) {
case GRID_TYPE_CARTESIAN:
case GRID_TYPE_CARTESIAN_EXTRUDED:
nValsI = nCellsI;
nValsJ = nCellsJ;
if (nDims == 3) {
nValsK = nCellsK;
}
break;
case GRID_TYPE_CURVILINEAR:
case GRID_TYPE_CURVILINEAR_EXTRUDED:
if (nDims == 3) {
// three dimensions
nValsI = nValsJ = nValsK = (nCellsI + 1) * (nCellsJ + 1) *(nCellsK + 1);
}
else {
// two dimensions
nValsI = nValsJ = (nCellsI + 1) * (nCellsJ + 1);
}
break;
default:
printf("Invalid grid type.");
return -1;
break;
}
dCoordI = new double[nValsI];
dCoordJ = new double[nValsJ];
if (nDims == 3) {
dCoordK = new double[nValsK];
}
error = xfGetGridCoordsI(a_Id, nValsI, dCoordI);
if (error >= 0) {
error = xfGetGridCoordsJ(a_Id, nValsJ, dCoordJ);
if (error >= 0 && nDims == 3) {
error = xfGetGridCoordsK(a_Id, nValsK, dCoordK);
}
}
if (error < 0) {
printf("Error reading coordinates.\n");
return -1;
}
fprintf(a_Outfile, "The Coordinates in direction I:\n");
for (i = 0; i < nValsI; i++) {
if ((i + 1) % 5 == 0) {
fprintf(a_Outfile, "\n");
}
fprintf(a_Outfile, "%lf ", dCoordI[i]);
}
fprintf(a_Outfile, "\n");
fprintf(a_Outfile, "The Coordinates in direction J:\n");
for (i = 0; i < nValsJ; i++) {
if ((i + 1) % 5 == 0) {
fprintf(a_Outfile, "\n");
}
fprintf(a_Outfile, "%lf ", dCoordJ[i]);
}
fprintf(a_Outfile, "\n");
if (nDims == 3) {
fprintf(a_Outfile, "The Coordinates in direction K:\n");
for (i = 0; i < nValsK; i++) {
if ((i + 1) % 5 == 0) {
fprintf(a_Outfile, "\n");
}
fprintf(a_Outfile, "%lf ", dCoordK[i]);
}
}
fprintf(a_Outfile, "\n");
if (dCoordI) {
delete dCoordI;
}
if (dCoordJ) {
delete dCoordJ;
}
if (dCoordK) {
delete dCoordK;
}
// Extrude data
if (nGridType == GRID_TYPE_CARTESIAN_EXTRUDED ||
nGridType == GRID_TYPE_CURVILINEAR_EXTRUDED) {
error = xfGetExtrudeNumLayers(a_Id, &nLayers);
if (error < 0) {
return error;
}
switch(nExtrudeType) {
case EXTRUDE_SIGMA:
nExtrudeVals = nLayers;
break;
case EXTRUDE_CURV_AT_CORNERS:
nExtrudeVals = (nCellsI + 1) * (nCellsJ + 1) * nLayers;
break;
case EXTRUDE_CURV_AT_CELLS:
nExtrudeVals = nCellsI * nCellsJ * nLayers;
break;
}
dExtrudeVals = new double[nExtrudeVals];
error = xfGetExtrudeValues(a_Id, nExtrudeVals, dExtrudeVals);
if (error < 0) {
return error;
}
printf("The extrude values are:\n");
for (i = 0; i < nExtrudeVals; i++) {
if ((i + 1) % 5 == 0) {
fprintf(a_Outfile, "\n");
}
fprintf(a_Outfile, "%lf ", dExtrudeVals[i]);
}
if (dExtrudeVals) {
delete dExtrudeVals;
}
}
return error;
} // tgReadGrid
//////////////////////////////////////////////////////////////////////////////
// FUNCTION tgWriteTestGridCart2D
// PURPOSE Write a file that contains data for a 2D Cartesian Grid
// NOTES A picture of the grid is in the file (TestGridCart2D.gif)
// returns TRUE on success and FALSE on failure
//////////////////////////////////////////////////////////////////////////////
int tgWriteTestGridCart2D(LPCSTR Filename, int Compression)
{
int nDimensions = 2;
int nCellsI = 5, nCellsJ = 5;
int nGridType = GRID_TYPE_CARTESIAN;
int nCompOrigin = 4, nUDir = -2;
double dOriginX = 10.0, dOriginY = 10.0, dOriginZ = 0.0;
int nOrientation = ORIENTATION_RIGHT_HAND;
double dBearing = 45.0;
double PlanesI[5], PlanesJ[5];
int i, j, iSpcZone;
xid xFileId = NONE, xGridId = NONE, xCoordId = NONE;
int status;
// Fill in the grid plane data with a constant size of 30
for (i = 1; i <= nCellsI; i++) {
PlanesI[i - 1] = (double)i*30.0;
}
for (j = 1; j <= nCellsJ; j++) {
PlanesJ[j - 1] = (double)j*30.0;
}
// create the file
status = xfCreateFile(Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store the grid
status = xfCreateGroupForGrid(xFileId, GRID_CART2D_GROUP_NAME, &xGridId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// Write the grid information to the file
if (xfSetGridType(xGridId, nGridType) < 0 ||
xfSetNumberOfDimensions(xGridId, nDimensions) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// set origin and orientation
if (xfSetOrigin(xGridId, dOriginX, dOriginY, dOriginZ) < 0 ||
xfSetOrientation(xGridId, nOrientation) < 0 ) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set bearing
if (xfSetBearing(xGridId, dBearing) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set computational origin
if (xfSetComputationalOrigin(xGridId, nCompOrigin) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set u direction
if (xfSetUDirection(xGridId, nUDir) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Write the grid geometry to the file
// Set the number of cells in each direction
if (xfSetNumberCellsInI(xGridId, nCellsI) < 0 ||
xfSetNumberCellsInJ(xGridId, nCellsJ) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set the grid plane locations
if (xfSetGridCoordsI(xGridId, nCellsI, PlanesI) < 0 ||
xfSetGridCoordsJ(xGridId, nCellsJ, PlanesJ) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Write Coordinate file - for GridCart2D, we will set the coordinate system
// to be State Plane NAD27.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return -1;
}
iSpcZone = 3601; // Oregon North
xfSetHorizDatum(xCoordId, HORIZ_DATUM_STATE_PLANE_NAD27);
xfSetHorizUnits(xCoordId, COORD_UNITS_US_FEET);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_US_FEET);
// write additional information
xfSetSPCZone(xCoordId, iSpcZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// release memory
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return TRUE;
} // tgWriteTestGridCart2D
//////////////////////////////////////////////////////////////////////////////
// FUNCTION tgWriteTestGridCurv2D
// PURPOSE Write a file that contains data for a 2D Curvilinear Grid
// NOTES A picture of the grid is TestGridCurv2D.gif
// returns TRUE on success and FALSE on failure
//////////////////////////////////////////////////////////////////////////////
int tgWriteTestGridCurv2D(LPCSTR Filename, int Compression)
{
int nDimensions = 2;
int nCompOrigin = 1, nUDir = 1;
int nCellsI = 2, nCellsJ = 3;
int nCells = nCellsI*nCellsJ;
int nCorners = (nCellsI + 1)*(nCellsJ + 1);
int nGridType = GRID_TYPE_CURVILINEAR, i;
double xVals[16], yVals[16]; // 16 is the number of corners
double dCppLat, dCppLon;
xid xFileId = NONE, xGridId = NONE, xPropId = NONE,
xDatasetsId = NONE, xScalarId = NONE, xCoordId = NONE;
double dNullValue = -999.0;
int nOrientation = ORIENTATION_RIGHT_HAND;
float fDsetCellVals[6]; // for cell-centered dataset
float fDsetCornerVals[12]; // for corner-centered dataset
xmbool bDsetCellActive[6];
xmbool bDsetCornerActive[12];
int status;
// There is no cell in the top right corner so we have a NullValue for
// the top right corner
// xValues row by row
xVals[0] = 0.0; xVals[1] = 7.5; xVals[2] = 15.0;
xVals[3] = 2.5; xVals[4] = 10.0; xVals[5] = 17.5;
xVals[6] = 3.5; xVals[7] = 11.0; xVals[8] = 18.5;
xVals[9] = 0.0; xVals[10] = 7.5; xVals[11] = dNullValue;
// yValues row by row
yVals[0] = 0.0; yVals[1] = 0.0; yVals[2] = 0.0;
yVals[3] = 10.0; yVals[4] = 10.0; yVals[5] = 10.0;
yVals[6] = 20.0; yVals[7] = 20.0; yVals[8] = 20.0;
yVals[9] = 30.0; yVals[10] = 30.0; yVals[11] = dNullValue;
// cell centered velocity dataset values
fDsetCellVals[0] = (float)2.1; fDsetCellVals[1] = (float)2.0;
fDsetCellVals[2] = (float)1.9; fDsetCellVals[3] = (float)2.3;
fDsetCellVals[4] = (float)2.5; fDsetCellVals[5] = (float)dNullValue;
// all are active except the last value
for (i = 0; i < nCells; i++) {
bDsetCellActive[i] = XTRUE;
}
bDsetCellActive[nCells - 1] = XFALSE;
// corner centered elevation dataset values
fDsetCornerVals[0] = (float)1.0; fDsetCornerVals[1] = (float)0.8;
fDsetCornerVals[2] = (float)1.2;
fDsetCornerVals[3] = (float)1.4; fDsetCornerVals[4] = (float)1.8;
fDsetCornerVals[5] = (float)2.2;
fDsetCornerVals[6] = (float)1.8; fDsetCornerVals[7] = (float)1.4;
fDsetCornerVals[8] = (float)2.0;
fDsetCornerVals[9] = (float)1.0; fDsetCornerVals[10] = (float)1.8;
fDsetCornerVals[11] = (float)2.2;
// all are active except the last value
for (i = 0; i < nCorners; i++) {
bDsetCornerActive[i] = XTRUE;
}
bDsetCornerActive[nCorners - 1] = XFALSE;
// create the file
status = xfCreateFile(Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store the grid
status = xfCreateGroupForGrid(xFileId, GRID_CURV2D_GROUP_NAME, &xGridId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// Write the grid information to the file
if (xfSetGridType(xGridId, nGridType) < 0 ||
xfSetNumberOfDimensions(xGridId, nDimensions) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// set orientation
if (xfSetOrientation(xGridId, nOrientation) < 0 ) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set computational origin
if (xfSetComputationalOrigin(xGridId, nCompOrigin) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set u direction
if (xfSetUDirection(xGridId, nUDir) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Write the grid geometry to the file
// Set the number of cells in each direction
if (xfSetNumberCellsInI(xGridId, nCellsI) < 0 ||
xfSetNumberCellsInJ(xGridId, nCellsJ) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set a NullValue. This is used to identify locations in the grid that are
// not being used. In our case no geometry is defined for the top right
// corner.
if (xfCreateGridPropertyGroup(xGridId, &xPropId) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
if (xfWritePropertyDouble(xPropId, PROP_NULL_VALUE, 1, &dNullValue, NONE) < 0){
xfCloseGroup(xPropId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
xfCloseGroup(xPropId);
// Set the grid plane locations
if (xfSetGridCoordsI(xGridId, nCorners, xVals) < 0 ||
xfSetGridCoordsJ(xGridId, nCorners, yVals) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Create the datasets group
if (xfCreateGenericGroup(xGridId, "Datasets", &xDatasetsId) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Create the cell-centered dataset
if (xfCreateScalarDataset(xDatasetsId, "Velocity Mag", "ft/s", TS_MINUTES,
Compression, &xScalarId) < 0) {
xfCloseGroup(xDatasetsId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// specify that the dataset is cell-centered
if (xfScalarDataLocation(xScalarId, GRID_LOC_CENTER) < 0) {
xfCloseGroup(xScalarId);
xfCloseGroup(xDatasetsId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Write the data
if (xfWriteScalarTimestep(xScalarId, 0.0, nCells, fDsetCellVals) < 0 ||
xfWriteActivityTimestep(xScalarId, nCells, bDsetCellActive) < 0) {
xfCloseGroup(xScalarId);
xfCloseGroup(xDatasetsId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// close the cell-centered dataset
xfCloseGroup(xScalarId);
// Create the corner-centered dataset
if (xfCreateScalarDataset(xDatasetsId, "elevation", "ft", TS_MINUTES,
Compression, &xScalarId) < 0) {
xfCloseGroup(xDatasetsId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// specify that the dataset is corner-centered
if (xfScalarDataLocation(xScalarId, GRID_LOC_CORNER) < 0) {
xfCloseGroup(xScalarId);
xfCloseGroup(xDatasetsId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Write the data
if (xfWriteScalarTimestep(xScalarId, 0.0, nCorners, fDsetCornerVals) < 0 ||
xfWriteActivityTimestep(xScalarId, nCorners, bDsetCornerActive) < 0){
xfCloseGroup(xScalarId);
xfCloseGroup(xDatasetsId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Write Coordinate file - for GridCurv2D, we will set the coordinate system
// to be CPP, with CPP Latitude and CPP Longitude settings written
// to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xScalarId);
xfCloseGroup(xDatasetsId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return -1;
}
dCppLat = 56.0; // Made-up value
dCppLon = 23.0; // Made-up value
xfSetHorizDatum(xCoordId, HORIZ_DATUM_CPP);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetCPPLat(xCoordId, dCppLat);
xfSetCPPLon(xCoordId, dCppLon);
xfCloseGroup(xCoordId);
xCoordId = 0;
// release memory
xfCloseGroup(xScalarId);
xfCloseGroup(xDatasetsId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return TRUE;
} // tgWriteTestGridCurv2D
//////////////////////////////////////////////////////////////////////////////
// FUNCTION tgWriteTestGridCart3D
// PURPOSE Write a file that contains data for a 2D Cartesian Grid
// NOTES A picture of the grid is in the file (TestGridCart2D.gif)
// returns TRUE on success and FALSE on failure
//////////////////////////////////////////////////////////////////////////////
int tgWriteTestGridCart3D(LPCSTR Filename, int Compression)
{
int nDimensions = 3;
int nCompOrigin = 8, nUDir = -2;
int nCellsI = 5, nCellsJ = 5, nCellsK = 3;
int nGridType = GRID_TYPE_CARTESIAN;
double dOriginX = 10.0, dOriginY = 10.0, dOriginZ = 0.0;
int nOrientation = ORIENTATION_RIGHT_HAND;
double dBearing = 45.0, dDip = 0.0, dRoll = 0.0;
double PlanesI[5], PlanesJ[5], PlanesK[3];
int i, j, status, iSpcZone;
xid xFileId = NONE, xGridId = NONE;
xid xPropId = NONE, xCoordId = NONE;
int nCells = nCellsI * nCellsJ * nCellsK;
int Active[75];
// Fill in the grid plane data with a constant size of 30
for (i = 1; i <= nCellsI; i++) {
PlanesI[i - 1] = (double)i*30.0;
}
for (j = 1; j <= nCellsJ; j++) {
PlanesJ[j - 1] = (double)j*30.0;
}
for (j = 1; j <= nCellsK; j++) {
PlanesK[j - 1] = (double)j*30.0;
}
// fill in the activity array
// default array to active
for (i = 0; i < nCells; i++) {
Active[i] = (int)XTRUE;
}
// two cells are inactive (identified by array index)
// i = 0, j = 0, k = 0 and i = 4, j = 4, k = 0
Active[0] = (int)XFALSE;
Active[4*nCellsJ*nCellsK+4*nCellsK] = (int)XFALSE;
// create the file
if (xfCreateFile(Filename, &xFileId, XTRUE) < 0) {
return FALSE;
}
// create the group to store the grid
if (xfCreateGroupForGrid(xFileId, GRID_CART3D_GROUP_NAME, &xGridId) < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// Write the grid information to the file
if (xfSetGridType(xGridId, nGridType) < 0 ||
xfSetNumberOfDimensions(xGridId, nDimensions) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// set origin and orientation
if (xfSetOrigin(xGridId, dOriginX, dOriginY, dOriginZ) < 0 ||
xfSetOrientation(xGridId, nOrientation) < 0 ) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set bearing, dip and roll
if (xfSetBearing(xGridId, dBearing) < 0 ||
xfSetDip(xGridId, dDip) < 0 ||
xfSetRoll(xGridId, dRoll) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set computational origin
if (xfSetComputationalOrigin(xGridId, nCompOrigin) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set u direction
if (xfSetUDirection(xGridId, nUDir) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Write the grid geometry to the file
// Set the number of cells in each direction
if (xfSetNumberCellsInI(xGridId, nCellsI) < 0 ||
xfSetNumberCellsInJ(xGridId, nCellsJ) < 0 ||
xfSetNumberCellsInK(xGridId, nCellsK) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Set the grid plane locations
if (xfSetGridCoordsI(xGridId, nCellsI, PlanesI) < 0 ||
xfSetGridCoordsJ(xGridId, nCellsJ, PlanesJ) < 0 ||
xfSetGridCoordsK(xGridId, nCellsK, PlanesK) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
// Write the activity array
if (xfCreateGridCellPropertyGroup(xGridId, &xPropId) < 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
if (xfWritePropertyInt(xPropId, PROP_ACTIVITY, nCells, Active,
Compression) < 0) {
xfCloseGroup(xPropId);
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return FALSE;
}
xfCloseGroup(xPropId);
// Write Coordinate file - for GridCart3D, we will set the coordinate system
// to be State Plane NAD27.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return -1;
}
iSpcZone = 3601; // Oregon North
xfSetHorizDatum(xCoordId, HORIZ_DATUM_STATE_PLANE_NAD27);
xfSetHorizUnits(xCoordId, COORD_UNITS_US_FEET);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_US_FEET);
// write additional information
xfSetSPCZone(xCoordId, iSpcZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// release memory
xfCloseGroup(xGridId);
xfCloseFile(xFileId);
return TRUE;
} // tgWriteTestGridCart3D

TestGrid.cpp tests grids

#include "stdafx.h"
#include <xmdf/Xmdf.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#define MESH_A_GROUP_NAME "MeshA Group"
#define MESH_B_GROUP_NAME "MeshB Group"
// ---------------------------------------------------------------------------
// FUNCTION tmReadMesh
// PURPOSE
// NOTES
// ---------------------------------------------------------------------------
int tmReadMesh (xid xGroupId, FILE *a_OutFile)
{
int nElems = 0, nNodes = 0, nNodesPerElem = 0, nElemType, nNodeId;
xmbool bElementsOneType;
int status;
int *ElemTypes = NULL;
int i, j, StrType, UIntType, IntType, DblType, FloatType;
int *NodesInElem = NULL;
double *XNodeLocs, *YNodeLocs, *ZNodeLocs;
xid xPropGrpId;
// Get the number of elements, nodes, and Maximum number of nodes per element
status = xfGetNumberOfElements(xGroupId, &nElems);
if (status >= 0) {
status = xfGetNumberOfNodes(xGroupId, &nNodes);
if (status >= 0) {
status = xfGetMaxNodesInElem(xGroupId, &nNodesPerElem);
}
}
if (status < 0) {
return -1;
}
// Do Element information first
fprintf(a_OutFile, "Number of Elements: %d\n", nElems);
// Element types
status = xfAreAllElemsSameType(xGroupId, &bElementsOneType);
if (status < 0) {
return -1;
}
if (bElementsOneType == (xmbool)XTRUE) {
status = xfReadElemTypesSingleValue(xGroupId, &nElemType);
fprintf(a_OutFile, "All elements are type %d\n", nElemType);
}
else {
ElemTypes = new int[nElems];
if (ElemTypes == NULL) {
printf("Memory Error");
return -1;
}
status = xfReadElemTypes(xGroupId, nElems, ElemTypes);
if (status < 0) {
return -1;
}
fprintf(a_OutFile, "Element Types:\n");
for (i = 0; i < nElems; i++) {
fprintf(a_OutFile, "Elem %d, Type %d\n", i+1, ElemTypes[i]);
}
delete ElemTypes;
ElemTypes = NULL;
}
// Nodes in each element
NodesInElem = new int[nElems*nNodesPerElem];
xfReadElemNodeIds(xGroupId, nElems, nNodesPerElem, NodesInElem);
for (i = 0; i < nElems; i++) {
fprintf(a_OutFile, "Elem: %4d - ", i+1);
for (j = 0; j < nNodesPerElem; j++) {
nNodeId = NodesInElem[i*nNodesPerElem + j];
if (nNodeId > 0) { // -1 is for unused array locations
fprintf(a_OutFile, "%d ", nNodeId);
}
}
fprintf(a_OutFile, "\n");
}
delete NodesInElem;
NodesInElem = NULL;
// NodeLocations
XNodeLocs = new double[nNodes];
YNodeLocs = new double[nNodes];
ZNodeLocs = new double[nNodes];
if (XNodeLocs == NULL || YNodeLocs == NULL || ZNodeLocs == NULL) {
if (XNodeLocs != NULL) {
delete XNodeLocs;
XNodeLocs = NULL;
}
if (YNodeLocs != NULL) {
delete YNodeLocs;
YNodeLocs = NULL;
}
if (ZNodeLocs != NULL) {
delete ZNodeLocs;
ZNodeLocs = NULL;
}
printf("Memory Error!");
return -1;
}
status = xfReadXNodeLocations(xGroupId, nNodes, XNodeLocs);
if (status >= 0) {
status = xfReadYNodeLocations(xGroupId, nNodes, YNodeLocs);
if (status >= 0) {
status = xfReadZNodeLocations(xGroupId, nNodes, ZNodeLocs);
}
else {
return -1;
}
}
else {
return -1;
}
fprintf(a_OutFile, "Node Locations:\n");
for (i = 0; i < nNodes; i++) {
fprintf(a_OutFile, "Node: %d Location: %lf %lf %lf\n", i + 1, XNodeLocs[i],
YNodeLocs[i], ZNodeLocs[i]);
}
// Open the property group
status = xfOpenGroup(xGroupId, "PROPERTIES", &xPropGrpId);
if (status < 0) {
fprintf(a_OutFile, "\n");
fprintf(a_OutFile, "Properties Group not found\n");
fprintf(a_OutFile, "\n");
return -1;
}
// Get the Property Types
status = xfGetPropertyType(xPropGrpId, "String", &StrType);
status = xfGetPropertyType(xPropGrpId, "UInt", &UIntType);
status = xfGetPropertyType(xPropGrpId, "Int", &IntType);
status = xfGetPropertyType(xPropGrpId, "Double", &DblType);
status = xfGetPropertyType(xPropGrpId, "Float", &FloatType);
// Property Types:
fprintf(a_OutFile, "\n");
if (StrType == XF_TYPE_STRING) {
fprintf(a_OutFile, "String Property Type Read Correctly\n");
}
else {
fprintf(a_OutFile, "Error in Getting String Property Type\n");
}
if (UIntType == XF_TYPE_UINT) {
fprintf(a_OutFile, "Unsigned Integer Property Type Read Correctly\n");
}
else {
fprintf(a_OutFile, "Error in Getting Unsigned Integer Property Type\n");
}
if (IntType == XF_TYPE_INT) {
fprintf(a_OutFile, "Integer Property Type Read Correctly\n");
}
else {
fprintf(a_OutFile, "Error in Getting Integer Property Type\n");
}
if (DblType == XF_TYPE_DOUBLE) {
fprintf(a_OutFile, "Double Property Type Read Correctly\n");
}
else {
fprintf(a_OutFile, "Error in Getting Double Property Type\n");
}
if (FloatType == XF_TYPE_FLOAT) {
fprintf(a_OutFile, "Float Property Type Read Correctly\n");
}
else {
fprintf(a_OutFile, "Error in Getting Float Property Type\n");
}
fprintf(a_OutFile, "\n");
if (XNodeLocs) {
delete XNodeLocs;
}
if (YNodeLocs) {
delete YNodeLocs;
}
if (ZNodeLocs) {
delete ZNodeLocs;
}
return TRUE;
} // tmReadMesh
//////////////////////////////////////////////////////////////////////////////
// FUNCTION tmWriteTestMeshA
// PURPOSE Write a file that contains data for an all tri mesh
// NOTES A picture of the mesh is in the file (TestMeshA.gif)
// returns TRUE on success and FALSE on failure
//////////////////////////////////////////////////////////////////////////////
int tmWriteTestMeshA(LPCSTR Filename, int Compression)
{
int nElements = 3, nNodes = 5;
xid xFileId = NONE, xMeshId = NONE;
xid xPropGrpId = NONE, xCoordId = NONE;
double dNodeLocsX[5], dNodeLocsY[5], dNodeLocsZ[5];
int iElementNodes[3][3]; // numelements, max elems per node
int status, propint, iEllipse;
char *propstring;
unsigned int propuint;
double propdouble, dMajorR, dMinorR;
float propfloat;
// Setup the arrays for the mesh data
// nodes
dNodeLocsX[0] = 0.0; dNodeLocsY[0] = 5.0; dNodeLocsZ[0] = 0.0;
dNodeLocsX[1] = 5.0; dNodeLocsY[1] = 5.0; dNodeLocsZ[1] = 0.0;
dNodeLocsX[2] = 0.0; dNodeLocsY[2] = 0.0; dNodeLocsZ[2] = 0.0;
dNodeLocsX[3] = 5.0; dNodeLocsY[3] = 0.0; dNodeLocsZ[3] = 0.0;
dNodeLocsX[4] = 7.5; dNodeLocsY[4] = 2.5; dNodeLocsZ[4] = 0.0;
// nodes for each element
// must be counter-clockwize
iElementNodes[0][0] = 1; iElementNodes[0][1] = 3; iElementNodes[0][2] = 2;
iElementNodes[1][0] = 2; iElementNodes[1][1] = 3; iElementNodes[1][2] = 4;
iElementNodes[2][0] = 5; iElementNodes[2][1] = 2; iElementNodes[2][2] = 4;
// create the file
status = xfCreateFile(Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store the mesh
status = xfCreateGroupForMesh(xFileId, MESH_A_GROUP_NAME, &xMeshId);
if (status < 0) {
return FALSE;
}
// Element types - all are linear triangles
status = xfSetAllElemsSameType(xMeshId, EL_TYPE_TRI_LINEAR);
if (status < 0) {
return FALSE;
}
// node information
status = xfSetNumberOfNodes(xMeshId, nNodes);
if (status < 0) {
return FALSE;
}
status = xfWriteXNodeLocations(xMeshId, nNodes, dNodeLocsX, Compression);
if (status < 0) {
return FALSE;
}
status = xfWriteYNodeLocations(xMeshId, nNodes, dNodeLocsY);
if (status < 0) {
return FALSE;
}
status = xfWriteZNodeLocations(xMeshId, nNodes, dNodeLocsZ);
if (status < 0) {
return FALSE;
}
// element information
status = xfSetNumberOfElements(xMeshId, nElements);
if (status < 0) {
return FALSE;
}
// Write the node array ids for the nodes in each element
status = xfWriteElemNodeIds(xMeshId, nElements, 3, &iElementNodes[0][0],
Compression);
if (status < 0) {
return FALSE;
}
// Write the property file
status = xfCreateMeshPropertyGroup(xMeshId, &xPropGrpId);
if (status < 0) {
xfCloseGroup(xFileId);
return FALSE;
}
propstring = "Property String";
propuint = 5;
propint = -5;
propdouble = 5.6789012345;
propfloat = (float)5.6789;
status = xfWritePropertyString(xPropGrpId, "String", 1,
strlen(propstring), propstring);
status = xfWritePropertyUnsignedInt(xPropGrpId, "UInt", 1, &propuint, NONE);
status = xfWritePropertyInt(xPropGrpId, "Int", 1, &propint, NONE);
status = xfWritePropertyDouble(xPropGrpId, "Double", 1, &propdouble, NONE);
status = xfWritePropertyFloat(xPropGrpId, "Float", 1, &propfloat, NONE);
// Write Coordinate file - for MeshA, we will set the coordinate system to be
// Geogrpahic, with Latitude, Longitude, and user-defined ellipsoid settings
// written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xPropGrpId);
xfCloseGroup(xMeshId);
xfCloseFile(xFileId);
return -1;
}
// set coordinate values
iEllipse = 32; // User defined
dMajorR = 45.0; // Made up
dMinorR = 32.0; // Made up
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC);
xfSetHorizUnits(xCoordId, COORD_UNITS_US_FEET);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_US_FEET);
// write additional information
xfSetEllipse(xCoordId, iEllipse);
xfSetLat(xCoordId, LATITUDE_NORTH);
xfSetLon(xCoordId, LONGITUDE_EAST);
xfSetMajorR(xCoordId, dMajorR);
xfSetMinorR(xCoordId, dMinorR);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the resources
xfCloseGroup(xPropGrpId);
xfCloseGroup(xMeshId);
xfCloseFile(xFileId);
return TRUE;
} // tmWriteTestMeshA
//////////////////////////////////////////////////////////////////////////////
// FUNCTION tmWriteTestMeshB
// PURPOSE Write a file that contains data for an mixed quad/tri linear mesh
// NOTES A picture of the mesh is in the file (TestMeshB.gif)
// returns TRUE on success and FALSE on failure
//////////////////////////////////////////////////////////////////////////////
int tmWriteTestMeshB(LPCSTR Filename, int Compression)
{
int nElements = 2, nNodes = 5, nMaxNodePerElem = 4;
xid xFileId = NONE, xMeshId = NONE;
xid xPropGrpId = NONE, xCoordId = NONE;
double dNodeLocsX[5], dNodeLocsY[5], dNodeLocsZ[5];
int iElementNodes[2][4]; // numelements, max nodes per elem
int iElementTypes[2];
int status, propint, iEllipse;
char *propstring;
unsigned int propuint;
double propdouble;
float propfloat;
// Setup the arrays for the mesh data
// nodes
dNodeLocsX[0] = 0.0; dNodeLocsY[0] = 5.0; dNodeLocsZ[0] = 0.0;
dNodeLocsX[1] = 5.0; dNodeLocsY[1] = 5.0; dNodeLocsZ[1] = 0.0;
dNodeLocsX[2] = 0.0; dNodeLocsY[2] = 0.0; dNodeLocsZ[2] = 0.0;
dNodeLocsX[3] = 5.0; dNodeLocsY[3] = 0.0; dNodeLocsZ[3] = 0.0;
dNodeLocsX[4] = 7.5; dNodeLocsY[4] = 2.5; dNodeLocsZ[4] = 0.0;
// nodes for each element
// must be counter-clockwize
iElementNodes[0][0] = 1; iElementNodes[0][1] = 3; iElementNodes[0][2] = 4;
iElementNodes[0][3] = 2;
iElementNodes[1][0] = 2; iElementNodes[1][1] = 4; iElementNodes[1][2] = 5;
iElementNodes[1][3] = NONE;
iElementTypes[0] = EL_TYPE_QUADRILATERAL_LINEAR;
iElementTypes[1] = EL_TYPE_TRI_LINEAR;
// create the file
status = xfCreateFile(Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store the mesh
status = xfCreateGroupForMesh(xFileId, MESH_B_GROUP_NAME, &xMeshId);
if (status < 0) {
return FALSE;
}
// node information
status = xfSetNumberOfNodes(xMeshId, nNodes);
if (status < 0) {
return FALSE;
}
status = xfWriteXNodeLocations(xMeshId, nNodes, dNodeLocsX, Compression);
if (status < 0) {
return FALSE;
}
status = xfWriteYNodeLocations(xMeshId, nNodes, dNodeLocsY);
if (status < 0) {
return FALSE;
}
status = xfWriteZNodeLocations(xMeshId, nNodes, dNodeLocsZ);
if (status < 0) {
return FALSE;
}
// element information
status = xfSetNumberOfElements(xMeshId, nElements);
if (status < 0) {
return FALSE;
}
// Element types
status = xfWriteElemTypes(xMeshId, nElements, iElementTypes, Compression);
if (status < 0) {
return FALSE;
}
// Write the node array ids for the nodes in each element
status = xfWriteElemNodeIds(xMeshId, nElements, nMaxNodePerElem,
&iElementNodes[0][0], Compression);
if (status < 0) {
return FALSE;
}
// Write the property file
status = xfCreateMeshPropertyGroup(xMeshId, &xPropGrpId);
if (status < 0) {
xfCloseGroup(xFileId);
return FALSE;
}
propstring = "String Property";
propuint = 2;
propint = -2;
propdouble = 2.3456789012;
propfloat = (float)2.3456;
status = xfWritePropertyString(xPropGrpId, "String", 1,
strlen(propstring), propstring);
status = xfWritePropertyUnsignedInt(xPropGrpId, "UInt", 1, &propuint, NONE);
status = xfWritePropertyInt(xPropGrpId, "Int", 1, &propint, NONE);
status = xfWritePropertyDouble(xPropGrpId, "Double", 1, &propdouble, NONE);
status = xfWritePropertyFloat(xPropGrpId, "Float", 1, &propfloat, NONE);
// Write Coordinate file - for MeshB, we will set the coordinate system to be
// Geogrpahic, with Latitude, Longitude, and standard ellipsoid settings
// written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xPropGrpId);
xfCloseGroup(xMeshId);
xfCloseFile(xFileId);
return -1;
}
// set coordinate values
iEllipse = 21; // International 1924
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_NGVD_88);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetEllipse(xCoordId, iEllipse);
xfSetLat(xCoordId, LATITUDE_SOUTH);
xfSetLon(xCoordId, LONGITUDE_WEST);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the resources
xfCloseGroup(xPropGrpId);
xfCloseGroup(xMeshId);
xfCloseFile(xFileId);
return TRUE;
} // tmWriteTestMeshB

TestMesh.cpp tests meshes

// This file has functions that can be used to test reading and writing of
// timesteps using HDF5. This code is intended to be used as tests for the
// XMDF library as well as sample code for distribution.
// Untested XMDF functions used for timesteps:
// xfGetDatasetMinsDouble
// xfGetDatasetMaxsDouble
// xfReadScalarValuesTimestepInt
// xfReadVectorValuesAtIndexDouble
// All XMDF functions used for timesteps:
// xfGetDatasetTimes
// xfGetDatasetMins
// xfGetDatasetMaxs
// xfGetDatasetMinsFloat
// xfGetDatasetMaxsFloat
// xfGetDatasetMinsDouble
// xfGetDatasetMaxsDouble
// xfReadActivityTimestep
// xfReadActivityValuesAtIndex
// xfReadScalarValuesTimestep
// xfReadScalarValuesTimestepFloat
// xfReadScalarValuesTimestepFloatPortion
// xfReadScalarValuesTimestepDouble
// xfReadScalarValuesTimestepDoublePortion
// xfReadScalarValuesTimestepInt
// xfReadScalarValuesAtIndex
// xfReadScalarValuesAtIndexFloat
// xfReadScalarValuesAtIndexDouble
// xfReadScalarValuesAtIndices
// xfReadScalarValuesAtIndicesFloat
// xfReadVectorValuesTimestep
// xfReadVectorValuesTimestepFloat
// xfReadVectorValuesTimestepFloatPortion
// xfReadVectorValuesTimestepDouble
// xfReadVectorValuesTimestepDoublePortion
#include "stdafx.h"
#include <xmdf/Xmdf.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#define DATASETS_LOCATION "Datasets"
#define SCALAR_A_LOCATION "Scalars/ScalarA"
#define SCALAR_B_LOCATION "Scalars/ScalarB"
#define VECTOR2D_A_LOCATION "Vectors/Vector2D_A"
#define VECTOR2D_B_LOCATION "Vectors/Vector2D_B"
void ttiDatasetArray (double a_dMin, double a_dMax, int a_nCycle,
int a_SeedMultiplier, int a_nValues, float *a_Array);
double ttiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed);
int ttiReadScalar (xid a_xScalarId, FILE *a_fp);
int ttiReadVector (xid a_xVectorId, FILE *a_fp);
int ttiTestNumTimes( xid a_DatasetId, int a_Itimestep );
// --------------------------------------------------------------------------
// FUNCTION ttReadDatasets
// PURPOSE Read a dataset group from an XMDF file and output information to
// to a text file
// NOTES
// --------------------------------------------------------------------------
int ttReadDatasets (xid a_xGroupId, FILE *a_fp)
{
int nPaths=0, nMaxPathLength=0, nMultiDatasets=0;
char *Paths = NULL, *IndividualPath = NULL;
int nStatus, i, j;
xid xScalarId = NONE, xVectorId = NONE, xMultiId = NONE;
// Look for scalar datasets
nStatus = xfGetScalarDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
if (nStatus >= 0) {
Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
xfGetScalarDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
}
if (nStatus < 0) {
return -1;
}
// Output number and paths to scalar datasets
fprintf(a_fp, "Number of Scalars %d\n", nPaths);
for (i = 0; i < nPaths; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(a_fp, "Reading scalar: %s\n", IndividualPath);
nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xScalarId);
if (nStatus < 0) {
return -1;
}
nStatus = ttiReadScalar(xScalarId, a_fp);
xfCloseGroup(xScalarId);
if (nStatus < 0) {
printf("%d: ERROR reading scalar dataset.\n", __LINE__);
return -1;
}
}
if (Paths) {
free(Paths);
Paths = NULL;
}
// Look for vector datasets
nStatus = xfGetVectorDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
if (nStatus >= 0 && nPaths > 0) {
Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
xfGetVectorDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
}
if (nStatus < 0) {
return -1;
}
// Output number and paths to scalar datasets
fprintf(a_fp, "Number of Vectors %d\n", nPaths);
for (i = 0; i < nPaths; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(a_fp, "Reading Vector: %s\n", IndividualPath);
nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xVectorId);
if (nStatus < 0) {
return -1;
}
nStatus = ttiReadVector(xVectorId, a_fp);
xfCloseGroup(xVectorId);
if (nStatus < 0) {
printf("%d: ERROR reading vector dataset.\n", __LINE__);
return -1;
}
}
// find multidataset folders
nStatus = xfGetGroupPathsSizeForMultiDatasets(a_xGroupId, &nMultiDatasets,
&nMaxPathLength);
if (nStatus >= 0 && nMultiDatasets > 0) {
Paths = (char *)malloc(nMultiDatasets*nMaxPathLength*sizeof(char));
nStatus = xfGetAllGroupPathsForMultiDatasets(a_xGroupId, nMultiDatasets,
nMaxPathLength, Paths);
if (nStatus < 0) {
return -1;
}
// Output number and paths to multidatasets
fprintf(a_fp, "Number of Multidatasets: %d\n", nMultiDatasets);
for (i=0; i<nMultiDatasets; i++) {
IndividualPath = "";
for (j=0; j<nMaxPathLength-1; j++) {
IndividualPath = &Paths[i*nMaxPathLength];
}
fprintf(a_fp, "Reading multidataset: %s\n", IndividualPath);
nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xMultiId);
if (nStatus < 0) {
return -1;
}
nStatus = ttReadDatasets(xMultiId, a_fp);
nStatus = xfCloseGroup(xMultiId);
if (nStatus < 0) {
printf("%d: ERROR reading multidatasets.\n", __LINE__);
return -1;
}
}
}
if (Paths) {
free(Paths);
Paths = NULL;
}
return 1;
} // ttReadDatasets
// --------------------------------------------------------------------------
// FUNCTION ttReadActivityScalarAIndex
// PURPOSE Read all timestep values for a particular index
// NOTES
// --------------------------------------------------------------------------
int ttReadActivityScalarAIndex (LPCSTR a_Filename, int a_Index)
{
int status;
xid xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
int nTimesteps;
xmbool *bActive;
// open the file
status = xfOpenFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// open the dataset group
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status >= 0) {
status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
}
if (status < 0) {
return status;
}
// Find out the number of timesteps in the file
status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
if (status < 0) {
return status;
}
if (nTimesteps < 1) {
return -1;
}
// Read the values for the index
bActive = new xmbool[nTimesteps];
status = xfReadActivityValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
bActive);
// output the data
printf("\nReading activity for scalar A slice at index: %d\n", a_Index);
for (int i = 0; i < nTimesteps; i++) {
printf("%d ", bActive[i]);
}
printf("\n");
delete [] bActive;
return status;
} // ttReadActivityScalarAtIndex
// --------------------------------------------------------------------------
// FUNCTION ttReadScalarAIndex
// PURPOSE Read all timestep values for a particular index
// NOTES
// --------------------------------------------------------------------------
int ttReadScalarAIndex (LPCSTR a_Filename, int a_Index)
{
int status;
xid xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
int nTimesteps;
float *fValues;
// open the file
status = xfOpenFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// open the dataset group
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status >= 0) {
status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
}
if (status < 0) {
return status;
}
// Find out the number of timesteps in the file
status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
if (status < 0) {
return status;
}
if (nTimesteps < 1) {
return -1;
}
// Read the values for the index
fValues = new float[nTimesteps];
status = xfReadScalarValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
fValues);
// output the data
printf("\nReading scalar A slice at index: %d\n", a_Index);
for (int i = 0; i < nTimesteps; i++) {
printf("%f ", fValues[i]);
}
printf("\n");
delete [] fValues;
return status;
} // ttReadScalarAtIndex
// --------------------------------------------------------------------------
// FUNCTION ttWriteScalarA
// PURPOSE Write scalar Dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// This dataset is dynamic concentrations (mg/L) with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// reads/writes a reference time in julian days
// --------------------------------------------------------------------------
int ttWriteScalarA (LPCSTR a_Filename, int a_Compression)
{
xid xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
int nValues = 10, nTimes = 3, nActive = 8;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[10]; // nValues
xmbool bActivity[10]; // activity
int status, iHpgnZone;
double dJulianReftime;
int nErrors = 0, i = 0;
char **Errors = NULL;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
bActivity[iActive] = XTRUE;
}
bActivity[5] = XFALSE;
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group where we will put all the datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// uncomment next line to test error handling function
// xfCloseGroup(xDsetsId);
// Create the scalar A dataset group
status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
"mg/L", TS_HOURS, a_Compression,
&xScalarAId);
if (status < 0) {
// print the error stack
xfGetNumErrorMessages(&nErrors);
if (nErrors > 0) {
Errors = new char*[nErrors];
for (i = 0; i < nErrors; i++) {
Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
}
status = xfGetErrorMessages(nErrors, Errors);
if (status > 0) {
for (i = 0; i < nErrors; i++) {
printf("%s\n", Errors[i]);
}
}
for (i = 0; i < nErrors; i++) {
delete Errors[i];
}
delete Errors;
}
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
// Add in a reftime. This is a julian day for:
// noon July 1, 2003
dJulianReftime = 2452822.0;
status = xfDatasetReftime(xScalarAId, dJulianReftime);
if (status < 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
fValues[0] = (float)dTime;
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*2.5);
}
// write the dataset array values
status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
if (status < 0) {
printf( "%d: ERROR writing activity timestep: %d\n",
__LINE__, status );
}
}
if (status < 0) {
printf( "%d: ERROR writing scalar timestep.\n", __LINE__ );
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
status = ttiTestNumTimes( xScalarAId, iTimestep );
}
// Write Coordinate file - for ScalarA, we will set the coordinate system
// to be Geographic HPGN, with HPGN settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// set HPGN Zone for test
iHpgnZone = 29; // Utah
// Write Coordinate Information to file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetHPGNArea(xCoordId, iHpgnZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xScalarAId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
} // ttWriteScalarA
// --------------------------------------------------------------------------
// FUNCTION ttWriteScalarB
// PURPOSE Write scalar Dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// This dataset is dynamic concentrations (mg/L) with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// reads/writes a reference time in julian days
// --------------------------------------------------------------------------
int ttWriteScalarB (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
{
xid xFileId, xDsetsId, xScalarBId, xCoordId = NONE;
int nValues = 10, nTimes = 3, nActive = 8;
double dTime = 0.0, dJulianReftime;
int iTimestep, iActive;
float fValues[10]; // nValues
xmbool bActivity[10]; // activity
int status, nErrors = 0, i = 0;
char **Errors = NULL;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
bActivity[iActive] = XTRUE;
}
bActivity[5] = XFALSE;
if (a_Overwrite) {
// open the already-existing file
status = xfOpenFile(a_Filename, &xFileId, XFALSE);
if (status < 0) {
return -1;
}
// open the group where we have all the datasets
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return -1;
}
}
else {
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return -1;
}
// create the group where we will put all the datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return -1;
}
}
// uncomment next line to test error handling function
// xfCloseGroup(xDsetsId);
// Create/Overwrite the scalar B dataset group
status = xfCreateScalarDataset(xDsetsId, SCALAR_B_LOCATION,
"mg/L", TS_HOURS, a_Compression,
&xScalarBId);
if (status < 0) {
// print the error stack
xfGetNumErrorMessages(&nErrors);
if (nErrors > 0) {
Errors = new char*[nErrors];
for (i = 0; i < nErrors; i++) {
Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
}
status = xfGetErrorMessages(nErrors, Errors);
if (status > 0) {
for (i = 0; i < nErrors; i++) {
printf("%s\n", Errors[i]);
}
}
for (i = 0; i < nErrors; i++) {
delete Errors[i];
}
delete Errors;
}
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// Add in a reftime. This is a julian day for:
// noon July 1, 2003
dJulianReftime = 2452822.0;
status = xfDatasetReftime(xScalarBId, dJulianReftime);
if (status < 0) {
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
if (!a_Overwrite) {
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
fValues[0] = (float)dTime;
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*2.5);
}
// write the dataset array values
status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
}
else {
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 1.5 hour timestep
dTime = (iTimestep + 1) * 1.5;
fValues[0] = (float)dTime;
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*1.5);
}
// write the dataset array values
status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
}
if (!a_Overwrite) {
// Write Coordinate file
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// For ScalarB, we will set the coordinate system
// to be UTM, with UTM Zone settings written to the file.
// Write Coord Info to file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information - we'll use the max value for this test
xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
xfCloseGroup(xCoordId);
xCoordId = 0;
}
// close the dataset
xfCloseGroup(xScalarBId);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return 1;
} // ttWriteScalarB
// --------------------------------------------------------------------------
// FUNCTION ttWriteCoordsToMulti
// PURPOSE Write coordinate system to a multidataset file
// NOTES
// --------------------------------------------------------------------------
int ttWriteCoordsToMulti (xid a_xFileId)
{
xid xCoordId = NONE;
int status;
// Write Coordinate file - for Multidatasets, we will set the coordinate system
// to be UTM, with UTM Zone settings written to the file.
status = xfCreateCoordinateGroup(a_xFileId, &xCoordId);
if (status <= 0) {
return -1;
}
// Write Coord Info to file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information - we'll use the max value for this test
xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
xfCloseGroup(xCoordId);
xCoordId = 0;
return XTRUE;
} // ttWriteCoordsToMulti
// --------------------------------------------------------------------------
// FUNCTION ttWriteScalarAToMulti
// PURPOSE Write scalar Dataset to a multidataset
// NOTES This tests dynamic data sets, and activity
// This dataset is dynamic concentrations (mg/L) with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// reads/writes a reference time in julian days
// --------------------------------------------------------------------------
int ttWriteScalarAToMulti (xid a_GroupId)
{
xid xScalarAId;
int nValues = 10, nTimes = 3, nActive = 8;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[10]; // nValues
xmbool bActivity[10]; // activity
int status;
double dJulianReftime;
int i = 0;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
bActivity[iActive] = XTRUE;
}
bActivity[5] = XFALSE;
// Create the scalar A dataset group
status = xfCreateScalarDataset(a_GroupId, SCALAR_A_LOCATION,
"mg/L", TS_HOURS, NONE,
&xScalarAId);
// Add in a reftime. This is a julian day for:
// noon July 1, 2003
dJulianReftime = 2452822.0;
status = xfDatasetReftime(xScalarAId, dJulianReftime);
if (status < 0) {
xfCloseGroup(xScalarAId);
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
fValues[0] = (float)dTime;
for (i = 1; i < nValues; i++) {
fValues[i] = float(fValues[i-1]*2.5);
}
// write the dataset array values
status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xScalarAId);
}
status = ttiTestNumTimes( xScalarAId, iTimestep );
}
// close the dataset
xfCloseGroup(xScalarAId);
return FALSE;
} // ttWriteScalarAToMulti
// --------------------------------------------------------------------------
// FUNCTION ttReadVector2DAIndex
// PURPOSE Read all timestep values for a particular index
// NOTES
// --------------------------------------------------------------------------
int ttReadVector2DAIndex (LPCSTR a_Filename, int a_Index)
{
int status;
xid xFileId = NONE, xDsetsId = NONE, xVector2DA = NONE;
int nTimesteps;
float *fValues;
// open the file
status = xfOpenFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// open the dataset group
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status >= 0) {
status = xfOpenGroup(xDsetsId, VECTOR2D_A_LOCATION, &xVector2DA);
}
if (status < 0) {
return status;
}
// Find out the number of timesteps in the file
status = xfGetDatasetNumTimes(xVector2DA, &nTimesteps);
if (status < 0) {
return status;
}
if (nTimesteps < 1) {
return -1;
}
// Read the values for the index
fValues = new float[nTimesteps*2];
status = xfReadVectorValuesAtIndex(xVector2DA, a_Index, 1, nTimesteps, 2,
fValues);
// output the data
printf("\nReading vector 2D A slice at index: %d\n", a_Index);
for (int i = 0; i < nTimesteps; i++) {
printf("%f %f \n", fValues[i*2], fValues[i*2 + 1]);
}
printf("\n");
delete [] fValues;
return status;
} // ttReadVector2DAIndex
// --------------------------------------------------------------------------
// FUNCTION ttWriteVector2D_A
// PURPOSE Write 2D vector dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// Add reftime when it is completed
// This dataset is dynamic water velocities with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// --------------------------------------------------------------------------
int ttWriteVector2D_A (LPCSTR a_Filename, int a_Compression)
{
xid xFileId, xDsetsId, xVectorA, xCoordId = NONE;
int nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[100*2]; // nValues*nComponents
xmbool bActivity[75]; // activity
// double dMin = 0.5, dMax = 3.5;
// int nSeedMultiplier = 138592;
int i, j, status;
int iHpgnZone;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
if (iActive % 3 == 0) {
bActivity[iActive] = XFALSE;
}
else {
bActivity[iActive] = XTRUE;
}
}
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store all datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
// Create the scalar A dataset group
status = xfCreateVectorDataset(xDsetsId, VECTOR2D_A_LOCATION, "ft/s",
TS_SECONDS, a_Compression, &xVectorA);
if (status < 0) {
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
// // generate values array using random numbers between dMin and dMax
// ttiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
// nValues*nComponents, fValues);
// write the dataset array values
status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorA, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
status = ttiTestNumTimes( xVectorA, iTimestep );
}
// Write Coordinate file - for Vector2D_A, we will set the coordinate system
// to be Geographic HPGN, with HPGN settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// set HPGN info for test
iHpgnZone = 29; // Utah
xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information
xfSetHPGNArea(xCoordId, iHpgnZone);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xVectorA);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
} // ttWriteVector2D_A
// --------------------------------------------------------------------------
// FUNCTION ttWriteVector2D_B
// PURPOSE Write 2D vector dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// Add reftime when it is completed
// This dataset is dynamic water velocities with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// --------------------------------------------------------------------------
int ttWriteVector2D_B (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
{
xid xFileId, xDsetsId, xVectorB, xCoordId = NONE;
int nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[100*2]; // nValues*nComponents
xmbool bActivity[75]; // activity
// double dMin = 0.5, dMax = 3.5;
// int nSeedMultiplier = 138592;
int i, j, status;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
if (iActive % 3 == 0) {
bActivity[iActive] = XFALSE;
}
else {
bActivity[iActive] = XTRUE;
}
}
if (a_Overwrite) {
//open the already-existing file
status = xfOpenFile(a_Filename, &xFileId, XFALSE);
if (status < 0) {
return -1;
}
// open the group where we have all the datasets
status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return -1;
}
}
else {
// create the file
status = xfCreateFile(a_Filename, &xFileId, XTRUE);
if (status < 0) {
return FALSE;
}
// create the group to store all datasets
status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
if (status < 0) {
xfCloseFile(xFileId);
return FALSE;
}
}
// Create the Vector B dataset group
status = xfCreateVectorDataset(xDsetsId, VECTOR2D_B_LOCATION, "ft/s",
TS_SECONDS, a_Compression, &xVectorB);
if (status < 0) {
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return FALSE;
}
if (!a_Overwrite) {
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
// write the dataset array values
status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorB, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorB);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
}
else {
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 1.5 hour timestep
dTime = (iTimestep + 1) * 1.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
// write the dataset array values
status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorB, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorB);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
}
}
}
// Write Coordinate file - for ScalarB, we will set the coordinate system
// to be UTM, with UTM Zone settings written to the file.
status = xfCreateCoordinateGroup(xFileId, &xCoordId);
if (status <= 0) {
xfCloseGroup(xVectorB);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return -1;
}
// write the coordinate data to the file
xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
// write additional information - we'll use the max UTM zone for the test
xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
xfCloseGroup(xCoordId);
xCoordId = 0;
// close the dataset
xfCloseGroup(xVectorB);
xfCloseGroup(xDsetsId);
xfCloseFile(xFileId);
return 1;
} // ttWriteVector2D_B
// --------------------------------------------------------------------------
// FUNCTION ttWriteVector2DAToMulti
// PURPOSE Write 2D vector dataset to an HDF5 File
// NOTES This tests dynamic data sets, and activity
// Add reftime when it is completed
// This dataset is dynamic water velocities with output times
// in minutes.
// Dataset is for a mesh and so nActive is the number of elements
// which is not the same as the nValues which would be number of nodes
// --------------------------------------------------------------------------
int ttWriteVector2DAToMulti (xid a_GroupId)
{
xid xVectorA;
int nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
double dTime = 0.0;
int iTimestep, iActive;
float fValues[100*2]; // nValues*nComponents
xmbool bActivity[75]; // activity
// double dMin = 0.5, dMax = 3.5;
// int nSeedMultiplier = 138592;
int i, j, status;
// 5th item in data set is always inactive, others active
for (iActive = 0; iActive < nActive; iActive++) {
if (iActive % 3 == 0) {
bActivity[iActive] = XFALSE;
}
else {
bActivity[iActive] = XTRUE;
}
}
// Create the scalar A dataset group
status = xfCreateVectorDataset(a_GroupId, VECTOR2D_A_LOCATION, "ft/s",
TS_SECONDS, NONE, &xVectorA);
if (status < 0) {
return FALSE;
}
// Loop through timesteps adding them to the file
for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
// We will have an 0.5 hour timestep
dTime = (iTimestep + 1) * 0.5;
for (i = 0; i < nValues; i++) {
for (j = 0; j < nComponents; j++) {
fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
}
}
// // generate values array using random numbers between dMin and dMax
// ttiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
// nValues*nComponents, fValues);
// write the dataset array values
status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
fValues);
if (status >= 0) {
// write activity array
xfWriteActivityTimestep(xVectorA, nActive, bActivity);
}
if (status < 0) {
xfCloseGroup(xVectorA);
}
status = ttiTestNumTimes( xVectorA, iTimestep );
}
// close the dataset
xfCloseGroup(xVectorA);
return FALSE;
} // ttWriteVector2DAToMulti
// --------------------------------------------------------------------------
// FUNCTION ttiRandomNumberInRange
// PURPOSE generate Psuedo Random numbers. We use the same seeds every
// time so we end up with consistent values for testing purposes.
// --------------------------------------------------------------------------
double ttiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed)
{
int nRandom;
double dValue;
srand(a_nSeed);
nRandom = rand();
dValue = a_dMin + ((double)(nRandom)*(a_dMax - a_dMin))/RAND_MAX;
return dValue;
} // ttiRandomNumberInRange
// --------------------------------------------------------------------------
// FUNCTION ttDatasetArray
// PURPOSE Get dataset data to use in a dataset
// NOTES Generates random numbers between a range to fill in the array
// --------------------------------------------------------------------------
void ttiDatasetArray (double a_dMin, double a_dMax, int a_nCycle,
int a_SeedMultiplier, int a_nValues, float *a_Array)
{
int i, nSeedBase;
for (i = 0; i < a_nValues; i++) {
nSeedBase = a_nCycle*a_nValues + i;
a_Array[i] = (float)ttiRandomNumberInRange(a_dMin, a_dMax,
nSeedBase*a_SeedMultiplier);
}
} // ttDatasetArray
// --------------------------------------------------------------------------
// FUNCTION ttiReadScalar
// PURPOSE Read a scalar from an XMDF file and output information to
// to a text file
// NOTES
// --------------------------------------------------------------------------
int ttiReadScalar (xid a_xScalarId, FILE *a_fp)
{
int nTimes = NONE, nValues = NONE, nActive = NONE;
int nStatus = TRUE, iTime, iVal, iActive;
char TimeUnits[100], Units[100];
double *Times = NULL;
float *Values = NULL, *Mins = NULL, *Maxs = NULL;
xmbool *Active = NULL;
xmbool bUseReftime;
double Reftime;
// read the time units
nStatus = xfGetDatasetTimeUnits(a_xScalarId, TimeUnits);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "Time units: %s\n", TimeUnits);
// see if we are using a reftime
nStatus = xfUseDatasetReftime(a_xScalarId, &bUseReftime);
if (nStatus < 0) {
return nStatus;
}
if (bUseReftime) {
nStatus = xfReadDatasetReftime(a_xScalarId, &Reftime);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "Reftime: %f\n", Reftime);
}
// read the units
nStatus = xfGetDatasetUnits(a_xScalarId, Units);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "units: %s\n", Units);
// read in the number of values and number of active values
nStatus = xfGetDatasetNumVals(a_xScalarId, &nValues);
if (nStatus >= 0) {
nStatus = xfGetDatasetNumActive(a_xScalarId, &nActive);
}
if (nStatus < 0) {
return nStatus;
}
if (nValues <= 0) {
printf("No data to read in.");
return -1;
}
// read in the number of times
nStatus = xfGetDatasetNumTimes(a_xScalarId, &nTimes);
if (nStatus < 0) {
return nStatus;
}
// Read in the individual time values
Times = (double *)malloc(nTimes*sizeof(double));
if (Times == NULL) {
printf("Out of memory");
return -1;
}
nStatus = xfGetDatasetTimes(a_xScalarId, nTimes, Times);
if (nStatus < 0) {
return nStatus;
}
// Read in the minimum and maximum values
Mins = (float *)malloc(nTimes*sizeof(float));
Maxs = (float *)malloc(nTimes*sizeof(float));
if (Mins == NULL || Maxs == NULL) {
free(Times);
printf("Out of memory");
return -1;
}
nStatus = xfGetDatasetMins(a_xScalarId, nTimes, Mins);
if (nStatus >= 0) {
nStatus = xfGetDatasetMaxs(a_xScalarId, nTimes, Maxs);
}
if (nStatus < 0) {
free(Times);
free(Mins);
free(Maxs);
return nStatus;
}
Values = (float *)malloc(nValues*sizeof(float));
if (nActive > 0) {
Active = (xmbool *)malloc(nActive*sizeof(xmbool));
}
fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
fprintf(a_fp, "Number Values: %d\n", nValues);
fprintf(a_fp, "Number Active: %d\n", nActive);
// loop through the timesteps, read the values and active values and write
// them to the text file
for (iTime = 0; iTime < nTimes; iTime++) {
// indices should be 1 based
nStatus = xfReadScalarValuesTimestep(a_xScalarId, iTime + 1,
nValues, Values);
if (nStatus >= 0 && nActive > 0) {
// indices should be 1 based
nStatus = xfReadActivityTimestep(a_xScalarId, iTime + 1, nActive, Active);
}
// Write the time, min, max, values and active values to the text output
// file.
fprintf(a_fp, "\nTimestep at %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n",
Times[iTime], Mins[iTime], Maxs[iTime]);
fprintf(a_fp, "Values:\n");
// print 5 values per line
for (iVal = 0; iVal < nValues; iVal++) {
fprintf(a_fp, "%6.3f ", Values[iVal]);
if ((iVal + 1) % 5 == 0) {
fprintf(a_fp, "\n");
}
}
fprintf(a_fp, "\n");
fprintf(a_fp, "Activity:\n");
// print 5 values per line
for (iActive = 0; iActive < nActive; iActive++) {
fprintf(a_fp, "%4d ", (int)Active[iActive]);
if ((iActive + 1) % 5 == 0) {
fprintf(a_fp, "\n");
}
}
fprintf(a_fp, "\n\n");
}
if (Times) {
free(Times);
Times = NULL;
}
if (Mins) {
free(Mins);
Mins = NULL;
}
if (Maxs) {
free(Maxs);
Maxs = NULL;
}
if (Values) {
free(Values);
Values = NULL;
}
if (Active) {
free(Active);
Active = NULL;
}
return TRUE;
} // ttiReadScalar
// --------------------------------------------------------------------------
// FUNCTION ttiReadVector
// PURPOSE Read a vector from an XMDF file and output information to
// to a text file
// NOTES
// --------------------------------------------------------------------------
int ttiReadVector (xid a_xVectorId, FILE *a_fp)
{
int nTimes = NONE, nValues = NONE, nComponents = NONE, nActive = NONE;
int nStatus = TRUE, iTime, iVal, iActive;
char TimeUnits[100];
double *Times = NULL;
float *Values = NULL, *Mins = NULL, *Maxs = NULL;
xmbool *Active = NULL;
xmbool bUseReftime;
double Reftime;
// read the time units
nStatus = xfGetDatasetTimeUnits(a_xVectorId, TimeUnits);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "Time units: %s\n", TimeUnits);
// see if we are using a reftime
nStatus = xfUseDatasetReftime(a_xVectorId, &bUseReftime);
if (nStatus < 0) {
return nStatus;
}
if (bUseReftime) {
nStatus = xfReadDatasetReftime(a_xVectorId, &Reftime);
if (nStatus < 0) {
return nStatus;
}
fprintf(a_fp, "Reftime: %f", Reftime);
}
// read in the number of values and number of active values
nStatus = xfGetDatasetNumVals(a_xVectorId, &nValues);
if (nStatus >= 0) {
nStatus = xfGetDatasetVecNumComponents(a_xVectorId, &nComponents);
if (nStatus >= 0) {
nStatus = xfGetDatasetNumActive(a_xVectorId, &nActive);
}
}
if (nStatus < 0) {
return nStatus;
}
if (nValues <= 0) {
printf("No data to read in.");
return -1;
}
// read in the number of times
nStatus = xfGetDatasetNumTimes(a_xVectorId, &nTimes);
if (nStatus < 0) {
return nStatus;
}
// Read in the individual time values
Times = (double *)malloc(nTimes*sizeof(double));
if (Times == NULL) {
printf("Out of memory");
return -1;
}
nStatus = xfGetDatasetTimes(a_xVectorId, nTimes, Times);
if (nStatus < 0) {
return nStatus;
}
// Read in the minimum and maximum values
Mins = (float *)malloc(nTimes*sizeof(float));
Maxs = (float *)malloc(nTimes*sizeof(float));
if (Mins == NULL || Maxs == NULL) {
free(Times);
printf("Out of memory");
return -1;
}
nStatus = xfGetDatasetMins(a_xVectorId, nTimes, Mins);
if (nStatus >= 0) {
nStatus = xfGetDatasetMaxs(a_xVectorId, nTimes, Maxs);
}
if (nStatus < 0) {
free(Times);
free(Mins);
free(Maxs);
return nStatus;
}
Values = (float *)malloc(nValues*nComponents*sizeof(float));
if (nActive > 0) {
Active = (xmbool *)malloc(nActive*sizeof(xmbool));
}
fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
fprintf(a_fp, "Number Values: %d\n", nValues);
fprintf(a_fp, "Number Components: %d\n", nComponents);
fprintf(a_fp, "Number Active: %d\n", nActive);
// loop through the timesteps, read the values and active values and write
// them to the text file
for (iTime = 0; iTime < nTimes; iTime++) {
nStatus = xfReadVectorValuesTimestep(a_xVectorId, iTime + 1,
nValues, nComponents, Values);
if (nStatus >= 0 && nActive > 0) {
nStatus = xfReadActivityTimestep(a_xVectorId, iTime + 1, nActive, Active);
}
// Write the time, min, max, values and active values to the text output
// file.
fprintf(a_fp, "\nTimestep at %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n",
Times[iTime], Mins[iTime], Maxs[iTime]);
fprintf(a_fp, "Values:\n");
// print a set of vector values per line
for (iVal = 0; iVal < nValues; iVal++) {
fprintf(a_fp, "%6.3f %6.3f\n", Values[iVal*nComponents],
Values[(iVal*nComponents) + 1]);
}
fprintf(a_fp, "\n");
fprintf(a_fp, "Activity:\n");
// print 5 values per line
for (iActive = 0; iActive < nActive; iActive++) {
fprintf(a_fp, "%4d ", (int)Active[iActive]);
if ((iActive + 1) % 5 == 0) {
fprintf(a_fp, "\n");
}
}
fprintf(a_fp, "\n\n");
}
if (Times) {
free(Times);
Times = NULL;
}
if (Mins) {
free(Mins);
Mins = NULL;
}
if (Maxs) {
free(Maxs);
Maxs = NULL;
}
if (Values) {
free(Values);
Values = NULL;
}
if (Active) {
free(Active);
Active = NULL;
}
return TRUE;
} // ttiReadVector
// --------------------------------------------------------------------------
// FUNCTION ttiTestNumTimes
// PURPOSE Change the NumTimes to truncate timesteps
// NOTES
// --------------------------------------------------------------------------
int ttiTestNumTimes( xid a_DatasetId, int a_Itimestep )
{
int status = 1;
// truncate just written timestep and test error conditions
if (1 == a_Itimestep ||
3 == a_Itimestep ||
5 == a_Itimestep)
{
int NumTimes;
// Test setting NumTimes after end of dataset
status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep + 2 );
if (status >= 0)
printf( "%d: ERROR: xfSetDatasetNumTimes must return ERROR.\n",
__LINE__ );
if (1 == a_Itimestep) a_Itimestep = 1;
if (3 == a_Itimestep) a_Itimestep = 2;
if (5 == a_Itimestep) a_Itimestep = 3;
// Write actual NumTimes
status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep );
if (status < 0)
printf( "%d: ERROR: xfSetDatasetNumTimes must NOT return error.\n",
__LINE__ );
// Test setting NumTimes after end step.
status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep + 1 );
if (status >= 0)
printf( "%d: ERROR: xfSetDatasetNumTimes must return ERROR.\n",
__LINE__ );
// Test reading NumTimes
status = xfGetDatasetNumTimes( a_DatasetId, &NumTimes );
if (status < 0)
printf( "%d: ERROR: xfGetDatasetNumTimes must NOT return error.\n",
__LINE__ );
if (NumTimes != a_Itimestep)
printf( "%d: ERROR: xfGetDatasetNumTimes must return CORRECT NumTimes.\n",
__LINE__ );
}
return status;
}

TestTimestep.cpp tests timesteps

// TestXFormat.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <hdf5.h>
#include <xmdf/Xmdf.h>
#include "xmdf/xmdf_private.h"
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include "TestTimestep.h"
#include "TestDatasets.h"
#include "TestMesh.h"
#include "TestGrid.h"
#include "TestGeomPaths.h"
#include "TestXmdf.h"
#define NUMTIMES1 5
#define NUMVALUES1 5
#define NUMACTIVE1 3
#define NUMTIMESADD 1
int txiTestCalendar();
int txiTestCoordSystem(xid xGroupId, FILE *a_OutFile);
int txiTestDatasets();
int txiTestFortran();
int txiTestGeometricPaths();
int txiTestGrids();
int txiTestMeshs();
int txiTestOverwriteDsets();
int txiTestTimesteps();
int txiTestVersion();
int txiReadXFormatFile(LPCSTR a_XmdfFile, LPCSTR a_OutFile);
int txiReadXFormatFileT (LPCSTR a_XmdfFile, LPCSTR a_OutFile);
//-----------------------------------------------------------------------------
// FUNCTION main
// PURPOSE runs the test cases for XMDF
// NOTES
//-----------------------------------------------------------------------------
int main()
{
int status = 0;
::txiReadXFormatFile("C:\\SMS\\Testcases\\bugs\\adcp_observed\\sms_adcp_observed - pete_comb_vel_vector (2).h5",
"C:\\SMS\\Testcases\\bugs\\adcp_observed\\sms_adcp_observed out.txt");
#if 1
// test the timestep routines
status = txiTestTimesteps();
printf("=== Finished testing timesteps ===\n");
if (status < 0) return status;
// test the dataset routines
status = txiTestDatasets();
printf("=== Finished testing datasets ===\n");
if (status < 0) return status;
// test overwriting already-existing datasets
status = txiTestOverwriteDsets();
if (status < 0) return status;
// Test Mesh stuff
status = txiTestMeshs();
if (status < 0) return status;
// Test grid stuff
status = txiTestGrids();
if (status < 0) return status;
// Test writing particle paths
status = txiTestGeometricPaths();
if (status < 0) return status;
// Test reading files that were written by fortan.
status = txiTestFortran();
if (status < 0) return status;
// Test Calendar Conversion Stuff
status = txiTestCalendar();
if (status < 0) return status;
// Test reading the version written to the files
status = txiTestVersion();
if (status < 0) return status;
#endif
printf("Press ENTER to Exit...");
char pause[1024];
//scanf("%c", pause);
return 0;
}
//-----------------------------------------------------------------------------
// FUNCTION txiTestTimesteps
// PURPOSE
// NOTES
//-----------------------------------------------------------------------------
int txiTestTimesteps()
{
const char *SCALAR_A_FILE_C = "TT_ScalarA_c.h5";
const char *SCALAR_A_TEXT_C = "TT_ScalarA_c.txt";
const char *VECTOR2D_A_FILE_C = "TT_Vector2D_A_c.h5";
const char *VECTOR2D_A_TEXT_C = "TT_Vector2D_A_c.txt";
const char *MULTIDATASET_FILE_C = "TT_MultiDataSet_c.h5";
const char *MULTIDATASET_TEXT_C = "TT_MultiDataSet_c.txt";
int status = 1;
int compression = NONE;
xid MultiFileId=NONE, MultiGroupId=NONE;
int NumOpen=0;
char SdoGuid[37];
strcpy(SdoGuid, "73289C80-6235-4fdc-9649-49E4F5AEB676");
xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","",
SdoGuid, XF_OVERWRITE_CLEAR_FILE, &MultiFileId, &MultiGroupId);
// Write coordinates to multidatasets
ttWriteCoordsToMulti(MultiFileId);
// Write scalar A and Vector A to multidatasets.
ttWriteScalarAToMulti(MultiGroupId);
ttWriteVector2DAToMulti(MultiGroupId);
xfCloseGroup(MultiGroupId);
xfCloseFile(MultiFileId);
printf("Done writing multiple datasets...\n");
// scalar datasets
status = ttWriteScalarA(SCALAR_A_FILE_C, compression);
if (status < 0) {
return status;
}
printf("Done writing scalar datasets...\n");
// vector datasets
status = ttWriteVector2D_A(VECTOR2D_A_FILE_C, compression);
if (status < 0) {
printf("Error writing dataset vector2D_A.");
return status;
}
printf("Done writing vector datasets...\n");
printf("Done writing datasets...\n");
// Read the files back in
status = txiReadXFormatFileT(SCALAR_A_FILE_C, SCALAR_A_TEXT_C);
if (status < 0) {
return status;
}
status = txiReadXFormatFileT(VECTOR2D_A_FILE_C, VECTOR2D_A_TEXT_C);
if (status < 0) {
return status;
}
status = txiReadXFormatFileT(MULTIDATASET_FILE_C, MULTIDATASET_TEXT_C);
if (status < 0) {
return status;
}
printf("Done reading datasets...\n");
xfGetNumOpenIdentifiers(H5F_OBJ_ALL, &NumOpen);
xfpCloseOpenIdentifiers(H5F_OBJ_ALL);
xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","",
SdoGuid, XF_OVERWRITE_CLEAR_DATASET_GROUP, &MultiFileId, &MultiGroupId);
ttWriteScalarAToMulti(MultiGroupId);
xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","",
SdoGuid, XF_OVERWRITE_NONE, &MultiFileId, &MultiGroupId);
ttWriteVector2DAToMulti(MultiGroupId);
// Test reading information at index for multiple timesteps
status = ttReadScalarAIndex(SCALAR_A_FILE_C, 2);
if (status < 0) {
return status;
}
printf("Done reading scalar data at index.\n");
status = ttReadVector2DAIndex(VECTOR2D_A_FILE_C, 4);
if (status < 0) {
return status;
}
printf("Done reading vector data at index.\n");
status = ttReadActivityScalarAIndex(SCALAR_A_FILE_C, 5);
if (status < 0) {
return status;
}
return status;
} // txiTestTimesteps
//-----------------------------------------------------------------------------
// #defines used in txiTestDatasets
//-----------------------------------------------------------------------------
#define XMDF_VERSION_OUT_C "XMDF_Version_c.txt"
#define SCALAR_A_FILE_C "ScalarA_c.h5"
#define SCALAR_A_TEXT_C "ScalarA_c.txt"
#define SCALAR_A_PIECES_FILE_C "ScalarA_Pieces_c.h5"
#define SCALAR_A_PIECES_TEXT_C "ScalarA_Pieces_c.txt"
#define SCALAR_A_EDITED_FILE_C "ScalarA_edited_c.h5"
#define SCALAR_A_EDITED_TEXT_C "ScalarA_edited_c.txt"
#define VECTOR2D_A_FILE_C "Vector2D_A_c.h5"
#define SCALAR_A_PIECES_ALT_FILE_C "ScalarA_Pieces_alt_c.h5"
#define SCALAR_A_PIECES_ALT_TEXT_C "ScalarA_Pieces_alt_c.txt"
#define SCALAR_A_EDITED_ALT_FILE_C "ScalarA_edited_alt_c.h5"
#define SCALAR_A_EDITED_ALT_TEXT_C "ScalarA_edited_alt_c.txt"
#define VECTOR2D_A_TEXT_C "Vector2D_A_c.txt"
#define VECTOR2D_A_FILE_PIECES_C "Vector2D_A_Pieces_c.h5"
#define SCALAR_A_FILE_F "ScalarA_f.h5"
#define SCALAR_A_TEXT_FC "ScalarA_fc.txt"
#define VECTOR2D_A_FILE_F "Vector2D_A_f.h5"
#define VECTOR2D_A_TEXT_FC "Vector2D_A_fc.txt"
#define MULTIDATASET_FILE_C "MultiDataSet_c.h5"
#define MULTIDATASET_TEXT_C "MultiDataSet_c.txt"
//-----------------------------------------------------------------------------
// FUNCTION txiTestDatasets
// PURPOSE
// NOTES
//-----------------------------------------------------------------------------
int txiTestDatasets()
{
int status = 1;
int compression = NONE;
xid MultiFileId=NONE, MultiGroupId=NONE;
int NumOpen=0;
char SdoGuid[37];
strcpy(SdoGuid, "73289C80-6235-4fdc-9649-49E4F5AEB676");
xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","",
SdoGuid, XF_OVERWRITE_CLEAR_FILE, &MultiFileId, &MultiGroupId);
// Write coordinates to multidatasets
tdWriteCoordsToMulti(MultiFileId);
// Write scalar A and Vector A to multidatasets.
tdWriteScalarAToMulti(MultiGroupId);
tdWriteVector2DAToMulti(MultiGroupId);
xfCloseGroup(MultiGroupId);
xfCloseFile(MultiFileId);
printf("Done writing multiple datasets...\n");
// scalar datasets
status = tdWriteScalarA(SCALAR_A_FILE_C, compression);
if (status < 0) {
return status;
}
status = tdWriteScalarAPieces(SCALAR_A_PIECES_FILE_C, compression);
if (status < 0) {
return status;
}
status = tdWriteScalarAPiecesAltMinMax(SCALAR_A_PIECES_ALT_FILE_C,
compression);
if (status < 0) {
return status;
}
printf("Done writing scalar datasets...\n");
// vector datasets
status = tdWriteVector2D_A(VECTOR2D_A_FILE_C, compression);
printf("Done writing dataset vector2D_A. Status %d\n", status);
if (status < 0) {
return status;
}
status = tdWriteVector2D_A_Pieces(VECTOR2D_A_FILE_PIECES_C, compression);
printf("Done writing dataset vector2D_A_Pieces. Status %d\n", status);
if (status < 0) {
return status;
}
printf("Done writing vector datasets...\n");
status = tdEditScalarAValues(SCALAR_A_EDITED_FILE_C, compression);
printf("Done writing edited scalar datasets. Status %d\n", status);
if (status < 0) {
return status;
}
printf("Done writing datasets...\n");
// Read the files back in
status = txiReadXFormatFile(SCALAR_A_FILE_C, SCALAR_A_TEXT_C);
if (status < 0) {
return status;
}
status = txiReadXFormatFile(VECTOR2D_A_FILE_C, VECTOR2D_A_TEXT_C);
if (status < 0) {
return status;
}
status = txiReadXFormatFile(MULTIDATASET_FILE_C, MULTIDATASET_TEXT_C);
if (status < 0) {
return status;
}
status = txiReadXFormatFile(SCALAR_A_EDITED_FILE_C, SCALAR_A_EDITED_TEXT_C);
if (status < 0) {
return status;
}
printf("Done reading datasets...\n");
xfGetNumOpenIdentifiers(H5F_OBJ_ALL, &NumOpen);
xfpCloseOpenIdentifiers(H5F_OBJ_ALL);
xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","",
SdoGuid, XF_OVERWRITE_CLEAR_DATASET_GROUP, &MultiFileId, &MultiGroupId);
tdWriteScalarAToMulti(MultiGroupId);
xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","",
SdoGuid, XF_OVERWRITE_NONE, &MultiFileId, &MultiGroupId);
tdWriteVector2DAToMulti(MultiGroupId);
// Test reading information at index for multiple timesteps
status = tdReadScalarAIndex(SCALAR_A_FILE_C, 2);
printf("Done reading scalar data at index. Status %d\n", status);
if (status < 0) {
return status;
}
status = tdReadVector2DAIndex(VECTOR2D_A_FILE_C, 4);
printf("Done reading vector data at index. Status %d\n", status);
if (status < 0) {
return status;
}
status = tdReadActivityScalarAIndex(SCALAR_A_FILE_C, 5);
printf("Done reading scalar activity at index. Status %d\n", status);
if (status < 0) {
return status;
}
// Test reading information at multiple indices
const int nIndices = 3;
int indices[nIndices];
indices[0] = 2;
indices[1] = 3;
indices[2] = 5;
status = tdReadScalarAIndices(SCALAR_A_FILE_C, nIndices, indices);
printf("Done reading scalar data at indices. Status %d\n", status);
if (status < 0) {
return status;
}
status = tdReadVectorAIndices(VECTOR2D_A_FILE_C, nIndices, indices);
printf("Done reading vector data at indices. Status %d\n", status);
return status;
} // txiTestDatasets
#define GEOMPATH_A_FILE_C "geompath_a_file_c.h5"
#define GEOMPATH_A_FILE_COUT "geompath_a_file_c_out.txt"
int txiTestGeometricPaths()
{
int status = 1;
int compression = NONE;
/* test writing a geometric path file */
printf("\n\nWriting geometric path data.\n\n");
status = tmWriteTestPaths(GEOMPATH_A_FILE_C, compression);
if (status <= 0) {
printf("Error writing geometric path data A\n");
}
printf("Finished writing geometric path data A\n");
/* test reading a geometric path file */
status = tmReadTestPaths(GEOMPATH_A_FILE_C, GEOMPATH_A_FILE_COUT);
return status;
}
//-----------------------------------------------------------------------------
// #defines used in txiTestOverwriteDsets
//-----------------------------------------------------------------------------
#define SCALAR_B_FILE_C "ScalarB_c.h5"
#define SCALAR_B_TEXT_C "ScalarB_c.txt"
#define VECTOR2D_B_FILE_C "Vector2D_B_c.h5"
#define VECTOR2D_B_TEXT_C "Vector2D_B_c.txt"
#define SCALAR_B_FILE_F "ScalarB_f.h5"
#define SCALAR_B_TEXT_FC "ScalarB_fc.txt"
#define VECTOR2D_B_FILE_F "Vector2D_B_f.h5"
#define VECTOR2D_B_TEXT_FC "Vector2D_B_fc.txt"
//-----------------------------------------------------------------------------
// FUNCTION txiTestOverwriteDsets
// PURPOSE Check to see if already-written datasets can be overwritten
// NOTES
//-----------------------------------------------------------------------------
int txiTestOverwriteDsets()
{
int status = 1;
int compression = NONE;
// scalar datasets
status = tdWriteScalarB(SCALAR_B_FILE_C, compression, 0);
if (status < 0) {
return status;
}
// overwrite scalar datasets
status = tdWriteScalarB(SCALAR_B_FILE_C, compression, 1);
if (status < 0) {
return status;
}
// vector datasets
status = tdWriteVector2D_B(VECTOR2D_B_FILE_C, compression, 0);
if (status < 0) {
printf("Error writing dataset vector2D_B.");
return status;
}
// overwrite vector datasets
status = tdWriteVector2D_B(VECTOR2D_B_FILE_C, compression, 1);
if (status < 0) {
printf("Error writing dataset vector2D_B.");
return status;
}
// Read the files back in
status = txiReadXFormatFile(SCALAR_B_FILE_C, SCALAR_B_TEXT_C);
if (status < 0) {
return status;
}
status = txiReadXFormatFile(VECTOR2D_B_FILE_C, VECTOR2D_B_TEXT_C);
if (status < 0) {
return status;
}
return status;
} // txiTestDatasets
//-----------------------------------------------------------------------------
// #defines used in txiTestGrids
//-----------------------------------------------------------------------------
#define GRID_CART2D_A_FILE_C "grid_cart2d_a_file_c.h5"
#define GRID_CURV2D_A_FILE_C "grid_curv2d_a_file_c.h5"
#define GRID_CART3D_A_FILE_C "grid_cart3d_a_file_c.h5"
#define GRID_CART2D_A_OUT_C "grid_cart2d_a_out_c.txt"
#define GRID_CURV2D_A_OUT_C "grid_curv2d_a_out_c.txt"
#define GRID_CART3D_A_OUT_C "grid_cart3d_a_out_c.txt"
#define GRID_CART2D_A_FILE_F "grid_cart2d_a_file_f.h5"
#define GRID_CURV2D_A_FILE_F "grid_curv2d_a_file_f.h5"
#define GRID_CART3D_A_FILE_F "grid_cart3d_a_file_f.h5"
#define GRID_CART2D_A_OUT_FC "grid_cart2d_a_out_fc.txt"
#define GRID_CURV2D_A_OUT_FC "grid_curv2d_a_out_fc.txt"
#define GRID_CART3D_A_OUT_FC "grid_cart3d_a_out_fc.txt"
//-----------------------------------------------------------------------------
// FUNCTION txiTestGrids
// PURPOSE
// NOTES
//-----------------------------------------------------------------------------
int txiTestGrids()
{
int status = 1;
int compression = NONE;
printf("\n\nWriting grid data.\n\n");
status = tgWriteTestGridCart2D(GRID_CART2D_A_FILE_C, compression);
if (status < 0) {
printf("Error writing grid Cartesian 2D A\n");
}
printf("Finished writing grid Cartesian 2D A\n");
status = tgWriteTestGridCurv2D(GRID_CURV2D_A_FILE_C, compression);
if (status < 0) {
printf("Error writing grid Curvilinear 2D A\n");
}
printf("Finished writing grid Curvilinear 2D A\n");
status = tgWriteTestGridCart3D(GRID_CART3D_A_FILE_C, compression);
if (status < 0) {
printf("Error writing grid Cartesian 3D A\n");
}
printf("Finished writing grid Cartesian 3D A\n");
// read the files back in
status = txiReadXFormatFile(GRID_CART2D_A_FILE_C, GRID_CART2D_A_OUT_C);
if (status < 0) {
printf("Error reading grid Cartesian 2D A\n");
}
printf("Finished reading grid Cartesian 2D A\n");
status = txiReadXFormatFile(GRID_CURV2D_A_FILE_C, GRID_CURV2D_A_OUT_C);
if (status < 0) {
printf("Error reading grid Curvilinear 2D A\n");
}
printf("Finished reading grid Curvilinear 2D A\n");
status = txiReadXFormatFile(GRID_CART3D_A_FILE_C, GRID_CART3D_A_OUT_C);
if (status < 0) {
printf("Error reading grid Cartesian 3D A\n");
}
printf("Finished reading grid Cartesian 3D A\n");
return status;
} // txiTestGrids
//-----------------------------------------------------------------------------
// #defines used in txiTestMeshs
//-----------------------------------------------------------------------------
#define MESH_A_FILE_C "mesh_a_file_c.h5"
#define MESH_B_FILE_C "mesh_b_file_c.h5"
#define MESH_A_OUT_C "mesh_a_file_c.txt"
#define MESH_B_OUT_C "mesh_b_file_c.txt"
#define MESH_A_FILE_F "mesh_a_file_f.h5"
#define MESH_B_FILE_F "mesh_b_file_f.h5"
#define MESH_A_OUT_FC "mesh_a_file_fc.txt"
#define MESH_B_OUT_FC "mesh_b_file_fc.txt"
// ---------------------------------------------------------------------------
// FUNCTION txiTestMeshs
// PURPOSE
// NOTES
// ---------------------------------------------------------------------------
int txiTestMeshs ()
{
int status = 1;
int compression = NONE;
status = tmWriteTestMeshA(MESH_A_FILE_C, compression);
if (status != TRUE) {
printf("Error writing TestMeshA\n");
return status;
}
status = tmWriteTestMeshB(MESH_B_FILE_C, compression);
if (status != TRUE) {
printf("Error writing TestMeshB\n");
return status;
}
printf("Finished writing meshes.\n");
// read the files back in
status = txiReadXFormatFile(MESH_A_FILE_C, MESH_A_OUT_C);
if (status != TRUE) {
printf("Error reading TestMeshA\n");
return status;
}
// read the files back in
status = txiReadXFormatFile(MESH_B_FILE_C, MESH_B_OUT_C);
if (status != TRUE) {
printf("Error reading TestMeshB\n");
return status;
}
printf("Finished reading meshes.\n");
return status;
} // txiTestMeshs
// ---------------------------------------------------------------------------
// FUNCTION txiTestFortran
// PURPOSE test to see if C code can read file written with fortran.
// NOTES
// ---------------------------------------------------------------------------
int txiTestFortran ()
{
xid xFileId = 0;
herr_t (*old_func)(void*);
int status = 1;
int nStatus = 1;
void *old_client_data;
// Check to see if files written with C exist
H5Eget_auto1(&old_func, &old_client_data);
// Turn off error handling
H5Eset_auto1(NULL, NULL);
// Try opening a file written with C to see if one exists.
nStatus = xfOpenFile(SCALAR_A_FILE_F, &xFileId, XTRUE);
// If the file written with FORTRAN doesn't exist, return.
if (nStatus < 0) {
xfCloseFile(xFileId);
// Restore previous error handler
H5Eset_auto1(old_func, old_client_data);
return FALSE;
// If the file written with C does exist, assume all C files exist.
}
else {
xfCloseFile(xFileId);
// Restore previous error handler
H5Eset_auto1(old_func, old_client_data);
}
// Read the files back in
status = txiReadXFormatFile(SCALAR_A_FILE_F, SCALAR_A_TEXT_FC);
if (status < 0) {
return status;
}
status = txiReadXFormatFile(SCALAR_B_FILE_F, SCALAR_B_TEXT_FC);
if (status < 0) {
return status;
}
status = txiReadXFormatFile(VECTOR2D_A_FILE_F, VECTOR2D_A_TEXT_FC);
if (status < 0) {
return status;
}
status = txiReadXFormatFile(VECTOR2D_B_FILE_F, VECTOR2D_B_TEXT_FC);
if (status < 0) {
return status;
}
printf("Done reading fortran datasets...\n");
status = txiReadXFormatFile(GRID_CART2D_A_FILE_F, GRID_CART2D_A_OUT_FC);
if (status < 0) {
printf("Error reading fortran grid Cartesian 2D A\n");
}
printf("Finished reading fortran grid Cartesian 2D A\n");
status = txiReadXFormatFile(GRID_CURV2D_A_FILE_F, GRID_CURV2D_A_OUT_FC);
if (status < 0) {
printf("Error reading fortran grid Curvilinear 2D A\n");
}
printf("Finished reading fortran grid Curvilinear 2D A\n");
status = txiReadXFormatFile(GRID_CART3D_A_FILE_F, GRID_CART3D_A_OUT_FC);
if (status < 0) {
printf("Error reading grid fortran Cartesian 3D A\n");
}
printf("Finished reading fortran grid Cartesian 3D A\n");
// read the files back in
status = txiReadXFormatFile(MESH_A_FILE_F, MESH_A_OUT_FC);
if (status != TRUE) {
printf("Error reading fortran TestMeshA\n");
return status;
}
// read the files back in
status = txiReadXFormatFile(MESH_B_FILE_F, MESH_B_OUT_FC);
if (status != TRUE) {
printf("Error reading fortran TestMeshB\n");
return status;
}
printf("Finished reading fortran meshes.\n");
return status;
} // txiTestFortran
// --------------------------------------------------------------------------
// FUNCTION txiReadXFormatFile
// PURPOSE Read a file using XMDF and write information about the data
// contained in the file to a output file
// --------------------------------------------------------------------------
int txiReadXFormatFile (LPCSTR a_XmdfFile, LPCSTR a_OutFile)
{
int nMeshGroups, nMaxPathLength, nGridGroups;
char *Paths = NULL, *IndividualPath = NULL;
int nStatus, i;
float Version;
xid xFileId = NONE, xGroupId = NONE;
FILE *fp = NULL;
// int NameSize;
// char *Name = NULL;
// H5I_type_t IdentifierType;
// Open the XMDF file
nStatus = xfOpenFile(a_XmdfFile, &xFileId, XTRUE);
if (nStatus < 0) {
return -1;
}
// open the status file
fp = fopen(a_OutFile, "w");
if (fp == NULL) {
xfCloseFile(xFileId);
return -1;
}
fprintf(fp, "File %s opened.\n", a_XmdfFile);
// write the version number to the file
xfGetLibraryVersionFile(xFileId, &Version);
fprintf(fp, "XMDF Version: %f\n", Version);
// Write Coordinate System Informatioin to the .txt file
nStatus = txiTestCoordSystem(xFileId, fp);
fprintf(fp, "\n");
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// read all datasets not beneath a mesh, grid, or cross-sections
nStatus = tdReadDatasets(xFileId, fp);
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// Get the number and paths of datasets in the file.
nStatus = xfGetGroupPathsSizeForMeshes(xFileId, &nMeshGroups,
&nMaxPathLength);
if (nStatus >= 0) {
Paths = (char *)malloc(nMaxPathLength*nMeshGroups*sizeof(char));
nStatus = xfGetGroupPathsForMeshes(xFileId, nMeshGroups,
nMaxPathLength, Paths);
}
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// Report the number and paths to individual meshes in the file.
fprintf(fp, "Number of meshes in file: %d\n", nMeshGroups);
fprintf(fp, "Paths:\n");
for (i = 0; i < nMeshGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, " %s\n", IndividualPath);
}
fprintf(fp, "\n");
// Open each mesh group
for (i = 0; i < nMeshGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, "Reading mesh in group: %s\n", IndividualPath);
nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
if (nStatus >= 0) {
// RDJ to delete
// IdentifierType = H5Iget_type(xGroupId);
// NameSize = H5Iget_name(xGroupId, NULL, NULL);
// Name = new char[NameSize + 1];
// NameSize = H5Iget_name(xGroupId, Name, NULL);
// if (Name) {
// delete [] Name;
// }
nStatus = tmReadMesh(xGroupId, fp);
}
if (nStatus < 0) {
printf("Error reading mesh..\n");
}
}
if (Paths) {
free(Paths);
Paths = NULL;
}
// Grid stuff
nStatus = xfGetGroupPathsSizeForGrids(xFileId, &nGridGroups,
&nMaxPathLength);
if (nStatus >= 0) {
Paths = (char *)malloc(nMaxPathLength*nGridGroups*sizeof(char));
nStatus = xfGetGroupPathsForGrids(xFileId, nGridGroups,
nMaxPathLength, Paths);
}
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// Report the number and paths to individual meshes in the file.
fprintf(fp, "Number of grids in file: %d\n", nGridGroups);
fprintf(fp, "Paths:\n");
for (i = 0; i < nGridGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, " %s\n", IndividualPath);
}
fprintf(fp, "\n");
// Open each grid group
for (i = 0; i < nGridGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, "Reading grid in group: %s\n", IndividualPath);
nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
if (nStatus >= 0) {
nStatus = tgReadGrid(xGroupId, fp);
}
if (nStatus < 0) {
printf("Error reading grid..\n");
}
}
if (Paths) {
free(Paths);
Paths = NULL;
}
// TODO do grid, and cross-section stuff.
// close the files
xfCloseFile(xFileId);
fclose(fp);
return TRUE;
} // txiReadXFormatFile
// --------------------------------------------------------------------------
// FUNCTION txiReadXFormatFileT
// PURPOSE Read a file using XMDF and write information about the data
// contained in the file to a output file
// --------------------------------------------------------------------------
int txiReadXFormatFileT (LPCSTR a_XmdfFile, LPCSTR a_OutFile)
{
int nMeshGroups, nMaxPathLength, nGridGroups;
char *Paths = NULL, *IndividualPath = NULL;
int nStatus, i;
float Version;
xid xFileId = NONE, xGroupId = NONE;
FILE *fp = NULL;
// Open the XMDF file
nStatus = xfOpenFile(a_XmdfFile, &xFileId, XTRUE);
if (nStatus < 0) {
return -1;
}
// open the status file
fp = fopen(a_OutFile, "w");
if (fp == NULL) {
xfCloseFile(xFileId);
return -1;
}
fprintf(fp, "File %s opened.\n", a_XmdfFile);
// write the version number to the file
xfGetLibraryVersionFile(xFileId, &Version);
fprintf(fp, "XMDF Version: %f\n", Version);
// Write Coordinate System Informatioin to the .txt file
nStatus = txiTestCoordSystem(xFileId, fp);
fprintf(fp, "\n");
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// read all datasets not beneath a mesh, grid, or cross-sections
nStatus = ttReadDatasets(xFileId, fp);
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// Get the number and paths of datasets in the file.
nStatus = xfGetGroupPathsSizeForMeshes(xFileId, &nMeshGroups,
&nMaxPathLength);
if (nStatus >= 0) {
Paths = (char *)malloc(nMaxPathLength*nMeshGroups*sizeof(char));
nStatus = xfGetGroupPathsForMeshes(xFileId, nMeshGroups,
nMaxPathLength, Paths);
}
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// Report the number and paths to individual meshes in the file.
fprintf(fp, "Number of meshes in file: %d\n", nMeshGroups);
fprintf(fp, "Paths:\n");
for (i = 0; i < nMeshGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, " %s\n", IndividualPath);
}
fprintf(fp, "\n");
// Open each mesh group
for (i = 0; i < nMeshGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, "Reading mesh in group: %s\n", IndividualPath);
nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
if (nStatus >= 0) {
nStatus = tmReadMesh(xGroupId, fp);
}
if (nStatus < 0) {
printf("Error reading mesh..\n");
}
}
if (Paths) {
free(Paths);
Paths = NULL;
}
// Grid stuff
nStatus = xfGetGroupPathsSizeForGrids(xFileId, &nGridGroups,
&nMaxPathLength);
if (nStatus >= 0) {
Paths = (char *)malloc(nMaxPathLength*nGridGroups*sizeof(char));
nStatus = xfGetGroupPathsForGrids(xFileId, nGridGroups,
nMaxPathLength, Paths);
}
if (nStatus < 0) {
xfCloseFile(xFileId);
return -1;
}
// Report the number and paths to individual meshes in the file.
fprintf(fp, "Number of grids in file: %d\n", nGridGroups);
fprintf(fp, "Paths:\n");
for (i = 0; i < nGridGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, " %s\n", IndividualPath);
}
fprintf(fp, "\n");
// Open each grid group
for (i = 0; i < nGridGroups; i++) {
IndividualPath = &Paths[i*nMaxPathLength];
fprintf(fp, "Reading grid in group: %s\n", IndividualPath);
nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
if (nStatus >= 0) {
nStatus = tgReadGrid(xGroupId, fp);
}
if (nStatus < 0) {
printf("Error reading grid..\n");
}
}
if (Paths) {
free(Paths);
Paths = NULL;
}
// TODO do grid, and cross-section stuff.
// close the files
xfCloseFile(xFileId);
fclose(fp);
return TRUE;
} // txiReadXFormatFileT
//-----------------------------------------------------------------------------
// FUNCTION TXI_WRITE_XMDF_VERSION
// PURPOSE Write the XMDF version number to the screen
// NOTES
//-----------------------------------------------------------------------------
int txiTestVersion ()
{
float Version;
printf("\n");
xfGetLibraryVersion(&Version);
printf("The current version of XMDF is: %f\n\n", Version);
return 1;
} // txiTestVersion
//-----------------------------------------------------------------------------
// #defines used in txiTestCalendar
//-----------------------------------------------------------------------------
#define CALENDAR_OUT_C "Calendar_c.txt"
//----------------------------------------------------------------------------
// SUBROUTINE txiTestCalendar
// PURPOSE Check the Calculations of Julian date from calendar date or
// vice-versa.
// NOTES Use #defines: ERA_IS_BCE (BC), and ERA_IS_CE (AD).
//----------------------------------------------------------------------------
int txiTestCalendar ()
{
FILE *fp = NULL;
xmbool era1, era2, era3, era4;
int yr1, mo1, day1, hr1, min1, sec1;
int yr2, mo2, day2, hr2, min2, sec2;
int yr3, mo3, day3, hr3, min3, sec3;
int yr4, mo4, day4, hr4, min4, sec4, calendarworks;
double julian1, julian2, julian3, julian4;
calendarworks = 0;
// open the status file
fp = fopen(CALENDAR_OUT_C, "w");
if (fp == NULL) {
return FALSE;
}
fprintf(fp, "Calendar conversion:\n\n");
era1 = ERA_IS_BCE;
yr1 = mo1 = day1 = hr1 = min1 = sec1 = 0;
julian1 = 2655.5;
xfJulianToCalendar(&era1, &yr1, &mo1, &day1, &hr1, &min1, &sec1, julian1);
yr2 = 4706;
mo2 = 4;
day2 = 10;
era2 = ERA_IS_BCE;
hr2 = min2 = sec2 = 0;
julian2 = 0.0;
xfCalendarToJulian(era2, yr2, mo2, day2, hr2, min2, sec2, &julian2);
era3 = ERA_IS_CE;
yr3 = 2004;
mo3 = 6;
day3 = 3;
hr3 = 2;
min3 = 8;
sec3 = 32;
julian3 = 0.0;
xfCalendarToJulian(era3, yr3, mo3, day3, hr3, min3, sec3, &julian3);
era4 = ERA_IS_BCE;
yr4 = mo4 = day4 = hr4 = min4 = sec4 = 0;
julian4 = 2453159.5892592594;
xfJulianToCalendar(&era4, &yr4, &mo4, &day4, &hr4, &min4, &sec4, julian4);
fprintf(fp, "Dates #1 & #2 were calculated with the same date:\n\n");
fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
era1, yr1, mo1, day1, hr1, min1, sec1, julian1);
fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n\n",
era2, yr2, mo2, day2, hr2, min2, sec2, julian2);
fprintf(fp, "Dates #3 & #4 were calculated with the same date:\n\n");
fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
era3, yr3, mo3, day3, hr3, min3, sec3, julian3);
fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
era4, yr4, mo4, day4, hr4, min4, sec4, julian4);
if (era1==era2 && era3==era4) {
if (yr1==yr2 && yr3==yr4) {
if (mo1==mo2 && mo3==mo4) {
if (day1==day2 && day3==day4) {
if (hr1==hr2 && hr3==hr4) {
if (min1==min2 && min3==min4) {
if (EQ_EPS(julian1, julian2, DBL_EPS) &&
EQ_EPS(julian3, julian4, DBL_EPS)) {
printf("\n");
printf("Calendar conversion works correctly.\n");
calendarworks = 1;
}
}
}
}
}
}
}
if (calendarworks != 1) {
printf("\n");
printf("Calendar Conversion sdfse DOES NOT Work Correctly.\n");
return -1;
}
else {
return 1;
}
}
//----------------------------------------------------------------------------
// SUBROUTINE txiTestCoordSystem
// PURPOSE Reads a file's Coordinate Group and prints coordinate data out
// to each text file.
// NOTES
//----------------------------------------------------------------------------
int txiTestCoordSystem (xid xFileId, FILE *a_OutFile)
{
int iHorizDatum, iHorizUnits, iVertDatum, iVertUnits;
int iLat, iLon, iUtmZone, iSpcZone, iHpgnArea, iEllipse;
int bHorizDatum, nStatus;
double dCppLat, dCppLon, dMajorR, dMinorR;
xid xCoordId = NONE;
char strHorizUnits[256], strVertDatum[256], strVertUnits[256];
// Coordinate stuff
// Read Coordinate Info
// Open the Coordinate group
nStatus = xfOpenCoordinateGroup(xFileId, &xCoordId);
if (nStatus <= 0) {
fprintf(a_OutFile, "\n");
fprintf(a_OutFile, "Coordinate Group not found\n");
fprintf(a_OutFile, "\n");
return -1;
}
fprintf(a_OutFile, "\n");
fprintf(a_OutFile, "Coordinate System:\n");
bHorizDatum = xfGetHorizDatum(xCoordId, &iHorizDatum);
xfGetHorizUnits(xCoordId, &iHorizUnits);
xfGetVertDatum(xCoordId, &iVertDatum);
xfGetVertUnits(xCoordId, &iVertUnits);
// set horizontal units
if (iHorizUnits == 0) {
strcpy(strHorizUnits, "Horizontal units = US Survey Feet (=0)");
}
else if (iHorizUnits == 1) {
strcpy(strHorizUnits, "Horizontal units = International Feet (=1)");
}
else if (iHorizUnits == 2) {
strcpy(strHorizUnits, "Horizontal units = Meters (=2)");
}
else {
strcpy(strHorizUnits, "ERROR in reading Horizontal units");
}
// set vertical datum
if (iVertDatum == 0) {
strcpy(strVertDatum, "Vertical datum = Local (=0)");
}
else if (iVertDatum == 1) {
strcpy(strVertDatum, "Vertical datum = NGVD 29 (=1)");
}
else if (iVertDatum == 2) {
strcpy(strVertDatum, "Vertical datum = NGVD 88 (=2)");
}
else {
strcpy(strVertDatum, "ERROR in reading the Vertical datum\n");
}
// set vertocal units
if (iVertUnits == 0) {
strcpy(strVertUnits, "Vertical units = US Survey Feet (=0)");
}
else if (iVertUnits == 1) {
strcpy(strVertUnits, "Vertical units = International Feet (=1)");
}
else if (iVertUnits == 2) {
strcpy(strVertUnits, "Vertical units = Meters (=2)");
}
else {
strcpy(strVertUnits, "ERROR in reading the Vertical units");
}
if (bHorizDatum >= 0) {
switch (iHorizDatum) {
case HORIZ_DATUM_GEOGRAPHIC:
xfGetEllipse(xCoordId, &iEllipse);
xfGetLat(xCoordId, &iLat);
xfGetLon(xCoordId, &iLon);
// Write Horizontal and Vertical Info
fprintf(a_OutFile, "Horizontal datum = Geographic\n");
fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
// Write Latitude data
if (iLat == 0) {
fprintf(a_OutFile, " Latitude = North (=%d)\n", iLat);
}
else if (iLat == 1) {
fprintf(a_OutFile, " Latitude = South (=%d)\n", iLat);
}
else {
fprintf(a_OutFile, " LATITUDE INFO INCORRECT\n");
}
// Longitude
if (iLon == 0) {
fprintf(a_OutFile, " Longitude = East (=%d)\n", iLon);
}
else if (iLon == 1) {
fprintf(a_OutFile, " Longitude = West (=%d)\n", iLon);
}
else {
fprintf(a_OutFile, " LONGITUDE INFO INCORRECT\n");
}
// Ellipse Information
// User-defined Ellipse (==32)
if (iEllipse == 32) {
fprintf(a_OutFile, "Ellipse = User-defined:\n");
xfGetMajorR(xCoordId, &dMajorR);
xfGetMinorR(xCoordId, &dMinorR);
fprintf(a_OutFile, " MajorR = %lf\n", dMajorR);
fprintf(a_OutFile, " MinorR = %lf\n\n", dMinorR);
}
else {
fprintf(a_OutFile, "Ellipse = %d\n\n", iEllipse);
}
break;
case HORIZ_DATUM_UTM:
case HORIZ_DATUM_UTM_NAD27:
case HORIZ_DATUM_UTM_NAD83:
xfGetUTMZone(xCoordId, &iUtmZone);
// output info to text file
if (iHorizDatum == HORIZ_DATUM_UTM) {
fprintf(a_OutFile, "Horizontal datum = UTM\n");
}
else if (iHorizDatum == HORIZ_DATUM_UTM_NAD27) {
fprintf(a_OutFile, "Horizontal datum = UTM NAD27 (US)\n");
}
else {
fprintf(a_OutFile, "Horizontal datum = UTM NAD83 (US)\n");
}
fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
fprintf(a_OutFile, "UTM Zone = %d\n\n", iUtmZone);
break;
case HORIZ_DATUM_STATE_PLANE_NAD27:
case HORIZ_DATUM_STATE_PLANE_NAD83:
xfGetSPCZone(xCoordId, &iSpcZone);
// output info to text file
if (iHorizDatum == HORIZ_DATUM_STATE_PLANE_NAD27) {
fprintf(a_OutFile, "Horizontal datum = State Plane NAD27 (US)\n");
}
else {
fprintf(a_OutFile, "Horizontal datum = State Plane NAD83 (US)\n");
}
fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
fprintf(a_OutFile, "SPC Zone = %d\n\n", iSpcZone);
break;
case HORIZ_DATUM_UTM_HPGN:
case HORIZ_DATUM_STATE_PLANE_HPGN:
case HORIZ_DATUM_GEOGRAPHIC_HPGN:
xfGetHPGNArea(xCoordId, &iHpgnArea);
if (iHorizDatum == HORIZ_DATUM_UTM_HPGN) {
fprintf(a_OutFile, "Horizontal datum = UTM HPGN (US)\n");
}
else if (iHorizDatum == HORIZ_DATUM_STATE_PLANE_HPGN) {
fprintf(a_OutFile, "Horizontal datum = State Plane HPGN (US)\n");
}
else {
fprintf(a_OutFile, "Horizontal datum = Geographic HPGN (US)\n");
}
fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
fprintf(a_OutFile, "HPGN Area = %d\n\n", iHpgnArea);
break;
case HORIZ_DATUM_CPP:
xfGetCPPLat(xCoordId, &dCppLat);
xfGetCPPLon(xCoordId, &dCppLon);
fprintf(a_OutFile, "Horizontal datum = CPP (Carte Parallelo-Grammatique Projection)\n");
fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
fprintf(a_OutFile, "CPP Latitude = %lf\n", dCppLat);
fprintf(a_OutFile, "CPP Longitude = %lf\n\n", dCppLon);
break;
default:
// do other systems
if (iHorizDatum == HORIZ_DATUM_LOCAL) {
fprintf(a_OutFile, "Horizontal datum = Local\n");
}
else if (iHorizDatum == HORIZ_DATUM_GEOGRAPHIC_NAD27) {
fprintf(a_OutFile, "Horizontal datum = Geographic NAD27 (US)\n");
}
else if (iHorizDatum == HORIZ_DATUM_GEOGRAPHIC_NAD83) {
fprintf(a_OutFile, "Horizontal datum = Geographic NAD83 (US)\n");
}
else {
fprintf(a_OutFile, "ERROR: The Horizontal Datum in the .h5 file is not recognizable\n");
return -1;
}
fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
fprintf(a_OutFile, "Vertical units = %s\n\n", strVertUnits);
break;
}
}
else {
fprintf(a_OutFile, "Coordinate information in HDF5 file is incomplete.");
fprintf(a_OutFile, "\n");
}
xfCloseGroup(xCoordId);
xCoordId = 0;
return TRUE;
} // txiTestCoordSystem