TestXmdf.cpp

TestXmdf.cpp provides C++ code examples for many XMDF APIs.
00001 // This file has functions that can be used to test reading and writing of
00002 // datasets using HDF5.  This code is intended to be used as tests for the
00003 // XMDF library as well as sample code for distribution.
00004 
00005 #include "stdafx.h"
00006 #include <Xmdf.h>
00007 #include <stdio.h>
00008 #include <windows.h>
00009 #include <string.h>
00010 #include <stdlib.h>
00011 
00012 #define    DATASETS_LOCATION "Datasets"
00013 #define    SCALAR_A_LOCATION "Scalars/ScalarA"
00014 #define    SCALAR_B_LOCATION "Scalars/ScalarB"
00015 #define    VECTOR2D_A_LOCATION "Vectors/Vector2D_A"
00016 #define    VECTOR2D_B_LOCATION "Vectors/Vector2D_B"
00017 
00018 void tdiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
00019                      int a_SeedMultiplier, int a_nValues, float *a_Array);
00020 double tdiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed);
00021 int tdiReadScalar (xid a_xScalarId, FILE *a_fp);
00022 int tdiReadVector (xid a_xVectorId, FILE *a_fp);
00023 
00024 // --------------------------------------------------------------------------
00025 // FUNCTION tdReadDatasets
00026 // PURPOSE  Read a dataset group from an XMDF file and output information to
00027 //          to a text file
00028 // NOTES    
00029 // --------------------------------------------------------------------------
00030 int tdReadDatasets (xid a_xGroupId, FILE *a_fp)
00031 {
00032   int   nPaths=0, nMaxPathLength=0, nMultiDatasets=0;
00033   char *Paths = NULL, *IndividualPath = NULL;
00034   int   nStatus, i, j;
00035   xid   xScalarId = NONE, xVectorId = NONE, xMultiId = NONE;
00036 
00037   // Look for scalar datasets
00038   nStatus = xfGetScalarDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00039   if (nStatus >= 0) {
00040     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00041     xfGetScalarDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00042   }
00043   if (nStatus < 0) {
00044     return -1;
00045   }
00046   
00047   // Output number and paths to scalar datasets
00048   fprintf(a_fp, "Number of Scalars %d\n", nPaths);
00049   for (i = 0; i < nPaths; i++) {
00050     IndividualPath = &Paths[i*nMaxPathLength];
00051     fprintf(a_fp, "Reading scalar: %s\n", IndividualPath);
00052    
00053     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xScalarId);
00054     if (nStatus < 0) {
00055       return -1; 
00056     }
00057 
00058     nStatus = tdiReadScalar(xScalarId, a_fp);
00059     xfCloseGroup(xScalarId);
00060     if (nStatus < 0) {
00061       printf("Error reading scalar dataset.");
00062       return -1;
00063     }
00064   }
00065 
00066   if (Paths) {
00067     free(Paths);
00068     Paths = NULL;
00069   }
00070 
00071   // Look for vector datasets
00072   nStatus = xfGetVectorDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00073   if (nStatus >= 0 && nPaths > 0) {
00074     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00075     xfGetVectorDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00076   }
00077   if (nStatus < 0) {
00078     return -1;
00079   }
00080 
00081 
00082   // Output number and paths to scalar datasets
00083   fprintf(a_fp, "Number of Vectors %d\n", nPaths);
00084   for (i = 0; i < nPaths; i++) {
00085     IndividualPath = &Paths[i*nMaxPathLength];
00086     fprintf(a_fp, "Reading Vector: %s\n", IndividualPath);
00087    
00088     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xVectorId);
00089     if (nStatus < 0) {
00090       return -1; 
00091     }
00092 
00093     nStatus = tdiReadVector(xVectorId, a_fp);
00094     xfCloseGroup(xVectorId);
00095     if (nStatus < 0) {
00096       printf("Error reading vector dataset.");
00097       return -1;
00098     }
00099   }
00100 
00101   // find multidataset folders
00102   nStatus = xfGetGroupPathsSizeForMultiDatasets(a_xGroupId, &nMultiDatasets,
00103                                                       &nMaxPathLength);
00104   if (nStatus >= 0 && nMultiDatasets > 0) {
00105     Paths = (char *)malloc(nMultiDatasets*nMaxPathLength*sizeof(char));
00106     nStatus = xfGetAllGroupPathsForMultiDatasets(a_xGroupId, nMultiDatasets, 
00107                                                  nMaxPathLength, Paths);
00108     if (nStatus < 0) {
00109       return -1;
00110     }
00111 
00112   // Output number and paths to multidatasets
00113     fprintf(a_fp, "Number of Multidatasets: %d\n", nMultiDatasets);
00114     for (i=0; i<nMultiDatasets; i++) {
00115       IndividualPath = "";
00116       for (j=0; j<nMaxPathLength-1; j++) {
00117         IndividualPath = &Paths[i*nMaxPathLength];
00118       }
00119       fprintf(a_fp, "Reading multidataset: %s\n", IndividualPath);
00120       nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xMultiId);
00121       if (nStatus < 0) {
00122             return -1;
00123       }
00124 
00125       nStatus = tdReadDatasets(xMultiId, a_fp);
00126       nStatus = xfCloseGroup(xMultiId);
00127       if (nStatus < 0) {
00128         printf("Error reading multidatasets.");
00129             return -1;
00130       }
00131     }
00132   }
00133 
00134   if (Paths) {
00135     free(Paths);
00136     Paths = NULL;
00137   }
00138 
00139   return 1;
00140 } // tdReadDatasets
00141 // --------------------------------------------------------------------------
00142 // FUNCTION tdReadActivityScalarAIndex
00143 // PURPOSE  Read all timestep values for a particular index
00144 // NOTES    
00145 // --------------------------------------------------------------------------
00146 int tdReadActivityScalarAIndex (LPCSTR a_Filename, int a_Index)
00147 {
00148   int     status;
00149   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00150   int     nTimesteps;
00151   xmbool  *bActive;
00152 
00153   // open the file
00154   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00155   if (status < 0) {
00156     return FALSE;
00157   }
00158 
00159   // open the dataset group
00160   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00161   if (status >= 0) {
00162     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00163   }
00164   if (status < 0) {
00165     return status;
00166   }
00167 
00168   // Find out the number of timesteps in the file
00169   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00170   if (status < 0) {
00171     return status;
00172   }
00173   if (nTimesteps < 1) {
00174     return -1;
00175   }
00176 
00177   // Read the values for the index
00178   bActive = new xmbool[nTimesteps];
00179   status = xfReadActivityValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00180                                        bActive);
00181 
00182   // output the data
00183   printf("\nReading activity for scalar A slice at index: %d\n", a_Index);
00184   for (int i = 0; i < nTimesteps; i++) {
00185     printf("%d ", bActive[i]);
00186   }
00187   printf("\n");
00188 
00189   delete [] bActive;
00190 
00191   return status;
00192 } // tdReadActivityScalarAtIndex
00193 // --------------------------------------------------------------------------
00194 // FUNCTION tdReadScalarAIndex
00195 // PURPOSE  Read all timestep values for a particular index
00196 // NOTES    
00197 // --------------------------------------------------------------------------
00198 int tdReadScalarAIndex (LPCSTR a_Filename, int a_Index)
00199 {
00200   int     status;
00201   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00202   int     nTimesteps;
00203   float  *fValues;
00204 
00205   // open the file
00206   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00207   if (status < 0) {
00208     return FALSE;
00209   }
00210 
00211   // open the dataset group
00212   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00213   if (status >= 0) {
00214     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00215   }
00216   if (status < 0) {
00217     return status;
00218   }
00219 
00220   // Find out the number of timesteps in the file
00221   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00222   if (status < 0) {
00223     return status;
00224   }
00225   if (nTimesteps < 1) {
00226     return -1;
00227   }
00228 
00229   // Read the values for the index
00230   fValues = new float[nTimesteps];
00231   status = xfReadScalarValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00232                                      fValues);
00233 
00234   // output the data
00235   printf("\nReading scalar A slice at index: %d\n", a_Index);
00236   for (int i = 0; i < nTimesteps; i++) {
00237     printf("%f ", fValues[i]);
00238   }
00239   printf("\n");
00240 
00241   delete [] fValues;
00242 
00243   return status;
00244 } // tdReadScalarAtIndex
00245 // --------------------------------------------------------------------------
00246 // FUNCTION tdWriteScalarA
00247 // PURPOSE  Write scalar Dataset to an HDF5 File
00248 // NOTES    This tests dynamic data sets, and activity
00249 //          This dataset is dynamic concentrations (mg/L) with output times
00250 //          in minutes.
00251 //          Dataset is for a mesh and so nActive is the number of elements
00252 //          which is not the same as the nValues which would be number of nodes
00253 //          reads/writes a reference time in julian days
00254 // --------------------------------------------------------------------------
00255 int tdWriteScalarA (LPCSTR a_Filename, int a_Compression)
00256 {
00257   xid      xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
00258   int      nValues = 10, nTimes = 3, nActive = 8;
00259   double   dTime = 0.0;
00260   int      iTimestep, iActive;
00261   float    fValues[10]; // nValues
00262   xmbool    bActivity[10]; // activity
00263   int      status, iHpgnZone;
00264   double   dJulianReftime;
00265   int      nErrors = 0, i = 0;
00266   char     **Errors = NULL;
00267 
00268   // 5th item in data set is always inactive, others active
00269   for (iActive = 0; iActive < nActive; iActive++) {
00270     bActivity[iActive] = XTRUE;
00271   }
00272   bActivity[5] = XFALSE;
00273 
00274   // create the file
00275   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00276   if (status < 0) {
00277     return FALSE;
00278   }
00279 
00280   // create the group where we will put all the datasets 
00281   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00282   if (status < 0) {
00283     xfCloseFile(xFileId);
00284     return FALSE;
00285   }
00286 
00287   // uncomment next line to test error handling function
00288   // xfCloseGroup(xDsetsId);
00289 
00290   // Create the scalar A dataset group
00291   status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
00292                                  "mg/L", TS_HOURS, a_Compression,
00293                                  &xScalarAId);
00294   if (status < 0) {
00295     // print the error stack
00296     xfGetNumErrorMessages(&nErrors);
00297     if (nErrors > 0) {
00298       Errors = new char*[nErrors];
00299       for (i = 0; i < nErrors; i++) {
00300         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00301       }
00302       status = xfGetErrorMessages(nErrors, Errors);
00303       if (status > 0) {
00304         for (i = 0; i < nErrors; i++) {
00305           printf("%s\n", Errors[i]);
00306         }
00307       }
00308       for (i = 0; i < nErrors; i++) {
00309         delete Errors[i];
00310       }
00311       delete Errors;
00312     }
00313 
00314     xfCloseGroup(xDsetsId);
00315     xfCloseFile(xFileId);
00316     return FALSE;
00317   }
00318 
00319   // Add in a reftime.  This is a julian day for:
00320   // noon July 1, 2003
00321   dJulianReftime = 2452822.0;
00322   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00323   if (status < 0) {
00324     xfCloseGroup(xScalarAId);
00325     xfCloseGroup(xDsetsId);
00326     xfCloseFile(xFileId);
00327   }
00328 
00329   // Loop through timesteps adding them to the file
00330   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00331     // We will have an 0.5 hour timestep
00332     dTime = (iTimestep + 1) * 0.5;
00333 
00334     fValues[0] = (float)dTime;
00335     for (i = 1; i < nValues; i++) {
00336       fValues[i] = float(fValues[i-1]*2.5);
00337     }
00338 
00339     // write the dataset array values
00340     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00341     if (status >= 0) {
00342       // write activity array
00343       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00344     }
00345     if (status < 0) {
00346       xfCloseGroup(xScalarAId);
00347       xfCloseGroup(xDsetsId);
00348       xfCloseFile(xFileId);
00349     }
00350   }
00351 
00352   // Write Coordinate file - for ScalarA, we will set the coordinate system
00353   //   to be Geographic HPGN, with HPGN settings written to the file.
00354   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00355   if (status <= 0) {
00356     xfCloseGroup(xScalarAId);
00357     xfCloseGroup(xDsetsId);
00358     xfCloseFile(xFileId);
00359         return -1;
00360   }
00361 
00362     // set HPGN Zone for test
00363   iHpgnZone = 29;      // Utah
00364 
00365     // Write Coordinate Information to file
00366   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00367   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00368   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00369   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00370 
00371     // write additional information
00372   xfSetHPGNArea(xCoordId, iHpgnZone);
00373 
00374   xfCloseGroup(xCoordId);
00375   xCoordId = 0;
00376 
00377   // close the dataset
00378   xfCloseGroup(xScalarAId);
00379   xfCloseGroup(xDsetsId);
00380   xfCloseFile(xFileId);
00381 
00382   return FALSE;
00383 } // tdWriteScalarA
00384 
00385 // --------------------------------------------------------------------------
00386 // FUNCTION tdWriteScalarB
00387 // PURPOSE  Write scalar Dataset to an HDF5 File
00388 // NOTES    This tests dynamic data sets, and activity
00389 //          This dataset is dynamic concentrations (mg/L) with output times
00390 //          in minutes.
00391 //          Dataset is for a mesh and so nActive is the number of elements
00392 //          which is not the same as the nValues which would be number of nodes
00393 //          reads/writes a reference time in julian days
00394 // --------------------------------------------------------------------------
00395 int tdWriteScalarB (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00396 {
00397   xid      xFileId, xDsetsId, xScalarBId, xCoordId = NONE;
00398   int      nValues = 10, nTimes = 3, nActive = 8;
00399   double   dTime = 0.0, dJulianReftime;
00400   int      iTimestep, iActive;
00401   float    fValues[10]; // nValues
00402   xmbool    bActivity[10]; // activity
00403   int      status, nErrors = 0, i = 0;
00404   char     **Errors = NULL;
00405 
00406   // 5th item in data set is always inactive, others active
00407   for (iActive = 0; iActive < nActive; iActive++) {
00408     bActivity[iActive] = XTRUE;
00409   }
00410   bActivity[5] = XFALSE;
00411 
00412   if (a_Overwrite) {
00413       // open the already-existing file
00414     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00415     if (status < 0) {
00416       return -1;
00417     }
00418       // open the group where we have all the datasets 
00419     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00420     if (status < 0) {
00421       xfCloseFile(xFileId);
00422       return -1;
00423     }
00424   }
00425   else {
00426       // create the file
00427     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00428     if (status < 0) {
00429       return -1;
00430     }
00431       // create the group where we will put all the datasets 
00432     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00433     if (status < 0) {
00434       xfCloseFile(xFileId);
00435       return -1;
00436     }
00437   }
00438 
00439   // uncomment next line to test error handling function
00440   // xfCloseGroup(xDsetsId);
00441 
00442   // Create/Overwrite the scalar B dataset group
00443   status = xfCreateScalarDataset(xDsetsId, SCALAR_B_LOCATION,
00444                                  "mg/L", TS_HOURS, a_Compression,
00445                                  &xScalarBId);
00446   if (status < 0) {
00447     // print the error stack
00448     xfGetNumErrorMessages(&nErrors);
00449     if (nErrors > 0) {
00450       Errors = new char*[nErrors];
00451       for (i = 0; i < nErrors; i++) {
00452         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00453       }
00454       status = xfGetErrorMessages(nErrors, Errors);
00455       if (status > 0) {
00456         for (i = 0; i < nErrors; i++) {
00457           printf("%s\n", Errors[i]);
00458         }
00459       }
00460       for (i = 0; i < nErrors; i++) {
00461         delete Errors[i];
00462       }
00463       delete Errors;
00464     }
00465 
00466     xfCloseGroup(xDsetsId);
00467     xfCloseFile(xFileId);
00468     return -1;
00469   }
00470 
00471   // Add in a reftime.  This is a julian day for:
00472   // noon July 1, 2003
00473   dJulianReftime = 2452822.0;
00474   status = xfDatasetReftime(xScalarBId, dJulianReftime);
00475   if (status < 0) {
00476     xfCloseGroup(xScalarBId);
00477     xfCloseGroup(xDsetsId);
00478     xfCloseFile(xFileId);
00479   }
00480 
00481   if (!a_Overwrite) {
00482     // Loop through timesteps adding them to the file
00483     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00484       // We will have an 0.5 hour timestep
00485       dTime = (iTimestep + 1) * 0.5;
00486 
00487       fValues[0] = (float)dTime;
00488       for (i = 1; i < nValues; i++) {
00489         fValues[i] = float(fValues[i-1]*2.5);
00490       }
00491 
00492       // write the dataset array values
00493       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00494       if (status >= 0) {
00495         // write activity array
00496         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00497       }
00498       if (status < 0) {
00499         xfCloseGroup(xScalarBId);
00500         xfCloseGroup(xDsetsId);
00501         xfCloseFile(xFileId);
00502       }
00503     }
00504   }
00505   else {
00506     // Loop through timesteps adding them to the file
00507     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00508       // We will have an 1.5 hour timestep
00509       dTime = (iTimestep + 1) * 1.5;
00510 
00511       fValues[0] = (float)dTime;
00512       for (i = 1; i < nValues; i++) {
00513         fValues[i] = float(fValues[i-1]*1.5);
00514       }
00515 
00516       // write the dataset array values
00517       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00518       if (status >= 0) {
00519         // write activity array
00520         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00521       }
00522       if (status < 0) {
00523         xfCloseGroup(xScalarBId);
00524         xfCloseGroup(xDsetsId);
00525         xfCloseFile(xFileId);
00526       }
00527     }
00528   }
00529 
00530   if (!a_Overwrite) {
00531     // Write Coordinate file
00532     status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00533     if (status <= 0) {
00534       xfCloseGroup(xScalarBId);
00535       xfCloseGroup(xDsetsId);
00536       xfCloseFile(xFileId);
00537       return -1;
00538     }
00539 
00540     // For ScalarB, we will set the coordinate system
00541     // to be UTM, with UTM Zone settings written to the file.
00542       // Write Coord Info to file
00543     xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00544     xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00545 
00546     xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00547     xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00548 
00549       // write additional information - we'll use the max value for this test
00550     xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00551 
00552     xfCloseGroup(xCoordId);
00553     xCoordId = 0;
00554   }
00555 
00556   // close the dataset
00557   xfCloseGroup(xScalarBId);
00558   xfCloseGroup(xDsetsId);
00559   xfCloseFile(xFileId);
00560 
00561   return 1;
00562 } // tdWriteScalarB
00563 // --------------------------------------------------------------------------
00564 // FUNCTION tdWriteCoordsToMulti
00565 // PURPOSE  Write coordinate system to a multidataset file
00566 // NOTES
00567 // --------------------------------------------------------------------------
00568 int tdWriteCoordsToMulti (xid a_xFileId)
00569 {
00570   xid   xCoordId = NONE;
00571   int   status;
00572 
00573   // Write Coordinate file - for Multidatasets, we will set the coordinate system
00574   //   to be UTM, with UTM Zone settings written to the file.
00575   status = xfCreateCoordinateGroup(a_xFileId, &xCoordId);
00576   if (status <= 0) {
00577     return -1;
00578   }
00579 
00580    // Write Coord Info to file
00581   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00582   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00583 
00584   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00585   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00586 
00587     // write additional information - we'll use the max value for this test
00588   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00589 
00590   xfCloseGroup(xCoordId);
00591   xCoordId = 0;
00592 
00593   return XTRUE;
00594 } // tdWriteCoordsToMulti
00595 // --------------------------------------------------------------------------
00596 // FUNCTION tdWriteScalarAToMulti
00597 // PURPOSE  Write scalar Dataset to a multidataset
00598 // NOTES    This tests dynamic data sets, and activity
00599 //          This dataset is dynamic concentrations (mg/L) with output times
00600 //          in minutes.
00601 //          Dataset is for a mesh and so nActive is the number of elements
00602 //          which is not the same as the nValues which would be number of nodes
00603 //          reads/writes a reference time in julian days
00604 // --------------------------------------------------------------------------
00605 int tdWriteScalarAToMulti (xid a_GroupId)
00606 {
00607   xid      xScalarAId;
00608   int      nValues = 10, nTimes = 3, nActive = 8;
00609   double   dTime = 0.0;
00610   int      iTimestep, iActive;
00611   float    fValues[10]; // nValues
00612   xmbool    bActivity[10]; // activity
00613   int      status;
00614   double   dJulianReftime;
00615   int      i = 0;
00616 
00617   // 5th item in data set is always inactive, others active
00618   for (iActive = 0; iActive < nActive; iActive++) {
00619     bActivity[iActive] = XTRUE;
00620   }
00621   bActivity[5] = XFALSE;
00622 
00623   // Create the scalar A dataset group
00624   status = xfCreateScalarDataset(a_GroupId, SCALAR_A_LOCATION,
00625                                  "mg/L", TS_HOURS, NONE,
00626                                  &xScalarAId);
00627   
00628   // Add in a reftime.  This is a julian day for:
00629   // noon July 1, 2003
00630   dJulianReftime = 2452822.0;
00631   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00632   if (status < 0) {
00633     xfCloseGroup(xScalarAId);
00634   }
00635 
00636   // Loop through timesteps adding them to the file
00637   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00638     // We will have an 0.5 hour timestep
00639     dTime = (iTimestep + 1) * 0.5;
00640 
00641     fValues[0] = (float)dTime;
00642     for (i = 1; i < nValues; i++) {
00643       fValues[i] = float(fValues[i-1]*2.5);
00644     }
00645 
00646     // write the dataset array values
00647     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00648     if (status >= 0) {
00649       // write activity array
00650       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00651     }
00652     if (status < 0) {
00653       xfCloseGroup(xScalarAId);
00654     }
00655   }
00656 
00657   // close the dataset
00658   xfCloseGroup(xScalarAId);
00659 
00660   return FALSE;
00661 } // tdWriteScalarAToMulti
00662 // --------------------------------------------------------------------------
00663 // FUNCTION tdReadVector2DAIndex
00664 // PURPOSE  Read all timestep values for a particular index
00665 // NOTES    
00666 // --------------------------------------------------------------------------
00667 int tdReadVector2DAIndex (LPCSTR a_Filename, int a_Index)
00668 {
00669   int     status;
00670   xid     xFileId = NONE, xDsetsId = NONE, xVector2DA = NONE;
00671   int     nTimesteps;
00672   float  *fValues;
00673 
00674   // open the file
00675   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00676   if (status < 0) {
00677     return FALSE;
00678   }
00679 
00680   // open the dataset group
00681   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00682   if (status >= 0) {
00683     status = xfOpenGroup(xDsetsId, VECTOR2D_A_LOCATION, &xVector2DA);
00684   }
00685   if (status < 0) {
00686     return status;
00687   }
00688 
00689   // Find out the number of timesteps in the file
00690   status = xfGetDatasetNumTimes(xVector2DA, &nTimesteps);
00691   if (status < 0) {
00692     return status;
00693   }
00694   if (nTimesteps < 1) {
00695     return -1;
00696   }
00697 
00698   // Read the values for the index
00699   fValues = new float[nTimesteps*2];
00700   status = xfReadVectorValuesAtIndex(xVector2DA, a_Index, 1, nTimesteps, 2,
00701                                      fValues);
00702 
00703   // output the data
00704   printf("\nReading vector 2D A slice at index: %d\n", a_Index);
00705   for (int i = 0; i < nTimesteps; i++) {
00706     printf("%f %f \n", fValues[i*2], fValues[i*2 + 1]);
00707   }
00708   printf("\n");
00709 
00710   delete [] fValues;
00711 
00712   return status;
00713 } // tdReadVector2DAIndex
00714 // --------------------------------------------------------------------------
00715 // FUNCTION tdWriteVector2D_A
00716 // PURPOSE  Write 2D vector dataset to an HDF5 File
00717 // NOTES    This tests dynamic data sets, and activity
00718 //          Add reftime when it is completed
00719 //          This dataset is dynamic water velocities with output times
00720 //          in minutes.
00721 //          Dataset is for a mesh and so nActive is the number of elements
00722 //          which is not the same as the nValues which would be number of nodes
00723 // --------------------------------------------------------------------------
00724 int tdWriteVector2D_A (LPCSTR a_Filename, int a_Compression)
00725 {
00726   xid      xFileId, xDsetsId, xVectorA, xCoordId = NONE;
00727   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00728   double   dTime = 0.0;
00729   int      iTimestep, iActive;
00730   float    fValues[100*2]; // nValues*nComponents
00731   xmbool    bActivity[75]; // activity
00732 //  double   dMin = 0.5, dMax = 3.5;
00733 //  int      nSeedMultiplier = 138592;
00734   int      i, j, status;
00735   int      iHpgnZone;
00736 
00737   // 5th item in data set is always inactive, others active
00738   for (iActive = 0; iActive < nActive; iActive++) {
00739     if (iActive % 3 == 0) {
00740       bActivity[iActive] = XFALSE;
00741     }
00742     else {
00743       bActivity[iActive] = XTRUE;
00744     }
00745   }
00746 
00747   // create the file
00748   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00749   if (status < 0) {
00750     return FALSE;
00751   }
00752 
00753   // create the group to store all datasets 
00754   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00755   if (status < 0) {
00756     xfCloseFile(xFileId);
00757     return FALSE;
00758   }
00759 
00760   // Create the scalar A dataset group
00761   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_A_LOCATION, "ft/s",
00762                TS_SECONDS, a_Compression, &xVectorA);
00763   if (status < 0) {
00764     xfCloseGroup(xDsetsId);
00765     xfCloseFile(xFileId);
00766     return FALSE;
00767   }
00768 
00769   // Loop through timesteps adding them to the file
00770   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00771     // We will have an 0.5 hour timestep
00772     dTime = (iTimestep + 1) * 0.5;
00773 
00774     for (i = 0; i < nValues; i++) {
00775       for (j = 0; j < nComponents; j++) {
00776         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00777       }
00778     }
00779 //    // generate values array using random numbers between dMin and dMax
00780 //    tdiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
00781 //                    nValues*nComponents, fValues);
00782 
00783     // write the dataset array values
00784     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
00785                                    fValues);
00786     if (status >= 0) {
00787       // write activity array
00788       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
00789     }
00790     if (status < 0) {
00791       xfCloseGroup(xVectorA);
00792       xfCloseGroup(xDsetsId);
00793       xfCloseFile(xFileId);
00794     }
00795   }
00796 
00797   // Write Coordinate file - for Vector2D_A, we will set the coordinate system
00798   //   to be Geographic HPGN, with HPGN settings written to the file.
00799   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00800   if (status <= 0) {
00801     xfCloseGroup(xVectorA);
00802     xfCloseGroup(xDsetsId);
00803     xfCloseFile(xFileId);
00804         return -1;
00805   }
00806 
00807     // set HPGN info for test
00808   iHpgnZone = 29;      // Utah
00809 
00810   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00811   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00812   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00813   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00814 
00815     // write additional information
00816   xfSetHPGNArea(xCoordId, iHpgnZone);
00817 
00818   xfCloseGroup(xCoordId);
00819   xCoordId = 0;
00820 
00821   // close the dataset
00822   xfCloseGroup(xVectorA);
00823   xfCloseGroup(xDsetsId);
00824   xfCloseFile(xFileId);
00825 
00826   return FALSE;
00827 } // tdWriteVector2D_A
00828 // --------------------------------------------------------------------------
00829 // FUNCTION tdWriteVector2D_B
00830 // PURPOSE  Write 2D vector dataset to an HDF5 File
00831 // NOTES    This tests dynamic data sets, and activity
00832 //          Add reftime when it is completed
00833 //          This dataset is dynamic water velocities with output times
00834 //          in minutes.
00835 //          Dataset is for a mesh and so nActive is the number of elements
00836 //          which is not the same as the nValues which would be number of nodes
00837 // --------------------------------------------------------------------------
00838 int tdWriteVector2D_B (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00839 {
00840   xid      xFileId, xDsetsId, xVectorB, xCoordId = NONE;
00841   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00842   double   dTime = 0.0;
00843   int      iTimestep, iActive;
00844   float    fValues[100*2]; // nValues*nComponents
00845   xmbool    bActivity[75]; // activity
00846 //  double   dMin = 0.5, dMax = 3.5;
00847 //  int      nSeedMultiplier = 138592;
00848   int      i, j, status;
00849 
00850   // 5th item in data set is always inactive, others active
00851   for (iActive = 0; iActive < nActive; iActive++) {
00852     if (iActive % 3 == 0) {
00853       bActivity[iActive] = XFALSE;
00854     }
00855     else {
00856       bActivity[iActive] = XTRUE;
00857     }
00858   }
00859 
00860   if (a_Overwrite) {
00861       //open the already-existing file
00862     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00863     if (status < 0) {
00864       return -1;
00865     }
00866       // open the group where we have all the datasets
00867     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00868     if (status < 0) {
00869       xfCloseFile(xFileId);
00870       return -1;
00871     }
00872   }
00873   else {
00874       // create the file
00875     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00876     if (status < 0) {
00877       return FALSE;
00878     }
00879       // create the group to store all datasets 
00880     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00881     if (status < 0) {
00882       xfCloseFile(xFileId);
00883       return FALSE;
00884     }
00885   }
00886 
00887   // Create the Vector B dataset group
00888   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_B_LOCATION, "ft/s",
00889                TS_SECONDS, a_Compression, &xVectorB);
00890   if (status < 0) {
00891     xfCloseGroup(xDsetsId);
00892     xfCloseFile(xFileId);
00893     return FALSE;
00894   }
00895 
00896   if (!a_Overwrite) {
00897     // Loop through timesteps adding them to the file
00898     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00899       // We will have an 0.5 hour timestep
00900       dTime = (iTimestep + 1) * 0.5;
00901 
00902       for (i = 0; i < nValues; i++) {
00903         for (j = 0; j < nComponents; j++) {
00904           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00905         }
00906       }
00907 
00908       // write the dataset array values
00909       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
00910                                      fValues);
00911       if (status >= 0) {
00912         // write activity array
00913         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
00914       }
00915       if (status < 0) {
00916         xfCloseGroup(xVectorB);
00917         xfCloseGroup(xDsetsId);
00918         xfCloseFile(xFileId);
00919       }
00920     }
00921   }
00922   else {
00923     // Loop through timesteps adding them to the file
00924     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00925       // We will have an 1.5 hour timestep
00926       dTime = (iTimestep + 1) * 1.5;
00927 
00928       for (i = 0; i < nValues; i++) {
00929         for (j = 0; j < nComponents; j++) {
00930           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00931         }
00932       }
00933 
00934       // write the dataset array values
00935       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
00936                                      fValues);
00937       if (status >= 0) {
00938         // write activity array
00939         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
00940       }
00941       if (status < 0) {
00942         xfCloseGroup(xVectorB);
00943         xfCloseGroup(xDsetsId);
00944         xfCloseFile(xFileId);
00945       }
00946     }
00947   }
00948 
00949   // Write Coordinate file - for ScalarB, we will set the coordinate system
00950   //   to be UTM, with UTM Zone settings written to the file.
00951   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00952   if (status <= 0) {
00953     xfCloseGroup(xVectorB);
00954     xfCloseGroup(xDsetsId);
00955     xfCloseFile(xFileId);
00956         return -1;
00957   }
00958 
00959     // write the coordinate data to the file
00960   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00961   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00962   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00963   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00964 
00965     // write additional information - we'll use the max UTM zone for the test
00966   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00967 
00968   xfCloseGroup(xCoordId);
00969   xCoordId = 0;
00970 
00971   // close the dataset
00972   xfCloseGroup(xVectorB);
00973   xfCloseGroup(xDsetsId);
00974   xfCloseFile(xFileId);
00975 
00976   return 1;
00977 } // tdWriteVector2D_B
00978 // --------------------------------------------------------------------------
00979 // FUNCTION tdWriteVector2DAToMulti
00980 // PURPOSE  Write 2D vector dataset to an HDF5 File
00981 // NOTES    This tests dynamic data sets, and activity
00982 //          Add reftime when it is completed
00983 //          This dataset is dynamic water velocities with output times
00984 //          in minutes.
00985 //          Dataset is for a mesh and so nActive is the number of elements
00986 //          which is not the same as the nValues which would be number of nodes
00987 // --------------------------------------------------------------------------
00988 int tdWriteVector2DAToMulti (xid a_GroupId)
00989 {
00990   xid      xVectorA;
00991   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00992   double   dTime = 0.0;
00993   int      iTimestep, iActive;
00994   float    fValues[100*2]; // nValues*nComponents
00995   xmbool    bActivity[75]; // activity
00996 //  double   dMin = 0.5, dMax = 3.5;
00997 //  int      nSeedMultiplier = 138592;
00998   int      i, j, status;
00999 
01000   // 5th item in data set is always inactive, others active
01001   for (iActive = 0; iActive < nActive; iActive++) {
01002     if (iActive % 3 == 0) {
01003       bActivity[iActive] = XFALSE;
01004     }
01005     else {
01006       bActivity[iActive] = XTRUE;
01007     }
01008   }
01009 
01010   // Create the scalar A dataset group
01011   status = xfCreateVectorDataset(a_GroupId, VECTOR2D_A_LOCATION, "ft/s",
01012                TS_SECONDS, NONE, &xVectorA);
01013   if (status < 0) {
01014     return FALSE;
01015   }
01016 
01017   // Loop through timesteps adding them to the file
01018   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
01019     // We will have an 0.5 hour timestep
01020     dTime = (iTimestep + 1) * 0.5;
01021 
01022     for (i = 0; i < nValues; i++) {
01023       for (j = 0; j < nComponents; j++) {
01024         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
01025       }
01026     }
01027 //    // generate values array using random numbers between dMin and dMax
01028 //    tdiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
01029 //                    nValues*nComponents, fValues);
01030 
01031     // write the dataset array values
01032     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
01033                                    fValues);
01034     if (status >= 0) {
01035       // write activity array
01036       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
01037     }
01038     if (status < 0) {
01039       xfCloseGroup(xVectorA);
01040     }
01041   }
01042 
01043   // close the dataset
01044   xfCloseGroup(xVectorA);
01045 
01046   return FALSE;
01047 } // tdWriteVector2DAToMulti
01048 // --------------------------------------------------------------------------
01049 // FUNCTION tdiRandomNumberInRange
01050 // PURPOSE  generate Psuedo Random numbers.  We use the same seeds every
01051 //          time so we end up with consistent values for testing purposes.
01052 // --------------------------------------------------------------------------
01053 double tdiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed)
01054 {
01055   int nRandom;
01056   double dValue;
01057 
01058   srand(a_nSeed);
01059   nRandom = rand();
01060 
01061   dValue = a_dMin + ((double)(nRandom)*(a_dMax - a_dMin))/RAND_MAX;
01062 
01063   return dValue;
01064 } // tdiRandomNumberInRange
01065 // --------------------------------------------------------------------------
01066 // FUNCTION tdDatasetArray
01067 // PURPOSE  Get dataset data to use in a dataset
01068 // NOTES    Generates random numbers between a range to fill in the array
01069 // --------------------------------------------------------------------------
01070 void tdiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
01071                      int a_SeedMultiplier, int a_nValues, float *a_Array)
01072 {
01073   int       i, nSeedBase;
01074 
01075   for (i = 0; i < a_nValues; i++) {
01076     nSeedBase = a_nCycle*a_nValues + i;
01077     a_Array[i] = (float)tdiRandomNumberInRange(a_dMin, a_dMax, 
01078                                               nSeedBase*a_SeedMultiplier);
01079   }
01080 } // tdDatasetArray
01081 // --------------------------------------------------------------------------
01082 // FUNCTION tdiReadScalar
01083 // PURPOSE  Read a scalar from an XMDF file and output information to
01084 //          to a text file
01085 // NOTES    
01086 // --------------------------------------------------------------------------
01087 int tdiReadScalar (xid a_xScalarId, FILE *a_fp)
01088 {
01089   int    nTimes = NONE, nValues = NONE, nActive = NONE;
01090   int    nStatus = TRUE, iTime, iVal, iActive;
01091   char   TimeUnits[100], Units[100];
01092   double *Times = NULL;
01093   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01094   xmbool  *Active = NULL;
01095   xmbool  bUseReftime;
01096   double Reftime;
01097 
01098   // read the time units
01099   nStatus = xfGetDatasetTimeUnits(a_xScalarId, TimeUnits);
01100   if (nStatus < 0) {
01101     return nStatus;
01102   }
01103   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01104 
01105   // see if we are using a reftime
01106   nStatus = xfUseDatasetReftime(a_xScalarId, &bUseReftime);
01107   if (nStatus < 0) {
01108     return nStatus;
01109   }
01110   if (bUseReftime) {
01111     nStatus = xfReadDatasetReftime(a_xScalarId, &Reftime);
01112     if (nStatus < 0) {
01113       return nStatus;
01114     }
01115     fprintf(a_fp, "Reftime: %f\n", Reftime);
01116   }
01117 
01118   // read the units
01119   nStatus = xfGetDatasetUnits(a_xScalarId, Units);
01120   if (nStatus < 0) { 
01121     return nStatus;
01122   }
01123   fprintf(a_fp, "units: %s\n", Units);
01124 
01125   // read in the number of values and number of active values
01126   nStatus = xfGetDatasetNumVals(a_xScalarId, &nValues);
01127   if (nStatus >= 0) {
01128     nStatus = xfGetDatasetNumActive(a_xScalarId, &nActive);
01129   }
01130   if (nStatus < 0) {
01131     return nStatus;
01132   }
01133 
01134   if (nValues <= 0) {
01135     printf("No data to read in.");
01136     return -1;
01137   }
01138 
01139   // read in the number of times
01140   nStatus = xfGetDatasetNumTimes(a_xScalarId, &nTimes);
01141   if (nStatus < 0) {
01142     return nStatus;
01143   }
01144 
01145   // Read in the individual time values
01146   Times = (double *)malloc(nTimes*sizeof(double));
01147   if (Times == NULL) {
01148     printf("Out of memory");
01149     return -1;
01150   }
01151   nStatus = xfGetDatasetTimes(a_xScalarId, nTimes, Times);
01152   if (nStatus < 0) {
01153     return nStatus;
01154   }
01155 
01156   // Read in the minimum and maximum values
01157   Mins = (float *)malloc(nTimes*sizeof(float));
01158   Maxs = (float *)malloc(nTimes*sizeof(float));
01159   if (Mins == NULL || Maxs == NULL) {
01160     free(Times);
01161     printf("Out of memory");
01162     return -1;
01163   }
01164 
01165   nStatus = xfGetDatasetMins(a_xScalarId, nTimes, Mins);
01166   if (nStatus >= 0) {
01167     nStatus = xfGetDatasetMaxs(a_xScalarId, nTimes, Maxs);
01168   }
01169   if (nStatus < 0) {
01170     free(Times);
01171     free(Mins);
01172     free(Maxs);
01173     return nStatus;
01174   }
01175 
01176   Values = (float *)malloc(nValues*sizeof(float));
01177   if (nActive > 0) {
01178     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01179   }
01180 
01181   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01182   fprintf(a_fp, "Number Values: %d\n", nValues);
01183   fprintf(a_fp, "Number Active: %d\n", nActive);
01184 
01185   // loop through the timesteps, read the values and active values and write
01186   // them to the text file
01187   for (iTime = 0; iTime < nTimes; iTime++) {
01188       // indices should be 1 based
01189     nStatus = xfReadScalarValuesTimestep(a_xScalarId, iTime + 1,
01190                                          nValues, Values);
01191     if (nStatus >= 0 && nActive > 0) {
01192         // indices should be 1 based
01193       nStatus = xfReadActivityTimestep(a_xScalarId, iTime + 1, nActive, Active);
01194     }
01195 
01196     // Write the time, min, max, values and active values to the text output
01197     // file.
01198     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01199                   Times[iTime], Mins[iTime], Maxs[iTime]);
01200 
01201     fprintf(a_fp, "Values:\n");
01202     // print 5 values per line
01203     for (iVal = 0; iVal < nValues; iVal++) {
01204       fprintf(a_fp, "%6.3f ", Values[iVal]);
01205       if ((iVal + 1) % 5 == 0) {
01206         fprintf(a_fp, "\n");
01207       }
01208     }
01209     fprintf(a_fp, "\n");
01210 
01211     fprintf(a_fp, "Activity:\n");
01212     // print 5 values per line
01213     for (iActive = 0; iActive < nActive; iActive++) {
01214       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01215       if ((iActive + 1) % 5 == 0) {
01216         fprintf(a_fp, "\n");
01217       }
01218     }
01219     fprintf(a_fp, "\n\n");
01220   }
01221 
01222   if (Times) {
01223     free(Times);
01224     Times = NULL;
01225   }
01226   
01227   if (Mins) {
01228     free(Mins);
01229     Mins = NULL;
01230   }
01231 
01232   if (Maxs) {
01233     free(Maxs);
01234     Maxs = NULL;
01235   }
01236 
01237   if (Values) {
01238     free(Values);
01239     Values = NULL;
01240   }
01241 
01242   if (Active) {
01243     free(Active);
01244     Active = NULL;
01245   }
01246 
01247   return TRUE;
01248 } // tdiReadScalar
01249 // --------------------------------------------------------------------------
01250 // FUNCTION tdiReadVector
01251 // PURPOSE  Read a vector from an XMDF file and output information to
01252 //          to a text file
01253 // NOTES    
01254 // --------------------------------------------------------------------------
01255 int tdiReadVector (xid a_xVectorId, FILE *a_fp)
01256 {
01257   int    nTimes = NONE, nValues = NONE, nComponents = NONE, nActive = NONE;
01258   int    nStatus = TRUE, iTime, iVal, iActive;
01259   char   TimeUnits[100];
01260   double *Times = NULL;
01261   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01262   xmbool  *Active = NULL;
01263   xmbool  bUseReftime;
01264   double Reftime;
01265 
01266   // read the time units
01267   nStatus = xfGetDatasetTimeUnits(a_xVectorId, TimeUnits);
01268   if (nStatus < 0) {
01269     return nStatus;
01270   }
01271   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01272 
01273   // see if we are using a reftime
01274   nStatus = xfUseDatasetReftime(a_xVectorId, &bUseReftime);
01275   if (nStatus < 0) {
01276     return nStatus;
01277   }
01278   if (bUseReftime) {
01279     nStatus = xfReadDatasetReftime(a_xVectorId, &Reftime);
01280     if (nStatus < 0) {
01281       return nStatus;
01282     }
01283     fprintf(a_fp, "Reftime: %f", Reftime);
01284   }
01285 
01286   // read in the number of values and number of active values
01287   nStatus = xfGetDatasetNumVals(a_xVectorId, &nValues);
01288   if (nStatus >= 0) {
01289     nStatus = xfGetDatasetVecNumComponents(a_xVectorId, &nComponents);
01290     if (nStatus >= 0) {
01291       nStatus = xfGetDatasetNumActive(a_xVectorId, &nActive);
01292     }
01293   }
01294   if (nStatus < 0) {
01295     return nStatus;
01296   }
01297 
01298   if (nValues <= 0) {
01299     printf("No data to read in.");
01300     return -1;
01301   }
01302 
01303   // read in the number of times
01304   nStatus = xfGetDatasetNumTimes(a_xVectorId, &nTimes);
01305   if (nStatus < 0) {
01306     return nStatus;
01307   }
01308 
01309   // Read in the individual time values
01310   Times = (double *)malloc(nTimes*sizeof(double));
01311   if (Times == NULL) {
01312     printf("Out of memory");
01313     return -1;
01314   }
01315   nStatus = xfGetDatasetTimes(a_xVectorId, nTimes, Times);
01316   if (nStatus < 0) {
01317     return nStatus;
01318   }
01319 
01320   // Read in the minimum and maximum values
01321   Mins = (float *)malloc(nTimes*sizeof(float));
01322   Maxs = (float *)malloc(nTimes*sizeof(float));
01323   if (Mins == NULL || Maxs == NULL) {
01324     free(Times);
01325     printf("Out of memory");
01326     return -1;
01327   }
01328 
01329   nStatus = xfGetDatasetMins(a_xVectorId, nTimes, Mins);
01330   if (nStatus >= 0) {
01331     nStatus = xfGetDatasetMaxs(a_xVectorId, nTimes, Maxs);
01332   }
01333   if (nStatus < 0) {
01334     free(Times);
01335     free(Mins);
01336     free(Maxs);
01337     return nStatus;
01338   }
01339 
01340   Values = (float *)malloc(nValues*nComponents*sizeof(float));
01341   if (nActive > 0) {
01342     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01343   }
01344 
01345   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01346   fprintf(a_fp, "Number Values: %d\n", nValues);
01347   fprintf(a_fp, "Number Components: %d\n", nComponents);
01348   fprintf(a_fp, "Number Active: %d\n", nActive);
01349 
01350   // loop through the timesteps, read the values and active values and write
01351   // them to the text file
01352   for (iTime = 0; iTime < nTimes; iTime++) {
01353     nStatus = xfReadVectorValuesTimestep(a_xVectorId, iTime + 1,
01354                                          nValues, nComponents, Values);
01355     if (nStatus >= 0 && nActive > 0) {
01356       nStatus = xfReadActivityTimestep(a_xVectorId, iTime + 1, nActive, Active);
01357     }
01358 
01359     // Write the time, min, max, values and active values to the text output
01360     // file.
01361     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01362                   Times[iTime], Mins[iTime], Maxs[iTime]);
01363 
01364     fprintf(a_fp, "Values:\n");
01365     // print a set of vector values per line
01366     for (iVal = 0; iVal < nValues; iVal++) {
01367       fprintf(a_fp, "%6.3f %6.3f\n", Values[iVal*nComponents], 
01368                                      Values[(iVal*nComponents) + 1]);
01369     }
01370     fprintf(a_fp, "\n");
01371 
01372     fprintf(a_fp, "Activity:\n");
01373     // print 5 values per line
01374     for (iActive = 0; iActive < nActive; iActive++) {
01375       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01376       if ((iActive + 1) % 5 == 0) {
01377         fprintf(a_fp, "\n");
01378       }
01379     }
01380     fprintf(a_fp, "\n\n");
01381   }
01382 
01383   if (Times) {
01384     free(Times);
01385     Times = NULL;
01386   }
01387   
01388   if (Mins) {
01389     free(Mins);
01390     Mins = NULL;
01391   }
01392 
01393   if (Maxs) {
01394     free(Maxs);
01395     Maxs = NULL;
01396   }
01397 
01398   if (Values) {
01399     free(Values);
01400     Values = NULL;
01401   }
01402 
01403   if (Active) {
01404     free(Active);
01405     Active = NULL;
01406   }
01407 
01408   return TRUE;
01409 } // tdiReadVector
TestDatasets.cpp tests datasets
00001 #include "stdafx.h"
00002 #include <Xmdf.h>
00003 #include <stdio.h>
00004 #include <windows.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007 #include "TestGeomPaths.h"
00008 
00009 /* tmReadTestPaths */
00010 int tmReadTestPaths(LPCSTR Filename, LPCSTR OutFilename)
00011 {
00012   int         nGroups, nMaxPathLength, nDims, nPaths, nTimes, i, j;
00013   int         PathIndices[2];
00014   char       *Paths = NULL, *IndividualPath = NULL;
00015   double     *times, *locs, NullVal = 0;
00016   xid         xFileId = NONE, xGroupId = NONE;
00017   int         nStatus;
00018   FILE       *fp = NULL;
00019 
00020   // open the XMDF file 
00021   nStatus = xfOpenFile(Filename, &xFileId, TRUE);
00022   if (nStatus < 0) {
00023     printf("Unable to open XMDF file tmReadTestPaths.");
00024     return nStatus;
00025   }
00026 
00027   // open the Output file 
00028   fp = fopen(OutFilename, "w");
00029   if (fp == NULL) {
00030     printf("Unable to open output file tmReadTestPaths.");
00031     return nStatus;
00032   }
00033 
00034   // find the geomotric path groups
00035   // Get the number and paths of datasets in the file.
00036   nStatus = xfGetGroupPathsSizeForGeomPaths(xFileId, &nGroups,
00037                                                     &nMaxPathLength);
00038   if (nStatus >= 0) {
00039     Paths = (char *)malloc(nMaxPathLength*nGroups*sizeof(char));
00040     nStatus = xfGetGroupPathsForGeomPaths(xFileId, nGroups, 
00041                                          nMaxPathLength, Paths);
00042   }
00043   if (nStatus < 0) {
00044     xfCloseFile(xFileId);
00045     return -1;
00046   }
00047   // Report the number and paths to individual geom paths groups in the file.
00048   fprintf(fp, "Number of geometric paths in file: %d\n", nGroups);
00049   fprintf(fp, "Paths:\n");
00050   for (i = 0; i < nGroups; i++) {
00051     IndividualPath = &Paths[i*nMaxPathLength];  
00052     fprintf(fp, "  %s\n", IndividualPath);
00053   }
00054   fprintf(fp, "\n");
00055 
00056   // Open each geometric path group
00057   for (i = 0; i < nGroups; i++) {
00058     IndividualPath = &Paths[i*nMaxPathLength];  
00059     
00060     fprintf(fp, "Reading geom paths in group: %s\n", IndividualPath);
00061     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00062     if (nStatus >= 0) {
00063       // read the dimensionality of the paths
00064       nStatus = xfGetPathDimensionality(xGroupId, &nDims);
00065       if (nStatus >= 0) {
00066         fprintf(fp, "Group dimensionality: %d\n", nDims);
00067         // read the number of paths
00068         nStatus = xfGetNumberOfPaths(xGroupId, &nPaths);
00069         if (nStatus >= 0) {
00070           fprintf(fp, "Number of paths in group: %d\n", nPaths);
00071           // read the number of timesteps
00072           nStatus = xfGetNumberOfTimes(xGroupId, &nTimes);
00073           if (nStatus >= 0) {
00074             fprintf(fp, "Number of timesteps in group: %d\n", nTimes);
00075             // allocate times array
00076             times = (double *)malloc(nTimes*sizeof(double));
00077             if (times != NULL) {
00078               nStatus = xfGetPathTimesArray(xGroupId, nTimes, times);
00079               if (nStatus >= 0) {
00080                     // get space for the data location values
00081                 locs = (double *)malloc(nPaths*nDims*sizeof(double));
00082                 if (locs != NULL) {
00083                   // read null value 
00084                   nStatus = xfGetPathNullVal(xGroupId, &NullVal);
00085                   if (nStatus >= 0) {
00086                     fprintf(fp, "Null value: %lf\n", NullVal);
00087                     for (i=0; i<nTimes; ++i) {
00088                       fprintf(fp, "Timestep: %lf\n", times[i]);
00089                       // read the data for this timestep
00090                       nStatus = xfReadPathLocationsAtTime(xGroupId, i+1,
00091                                 1, nPaths, locs);
00092                       if (nStatus >= 0) {
00093                         // write  the data for this timestep
00094                         fprintf(fp, "  X        Y");
00095                         if (nDims == 3) {
00096                           fprintf(fp, "       Z");
00097                         }
00098                         fprintf(fp, "\n");
00099                         for (j=0; j<nPaths; ++j) {
00100                           if (locs[j*nDims] == NullVal) {
00101                             fprintf(fp, "Particle not active yet\n");
00102                           }
00103                           else {
00104                             fprintf(fp, "%lf %lf", locs[j*nDims],
00105                                     locs[j*nDims+1]);
00106                             if (nDims == 3) {
00107                               fprintf(fp, " %lf", locs[j*nDims+2]);
00108                             }
00109                             fprintf(fp, "\n");
00110                           }
00111                         } // Loop through the points
00112                       }
00113                     } // Loop through timesteps
00114                   }
00115                   free(locs);
00116                 }
00117                     // get space for the data location values - 1 particle 
00118                     // all times
00119                 locs = (double *)malloc(nTimes*nDims*sizeof(double));
00120                 if (locs != NULL) {
00121                   for (i=0; i<nPaths; ++i) {
00122                     // read the values for this particle for all timesteps
00123                     nStatus = xfReadPathLocationsForParticle(xGroupId, i+1, 
00124                                    1, nTimes, locs);
00125                     if (nStatus >= 0) {
00126                         // write  the data for this path
00127                       fprintf(fp, "Time       X        Y");
00128                       if (nDims == 3) {
00129                         fprintf(fp, "        Z");
00130                       }
00131                       fprintf(fp, "\n");
00132                       for (j=0; j<nTimes; ++j) {
00133                         if (locs[j*nDims] != NullVal) {
00134                           fprintf(fp, "%lf %lf %lf", times[j], locs[j*nDims],
00135                                   locs[j*nDims+1]);
00136                           if (nDims == 3) {
00137                             fprintf(fp, " %lf", locs[j*nDims+2]);
00138                           }
00139                           fprintf(fp, "\n");
00140                         }
00141                       } // Loop through the times
00142                     }
00143                   } // Loop through the paths
00144                   free(locs);
00145                 }
00146                     // get space for the data location values - 2 particle 
00147                     // all times
00148                 locs = (double *)malloc(nTimes*nDims*2*sizeof(double));
00149                 if (locs != NULL) {
00150                   PathIndices[0] = 1;
00151                   PathIndices[1] = nPaths;                
00152                   nStatus = xfReadPathLocationsForParticles(xGroupId, 2,
00153                               PathIndices, 1, nTimes, locs);
00154                   if (nStatus >= 0) {
00155                       // write  the data for these 2 paths
00156                     if (nDims == 3) {
00157                       fprintf(fp, "Timestep       X1        Y1        Z1        Xn        Yn        Zn\n");
00158                     }
00159                     else {
00160                       fprintf(fp, "Timestep       X1        Y1        Xn        Yn\n");
00161                     }
00162                     for (j=0; j<nTimes; ++j) {
00163                       if (nDims == 3) {
00164                         fprintf(fp, "%lf %lf %lf %lf %lf %lf %lf\n", times[j],
00165                              locs[j*2*nDims], locs[j*2*nDims+1],
00166                              locs[j*2*nDims+2], locs[j*2*nDims+3],
00167                              locs[j*2*nDims+4], locs[j*2*nDims+5]);
00168                       }
00169                       else {
00170                         fprintf(fp, "%lf %lf %lf %lf %lf\n", times[j],
00171                              locs[j*2*nDims], locs[j*2*nDims+1],
00172                              locs[j*2*nDims+2], locs[j*2*nDims+3]);
00173                       }
00174                     } // Loop through the times
00175                   }
00176                   free(locs);
00177                 }
00178               }
00179               free(times);
00180             }
00181           }
00182         }
00183       }
00184       xfCloseGroup(xGroupId);
00185     }
00186     if (nStatus < 0) {
00187       printf("Error reading geometric paths..\n");
00188     }
00189   }
00190     // free the paths
00191   if (Paths) {
00192     free(Paths);
00193     Paths = NULL;
00194   }
00195     // close the files
00196   fclose(fp);
00197   xfCloseFile(xFileId);
00198   return nStatus;
00199 } /* tmReadTestPaths */
00200 
00201 /* tmWriteTestPaths */
00202 int tmWriteTestPaths(LPCSTR Filename, int Compression)
00203 {
00204   int         nPaths = 0;
00205   double      pLocs[6];
00206   float       pSpeeds[2], NullVal = (float)-99999.9;
00207   xid         xFileId = NONE, xPathGroupId = NONE, xSpeedId = NONE,
00208               xPropGroupId = NONE;
00209   int         status;
00210 
00211   /* create the file */
00212   status = xfCreateFile(Filename, &xFileId, XTRUE);
00213   if (status < 0) {
00214     return FALSE;
00215   }
00216 
00217   /* create the group to store the particle paths */
00218   status = xfCreateGeometricPathGroup(xFileId, "particles",
00219                "abcdefglasdfjoaieur", Compression,
00220                &xPathGroupId, -99999.9);
00221   if (status < 0) {
00222     return FALSE;
00223   }
00224 
00225   /* create the data set to store the speed */
00226   status = xfCreateScalarDatasetExtendable(xPathGroupId, "Vmag", "m/s",
00227              TS_SECONDS, NullVal, Compression, &xSpeedId);
00228   if (status < 0) {
00229     return -1;
00230   }
00231 
00232   if (xfCreatePropertyGroup(xSpeedId, &xPropGroupId) < 0) {
00233     xfCloseGroup(xSpeedId);
00234     return -1;
00235   }
00236   xfWritePropertyFloat(xPropGroupId, PROP_NULL_VALUE, 1, &NullVal, -1);
00237   xfCloseGroup(xPropGroupId);
00238 
00239   // Setup the arrays for the path group at timestep 0 
00240     // particle location at the first timestep
00241   nPaths = 1;
00242   pLocs[0] = 1.0; pLocs[1] = 2.0; pLocs[2] = 3.0;
00243   
00244     // store the particles for the first timestep
00245   status = xfWriteParticleTimestep(xPathGroupId, 3, 0.0, nPaths, pLocs);
00246   if (status < 0) {
00247     return FALSE;
00248   }
00249     // set up and store the speed at timestep 0
00250   pSpeeds[0] = (float)(1.1);
00251   status = xfWriteScalarTimestep(xSpeedId, 0.0, 1, pSpeeds); 
00252   if (status < 0) {
00253     return FALSE;
00254   }
00255 
00256   // Setup the arrays for the path group at timestep 1 
00257     // particle location at the first timestep
00258   pLocs[0] = 4.0; pLocs[1] = 5.0; pLocs[2] = 6.0;
00259   
00260     // store the particles for the first timestep
00261   status = xfWriteParticleTimestep(xPathGroupId, 3, 1.0, nPaths, pLocs);
00262   if (status < 0) {
00263     return FALSE;
00264   }
00265   
00266     // set up and store the speed at timestep 1
00267   pSpeeds[0] = (float)(1.2);
00268   status = xfWriteScalarTimestep(xSpeedId, 1.0, 1, pSpeeds); 
00269   if (status < 0) {
00270     return FALSE;
00271   }
00272 
00273   // Setup the arrays for the path group at timestep 2-add a particle
00274     // particle location at the first timestep
00275   nPaths = 2;
00276   pLocs[0] = 7.0;  pLocs[1] = 8.0;  pLocs[2] = 9.0;
00277   pLocs[3] = -1.0; pLocs[4] = -2.0; pLocs[5] = -3.0;
00278   
00279     // store the particles for the timestep 2
00280   status = xfWriteParticleTimestep(xPathGroupId, 3, 2.0, nPaths, pLocs);
00281   if (status < 0) {
00282     return FALSE;
00283   }
00284 
00285     // extend the data set for speed
00286   status = xfExtendScalarDataset(xSpeedId, 2);
00287   if (status < 0) {
00288     return FALSE;
00289   }
00290 
00291     // set up and store the speed at timestep 2
00292   pSpeeds[0] = (float)1.3;
00293   pSpeeds[1] = (float)2.1;
00294   status = xfWriteScalarTimestep(xSpeedId, 2.0, 2, pSpeeds); 
00295   if (status < 0) {
00296     return FALSE;
00297   }
00298 
00299   // Setup the arrays for the path group at timestep 3-inactive particle(static)
00300     // particle location at the first timestep
00301   pLocs[0] = 7.0;  pLocs[1] = 8.0;  pLocs[2] = 9.0;
00302   pLocs[3] = -4.0; pLocs[4] = -5.0; pLocs[5] = -6.0;
00303   
00304     // store the particles for timestep 3
00305   status = xfWriteParticleTimestep(xPathGroupId, 3, 3.0, nPaths, pLocs);
00306   if (status < 0) {
00307     return FALSE;
00308   }
00309 
00310     // set up and store the speed at timestep 3
00311   pSpeeds[0] = NullVal;
00312   pSpeeds[1] = (float)2.2;
00313   status = xfWriteScalarTimestep(xSpeedId, 3.0, 2, pSpeeds); 
00314   if (status < 0) {
00315     return FALSE;
00316   }
00317 
00318   // close the resources
00319   xfCloseGroup(xSpeedId);
00320   xfCloseGroup(xPathGroupId);
00321   xfCloseFile(xFileId);
00322 
00323   return TRUE;
00324 }
TestGeomPaths.cpp tests geometry paths
00001 #include "stdafx.h"
00002 #include <Xmdf.h>
00003 #include <stdio.h>
00004 #include <windows.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007 
00008 #define GRID_CART2D_GROUP_NAME "Grid Cart2D Group"
00009 #define GRID_CURV2D_GROUP_NAME "Grid Curv2D Group"
00010 #define GRID_CART3D_GROUP_NAME "Grid Cart3D Group"
00011 // ---------------------------------------------------------------------------
00012 // FUNCTION  tgReadGrid
00013 // PURPOSE   Read a grid and write data to a text file
00014 // NOTES     
00015 // ---------------------------------------------------------------------------
00016 int tgReadGrid (xid a_Id, FILE *a_Outfile)
00017 {
00018   int      nGridType = 0, nExtrudeType = 0, nDims = 0, nCellsI = 0, nCellsJ = 0;
00019   int      nCellsK = 0, nLayers = 0, nOrientation = 0, nValsI = 0, nValsJ = 0;
00020   int      nValsK = 0, nExtrudeVals = 0, nCompOrigin = 1, nUDir = 1;
00021   char     strGridType[256], strExtrudeType[256];
00022   xmbool    bDefined = XFALSE;
00023   double   dOrigin[3], dBearing = 0.0, dDip = 0.0, dRoll =0.0;
00024   double  *dExtrudeVals = NULL, *dCoordI = NULL, *dCoordJ = NULL;
00025   double  *dCoordK = NULL;
00026   int      i = 0, error = 1;
00027 
00028   // Grid type
00029   error = xfGetGridType(a_Id, &nGridType);
00030   if (error < 0) {
00031     return error;
00032   }
00033   switch (nGridType) {
00034     case GRID_TYPE_CARTESIAN:
00035       strcpy(strGridType, "Cartesian");
00036       break;
00037     case GRID_TYPE_CURVILINEAR:
00038       strcpy(strGridType, "Curvilinear");
00039       break;
00040     case GRID_TYPE_CARTESIAN_EXTRUDED:
00041       strcpy(strGridType, "Cartesian extruded");
00042       break;
00043     case GRID_TYPE_CURVILINEAR_EXTRUDED:
00044       strcpy(strGridType, "Curvilinear extruded");
00045       break;
00046     default:
00047       printf("Invalid grid type.");
00048       return -1;
00049       break;
00050   }
00051   fprintf(a_Outfile, "The grid type is: %s\n", strGridType);
00052 
00053   // Number of dimensions
00054   error = xfGetNumberOfDimensions(a_Id, &nDims);
00055   if (error < 0) {
00056     return error;
00057   }
00058   if (nDims == 2) {
00059     fprintf(a_Outfile, "The grid is two-dimensional\n");
00060   }
00061   else if (nDims == 3) {
00062     fprintf(a_Outfile, "The grid is three-dimensional\n");
00063   }
00064   else {
00065     printf("The grid dimensions are invalid.");
00066     return -1;
00067   }
00068 
00069   // Extrusion type if applicable
00070   if (nGridType == GRID_TYPE_CARTESIAN_EXTRUDED ||
00071       nGridType == GRID_TYPE_CURVILINEAR_EXTRUDED) {
00072     error = xfGetExtrusionType(a_Id, &nExtrudeType);
00073     if (error < 0) {
00074       return error;
00075     }
00076     switch(nExtrudeType) {
00077       case EXTRUDE_SIGMA:
00078         strcpy(strExtrudeType, "Sigma stretch");
00079         break;
00080       case EXTRUDE_CARTESIAN:
00081         strcpy(strExtrudeType, "Cartesian");
00082         break;
00083       case EXTRUDE_CURV_AT_CORNERS:
00084         strcpy(strExtrudeType, "Curvilinear at Corners");
00085         break;
00086       case EXTRUDE_CURV_AT_CELLS:
00087         strcpy(strExtrudeType, "Curvilinear at Cells");
00088         break;
00089     }
00090     fprintf(a_Outfile, "The grid is extruding using: %s\n", strExtrudeType);
00091   }
00092 
00093   // Origin
00094   error = xfOriginDefined(a_Id, &bDefined);
00095   if (error < 0) {
00096     return error;
00097   }
00098   if (bDefined) {
00099     error = xfGetOrigin(a_Id, &dOrigin[0], &dOrigin[1], &dOrigin[2]);
00100     if (error < 0) {
00101       return error;
00102     }
00103     fprintf(a_Outfile, "The grid origin is %lf %lf %lf\n", dOrigin[0], 
00104                        dOrigin[1], dOrigin[2]);
00105   }
00106   
00107   // Orientation
00108   error = xfGetOrientation(a_Id, &nOrientation);
00109   if (error < 0) {
00110     return error;
00111   }
00112   if (nOrientation == ORIENTATION_RIGHT_HAND) {
00113     fprintf(a_Outfile, "The grid has a right hand orientation\n");
00114   }
00115   else if (nOrientation == ORIENTATION_LEFT_HAND) {
00116     fprintf(a_Outfile, "The grid has a left hand orientation\n");
00117   }
00118   else {
00119     printf("Invalid grid orientation.");
00120     return -1;
00121   }
00122 
00123   // Bearing
00124   error = xfBearingDefined(a_Id, &bDefined);
00125   if (error < 0) {
00126     return error;
00127   }
00128   if (bDefined) {
00129     error = xfGetBearing(a_Id, &dBearing);
00130     if (error < 0) {
00131       return error;
00132     }
00133     fprintf(a_Outfile, "The grid bearing is %lf\n", dBearing);
00134   }
00135 
00136   // Dip
00137   error = xfDipDefined(a_Id, &bDefined);
00138   if (error < 0) {
00139     return error;
00140   }
00141   if (bDefined) {
00142     error = xfGetDip(a_Id, &dDip);
00143     if (error < 0) {
00144       return error;
00145     }
00146     fprintf(a_Outfile, "The grid Dip is %lf\n", dDip);
00147   }
00148 
00149   if (nDims == 3) {
00150     // Roll
00151     error = xfRollDefined(a_Id, &bDefined);
00152     if (error < 0) {
00153       return error;
00154     }
00155     if (bDefined) {
00156       error = xfGetRoll(a_Id, &dRoll);
00157       if (error < 0) {
00158         return error;
00159       }
00160       fprintf(a_Outfile, "The grid Roll is %lf\n", dRoll);
00161     }
00162   }
00163   // Computational origin
00164   error = xfComputationalOriginDefined(a_Id, &bDefined);
00165   if (error < 0) {
00166     return error;
00167   }
00168   if (bDefined) {
00169     error = xfGetComputationalOrigin(a_Id, &nCompOrigin);
00170     if (error < 0) {
00171       return error;
00172     }
00173     fprintf(a_Outfile, "The grid Computational Origin is %d\n", nCompOrigin);
00174   }
00175   else {
00176     fprintf(a_Outfile, "The grid Computational Origin is not defined\n");
00177   }
00178 
00179 
00180   // U Direction
00181   error = xfGetUDirectionDefined(a_Id, &bDefined);
00182   if (error < 0) {
00183     return error;
00184   }
00185   if (bDefined) {
00186     error = xfGetUDirection(a_Id, &nUDir);
00187     if (error < 0) {
00188       return error;
00189     }
00190     fprintf(a_Outfile, "The grid U Direction is %d\n", nUDir);
00191   }
00192   else {
00193     fprintf(a_Outfile, "The grid U Direction is not defined\n");
00194   }
00195 
00196 
00197   // number of cells in each direction
00198   error = xfGetNumberCellsInI(a_Id, &nCellsI);
00199   if (error >= 0) {
00200     error = xfGetNumberCellsInJ(a_Id, &nCellsJ);
00201     if (error >= 0 && nDims == 3) { 
00202       error = xfGetNumberCellsInK(a_Id, &nCellsK);
00203     }
00204   }
00205   if (error < 0) {
00206     return error;
00207   }
00208   fprintf(a_Outfile, "Number of cells in I %d\n", nCellsI);
00209   fprintf(a_Outfile, "Number of cells in J %d\n", nCellsJ);
00210   if (nDims == 3) {
00211     fprintf(a_Outfile, "Number of cells in K %d\n", nCellsK);
00212   }
00213 
00214   // Grid coordinates
00215   switch (nGridType) {
00216     case GRID_TYPE_CARTESIAN:
00217     case GRID_TYPE_CARTESIAN_EXTRUDED:
00218       nValsI = nCellsI;
00219       nValsJ = nCellsJ;
00220       if (nDims == 3) {
00221         nValsK = nCellsK;
00222       }
00223       break;
00224     case GRID_TYPE_CURVILINEAR:
00225     case GRID_TYPE_CURVILINEAR_EXTRUDED:
00226       if (nDims == 3) {
00227         // three dimensions
00228         nValsI = nValsJ = nValsK = (nCellsI + 1) * (nCellsJ + 1) *(nCellsK + 1);
00229       }
00230       else {
00231         // two dimensions
00232         nValsI = nValsJ = (nCellsI + 1) * (nCellsJ + 1);
00233       }
00234       break;
00235     default:
00236       printf("Invalid grid type.");
00237       return -1;
00238       break;
00239   }
00240 
00241   dCoordI = new double[nValsI];
00242   dCoordJ = new double[nValsJ];
00243   if (nDims == 3) {
00244     dCoordK = new double[nValsK];
00245   }
00246 
00247   error = xfGetGridCoordsI(a_Id, nValsI, dCoordI);
00248   if (error >= 0) {
00249     error = xfGetGridCoordsJ(a_Id, nValsJ, dCoordJ);
00250     if (error >= 0 && nDims == 3) {
00251       error = xfGetGridCoordsK(a_Id, nValsK, dCoordK);
00252     }
00253   }
00254   if (error < 0) {
00255     printf("Error reading coordinates.\n");
00256     return -1;
00257   }
00258 
00259   fprintf(a_Outfile, "The Coordinates in direction I:\n");
00260   for (i = 0; i < nValsI; i++) {
00261     if ((i + 1) % 5 == 0) {
00262       fprintf(a_Outfile, "\n");
00263     }
00264     fprintf(a_Outfile, "%lf ", dCoordI[i]);
00265   }
00266   fprintf(a_Outfile, "\n");
00267 
00268   fprintf(a_Outfile, "The Coordinates in direction J:\n");
00269   for (i = 0; i < nValsJ; i++) {
00270     if ((i + 1) % 5 == 0) {
00271       fprintf(a_Outfile, "\n");
00272     }
00273     fprintf(a_Outfile, "%lf ", dCoordJ[i]);
00274   }
00275   fprintf(a_Outfile, "\n");
00276 
00277   if (nDims == 3) {
00278     fprintf(a_Outfile, "The Coordinates in direction K:\n");
00279     for (i = 0; i < nValsK; i++) {
00280       if ((i + 1) % 5 == 0) {
00281         fprintf(a_Outfile, "\n");
00282       }
00283       fprintf(a_Outfile, "%lf ", dCoordK[i]);
00284     }
00285   }
00286   fprintf(a_Outfile, "\n");
00287 
00288   if (dCoordI) {
00289     delete dCoordI;
00290   }
00291   if (dCoordJ) {
00292     delete dCoordJ;
00293   }
00294   if (dCoordK) {
00295     delete dCoordK;
00296   }
00297 
00298   // Extrude data
00299   if (nGridType == GRID_TYPE_CARTESIAN_EXTRUDED ||
00300       nGridType == GRID_TYPE_CURVILINEAR_EXTRUDED) {
00301     error = xfGetExtrudeNumLayers(a_Id, &nLayers);
00302     if (error < 0) {
00303       return error;
00304     }
00305 
00306     switch(nExtrudeType) {
00307       case EXTRUDE_SIGMA:
00308         nExtrudeVals = nLayers;
00309         break;
00310 
00311       case EXTRUDE_CURV_AT_CORNERS:
00312         nExtrudeVals = (nCellsI + 1) * (nCellsJ + 1) * nLayers;
00313         break;
00314       
00315       case EXTRUDE_CURV_AT_CELLS:
00316         nExtrudeVals = nCellsI * nCellsJ * nLayers;
00317         break;
00318     }
00319     dExtrudeVals = new double[nExtrudeVals];
00320 
00321     error = xfGetExtrudeValues(a_Id, nExtrudeVals, dExtrudeVals);
00322     if (error < 0) {
00323       return error;
00324     }
00325 
00326     printf("The extrude values are:\n");
00327     for (i = 0; i < nExtrudeVals; i++) {
00328       if ((i + 1) % 5 == 0) {
00329         fprintf(a_Outfile, "\n");
00330       }
00331       fprintf(a_Outfile, "%lf ", dExtrudeVals[i]);
00332     }
00333 
00334     if (dExtrudeVals) {
00335       delete dExtrudeVals;
00336     }
00337   }
00338 
00339   return error;
00340 } // tgReadGrid
00341 //////////////////////////////////////////////////////////////////////////////
00342 // FUNCTION   tgWriteTestGridCart2D
00343 // PURPOSE    Write a file that contains data for a 2D Cartesian Grid
00344 // NOTES      A picture of the grid is in the file (TestGridCart2D.gif)
00345 //            returns TRUE on success and FALSE on failure
00346 //////////////////////////////////////////////////////////////////////////////
00347 int tgWriteTestGridCart2D(LPCSTR Filename, int Compression)
00348 {
00349   int         nDimensions = 2;
00350   int         nCellsI = 5, nCellsJ = 5;
00351   int         nGridType = GRID_TYPE_CARTESIAN;
00352   int         nCompOrigin = 4, nUDir = -2;
00353   double      dOriginX = 10.0, dOriginY = 10.0, dOriginZ = 0.0;
00354   int         nOrientation = ORIENTATION_RIGHT_HAND;
00355   double      dBearing = 45.0;
00356   double      PlanesI[5], PlanesJ[5];
00357   int         i, j, iSpcZone;
00358   xid         xFileId = NONE, xGridId = NONE, xCoordId = NONE;
00359   int         status;
00360 
00361   // Fill in the grid plane data with a constant size of 30
00362   for (i = 1; i <= nCellsI; i++) {
00363     PlanesI[i - 1] = (double)i*30.0;
00364   }
00365   for (j = 1; j <= nCellsJ; j++) {
00366     PlanesJ[j - 1] = (double)j*30.0;
00367   }
00368   
00369   // create the file
00370   status = xfCreateFile(Filename, &xFileId, XTRUE);
00371   if (status < 0) {
00372     return FALSE;
00373   }
00374 
00375   // create the group to store the grid
00376   status = xfCreateGroupForGrid(xFileId, GRID_CART2D_GROUP_NAME, &xGridId);
00377   if (status < 0) {
00378     xfCloseFile(xFileId);
00379     return FALSE;
00380   }
00381 
00382   // Write the grid information to the file
00383   if (xfSetGridType(xGridId, nGridType) < 0 ||
00384       xfSetNumberOfDimensions(xGridId, nDimensions) < 0) {
00385     xfCloseGroup(xGridId);
00386     xfCloseFile(xFileId);
00387     return FALSE;
00388   }
00389 
00390   // set origin and orientation
00391   if (xfSetOrigin(xGridId, dOriginX, dOriginY, dOriginZ) < 0 ||
00392       xfSetOrientation(xGridId, nOrientation) < 0 ) {
00393     xfCloseGroup(xGridId);
00394     xfCloseFile(xFileId);
00395     return FALSE;
00396   }
00397  
00398   // Set bearing
00399   if (xfSetBearing(xGridId, dBearing) < 0) {
00400     xfCloseGroup(xGridId);
00401     xfCloseFile(xFileId);
00402     return FALSE;
00403   }
00404 
00405   // Set computational origin
00406   if (xfSetComputationalOrigin(xGridId, nCompOrigin) < 0) {
00407     xfCloseGroup(xGridId);
00408     xfCloseFile(xFileId);
00409     return FALSE;
00410   }
00411 
00412   // Set u direction
00413   if (xfSetUDirection(xGridId, nUDir) < 0) {
00414     xfCloseGroup(xGridId);
00415     xfCloseFile(xFileId);
00416     return FALSE;
00417   }
00418 
00419   // Write the grid geometry to the file
00420   // Set the number of cells in each direction
00421   if (xfSetNumberCellsInI(xGridId, nCellsI) < 0 ||
00422       xfSetNumberCellsInJ(xGridId, nCellsJ) < 0) {
00423     xfCloseGroup(xGridId);
00424     xfCloseFile(xFileId);
00425     return FALSE;
00426   }
00427 
00428   // Set the grid plane locations
00429   if (xfSetGridCoordsI(xGridId, nCellsI, PlanesI) < 0 ||
00430       xfSetGridCoordsJ(xGridId, nCellsJ, PlanesJ) < 0) {
00431     xfCloseGroup(xGridId);
00432     xfCloseFile(xFileId);
00433     return FALSE;
00434   }
00435 
00436   // Write Coordinate file - for GridCart2D, we will set the coordinate system
00437   //   to be State Plane NAD27.
00438   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00439   if (status <= 0) {
00440     xfCloseGroup(xGridId);
00441     xfCloseFile(xFileId);
00442         return -1;
00443   }
00444 
00445   iSpcZone = 3601; // Oregon North
00446 
00447   xfSetHorizDatum(xCoordId, HORIZ_DATUM_STATE_PLANE_NAD27);
00448   xfSetHorizUnits(xCoordId, COORD_UNITS_US_FEET);
00449 
00450   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00451   xfSetVertUnits(xCoordId, COORD_UNITS_US_FEET);
00452 
00453     // write additional information
00454   xfSetSPCZone(xCoordId, iSpcZone);
00455 
00456   xfCloseGroup(xCoordId);
00457   xCoordId = 0;
00458 
00459   // release memory
00460   xfCloseGroup(xGridId);
00461   xfCloseFile(xFileId);
00462   return TRUE;
00463 } // tgWriteTestGridCart2D
00464 //////////////////////////////////////////////////////////////////////////////
00465 // FUNCTION   tgWriteTestGridCurv2D
00466 // PURPOSE    Write a file that contains data for a 2D Curvilinear Grid
00467 // NOTES      A picture of the grid is TestGridCurv2D.gif
00468 //            returns TRUE on success and FALSE on failure
00469 //////////////////////////////////////////////////////////////////////////////
00470 int tgWriteTestGridCurv2D(LPCSTR Filename, int Compression)
00471 {
00472   int         nDimensions = 2;
00473   int         nCompOrigin = 1, nUDir = 1;
00474   int         nCellsI = 2, nCellsJ = 3;
00475   int         nCells = nCellsI*nCellsJ;
00476   int         nCorners = (nCellsI + 1)*(nCellsJ + 1);
00477   int         nGridType = GRID_TYPE_CURVILINEAR, i;
00478   double      xVals[16], yVals[16]; // 16 is the number of corners
00479   double      dCppLat, dCppLon;
00480   xid         xFileId = NONE, xGridId = NONE, xPropId = NONE,
00481               xDatasetsId = NONE, xScalarId = NONE, xCoordId = NONE;
00482   double      dNullValue = -999.0;
00483   int         nOrientation = ORIENTATION_RIGHT_HAND;
00484   float       fDsetCellVals[6]; // for cell-centered dataset
00485   float       fDsetCornerVals[12]; // for corner-centered dataset
00486   xmbool       bDsetCellActive[6];
00487   xmbool       bDsetCornerActive[12];
00488   int         status;
00489 
00490   // There is no cell in the top right corner so we have a NullValue for
00491   // the top right corner
00492 
00493   // xValues row by row
00494   xVals[0] = 0.0; xVals[1] = 7.5; xVals[2] = 15.0;
00495   xVals[3] = 2.5; xVals[4] = 10.0; xVals[5] = 17.5;
00496   xVals[6] = 3.5; xVals[7] = 11.0; xVals[8] = 18.5;
00497   xVals[9] = 0.0; xVals[10] = 7.5; xVals[11] = dNullValue;
00498 
00499   // yValues row by row
00500   yVals[0] = 0.0; yVals[1] = 0.0; yVals[2] = 0.0;
00501   yVals[3] = 10.0; yVals[4] = 10.0; yVals[5] = 10.0;
00502   yVals[6] = 20.0; yVals[7] = 20.0; yVals[8] = 20.0;
00503   yVals[9] = 30.0; yVals[10] = 30.0; yVals[11] = dNullValue;
00504 
00505   // cell centered velocity dataset values
00506   fDsetCellVals[0] = (float)2.1; fDsetCellVals[1] = (float)2.0;
00507   fDsetCellVals[2] = (float)1.9; fDsetCellVals[3] = (float)2.3;
00508   fDsetCellVals[4] = (float)2.5; fDsetCellVals[5] = (float)dNullValue;
00509   // all are active except the last value
00510   for (i = 0; i < nCells; i++) {
00511     bDsetCellActive[i] = XTRUE;
00512   }
00513   bDsetCellActive[nCells - 1] = XFALSE;
00514 
00515   // corner centered elevation dataset values
00516   fDsetCornerVals[0] = (float)1.0; fDsetCornerVals[1] = (float)0.8; 
00517   fDsetCornerVals[2] = (float)1.2;
00518   fDsetCornerVals[3] = (float)1.4; fDsetCornerVals[4] = (float)1.8;
00519   fDsetCornerVals[5] = (float)2.2;
00520   fDsetCornerVals[6] = (float)1.8; fDsetCornerVals[7] = (float)1.4;
00521   fDsetCornerVals[8] = (float)2.0;
00522   fDsetCornerVals[9] = (float)1.0; fDsetCornerVals[10] = (float)1.8;
00523   fDsetCornerVals[11] = (float)2.2;
00524   // all are active except the last value
00525   for (i = 0; i < nCorners; i++) {
00526     bDsetCornerActive[i] = XTRUE;
00527   }
00528   bDsetCornerActive[nCorners - 1] = XFALSE;
00529 
00530   // create the file
00531   status = xfCreateFile(Filename, &xFileId, XTRUE);
00532   if (status < 0) {
00533     return FALSE;
00534   }
00535 
00536   // create the group to store the grid
00537   status = xfCreateGroupForGrid(xFileId, GRID_CURV2D_GROUP_NAME, &xGridId);
00538   if (status < 0) {
00539     xfCloseFile(xFileId);
00540     return FALSE;
00541   }
00542 
00543   // Write the grid information to the file
00544   if (xfSetGridType(xGridId, nGridType) < 0 ||
00545       xfSetNumberOfDimensions(xGridId, nDimensions) < 0) {
00546     xfCloseGroup(xGridId);
00547     xfCloseFile(xFileId);
00548     return FALSE;
00549   }
00550 
00551   // set orientation
00552   if (xfSetOrientation(xGridId, nOrientation) < 0 ) {
00553     xfCloseGroup(xGridId);
00554     xfCloseFile(xFileId);
00555     return FALSE;
00556   }
00557 
00558   // Set computational origin
00559   if (xfSetComputationalOrigin(xGridId, nCompOrigin) < 0) {
00560     xfCloseGroup(xGridId);
00561     xfCloseFile(xFileId);
00562     return FALSE;
00563   }
00564 
00565   // Set u direction
00566   if (xfSetUDirection(xGridId, nUDir) < 0) {
00567     xfCloseGroup(xGridId);
00568     xfCloseFile(xFileId);
00569     return FALSE;
00570   }
00571 
00572   // Write the grid geometry to the file
00573   // Set the number of cells in each direction
00574   if (xfSetNumberCellsInI(xGridId, nCellsI) < 0 ||
00575       xfSetNumberCellsInJ(xGridId, nCellsJ) < 0) {
00576     xfCloseGroup(xGridId);
00577     xfCloseFile(xFileId);
00578     return FALSE;
00579   }
00580 
00581   // Set a NullValue.  This is used to identify locations in the grid that are
00582   // not being used.  In our case no geometry is defined for the top right
00583   // corner.
00584   if (xfCreateGridPropertyGroup(xGridId, &xPropId) < 0) {
00585     xfCloseGroup(xGridId);
00586     xfCloseFile(xFileId);
00587     return FALSE;
00588   }
00589 
00590   if (xfWritePropertyDouble(xPropId, PROP_NULL_VALUE, 1, &dNullValue, NONE) < 0){
00591     xfCloseGroup(xPropId);
00592     xfCloseGroup(xGridId);
00593     xfCloseFile(xFileId);
00594     return FALSE;
00595   }
00596   xfCloseGroup(xPropId);
00597 
00598   // Set the grid plane locations
00599   if (xfSetGridCoordsI(xGridId, nCorners, xVals) < 0 ||
00600       xfSetGridCoordsJ(xGridId, nCorners, yVals) < 0) {
00601     xfCloseGroup(xGridId);
00602     xfCloseFile(xFileId);
00603     return FALSE;
00604   }
00605 
00606   // Create the datasets group
00607   if (xfCreateGenericGroup(xGridId, "Datasets", &xDatasetsId) < 0) {
00608     xfCloseGroup(xGridId);
00609     xfCloseFile(xFileId);
00610     return FALSE;
00611   }
00612 
00613   // Create the cell-centered dataset
00614   if (xfCreateScalarDataset(xDatasetsId, "Velocity Mag",  "ft/s", TS_MINUTES,
00615                             Compression, &xScalarId) < 0) {
00616     xfCloseGroup(xDatasetsId);
00617     xfCloseGroup(xGridId);
00618     xfCloseFile(xFileId);
00619     return FALSE;
00620   }
00621 
00622   // specify that the dataset is cell-centered
00623   if (xfScalarDataLocation(xScalarId, GRID_LOC_CENTER) < 0) {
00624     xfCloseGroup(xScalarId);
00625     xfCloseGroup(xDatasetsId);
00626     xfCloseGroup(xGridId);
00627     xfCloseFile(xFileId);
00628     return FALSE;
00629   }
00630 
00631   // Write the data
00632   if (xfWriteScalarTimestep(xScalarId, 0.0, nCells, fDsetCellVals) < 0 ||
00633       xfWriteActivityTimestep(xScalarId, nCells, bDsetCellActive) < 0) {
00634     xfCloseGroup(xScalarId);
00635     xfCloseGroup(xDatasetsId);
00636     xfCloseGroup(xGridId);
00637     xfCloseFile(xFileId);
00638     return FALSE;
00639   }
00640 
00641   // close the cell-centered dataset
00642   xfCloseGroup(xScalarId);
00643 
00644   // Create the corner-centered dataset
00645   if (xfCreateScalarDataset(xDatasetsId, "elevation",  "ft", TS_MINUTES,
00646                             Compression, &xScalarId) < 0) {
00647     xfCloseGroup(xDatasetsId);
00648     xfCloseGroup(xGridId);
00649     xfCloseFile(xFileId);
00650     return FALSE;
00651   }
00652 
00653   // specify that the dataset is corner-centered
00654   if (xfScalarDataLocation(xScalarId, GRID_LOC_CORNER) < 0) {
00655     xfCloseGroup(xScalarId);
00656     xfCloseGroup(xDatasetsId);
00657     xfCloseGroup(xGridId);
00658     xfCloseFile(xFileId);
00659     return FALSE;
00660   }
00661 
00662   // Write the data
00663   if (xfWriteScalarTimestep(xScalarId, 0.0, nCorners, fDsetCornerVals) < 0 ||
00664       xfWriteActivityTimestep(xScalarId, nCorners, bDsetCornerActive) < 0){
00665     xfCloseGroup(xScalarId);
00666     xfCloseGroup(xDatasetsId);
00667     xfCloseGroup(xGridId);
00668     xfCloseFile(xFileId);
00669     return FALSE;
00670   }
00671 
00672   // Write Coordinate file - for GridCurv2D, we will set the coordinate system
00673   //   to be CPP, with CPP Latitude and CPP Longitude settings written 
00674   //   to the file.
00675   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00676   if (status <= 0) {
00677     xfCloseGroup(xScalarId);
00678     xfCloseGroup(xDatasetsId);
00679     xfCloseGroup(xGridId);
00680     xfCloseFile(xFileId);
00681           return -1;
00682   }
00683 
00684   dCppLat = 56.0;   // Made-up value
00685   dCppLon = 23.0;   // Made-up value
00686 
00687   xfSetHorizDatum(xCoordId, HORIZ_DATUM_CPP);
00688   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00689 
00690   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00691   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00692 
00693     // write additional information
00694   xfSetCPPLat(xCoordId, dCppLat);
00695   xfSetCPPLon(xCoordId, dCppLon);
00696 
00697   xfCloseGroup(xCoordId);
00698   xCoordId = 0;
00699 
00700   // release memory
00701   xfCloseGroup(xScalarId);
00702   xfCloseGroup(xDatasetsId);
00703   xfCloseGroup(xGridId);
00704   xfCloseFile(xFileId);
00705   return TRUE;
00706 } // tgWriteTestGridCurv2D
00707 //////////////////////////////////////////////////////////////////////////////
00708 // FUNCTION   tgWriteTestGridCart3D
00709 // PURPOSE    Write a file that contains data for a 2D Cartesian Grid
00710 // NOTES      A picture of the grid is in the file (TestGridCart2D.gif)
00711 //            returns TRUE on success and FALSE on failure
00712 //////////////////////////////////////////////////////////////////////////////
00713 int tgWriteTestGridCart3D(LPCSTR Filename, int Compression)
00714 {
00715   int         nDimensions = 3;
00716   int         nCompOrigin = 8, nUDir = -2;
00717   int         nCellsI = 5, nCellsJ = 5, nCellsK = 3;
00718   int         nGridType = GRID_TYPE_CARTESIAN;
00719   double      dOriginX = 10.0, dOriginY = 10.0, dOriginZ = 0.0;
00720   int         nOrientation = ORIENTATION_RIGHT_HAND;
00721   double      dBearing = 45.0, dDip = 0.0, dRoll = 0.0;
00722   double      PlanesI[5], PlanesJ[5], PlanesK[3];
00723   int         i, j, status, iSpcZone;
00724   xid         xFileId = NONE, xGridId = NONE;
00725   xid         xPropId = NONE, xCoordId = NONE;
00726   int         nCells = nCellsI * nCellsJ * nCellsK;
00727   int         Active[75];
00728 
00729   // Fill in the grid plane data with a constant size of 30
00730   for (i = 1; i <= nCellsI; i++) {
00731     PlanesI[i - 1] = (double)i*30.0;
00732   }
00733   for (j = 1; j <= nCellsJ; j++) {
00734     PlanesJ[j - 1] = (double)j*30.0;
00735   }
00736   for (j = 1; j <= nCellsK; j++) {
00737     PlanesK[j - 1] = (double)j*30.0;
00738   }
00739 
00740   // fill in the activity array
00741   // default array to active
00742   for (i = 0; i < nCells; i++) {
00743     Active[i] = (int)XTRUE;
00744   }
00745 
00746   // two cells are inactive (identified by array index)
00747   // i = 0, j = 0, k = 0  and i = 4, j = 4, k = 0
00748   Active[0] = (int)XFALSE;
00749   Active[4*nCellsJ*nCellsK+4*nCellsK] = (int)XFALSE;
00750 
00751   // create the file
00752   if (xfCreateFile(Filename, &xFileId, XTRUE) < 0) {
00753     return FALSE;
00754   }
00755 
00756   // create the group to store the grid
00757   if (xfCreateGroupForGrid(xFileId, GRID_CART3D_GROUP_NAME, &xGridId) < 0) {
00758     xfCloseFile(xFileId);
00759     return FALSE;
00760   }
00761 
00762   // Write the grid information to the file
00763   if (xfSetGridType(xGridId, nGridType) < 0 ||
00764       xfSetNumberOfDimensions(xGridId, nDimensions) < 0) {
00765     xfCloseGroup(xGridId);
00766     xfCloseFile(xFileId);
00767     return FALSE;
00768   }
00769 
00770   // set origin and orientation
00771   if (xfSetOrigin(xGridId, dOriginX, dOriginY, dOriginZ) < 0 ||
00772       xfSetOrientation(xGridId, nOrientation) < 0 ) {
00773     xfCloseGroup(xGridId);
00774     xfCloseFile(xFileId);
00775     return FALSE;
00776   }
00777  
00778   // Set bearing, dip and roll
00779   if (xfSetBearing(xGridId, dBearing) < 0 ||
00780       xfSetDip(xGridId, dDip) < 0 ||
00781       xfSetRoll(xGridId, dRoll) < 0) {
00782     xfCloseGroup(xGridId);
00783     xfCloseFile(xFileId);
00784     return FALSE;
00785   }
00786 
00787   // Set computational origin
00788   if (xfSetComputationalOrigin(xGridId, nCompOrigin) < 0) {
00789     xfCloseGroup(xGridId);
00790     xfCloseFile(xFileId);
00791     return FALSE;
00792   }
00793 
00794   // Set u direction
00795   if (xfSetUDirection(xGridId, nUDir) < 0) {
00796     xfCloseGroup(xGridId);
00797     xfCloseFile(xFileId);
00798     return FALSE;
00799   }
00800 
00801   // Write the grid geometry to the file
00802   // Set the number of cells in each direction
00803   if (xfSetNumberCellsInI(xGridId, nCellsI) < 0 ||
00804       xfSetNumberCellsInJ(xGridId, nCellsJ) < 0 ||
00805       xfSetNumberCellsInK(xGridId, nCellsK) < 0) {
00806     xfCloseGroup(xGridId);
00807     xfCloseFile(xFileId);
00808     return FALSE;
00809   }
00810 
00811   // Set the grid plane locations
00812   if (xfSetGridCoordsI(xGridId, nCellsI, PlanesI) < 0 ||
00813       xfSetGridCoordsJ(xGridId, nCellsJ, PlanesJ) < 0 ||
00814       xfSetGridCoordsK(xGridId, nCellsK, PlanesK) < 0) {
00815     xfCloseGroup(xGridId);
00816     xfCloseFile(xFileId);
00817     return FALSE;
00818   }
00819 
00820   // Write the activity array
00821   if (xfCreateGridCellPropertyGroup(xGridId, &xPropId) < 0) {
00822     xfCloseGroup(xGridId);
00823     xfCloseFile(xFileId);
00824     return FALSE;
00825   }
00826 
00827   if (xfWritePropertyInt(xPropId, PROP_ACTIVITY, nCells, Active, 
00828                          Compression) < 0) {
00829     xfCloseGroup(xPropId);
00830     xfCloseGroup(xGridId);
00831     xfCloseFile(xFileId);
00832     return FALSE;
00833   }
00834   xfCloseGroup(xPropId);
00835 
00836   // Write Coordinate file - for GridCart3D, we will set the coordinate system
00837   //   to be State Plane NAD27.
00838   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00839   if (status <= 0) {
00840     xfCloseGroup(xGridId);
00841     xfCloseFile(xFileId);
00842           return -1;
00843   }
00844 
00845   iSpcZone = 3601; // Oregon North
00846 
00847   xfSetHorizDatum(xCoordId, HORIZ_DATUM_STATE_PLANE_NAD27);
00848   xfSetHorizUnits(xCoordId, COORD_UNITS_US_FEET);
00849 
00850   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00851   xfSetVertUnits(xCoordId, COORD_UNITS_US_FEET);
00852 
00853     // write additional information
00854   xfSetSPCZone(xCoordId, iSpcZone);
00855 
00856   xfCloseGroup(xCoordId);
00857   xCoordId = 0;
00858 
00859   // release memory
00860   xfCloseGroup(xGridId);
00861   xfCloseFile(xFileId);
00862   return TRUE;
00863 } // tgWriteTestGridCart3D
TestGrid.cpp tests grids
00001 #include "stdafx.h"
00002 #include <Xmdf.h>
00003 #include <stdio.h>
00004 #include <windows.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007 
00008 #define MESH_A_GROUP_NAME "MeshA Group"
00009 #define MESH_B_GROUP_NAME "MeshB Group"
00010 // ---------------------------------------------------------------------------
00011 // FUNCTION  tmReadMesh
00012 // PURPOSE   
00013 // NOTES     
00014 // ---------------------------------------------------------------------------
00015 int tmReadMesh (xid xGroupId, FILE *a_OutFile)
00016 {
00017   int    nElems = 0, nNodes = 0, nNodesPerElem = 0, nElemType, nNodeId;
00018   xmbool  bElementsOneType;
00019   int    status;
00020   int   *ElemTypes = NULL;
00021   int    i, j, StrType, UIntType, IntType, DblType, FloatType;
00022   int   *NodesInElem = NULL;
00023   double *XNodeLocs, *YNodeLocs, *ZNodeLocs;
00024   xid     xPropGrpId;
00025 
00026   // Get the number of elements, nodes, and Maximum number of nodes per element
00027   status = xfGetNumberOfElements(xGroupId, &nElems);
00028   if (status >= 0) {
00029     status = xfGetNumberOfNodes(xGroupId, &nNodes);
00030     if (status >= 0) {
00031       status = xfGetMaxNodesInElem(xGroupId, &nNodesPerElem);
00032     }
00033   }
00034   if (status < 0) {
00035     return -1;
00036   }
00037 
00038   // Do Element information first
00039   fprintf(a_OutFile, "Number of Elements: %d\n", nElems);
00040 
00041   // Element types
00042   status = xfAreAllElemsSameType(xGroupId, &bElementsOneType);
00043   if (status < 0) {
00044     return -1;
00045   }
00046 
00047   if (bElementsOneType == (xmbool)XTRUE) {
00048     status = xfReadElemTypesSingleValue(xGroupId, &nElemType);
00049     fprintf(a_OutFile, "All elements are type %d\n", nElemType);
00050   }
00051   else {
00052     ElemTypes = new int[nElems];
00053     if (ElemTypes == NULL) {
00054       printf("Memory Error");
00055       return -1;
00056     }
00057     status = xfReadElemTypes(xGroupId, nElems, ElemTypes);
00058     if (status < 0) {
00059       return -1;
00060     }
00061     fprintf(a_OutFile, "Element Types:\n");
00062     for (i = 0; i < nElems; i++) {
00063       fprintf(a_OutFile, "Elem %d, Type %d\n", i+1, ElemTypes[i]);
00064     }
00065     delete ElemTypes;
00066     ElemTypes = NULL;
00067   }
00068 
00069   // Nodes in each element
00070   NodesInElem  = new int[nElems*nNodesPerElem];
00071   xfReadElemNodeIds(xGroupId, nElems, nNodesPerElem, NodesInElem);
00072   for (i = 0; i < nElems; i++) {
00073     fprintf(a_OutFile, "Elem: %4d - ", i+1);
00074     for (j = 0; j < nNodesPerElem; j++) {
00075       nNodeId = NodesInElem[i*nNodesPerElem + j];
00076       if (nNodeId > 0) { // -1 is for unused array locations
00077         fprintf(a_OutFile, "%d ", nNodeId);
00078       }
00079     }
00080     fprintf(a_OutFile, "\n");
00081   }
00082   delete NodesInElem;
00083   NodesInElem = NULL;
00084 
00085   // NodeLocations
00086   XNodeLocs = new double[nNodes];
00087   YNodeLocs = new double[nNodes];
00088   ZNodeLocs = new double[nNodes];
00089   if (XNodeLocs == NULL || YNodeLocs == NULL || ZNodeLocs == NULL) {
00090     if (XNodeLocs != NULL) {
00091       delete XNodeLocs;
00092       XNodeLocs = NULL;
00093     }
00094     if (YNodeLocs != NULL) {
00095       delete YNodeLocs;
00096       YNodeLocs = NULL;
00097     }
00098     if (ZNodeLocs != NULL) {
00099       delete ZNodeLocs;
00100       ZNodeLocs = NULL;
00101     }
00102     printf("Memory Error!");
00103     return -1;
00104   }
00105 
00106   status = xfReadXNodeLocations(xGroupId, nNodes, XNodeLocs);
00107   if (status >= 0) {
00108     status = xfReadYNodeLocations(xGroupId, nNodes, YNodeLocs);
00109     if (status >= 0) {
00110       status = xfReadZNodeLocations(xGroupId, nNodes, ZNodeLocs);
00111     }
00112     else {
00113       return -1;
00114     }
00115   }
00116   else {
00117     return -1;
00118   }
00119 
00120   fprintf(a_OutFile, "Node Locations:\n");
00121   for (i = 0; i < nNodes; i++) {
00122     fprintf(a_OutFile, "Node: %d Location: %lf %lf %lf\n", i + 1, XNodeLocs[i],
00123                         YNodeLocs[i], ZNodeLocs[i]);
00124   }
00125 
00126   // Open the property group
00127   status = xfOpenGroup(xGroupId, "PROPERTIES", &xPropGrpId);
00128   if (status < 0) {
00129     fprintf(a_OutFile, "\n");
00130     fprintf(a_OutFile, "Properties Group not found\n");
00131     fprintf(a_OutFile, "\n");
00132     return -1; 
00133   }
00134 
00135   // Get the Property Types
00136   status = xfGetPropertyType(xPropGrpId, "String", &StrType);
00137   status = xfGetPropertyType(xPropGrpId, "UInt", &UIntType);
00138   status = xfGetPropertyType(xPropGrpId, "Int", &IntType);
00139   status = xfGetPropertyType(xPropGrpId, "Double", &DblType);
00140   status = xfGetPropertyType(xPropGrpId, "Float", &FloatType);
00141 
00142     // Property Types:
00143   fprintf(a_OutFile, "\n");
00144   if (StrType == XF_TYPE_STRING) {
00145     fprintf(a_OutFile, "String Property Type Read Correctly\n");
00146   }
00147   else {
00148     fprintf(a_OutFile, "Error in Getting String Property Type\n");
00149   }
00150   if (UIntType == XF_TYPE_UINT) {
00151     fprintf(a_OutFile, "Unsigned Integer Property Type Read Correctly\n");
00152   }
00153   else {
00154     fprintf(a_OutFile, "Error in Getting Unsigned Integer Property Type\n");
00155   }
00156   if (IntType == XF_TYPE_INT) {
00157     fprintf(a_OutFile, "Integer Property Type Read Correctly\n");
00158   }
00159   else {
00160     fprintf(a_OutFile, "Error in Getting Integer Property Type\n");
00161   }
00162   if (DblType == XF_TYPE_DOUBLE) {
00163     fprintf(a_OutFile, "Double Property Type Read Correctly\n");
00164   }
00165   else {
00166     fprintf(a_OutFile, "Error in Getting Double Property Type\n");
00167   }
00168   if (FloatType == XF_TYPE_FLOAT) {
00169     fprintf(a_OutFile, "Float Property Type Read Correctly\n");
00170   }
00171   else {
00172     fprintf(a_OutFile, "Error in Getting Float Property Type\n");
00173   }
00174   fprintf(a_OutFile, "\n");
00175 
00176   if (XNodeLocs) {
00177     delete XNodeLocs;
00178   }
00179   if (YNodeLocs) {
00180     delete YNodeLocs;
00181   }
00182   if (ZNodeLocs) {
00183     delete ZNodeLocs;
00184   }
00185 
00186   return TRUE;
00187 } // tmReadMesh
00188 //////////////////////////////////////////////////////////////////////////////
00189 // FUNCTION   tmWriteTestMeshA
00190 // PURPOSE    Write a file that contains data for an all tri mesh
00191 // NOTES      A picture of the mesh is in the file (TestMeshA.gif)
00192 //            returns TRUE on success and FALSE on failure
00193 //////////////////////////////////////////////////////////////////////////////
00194 int tmWriteTestMeshA(LPCSTR Filename, int Compression)
00195 {
00196   int         nElements = 3, nNodes = 5;
00197   xid         xFileId = NONE, xMeshId = NONE;
00198   xid         xPropGrpId = NONE, xCoordId = NONE;
00199   double      dNodeLocsX[5], dNodeLocsY[5], dNodeLocsZ[5];
00200   int         iElementNodes[3][3]; // numelements, max elems per node
00201   int         status, propint, iEllipse;
00202   char          *propstring;
00203   unsigned int  propuint;
00204   double        propdouble, dMajorR, dMinorR;
00205   float         propfloat;
00206 
00207   // Setup the arrays for the mesh data
00208     // nodes
00209   dNodeLocsX[0] = 0.0; dNodeLocsY[0] = 5.0; dNodeLocsZ[0] = 0.0;
00210   dNodeLocsX[1] = 5.0; dNodeLocsY[1] = 5.0; dNodeLocsZ[1] = 0.0;
00211   dNodeLocsX[2] = 0.0; dNodeLocsY[2] = 0.0; dNodeLocsZ[2] = 0.0;
00212   dNodeLocsX[3] = 5.0; dNodeLocsY[3] = 0.0; dNodeLocsZ[3] = 0.0;
00213   dNodeLocsX[4] = 7.5; dNodeLocsY[4] = 2.5; dNodeLocsZ[4] = 0.0;
00214   
00215     // nodes for each element
00216     // must be counter-clockwize
00217   iElementNodes[0][0] = 1; iElementNodes[0][1] = 3; iElementNodes[0][2] = 2;
00218   iElementNodes[1][0] = 2; iElementNodes[1][1] = 3; iElementNodes[1][2] = 4;
00219   iElementNodes[2][0] = 5; iElementNodes[2][1] = 2; iElementNodes[2][2] = 4;
00220 
00221   // create the file
00222   status = xfCreateFile(Filename, &xFileId, XTRUE);
00223   if (status < 0) {
00224     return FALSE;
00225   }
00226 
00227   // create the group to store the mesh
00228   status = xfCreateGroupForMesh(xFileId, MESH_A_GROUP_NAME, &xMeshId);
00229   if (status < 0) {
00230     return FALSE;
00231   }
00232 
00233   // Element types - all are linear triangles
00234   status = xfSetAllElemsSameType(xMeshId, EL_TYPE_TRI_LINEAR);
00235   if (status < 0) {
00236     return FALSE;
00237   }
00238 
00239   // node information
00240   status = xfSetNumberOfNodes(xMeshId, nNodes);
00241   if (status < 0) {
00242     return FALSE;
00243   }
00244 
00245   status = xfWriteXNodeLocations(xMeshId, nNodes, dNodeLocsX, Compression);
00246   if (status < 0) {
00247     return FALSE;
00248   }
00249   status = xfWriteYNodeLocations(xMeshId, nNodes, dNodeLocsY);
00250   if (status < 0) {
00251     return FALSE;
00252   }
00253   status = xfWriteZNodeLocations(xMeshId, nNodes, dNodeLocsZ);
00254   if (status < 0) {
00255     return FALSE;
00256   }
00257 
00258   // element information
00259   status = xfSetNumberOfElements(xMeshId, nElements);
00260   if (status < 0) {
00261     return FALSE;
00262   }
00263  
00264   // Write the node array ids for the nodes in each element
00265   status = xfWriteElemNodeIds(xMeshId, nElements, 3, &iElementNodes[0][0],
00266                               Compression);
00267   if (status < 0) {
00268     return FALSE;
00269   }
00270 
00271   // Write the property file
00272   status = xfCreateMeshPropertyGroup(xMeshId, &xPropGrpId);
00273   if (status < 0) {
00274     xfCloseGroup(xFileId);
00275     return FALSE;
00276   }
00277   propstring = "Property String";
00278   propuint = 5;
00279   propint = -5;
00280   propdouble = 5.6789012345;
00281   propfloat = (float)5.6789;
00282 
00283   status = xfWritePropertyString(xPropGrpId, "String", 1, 
00284                                  strlen(propstring), propstring);
00285   status = xfWritePropertyUnsignedInt(xPropGrpId, "UInt", 1, &propuint, NONE);
00286   status = xfWritePropertyInt(xPropGrpId, "Int", 1, &propint, NONE);
00287   status = xfWritePropertyDouble(xPropGrpId, "Double", 1, &propdouble, NONE);
00288   status = xfWritePropertyFloat(xPropGrpId, "Float", 1, &propfloat, NONE);
00289 
00290   // Write Coordinate file - for MeshA, we will set the coordinate system to be
00291   //   Geogrpahic, with Latitude, Longitude, and user-defined ellipsoid settings
00292   //   written to the file.
00293   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00294   if (status <= 0) {
00295     xfCloseGroup(xPropGrpId);
00296     xfCloseGroup(xMeshId);
00297     xfCloseFile(xFileId);
00298     return -1;
00299   }
00300 
00301     // set coordinate values
00302   iEllipse = 32;   // User defined
00303   dMajorR = 45.0;    // Made up
00304   dMinorR = 32.0;    // Made up
00305 
00306   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC);
00307   xfSetHorizUnits(xCoordId, COORD_UNITS_US_FEET);
00308 
00309   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00310   xfSetVertUnits(xCoordId, COORD_UNITS_US_FEET);
00311 
00312     // write additional information
00313   xfSetEllipse(xCoordId, iEllipse);
00314   xfSetLat(xCoordId, LATITUDE_NORTH);
00315   xfSetLon(xCoordId, LONGITUDE_EAST);
00316   xfSetMajorR(xCoordId, dMajorR);
00317   xfSetMinorR(xCoordId, dMinorR);
00318 
00319   xfCloseGroup(xCoordId);
00320   xCoordId = 0;
00321 
00322   // close the resources
00323   xfCloseGroup(xPropGrpId);
00324   xfCloseGroup(xMeshId);
00325   xfCloseFile(xFileId);
00326 
00327   return TRUE;
00328 } // tmWriteTestMeshA
00329 //////////////////////////////////////////////////////////////////////////////
00330 // FUNCTION   tmWriteTestMeshB
00331 // PURPOSE    Write a file that contains data for an mixed quad/tri linear mesh
00332 // NOTES      A picture of the mesh is in the file (TestMeshB.gif)
00333 //            returns TRUE on success and FALSE on failure
00334 //////////////////////////////////////////////////////////////////////////////
00335 int tmWriteTestMeshB(LPCSTR Filename, int Compression)
00336 {
00337   int         nElements = 2, nNodes = 5, nMaxNodePerElem = 4;
00338   xid         xFileId = NONE, xMeshId = NONE;
00339   xid         xPropGrpId = NONE, xCoordId = NONE;
00340   double      dNodeLocsX[5], dNodeLocsY[5], dNodeLocsZ[5];
00341   int         iElementNodes[2][4]; // numelements, max nodes per elem
00342   int         iElementTypes[2];
00343   int         status, propint, iEllipse;
00344   char          *propstring;
00345   unsigned int  propuint;
00346   double        propdouble;
00347   float         propfloat;
00348 
00349   // Setup the arrays for the mesh data
00350     // nodes
00351   dNodeLocsX[0] = 0.0; dNodeLocsY[0] = 5.0; dNodeLocsZ[0] = 0.0;
00352   dNodeLocsX[1] = 5.0; dNodeLocsY[1] = 5.0; dNodeLocsZ[1] = 0.0;
00353   dNodeLocsX[2] = 0.0; dNodeLocsY[2] = 0.0; dNodeLocsZ[2] = 0.0;
00354   dNodeLocsX[3] = 5.0; dNodeLocsY[3] = 0.0; dNodeLocsZ[3] = 0.0;
00355   dNodeLocsX[4] = 7.5; dNodeLocsY[4] = 2.5; dNodeLocsZ[4] = 0.0;
00356   
00357     // nodes for each element
00358     // must be counter-clockwize
00359   iElementNodes[0][0] = 1; iElementNodes[0][1] = 3; iElementNodes[0][2] = 4;
00360   iElementNodes[0][3] = 2;
00361   iElementNodes[1][0] = 2; iElementNodes[1][1] = 4; iElementNodes[1][2] = 5;
00362   iElementNodes[1][3] = NONE;
00363 
00364   iElementTypes[0] = EL_TYPE_QUADRILATERAL_LINEAR;
00365   iElementTypes[1] = EL_TYPE_TRI_LINEAR;
00366 
00367   // create the file
00368   status = xfCreateFile(Filename, &xFileId, XTRUE);
00369   if (status < 0) {
00370     return FALSE;
00371   }
00372 
00373   // create the group to store the mesh
00374   status = xfCreateGroupForMesh(xFileId, MESH_B_GROUP_NAME, &xMeshId);
00375   if (status < 0) {
00376     return FALSE;
00377   }
00378 
00379   // node information
00380   status = xfSetNumberOfNodes(xMeshId, nNodes);
00381   if (status < 0) {
00382     return FALSE;
00383   }
00384 
00385   status = xfWriteXNodeLocations(xMeshId, nNodes, dNodeLocsX, Compression);
00386   if (status < 0) {
00387     return FALSE;
00388   }
00389   status = xfWriteYNodeLocations(xMeshId, nNodes, dNodeLocsY);
00390   if (status < 0) {
00391     return FALSE;
00392   }
00393   status = xfWriteZNodeLocations(xMeshId, nNodes, dNodeLocsZ);
00394   if (status < 0) {
00395     return FALSE;
00396   }
00397 
00398   // element information
00399   status = xfSetNumberOfElements(xMeshId, nElements);
00400   if (status < 0) {
00401     return FALSE;
00402   }
00403 
00404   // Element types
00405   status = xfWriteElemTypes(xMeshId, nElements, iElementTypes, Compression);
00406   if (status < 0) {
00407     return FALSE;
00408   }
00409  
00410   // Write the node array ids for the nodes in each element
00411   status = xfWriteElemNodeIds(xMeshId, nElements, nMaxNodePerElem,
00412                               &iElementNodes[0][0], Compression);
00413   if (status < 0) {
00414     return FALSE;
00415   }
00416 
00417   // Write the property file
00418   status = xfCreateMeshPropertyGroup(xMeshId, &xPropGrpId);
00419   if (status < 0) {
00420     xfCloseGroup(xFileId);
00421     return FALSE;
00422   }
00423   propstring = "String Property";
00424   propuint = 2;
00425   propint = -2;
00426   propdouble = 2.3456789012;
00427   propfloat = (float)2.3456;
00428 
00429   status = xfWritePropertyString(xPropGrpId, "String", 1, 
00430                                  strlen(propstring), propstring);
00431   status = xfWritePropertyUnsignedInt(xPropGrpId, "UInt", 1, &propuint, NONE);
00432   status = xfWritePropertyInt(xPropGrpId, "Int", 1, &propint, NONE);
00433   status = xfWritePropertyDouble(xPropGrpId, "Double", 1, &propdouble, NONE);
00434   status = xfWritePropertyFloat(xPropGrpId, "Float", 1, &propfloat, NONE);
00435 
00436   // Write Coordinate file - for MeshB, we will set the coordinate system to be
00437   //   Geogrpahic, with Latitude, Longitude, and standard ellipsoid settings
00438   //   written to the file.
00439   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00440   if (status <= 0) {
00441     xfCloseGroup(xPropGrpId);
00442           xfCloseGroup(xMeshId);
00443           xfCloseFile(xFileId);
00444           return -1;
00445   }
00446 
00447     // set coordinate values
00448   iEllipse = 21;   // International 1924
00449 
00450   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC);
00451   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00452 
00453   xfSetVertDatum(xCoordId, VERT_DATUM_NGVD_88);
00454   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00455 
00456     // write additional information
00457   xfSetEllipse(xCoordId, iEllipse);
00458   xfSetLat(xCoordId, LATITUDE_SOUTH);
00459   xfSetLon(xCoordId, LONGITUDE_WEST);
00460 
00461   xfCloseGroup(xCoordId);
00462   xCoordId = 0;
00463 
00464   // close the resources
00465   xfCloseGroup(xPropGrpId);
00466   xfCloseGroup(xMeshId);
00467   xfCloseFile(xFileId);
00468 
00469   return TRUE;
00470 } // tmWriteTestMeshB
TestMesh.cpp tests meshes
00001 // This file has functions that can be used to test reading and writing of
00002 // timesteps using HDF5.  This code is intended to be used as tests for the
00003 // XMDF library as well as sample code for distribution.
00004 
00005 // Untested XMDF functions used for timesteps:
00006 // xfGetDatasetMinsDouble
00007 // xfGetDatasetMaxsDouble
00008 // xfReadScalarValuesTimestepInt
00009 // xfReadScalarValuesAtIndicesFloat
00010 // xfReadVectorValuesAtIndexDouble
00011 
00012 // All XMDF functions used for timesteps:
00013 // xfGetDatasetTimes
00014 // xfGetDatasetMins
00015 // xfGetDatasetMaxs
00016 // xfGetDatasetMinsFloat
00017 // xfGetDatasetMaxsFloat
00018 // xfGetDatasetMinsDouble
00019 // xfGetDatasetMaxsDouble
00020 // xfReadActivityTimestep
00021 // xfReadActivityValuesAtIndex
00022 // xfReadScalarValuesTimestep
00023 // xfReadScalarValuesTimestepFloat
00024 // xfReadScalarValuesTimestepFloatPortion
00025 // xfReadScalarValuesTimestepDouble
00026 // xfReadScalarValuesTimestepDoublePortion
00027 // xfReadScalarValuesTimestepInt
00028 // xfReadScalarValuesAtIndex
00029 // xfReadScalarValuesAtIndexFloat
00030 // xfReadScalarValuesAtIndexDouble
00031 // xfReadScalarValuesAtIndices
00032 // xfReadScalarValuesAtIndicesFloat
00033 // xfReadVectorValuesTimestep
00034 // xfReadVectorValuesTimestepFloat
00035 // xfReadVectorValuesTimestepFloatPortion
00036 // xfReadVectorValuesTimestepDouble
00037 // xfReadVectorValuesTimestepDoublePortion
00038 
00039 
00040 #include "stdafx.h"
00041 #include <Xmdf.h>
00042 #include <stdio.h>
00043 #include <windows.h>
00044 #include <string.h>
00045 #include <stdlib.h>
00046 
00047 #define    DATASETS_LOCATION "Datasets"
00048 #define    SCALAR_A_LOCATION "Scalars/ScalarA"
00049 #define    SCALAR_B_LOCATION "Scalars/ScalarB"
00050 #define    VECTOR2D_A_LOCATION "Vectors/Vector2D_A"
00051 #define    VECTOR2D_B_LOCATION "Vectors/Vector2D_B"
00052 
00053 void ttiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
00054                      int a_SeedMultiplier, int a_nValues, float *a_Array);
00055 double ttiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed);
00056 int ttiReadScalar (xid a_xScalarId, FILE *a_fp);
00057 int ttiReadVector (xid a_xVectorId, FILE *a_fp);
00058 int ttiTestNumTimes( xid a_DatasetId, int a_Itimestep );
00059 
00060 // --------------------------------------------------------------------------
00061 // FUNCTION ttReadDatasets
00062 // PURPOSE  Read a dataset group from an XMDF file and output information to
00063 //          to a text file
00064 // NOTES    
00065 // --------------------------------------------------------------------------
00066 int ttReadDatasets (xid a_xGroupId, FILE *a_fp)
00067 {
00068   int   nPaths=0, nMaxPathLength=0, nMultiDatasets=0;
00069   char *Paths = NULL, *IndividualPath = NULL;
00070   int   nStatus, i, j;
00071   xid   xScalarId = NONE, xVectorId = NONE, xMultiId = NONE;
00072 
00073   // Look for scalar datasets
00074   nStatus = xfGetScalarDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00075   if (nStatus >= 0) {
00076     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00077     xfGetScalarDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00078   }
00079   if (nStatus < 0) {
00080     return -1;
00081   }
00082   
00083   // Output number and paths to scalar datasets
00084   fprintf(a_fp, "Number of Scalars %d\n", nPaths);
00085   for (i = 0; i < nPaths; i++) {
00086     IndividualPath = &Paths[i*nMaxPathLength];
00087     fprintf(a_fp, "Reading scalar: %s\n", IndividualPath);
00088    
00089     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xScalarId);
00090     if (nStatus < 0) {
00091       return -1; 
00092     }
00093 
00094     nStatus = ttiReadScalar(xScalarId, a_fp);
00095     xfCloseGroup(xScalarId);
00096     if (nStatus < 0) {
00097       printf("%d: ERROR reading scalar dataset.\n", __LINE__);
00098       return -1;
00099     }
00100   }
00101 
00102   if (Paths) {
00103     free(Paths);
00104     Paths = NULL;
00105   }
00106 
00107   // Look for vector datasets
00108   nStatus = xfGetVectorDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00109   if (nStatus >= 0 && nPaths > 0) {
00110     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00111     xfGetVectorDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00112   }
00113   if (nStatus < 0) {
00114     return -1;
00115   }
00116 
00117 
00118   // Output number and paths to scalar datasets
00119   fprintf(a_fp, "Number of Vectors %d\n", nPaths);
00120   for (i = 0; i < nPaths; i++) {
00121     IndividualPath = &Paths[i*nMaxPathLength];
00122     fprintf(a_fp, "Reading Vector: %s\n", IndividualPath);
00123    
00124     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xVectorId);
00125     if (nStatus < 0) {
00126       return -1; 
00127     }
00128 
00129     nStatus = ttiReadVector(xVectorId, a_fp);
00130     xfCloseGroup(xVectorId);
00131     if (nStatus < 0) {
00132       printf("%d: ERROR reading vector dataset.\n", __LINE__);
00133       return -1;
00134     }
00135   }
00136 
00137   // find multidataset folders
00138   nStatus = xfGetGroupPathsSizeForMultiDatasets(a_xGroupId, &nMultiDatasets,
00139                                                       &nMaxPathLength);
00140   if (nStatus >= 0 && nMultiDatasets > 0) {
00141     Paths = (char *)malloc(nMultiDatasets*nMaxPathLength*sizeof(char));
00142     nStatus = xfGetAllGroupPathsForMultiDatasets(a_xGroupId, nMultiDatasets, 
00143                                                  nMaxPathLength, Paths);
00144     if (nStatus < 0) {
00145       return -1;
00146     }
00147 
00148   // Output number and paths to multidatasets
00149     fprintf(a_fp, "Number of Multidatasets: %d\n", nMultiDatasets);
00150     for (i=0; i<nMultiDatasets; i++) {
00151       IndividualPath = "";
00152       for (j=0; j<nMaxPathLength-1; j++) {
00153         IndividualPath = &Paths[i*nMaxPathLength];
00154       }
00155       fprintf(a_fp, "Reading multidataset: %s\n", IndividualPath);
00156       nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xMultiId);
00157       if (nStatus < 0) {
00158             return -1;
00159       }
00160 
00161       nStatus = ttReadDatasets(xMultiId, a_fp);
00162       nStatus = xfCloseGroup(xMultiId);
00163       if (nStatus < 0) {
00164         printf("%d: ERROR reading multidatasets.\n", __LINE__);
00165             return -1;
00166       }
00167     }
00168   }
00169 
00170   if (Paths) {
00171     free(Paths);
00172     Paths = NULL;
00173   }
00174 
00175   return 1;
00176 } // ttReadDatasets
00177 // --------------------------------------------------------------------------
00178 // FUNCTION ttReadActivityScalarAIndex
00179 // PURPOSE  Read all timestep values for a particular index
00180 // NOTES    
00181 // --------------------------------------------------------------------------
00182 int ttReadActivityScalarAIndex (LPCSTR a_Filename, int a_Index)
00183 {
00184   int     status;
00185   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00186   int     nTimesteps;
00187   xmbool  *bActive;
00188 
00189   // open the file
00190   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00191   if (status < 0) {
00192     return FALSE;
00193   }
00194 
00195   // open the dataset group
00196   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00197   if (status >= 0) {
00198     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00199   }
00200   if (status < 0) {
00201     return status;
00202   }
00203 
00204   // Find out the number of timesteps in the file
00205   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00206   if (status < 0) {
00207     return status;
00208   }
00209   if (nTimesteps < 1) {
00210     return -1;
00211   }
00212 
00213   // Read the values for the index
00214   bActive = new xmbool[nTimesteps];
00215   status = xfReadActivityValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00216                                        bActive);
00217 
00218   // output the data
00219   printf("\nReading activity for scalar A slice at index: %d\n", a_Index);
00220   for (int i = 0; i < nTimesteps; i++) {
00221     printf("%d ", bActive[i]);
00222   }
00223   printf("\n");
00224 
00225   delete [] bActive;
00226 
00227   return status;
00228 } // ttReadActivityScalarAtIndex
00229 // --------------------------------------------------------------------------
00230 // FUNCTION ttReadScalarAIndex
00231 // PURPOSE  Read all timestep values for a particular index
00232 // NOTES    
00233 // --------------------------------------------------------------------------
00234 int ttReadScalarAIndex (LPCSTR a_Filename, int a_Index)
00235 {
00236   int     status;
00237   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00238   int     nTimesteps;
00239   float  *fValues;
00240 
00241   // open the file
00242   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00243   if (status < 0) {
00244     return FALSE;
00245   }
00246 
00247   // open the dataset group
00248   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00249   if (status >= 0) {
00250     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00251   }
00252   if (status < 0) {
00253     return status;
00254   }
00255 
00256   // Find out the number of timesteps in the file
00257   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00258   if (status < 0) {
00259     return status;
00260   }
00261   if (nTimesteps < 1) {
00262     return -1;
00263   }
00264 
00265   // Read the values for the index
00266   fValues = new float[nTimesteps];
00267   status = xfReadScalarValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00268                                      fValues);
00269 
00270   // output the data
00271   printf("\nReading scalar A slice at index: %d\n", a_Index);
00272   for (int i = 0; i < nTimesteps; i++) {
00273     printf("%f ", fValues[i]);
00274   }
00275   printf("\n");
00276 
00277   delete [] fValues;
00278 
00279   return status;
00280 } // ttReadScalarAtIndex
00281 // --------------------------------------------------------------------------
00282 // FUNCTION ttWriteScalarA
00283 // PURPOSE  Write scalar Dataset to an HDF5 File
00284 // NOTES    This tests dynamic data sets, and activity
00285 //          This dataset is dynamic concentrations (mg/L) with output times
00286 //          in minutes.
00287 //          Dataset is for a mesh and so nActive is the number of elements
00288 //          which is not the same as the nValues which would be number of nodes
00289 //          reads/writes a reference time in julian days
00290 // --------------------------------------------------------------------------
00291 int ttWriteScalarA (LPCSTR a_Filename, int a_Compression)
00292 {
00293   xid      xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
00294   int      nValues = 10, nTimes = 3, nActive = 8;
00295   double   dTime = 0.0;
00296   int      iTimestep, iActive;
00297   float    fValues[10]; // nValues
00298   xmbool    bActivity[10]; // activity
00299   int      status, iHpgnZone;
00300   double   dJulianReftime;
00301   int      nErrors = 0, i = 0;
00302   char     **Errors = NULL;
00303 
00304   // 5th item in data set is always inactive, others active
00305   for (iActive = 0; iActive < nActive; iActive++) {
00306     bActivity[iActive] = XTRUE;
00307   }
00308   bActivity[5] = XFALSE;
00309 
00310   // create the file
00311   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00312   if (status < 0) {
00313     return FALSE;
00314   }
00315 
00316   // create the group where we will put all the datasets 
00317   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00318   if (status < 0) {
00319     xfCloseFile(xFileId);
00320     return FALSE;
00321   }
00322 
00323   // uncomment next line to test error handling function
00324   // xfCloseGroup(xDsetsId);
00325 
00326   // Create the scalar A dataset group
00327   status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
00328                                  "mg/L", TS_HOURS, a_Compression,
00329                                  &xScalarAId);
00330   if (status < 0) {
00331     // print the error stack
00332     xfGetNumErrorMessages(&nErrors);
00333     if (nErrors > 0) {
00334       Errors = new char*[nErrors];
00335       for (i = 0; i < nErrors; i++) {
00336         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00337       }
00338       status = xfGetErrorMessages(nErrors, Errors);
00339       if (status > 0) {
00340         for (i = 0; i < nErrors; i++) {
00341           printf("%s\n", Errors[i]);
00342         }
00343       }
00344       for (i = 0; i < nErrors; i++) {
00345         delete Errors[i];
00346       }
00347       delete Errors;
00348     }
00349 
00350     xfCloseGroup(xDsetsId);
00351     xfCloseFile(xFileId);
00352     return FALSE;
00353   }
00354 
00355   // Add in a reftime.  This is a julian day for:
00356   // noon July 1, 2003
00357   dJulianReftime = 2452822.0;
00358   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00359   if (status < 0) {
00360     xfCloseGroup(xScalarAId);
00361     xfCloseGroup(xDsetsId);
00362     xfCloseFile(xFileId);
00363   }
00364 
00365   // Loop through timesteps adding them to the file
00366   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00367     // We will have an 0.5 hour timestep
00368     dTime = (iTimestep + 1) * 0.5;
00369 
00370     fValues[0] = (float)dTime;
00371     for (i = 1; i < nValues; i++) {
00372       fValues[i] = float(fValues[i-1]*2.5);
00373     }
00374 
00375     // write the dataset array values
00376     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00377     if (status >= 0) {
00378       // write activity array
00379       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00380       if (status < 0)
00381         {
00382           printf( "%d: ERROR writing activity timestep: %d\n",
00383                   __LINE__, status );
00384         }
00385     }
00386     if (status < 0) {
00387       printf( "%d: ERROR writing scalar timestep.\n", __LINE__ );
00388       xfCloseGroup(xScalarAId);
00389       xfCloseGroup(xDsetsId);
00390       xfCloseFile(xFileId);
00391     }
00392 
00393     status = ttiTestNumTimes( xScalarAId, iTimestep );
00394   }
00395 
00396   // Write Coordinate file - for ScalarA, we will set the coordinate system
00397   //   to be Geographic HPGN, with HPGN settings written to the file.
00398   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00399   if (status <= 0) {
00400     xfCloseGroup(xScalarAId);
00401     xfCloseGroup(xDsetsId);
00402     xfCloseFile(xFileId);
00403         return -1;
00404   }
00405 
00406     // set HPGN Zone for test
00407   iHpgnZone = 29;      // Utah
00408 
00409     // Write Coordinate Information to file
00410   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00411   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00412   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00413   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00414 
00415     // write additional information
00416   xfSetHPGNArea(xCoordId, iHpgnZone);
00417 
00418   xfCloseGroup(xCoordId);
00419   xCoordId = 0;
00420 
00421   // close the dataset
00422   xfCloseGroup(xScalarAId);
00423   xfCloseGroup(xDsetsId);
00424   xfCloseFile(xFileId);
00425 
00426   return FALSE;
00427 } // ttWriteScalarA
00428 
00429 // --------------------------------------------------------------------------
00430 // FUNCTION ttWriteScalarB
00431 // PURPOSE  Write scalar Dataset to an HDF5 File
00432 // NOTES    This tests dynamic data sets, and activity
00433 //          This dataset is dynamic concentrations (mg/L) with output times
00434 //          in minutes.
00435 //          Dataset is for a mesh and so nActive is the number of elements
00436 //          which is not the same as the nValues which would be number of nodes
00437 //          reads/writes a reference time in julian days
00438 // --------------------------------------------------------------------------
00439 int ttWriteScalarB (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00440 {
00441   xid      xFileId, xDsetsId, xScalarBId, xCoordId = NONE;
00442   int      nValues = 10, nTimes = 3, nActive = 8;
00443   double   dTime = 0.0, dJulianReftime;
00444   int      iTimestep, iActive;
00445   float    fValues[10]; // nValues
00446   xmbool    bActivity[10]; // activity
00447   int      status, nErrors = 0, i = 0;
00448   char     **Errors = NULL;
00449 
00450   // 5th item in data set is always inactive, others active
00451   for (iActive = 0; iActive < nActive; iActive++) {
00452     bActivity[iActive] = XTRUE;
00453   }
00454   bActivity[5] = XFALSE;
00455 
00456   if (a_Overwrite) {
00457       // open the already-existing file
00458     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00459     if (status < 0) {
00460       return -1;
00461     }
00462       // open the group where we have all the datasets 
00463     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00464     if (status < 0) {
00465       xfCloseFile(xFileId);
00466       return -1;
00467     }
00468   }
00469   else {
00470       // create the file
00471     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00472     if (status < 0) {
00473       return -1;
00474     }
00475       // create the group where we will put all the datasets 
00476     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00477     if (status < 0) {
00478       xfCloseFile(xFileId);
00479       return -1;
00480     }
00481   }
00482 
00483   // uncomment next line to test error handling function
00484   // xfCloseGroup(xDsetsId);
00485 
00486   // Create/Overwrite the scalar B dataset group
00487   status = xfCreateScalarDataset(xDsetsId, SCALAR_B_LOCATION,
00488                                  "mg/L", TS_HOURS, a_Compression,
00489                                  &xScalarBId);
00490   if (status < 0) {
00491     // print the error stack
00492     xfGetNumErrorMessages(&nErrors);
00493     if (nErrors > 0) {
00494       Errors = new char*[nErrors];
00495       for (i = 0; i < nErrors; i++) {
00496         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00497       }
00498       status = xfGetErrorMessages(nErrors, Errors);
00499       if (status > 0) {
00500         for (i = 0; i < nErrors; i++) {
00501           printf("%s\n", Errors[i]);
00502         }
00503       }
00504       for (i = 0; i < nErrors; i++) {
00505         delete Errors[i];
00506       }
00507       delete Errors;
00508     }
00509 
00510     xfCloseGroup(xDsetsId);
00511     xfCloseFile(xFileId);
00512     return -1;
00513   }
00514 
00515   // Add in a reftime.  This is a julian day for:
00516   // noon July 1, 2003
00517   dJulianReftime = 2452822.0;
00518   status = xfDatasetReftime(xScalarBId, dJulianReftime);
00519   if (status < 0) {
00520     xfCloseGroup(xScalarBId);
00521     xfCloseGroup(xDsetsId);
00522     xfCloseFile(xFileId);
00523   }
00524 
00525   if (!a_Overwrite) {
00526     // Loop through timesteps adding them to the file
00527     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00528       // We will have an 0.5 hour timestep
00529       dTime = (iTimestep + 1) * 0.5;
00530 
00531       fValues[0] = (float)dTime;
00532       for (i = 1; i < nValues; i++) {
00533         fValues[i] = float(fValues[i-1]*2.5);
00534       }
00535 
00536       // write the dataset array values
00537       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00538       if (status >= 0) {
00539         // write activity array
00540         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00541       }
00542       if (status < 0) {
00543         xfCloseGroup(xScalarBId);
00544         xfCloseGroup(xDsetsId);
00545         xfCloseFile(xFileId);
00546       }
00547     }
00548   }
00549   else {
00550     // Loop through timesteps adding them to the file
00551     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00552       // We will have an 1.5 hour timestep
00553       dTime = (iTimestep + 1) * 1.5;
00554 
00555       fValues[0] = (float)dTime;
00556       for (i = 1; i < nValues; i++) {
00557         fValues[i] = float(fValues[i-1]*1.5);
00558       }
00559 
00560       // write the dataset array values
00561       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00562       if (status >= 0) {
00563         // write activity array
00564         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00565       }
00566       if (status < 0) {
00567         xfCloseGroup(xScalarBId);
00568         xfCloseGroup(xDsetsId);
00569         xfCloseFile(xFileId);
00570       }
00571     }
00572   }
00573 
00574   if (!a_Overwrite) {
00575     // Write Coordinate file
00576     status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00577     if (status <= 0) {
00578       xfCloseGroup(xScalarBId);
00579       xfCloseGroup(xDsetsId);
00580       xfCloseFile(xFileId);
00581       return -1;
00582     }
00583 
00584     // For ScalarB, we will set the coordinate system
00585     // to be UTM, with UTM Zone settings written to the file.
00586       // Write Coord Info to file
00587     xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00588     xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00589 
00590     xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00591     xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00592 
00593       // write additional information - we'll use the max value for this test
00594     xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00595 
00596     xfCloseGroup(xCoordId);
00597     xCoordId = 0;
00598   }
00599 
00600   // close the dataset
00601   xfCloseGroup(xScalarBId);
00602   xfCloseGroup(xDsetsId);
00603   xfCloseFile(xFileId);
00604 
00605   return 1;
00606 } // ttWriteScalarB
00607 // --------------------------------------------------------------------------
00608 // FUNCTION ttWriteCoordsToMulti
00609 // PURPOSE  Write coordinate system to a multidataset file
00610 // NOTES
00611 // --------------------------------------------------------------------------
00612 int ttWriteCoordsToMulti (xid a_xFileId)
00613 {
00614   xid   xCoordId = NONE;
00615   int   status;
00616 
00617   // Write Coordinate file - for Multidatasets, we will set the coordinate system
00618   //   to be UTM, with UTM Zone settings written to the file.
00619   status = xfCreateCoordinateGroup(a_xFileId, &xCoordId);
00620   if (status <= 0) {
00621     return -1;
00622   }
00623 
00624    // Write Coord Info to file
00625   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00626   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00627 
00628   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00629   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00630 
00631     // write additional information - we'll use the max value for this test
00632   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00633 
00634   xfCloseGroup(xCoordId);
00635   xCoordId = 0;
00636 
00637   return XTRUE;
00638 } // ttWriteCoordsToMulti
00639 // --------------------------------------------------------------------------
00640 // FUNCTION ttWriteScalarAToMulti
00641 // PURPOSE  Write scalar Dataset to a multidataset
00642 // NOTES    This tests dynamic data sets, and activity
00643 //          This dataset is dynamic concentrations (mg/L) with output times
00644 //          in minutes.
00645 //          Dataset is for a mesh and so nActive is the number of elements
00646 //          which is not the same as the nValues which would be number of nodes
00647 //          reads/writes a reference time in julian days
00648 // --------------------------------------------------------------------------
00649 int ttWriteScalarAToMulti (xid a_GroupId)
00650 {
00651   xid      xScalarAId;
00652   int      nValues = 10, nTimes = 3, nActive = 8;
00653   double   dTime = 0.0;
00654   int      iTimestep, iActive;
00655   float    fValues[10]; // nValues
00656   xmbool    bActivity[10]; // activity
00657   int      status;
00658   double   dJulianReftime;
00659   int      i = 0;
00660 
00661   // 5th item in data set is always inactive, others active
00662   for (iActive = 0; iActive < nActive; iActive++) {
00663     bActivity[iActive] = XTRUE;
00664   }
00665   bActivity[5] = XFALSE;
00666 
00667   // Create the scalar A dataset group
00668   status = xfCreateScalarDataset(a_GroupId, SCALAR_A_LOCATION,
00669                                  "mg/L", TS_HOURS, NONE,
00670                                  &xScalarAId);
00671   
00672   // Add in a reftime.  This is a julian day for:
00673   // noon July 1, 2003
00674   dJulianReftime = 2452822.0;
00675   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00676   if (status < 0) {
00677     xfCloseGroup(xScalarAId);
00678   }
00679 
00680   // Loop through timesteps adding them to the file
00681   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00682     // We will have an 0.5 hour timestep
00683     dTime = (iTimestep + 1) * 0.5;
00684 
00685     fValues[0] = (float)dTime;
00686     for (i = 1; i < nValues; i++) {
00687       fValues[i] = float(fValues[i-1]*2.5);
00688     }
00689 
00690     // write the dataset array values
00691     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00692     if (status >= 0) {
00693       // write activity array
00694       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00695     }
00696     if (status < 0) {
00697       xfCloseGroup(xScalarAId);
00698     }
00699 
00700     status = ttiTestNumTimes( xScalarAId, iTimestep );
00701   }
00702 
00703   // close the dataset
00704   xfCloseGroup(xScalarAId);
00705 
00706   return FALSE;
00707 } // ttWriteScalarAToMulti
00708 // --------------------------------------------------------------------------
00709 // FUNCTION ttReadVector2DAIndex
00710 // PURPOSE  Read all timestep values for a particular index
00711 // NOTES    
00712 // --------------------------------------------------------------------------
00713 int ttReadVector2DAIndex (LPCSTR a_Filename, int a_Index)
00714 {
00715   int     status;
00716   xid     xFileId = NONE, xDsetsId = NONE, xVector2DA = NONE;
00717   int     nTimesteps;
00718   float  *fValues;
00719 
00720   // open the file
00721   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00722   if (status < 0) {
00723     return FALSE;
00724   }
00725 
00726   // open the dataset group
00727   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00728   if (status >= 0) {
00729     status = xfOpenGroup(xDsetsId, VECTOR2D_A_LOCATION, &xVector2DA);
00730   }
00731   if (status < 0) {
00732     return status;
00733   }
00734 
00735   // Find out the number of timesteps in the file
00736   status = xfGetDatasetNumTimes(xVector2DA, &nTimesteps);
00737   if (status < 0) {
00738     return status;
00739   }
00740   if (nTimesteps < 1) {
00741     return -1;
00742   }
00743 
00744   // Read the values for the index
00745   fValues = new float[nTimesteps*2];
00746   status = xfReadVectorValuesAtIndex(xVector2DA, a_Index, 1, nTimesteps, 2,
00747                                      fValues);
00748 
00749   // output the data
00750   printf("\nReading vector 2D A slice at index: %d\n", a_Index);
00751   for (int i = 0; i < nTimesteps; i++) {
00752     printf("%f %f \n", fValues[i*2], fValues[i*2 + 1]);
00753   }
00754   printf("\n");
00755 
00756   delete [] fValues;
00757 
00758   return status;
00759 } // ttReadVector2DAIndex
00760 // --------------------------------------------------------------------------
00761 // FUNCTION ttWriteVector2D_A
00762 // PURPOSE  Write 2D vector dataset to an HDF5 File
00763 // NOTES    This tests dynamic data sets, and activity
00764 //          Add reftime when it is completed
00765 //          This dataset is dynamic water velocities with output times
00766 //          in minutes.
00767 //          Dataset is for a mesh and so nActive is the number of elements
00768 //          which is not the same as the nValues which would be number of nodes
00769 // --------------------------------------------------------------------------
00770 int ttWriteVector2D_A (LPCSTR a_Filename, int a_Compression)
00771 {
00772   xid      xFileId, xDsetsId, xVectorA, xCoordId = NONE;
00773   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00774   double   dTime = 0.0;
00775   int      iTimestep, iActive;
00776   float    fValues[100*2]; // nValues*nComponents
00777   xmbool    bActivity[75]; // activity
00778 //  double   dMin = 0.5, dMax = 3.5;
00779 //  int      nSeedMultiplier = 138592;
00780   int      i, j, status;
00781   int      iHpgnZone;
00782 
00783   // 5th item in data set is always inactive, others active
00784   for (iActive = 0; iActive < nActive; iActive++) {
00785     if (iActive % 3 == 0) {
00786       bActivity[iActive] = XFALSE;
00787     }
00788     else {
00789       bActivity[iActive] = XTRUE;
00790     }
00791   }
00792 
00793   // create the file
00794   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00795   if (status < 0) {
00796     return FALSE;
00797   }
00798 
00799   // create the group to store all datasets 
00800   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00801   if (status < 0) {
00802     xfCloseFile(xFileId);
00803     return FALSE;
00804   }
00805 
00806   // Create the scalar A dataset group
00807   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_A_LOCATION, "ft/s",
00808                TS_SECONDS, a_Compression, &xVectorA);
00809   if (status < 0) {
00810     xfCloseGroup(xDsetsId);
00811     xfCloseFile(xFileId);
00812     return FALSE;
00813   }
00814 
00815   // Loop through timesteps adding them to the file
00816   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00817     // We will have an 0.5 hour timestep
00818     dTime = (iTimestep + 1) * 0.5;
00819 
00820     for (i = 0; i < nValues; i++) {
00821       for (j = 0; j < nComponents; j++) {
00822         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00823       }
00824     }
00825 //    // generate values array using random numbers between dMin and dMax
00826 //    ttiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
00827 //                    nValues*nComponents, fValues);
00828 
00829     // write the dataset array values
00830     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
00831                                    fValues);
00832     if (status >= 0) {
00833       // write activity array
00834       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
00835     }
00836     if (status < 0) {
00837       xfCloseGroup(xVectorA);
00838       xfCloseGroup(xDsetsId);
00839       xfCloseFile(xFileId);
00840     }
00841 
00842     status = ttiTestNumTimes( xVectorA, iTimestep );
00843   }
00844 
00845   // Write Coordinate file - for Vector2D_A, we will set the coordinate system
00846   //   to be Geographic HPGN, with HPGN settings written to the file.
00847   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00848   if (status <= 0) {
00849     xfCloseGroup(xVectorA);
00850     xfCloseGroup(xDsetsId);
00851     xfCloseFile(xFileId);
00852         return -1;
00853   }
00854 
00855     // set HPGN info for test
00856   iHpgnZone = 29;      // Utah
00857 
00858   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00859   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00860   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00861   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00862 
00863     // write additional information
00864   xfSetHPGNArea(xCoordId, iHpgnZone);
00865 
00866   xfCloseGroup(xCoordId);
00867   xCoordId = 0;
00868 
00869   // close the dataset
00870   xfCloseGroup(xVectorA);
00871   xfCloseGroup(xDsetsId);
00872   xfCloseFile(xFileId);
00873 
00874   return FALSE;
00875 } // ttWriteVector2D_A
00876 // --------------------------------------------------------------------------
00877 // FUNCTION ttWriteVector2D_B
00878 // PURPOSE  Write 2D vector dataset to an HDF5 File
00879 // NOTES    This tests dynamic data sets, and activity
00880 //          Add reftime when it is completed
00881 //          This dataset is dynamic water velocities with output times
00882 //          in minutes.
00883 //          Dataset is for a mesh and so nActive is the number of elements
00884 //          which is not the same as the nValues which would be number of nodes
00885 // --------------------------------------------------------------------------
00886 int ttWriteVector2D_B (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00887 {
00888   xid      xFileId, xDsetsId, xVectorB, xCoordId = NONE;
00889   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00890   double   dTime = 0.0;
00891   int      iTimestep, iActive;
00892   float    fValues[100*2]; // nValues*nComponents
00893   xmbool    bActivity[75]; // activity
00894 //  double   dMin = 0.5, dMax = 3.5;
00895 //  int      nSeedMultiplier = 138592;
00896   int      i, j, status;
00897 
00898   // 5th item in data set is always inactive, others active
00899   for (iActive = 0; iActive < nActive; iActive++) {
00900     if (iActive % 3 == 0) {
00901       bActivity[iActive] = XFALSE;
00902     }
00903     else {
00904       bActivity[iActive] = XTRUE;
00905     }
00906   }
00907 
00908   if (a_Overwrite) {
00909       //open the already-existing file
00910     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00911     if (status < 0) {
00912       return -1;
00913     }
00914       // open the group where we have all the datasets
00915     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00916     if (status < 0) {
00917       xfCloseFile(xFileId);
00918       return -1;
00919     }
00920   }
00921   else {
00922       // create the file
00923     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00924     if (status < 0) {
00925       return FALSE;
00926     }
00927       // create the group to store all datasets 
00928     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00929     if (status < 0) {
00930       xfCloseFile(xFileId);
00931       return FALSE;
00932     }
00933   }
00934 
00935   // Create the Vector B dataset group
00936   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_B_LOCATION, "ft/s",
00937                TS_SECONDS, a_Compression, &xVectorB);
00938   if (status < 0) {
00939     xfCloseGroup(xDsetsId);
00940     xfCloseFile(xFileId);
00941     return FALSE;
00942   }
00943 
00944   if (!a_Overwrite) {
00945     // Loop through timesteps adding them to the file
00946     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00947       // We will have an 0.5 hour timestep
00948       dTime = (iTimestep + 1) * 0.5;
00949 
00950       for (i = 0; i < nValues; i++) {
00951         for (j = 0; j < nComponents; j++) {
00952           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00953         }
00954       }
00955 
00956       // write the dataset array values
00957       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
00958                                      fValues);
00959       if (status >= 0) {
00960         // write activity array
00961         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
00962       }
00963       if (status < 0) {
00964         xfCloseGroup(xVectorB);
00965         xfCloseGroup(xDsetsId);
00966         xfCloseFile(xFileId);
00967       }
00968     }
00969   }
00970   else {
00971     // Loop through timesteps adding them to the file
00972     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00973       // We will have an 1.5 hour timestep
00974       dTime = (iTimestep + 1) * 1.5;
00975 
00976       for (i = 0; i < nValues; i++) {
00977         for (j = 0; j < nComponents; j++) {
00978           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00979         }
00980       }
00981 
00982       // write the dataset array values
00983       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
00984                                      fValues);
00985       if (status >= 0) {
00986         // write activity array
00987         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
00988       }
00989       if (status < 0) {
00990         xfCloseGroup(xVectorB);
00991         xfCloseGroup(xDsetsId);
00992         xfCloseFile(xFileId);
00993       }
00994     }
00995   }
00996 
00997   // Write Coordinate file - for ScalarB, we will set the coordinate system
00998   //   to be UTM, with UTM Zone settings written to the file.
00999   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
01000   if (status <= 0) {
01001     xfCloseGroup(xVectorB);
01002     xfCloseGroup(xDsetsId);
01003     xfCloseFile(xFileId);
01004         return -1;
01005   }
01006 
01007     // write the coordinate data to the file
01008   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
01009   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
01010   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
01011   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
01012 
01013     // write additional information - we'll use the max UTM zone for the test
01014   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
01015 
01016   xfCloseGroup(xCoordId);
01017   xCoordId = 0;
01018 
01019   // close the dataset
01020   xfCloseGroup(xVectorB);
01021   xfCloseGroup(xDsetsId);
01022   xfCloseFile(xFileId);
01023 
01024   return 1;
01025 } // ttWriteVector2D_B
01026 // --------------------------------------------------------------------------
01027 // FUNCTION ttWriteVector2DAToMulti
01028 // PURPOSE  Write 2D vector dataset to an HDF5 File
01029 // NOTES    This tests dynamic data sets, and activity
01030 //          Add reftime when it is completed
01031 //          This dataset is dynamic water velocities with output times
01032 //          in minutes.
01033 //          Dataset is for a mesh and so nActive is the number of elements
01034 //          which is not the same as the nValues which would be number of nodes
01035 // --------------------------------------------------------------------------
01036 int ttWriteVector2DAToMulti (xid a_GroupId)
01037 {
01038   xid      xVectorA;
01039   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
01040   double   dTime = 0.0;
01041   int      iTimestep, iActive;
01042   float    fValues[100*2]; // nValues*nComponents
01043   xmbool    bActivity[75]; // activity
01044 //  double   dMin = 0.5, dMax = 3.5;
01045 //  int      nSeedMultiplier = 138592;
01046   int      i, j, status;
01047 
01048   // 5th item in data set is always inactive, others active
01049   for (iActive = 0; iActive < nActive; iActive++) {
01050     if (iActive % 3 == 0) {
01051       bActivity[iActive] = XFALSE;
01052     }
01053     else {
01054       bActivity[iActive] = XTRUE;
01055     }
01056   }
01057 
01058   // Create the scalar A dataset group
01059   status = xfCreateVectorDataset(a_GroupId, VECTOR2D_A_LOCATION, "ft/s",
01060                TS_SECONDS, NONE, &xVectorA);
01061   if (status < 0) {
01062     return FALSE;
01063   }
01064 
01065   // Loop through timesteps adding them to the file
01066   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
01067     // We will have an 0.5 hour timestep
01068     dTime = (iTimestep + 1) * 0.5;
01069 
01070     for (i = 0; i < nValues; i++) {
01071       for (j = 0; j < nComponents; j++) {
01072         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
01073       }
01074     }
01075 //    // generate values array using random numbers between dMin and dMax
01076 //    ttiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
01077 //                    nValues*nComponents, fValues);
01078 
01079     // write the dataset array values
01080     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
01081                                    fValues);
01082     if (status >= 0) {
01083       // write activity array
01084       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
01085     }
01086     if (status < 0) {
01087       xfCloseGroup(xVectorA);
01088     }
01089 
01090     status = ttiTestNumTimes( xVectorA, iTimestep );
01091   }
01092 
01093   // close the dataset
01094   xfCloseGroup(xVectorA);
01095 
01096   return FALSE;
01097 } // ttWriteVector2DAToMulti
01098 // --------------------------------------------------------------------------
01099 // FUNCTION ttiRandomNumberInRange
01100 // PURPOSE  generate Psuedo Random numbers.  We use the same seeds every
01101 //          time so we end up with consistent values for testing purposes.
01102 // --------------------------------------------------------------------------
01103 double ttiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed)
01104 {
01105   int nRandom;
01106   double dValue;
01107 
01108   srand(a_nSeed);
01109   nRandom = rand();
01110 
01111   dValue = a_dMin + ((double)(nRandom)*(a_dMax - a_dMin))/RAND_MAX;
01112 
01113   return dValue;
01114 } // ttiRandomNumberInRange
01115 // --------------------------------------------------------------------------
01116 // FUNCTION ttDatasetArray
01117 // PURPOSE  Get dataset data to use in a dataset
01118 // NOTES    Generates random numbers between a range to fill in the array
01119 // --------------------------------------------------------------------------
01120 void ttiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
01121                      int a_SeedMultiplier, int a_nValues, float *a_Array)
01122 {
01123   int       i, nSeedBase;
01124 
01125   for (i = 0; i < a_nValues; i++) {
01126     nSeedBase = a_nCycle*a_nValues + i;
01127     a_Array[i] = (float)ttiRandomNumberInRange(a_dMin, a_dMax, 
01128                                               nSeedBase*a_SeedMultiplier);
01129   }
01130 } // ttDatasetArray
01131 // --------------------------------------------------------------------------
01132 // FUNCTION ttiReadScalar
01133 // PURPOSE  Read a scalar from an XMDF file and output information to
01134 //          to a text file
01135 // NOTES    
01136 // --------------------------------------------------------------------------
01137 int ttiReadScalar (xid a_xScalarId, FILE *a_fp)
01138 {
01139   int    nTimes = NONE, nValues = NONE, nActive = NONE;
01140   int    nStatus = TRUE, iTime, iVal, iActive;
01141   char   TimeUnits[100], Units[100];
01142   double *Times = NULL;
01143   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01144   xmbool  *Active = NULL;
01145   xmbool  bUseReftime;
01146   double Reftime;
01147 
01148   // read the time units
01149   nStatus = xfGetDatasetTimeUnits(a_xScalarId, TimeUnits);
01150   if (nStatus < 0) {
01151     return nStatus;
01152   }
01153   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01154 
01155   // see if we are using a reftime
01156   nStatus = xfUseDatasetReftime(a_xScalarId, &bUseReftime);
01157   if (nStatus < 0) {
01158     return nStatus;
01159   }
01160   if (bUseReftime) {
01161     nStatus = xfReadDatasetReftime(a_xScalarId, &Reftime);
01162     if (nStatus < 0) {
01163       return nStatus;
01164     }
01165     fprintf(a_fp, "Reftime: %f\n", Reftime);
01166   }
01167 
01168   // read the units
01169   nStatus = xfGetDatasetUnits(a_xScalarId, Units);
01170   if (nStatus < 0) { 
01171     return nStatus;
01172   }
01173   fprintf(a_fp, "units: %s\n", Units);
01174 
01175   // read in the number of values and number of active values
01176   nStatus = xfGetDatasetNumVals(a_xScalarId, &nValues);
01177   if (nStatus >= 0) {
01178     nStatus = xfGetDatasetNumActive(a_xScalarId, &nActive);
01179   }
01180   if (nStatus < 0) {
01181     return nStatus;
01182   }
01183 
01184   if (nValues <= 0) {
01185     printf("No data to read in.");
01186     return -1;
01187   }
01188 
01189   // read in the number of times
01190   nStatus = xfGetDatasetNumTimes(a_xScalarId, &nTimes);
01191   if (nStatus < 0) {
01192     return nStatus;
01193   }
01194 
01195   // Read in the individual time values
01196   Times = (double *)malloc(nTimes*sizeof(double));
01197   if (Times == NULL) {
01198     printf("Out of memory");
01199     return -1;
01200   }
01201   nStatus = xfGetDatasetTimes(a_xScalarId, nTimes, Times);
01202   if (nStatus < 0) {
01203     return nStatus;
01204   }
01205 
01206   // Read in the minimum and maximum values
01207   Mins = (float *)malloc(nTimes*sizeof(float));
01208   Maxs = (float *)malloc(nTimes*sizeof(float));
01209   if (Mins == NULL || Maxs == NULL) {
01210     free(Times);
01211     printf("Out of memory");
01212     return -1;
01213   }
01214 
01215   nStatus = xfGetDatasetMins(a_xScalarId, nTimes, Mins);
01216   if (nStatus >= 0) {
01217     nStatus = xfGetDatasetMaxs(a_xScalarId, nTimes, Maxs);
01218   }
01219   if (nStatus < 0) {
01220     free(Times);
01221     free(Mins);
01222     free(Maxs);
01223     return nStatus;
01224   }
01225 
01226   Values = (float *)malloc(nValues*sizeof(float));
01227   if (nActive > 0) {
01228     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01229   }
01230 
01231   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01232   fprintf(a_fp, "Number Values: %d\n", nValues);
01233   fprintf(a_fp, "Number Active: %d\n", nActive);
01234 
01235   // loop through the timesteps, read the values and active values and write
01236   // them to the text file
01237   for (iTime = 0; iTime < nTimes; iTime++) {
01238       // indices should be 1 based
01239     nStatus = xfReadScalarValuesTimestep(a_xScalarId, iTime + 1,
01240                                          nValues, Values);
01241     if (nStatus >= 0 && nActive > 0) {
01242         // indices should be 1 based
01243       nStatus = xfReadActivityTimestep(a_xScalarId, iTime + 1, nActive, Active);
01244     }
01245 
01246     // Write the time, min, max, values and active values to the text output
01247     // file.
01248     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01249                   Times[iTime], Mins[iTime], Maxs[iTime]);
01250 
01251     fprintf(a_fp, "Values:\n");
01252     // print 5 values per line
01253     for (iVal = 0; iVal < nValues; iVal++) {
01254       fprintf(a_fp, "%6.3f ", Values[iVal]);
01255       if ((iVal + 1) % 5 == 0) {
01256         fprintf(a_fp, "\n");
01257       }
01258     }
01259     fprintf(a_fp, "\n");
01260 
01261     fprintf(a_fp, "Activity:\n");
01262     // print 5 values per line
01263     for (iActive = 0; iActive < nActive; iActive++) {
01264       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01265       if ((iActive + 1) % 5 == 0) {
01266         fprintf(a_fp, "\n");
01267       }
01268     }
01269     fprintf(a_fp, "\n\n");
01270   }
01271 
01272   if (Times) {
01273     free(Times);
01274     Times = NULL;
01275   }
01276   
01277   if (Mins) {
01278     free(Mins);
01279     Mins = NULL;
01280   }
01281 
01282   if (Maxs) {
01283     free(Maxs);
01284     Maxs = NULL;
01285   }
01286 
01287   if (Values) {
01288     free(Values);
01289     Values = NULL;
01290   }
01291 
01292   if (Active) {
01293     free(Active);
01294     Active = NULL;
01295   }
01296 
01297   return TRUE;
01298 } // ttiReadScalar
01299 // --------------------------------------------------------------------------
01300 // FUNCTION ttiReadVector
01301 // PURPOSE  Read a vector from an XMDF file and output information to
01302 //          to a text file
01303 // NOTES    
01304 // --------------------------------------------------------------------------
01305 int ttiReadVector (xid a_xVectorId, FILE *a_fp)
01306 {
01307   int    nTimes = NONE, nValues = NONE, nComponents = NONE, nActive = NONE;
01308   int    nStatus = TRUE, iTime, iVal, iActive;
01309   char   TimeUnits[100];
01310   double *Times = NULL;
01311   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01312   xmbool  *Active = NULL;
01313   xmbool  bUseReftime;
01314   double Reftime;
01315 
01316   // read the time units
01317   nStatus = xfGetDatasetTimeUnits(a_xVectorId, TimeUnits);
01318   if (nStatus < 0) {
01319     return nStatus;
01320   }
01321   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01322 
01323   // see if we are using a reftime
01324   nStatus = xfUseDatasetReftime(a_xVectorId, &bUseReftime);
01325   if (nStatus < 0) {
01326     return nStatus;
01327   }
01328   if (bUseReftime) {
01329     nStatus = xfReadDatasetReftime(a_xVectorId, &Reftime);
01330     if (nStatus < 0) {
01331       return nStatus;
01332     }
01333     fprintf(a_fp, "Reftime: %f", Reftime);
01334   }
01335 
01336   // read in the number of values and number of active values
01337   nStatus = xfGetDatasetNumVals(a_xVectorId, &nValues);
01338   if (nStatus >= 0) {
01339     nStatus = xfGetDatasetVecNumComponents(a_xVectorId, &nComponents);
01340     if (nStatus >= 0) {
01341       nStatus = xfGetDatasetNumActive(a_xVectorId, &nActive);
01342     }
01343   }
01344   if (nStatus < 0) {
01345     return nStatus;
01346   }
01347 
01348   if (nValues <= 0) {
01349     printf("No data to read in.");
01350     return -1;
01351   }
01352 
01353   // read in the number of times
01354   nStatus = xfGetDatasetNumTimes(a_xVectorId, &nTimes);
01355   if (nStatus < 0) {
01356     return nStatus;
01357   }
01358 
01359   // Read in the individual time values
01360   Times = (double *)malloc(nTimes*sizeof(double));
01361   if (Times == NULL) {
01362     printf("Out of memory");
01363     return -1;
01364   }
01365   nStatus = xfGetDatasetTimes(a_xVectorId, nTimes, Times);
01366   if (nStatus < 0) {
01367     return nStatus;
01368   }
01369 
01370   // Read in the minimum and maximum values
01371   Mins = (float *)malloc(nTimes*sizeof(float));
01372   Maxs = (float *)malloc(nTimes*sizeof(float));
01373   if (Mins == NULL || Maxs == NULL) {
01374     free(Times);
01375     printf("Out of memory");
01376     return -1;
01377   }
01378 
01379   nStatus = xfGetDatasetMins(a_xVectorId, nTimes, Mins);
01380   if (nStatus >= 0) {
01381     nStatus = xfGetDatasetMaxs(a_xVectorId, nTimes, Maxs);
01382   }
01383   if (nStatus < 0) {
01384     free(Times);
01385     free(Mins);
01386     free(Maxs);
01387     return nStatus;
01388   }
01389 
01390   Values = (float *)malloc(nValues*nComponents*sizeof(float));
01391   if (nActive > 0) {
01392     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01393   }
01394 
01395   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01396   fprintf(a_fp, "Number Values: %d\n", nValues);
01397   fprintf(a_fp, "Number Components: %d\n", nComponents);
01398   fprintf(a_fp, "Number Active: %d\n", nActive);
01399 
01400   // loop through the timesteps, read the values and active values and write
01401   // them to the text file
01402   for (iTime = 0; iTime < nTimes; iTime++) {
01403     nStatus = xfReadVectorValuesTimestep(a_xVectorId, iTime + 1,
01404                                          nValues, nComponents, Values);
01405     if (nStatus >= 0 && nActive > 0) {
01406       nStatus = xfReadActivityTimestep(a_xVectorId, iTime + 1, nActive, Active);
01407     }
01408 
01409     // Write the time, min, max, values and active values to the text output
01410     // file.
01411     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01412                   Times[iTime], Mins[iTime], Maxs[iTime]);
01413 
01414     fprintf(a_fp, "Values:\n");
01415     // print a set of vector values per line
01416     for (iVal = 0; iVal < nValues; iVal++) {
01417       fprintf(a_fp, "%6.3f %6.3f\n", Values[iVal*nComponents], 
01418                                      Values[(iVal*nComponents) + 1]);
01419     }
01420     fprintf(a_fp, "\n");
01421 
01422     fprintf(a_fp, "Activity:\n");
01423     // print 5 values per line
01424     for (iActive = 0; iActive < nActive; iActive++) {
01425       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01426       if ((iActive + 1) % 5 == 0) {
01427         fprintf(a_fp, "\n");
01428       }
01429     }
01430     fprintf(a_fp, "\n\n");
01431   }
01432 
01433   if (Times) {
01434     free(Times);
01435     Times = NULL;
01436   }
01437   
01438   if (Mins) {
01439     free(Mins);
01440     Mins = NULL;
01441   }
01442 
01443   if (Maxs) {
01444     free(Maxs);
01445     Maxs = NULL;
01446   }
01447 
01448   if (Values) {
01449     free(Values);
01450     Values = NULL;
01451   }
01452 
01453   if (Active) {
01454     free(Active);
01455     Active = NULL;
01456   }
01457 
01458   return TRUE;
01459 } // ttiReadVector
01460 
01461 // --------------------------------------------------------------------------
01462 // FUNCTION ttiTestNumTimes
01463 // PURPOSE  Change the NumTimes to truncate timesteps
01464 // NOTES    
01465 // --------------------------------------------------------------------------
01466 int ttiTestNumTimes( xid a_DatasetId, int a_Itimestep )
01467 {
01468   int status = 1;
01469 
01470   // truncate just written timestep and test error conditions
01471   if (1 == a_Itimestep ||
01472       3 == a_Itimestep ||
01473       5 == a_Itimestep)
01474     {
01475       int NumTimes;
01476 
01477       // Test setting NumTimes after end of dataset
01478       status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep + 2 );
01479       if (status >= 0)
01480         printf( "%d: ERROR: xfSetDatasetNumTimes must return ERROR.\n",
01481                 __LINE__ );
01482 
01483       if (1 == a_Itimestep) a_Itimestep = 1;
01484       if (3 == a_Itimestep) a_Itimestep = 2;
01485       if (5 == a_Itimestep) a_Itimestep = 3;
01486 
01487       // Write actual NumTimes
01488       status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep );
01489       if (status < 0)
01490         printf( "%d: ERROR: xfSetDatasetNumTimes must NOT return error.\n",
01491                 __LINE__ );
01492 
01493       // Test setting NumTimes after end step.
01494       status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep + 1 );
01495       if (status >= 0)
01496         printf( "%d: ERROR: xfSetDatasetNumTimes must return ERROR.\n",
01497                 __LINE__ );
01498 
01499       // Test reading NumTimes
01500       status = xfGetDatasetNumTimes( a_DatasetId, &NumTimes );
01501       if (status < 0)
01502         printf( "%d: ERROR: xfGetDatasetNumTimes must NOT return error.\n",
01503                 __LINE__ );
01504       if (NumTimes != a_Itimestep)
01505         printf( "%d: ERROR: xfGetDatasetNumTimes must return CORRECT NumTimes.\n",
01506                 __LINE__ );
01507     }
01508 
01509   return status;
01510 }
TestTimestep.cpp tests timesteps

