// 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.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); // 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 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, ×tepId); 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, ×tepId); 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, ×tepId); 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, ×tepId); 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, ×tepId); // 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
#include "stdafx.h" #include <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; }
#include "stdafx.h" #include <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
#include "stdafx.h" #include <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
// 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.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; }
// TestXFormat.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <hdf5.h> #include <Xmdf.h> #include <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); if (status < 0) { printf("Error writing dataset vector2D_A."); return status; } status = tdWriteVector2D_A_Pieces(VECTOR2D_A_FILE_PIECES_C, compression); if (status < 0) { printf("Error writing dataset vector2D_A_Pieces"); return status; } printf("Done writing vector datasets...\n"); printf("Write edited scalar datasets...\n"); status = tdEditScalarAValues(SCALAR_A_EDITED_FILE_C, compression); 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); if (status < 0) { return status; } printf("Done reading scalar data at index.\n"); status = tdReadVector2DAIndex(VECTOR2D_A_FILE_C, 4); if (status < 0) { return status; } printf("Done reading vector data at index.\n"); status = tdReadActivityScalarAIndex(SCALAR_A_FILE_C, 5); 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); 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