00001 // TestXFormat.cpp : Defines the entry point for the console application.
00002 //
00003 
00004 #include "stdafx.h"
00005 #include <hdf5.h>
00006 #include <Xmdf.h>
00007 #include <Xmdf_private.h>
00008 #include <stdio.h>
00009 #include <windows.h>
00010 #include <string.h>
00011 #include <stdlib.h>
00012 #include "TestTimestep.h"
00013 #include "TestDatasets.h"
00014 #include "TestMesh.h"
00015 #include "TestGrid.h"
00016 #include "TestGeomPaths.h"
00017 #include "TestXmdf.h"
00018 
00019 #define NUMTIMES1 5
00020 #define NUMVALUES1 5
00021 #define NUMACTIVE1 3
00022 
00023 #define NUMTIMESADD 1
00024 
00025 int txiTestCalendar();
00026 int txiTestCoordSystem(xid xGroupId, FILE *a_OutFile);
00027 int txiTestDatasets();
00028 int txiTestFortran();
00029 int txiTestGeometricPaths();
00030 int txiTestGrids();
00031 int txiTestMeshs();
00032 int txiTestOverwriteDsets();
00033 int txiTestTimesteps();
00034 int txiTestVersion();
00035 int txiReadXFormatFile(LPCSTR a_XmdfFile, LPCSTR a_OutFile);
00036 int txiReadXFormatFileT (LPCSTR a_XmdfFile, LPCSTR a_OutFile);
00037 
00038 
00039 //-----------------------------------------------------------------------------
00040 // FUNCTION  main
00041 // PURPOSE   runs the test cases for XMDF
00042 // NOTES
00043 //-----------------------------------------------------------------------------
00044 int main()
00045 {
00046   ::txiReadXFormatFile("C:\\SMS\\Testcases\\bugs\\adcp_observed\\sms_adcp_observed - pete_comb_vel_vector (2).h5",
00047                        "C:\\SMS\\Testcases\\bugs\\adcp_observed\\sms_adcp_observed out.txt");
00048 
00049 #if 1
00050   // test the timestep routines
00051   txiTestTimesteps();
00052   printf("=== Finished testing timesteps ===\n");
00053 
00054   // test the dataset routines
00055   txiTestDatasets();
00056   printf("=== Finished testing datasets ===\n");
00057 
00058   // test overwriting already-existing datasets
00059   txiTestOverwriteDsets();
00060 
00061   // Test Mesh stuff
00062   txiTestMeshs();
00063 
00064   // Test grid stuff
00065   txiTestGrids();
00066 
00067   // Test writing particle paths
00068   txiTestGeometricPaths();
00069 
00070   // Test reading files that were written by fortan.
00071   txiTestFortran();
00072 
00073   // Test Calendar Conversion Stuff
00074   txiTestCalendar();
00075 
00076   // Test reading the version written to the files
00077   txiTestVersion();
00078 #endif
00079 
00080 
00081   printf("Press ENTER to Exit...");
00082   char pause[1024];
00083 
00084   scanf("%c", pause);
00085    
00086   return 0;
00087 }
00088 
00089 //-----------------------------------------------------------------------------
00090 // FUNCTION  txiTestTimesteps
00091 // PURPOSE
00092 // NOTES
00093 //-----------------------------------------------------------------------------
00094 int txiTestTimesteps()
00095 {
00096   const char *SCALAR_A_FILE_C = "TT_ScalarA_c.h5";
00097   const char *SCALAR_A_TEXT_C = "TT_ScalarA_c.txt";
00098   const char *VECTOR2D_A_FILE_C = "TT_Vector2D_A_c.h5";
00099   const char *VECTOR2D_A_TEXT_C = "TT_Vector2D_A_c.txt";
00100 
00101   const char *MULTIDATASET_FILE_C = "TT_MultiDataSet_c.h5";
00102   const char *MULTIDATASET_TEXT_C = "TT_MultiDataSet_c.txt";
00103 
00104   int status = 1;
00105   int compression = NONE;
00106   xid  MultiFileId=NONE, MultiGroupId=NONE;
00107   int         NumOpen=0;
00108 
00109   char SdoGuid[37];
00110 
00111   strcpy(SdoGuid, "73289C80-6235-4fdc-9649-49E4F5AEB676");
00112 
00113   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00114            SdoGuid, XF_OVERWRITE_CLEAR_FILE, &MultiFileId, &MultiGroupId);
00115 
00116   // Write coordinates to multidatasets
00117   ttWriteCoordsToMulti(MultiFileId);
00118 
00119  // Write scalar A and Vector A to multidatasets.
00120   ttWriteScalarAToMulti(MultiGroupId);
00121 
00122   ttWriteVector2DAToMulti(MultiGroupId);
00123 
00124   xfCloseGroup(MultiGroupId);
00125   xfCloseFile(MultiFileId);
00126   printf("Done writing multiple datasets...\n");
00127 
00128 
00129   // scalar datasets
00130   status = ttWriteScalarA(SCALAR_A_FILE_C, compression);
00131   if (status < 0) {
00132     return status;
00133   }
00134   
00135   printf("Done writing scalar datasets...\n");
00136 
00137   // vector datasets
00138   status = ttWriteVector2D_A(VECTOR2D_A_FILE_C, compression);
00139   if (status < 0) {
00140     printf("Error writing dataset vector2D_A.");
00141     return status;
00142   }
00143 
00144   printf("Done writing vector datasets...\n");
00145 
00146   printf("Done writing datasets...\n");
00147 
00148   // Read the files back in
00149   status = txiReadXFormatFileT(SCALAR_A_FILE_C, SCALAR_A_TEXT_C);
00150   if (status < 0) {
00151     return status;
00152   }
00153 
00154   status = txiReadXFormatFileT(VECTOR2D_A_FILE_C, VECTOR2D_A_TEXT_C);
00155   if (status < 0) {
00156     return status;
00157   }
00158 
00159   status = txiReadXFormatFileT(MULTIDATASET_FILE_C, MULTIDATASET_TEXT_C);
00160   if (status < 0) {
00161     return status;
00162   }
00163 
00164   printf("Done reading datasets...\n");
00165 
00166   xfGetNumOpenIdentifiers(H5F_OBJ_ALL, &NumOpen);
00167 
00168   xfpCloseOpenIdentifiers(H5F_OBJ_ALL);
00169 
00170   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00171      SdoGuid, XF_OVERWRITE_CLEAR_DATASET_GROUP, &MultiFileId, &MultiGroupId);
00172 
00173   ttWriteScalarAToMulti(MultiGroupId);
00174 
00175   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00176      SdoGuid, XF_OVERWRITE_NONE, &MultiFileId, &MultiGroupId);
00177 
00178   ttWriteVector2DAToMulti(MultiGroupId);
00179 
00180 
00181   // Test reading information at index for multiple timesteps
00182   status = ttReadScalarAIndex(SCALAR_A_FILE_C, 2);
00183   if (status < 0) {
00184     return status;
00185   }
00186   printf("Done reading scalar data at index.\n");
00187   
00188   status = ttReadVector2DAIndex(VECTOR2D_A_FILE_C, 4);
00189   if (status < 0) {
00190     return status;
00191   }
00192   printf("Done reading vector data at index.\n");
00193 
00194   status = ttReadActivityScalarAIndex(SCALAR_A_FILE_C, 5);
00195   if (status < 0) {
00196     return status;
00197   }
00198 
00199   return status;
00200 } // txiTestTimesteps
00201 
00202 //-----------------------------------------------------------------------------
00203 // #defines used in txiTestDatasets
00204 //-----------------------------------------------------------------------------
00205 #define XMDF_VERSION_OUT_C "XMDF_Version_c.txt"
00206 
00207 #define SCALAR_A_FILE_C "ScalarA_c.h5"
00208 #define SCALAR_A_TEXT_C "ScalarA_c.txt"
00209 #define VECTOR2D_A_FILE_C "Vector2D_A_c.h5"
00210 #define VECTOR2D_A_TEXT_C "Vector2D_A_c.txt"
00211 
00212 #define SCALAR_A_FILE_F "ScalarA_f.h5"
00213 #define SCALAR_A_TEXT_FC "ScalarA_fc.txt"
00214 #define VECTOR2D_A_FILE_F "Vector2D_A_f.h5"
00215 #define VECTOR2D_A_TEXT_FC "Vector2D_A_fc.txt"
00216 
00217 #define MULTIDATASET_FILE_C "MultiDataSet_c.h5"
00218 #define MULTIDATASET_TEXT_C "MultiDataSet_c.txt"
00219 
00220 //-----------------------------------------------------------------------------
00221 // FUNCTION  txiTestDatasets
00222 // PURPOSE
00223 // NOTES
00224 //-----------------------------------------------------------------------------
00225 int txiTestDatasets()
00226 {
00227   int status = 1;
00228   int compression = NONE;
00229   xid  MultiFileId=NONE, MultiGroupId=NONE;
00230   int         NumOpen=0;
00231 
00232   char SdoGuid[37];
00233 
00234   strcpy(SdoGuid, "73289C80-6235-4fdc-9649-49E4F5AEB676");
00235 
00236   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00237            SdoGuid, XF_OVERWRITE_CLEAR_FILE, &MultiFileId, &MultiGroupId);
00238 
00239   // Write coordinates to multidatasets
00240   tdWriteCoordsToMulti(MultiFileId);
00241 
00242  // Write scalar A and Vector A to multidatasets.
00243   tdWriteScalarAToMulti(MultiGroupId);
00244 
00245   tdWriteVector2DAToMulti(MultiGroupId);
00246 
00247   xfCloseGroup(MultiGroupId);
00248   xfCloseFile(MultiFileId);
00249   printf("Done writing multiple datasets...\n");
00250 
00251 
00252   // scalar datasets
00253   status = tdWriteScalarA(SCALAR_A_FILE_C, compression);
00254   if (status < 0) {
00255     return status;
00256   }
00257   
00258   printf("Done writing scalar datasets...\n");
00259 
00260   // vector datasets
00261   status = tdWriteVector2D_A(VECTOR2D_A_FILE_C, compression);
00262   if (status < 0) {
00263     printf("Error writing dataset vector2D_A.");
00264     return status;
00265   }
00266 
00267   printf("Done writing vector datasets...\n");
00268 
00269   printf("Done writing datasets...\n");
00270 
00271   // Read the files back in
00272   status = txiReadXFormatFile(SCALAR_A_FILE_C, SCALAR_A_TEXT_C);
00273   if (status < 0) {
00274     return status;
00275   }
00276 
00277   status = txiReadXFormatFile(VECTOR2D_A_FILE_C, VECTOR2D_A_TEXT_C);
00278   if (status < 0) {
00279     return status;
00280   }
00281 
00282   status = txiReadXFormatFile(MULTIDATASET_FILE_C, MULTIDATASET_TEXT_C);
00283   if (status < 0) {
00284     return status;
00285   }
00286 
00287   printf("Done reading datasets...\n");
00288 
00289   xfGetNumOpenIdentifiers(H5F_OBJ_ALL, &NumOpen);
00290 
00291   xfpCloseOpenIdentifiers(H5F_OBJ_ALL);
00292 
00293   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00294      SdoGuid, XF_OVERWRITE_CLEAR_DATASET_GROUP, &MultiFileId, &MultiGroupId);
00295 
00296   tdWriteScalarAToMulti(MultiGroupId);
00297 
00298   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00299      SdoGuid, XF_OVERWRITE_NONE, &MultiFileId, &MultiGroupId);
00300 
00301   tdWriteVector2DAToMulti(MultiGroupId);
00302 
00303 
00304   // Test reading information at index for multiple timesteps
00305   status = tdReadScalarAIndex(SCALAR_A_FILE_C, 2);
00306   if (status < 0) {
00307     return status;
00308   }
00309   printf("Done reading scalar data at index.\n");
00310   
00311   status = tdReadVector2DAIndex(VECTOR2D_A_FILE_C, 4);
00312   if (status < 0) {
00313     return status;
00314   }
00315   printf("Done reading vector data at index.\n");
00316 
00317   status = tdReadActivityScalarAIndex(SCALAR_A_FILE_C, 5);
00318   if (status < 0) {
00319     return status;
00320   }
00321 
00322   return status;
00323 } // txiTestDatasets
00324 
00325 #define GEOMPATH_A_FILE_C "geompath_a_file_c.h5"
00326 #define GEOMPATH_A_FILE_COUT "geompath_a_file_c_out.txt"
00327 
00328 int txiTestGeometricPaths()
00329 {
00330   int status = 1;
00331   int compression = NONE;
00332     /* test writing a geometric path file */
00333   printf("\n\nWriting geometric path data.\n\n");
00334  
00335   status = tmWriteTestPaths(GEOMPATH_A_FILE_C, compression);
00336   if (status <= 0) {
00337     printf("Error writing geometric path data A\n");
00338   }
00339   printf("Finished writing geometric path data A\n");
00340 
00341     /* test reading a geometric path file */
00342   status = tmReadTestPaths(GEOMPATH_A_FILE_C, GEOMPATH_A_FILE_COUT);
00343 
00344   return status;
00345 }
00346 
00347 //-----------------------------------------------------------------------------
00348 // #defines used in txiTestOverwriteDsets
00349 //-----------------------------------------------------------------------------
00350 
00351 #define SCALAR_B_FILE_C "ScalarB_c.h5"
00352 #define SCALAR_B_TEXT_C "ScalarB_c.txt"
00353 #define VECTOR2D_B_FILE_C "Vector2D_B_c.h5"
00354 #define VECTOR2D_B_TEXT_C "Vector2D_B_c.txt"
00355 
00356 #define SCALAR_B_FILE_F "ScalarB_f.h5"
00357 #define SCALAR_B_TEXT_FC "ScalarB_fc.txt"
00358 #define VECTOR2D_B_FILE_F "Vector2D_B_f.h5"
00359 #define VECTOR2D_B_TEXT_FC "Vector2D_B_fc.txt"
00360 
00361 //-----------------------------------------------------------------------------
00362 // FUNCTION  txiTestOverwriteDsets
00363 // PURPOSE   Check to see if already-written datasets can be overwritten
00364 // NOTES
00365 //-----------------------------------------------------------------------------
00366 int txiTestOverwriteDsets()
00367 {
00368   int status = 1;
00369   int compression = NONE;
00370 
00371     // scalar datasets
00372   status = tdWriteScalarB(SCALAR_B_FILE_C, compression, 0);
00373   if (status < 0) {
00374     return status;
00375   }
00376     // overwrite scalar datasets
00377   status = tdWriteScalarB(SCALAR_B_FILE_C, compression, 1);
00378   if (status < 0) {
00379     return status;
00380   }
00381   
00382     // vector datasets
00383   status = tdWriteVector2D_B(VECTOR2D_B_FILE_C, compression, 0);
00384   if (status < 0) {
00385     printf("Error writing dataset vector2D_B.");
00386     return status;
00387   }
00388     // overwrite vector datasets
00389   status = tdWriteVector2D_B(VECTOR2D_B_FILE_C, compression, 1);
00390   if (status < 0) {
00391     printf("Error writing dataset vector2D_B.");
00392     return status;
00393   }
00394 
00395   // Read the files back in
00396   status = txiReadXFormatFile(SCALAR_B_FILE_C, SCALAR_B_TEXT_C);
00397   if (status < 0) {
00398     return status;
00399   }
00400 
00401   status = txiReadXFormatFile(VECTOR2D_B_FILE_C, VECTOR2D_B_TEXT_C);
00402   if (status < 0) {
00403     return status;
00404   }
00405 
00406   return status;
00407 } // txiTestDatasets
00408 
00409 //-----------------------------------------------------------------------------
00410 // #defines used in txiTestGrids
00411 //-----------------------------------------------------------------------------
00412 
00413 #define GRID_CART2D_A_FILE_C "grid_cart2d_a_file_c.h5"
00414 #define GRID_CURV2D_A_FILE_C "grid_curv2d_a_file_c.h5"
00415 #define GRID_CART3D_A_FILE_C "grid_cart3d_a_file_c.h5"
00416 
00417 #define GRID_CART2D_A_OUT_C "grid_cart2d_a_out_c.txt"
00418 #define GRID_CURV2D_A_OUT_C "grid_curv2d_a_out_c.txt"
00419 #define GRID_CART3D_A_OUT_C "grid_cart3d_a_out_c.txt"
00420 
00421 #define GRID_CART2D_A_FILE_F "grid_cart2d_a_file_f.h5"
00422 #define GRID_CURV2D_A_FILE_F "grid_curv2d_a_file_f.h5"
00423 #define GRID_CART3D_A_FILE_F "grid_cart3d_a_file_f.h5"
00424 
00425 #define GRID_CART2D_A_OUT_FC "grid_cart2d_a_out_fc.txt"
00426 #define GRID_CURV2D_A_OUT_FC "grid_curv2d_a_out_fc.txt"
00427 #define GRID_CART3D_A_OUT_FC "grid_cart3d_a_out_fc.txt"
00428 
00429 //-----------------------------------------------------------------------------
00430 // FUNCTION  txiTestGrids
00431 // PURPOSE
00432 // NOTES
00433 //-----------------------------------------------------------------------------
00434 int txiTestGrids()
00435 {
00436   int status = 1;
00437   int compression = NONE;
00438 
00439   printf("\n\nWriting grid data.\n\n");
00440  
00441   status = tgWriteTestGridCart2D(GRID_CART2D_A_FILE_C, compression);
00442   if (status < 0) {
00443     printf("Error writing grid Cartesian 2D A\n");
00444   }
00445   printf("Finished writing grid Cartesian 2D A\n");
00446 
00447   status = tgWriteTestGridCurv2D(GRID_CURV2D_A_FILE_C, compression);
00448   if (status < 0) {
00449     printf("Error writing grid Curvilinear 2D A\n");
00450   }
00451   printf("Finished writing grid Curvilinear 2D A\n");
00452 
00453   status = tgWriteTestGridCart3D(GRID_CART3D_A_FILE_C, compression);
00454   if (status < 0) {
00455     printf("Error writing grid Cartesian 3D A\n");
00456   }
00457   printf("Finished writing grid Cartesian 3D A\n"); 
00458   
00459 
00460   // read the files back in
00461   status = txiReadXFormatFile(GRID_CART2D_A_FILE_C, GRID_CART2D_A_OUT_C);
00462   if (status < 0) {
00463     printf("Error reading grid Cartesian 2D A\n");
00464   }
00465   printf("Finished reading grid Cartesian 2D A\n");
00466 
00467   status = txiReadXFormatFile(GRID_CURV2D_A_FILE_C, GRID_CURV2D_A_OUT_C);
00468   if (status < 0) {
00469     printf("Error reading grid Curvilinear 2D A\n");
00470   }
00471   printf("Finished reading grid Curvilinear 2D A\n");
00472 
00473   status = txiReadXFormatFile(GRID_CART3D_A_FILE_C, GRID_CART3D_A_OUT_C);
00474   if (status < 0) {
00475     printf("Error reading grid Cartesian 3D A\n");
00476   }
00477   printf("Finished reading grid Cartesian 3D A\n"); 
00478  
00479 
00480   return status;
00481 } // txiTestGrids
00482 
00483 //-----------------------------------------------------------------------------
00484 // #defines used in txiTestMeshs
00485 //-----------------------------------------------------------------------------
00486 
00487 #define MESH_A_FILE_C  "mesh_a_file_c.h5"
00488 #define MESH_B_FILE_C  "mesh_b_file_c.h5"
00489 #define MESH_A_OUT_C   "mesh_a_file_c.txt"
00490 #define MESH_B_OUT_C   "mesh_b_file_c.txt"
00491 
00492 #define MESH_A_FILE_F  "mesh_a_file_f.h5"
00493 #define MESH_B_FILE_F  "mesh_b_file_f.h5"
00494 #define MESH_A_OUT_FC  "mesh_a_file_fc.txt"
00495 #define MESH_B_OUT_FC  "mesh_b_file_fc.txt"
00496 
00497 // ---------------------------------------------------------------------------
00498 // FUNCTION  txiTestMeshs
00499 // PURPOSE   
00500 // NOTES     
00501 // ---------------------------------------------------------------------------
00502 int txiTestMeshs ()
00503 {
00504   int status = 1;
00505   int compression = NONE;
00506 
00507   status = tmWriteTestMeshA(MESH_A_FILE_C, compression);
00508   if (status != TRUE) {
00509     printf("Error writing TestMeshA\n");
00510     return status;
00511   }
00512 
00513   status = tmWriteTestMeshB(MESH_B_FILE_C, compression);
00514   if (status != TRUE) {
00515     printf("Error writing TestMeshB\n");
00516     return status;
00517   }
00518 
00519   printf("Finished writing meshes.\n");
00520 
00521   // read the files back in
00522   status = txiReadXFormatFile(MESH_A_FILE_C, MESH_A_OUT_C);
00523   if (status != TRUE) {
00524     printf("Error reading TestMeshA\n");
00525     return status;
00526   }
00527 
00528   // read the files back in
00529   status = txiReadXFormatFile(MESH_B_FILE_C, MESH_B_OUT_C);
00530   if (status != TRUE) {
00531     printf("Error reading TestMeshB\n");
00532     return status;
00533   }
00534 
00535   printf("Finished reading meshes.\n");
00536 
00537   return status;
00538 } // txiTestMeshs
00539 // ---------------------------------------------------------------------------
00540 // FUNCTION  txiTestFortran
00541 // PURPOSE   test to see if C code can read file written with fortran.
00542 // NOTES     
00543 // ---------------------------------------------------------------------------
00544 int txiTestFortran ()
00545 {
00546   xid    xFileId = 0;
00547   herr_t (*old_func)(void*);
00548   int     status = 1;
00549   int     nStatus = 1;
00550   void    *old_client_data;
00551 
00552     // Check to see if files written with C exist
00553   H5Eget_auto(&old_func, &old_client_data);
00554     // Turn off error handling
00555   H5Eset_auto(NULL, NULL);
00556 
00557     // Try opening a file written with C to see if one exists.
00558   nStatus = xfOpenFile(SCALAR_A_FILE_F, &xFileId, XTRUE);
00559     // If the file written with FORTRAN doesn't exist, return.
00560   if (nStatus < 0) {
00561     xfCloseFile(xFileId);
00562       // Restore previous error handler
00563     H5Eset_auto(old_func, old_client_data);
00564     return FALSE;
00565       // If the file written with C does exist, assume all C files exist.
00566   }
00567   else {
00568     xfCloseFile(xFileId);
00569       // Restore previous error handler
00570     H5Eset_auto(old_func, old_client_data);
00571   }
00572 
00573   // Read the files back in
00574   status = txiReadXFormatFile(SCALAR_A_FILE_F, SCALAR_A_TEXT_FC);
00575   if (status < 0) {
00576     return status;
00577   }
00578   status = txiReadXFormatFile(SCALAR_B_FILE_F, SCALAR_B_TEXT_FC);
00579   if (status < 0) {
00580     return status;
00581   }
00582 
00583   status = txiReadXFormatFile(VECTOR2D_A_FILE_F, VECTOR2D_A_TEXT_FC);
00584   if (status < 0) {
00585     return status;
00586   }
00587   status = txiReadXFormatFile(VECTOR2D_B_FILE_F, VECTOR2D_B_TEXT_FC);
00588   if (status < 0) {
00589     return status;
00590   }
00591 
00592   printf("Done reading fortran datasets...\n");
00593 
00594   status = txiReadXFormatFile(GRID_CART2D_A_FILE_F, GRID_CART2D_A_OUT_FC);
00595   if (status < 0) {
00596     printf("Error reading fortran grid Cartesian 2D A\n");
00597   }
00598   printf("Finished reading fortran grid Cartesian 2D A\n");
00599 
00600   status = txiReadXFormatFile(GRID_CURV2D_A_FILE_F, GRID_CURV2D_A_OUT_FC);
00601   if (status < 0) {
00602     printf("Error reading fortran grid Curvilinear 2D A\n");
00603   }
00604   printf("Finished reading fortran grid Curvilinear 2D A\n");
00605 
00606   status = txiReadXFormatFile(GRID_CART3D_A_FILE_F, GRID_CART3D_A_OUT_FC);
00607   if (status < 0) {
00608     printf("Error reading grid fortran Cartesian 3D A\n");
00609   }
00610   printf("Finished reading fortran grid Cartesian 3D A\n");
00611 
00612 
00613   // read the files back in
00614   status = txiReadXFormatFile(MESH_A_FILE_F, MESH_A_OUT_FC);
00615   if (status != TRUE) {
00616     printf("Error reading fortran TestMeshA\n");
00617     return status;
00618   }
00619 
00620   // read the files back in
00621   status = txiReadXFormatFile(MESH_B_FILE_F, MESH_B_OUT_FC);
00622   if (status != TRUE) {
00623     printf("Error reading fortran TestMeshB\n");
00624     return status;
00625   }
00626 
00627   printf("Finished reading fortran meshes.\n");
00628   
00629   return status;
00630 } // txiTestFortran
00631 // --------------------------------------------------------------------------
00632 // FUNCTION txiReadXFormatFile
00633 // PURPOSE  Read a file using XMDF and write information about the data
00634 //          contained in the file to a output file
00635 // --------------------------------------------------------------------------
00636 int txiReadXFormatFile (LPCSTR a_XmdfFile, LPCSTR a_OutFile)
00637 {
00638   int    nMeshGroups, nMaxPathLength, nGridGroups;
00639   char  *Paths = NULL, *IndividualPath = NULL;
00640   int    nStatus, i;
00641   float  Version;
00642   xid    xFileId = NONE, xGroupId = NONE;
00643   FILE  *fp = NULL;
00644 //  int    NameSize;
00645 //  char  *Name = NULL;
00646 //  H5I_type_t IdentifierType;
00647 
00648   // Open the XMDF file
00649   nStatus = xfOpenFile(a_XmdfFile, &xFileId, XTRUE);
00650   if (nStatus < 0) {
00651     return -1;
00652   }
00653 
00654   // open the status file
00655   fp = fopen(a_OutFile, "w");
00656   if (fp == NULL) {
00657     xfCloseFile(xFileId);
00658     return -1;
00659   }
00660 
00661   fprintf(fp, "File %s opened.\n", a_XmdfFile);
00662 
00663   // write the version number to the file
00664   xfGetLibraryVersionFile(xFileId, &Version);
00665   fprintf(fp, "XMDF Version: %f\n", Version);
00666 
00667   // Write Coordinate System Informatioin to the .txt file
00668   nStatus = txiTestCoordSystem(xFileId, fp);
00669   fprintf(fp, "\n");
00670   if (nStatus < 0) {
00671     xfCloseFile(xFileId);
00672     return -1;
00673   }
00674 
00675   // read all datasets not beneath a mesh, grid, or cross-sections
00676   nStatus = tdReadDatasets(xFileId, fp);
00677   if (nStatus < 0) {
00678     xfCloseFile(xFileId);
00679     return -1;
00680   } 
00681 
00682   // Get the number and paths of datasets in the file.
00683   nStatus = xfGetGroupPathsSizeForMeshes(xFileId, &nMeshGroups,
00684                                                     &nMaxPathLength);
00685   if (nStatus >= 0) {
00686     Paths = (char *)malloc(nMaxPathLength*nMeshGroups*sizeof(char));
00687     nStatus = xfGetGroupPathsForMeshes(xFileId, nMeshGroups, 
00688                                          nMaxPathLength, Paths);
00689   }
00690   if (nStatus < 0) {
00691     xfCloseFile(xFileId);
00692     return -1;
00693   }
00694 
00695   // Report the number and paths to individual meshes in the file.
00696   fprintf(fp, "Number of meshes in file: %d\n", nMeshGroups);
00697   fprintf(fp, "Paths:\n");
00698   for (i = 0; i < nMeshGroups; i++) {
00699     IndividualPath = &Paths[i*nMaxPathLength];  
00700     fprintf(fp, "  %s\n", IndividualPath);
00701   }
00702   fprintf(fp, "\n");
00703 
00704   // Open each mesh group
00705   for (i = 0; i < nMeshGroups; i++) {
00706     IndividualPath = &Paths[i*nMaxPathLength];  
00707     
00708     fprintf(fp, "Reading mesh in group: %s\n", IndividualPath);
00709     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00710     if (nStatus >= 0) {
00711       // RDJ to delete
00712 //      IdentifierType = H5Iget_type(xGroupId);
00713 //      NameSize = H5Iget_name(xGroupId, NULL, NULL);
00714 //      Name = new char[NameSize + 1];
00715 //      NameSize = H5Iget_name(xGroupId, Name, NULL);
00716 //      if (Name) {
00717 //        delete [] Name;
00718 //      }
00719 
00720       nStatus = tmReadMesh(xGroupId, fp);
00721     }
00722     if (nStatus < 0) {
00723       printf("Error reading mesh..\n");
00724     }
00725   }
00726 
00727   if (Paths) {
00728     free(Paths);
00729     Paths = NULL;
00730   }
00731 
00732   // Grid stuff
00733   nStatus = xfGetGroupPathsSizeForGrids(xFileId, &nGridGroups,
00734                                                     &nMaxPathLength);
00735   if (nStatus >= 0) {
00736     Paths = (char *)malloc(nMaxPathLength*nGridGroups*sizeof(char));
00737     nStatus = xfGetGroupPathsForGrids(xFileId, nGridGroups, 
00738                                          nMaxPathLength, Paths);
00739   }
00740   if (nStatus < 0) {
00741     xfCloseFile(xFileId);
00742     return -1;
00743   }
00744 
00745   // Report the number and paths to individual meshes in the file.
00746   fprintf(fp, "Number of grids in file: %d\n", nGridGroups);
00747   fprintf(fp, "Paths:\n");
00748   for (i = 0; i < nGridGroups; i++) {
00749     IndividualPath = &Paths[i*nMaxPathLength];  
00750     fprintf(fp, "  %s\n", IndividualPath);
00751   }
00752   fprintf(fp, "\n");
00753 
00754   // Open each grid group
00755   for (i = 0; i < nGridGroups; i++) {
00756     IndividualPath = &Paths[i*nMaxPathLength];  
00757     
00758     fprintf(fp, "Reading grid in group: %s\n", IndividualPath);
00759     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00760     if (nStatus >= 0) {
00761       nStatus = tgReadGrid(xGroupId, fp);
00762     }
00763     if (nStatus < 0) {
00764       printf("Error reading grid..\n");
00765     }
00766   }
00767 
00768   if (Paths) {
00769     free(Paths);
00770     Paths = NULL;
00771   }
00772   
00773   // TODO do grid, and cross-section stuff.
00774    
00775 
00776   // close the files
00777   xfCloseFile(xFileId);
00778   fclose(fp);
00779   
00780   return TRUE;
00781 } // txiReadXFormatFile
00782 
00783 // --------------------------------------------------------------------------
00784 // FUNCTION txiReadXFormatFileT
00785 // PURPOSE  Read a file using XMDF and write information about the data
00786 //          contained in the file to a output file
00787 // --------------------------------------------------------------------------
00788 int txiReadXFormatFileT (LPCSTR a_XmdfFile, LPCSTR a_OutFile)
00789 {
00790   int    nMeshGroups, nMaxPathLength, nGridGroups;
00791   char  *Paths = NULL, *IndividualPath = NULL;
00792   int    nStatus, i;
00793   float  Version;
00794   xid    xFileId = NONE, xGroupId = NONE;
00795   FILE  *fp = NULL;
00796 
00797   // Open the XMDF file
00798   nStatus = xfOpenFile(a_XmdfFile, &xFileId, XTRUE);
00799   if (nStatus < 0) {
00800     return -1;
00801   }
00802 
00803   // open the status file
00804   fp = fopen(a_OutFile, "w");
00805   if (fp == NULL) {
00806     xfCloseFile(xFileId);
00807     return -1;
00808   }
00809 
00810   fprintf(fp, "File %s opened.\n", a_XmdfFile);
00811 
00812   // write the version number to the file
00813   xfGetLibraryVersionFile(xFileId, &Version);
00814   fprintf(fp, "XMDF Version: %f\n", Version);
00815 
00816   // Write Coordinate System Informatioin to the .txt file
00817   nStatus = txiTestCoordSystem(xFileId, fp);
00818   fprintf(fp, "\n");
00819   if (nStatus < 0) {
00820     xfCloseFile(xFileId);
00821     return -1;
00822   }
00823 
00824   // read all datasets not beneath a mesh, grid, or cross-sections
00825   nStatus = ttReadDatasets(xFileId, fp);
00826   if (nStatus < 0) {
00827     xfCloseFile(xFileId);
00828     return -1;
00829   } 
00830 
00831   // Get the number and paths of datasets in the file.
00832   nStatus = xfGetGroupPathsSizeForMeshes(xFileId, &nMeshGroups,
00833                                                     &nMaxPathLength);
00834   if (nStatus >= 0) {
00835     Paths = (char *)malloc(nMaxPathLength*nMeshGroups*sizeof(char));
00836     nStatus = xfGetGroupPathsForMeshes(xFileId, nMeshGroups, 
00837                                          nMaxPathLength, Paths);
00838   }
00839   if (nStatus < 0) {
00840     xfCloseFile(xFileId);
00841     return -1;
00842   }
00843 
00844   // Report the number and paths to individual meshes in the file.
00845   fprintf(fp, "Number of meshes in file: %d\n", nMeshGroups);
00846   fprintf(fp, "Paths:\n");
00847   for (i = 0; i < nMeshGroups; i++) {
00848     IndividualPath = &Paths[i*nMaxPathLength];  
00849     fprintf(fp, "  %s\n", IndividualPath);
00850   }
00851   fprintf(fp, "\n");
00852 
00853   // Open each mesh group
00854   for (i = 0; i < nMeshGroups; i++) {
00855     IndividualPath = &Paths[i*nMaxPathLength];  
00856     
00857     fprintf(fp, "Reading mesh in group: %s\n", IndividualPath);
00858     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00859     if (nStatus >= 0) {
00860       nStatus = tmReadMesh(xGroupId, fp);
00861     }
00862     if (nStatus < 0) {
00863       printf("Error reading mesh..\n");
00864     }
00865   }
00866 
00867   if (Paths) {
00868     free(Paths);
00869     Paths = NULL;
00870   }
00871 
00872   // Grid stuff
00873   nStatus = xfGetGroupPathsSizeForGrids(xFileId, &nGridGroups,
00874                                                     &nMaxPathLength);
00875   if (nStatus >= 0) {
00876     Paths = (char *)malloc(nMaxPathLength*nGridGroups*sizeof(char));
00877     nStatus = xfGetGroupPathsForGrids(xFileId, nGridGroups, 
00878                                          nMaxPathLength, Paths);
00879   }
00880   if (nStatus < 0) {
00881     xfCloseFile(xFileId);
00882     return -1;
00883   }
00884 
00885   // Report the number and paths to individual meshes in the file.
00886   fprintf(fp, "Number of grids in file: %d\n", nGridGroups);
00887   fprintf(fp, "Paths:\n");
00888   for (i = 0; i < nGridGroups; i++) {
00889     IndividualPath = &Paths[i*nMaxPathLength];  
00890     fprintf(fp, "  %s\n", IndividualPath);
00891   }
00892   fprintf(fp, "\n");
00893 
00894   // Open each grid group
00895   for (i = 0; i < nGridGroups; i++) {
00896     IndividualPath = &Paths[i*nMaxPathLength];  
00897     
00898     fprintf(fp, "Reading grid in group: %s\n", IndividualPath);
00899     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00900     if (nStatus >= 0) {
00901       nStatus = tgReadGrid(xGroupId, fp);
00902     }
00903     if (nStatus < 0) {
00904       printf("Error reading grid..\n");
00905     }
00906   }
00907 
00908   if (Paths) {
00909     free(Paths);
00910     Paths = NULL;
00911   }
00912   
00913   // TODO do grid, and cross-section stuff.
00914    
00915 
00916   // close the files
00917   xfCloseFile(xFileId);
00918   fclose(fp);
00919   
00920   return TRUE;
00921 } // txiReadXFormatFileT
00922 
00923 //-----------------------------------------------------------------------------
00924 // FUNCTION TXI_WRITE_XMDF_VERSION
00925 // PURPOSE  Write the XMDF version number to the screen
00926 // NOTES
00927 //-----------------------------------------------------------------------------
00928 int txiTestVersion ()
00929 {
00930   float    Version;
00931 
00932   printf("\n");
00933 
00934   xfGetLibraryVersion(&Version);
00935   printf("The current version of XMDF is: %f\n\n", Version);
00936 
00937   return 1;
00938 }  // txiTestVersion
00939 
00940 //-----------------------------------------------------------------------------
00941 // #defines used in txiTestCalendar
00942 //-----------------------------------------------------------------------------
00943 
00944 #define CALENDAR_OUT_C "Calendar_c.txt"
00945 
00946 //----------------------------------------------------------------------------
00947 // SUBROUTINE txiTestCalendar
00948 // PURPOSE    Check the Calculations of Julian date from calendar date or  
00949 //            vice-versa.
00950 // NOTES      Use #defines: ERA_IS_BCE (BC), and ERA_IS_CE (AD).
00951 //----------------------------------------------------------------------------
00952 int txiTestCalendar ()
00953 {
00954   FILE    *fp = NULL;
00955   xmbool   era1, era2, era3, era4;
00956   int     yr1, mo1, day1, hr1, min1, sec1;
00957   int     yr2, mo2, day2, hr2, min2, sec2;
00958   int     yr3, mo3, day3, hr3, min3, sec3;
00959   int     yr4, mo4, day4, hr4, min4, sec4, calendarworks;
00960   double  julian1, julian2, julian3, julian4;
00961 
00962   calendarworks = 0;
00963 
00964   // open the status file
00965   fp = fopen(CALENDAR_OUT_C, "w");
00966   if (fp == NULL) {
00967     return FALSE;
00968   }
00969 
00970 
00971   fprintf(fp, "Calendar conversion:\n\n");
00972 
00973   era1 = ERA_IS_BCE;
00974   yr1 = mo1 = day1 = hr1 = min1 = sec1 = 0;
00975   julian1 = 2655.5;
00976   xfJulianToCalendar(&era1, &yr1, &mo1, &day1, &hr1, &min1, &sec1, julian1);
00977 
00978   yr2  = 4706;
00979   mo2  = 4;
00980   day2 = 10;
00981   era2 = ERA_IS_BCE;
00982   hr2  = min2 = sec2 = 0;
00983   julian2 = 0.0;
00984   xfCalendarToJulian(era2, yr2, mo2, day2, hr2, min2, sec2, &julian2);
00985 
00986   era3 = ERA_IS_CE;
00987   yr3  = 2004;
00988   mo3  = 6;
00989   day3 = 3;
00990   hr3  = 2;
00991   min3 = 8;
00992   sec3 = 32;
00993   julian3 = 0.0;
00994   xfCalendarToJulian(era3, yr3, mo3, day3, hr3, min3, sec3, &julian3);
00995 
00996   era4 = ERA_IS_BCE;
00997   yr4 = mo4 = day4 = hr4 = min4 = sec4 = 0;
00998   julian4 = 2453159.58926;
00999   xfJulianToCalendar(&era4, &yr4, &mo4, &day4, &hr4, &min4, &sec4, julian4);
01000 
01001 fprintf(fp, "Dates #1 & #2  were calculated with the same date:\n\n");
01002 fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
01003         era1, yr1, mo1, day1, hr1, min1, sec1, julian1);
01004 fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n\n",
01005         era2, yr2, mo2, day2, hr2, min2, sec2, julian2);
01006 fprintf(fp, "Dates #3 & #4  were calculated with the same date:\n\n");
01007 fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
01008         era3, yr3, mo3, day3, hr3, min3, sec3, julian3);
01009 fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
01010         era4, yr4, mo4, day4, hr4, min4, sec4, julian4);
01011 
01012   if (era1==era2 && era3==era4) {
01013     if (yr1==yr2 && yr3==yr4) {
01014       if (mo1==mo2 && mo3==mo4) {
01015         if (day1==day2 && day3==day4) {
01016           if (hr1==hr2 && hr3==hr4) {
01017             if (min1==min2 && min3==min4) {
01018               if (EQ_EPS(julian1, julian2, DBL_EPS) && 
01019                   EQ_EPS(julian3, julian4, DBL_EPS)) {
01020                                   printf("\n");
01021                                   printf("Calendar conversion works correctly.\n");
01022                                         calendarworks = 1;
01023               }
01024             }
01025           }
01026         }
01027       }
01028     }
01029   }
01030 
01031   if (calendarworks != 1) {
01032     printf("\n");
01033     printf("Calendar Conversion DOES NOT Work Correctly.\n");
01034           return -1;
01035   }
01036   else {
01037     return 1;
01038   }
01039 
01040 }
01041 //----------------------------------------------------------------------------
01042 // SUBROUTINE txiTestCoordSystem
01043 // PURPOSE    Reads a file's Coordinate Group and prints coordinate data out
01044 //            to each text file.
01045 // NOTES
01046 //----------------------------------------------------------------------------
01047 int txiTestCoordSystem (xid xFileId, FILE *a_OutFile)
01048 {
01049   int     iHorizDatum, iHorizUnits, iVertDatum, iVertUnits;
01050   int     iLat, iLon, iUtmZone, iSpcZone, iHpgnArea, iEllipse;
01051   int     bHorizDatum, nStatus;
01052   double  dCppLat, dCppLon, dMajorR, dMinorR;
01053   xid     xCoordId = NONE;
01054   char    strHorizUnits[256], strVertDatum[256], strVertUnits[256];
01055 
01056   // Coordinate stuff
01057   // Read Coordinate Info
01058     // Open the Coordinate group
01059   nStatus = xfOpenCoordinateGroup(xFileId, &xCoordId);
01060   if (nStatus <= 0) {
01061     fprintf(a_OutFile, "\n");
01062     fprintf(a_OutFile, "Coordinate Group not found\n");
01063     fprintf(a_OutFile, "\n");
01064     return -1;
01065   }
01066 
01067   fprintf(a_OutFile, "\n");
01068   fprintf(a_OutFile, "Coordinate System:\n");
01069 
01070   bHorizDatum = xfGetHorizDatum(xCoordId, &iHorizDatum);
01071   xfGetHorizUnits(xCoordId, &iHorizUnits);
01072   xfGetVertDatum(xCoordId, &iVertDatum);
01073   xfGetVertUnits(xCoordId, &iVertUnits);
01074     // set horizontal units
01075   if (iHorizUnits == 0) {
01076     strcpy(strHorizUnits, "Horizontal units = US Survey Feet (=0)");
01077   }
01078   else if (iHorizUnits == 1) {
01079     strcpy(strHorizUnits, "Horizontal units = International Feet (=1)");
01080   }
01081   else if (iHorizUnits == 2) {
01082     strcpy(strHorizUnits, "Horizontal units = Meters (=2)");
01083   }
01084   else {
01085     strcpy(strHorizUnits, "ERROR in reading Horizontal units");
01086   }
01087     // set vertical datum
01088   if (iVertDatum == 0) {
01089     strcpy(strVertDatum, "Vertical datum = Local (=0)");
01090   }
01091   else if (iVertDatum == 1) {
01092     strcpy(strVertDatum, "Vertical datum = NGVD 29 (=1)");
01093   }
01094   else if (iVertDatum == 2) {
01095     strcpy(strVertDatum, "Vertical datum = NGVD 88 (=2)");
01096   }
01097   else {
01098     strcpy(strVertDatum, "ERROR in reading the Vertical datum\n");
01099   }
01100     // set vertocal units
01101   if (iVertUnits == 0) {
01102     strcpy(strVertUnits, "Vertical units = US Survey Feet (=0)");
01103   }
01104   else if (iVertUnits == 1) {
01105     strcpy(strVertUnits, "Vertical units = International Feet (=1)");
01106   }
01107   else if (iVertUnits == 2) {
01108     strcpy(strVertUnits, "Vertical units = Meters (=2)");
01109   }
01110   else {
01111     strcpy(strVertUnits, "ERROR in reading the Vertical units");
01112   }
01113 
01114   if (bHorizDatum >= 0) {
01115     switch (iHorizDatum) {
01116       case HORIZ_DATUM_GEOGRAPHIC:
01117         xfGetEllipse(xCoordId, &iEllipse);
01118         xfGetLat(xCoordId, &iLat);
01119         xfGetLon(xCoordId, &iLon);
01120           // Write Horizontal and Vertical Info
01121         fprintf(a_OutFile, "Horizontal datum = Geographic\n");
01122         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01123         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01124         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01125           // Write Latitude data
01126         if (iLat == 0) {
01127           fprintf(a_OutFile, "  Latitude = North (=%d)\n", iLat);
01128         }
01129         else if (iLat == 1) {
01130           fprintf(a_OutFile, "  Latitude = South (=%d)\n", iLat);
01131         }
01132         else {
01133           fprintf(a_OutFile, "  LATITUDE INFO INCORRECT\n");
01134         }
01135           // Longitude
01136         if (iLon == 0) {
01137           fprintf(a_OutFile, "  Longitude = East (=%d)\n", iLon);
01138         }
01139         else if (iLon == 1) {
01140           fprintf(a_OutFile, "  Longitude = West (=%d)\n", iLon);
01141         }
01142         else {
01143           fprintf(a_OutFile, "  LONGITUDE INFO INCORRECT\n");
01144         }
01145           // Ellipse Information
01146           // User-defined Ellipse (==32)
01147         if (iEllipse == 32) {
01148           fprintf(a_OutFile, "Ellipse = User-defined:\n");
01149           xfGetMajorR(xCoordId, &dMajorR);
01150           xfGetMinorR(xCoordId, &dMinorR);
01151           fprintf(a_OutFile, "  MajorR = %lf\n", dMajorR);
01152           fprintf(a_OutFile, "  MinorR = %lf\n\n", dMinorR);
01153         }
01154         else {
01155           fprintf(a_OutFile, "Ellipse = %d\n\n", iEllipse);
01156         }
01157         break;
01158       case HORIZ_DATUM_UTM:
01159       case HORIZ_DATUM_UTM_NAD27:
01160       case HORIZ_DATUM_UTM_NAD83:
01161         xfGetUTMZone(xCoordId, &iUtmZone);
01162           // output info to text file
01163         if (iHorizDatum == HORIZ_DATUM_UTM) {
01164           fprintf(a_OutFile, "Horizontal datum = UTM\n");
01165         }
01166         else if (iHorizDatum == HORIZ_DATUM_UTM_NAD27) {
01167           fprintf(a_OutFile, "Horizontal datum = UTM NAD27 (US)\n");
01168         }
01169         else {
01170           fprintf(a_OutFile, "Horizontal datum = UTM NAD83 (US)\n");
01171         }
01172         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01173         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01174         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01175         fprintf(a_OutFile, "UTM Zone = %d\n\n", iUtmZone);
01176         break;
01177       case HORIZ_DATUM_STATE_PLANE_NAD27:
01178       case HORIZ_DATUM_STATE_PLANE_NAD83:
01179         xfGetSPCZone(xCoordId, &iSpcZone);
01180           // output info to text file
01181         if (iHorizDatum == HORIZ_DATUM_STATE_PLANE_NAD27) {
01182           fprintf(a_OutFile, "Horizontal datum = State Plane NAD27 (US)\n");
01183         }
01184         else {
01185           fprintf(a_OutFile, "Horizontal datum = State Plane NAD83 (US)\n");
01186         }
01187         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01188         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01189         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01190         fprintf(a_OutFile, "SPC Zone = %d\n\n", iSpcZone);
01191         break;
01192       case HORIZ_DATUM_UTM_HPGN:
01193       case HORIZ_DATUM_STATE_PLANE_HPGN:
01194       case HORIZ_DATUM_GEOGRAPHIC_HPGN:
01195         xfGetHPGNArea(xCoordId, &iHpgnArea);
01196         if (iHorizDatum == HORIZ_DATUM_UTM_HPGN) {
01197           fprintf(a_OutFile, "Horizontal datum = UTM HPGN (US)\n");
01198         }
01199         else if (iHorizDatum == HORIZ_DATUM_STATE_PLANE_HPGN) {
01200           fprintf(a_OutFile, "Horizontal datum = State Plane HPGN (US)\n");
01201         }
01202         else {
01203           fprintf(a_OutFile, "Horizontal datum = Geographic HPGN (US)\n");
01204         }
01205         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01206         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01207         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01208         fprintf(a_OutFile, "HPGN Area = %d\n\n", iHpgnArea);
01209         break;
01210       case HORIZ_DATUM_CPP:
01211         xfGetCPPLat(xCoordId, &dCppLat);
01212         xfGetCPPLon(xCoordId, &dCppLon);
01213         fprintf(a_OutFile, "Horizontal datum = CPP (Carte Parallelo-Grammatique Projection)\n");
01214         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01215         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01216         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01217         fprintf(a_OutFile, "CPP Latitude = %lf\n", dCppLat);
01218         fprintf(a_OutFile, "CPP Longitude = %lf\n\n", dCppLon);
01219         break;
01220       default:
01221         // do other systems
01222         if (iHorizDatum == HORIZ_DATUM_LOCAL) {
01223           fprintf(a_OutFile, "Horizontal datum = Local\n");
01224         }
01225         else if (iHorizDatum == HORIZ_DATUM_GEOGRAPHIC_NAD27) {
01226           fprintf(a_OutFile, "Horizontal datum = Geographic NAD27 (US)\n");
01227         }
01228         else if (iHorizDatum == HORIZ_DATUM_GEOGRAPHIC_NAD83) {
01229           fprintf(a_OutFile, "Horizontal datum = Geographic NAD83 (US)\n");
01230         }
01231         else {
01232           fprintf(a_OutFile, "ERROR: The Horizontal Datum in the .h5 file is not recognizable\n");
01233           return -1;
01234         }
01235         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01236         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01237         fprintf(a_OutFile, "Vertical units = %s\n\n", strVertUnits);
01238         break;
01239     }
01240   }
01241   else {
01242     fprintf(a_OutFile, "Coordinate information in HDF5 file is incomplete.");
01243     fprintf(a_OutFile, "\n");
01244   }
01245 
01246   xfCloseGroup(xCoordId);
01247   xCoordId = 0;
01248 
01249   return TRUE;
01250 } // txiTestCoordSystem

Generated on Mon Oct 16 16:29:13 2006 for XMDF Documentation by  doxygen 1.4.6-NO