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 #include "TestDatasets.h"
00012 
00013 #define    DATASETS_LOCATION "Datasets"
00014 #define    SCALAR_A_LOCATION "Scalars/ScalarA"
00015 #define    SCALAR_B_LOCATION "Scalars/ScalarB"
00016 #define    VECTOR2D_A_LOCATION "Vectors/Vector2D_A"
00017 #define    VECTOR2D_B_LOCATION "Vectors/Vector2D_B"
00018 
00019 void tdiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
00020                      int a_SeedMultiplier, int a_nValues, float *a_Array);
00021 double tdiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed);
00022 int tdiReadScalar (xid a_xScalarId, FILE *a_fp);
00023 int tdiReadVector (xid a_xVectorId, FILE *a_fp);
00024 
00025 // ---------------------------------------------------------------------------
00026 // FUNCTION  tdEditScalarAValues
00027 // PURPOSE   
00028 // NOTES     
00029 // ---------------------------------------------------------------------------
00030 int tdEditScalarAValues (LPCSTR a_Filename, int a_Compression)
00031 {
00032   int nStatus = NONE;
00033   xid xFileId = 0, xScalarId = 0;
00034   const char * DATASET_PATH = "Datasets/Scalars/ScalarA";
00035 
00036   nStatus = tdWriteScalarA(a_Filename, a_Compression);
00037   if (nStatus < 0) {
00038     return nStatus;
00039   }
00040     // open the file and edit the values
00041   
00042   nStatus = xfOpenFile(a_Filename, &xFileId, XFALSE);
00043   if (nStatus < 0) {
00044     return -1;
00045   }
00046 
00047   nStatus = xfOpenGroup(xFileId, DATASET_PATH, &xScalarId);
00048   if (nStatus < 0) {
00049     xfCloseFile(xFileId);
00050     return -1; 
00051   }
00052   
00053     // Edit values in timestep 1, make index 1 = 4, index 5 = 40,
00054     // and index 10 = 400
00055   int editTimestep = 1;
00056   const int editNumValues = 3;
00057   int indices[editNumValues];
00058   indices[0] = 1;
00059   indices[1] = 5;
00060   indices[2] = 10;
00061   float new_values[editNumValues];
00062   new_values[0] = 4.0;
00063   new_values[1] = 40.0;
00064   new_values[2] = 400.0;
00065 
00066   nStatus = xfChangeScalarValuesTimestepFloat(xScalarId, editTimestep, editNumValues,
00067                                indices, new_values);
00068   if (nStatus < 0) {
00069     xfCloseGroup(xScalarId);
00070     xfCloseFile(xFileId);
00071     return -1; 
00072   }
00073 
00074     // Edit values in timestep 2, make index 2 = 6, index 3 = 60, and 
00075     // index 9 = 600
00076   editTimestep = 2;
00077   indices[0] = 2;
00078   indices[1] = 3;
00079   indices[2] = 9;
00080   new_values[0] = -6.0;
00081   new_values[1] = 60.0;
00082   new_values[2] = 6000.0;
00083 
00084   nStatus = xfChangeScalarValuesTimestepFloat(xScalarId, editTimestep, editNumValues,
00085                                indices, new_values);
00086   if (nStatus < 0) {
00087     xfCloseGroup(xScalarId);
00088     xfCloseFile(xFileId);
00089     return -1; 
00090   }
00091 
00092   xfCloseGroup(xScalarId);
00093   xfCloseFile(xFileId);
00094 
00095   return nStatus;
00096 } // tdEditScalarAValues
00097 // --------------------------------------------------------------------------
00098 // FUNCTION tdReadDatasets
00099 // PURPOSE  Read a dataset group from an XMDF file and output information to
00100 //          to a text file
00101 // NOTES    
00102 // --------------------------------------------------------------------------
00103 int tdReadDatasets (xid a_xGroupId, FILE *a_fp)
00104 {
00105   int   nPaths=0, nMaxPathLength=0, nMultiDatasets=0;
00106   char *Paths = NULL, *IndividualPath = NULL;
00107   int   nStatus, i, j;
00108   xid   xScalarId = NONE, xVectorId = NONE, xMultiId = NONE;
00109 
00110   // Look for scalar datasets
00111   nStatus = xfGetScalarDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00112   if (nStatus >= 0) {
00113     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00114     xfGetScalarDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00115   }
00116   if (nStatus < 0) {
00117     return -1;
00118   }
00119   
00120   // Output number and paths to scalar datasets
00121   fprintf(a_fp, "Number of Scalars %d\n", nPaths);
00122   for (i = 0; i < nPaths; i++) {
00123     IndividualPath = &Paths[i*nMaxPathLength];
00124     fprintf(a_fp, "Reading scalar: %s\n", IndividualPath);
00125    
00126     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xScalarId);
00127     if (nStatus < 0) {
00128       return -1; 
00129     }
00130 
00131     nStatus = tdiReadScalar(xScalarId, a_fp);
00132     xfCloseGroup(xScalarId);
00133     if (nStatus < 0) {
00134       printf("Error reading scalar dataset.");
00135       return -1;
00136     }
00137   }
00138 
00139   if (Paths) {
00140     free(Paths);
00141     Paths = NULL;
00142   }
00143 
00144   // Look for vector datasets
00145   nStatus = xfGetVectorDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00146   if (nStatus >= 0 && nPaths > 0) {
00147     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00148     xfGetVectorDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00149   }
00150   if (nStatus < 0) {
00151     return -1;
00152   }
00153 
00154 
00155   // Output number and paths to scalar datasets
00156   fprintf(a_fp, "Number of Vectors %d\n", nPaths);
00157   for (i = 0; i < nPaths; i++) {
00158     IndividualPath = &Paths[i*nMaxPathLength];
00159     fprintf(a_fp, "Reading Vector: %s\n", IndividualPath);
00160    
00161     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xVectorId);
00162     if (nStatus < 0) {
00163       return -1; 
00164     }
00165 
00166     nStatus = tdiReadVector(xVectorId, a_fp);
00167     xfCloseGroup(xVectorId);
00168     if (nStatus < 0) {
00169       printf("Error reading vector dataset.");
00170       return -1;
00171     }
00172   }
00173 
00174   // find multidataset folders
00175   nStatus = xfGetGroupPathsSizeForMultiDatasets(a_xGroupId, &nMultiDatasets,
00176                                                       &nMaxPathLength);
00177   if (nStatus >= 0 && nMultiDatasets > 0) {
00178     Paths = (char *)malloc(nMultiDatasets*nMaxPathLength*sizeof(char));
00179     nStatus = xfGetAllGroupPathsForMultiDatasets(a_xGroupId, nMultiDatasets, 
00180                                                  nMaxPathLength, Paths);
00181     if (nStatus < 0) {
00182       return -1;
00183     }
00184 
00185   // Output number and paths to multidatasets
00186     fprintf(a_fp, "Number of Multidatasets: %d\n", nMultiDatasets);
00187     for (i=0; i<nMultiDatasets; i++) {
00188       IndividualPath = "";
00189       for (j=0; j<nMaxPathLength-1; j++) {
00190         IndividualPath = &Paths[i*nMaxPathLength];
00191       }
00192       fprintf(a_fp, "Reading multidataset: %s\n", IndividualPath);
00193       nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xMultiId);
00194       if (nStatus < 0) {
00195             return -1;
00196       }
00197 
00198       nStatus = tdReadDatasets(xMultiId, a_fp);
00199       nStatus = xfCloseGroup(xMultiId);
00200       if (nStatus < 0) {
00201         printf("Error reading multidatasets.");
00202             return -1;
00203       }
00204     }
00205   }
00206 
00207   if (Paths) {
00208     free(Paths);
00209     Paths = NULL;
00210   }
00211 
00212   return 1;
00213 } // tdReadDatasets
00214 // --------------------------------------------------------------------------
00215 // FUNCTION tdReadActivityScalarAIndex
00216 // PURPOSE  Read all timestep values for a particular index
00217 // NOTES    
00218 // --------------------------------------------------------------------------
00219 int tdReadActivityScalarAIndex (LPCSTR a_Filename, int a_Index)
00220 {
00221   int     status;
00222   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00223   int     nTimesteps;
00224   xmbool  *bActive;
00225 
00226   // open the file
00227   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00228   if (status < 0) {
00229     return FALSE;
00230   }
00231 
00232   // open the dataset group
00233   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00234   if (status >= 0) {
00235     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00236   }
00237   if (status < 0) {
00238     return status;
00239   }
00240 
00241   // Find out the number of timesteps in the file
00242   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00243   if (status < 0) {
00244     return status;
00245   }
00246   if (nTimesteps < 1) {
00247     return -1;
00248   }
00249 
00250   // Read the values for the index
00251   bActive = new xmbool[nTimesteps];
00252   status = xfReadActivityValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00253                                        bActive);
00254 
00255   // output the data
00256   printf("\nReading activity for scalar A slice at index: %d\n", a_Index);
00257   for (int i = 0; i < nTimesteps; i++) {
00258     printf("%d ", bActive[i]);
00259   }
00260   printf("\n");
00261 
00262   delete [] bActive;
00263 
00264   return status;
00265 } // tdReadActivityScalarAtIndex
00266 // --------------------------------------------------------------------------
00267 // FUNCTION tdReadScalarAIndex
00268 // PURPOSE  Read all timestep values for a particular index
00269 // NOTES    
00270 // --------------------------------------------------------------------------
00271 int tdReadScalarAIndex (LPCSTR a_Filename, int a_Index)
00272 {
00273   int     status;
00274   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00275   int     nTimesteps;
00276   float  *fValues;
00277 
00278   // open the file
00279   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00280   if (status < 0) {
00281     return FALSE;
00282   }
00283 
00284   // open the dataset group
00285   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00286   if (status >= 0) {
00287     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00288   }
00289   if (status < 0) {
00290     return status;
00291   }
00292 
00293   // Find out the number of timesteps in the file
00294   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00295   if (status < 0) {
00296     return status;
00297   }
00298   if (nTimesteps < 1) {
00299     return -1;
00300   }
00301 
00302   // Read the values for the index
00303   fValues = new float[nTimesteps];
00304   status = xfReadScalarValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00305                                      fValues);
00306 
00307   // output the data
00308   printf("\nReading scalar A slice at index: %d\n", a_Index);
00309   for (int i = 0; i < nTimesteps; i++) {
00310     printf("%f ", fValues[i]);
00311   }
00312   printf("\n");
00313 
00314   delete [] fValues;
00315 
00316   return status;
00317 } // tdReadScalarAtIndex
00318 // ---------------------------------------------------------------------------
00319 // FUNCTION  tdReadScalarAIndices
00320 // PURPOSE   
00321 // NOTES     
00322 // ---------------------------------------------------------------------------
00323 int tdReadScalarAIndices (LPCSTR a_Filename, int a_nIndices, int *a_indices)
00324 {
00325   int     status;
00326   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00327   int     nTimesteps;
00328   float  *fValues;
00329   int     nValues = 0;
00330 
00331   // open the file
00332   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00333   if (status < 0) {
00334     return FALSE;
00335   }
00336 
00337   // open the dataset group
00338   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00339   if (status >= 0) {
00340     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00341   }
00342   if (status < 0) {
00343     return status;
00344   }
00345 
00346   // Find out the number of timesteps in the file
00347   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00348   if (status < 0) {
00349     return status;
00350   }
00351   if (nTimesteps < 1) {
00352     return -1;
00353   }
00354 
00355   // Read the values for the index
00356   nValues = nTimesteps*a_nIndices;
00357   fValues = new float[nValues];
00358   status = xfReadScalarValuesAtIndicesFloat(xScalarAId, a_nIndices, a_indices, 1,
00359                                             nTimesteps, fValues);
00360 
00361   // output the data
00362   printf("\nReading scalar A indices\n");
00363   int id = 0;
00364   for (int i = 0; i < nTimesteps; i++) {
00365     printf("Timestep: %d\n", i+1);
00366     for (int j = 0; j < a_nIndices; j++) {
00367       printf("index: %d  value: %f \n", a_indices[j], fValues[id]);
00368       id++;
00369     }
00370   }
00371   printf("\n");
00372 
00373   delete [] fValues;
00374 
00375   return status;
00376 } // tdReadScalarAIndices
00377 // --------------------------------------------------------------------------
00378 // FUNCTION tdWriteScalarA
00379 // PURPOSE  Write scalar Dataset to an HDF5 File
00380 // NOTES    This tests dynamic data sets, and activity
00381 //          This dataset is dynamic concentrations (mg/L) with output times
00382 //          in minutes.
00383 //          Dataset is for a mesh and so nActive is the number of elements
00384 //          which is not the same as the nValues which would be number of nodes
00385 //          reads/writes a reference time in julian days
00386 // --------------------------------------------------------------------------
00387 int tdWriteScalarA (LPCSTR a_Filename, int a_Compression)
00388 {
00389   xid      xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
00390   int      nValues = 10, nTimes = 3, nActive = 8;
00391   double   dTime = 0.0;
00392   int      iTimestep, iActive;
00393   float    fValues[10]; // nValues
00394   xmbool    bActivity[10]; // activity
00395   int      status, iHpgnZone;
00396   double   dJulianReftime;
00397   int      nErrors = 0, i = 0;
00398   char     **Errors = NULL;
00399 
00400   // 5th item in data set is always inactive, others active
00401   for (iActive = 0; iActive < nActive; iActive++) {
00402     bActivity[iActive] = XTRUE;
00403   }
00404   bActivity[5] = XFALSE;
00405 
00406   // create the file
00407   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00408   if (status < 0) {
00409     return FALSE;
00410   }
00411 
00412   // create the group where we will put all the datasets 
00413   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00414   if (status < 0) {
00415     xfCloseFile(xFileId);
00416     return FALSE;
00417   }
00418 
00419   // uncomment next line to test error handling function
00420   // xfCloseGroup(xDsetsId);
00421 
00422   // Create the scalar A dataset group
00423   status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
00424                                  "mg/L", TS_HOURS, a_Compression,
00425                                  &xScalarAId);
00426   if (status < 0) {
00427     // print the error stack
00428     xfGetNumErrorMessages(&nErrors);
00429     if (nErrors > 0) {
00430       Errors = new char*[nErrors];
00431       for (i = 0; i < nErrors; i++) {
00432         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00433       }
00434       status = xfGetErrorMessages(nErrors, Errors);
00435       if (status > 0) {
00436         for (i = 0; i < nErrors; i++) {
00437           printf("%s\n", Errors[i]);
00438         }
00439       }
00440       for (i = 0; i < nErrors; i++) {
00441         delete Errors[i];
00442       }
00443       delete Errors;
00444     }
00445 
00446     xfCloseGroup(xDsetsId);
00447     xfCloseFile(xFileId);
00448     return FALSE;
00449   }
00450 
00451   // Add in a reftime.  This is a julian day for:
00452   // noon July 1, 2003
00453   dJulianReftime = 2452822.0;
00454   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00455   if (status < 0) {
00456     xfCloseGroup(xScalarAId);
00457     xfCloseGroup(xDsetsId);
00458     xfCloseFile(xFileId);
00459   }
00460 
00461   // Loop through timesteps adding them to the file
00462   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00463     // We will have an 0.5 hour timestep
00464     dTime = (iTimestep + 1) * 0.5;
00465 
00466     fValues[0] = (float)dTime;
00467     for (i = 1; i < nValues; i++) {
00468       fValues[i] = float(fValues[i-1]*2.5);
00469     }
00470 
00471     // write the dataset array values
00472     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00473     if (status >= 0) {
00474       // write activity array
00475       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00476     }
00477     if (status < 0) {
00478       xfCloseGroup(xScalarAId);
00479       xfCloseGroup(xDsetsId);
00480       xfCloseFile(xFileId);
00481     }
00482   }
00483 
00484   // Write Coordinate file - for ScalarA, we will set the coordinate system
00485   //   to be Geographic HPGN, with HPGN settings written to the file.
00486   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00487   if (status <= 0) {
00488     xfCloseGroup(xScalarAId);
00489     xfCloseGroup(xDsetsId);
00490     xfCloseFile(xFileId);
00491         return -1;
00492   }
00493 
00494     // set HPGN Zone for test
00495   iHpgnZone = 29;      // Utah
00496 
00497     // Write Coordinate Information to file
00498   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00499   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00500   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00501   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00502 
00503     // write additional information
00504   xfSetHPGNArea(xCoordId, iHpgnZone);
00505 
00506   xfCloseGroup(xCoordId);
00507   xCoordId = 0;
00508 
00509   // close the dataset
00510   xfCloseGroup(xScalarAId);
00511   xfCloseGroup(xDsetsId);
00512   xfCloseFile(xFileId);
00513 
00514   return 1;
00515 } // tdWriteScalarA
00516 
00517 // --------------------------------------------------------------------------
00518 // FUNCTION tdWriteScalarB
00519 // PURPOSE  Write scalar Dataset to an HDF5 File
00520 // NOTES    This tests dynamic data sets, and activity
00521 //          This dataset is dynamic concentrations (mg/L) with output times
00522 //          in minutes.
00523 //          Dataset is for a mesh and so nActive is the number of elements
00524 //          which is not the same as the nValues which would be number of nodes
00525 //          reads/writes a reference time in julian days
00526 // --------------------------------------------------------------------------
00527 int tdWriteScalarB (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00528 {
00529   xid      xFileId, xDsetsId, xScalarBId, xCoordId = NONE;
00530   int      nValues = 10, nTimes = 3, nActive = 8;
00531   double   dTime = 0.0, dJulianReftime;
00532   int      iTimestep, iActive;
00533   float    fValues[10]; // nValues
00534   xmbool    bActivity[10]; // activity
00535   int      status, nErrors = 0, i = 0;
00536   char     **Errors = NULL;
00537 
00538   // 5th item in data set is always inactive, others active
00539   for (iActive = 0; iActive < nActive; iActive++) {
00540     bActivity[iActive] = XTRUE;
00541   }
00542   bActivity[5] = XFALSE;
00543 
00544   if (a_Overwrite) {
00545       // open the already-existing file
00546     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00547     if (status < 0) {
00548       return -1;
00549     }
00550       // open the group where we have all the datasets 
00551     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00552     if (status < 0) {
00553       xfCloseFile(xFileId);
00554       return -1;
00555     }
00556   }
00557   else {
00558       // create the file
00559     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00560     if (status < 0) {
00561       return -1;
00562     }
00563       // create the group where we will put all the datasets 
00564     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00565     if (status < 0) {
00566       xfCloseFile(xFileId);
00567       return -1;
00568     }
00569   }
00570 
00571   // uncomment next line to test error handling function
00572   // xfCloseGroup(xDsetsId);
00573 
00574   // Create/Overwrite the scalar B dataset group
00575   status = xfCreateScalarDataset(xDsetsId, SCALAR_B_LOCATION,
00576                                  "mg/L", TS_HOURS, a_Compression,
00577                                  &xScalarBId);
00578   if (status < 0) {
00579     // print the error stack
00580     xfGetNumErrorMessages(&nErrors);
00581     if (nErrors > 0) {
00582       Errors = new char*[nErrors];
00583       for (i = 0; i < nErrors; i++) {
00584         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00585       }
00586       status = xfGetErrorMessages(nErrors, Errors);
00587       if (status > 0) {
00588         for (i = 0; i < nErrors; i++) {
00589           printf("%s\n", Errors[i]);
00590         }
00591       }
00592       for (i = 0; i < nErrors; i++) {
00593         delete Errors[i];
00594       }
00595       delete Errors;
00596     }
00597 
00598     xfCloseGroup(xDsetsId);
00599     xfCloseFile(xFileId);
00600     return -1;
00601   }
00602 
00603   // Add in a reftime.  This is a julian day for:
00604   // noon July 1, 2003
00605   dJulianReftime = 2452822.0;
00606   status = xfDatasetReftime(xScalarBId, dJulianReftime);
00607   if (status < 0) {
00608     xfCloseGroup(xScalarBId);
00609     xfCloseGroup(xDsetsId);
00610     xfCloseFile(xFileId);
00611   }
00612 
00613   if (!a_Overwrite) {
00614     // Loop through timesteps adding them to the file
00615     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00616       // We will have an 0.5 hour timestep
00617       dTime = (iTimestep + 1) * 0.5;
00618 
00619       fValues[0] = (float)dTime;
00620       for (i = 1; i < nValues; i++) {
00621         fValues[i] = float(fValues[i-1]*2.5);
00622       }
00623 
00624       // write the dataset array values
00625       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00626       if (status >= 0) {
00627         // write activity array
00628         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00629       }
00630       if (status < 0) {
00631         xfCloseGroup(xScalarBId);
00632         xfCloseGroup(xDsetsId);
00633         xfCloseFile(xFileId);
00634       }
00635     }
00636   }
00637   else {
00638     // Loop through timesteps adding them to the file
00639     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00640       // We will have an 1.5 hour timestep
00641       dTime = (iTimestep + 1) * 1.5;
00642 
00643       fValues[0] = (float)dTime;
00644       for (i = 1; i < nValues; i++) {
00645         fValues[i] = float(fValues[i-1]*1.5);
00646       }
00647 
00648       // write the dataset array values
00649       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00650       if (status >= 0) {
00651         // write activity array
00652         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00653       }
00654       if (status < 0) {
00655         xfCloseGroup(xScalarBId);
00656         xfCloseGroup(xDsetsId);
00657         xfCloseFile(xFileId);
00658       }
00659     }
00660   }
00661 
00662   if (!a_Overwrite) {
00663     // Write Coordinate file
00664     status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00665     if (status <= 0) {
00666       xfCloseGroup(xScalarBId);
00667       xfCloseGroup(xDsetsId);
00668       xfCloseFile(xFileId);
00669       return -1;
00670     }
00671 
00672     // For ScalarB, we will set the coordinate system
00673     // to be UTM, with UTM Zone settings written to the file.
00674       // Write Coord Info to file
00675     xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00676     xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00677 
00678     xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00679     xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00680 
00681       // write additional information - we'll use the max value for this test
00682     xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00683 
00684     xfCloseGroup(xCoordId);
00685     xCoordId = 0;
00686   }
00687 
00688   // close the dataset
00689   xfCloseGroup(xScalarBId);
00690   xfCloseGroup(xDsetsId);
00691   xfCloseFile(xFileId);
00692 
00693   return 1;
00694 } // tdWriteScalarB
00695 // --------------------------------------------------------------------------
00696 // FUNCTION tdWriteCoordsToMulti
00697 // PURPOSE  Write coordinate system to a multidataset file
00698 // NOTES
00699 // --------------------------------------------------------------------------
00700 int tdWriteCoordsToMulti (xid a_xFileId)
00701 {
00702   xid   xCoordId = NONE;
00703   int   status;
00704 
00705   // Write Coordinate file - for Multidatasets, we will set the coordinate system
00706   //   to be UTM, with UTM Zone settings written to the file.
00707   status = xfCreateCoordinateGroup(a_xFileId, &xCoordId);
00708   if (status <= 0) {
00709     return -1;
00710   }
00711 
00712    // Write Coord Info to file
00713   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00714   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00715 
00716   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00717   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00718 
00719     // write additional information - we'll use the max value for this test
00720   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00721 
00722   xfCloseGroup(xCoordId);
00723   xCoordId = 0;
00724 
00725   return XTRUE;
00726 } // tdWriteCoordsToMulti
00727 // --------------------------------------------------------------------------
00728 // FUNCTION tdWriteScalarAToMulti
00729 // PURPOSE  Write scalar Dataset to a multidataset
00730 // NOTES    This tests dynamic data sets, and activity
00731 //          This dataset is dynamic concentrations (mg/L) with output times
00732 //          in minutes.
00733 //          Dataset is for a mesh and so nActive is the number of elements
00734 //          which is not the same as the nValues which would be number of nodes
00735 //          reads/writes a reference time in julian days
00736 // --------------------------------------------------------------------------
00737 int tdWriteScalarAToMulti (xid a_GroupId)
00738 {
00739   xid      xScalarAId;
00740   int      nValues = 10, nTimes = 3, nActive = 8;
00741   double   dTime = 0.0;
00742   int      iTimestep, iActive;
00743   float    fValues[10]; // nValues
00744   xmbool    bActivity[10]; // activity
00745   int      status;
00746   double   dJulianReftime;
00747   int      i = 0;
00748 
00749   // 5th item in data set is always inactive, others active
00750   for (iActive = 0; iActive < nActive; iActive++) {
00751     bActivity[iActive] = XTRUE;
00752   }
00753   bActivity[5] = XFALSE;
00754 
00755   // Create the scalar A dataset group
00756   status = xfCreateScalarDataset(a_GroupId, SCALAR_A_LOCATION,
00757                                  "mg/L", TS_HOURS, NONE,
00758                                  &xScalarAId);
00759   
00760   // Add in a reftime.  This is a julian day for:
00761   // noon July 1, 2003
00762   dJulianReftime = 2452822.0;
00763   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00764   if (status < 0) {
00765     xfCloseGroup(xScalarAId);
00766   }
00767 
00768   // Loop through timesteps adding them to the file
00769   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00770     // We will have an 0.5 hour timestep
00771     dTime = (iTimestep + 1) * 0.5;
00772 
00773     fValues[0] = (float)dTime;
00774     for (i = 1; i < nValues; i++) {
00775       fValues[i] = float(fValues[i-1]*2.5);
00776     }
00777 
00778     // write the dataset array values
00779     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00780     if (status >= 0) {
00781       // write activity array
00782       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00783     }
00784     if (status < 0) {
00785       xfCloseGroup(xScalarAId);
00786     }
00787   }
00788 
00789   // close the dataset
00790   xfCloseGroup(xScalarAId);
00791 
00792   return FALSE;
00793 } // tdWriteScalarAToMulti
00794 // --------------------------------------------------------------------------
00795 // FUNCTION tdReadVector2DAIndex
00796 // PURPOSE  Read all timestep values for a particular index
00797 // NOTES    
00798 // --------------------------------------------------------------------------
00799 int tdReadVector2DAIndex (LPCSTR a_Filename, int a_Index)
00800 {
00801   int     status;
00802   xid     xFileId = NONE, xDsetsId = NONE, xVector2DA = NONE;
00803   int     nTimesteps;
00804   float  *fValues;
00805 
00806   // open the file
00807   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00808   if (status < 0) {
00809     return FALSE;
00810   }
00811 
00812   // open the dataset group
00813   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00814   if (status >= 0) {
00815     status = xfOpenGroup(xDsetsId, VECTOR2D_A_LOCATION, &xVector2DA);
00816   }
00817   if (status < 0) {
00818     return status;
00819   }
00820 
00821   // Find out the number of timesteps in the file
00822   status = xfGetDatasetNumTimes(xVector2DA, &nTimesteps);
00823   if (status < 0) {
00824     return status;
00825   }
00826   if (nTimesteps < 1) {
00827     return -1;
00828   }
00829 
00830   // Read the values for the index
00831   fValues = new float[nTimesteps*2];
00832   status = xfReadVectorValuesAtIndex(xVector2DA, a_Index, 1, nTimesteps, 2,
00833                                      fValues);
00834 
00835   // output the data
00836   printf("\nReading vector 2D A slice at index: %d\n", a_Index);
00837   for (int i = 0; i < nTimesteps; i++) {
00838     printf("%f %f \n", fValues[i*2], fValues[i*2 + 1]);
00839   }
00840   printf("\n");
00841 
00842   delete [] fValues;
00843 
00844   return status;
00845 } // tdReadVector2DAIndex
00846 // --------------------------------------------------------------------------
00847 // FUNCTION tdWriteVector2D_A
00848 // PURPOSE  Write 2D vector dataset to an HDF5 File
00849 // NOTES    This tests dynamic data sets, and activity
00850 //          Add reftime when it is completed
00851 //          This dataset is dynamic water velocities with output times
00852 //          in minutes.
00853 //          Dataset is for a mesh and so nActive is the number of elements
00854 //          which is not the same as the nValues which would be number of nodes
00855 // --------------------------------------------------------------------------
00856 int tdWriteVector2D_A (LPCSTR a_Filename, int a_Compression)
00857 {
00858   xid      xFileId, xDsetsId, xVectorA, xCoordId = NONE;
00859   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00860   double   dTime = 0.0;
00861   int      iTimestep, iActive;
00862   float    fValues[100*2]; // nValues*nComponents
00863   xmbool    bActivity[75]; // activity
00864 //  double   dMin = 0.5, dMax = 3.5;
00865 //  int      nSeedMultiplier = 138592;
00866   int      i, j, status;
00867   int      iHpgnZone;
00868 
00869   // 5th item in data set is always inactive, others active
00870   for (iActive = 0; iActive < nActive; iActive++) {
00871     if (iActive % 3 == 0) {
00872       bActivity[iActive] = XFALSE;
00873     }
00874     else {
00875       bActivity[iActive] = XTRUE;
00876     }
00877   }
00878 
00879   // create the file
00880   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00881   if (status < 0) {
00882     return FALSE;
00883   }
00884 
00885   // create the group to store all datasets 
00886   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00887   if (status < 0) {
00888     xfCloseFile(xFileId);
00889     return FALSE;
00890   }
00891 
00892   // Create the scalar A dataset group
00893   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_A_LOCATION, "ft/s",
00894                TS_SECONDS, a_Compression, &xVectorA);
00895   if (status < 0) {
00896     xfCloseGroup(xDsetsId);
00897     xfCloseFile(xFileId);
00898     return FALSE;
00899   }
00900 
00901   // Loop through timesteps adding them to the file
00902   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00903     // We will have an 0.5 hour timestep
00904     dTime = (iTimestep + 1) * 0.5;
00905 
00906     for (i = 0; i < nValues; i++) {
00907       for (j = 0; j < nComponents; j++) {
00908         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00909       }
00910     }
00911 //    // generate values array using random numbers between dMin and dMax
00912 //    tdiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
00913 //                    nValues*nComponents, fValues);
00914 
00915     // write the dataset array values
00916     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
00917                                    fValues);
00918     if (status >= 0) {
00919       // write activity array
00920       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
00921     }
00922     if (status < 0) {
00923       xfCloseGroup(xVectorA);
00924       xfCloseGroup(xDsetsId);
00925       xfCloseFile(xFileId);
00926     }
00927   }
00928 
00929   // Write Coordinate file - for Vector2D_A, we will set the coordinate system
00930   //   to be Geographic HPGN, with HPGN settings written to the file.
00931   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00932   if (status <= 0) {
00933     xfCloseGroup(xVectorA);
00934     xfCloseGroup(xDsetsId);
00935     xfCloseFile(xFileId);
00936         return -1;
00937   }
00938 
00939     // set HPGN info for test
00940   iHpgnZone = 29;      // Utah
00941 
00942   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00943   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00944   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00945   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00946 
00947     // write additional information
00948   xfSetHPGNArea(xCoordId, iHpgnZone);
00949 
00950   xfCloseGroup(xCoordId);
00951   xCoordId = 0;
00952 
00953   // close the dataset
00954   xfCloseGroup(xVectorA);
00955   xfCloseGroup(xDsetsId);
00956   xfCloseFile(xFileId);
00957 
00958   return FALSE;
00959 } // tdWriteVector2D_A
00960 // --------------------------------------------------------------------------
00961 // FUNCTION tdWriteVector2D_B
00962 // PURPOSE  Write 2D vector dataset to an HDF5 File
00963 // NOTES    This tests dynamic data sets, and activity
00964 //          Add reftime when it is completed
00965 //          This dataset is dynamic water velocities with output times
00966 //          in minutes.
00967 //          Dataset is for a mesh and so nActive is the number of elements
00968 //          which is not the same as the nValues which would be number of nodes
00969 // --------------------------------------------------------------------------
00970 int tdWriteVector2D_B (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00971 {
00972   xid      xFileId, xDsetsId, xVectorB, xCoordId = NONE;
00973   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00974   double   dTime = 0.0;
00975   int      iTimestep, iActive;
00976   float    fValues[100*2]; // nValues*nComponents
00977   xmbool    bActivity[75]; // activity
00978 //  double   dMin = 0.5, dMax = 3.5;
00979 //  int      nSeedMultiplier = 138592;
00980   int      i, j, status;
00981 
00982   // 5th item in data set is always inactive, others active
00983   for (iActive = 0; iActive < nActive; iActive++) {
00984     if (iActive % 3 == 0) {
00985       bActivity[iActive] = XFALSE;
00986     }
00987     else {
00988       bActivity[iActive] = XTRUE;
00989     }
00990   }
00991 
00992   if (a_Overwrite) {
00993       //open the already-existing file
00994     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00995     if (status < 0) {
00996       return -1;
00997     }
00998       // open the group where we have all the datasets
00999     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
01000     if (status < 0) {
01001       xfCloseFile(xFileId);
01002       return -1;
01003     }
01004   }
01005   else {
01006       // create the file
01007     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
01008     if (status < 0) {
01009       return FALSE;
01010     }
01011       // create the group to store all datasets 
01012     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
01013     if (status < 0) {
01014       xfCloseFile(xFileId);
01015       return FALSE;
01016     }
01017   }
01018 
01019   // Create the Vector B dataset group
01020   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_B_LOCATION, "ft/s",
01021                TS_SECONDS, a_Compression, &xVectorB);
01022   if (status < 0) {
01023     xfCloseGroup(xDsetsId);
01024     xfCloseFile(xFileId);
01025     return FALSE;
01026   }
01027 
01028   if (!a_Overwrite) {
01029     // Loop through timesteps adding them to the file
01030     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
01031       // We will have an 0.5 hour timestep
01032       dTime = (iTimestep + 1) * 0.5;
01033 
01034       for (i = 0; i < nValues; i++) {
01035         for (j = 0; j < nComponents; j++) {
01036           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
01037         }
01038       }
01039 
01040       // write the dataset array values
01041       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
01042                                      fValues);
01043       if (status >= 0) {
01044         // write activity array
01045         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
01046       }
01047       if (status < 0) {
01048         xfCloseGroup(xVectorB);
01049         xfCloseGroup(xDsetsId);
01050         xfCloseFile(xFileId);
01051       }
01052     }
01053   }
01054   else {
01055     // Loop through timesteps adding them to the file
01056     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
01057       // We will have an 1.5 hour timestep
01058       dTime = (iTimestep + 1) * 1.5;
01059 
01060       for (i = 0; i < nValues; i++) {
01061         for (j = 0; j < nComponents; j++) {
01062           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
01063         }
01064       }
01065 
01066       // write the dataset array values
01067       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
01068                                      fValues);
01069       if (status >= 0) {
01070         // write activity array
01071         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
01072       }
01073       if (status < 0) {
01074         xfCloseGroup(xVectorB);
01075         xfCloseGroup(xDsetsId);
01076         xfCloseFile(xFileId);
01077       }
01078     }
01079   }
01080 
01081   // Write Coordinate file - for ScalarB, we will set the coordinate system
01082   //   to be UTM, with UTM Zone settings written to the file.
01083   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
01084   if (status <= 0) {
01085     xfCloseGroup(xVectorB);
01086     xfCloseGroup(xDsetsId);
01087     xfCloseFile(xFileId);
01088         return -1;
01089   }
01090 
01091     // write the coordinate data to the file
01092   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
01093   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
01094   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
01095   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
01096 
01097     // write additional information - we'll use the max UTM zone for the test
01098   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
01099 
01100   xfCloseGroup(xCoordId);
01101   xCoordId = 0;
01102 
01103   // close the dataset
01104   xfCloseGroup(xVectorB);
01105   xfCloseGroup(xDsetsId);
01106   xfCloseFile(xFileId);
01107 
01108   return 1;
01109 } // tdWriteVector2D_B
01110 // --------------------------------------------------------------------------
01111 // FUNCTION tdWriteVector2DAToMulti
01112 // PURPOSE  Write 2D vector dataset to an HDF5 File
01113 // NOTES    This tests dynamic data sets, and activity
01114 //          Add reftime when it is completed
01115 //          This dataset is dynamic water velocities with output times
01116 //          in minutes.
01117 //          Dataset is for a mesh and so nActive is the number of elements
01118 //          which is not the same as the nValues which would be number of nodes
01119 // --------------------------------------------------------------------------
01120 int tdWriteVector2DAToMulti (xid a_GroupId)
01121 {
01122   xid      xVectorA;
01123   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
01124   double   dTime = 0.0;
01125   int      iTimestep, iActive;
01126   float    fValues[100*2]; // nValues*nComponents
01127   xmbool    bActivity[75]; // activity
01128 //  double   dMin = 0.5, dMax = 3.5;
01129 //  int      nSeedMultiplier = 138592;
01130   int      i, j, status;
01131 
01132   // 5th item in data set is always inactive, others active
01133   for (iActive = 0; iActive < nActive; iActive++) {
01134     if (iActive % 3 == 0) {
01135       bActivity[iActive] = XFALSE;
01136     }
01137     else {
01138       bActivity[iActive] = XTRUE;
01139     }
01140   }
01141 
01142   // Create the scalar A dataset group
01143   status = xfCreateVectorDataset(a_GroupId, VECTOR2D_A_LOCATION, "ft/s",
01144                TS_SECONDS, NONE, &xVectorA);
01145   if (status < 0) {
01146     return FALSE;
01147   }
01148 
01149   // Loop through timesteps adding them to the file
01150   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
01151     // We will have an 0.5 hour timestep
01152     dTime = (iTimestep + 1) * 0.5;
01153 
01154     for (i = 0; i < nValues; i++) {
01155       for (j = 0; j < nComponents; j++) {
01156         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
01157       }
01158     }
01159 //    // generate values array using random numbers between dMin and dMax
01160 //    tdiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
01161 //                    nValues*nComponents, fValues);
01162 
01163     // write the dataset array values
01164     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
01165                                    fValues);
01166     if (status >= 0) {
01167       // write activity array
01168       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
01169     }
01170     if (status < 0) {
01171       xfCloseGroup(xVectorA);
01172     }
01173   }
01174 
01175   // close the dataset
01176   xfCloseGroup(xVectorA);
01177 
01178   return FALSE;
01179 } // tdWriteVector2DAToMulti
01180 // --------------------------------------------------------------------------
01181 // FUNCTION tdiRandomNumberInRange
01182 // PURPOSE  generate Psuedo Random numbers.  We use the same seeds every
01183 //          time so we end up with consistent values for testing purposes.
01184 // --------------------------------------------------------------------------
01185 double tdiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed)
01186 {
01187   int nRandom;
01188   double dValue;
01189 
01190   srand(a_nSeed);
01191   nRandom = rand();
01192 
01193   dValue = a_dMin + ((double)(nRandom)*(a_dMax - a_dMin))/RAND_MAX;
01194 
01195   return dValue;
01196 } // tdiRandomNumberInRange
01197 // --------------------------------------------------------------------------
01198 // FUNCTION tdDatasetArray
01199 // PURPOSE  Get dataset data to use in a dataset
01200 // NOTES    Generates random numbers between a range to fill in the array
01201 // --------------------------------------------------------------------------
01202 void tdiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
01203                      int a_SeedMultiplier, int a_nValues, float *a_Array)
01204 {
01205   int       i, nSeedBase;
01206 
01207   for (i = 0; i < a_nValues; i++) {
01208     nSeedBase = a_nCycle*a_nValues + i;
01209     a_Array[i] = (float)tdiRandomNumberInRange(a_dMin, a_dMax, 
01210                                               nSeedBase*a_SeedMultiplier);
01211   }
01212 } // tdDatasetArray
01213 // --------------------------------------------------------------------------
01214 // FUNCTION tdiReadScalar
01215 // PURPOSE  Read a scalar from an XMDF file and output information to
01216 //          to a text file
01217 // NOTES    
01218 // --------------------------------------------------------------------------
01219 int tdiReadScalar (xid a_xScalarId, FILE *a_fp)
01220 {
01221   int    nTimes = NONE, nValues = NONE, nActive = NONE;
01222   int    nStatus = TRUE, iTime, iVal, iActive;
01223   char   TimeUnits[100], Units[100];
01224   double *Times = NULL;
01225   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01226   xmbool  *Active = NULL;
01227   xmbool  bUseReftime;
01228   double Reftime;
01229 
01230   // read the time units
01231   nStatus = xfGetDatasetTimeUnits(a_xScalarId, TimeUnits);
01232   if (nStatus < 0) {
01233     return nStatus;
01234   }
01235   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01236 
01237   // see if we are using a reftime
01238   nStatus = xfUseDatasetReftime(a_xScalarId, &bUseReftime);
01239   if (nStatus < 0) {
01240     return nStatus;
01241   }
01242   if (bUseReftime) {
01243     nStatus = xfReadDatasetReftime(a_xScalarId, &Reftime);
01244     if (nStatus < 0) {
01245       return nStatus;
01246     }
01247     fprintf(a_fp, "Reftime: %f\n", Reftime);
01248   }
01249 
01250   // read the units
01251   nStatus = xfGetDatasetUnits(a_xScalarId, Units);
01252   if (nStatus < 0) { 
01253     return nStatus;
01254   }
01255   fprintf(a_fp, "units: %s\n", Units);
01256 
01257   // read in the number of values and number of active values
01258   nStatus = xfGetDatasetNumVals(a_xScalarId, &nValues);
01259   if (nStatus >= 0) {
01260     nStatus = xfGetDatasetNumActive(a_xScalarId, &nActive);
01261   }
01262   if (nStatus < 0) {
01263     return nStatus;
01264   }
01265 
01266   if (nValues <= 0) {
01267     printf("No data to read in.");
01268     return -1;
01269   }
01270 
01271   // read in the number of times
01272   nStatus = xfGetDatasetNumTimes(a_xScalarId, &nTimes);
01273   if (nStatus < 0) {
01274     return nStatus;
01275   }
01276 
01277   // Read in the individual time values
01278   Times = (double *)malloc(nTimes*sizeof(double));
01279   if (Times == NULL) {
01280     printf("Out of memory");
01281     return -1;
01282   }
01283   nStatus = xfGetDatasetTimes(a_xScalarId, nTimes, Times);
01284   if (nStatus < 0) {
01285     return nStatus;
01286   }
01287 
01288   // Read in the minimum and maximum values
01289   Mins = (float *)malloc(nTimes*sizeof(float));
01290   Maxs = (float *)malloc(nTimes*sizeof(float));
01291   if (Mins == NULL || Maxs == NULL) {
01292     free(Times);
01293     printf("Out of memory");
01294     return -1;
01295   }
01296 
01297   nStatus = xfGetDatasetMins(a_xScalarId, nTimes, Mins);
01298   if (nStatus >= 0) {
01299     nStatus = xfGetDatasetMaxs(a_xScalarId, nTimes, Maxs);
01300   }
01301   if (nStatus < 0) {
01302     free(Times);
01303     free(Mins);
01304     free(Maxs);
01305     return nStatus;
01306   }
01307 
01308   Values = (float *)malloc(nValues*sizeof(float));
01309   if (nActive > 0) {
01310     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01311   }
01312 
01313   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01314   fprintf(a_fp, "Number Values: %d\n", nValues);
01315   fprintf(a_fp, "Number Active: %d\n", nActive);
01316 
01317   // loop through the timesteps, read the values and active values and write
01318   // them to the text file
01319   for (iTime = 0; iTime < nTimes; iTime++) {
01320       // indices should be 1 based
01321     nStatus = xfReadScalarValuesTimestep(a_xScalarId, iTime + 1,
01322                                          nValues, Values);
01323     if (nStatus >= 0 && nActive > 0) {
01324         // indices should be 1 based
01325       nStatus = xfReadActivityTimestep(a_xScalarId, iTime + 1, nActive, Active);
01326     }
01327 
01328     // Write the time, min, max, values and active values to the text output
01329     // file.
01330     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01331                   Times[iTime], Mins[iTime], Maxs[iTime]);
01332 
01333     fprintf(a_fp, "Values:\n");
01334     // print 5 values per line
01335     for (iVal = 0; iVal < nValues; iVal++) {
01336       fprintf(a_fp, "%6.3f ", Values[iVal]);
01337       if ((iVal + 1) % 5 == 0) {
01338         fprintf(a_fp, "\n");
01339       }
01340     }
01341     fprintf(a_fp, "\n");
01342 
01343     fprintf(a_fp, "Activity:\n");
01344     // print 5 values per line
01345     for (iActive = 0; iActive < nActive; iActive++) {
01346       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01347       if ((iActive + 1) % 5 == 0) {
01348         fprintf(a_fp, "\n");
01349       }
01350     }
01351     fprintf(a_fp, "\n\n");
01352   }
01353 
01354   if (Times) {
01355     free(Times);
01356     Times = NULL;
01357   }
01358   
01359   if (Mins) {
01360     free(Mins);
01361     Mins = NULL;
01362   }
01363 
01364   if (Maxs) {
01365     free(Maxs);
01366     Maxs = NULL;
01367   }
01368 
01369   if (Values) {
01370     free(Values);
01371     Values = NULL;
01372   }
01373 
01374   if (Active) {
01375     free(Active);
01376     Active = NULL;
01377   }
01378 
01379   return TRUE;
01380 } // tdiReadScalar
01381 // --------------------------------------------------------------------------
01382 // FUNCTION tdiReadVector
01383 // PURPOSE  Read a vector from an XMDF file and output information to
01384 //          to a text file
01385 // NOTES    
01386 // --------------------------------------------------------------------------
01387 int tdiReadVector (xid a_xVectorId, FILE *a_fp)
01388 {
01389   int    nTimes = NONE, nValues = NONE, nComponents = NONE, nActive = NONE;
01390   int    nStatus = TRUE, iTime, iVal, iActive;
01391   char   TimeUnits[100];
01392   double *Times = NULL;
01393   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01394   xmbool  *Active = NULL;
01395   xmbool  bUseReftime;
01396   double Reftime;
01397 
01398   // read the time units
01399   nStatus = xfGetDatasetTimeUnits(a_xVectorId, TimeUnits);
01400   if (nStatus < 0) {
01401     return nStatus;
01402   }
01403   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01404 
01405   // see if we are using a reftime
01406   nStatus = xfUseDatasetReftime(a_xVectorId, &bUseReftime);
01407   if (nStatus < 0) {
01408     return nStatus;
01409   }
01410   if (bUseReftime) {
01411     nStatus = xfReadDatasetReftime(a_xVectorId, &Reftime);
01412     if (nStatus < 0) {
01413       return nStatus;
01414     }
01415     fprintf(a_fp, "Reftime: %f", Reftime);
01416   }
01417 
01418   // read in the number of values and number of active values
01419   nStatus = xfGetDatasetNumVals(a_xVectorId, &nValues);
01420   if (nStatus >= 0) {
01421     nStatus = xfGetDatasetVecNumComponents(a_xVectorId, &nComponents);
01422     if (nStatus >= 0) {
01423       nStatus = xfGetDatasetNumActive(a_xVectorId, &nActive);
01424     }
01425   }
01426   if (nStatus < 0) {
01427     return nStatus;
01428   }
01429 
01430   if (nValues <= 0) {
01431     printf("No data to read in.");
01432     return -1;
01433   }
01434 
01435   // read in the number of times
01436   nStatus = xfGetDatasetNumTimes(a_xVectorId, &nTimes);
01437   if (nStatus < 0) {
01438     return nStatus;
01439   }
01440 
01441   // Read in the individual time values
01442   Times = (double *)malloc(nTimes*sizeof(double));
01443   if (Times == NULL) {
01444     printf("Out of memory");
01445     return -1;
01446   }
01447   nStatus = xfGetDatasetTimes(a_xVectorId, nTimes, Times);
01448   if (nStatus < 0) {
01449     return nStatus;
01450   }
01451 
01452   // Read in the minimum and maximum values
01453   Mins = (float *)malloc(nTimes*sizeof(float));
01454   Maxs = (float *)malloc(nTimes*sizeof(float));
01455   if (Mins == NULL || Maxs == NULL) {
01456     free(Times);
01457     printf("Out of memory");
01458     return -1;
01459   }
01460 
01461   nStatus = xfGetDatasetMins(a_xVectorId, nTimes, Mins);
01462   if (nStatus >= 0) {
01463     nStatus = xfGetDatasetMaxs(a_xVectorId, nTimes, Maxs);
01464   }
01465   if (nStatus < 0) {
01466     free(Times);
01467     free(Mins);
01468     free(Maxs);
01469     return nStatus;
01470   }
01471 
01472   Values = (float *)malloc(nValues*nComponents*sizeof(float));
01473   if (nActive > 0) {
01474     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01475   }
01476 
01477   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01478   fprintf(a_fp, "Number Values: %d\n", nValues);
01479   fprintf(a_fp, "Number Components: %d\n", nComponents);
01480   fprintf(a_fp, "Number Active: %d\n", nActive);
01481 
01482   // loop through the timesteps, read the values and active values and write
01483   // them to the text file
01484   for (iTime = 0; iTime < nTimes; iTime++) {
01485     nStatus = xfReadVectorValuesTimestep(a_xVectorId, iTime + 1,
01486                                          nValues, nComponents, Values);
01487     if (nStatus >= 0 && nActive > 0) {
01488       nStatus = xfReadActivityTimestep(a_xVectorId, iTime + 1, nActive, Active);
01489     }
01490 
01491     // Write the time, min, max, values and active values to the text output
01492     // file.
01493     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01494                   Times[iTime], Mins[iTime], Maxs[iTime]);
01495 
01496     fprintf(a_fp, "Values:\n");
01497     // print a set of vector values per line
01498     for (iVal = 0; iVal < nValues; iVal++) {
01499       fprintf(a_fp, "%6.3f %6.3f\n", Values[iVal*nComponents], 
01500                                      Values[(iVal*nComponents) + 1]);
01501     }
01502     fprintf(a_fp, "\n");
01503 
01504     fprintf(a_fp, "Activity:\n");
01505     // print 5 values per line
01506     for (iActive = 0; iActive < nActive; iActive++) {
01507       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01508       if ((iActive + 1) % 5 == 0) {
01509         fprintf(a_fp, "\n");
01510       }
01511     }
01512     fprintf(a_fp, "\n\n");
01513   }
01514 
01515   if (Times) {
01516     free(Times);
01517     Times = NULL;
01518   }
01519   
01520   if (Mins) {
01521     free(Mins);
01522     Mins = NULL;
01523   }
01524 
01525   if (Maxs) {
01526     free(Maxs);
01527     Maxs = NULL;
01528   }
01529 
01530   if (Values) {
01531     free(Values);
01532     Values = NULL;
01533   }
01534 
01535   if (Active) {
01536     free(Active);
01537     Active = NULL;
01538   }
01539 
01540   return TRUE;
01541 } // 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 // xfReadVectorValuesAtIndexDouble
00010 
00011 // All XMDF functions used for timesteps:
00012 // xfGetDatasetTimes
00013 // xfGetDatasetMins
00014 // xfGetDatasetMaxs
00015 // xfGetDatasetMinsFloat
00016 // xfGetDatasetMaxsFloat
00017 // xfGetDatasetMinsDouble
00018 // xfGetDatasetMaxsDouble
00019 // xfReadActivityTimestep
00020 // xfReadActivityValuesAtIndex
00021 // xfReadScalarValuesTimestep
00022 // xfReadScalarValuesTimestepFloat
00023 // xfReadScalarValuesTimestepFloatPortion
00024 // xfReadScalarValuesTimestepDouble
00025 // xfReadScalarValuesTimestepDoublePortion
00026 // xfReadScalarValuesTimestepInt
00027 // xfReadScalarValuesAtIndex
00028 // xfReadScalarValuesAtIndexFloat
00029 // xfReadScalarValuesAtIndexDouble
00030 // xfReadScalarValuesAtIndices
00031 // xfReadScalarValuesAtIndicesFloat
00032 // xfReadVectorValuesTimestep
00033 // xfReadVectorValuesTimestepFloat
00034 // xfReadVectorValuesTimestepFloatPortion
00035 // xfReadVectorValuesTimestepDouble
00036 // xfReadVectorValuesTimestepDoublePortion
00037 
00038 
00039 #include "stdafx.h"
00040 #include <Xmdf.h>
00041 #include <stdio.h>
00042 #include <windows.h>
00043 #include <string.h>
00044 #include <stdlib.h>
00045 
00046 #define    DATASETS_LOCATION "Datasets"
00047 #define    SCALAR_A_LOCATION "Scalars/ScalarA"
00048 #define    SCALAR_B_LOCATION "Scalars/ScalarB"
00049 #define    VECTOR2D_A_LOCATION "Vectors/Vector2D_A"
00050 #define    VECTOR2D_B_LOCATION "Vectors/Vector2D_B"
00051 
00052 void ttiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
00053                      int a_SeedMultiplier, int a_nValues, float *a_Array);
00054 double ttiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed);
00055 int ttiReadScalar (xid a_xScalarId, FILE *a_fp);
00056 int ttiReadVector (xid a_xVectorId, FILE *a_fp);
00057 int ttiTestNumTimes( xid a_DatasetId, int a_Itimestep );
00058 
00059 // --------------------------------------------------------------------------
00060 // FUNCTION ttReadDatasets
00061 // PURPOSE  Read a dataset group from an XMDF file and output information to
00062 //          to a text file
00063 // NOTES    
00064 // --------------------------------------------------------------------------
00065 int ttReadDatasets (xid a_xGroupId, FILE *a_fp)
00066 {
00067   int   nPaths=0, nMaxPathLength=0, nMultiDatasets=0;
00068   char *Paths = NULL, *IndividualPath = NULL;
00069   int   nStatus, i, j;
00070   xid   xScalarId = NONE, xVectorId = NONE, xMultiId = NONE;
00071 
00072   // Look for scalar datasets
00073   nStatus = xfGetScalarDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00074   if (nStatus >= 0) {
00075     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00076     xfGetScalarDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00077   }
00078   if (nStatus < 0) {
00079     return -1;
00080   }
00081   
00082   // Output number and paths to scalar datasets
00083   fprintf(a_fp, "Number of Scalars %d\n", nPaths);
00084   for (i = 0; i < nPaths; i++) {
00085     IndividualPath = &Paths[i*nMaxPathLength];
00086     fprintf(a_fp, "Reading scalar: %s\n", IndividualPath);
00087    
00088     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xScalarId);
00089     if (nStatus < 0) {
00090       return -1; 
00091     }
00092 
00093     nStatus = ttiReadScalar(xScalarId, a_fp);
00094     xfCloseGroup(xScalarId);
00095     if (nStatus < 0) {
00096       printf("%d: ERROR reading scalar dataset.\n", __LINE__);
00097       return -1;
00098     }
00099   }
00100 
00101   if (Paths) {
00102     free(Paths);
00103     Paths = NULL;
00104   }
00105 
00106   // Look for vector datasets
00107   nStatus = xfGetVectorDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00108   if (nStatus >= 0 && nPaths > 0) {
00109     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00110     xfGetVectorDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00111   }
00112   if (nStatus < 0) {
00113     return -1;
00114   }
00115 
00116 
00117   // Output number and paths to scalar datasets
00118   fprintf(a_fp, "Number of Vectors %d\n", nPaths);
00119   for (i = 0; i < nPaths; i++) {
00120     IndividualPath = &Paths[i*nMaxPathLength];
00121     fprintf(a_fp, "Reading Vector: %s\n", IndividualPath);
00122    
00123     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xVectorId);
00124     if (nStatus < 0) {
00125       return -1; 
00126     }
00127 
00128     nStatus = ttiReadVector(xVectorId, a_fp);
00129     xfCloseGroup(xVectorId);
00130     if (nStatus < 0) {
00131       printf("%d: ERROR reading vector dataset.\n", __LINE__);
00132       return -1;
00133     }
00134   }
00135 
00136   // find multidataset folders
00137   nStatus = xfGetGroupPathsSizeForMultiDatasets(a_xGroupId, &nMultiDatasets,
00138                                                       &nMaxPathLength);
00139   if (nStatus >= 0 && nMultiDatasets > 0) {
00140     Paths = (char *)malloc(nMultiDatasets*nMaxPathLength*sizeof(char));
00141     nStatus = xfGetAllGroupPathsForMultiDatasets(a_xGroupId, nMultiDatasets, 
00142                                                  nMaxPathLength, Paths);
00143     if (nStatus < 0) {
00144       return -1;
00145     }
00146 
00147   // Output number and paths to multidatasets
00148     fprintf(a_fp, "Number of Multidatasets: %d\n", nMultiDatasets);
00149     for (i=0; i<nMultiDatasets; i++) {
00150       IndividualPath = "";
00151       for (j=0; j<nMaxPathLength-1; j++) {
00152         IndividualPath = &Paths[i*nMaxPathLength];
00153       }
00154       fprintf(a_fp, "Reading multidataset: %s\n", IndividualPath);
00155       nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xMultiId);
00156       if (nStatus < 0) {
00157             return -1;
00158       }
00159 
00160       nStatus = ttReadDatasets(xMultiId, a_fp);
00161       nStatus = xfCloseGroup(xMultiId);
00162       if (nStatus < 0) {
00163         printf("%d: ERROR reading multidatasets.\n", __LINE__);
00164             return -1;
00165       }
00166     }
00167   }
00168 
00169   if (Paths) {
00170     free(Paths);
00171     Paths = NULL;
00172   }
00173 
00174   return 1;
00175 } // ttReadDatasets
00176 // --------------------------------------------------------------------------
00177 // FUNCTION ttReadActivityScalarAIndex
00178 // PURPOSE  Read all timestep values for a particular index
00179 // NOTES    
00180 // --------------------------------------------------------------------------
00181 int ttReadActivityScalarAIndex (LPCSTR a_Filename, int a_Index)
00182 {
00183   int     status;
00184   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00185   int     nTimesteps;
00186   xmbool  *bActive;
00187 
00188   // open the file
00189   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00190   if (status < 0) {
00191     return FALSE;
00192   }
00193 
00194   // open the dataset group
00195   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00196   if (status >= 0) {
00197     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00198   }
00199   if (status < 0) {
00200     return status;
00201   }
00202 
00203   // Find out the number of timesteps in the file
00204   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00205   if (status < 0) {
00206     return status;
00207   }
00208   if (nTimesteps < 1) {
00209     return -1;
00210   }
00211 
00212   // Read the values for the index
00213   bActive = new xmbool[nTimesteps];
00214   status = xfReadActivityValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00215                                        bActive);
00216 
00217   // output the data
00218   printf("\nReading activity for scalar A slice at index: %d\n", a_Index);
00219   for (int i = 0; i < nTimesteps; i++) {
00220     printf("%d ", bActive[i]);
00221   }
00222   printf("\n");
00223 
00224   delete [] bActive;
00225 
00226   return status;
00227 } // ttReadActivityScalarAtIndex
00228 // --------------------------------------------------------------------------
00229 // FUNCTION ttReadScalarAIndex
00230 // PURPOSE  Read all timestep values for a particular index
00231 // NOTES    
00232 // --------------------------------------------------------------------------
00233 int ttReadScalarAIndex (LPCSTR a_Filename, int a_Index)
00234 {
00235   int     status;
00236   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00237   int     nTimesteps;
00238   float  *fValues;
00239 
00240   // open the file
00241   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00242   if (status < 0) {
00243     return FALSE;
00244   }
00245 
00246   // open the dataset group
00247   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00248   if (status >= 0) {
00249     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00250   }
00251   if (status < 0) {
00252     return status;
00253   }
00254 
00255   // Find out the number of timesteps in the file
00256   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00257   if (status < 0) {
00258     return status;
00259   }
00260   if (nTimesteps < 1) {
00261     return -1;
00262   }
00263 
00264   // Read the values for the index
00265   fValues = new float[nTimesteps];
00266   status = xfReadScalarValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00267                                      fValues);
00268 
00269   // output the data
00270   printf("\nReading scalar A slice at index: %d\n", a_Index);
00271   for (int i = 0; i < nTimesteps; i++) {
00272     printf("%f ", fValues[i]);
00273   }
00274   printf("\n");
00275 
00276   delete [] fValues;
00277 
00278   return status;
00279 } // ttReadScalarAtIndex
00280 // --------------------------------------------------------------------------
00281 // FUNCTION ttWriteScalarA
00282 // PURPOSE  Write scalar Dataset to an HDF5 File
00283 // NOTES    This tests dynamic data sets, and activity
00284 //          This dataset is dynamic concentrations (mg/L) with output times
00285 //          in minutes.
00286 //          Dataset is for a mesh and so nActive is the number of elements
00287 //          which is not the same as the nValues which would be number of nodes
00288 //          reads/writes a reference time in julian days
00289 // --------------------------------------------------------------------------
00290 int ttWriteScalarA (LPCSTR a_Filename, int a_Compression)
00291 {
00292   xid      xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
00293   int      nValues = 10, nTimes = 3, nActive = 8;
00294   double   dTime = 0.0;
00295   int      iTimestep, iActive;
00296   float    fValues[10]; // nValues
00297   xmbool    bActivity[10]; // activity
00298   int      status, iHpgnZone;
00299   double   dJulianReftime;
00300   int      nErrors = 0, i = 0;
00301   char     **Errors = NULL;
00302 
00303   // 5th item in data set is always inactive, others active
00304   for (iActive = 0; iActive < nActive; iActive++) {
00305     bActivity[iActive] = XTRUE;
00306   }
00307   bActivity[5] = XFALSE;
00308 
00309   // create the file
00310   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00311   if (status < 0) {
00312     return FALSE;
00313   }
00314 
00315   // create the group where we will put all the datasets 
00316   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00317   if (status < 0) {
00318     xfCloseFile(xFileId);
00319     return FALSE;
00320   }
00321 
00322   // uncomment next line to test error handling function
00323   // xfCloseGroup(xDsetsId);
00324 
00325   // Create the scalar A dataset group
00326   status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
00327                                  "mg/L", TS_HOURS, a_Compression,
00328                                  &xScalarAId);
00329   if (status < 0) {
00330     // print the error stack
00331     xfGetNumErrorMessages(&nErrors);
00332     if (nErrors > 0) {
00333       Errors = new char*[nErrors];
00334       for (i = 0; i < nErrors; i++) {
00335         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00336       }
00337       status = xfGetErrorMessages(nErrors, Errors);
00338       if (status > 0) {
00339         for (i = 0; i < nErrors; i++) {
00340           printf("%s\n", Errors[i]);
00341         }
00342       }
00343       for (i = 0; i < nErrors; i++) {
00344         delete Errors[i];
00345       }
00346       delete Errors;
00347     }
00348 
00349     xfCloseGroup(xDsetsId);
00350     xfCloseFile(xFileId);
00351     return FALSE;
00352   }
00353 
00354   // Add in a reftime.  This is a julian day for:
00355   // noon July 1, 2003
00356   dJulianReftime = 2452822.0;
00357   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00358   if (status < 0) {
00359     xfCloseGroup(xScalarAId);
00360     xfCloseGroup(xDsetsId);
00361     xfCloseFile(xFileId);
00362   }
00363 
00364   // Loop through timesteps adding them to the file
00365   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00366     // We will have an 0.5 hour timestep
00367     dTime = (iTimestep + 1) * 0.5;
00368 
00369     fValues[0] = (float)dTime;
00370     for (i = 1; i < nValues; i++) {
00371       fValues[i] = float(fValues[i-1]*2.5);
00372     }
00373 
00374     // write the dataset array values
00375     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00376     if (status >= 0) {
00377       // write activity array
00378       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00379       if (status < 0)
00380         {
00381           printf( "%d: ERROR writing activity timestep: %d\n",
00382                   __LINE__, status );
00383         }
00384     }
00385     if (status < 0) {
00386       printf( "%d: ERROR writing scalar timestep.\n", __LINE__ );
00387       xfCloseGroup(xScalarAId);
00388       xfCloseGroup(xDsetsId);
00389       xfCloseFile(xFileId);
00390     }
00391 
00392     status = ttiTestNumTimes( xScalarAId, iTimestep );
00393   }
00394 
00395   // Write Coordinate file - for ScalarA, we will set the coordinate system
00396   //   to be Geographic HPGN, with HPGN settings written to the file.
00397   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00398   if (status <= 0) {
00399     xfCloseGroup(xScalarAId);
00400     xfCloseGroup(xDsetsId);
00401     xfCloseFile(xFileId);
00402         return -1;
00403   }
00404 
00405     // set HPGN Zone for test
00406   iHpgnZone = 29;      // Utah
00407 
00408     // Write Coordinate Information to file
00409   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00410   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00411   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00412   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00413 
00414     // write additional information
00415   xfSetHPGNArea(xCoordId, iHpgnZone);
00416 
00417   xfCloseGroup(xCoordId);
00418   xCoordId = 0;
00419 
00420   // close the dataset
00421   xfCloseGroup(xScalarAId);
00422   xfCloseGroup(xDsetsId);
00423   xfCloseFile(xFileId);
00424 
00425   return FALSE;
00426 } // ttWriteScalarA
00427 
00428 // --------------------------------------------------------------------------
00429 // FUNCTION ttWriteScalarB
00430 // PURPOSE  Write scalar Dataset to an HDF5 File
00431 // NOTES    This tests dynamic data sets, and activity
00432 //          This dataset is dynamic concentrations (mg/L) with output times
00433 //          in minutes.
00434 //          Dataset is for a mesh and so nActive is the number of elements
00435 //          which is not the same as the nValues which would be number of nodes
00436 //          reads/writes a reference time in julian days
00437 // --------------------------------------------------------------------------
00438 int ttWriteScalarB (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00439 {
00440   xid      xFileId, xDsetsId, xScalarBId, xCoordId = NONE;
00441   int      nValues = 10, nTimes = 3, nActive = 8;
00442   double   dTime = 0.0, dJulianReftime;
00443   int      iTimestep, iActive;
00444   float    fValues[10]; // nValues
00445   xmbool    bActivity[10]; // activity
00446   int      status, nErrors = 0, i = 0;
00447   char     **Errors = NULL;
00448 
00449   // 5th item in data set is always inactive, others active
00450   for (iActive = 0; iActive < nActive; iActive++) {
00451     bActivity[iActive] = XTRUE;
00452   }
00453   bActivity[5] = XFALSE;
00454 
00455   if (a_Overwrite) {
00456       // open the already-existing file
00457     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00458     if (status < 0) {
00459       return -1;
00460     }
00461       // open the group where we have all the datasets 
00462     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00463     if (status < 0) {
00464       xfCloseFile(xFileId);
00465       return -1;
00466     }
00467   }
00468   else {
00469       // create the file
00470     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00471     if (status < 0) {
00472       return -1;
00473     }
00474       // create the group where we will put all the datasets 
00475     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00476     if (status < 0) {
00477       xfCloseFile(xFileId);
00478       return -1;
00479     }
00480   }
00481 
00482   // uncomment next line to test error handling function
00483   // xfCloseGroup(xDsetsId);
00484 
00485   // Create/Overwrite the scalar B dataset group
00486   status = xfCreateScalarDataset(xDsetsId, SCALAR_B_LOCATION,
00487                                  "mg/L", TS_HOURS, a_Compression,
00488                                  &xScalarBId);
00489   if (status < 0) {
00490     // print the error stack
00491     xfGetNumErrorMessages(&nErrors);
00492     if (nErrors > 0) {
00493       Errors = new char*[nErrors];
00494       for (i = 0; i < nErrors; i++) {
00495         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00496       }
00497       status = xfGetErrorMessages(nErrors, Errors);
00498       if (status > 0) {
00499         for (i = 0; i < nErrors; i++) {
00500           printf("%s\n", Errors[i]);
00501         }
00502       }
00503       for (i = 0; i < nErrors; i++) {
00504         delete Errors[i];
00505       }
00506       delete Errors;
00507     }
00508 
00509     xfCloseGroup(xDsetsId);
00510     xfCloseFile(xFileId);
00511     return -1;
00512   }
00513 
00514   // Add in a reftime.  This is a julian day for:
00515   // noon July 1, 2003
00516   dJulianReftime = 2452822.0;
00517   status = xfDatasetReftime(xScalarBId, dJulianReftime);
00518   if (status < 0) {
00519     xfCloseGroup(xScalarBId);
00520     xfCloseGroup(xDsetsId);
00521     xfCloseFile(xFileId);
00522   }
00523 
00524   if (!a_Overwrite) {
00525     // Loop through timesteps adding them to the file
00526     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00527       // We will have an 0.5 hour timestep
00528       dTime = (iTimestep + 1) * 0.5;
00529 
00530       fValues[0] = (float)dTime;
00531       for (i = 1; i < nValues; i++) {
00532         fValues[i] = float(fValues[i-1]*2.5);
00533       }
00534 
00535       // write the dataset array values
00536       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00537       if (status >= 0) {
00538         // write activity array
00539         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00540       }
00541       if (status < 0) {
00542         xfCloseGroup(xScalarBId);
00543         xfCloseGroup(xDsetsId);
00544         xfCloseFile(xFileId);
00545       }
00546     }
00547   }
00548   else {
00549     // Loop through timesteps adding them to the file
00550     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00551       // We will have an 1.5 hour timestep
00552       dTime = (iTimestep + 1) * 1.5;
00553 
00554       fValues[0] = (float)dTime;
00555       for (i = 1; i < nValues; i++) {
00556         fValues[i] = float(fValues[i-1]*1.5);
00557       }
00558 
00559       // write the dataset array values
00560       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00561       if (status >= 0) {
00562         // write activity array
00563         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00564       }
00565       if (status < 0) {
00566         xfCloseGroup(xScalarBId);
00567         xfCloseGroup(xDsetsId);
00568         xfCloseFile(xFileId);
00569       }
00570     }
00571   }
00572 
00573   if (!a_Overwrite) {
00574     // Write Coordinate file
00575     status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00576     if (status <= 0) {
00577       xfCloseGroup(xScalarBId);
00578       xfCloseGroup(xDsetsId);
00579       xfCloseFile(xFileId);
00580       return -1;
00581     }
00582 
00583     // For ScalarB, we will set the coordinate system
00584     // to be UTM, with UTM Zone settings written to the file.
00585       // Write Coord Info to file
00586     xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00587     xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00588 
00589     xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00590     xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00591 
00592       // write additional information - we'll use the max value for this test
00593     xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00594 
00595     xfCloseGroup(xCoordId);
00596     xCoordId = 0;
00597   }
00598 
00599   // close the dataset
00600   xfCloseGroup(xScalarBId);
00601   xfCloseGroup(xDsetsId);
00602   xfCloseFile(xFileId);
00603 
00604   return 1;
00605 } // ttWriteScalarB
00606 // --------------------------------------------------------------------------
00607 // FUNCTION ttWriteCoordsToMulti
00608 // PURPOSE  Write coordinate system to a multidataset file
00609 // NOTES
00610 // --------------------------------------------------------------------------
00611 int ttWriteCoordsToMulti (xid a_xFileId)
00612 {
00613   xid   xCoordId = NONE;
00614   int   status;
00615 
00616   // Write Coordinate file - for Multidatasets, we will set the coordinate system
00617   //   to be UTM, with UTM Zone settings written to the file.
00618   status = xfCreateCoordinateGroup(a_xFileId, &xCoordId);
00619   if (status <= 0) {
00620     return -1;
00621   }
00622 
00623    // Write Coord Info to file
00624   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00625   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00626 
00627   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00628   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00629 
00630     // write additional information - we'll use the max value for this test
00631   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00632 
00633   xfCloseGroup(xCoordId);
00634   xCoordId = 0;
00635 
00636   return XTRUE;
00637 } // ttWriteCoordsToMulti
00638 // --------------------------------------------------------------------------
00639 // FUNCTION ttWriteScalarAToMulti
00640 // PURPOSE  Write scalar Dataset to a multidataset
00641 // NOTES    This tests dynamic data sets, and activity
00642 //          This dataset is dynamic concentrations (mg/L) with output times
00643 //          in minutes.
00644 //          Dataset is for a mesh and so nActive is the number of elements
00645 //          which is not the same as the nValues which would be number of nodes
00646 //          reads/writes a reference time in julian days
00647 // --------------------------------------------------------------------------
00648 int ttWriteScalarAToMulti (xid a_GroupId)
00649 {
00650   xid      xScalarAId;
00651   int      nValues = 10, nTimes = 3, nActive = 8;
00652   double   dTime = 0.0;
00653   int      iTimestep, iActive;
00654   float    fValues[10]; // nValues
00655   xmbool    bActivity[10]; // activity
00656   int      status;
00657   double   dJulianReftime;
00658   int      i = 0;
00659 
00660   // 5th item in data set is always inactive, others active
00661   for (iActive = 0; iActive < nActive; iActive++) {
00662     bActivity[iActive] = XTRUE;
00663   }
00664   bActivity[5] = XFALSE;
00665 
00666   // Create the scalar A dataset group
00667   status = xfCreateScalarDataset(a_GroupId, SCALAR_A_LOCATION,
00668                                  "mg/L", TS_HOURS, NONE,
00669                                  &xScalarAId);
00670   
00671   // Add in a reftime.  This is a julian day for:
00672   // noon July 1, 2003
00673   dJulianReftime = 2452822.0;
00674   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00675   if (status < 0) {
00676     xfCloseGroup(xScalarAId);
00677   }
00678 
00679   // Loop through timesteps adding them to the file
00680   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00681     // We will have an 0.5 hour timestep
00682     dTime = (iTimestep + 1) * 0.5;
00683 
00684     fValues[0] = (float)dTime;
00685     for (i = 1; i < nValues; i++) {
00686       fValues[i] = float(fValues[i-1]*2.5);
00687     }
00688 
00689     // write the dataset array values
00690     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00691     if (status >= 0) {
00692       // write activity array
00693       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00694     }
00695     if (status < 0) {
00696       xfCloseGroup(xScalarAId);
00697     }
00698 
00699     status = ttiTestNumTimes( xScalarAId, iTimestep );
00700   }
00701 
00702   // close the dataset
00703   xfCloseGroup(xScalarAId);
00704 
00705   return FALSE;
00706 } // ttWriteScalarAToMulti
00707 // --------------------------------------------------------------------------
00708 // FUNCTION ttReadVector2DAIndex
00709 // PURPOSE  Read all timestep values for a particular index
00710 // NOTES    
00711 // --------------------------------------------------------------------------
00712 int ttReadVector2DAIndex (LPCSTR a_Filename, int a_Index)
00713 {
00714   int     status;
00715   xid     xFileId = NONE, xDsetsId = NONE, xVector2DA = NONE;
00716   int     nTimesteps;
00717   float  *fValues;
00718 
00719   // open the file
00720   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00721   if (status < 0) {
00722     return FALSE;
00723   }
00724 
00725   // open the dataset group
00726   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00727   if (status >= 0) {
00728     status = xfOpenGroup(xDsetsId, VECTOR2D_A_LOCATION, &xVector2DA);
00729   }
00730   if (status < 0) {
00731     return status;
00732   }
00733 
00734   // Find out the number of timesteps in the file
00735   status = xfGetDatasetNumTimes(xVector2DA, &nTimesteps);
00736   if (status < 0) {
00737     return status;
00738   }
00739   if (nTimesteps < 1) {
00740     return -1;
00741   }
00742 
00743   // Read the values for the index
00744   fValues = new float[nTimesteps*2];
00745   status = xfReadVectorValuesAtIndex(xVector2DA, a_Index, 1, nTimesteps, 2,
00746                                      fValues);
00747 
00748   // output the data
00749   printf("\nReading vector 2D A slice at index: %d\n", a_Index);
00750   for (int i = 0; i < nTimesteps; i++) {
00751     printf("%f %f \n", fValues[i*2], fValues[i*2 + 1]);
00752   }
00753   printf("\n");
00754 
00755   delete [] fValues;
00756 
00757   return status;
00758 } // ttReadVector2DAIndex
00759 // --------------------------------------------------------------------------
00760 // FUNCTION ttWriteVector2D_A
00761 // PURPOSE  Write 2D vector dataset to an HDF5 File
00762 // NOTES    This tests dynamic data sets, and activity
00763 //          Add reftime when it is completed
00764 //          This dataset is dynamic water velocities with output times
00765 //          in minutes.
00766 //          Dataset is for a mesh and so nActive is the number of elements
00767 //          which is not the same as the nValues which would be number of nodes
00768 // --------------------------------------------------------------------------
00769 int ttWriteVector2D_A (LPCSTR a_Filename, int a_Compression)
00770 {
00771   xid      xFileId, xDsetsId, xVectorA, xCoordId = NONE;
00772   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00773   double   dTime = 0.0;
00774   int      iTimestep, iActive;
00775   float    fValues[100*2]; // nValues*nComponents
00776   xmbool    bActivity[75]; // activity
00777 //  double   dMin = 0.5, dMax = 3.5;
00778 //  int      nSeedMultiplier = 138592;
00779   int      i, j, status;
00780   int      iHpgnZone;
00781 
00782   // 5th item in data set is always inactive, others active
00783   for (iActive = 0; iActive < nActive; iActive++) {
00784     if (iActive % 3 == 0) {
00785       bActivity[iActive] = XFALSE;
00786     }
00787     else {
00788       bActivity[iActive] = XTRUE;
00789     }
00790   }
00791 
00792   // create the file
00793   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00794   if (status < 0) {
00795     return FALSE;
00796   }
00797 
00798   // create the group to store all datasets 
00799   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00800   if (status < 0) {
00801     xfCloseFile(xFileId);
00802     return FALSE;
00803   }
00804 
00805   // Create the scalar A dataset group
00806   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_A_LOCATION, "ft/s",
00807                TS_SECONDS, a_Compression, &xVectorA);
00808   if (status < 0) {
00809     xfCloseGroup(xDsetsId);
00810     xfCloseFile(xFileId);
00811     return FALSE;
00812   }
00813 
00814   // Loop through timesteps adding them to the file
00815   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00816     // We will have an 0.5 hour timestep
00817     dTime = (iTimestep + 1) * 0.5;
00818 
00819     for (i = 0; i < nValues; i++) {
00820       for (j = 0; j < nComponents; j++) {
00821         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00822       }
00823     }
00824 //    // generate values array using random numbers between dMin and dMax
00825 //    ttiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
00826 //                    nValues*nComponents, fValues);
00827 
00828     // write the dataset array values
00829     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
00830                                    fValues);
00831     if (status >= 0) {
00832       // write activity array
00833       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
00834     }
00835     if (status < 0) {
00836       xfCloseGroup(xVectorA);
00837       xfCloseGroup(xDsetsId);
00838       xfCloseFile(xFileId);
00839     }
00840 
00841     status = ttiTestNumTimes( xVectorA, iTimestep );
00842   }
00843 
00844   // Write Coordinate file - for Vector2D_A, we will set the coordinate system
00845   //   to be Geographic HPGN, with HPGN settings written to the file.
00846   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00847   if (status <= 0) {
00848     xfCloseGroup(xVectorA);
00849     xfCloseGroup(xDsetsId);
00850     xfCloseFile(xFileId);
00851         return -1;
00852   }
00853 
00854     // set HPGN info for test
00855   iHpgnZone = 29;      // Utah
00856 
00857   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00858   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00859   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00860   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00861 
00862     // write additional information
00863   xfSetHPGNArea(xCoordId, iHpgnZone);
00864 
00865   xfCloseGroup(xCoordId);
00866   xCoordId = 0;
00867 
00868   // close the dataset
00869   xfCloseGroup(xVectorA);
00870   xfCloseGroup(xDsetsId);
00871   xfCloseFile(xFileId);
00872 
00873   return FALSE;
00874 } // ttWriteVector2D_A
00875 // --------------------------------------------------------------------------
00876 // FUNCTION ttWriteVector2D_B
00877 // PURPOSE  Write 2D vector dataset to an HDF5 File
00878 // NOTES    This tests dynamic data sets, and activity
00879 //          Add reftime when it is completed
00880 //          This dataset is dynamic water velocities with output times
00881 //          in minutes.
00882 //          Dataset is for a mesh and so nActive is the number of elements
00883 //          which is not the same as the nValues which would be number of nodes
00884 // --------------------------------------------------------------------------
00885 int ttWriteVector2D_B (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00886 {
00887   xid      xFileId, xDsetsId, xVectorB, xCoordId = NONE;
00888   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00889   double   dTime = 0.0;
00890   int      iTimestep, iActive;
00891   float    fValues[100*2]; // nValues*nComponents
00892   xmbool    bActivity[75]; // activity
00893 //  double   dMin = 0.5, dMax = 3.5;
00894 //  int      nSeedMultiplier = 138592;
00895   int      i, j, status;
00896 
00897   // 5th item in data set is always inactive, others active
00898   for (iActive = 0; iActive < nActive; iActive++) {
00899     if (iActive % 3 == 0) {
00900       bActivity[iActive] = XFALSE;
00901     }
00902     else {
00903       bActivity[iActive] = XTRUE;
00904     }
00905   }
00906 
00907   if (a_Overwrite) {
00908       //open the already-existing file
00909     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00910     if (status < 0) {
00911       return -1;
00912     }
00913       // open the group where we have all the datasets
00914     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00915     if (status < 0) {
00916       xfCloseFile(xFileId);
00917       return -1;
00918     }
00919   }
00920   else {
00921       // create the file
00922     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00923     if (status < 0) {
00924       return FALSE;
00925     }
00926       // create the group to store all datasets 
00927     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00928     if (status < 0) {
00929       xfCloseFile(xFileId);
00930       return FALSE;
00931     }
00932   }
00933 
00934   // Create the Vector B dataset group
00935   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_B_LOCATION, "ft/s",
00936                TS_SECONDS, a_Compression, &xVectorB);
00937   if (status < 0) {
00938     xfCloseGroup(xDsetsId);
00939     xfCloseFile(xFileId);
00940     return FALSE;
00941   }
00942 
00943   if (!a_Overwrite) {
00944     // Loop through timesteps adding them to the file
00945     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00946       // We will have an 0.5 hour timestep
00947       dTime = (iTimestep + 1) * 0.5;
00948 
00949       for (i = 0; i < nValues; i++) {
00950         for (j = 0; j < nComponents; j++) {
00951           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00952         }
00953       }
00954 
00955       // write the dataset array values
00956       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
00957                                      fValues);
00958       if (status >= 0) {
00959         // write activity array
00960         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
00961       }
00962       if (status < 0) {
00963         xfCloseGroup(xVectorB);
00964         xfCloseGroup(xDsetsId);
00965         xfCloseFile(xFileId);
00966       }
00967     }
00968   }
00969   else {
00970     // Loop through timesteps adding them to the file
00971     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00972       // We will have an 1.5 hour timestep
00973       dTime = (iTimestep + 1) * 1.5;
00974 
00975       for (i = 0; i < nValues; i++) {
00976         for (j = 0; j < nComponents; j++) {
00977           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00978         }
00979       }
00980 
00981       // write the dataset array values
00982       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
00983                                      fValues);
00984       if (status >= 0) {
00985         // write activity array
00986         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
00987       }
00988       if (status < 0) {
00989         xfCloseGroup(xVectorB);
00990         xfCloseGroup(xDsetsId);
00991         xfCloseFile(xFileId);
00992       }
00993     }
00994   }
00995 
00996   // Write Coordinate file - for ScalarB, we will set the coordinate system
00997   //   to be UTM, with UTM Zone settings written to the file.
00998   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00999   if (status <= 0) {
01000     xfCloseGroup(xVectorB);
01001     xfCloseGroup(xDsetsId);
01002     xfCloseFile(xFileId);
01003         return -1;
01004   }
01005 
01006     // write the coordinate data to the file
01007   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
01008   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
01009   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
01010   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
01011 
01012     // write additional information - we'll use the max UTM zone for the test
01013   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
01014 
01015   xfCloseGroup(xCoordId);
01016   xCoordId = 0;
01017 
01018   // close the dataset
01019   xfCloseGroup(xVectorB);
01020   xfCloseGroup(xDsetsId);
01021   xfCloseFile(xFileId);
01022 
01023   return 1;
01024 } // ttWriteVector2D_B
01025 // --------------------------------------------------------------------------
01026 // FUNCTION ttWriteVector2DAToMulti
01027 // PURPOSE  Write 2D vector dataset to an HDF5 File
01028 // NOTES    This tests dynamic data sets, and activity
01029 //          Add reftime when it is completed
01030 //          This dataset is dynamic water velocities with output times
01031 //          in minutes.
01032 //          Dataset is for a mesh and so nActive is the number of elements
01033 //          which is not the same as the nValues which would be number of nodes
01034 // --------------------------------------------------------------------------
01035 int ttWriteVector2DAToMulti (xid a_GroupId)
01036 {
01037   xid      xVectorA;
01038   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
01039   double   dTime = 0.0;
01040   int      iTimestep, iActive;
01041   float    fValues[100*2]; // nValues*nComponents
01042   xmbool    bActivity[75]; // activity
01043 //  double   dMin = 0.5, dMax = 3.5;
01044 //  int      nSeedMultiplier = 138592;
01045   int      i, j, status;
01046 
01047   // 5th item in data set is always inactive, others active
01048   for (iActive = 0; iActive < nActive; iActive++) {
01049     if (iActive % 3 == 0) {
01050       bActivity[iActive] = XFALSE;
01051     }
01052     else {
01053       bActivity[iActive] = XTRUE;
01054     }
01055   }
01056 
01057   // Create the scalar A dataset group
01058   status = xfCreateVectorDataset(a_GroupId, VECTOR2D_A_LOCATION, "ft/s",
01059                TS_SECONDS, NONE, &xVectorA);
01060   if (status < 0) {
01061     return FALSE;
01062   }
01063 
01064   // Loop through timesteps adding them to the file
01065   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
01066     // We will have an 0.5 hour timestep
01067     dTime = (iTimestep + 1) * 0.5;
01068 
01069     for (i = 0; i < nValues; i++) {
01070       for (j = 0; j < nComponents; j++) {
01071         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
01072       }
01073     }
01074 //    // generate values array using random numbers between dMin and dMax
01075 //    ttiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
01076 //                    nValues*nComponents, fValues);
01077 
01078     // write the dataset array values
01079     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
01080                                    fValues);
01081     if (status >= 0) {
01082       // write activity array
01083       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
01084     }
01085     if (status < 0) {
01086       xfCloseGroup(xVectorA);
01087     }
01088 
01089     status = ttiTestNumTimes( xVectorA, iTimestep );
01090   }
01091 
01092   // close the dataset
01093   xfCloseGroup(xVectorA);
01094 
01095   return FALSE;
01096 } // ttWriteVector2DAToMulti
01097 // --------------------------------------------------------------------------
01098 // FUNCTION ttiRandomNumberInRange
01099 // PURPOSE  generate Psuedo Random numbers.  We use the same seeds every
01100 //          time so we end up with consistent values for testing purposes.
01101 // --------------------------------------------------------------------------
01102 double ttiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed)
01103 {
01104   int nRandom;
01105   double dValue;
01106 
01107   srand(a_nSeed);
01108   nRandom = rand();
01109 
01110   dValue = a_dMin + ((double)(nRandom)*(a_dMax - a_dMin))/RAND_MAX;
01111 
01112   return dValue;
01113 } // ttiRandomNumberInRange
01114 // --------------------------------------------------------------------------
01115 // FUNCTION ttDatasetArray
01116 // PURPOSE  Get dataset data to use in a dataset
01117 // NOTES    Generates random numbers between a range to fill in the array
01118 // --------------------------------------------------------------------------
01119 void ttiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
01120                      int a_SeedMultiplier, int a_nValues, float *a_Array)
01121 {
01122   int       i, nSeedBase;
01123 
01124   for (i = 0; i < a_nValues; i++) {
01125     nSeedBase = a_nCycle*a_nValues + i;
01126     a_Array[i] = (float)ttiRandomNumberInRange(a_dMin, a_dMax, 
01127                                               nSeedBase*a_SeedMultiplier);
01128   }
01129 } // ttDatasetArray
01130 // --------------------------------------------------------------------------
01131 // FUNCTION ttiReadScalar
01132 // PURPOSE  Read a scalar from an XMDF file and output information to
01133 //          to a text file
01134 // NOTES    
01135 // --------------------------------------------------------------------------
01136 int ttiReadScalar (xid a_xScalarId, FILE *a_fp)
01137 {
01138   int    nTimes = NONE, nValues = NONE, nActive = NONE;
01139   int    nStatus = TRUE, iTime, iVal, iActive;
01140   char   TimeUnits[100], Units[100];
01141   double *Times = NULL;
01142   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01143   xmbool  *Active = NULL;
01144   xmbool  bUseReftime;
01145   double Reftime;
01146 
01147   // read the time units
01148   nStatus = xfGetDatasetTimeUnits(a_xScalarId, TimeUnits);
01149   if (nStatus < 0) {
01150     return nStatus;
01151   }
01152   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01153 
01154   // see if we are using a reftime
01155   nStatus = xfUseDatasetReftime(a_xScalarId, &bUseReftime);
01156   if (nStatus < 0) {
01157     return nStatus;
01158   }
01159   if (bUseReftime) {
01160     nStatus = xfReadDatasetReftime(a_xScalarId, &Reftime);
01161     if (nStatus < 0) {
01162       return nStatus;
01163     }
01164     fprintf(a_fp, "Reftime: %f\n", Reftime);
01165   }
01166 
01167   // read the units
01168   nStatus = xfGetDatasetUnits(a_xScalarId, Units);
01169   if (nStatus < 0) { 
01170     return nStatus;
01171   }
01172   fprintf(a_fp, "units: %s\n", Units);
01173 
01174   // read in the number of values and number of active values
01175   nStatus = xfGetDatasetNumVals(a_xScalarId, &nValues);
01176   if (nStatus >= 0) {
01177     nStatus = xfGetDatasetNumActive(a_xScalarId, &nActive);
01178   }
01179   if (nStatus < 0) {
01180     return nStatus;
01181   }
01182 
01183   if (nValues <= 0) {
01184     printf("No data to read in.");
01185     return -1;
01186   }
01187 
01188   // read in the number of times
01189   nStatus = xfGetDatasetNumTimes(a_xScalarId, &nTimes);
01190   if (nStatus < 0) {
01191     return nStatus;
01192   }
01193 
01194   // Read in the individual time values
01195   Times = (double *)malloc(nTimes*sizeof(double));
01196   if (Times == NULL) {
01197     printf("Out of memory");
01198     return -1;
01199   }
01200   nStatus = xfGetDatasetTimes(a_xScalarId, nTimes, Times);
01201   if (nStatus < 0) {
01202     return nStatus;
01203   }
01204 
01205   // Read in the minimum and maximum values
01206   Mins = (float *)malloc(nTimes*sizeof(float));
01207   Maxs = (float *)malloc(nTimes*sizeof(float));
01208   if (Mins == NULL || Maxs == NULL) {
01209     free(Times);
01210     printf("Out of memory");
01211     return -1;
01212   }
01213 
01214   nStatus = xfGetDatasetMins(a_xScalarId, nTimes, Mins);
01215   if (nStatus >= 0) {
01216     nStatus = xfGetDatasetMaxs(a_xScalarId, nTimes, Maxs);
01217   }
01218   if (nStatus < 0) {
01219     free(Times);
01220     free(Mins);
01221     free(Maxs);
01222     return nStatus;
01223   }
01224 
01225   Values = (float *)malloc(nValues*sizeof(float));
01226   if (nActive > 0) {
01227     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01228   }
01229 
01230   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01231   fprintf(a_fp, "Number Values: %d\n", nValues);
01232   fprintf(a_fp, "Number Active: %d\n", nActive);
01233 
01234   // loop through the timesteps, read the values and active values and write
01235   // them to the text file
01236   for (iTime = 0; iTime < nTimes; iTime++) {
01237       // indices should be 1 based
01238     nStatus = xfReadScalarValuesTimestep(a_xScalarId, iTime + 1,
01239                                          nValues, Values);
01240     if (nStatus >= 0 && nActive > 0) {
01241         // indices should be 1 based
01242       nStatus = xfReadActivityTimestep(a_xScalarId, iTime + 1, nActive, Active);
01243     }
01244 
01245     // Write the time, min, max, values and active values to the text output
01246     // file.
01247     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01248                   Times[iTime], Mins[iTime], Maxs[iTime]);
01249 
01250     fprintf(a_fp, "Values:\n");
01251     // print 5 values per line
01252     for (iVal = 0; iVal < nValues; iVal++) {
01253       fprintf(a_fp, "%6.3f ", Values[iVal]);
01254       if ((iVal + 1) % 5 == 0) {
01255         fprintf(a_fp, "\n");
01256       }
01257     }
01258     fprintf(a_fp, "\n");
01259 
01260     fprintf(a_fp, "Activity:\n");
01261     // print 5 values per line
01262     for (iActive = 0; iActive < nActive; iActive++) {
01263       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01264       if ((iActive + 1) % 5 == 0) {
01265         fprintf(a_fp, "\n");
01266       }
01267     }
01268     fprintf(a_fp, "\n\n");
01269   }
01270 
01271   if (Times) {
01272     free(Times);
01273     Times = NULL;
01274   }
01275   
01276   if (Mins) {
01277     free(Mins);
01278     Mins = NULL;
01279   }
01280 
01281   if (Maxs) {
01282     free(Maxs);
01283     Maxs = NULL;
01284   }
01285 
01286   if (Values) {
01287     free(Values);
01288     Values = NULL;
01289   }
01290 
01291   if (Active) {
01292     free(Active);
01293     Active = NULL;
01294   }
01295 
01296   return TRUE;
01297 } // ttiReadScalar
01298 // --------------------------------------------------------------------------
01299 // FUNCTION ttiReadVector
01300 // PURPOSE  Read a vector from an XMDF file and output information to
01301 //          to a text file
01302 // NOTES    
01303 // --------------------------------------------------------------------------
01304 int ttiReadVector (xid a_xVectorId, FILE *a_fp)
01305 {
01306   int    nTimes = NONE, nValues = NONE, nComponents = NONE, nActive = NONE;
01307   int    nStatus = TRUE, iTime, iVal, iActive;
01308   char   TimeUnits[100];
01309   double *Times = NULL;
01310   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01311   xmbool  *Active = NULL;
01312   xmbool  bUseReftime;
01313   double Reftime;
01314 
01315   // read the time units
01316   nStatus = xfGetDatasetTimeUnits(a_xVectorId, TimeUnits);
01317   if (nStatus < 0) {
01318     return nStatus;
01319   }
01320   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01321 
01322   // see if we are using a reftime
01323   nStatus = xfUseDatasetReftime(a_xVectorId, &bUseReftime);
01324   if (nStatus < 0) {
01325     return nStatus;
01326   }
01327   if (bUseReftime) {
01328     nStatus = xfReadDatasetReftime(a_xVectorId, &Reftime);
01329     if (nStatus < 0) {
01330       return nStatus;
01331     }
01332     fprintf(a_fp, "Reftime: %f", Reftime);
01333   }
01334 
01335   // read in the number of values and number of active values
01336   nStatus = xfGetDatasetNumVals(a_xVectorId, &nValues);
01337   if (nStatus >= 0) {
01338     nStatus = xfGetDatasetVecNumComponents(a_xVectorId, &nComponents);
01339     if (nStatus >= 0) {
01340       nStatus = xfGetDatasetNumActive(a_xVectorId, &nActive);
01341     }
01342   }
01343   if (nStatus < 0) {
01344     return nStatus;
01345   }
01346 
01347   if (nValues <= 0) {
01348     printf("No data to read in.");
01349     return -1;
01350   }
01351 
01352   // read in the number of times
01353   nStatus = xfGetDatasetNumTimes(a_xVectorId, &nTimes);
01354   if (nStatus < 0) {
01355     return nStatus;
01356   }
01357 
01358   // Read in the individual time values
01359   Times = (double *)malloc(nTimes*sizeof(double));
01360   if (Times == NULL) {
01361     printf("Out of memory");
01362     return -1;
01363   }
01364   nStatus = xfGetDatasetTimes(a_xVectorId, nTimes, Times);
01365   if (nStatus < 0) {
01366     return nStatus;
01367   }
01368 
01369   // Read in the minimum and maximum values
01370   Mins = (float *)malloc(nTimes*sizeof(float));
01371   Maxs = (float *)malloc(nTimes*sizeof(float));
01372   if (Mins == NULL || Maxs == NULL) {
01373     free(Times);
01374     printf("Out of memory");
01375     return -1;
01376   }
01377 
01378   nStatus = xfGetDatasetMins(a_xVectorId, nTimes, Mins);
01379   if (nStatus >= 0) {
01380     nStatus = xfGetDatasetMaxs(a_xVectorId, nTimes, Maxs);
01381   }
01382   if (nStatus < 0) {
01383     free(Times);
01384     free(Mins);
01385     free(Maxs);
01386     return nStatus;
01387   }
01388 
01389   Values = (float *)malloc(nValues*nComponents*sizeof(float));
01390   if (nActive > 0) {
01391     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01392   }
01393 
01394   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01395   fprintf(a_fp, "Number Values: %d\n", nValues);
01396   fprintf(a_fp, "Number Components: %d\n", nComponents);
01397   fprintf(a_fp, "Number Active: %d\n", nActive);
01398 
01399   // loop through the timesteps, read the values and active values and write
01400   // them to the text file
01401   for (iTime = 0; iTime < nTimes; iTime++) {
01402     nStatus = xfReadVectorValuesTimestep(a_xVectorId, iTime + 1,
01403                                          nValues, nComponents, Values);
01404     if (nStatus >= 0 && nActive > 0) {
01405       nStatus = xfReadActivityTimestep(a_xVectorId, iTime + 1, nActive, Active);
01406     }
01407 
01408     // Write the time, min, max, values and active values to the text output
01409     // file.
01410     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01411                   Times[iTime], Mins[iTime], Maxs[iTime]);
01412 
01413     fprintf(a_fp, "Values:\n");
01414     // print a set of vector values per line
01415     for (iVal = 0; iVal < nValues; iVal++) {
01416       fprintf(a_fp, "%6.3f %6.3f\n", Values[iVal*nComponents], 
01417                                      Values[(iVal*nComponents) + 1]);
01418     }
01419     fprintf(a_fp, "\n");
01420 
01421     fprintf(a_fp, "Activity:\n");
01422     // print 5 values per line
01423     for (iActive = 0; iActive < nActive; iActive++) {
01424       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01425       if ((iActive + 1) % 5 == 0) {
01426         fprintf(a_fp, "\n");
01427       }
01428     }
01429     fprintf(a_fp, "\n\n");
01430   }
01431 
01432   if (Times) {
01433     free(Times);
01434     Times = NULL;
01435   }
01436   
01437   if (Mins) {
01438     free(Mins);
01439     Mins = NULL;
01440   }
01441 
01442   if (Maxs) {
01443     free(Maxs);
01444     Maxs = NULL;
01445   }
01446 
01447   if (Values) {
01448     free(Values);
01449     Values = NULL;
01450   }
01451 
01452   if (Active) {
01453     free(Active);
01454     Active = NULL;
01455   }
01456 
01457   return TRUE;
01458 } // ttiReadVector
01459 
01460 // --------------------------------------------------------------------------
01461 // FUNCTION ttiTestNumTimes
01462 // PURPOSE  Change the NumTimes to truncate timesteps
01463 // NOTES    
01464 // --------------------------------------------------------------------------
01465 int ttiTestNumTimes( xid a_DatasetId, int a_Itimestep )
01466 {
01467   int status = 1;
01468 
01469   // truncate just written timestep and test error conditions
01470   if (1 == a_Itimestep ||
01471       3 == a_Itimestep ||
01472       5 == a_Itimestep)
01473     {
01474       int NumTimes;
01475 
01476       // Test setting NumTimes after end of dataset
01477       status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep + 2 );
01478       if (status >= 0)
01479         printf( "%d: ERROR: xfSetDatasetNumTimes must return ERROR.\n",
01480                 __LINE__ );
01481 
01482       if (1 == a_Itimestep) a_Itimestep = 1;
01483       if (3 == a_Itimestep) a_Itimestep = 2;
01484       if (5 == a_Itimestep) a_Itimestep = 3;
01485 
01486       // Write actual NumTimes
01487       status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep );
01488       if (status < 0)
01489         printf( "%d: ERROR: xfSetDatasetNumTimes must NOT return error.\n",
01490                 __LINE__ );
01491 
01492       // Test setting NumTimes after end step.
01493       status = xfSetDatasetNumTimes( a_DatasetId, a_Itimestep + 1 );
01494       if (status >= 0)
01495         printf( "%d: ERROR: xfSetDatasetNumTimes must return ERROR.\n",
01496                 __LINE__ );
01497 
01498       // Test reading NumTimes
01499       status = xfGetDatasetNumTimes( a_DatasetId, &NumTimes );
01500       if (status < 0)
01501         printf( "%d: ERROR: xfGetDatasetNumTimes must NOT return error.\n",
01502                 __LINE__ );
01503       if (NumTimes != a_Itimestep)
01504         printf( "%d: ERROR: xfGetDatasetNumTimes must return CORRECT NumTimes.\n",
01505                 __LINE__ );
01506     }
01507 
01508   return status;
01509 }
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 SCALAR_A_EDITED_FILE_C "ScalarA_edited_c.h5"
00210 #define SCALAR_A_EDITED_TEXT_C "ScalarA_edited_c.txt"
00211 #define VECTOR2D_A_FILE_C "Vector2D_A_c.h5"
00212 #define VECTOR2D_A_TEXT_C "Vector2D_A_c.txt"
00213 
00214 #define SCALAR_A_FILE_F "ScalarA_f.h5"
00215 #define SCALAR_A_TEXT_FC "ScalarA_fc.txt"
00216 #define VECTOR2D_A_FILE_F "Vector2D_A_f.h5"
00217 #define VECTOR2D_A_TEXT_FC "Vector2D_A_fc.txt"
00218 
00219 #define MULTIDATASET_FILE_C "MultiDataSet_c.h5"
00220 #define MULTIDATASET_TEXT_C "MultiDataSet_c.txt"
00221 
00222 //-----------------------------------------------------------------------------
00223 // FUNCTION  txiTestDatasets
00224 // PURPOSE
00225 // NOTES
00226 //-----------------------------------------------------------------------------
00227 int txiTestDatasets()
00228 {
00229   int status = 1;
00230   int compression = NONE;
00231   xid  MultiFileId=NONE, MultiGroupId=NONE;
00232   int         NumOpen=0;
00233 
00234   char SdoGuid[37];
00235 
00236   strcpy(SdoGuid, "73289C80-6235-4fdc-9649-49E4F5AEB676");
00237 
00238   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00239            SdoGuid, XF_OVERWRITE_CLEAR_FILE, &MultiFileId, &MultiGroupId);
00240 
00241   // Write coordinates to multidatasets
00242   tdWriteCoordsToMulti(MultiFileId);
00243 
00244  // Write scalar A and Vector A to multidatasets.
00245   tdWriteScalarAToMulti(MultiGroupId);
00246 
00247   tdWriteVector2DAToMulti(MultiGroupId);
00248 
00249   xfCloseGroup(MultiGroupId);
00250   xfCloseFile(MultiFileId);
00251   printf("Done writing multiple datasets...\n");
00252 
00253 
00254   // scalar datasets
00255   status = tdWriteScalarA(SCALAR_A_FILE_C, compression);
00256   if (status < 0) {
00257     return status;
00258   }
00259   
00260   printf("Done writing scalar datasets...\n");
00261 
00262   // vector datasets
00263   status = tdWriteVector2D_A(VECTOR2D_A_FILE_C, compression);
00264   if (status < 0) {
00265     printf("Error writing dataset vector2D_A.");
00266     return status;
00267   }
00268 
00269   printf("Done writing vector datasets...\n");
00270 
00271   printf("Write edited scalar datasets...\n");
00272   status = tdEditScalarAValues(SCALAR_A_EDITED_FILE_C, compression);
00273   if (status < 0) {
00274     return status;
00275   }
00276 
00277   printf("Done writing datasets...\n");
00278 
00279   // Read the files back in
00280   status = txiReadXFormatFile(SCALAR_A_FILE_C, SCALAR_A_TEXT_C);
00281   if (status < 0) {
00282     return status;
00283   }
00284 
00285   status = txiReadXFormatFile(VECTOR2D_A_FILE_C, VECTOR2D_A_TEXT_C);
00286   if (status < 0) {
00287     return status;
00288   }
00289 
00290   status = txiReadXFormatFile(MULTIDATASET_FILE_C, MULTIDATASET_TEXT_C);
00291   if (status < 0) {
00292     return status;
00293   }
00294 
00295   status = txiReadXFormatFile(SCALAR_A_EDITED_FILE_C, SCALAR_A_EDITED_TEXT_C);
00296   if (status < 0) {
00297     return status;
00298   }
00299 
00300   printf("Done reading datasets...\n");
00301 
00302   xfGetNumOpenIdentifiers(H5F_OBJ_ALL, &NumOpen);
00303 
00304   xfpCloseOpenIdentifiers(H5F_OBJ_ALL);
00305 
00306   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00307      SdoGuid, XF_OVERWRITE_CLEAR_DATASET_GROUP, &MultiFileId, &MultiGroupId);
00308 
00309   tdWriteScalarAToMulti(MultiGroupId);
00310 
00311   xfSetupToWriteDatasets(MULTIDATASET_FILE_C, "Multidatasets","", 
00312      SdoGuid, XF_OVERWRITE_NONE, &MultiFileId, &MultiGroupId);
00313 
00314   tdWriteVector2DAToMulti(MultiGroupId);
00315 
00316 
00317   // Test reading information at index for multiple timesteps
00318   status = tdReadScalarAIndex(SCALAR_A_FILE_C, 2);
00319   if (status < 0) {
00320     return status;
00321   }
00322   printf("Done reading scalar data at index.\n");
00323   
00324   status = tdReadVector2DAIndex(VECTOR2D_A_FILE_C, 4);
00325   if (status < 0) {
00326     return status;
00327   }
00328   printf("Done reading vector data at index.\n");
00329 
00330   status = tdReadActivityScalarAIndex(SCALAR_A_FILE_C, 5);
00331   if (status < 0) {
00332     return status;
00333   }
00334 
00335     // Test reading information at multiple indices
00336   const int  nIndices = 3;
00337   int indices[nIndices];
00338   indices[0] = 2;
00339   indices[1] = 3;
00340   indices[2] = 5;
00341   status = tdReadScalarAIndices(SCALAR_A_FILE_C, nIndices, indices);
00342 
00343   return status;
00344 } // txiTestDatasets
00345 
00346 #define GEOMPATH_A_FILE_C "geompath_a_file_c.h5"
00347 #define GEOMPATH_A_FILE_COUT "geompath_a_file_c_out.txt"
00348 
00349 int txiTestGeometricPaths()
00350 {
00351   int status = 1;
00352   int compression = NONE;
00353     /* test writing a geometric path file */
00354   printf("\n\nWriting geometric path data.\n\n");
00355  
00356   status = tmWriteTestPaths(GEOMPATH_A_FILE_C, compression);
00357   if (status <= 0) {
00358     printf("Error writing geometric path data A\n");
00359   }
00360   printf("Finished writing geometric path data A\n");
00361 
00362     /* test reading a geometric path file */
00363   status = tmReadTestPaths(GEOMPATH_A_FILE_C, GEOMPATH_A_FILE_COUT);
00364 
00365   return status;
00366 }
00367 
00368 //-----------------------------------------------------------------------------
00369 // #defines used in txiTestOverwriteDsets
00370 //-----------------------------------------------------------------------------
00371 
00372 #define SCALAR_B_FILE_C "ScalarB_c.h5"
00373 #define SCALAR_B_TEXT_C "ScalarB_c.txt"
00374 #define VECTOR2D_B_FILE_C "Vector2D_B_c.h5"
00375 #define VECTOR2D_B_TEXT_C "Vector2D_B_c.txt"
00376 
00377 #define SCALAR_B_FILE_F "ScalarB_f.h5"
00378 #define SCALAR_B_TEXT_FC "ScalarB_fc.txt"
00379 #define VECTOR2D_B_FILE_F "Vector2D_B_f.h5"
00380 #define VECTOR2D_B_TEXT_FC "Vector2D_B_fc.txt"
00381 
00382 //-----------------------------------------------------------------------------
00383 // FUNCTION  txiTestOverwriteDsets
00384 // PURPOSE   Check to see if already-written datasets can be overwritten
00385 // NOTES
00386 //-----------------------------------------------------------------------------
00387 int txiTestOverwriteDsets()
00388 {
00389   int status = 1;
00390   int compression = NONE;
00391 
00392     // scalar datasets
00393   status = tdWriteScalarB(SCALAR_B_FILE_C, compression, 0);
00394   if (status < 0) {
00395     return status;
00396   }
00397     // overwrite scalar datasets
00398   status = tdWriteScalarB(SCALAR_B_FILE_C, compression, 1);
00399   if (status < 0) {
00400     return status;
00401   }
00402   
00403     // vector datasets
00404   status = tdWriteVector2D_B(VECTOR2D_B_FILE_C, compression, 0);
00405   if (status < 0) {
00406     printf("Error writing dataset vector2D_B.");
00407     return status;
00408   }
00409     // overwrite vector datasets
00410   status = tdWriteVector2D_B(VECTOR2D_B_FILE_C, compression, 1);
00411   if (status < 0) {
00412     printf("Error writing dataset vector2D_B.");
00413     return status;
00414   }
00415 
00416   // Read the files back in
00417   status = txiReadXFormatFile(SCALAR_B_FILE_C, SCALAR_B_TEXT_C);
00418   if (status < 0) {
00419     return status;
00420   }
00421 
00422   status = txiReadXFormatFile(VECTOR2D_B_FILE_C, VECTOR2D_B_TEXT_C);
00423   if (status < 0) {
00424     return status;
00425   }
00426 
00427   return status;
00428 } // txiTestDatasets
00429 
00430 //-----------------------------------------------------------------------------
00431 // #defines used in txiTestGrids
00432 //-----------------------------------------------------------------------------
00433 
00434 #define GRID_CART2D_A_FILE_C "grid_cart2d_a_file_c.h5"
00435 #define GRID_CURV2D_A_FILE_C "grid_curv2d_a_file_c.h5"
00436 #define GRID_CART3D_A_FILE_C "grid_cart3d_a_file_c.h5"
00437 
00438 #define GRID_CART2D_A_OUT_C "grid_cart2d_a_out_c.txt"
00439 #define GRID_CURV2D_A_OUT_C "grid_curv2d_a_out_c.txt"
00440 #define GRID_CART3D_A_OUT_C "grid_cart3d_a_out_c.txt"
00441 
00442 #define GRID_CART2D_A_FILE_F "grid_cart2d_a_file_f.h5"
00443 #define GRID_CURV2D_A_FILE_F "grid_curv2d_a_file_f.h5"
00444 #define GRID_CART3D_A_FILE_F "grid_cart3d_a_file_f.h5"
00445 
00446 #define GRID_CART2D_A_OUT_FC "grid_cart2d_a_out_fc.txt"
00447 #define GRID_CURV2D_A_OUT_FC "grid_curv2d_a_out_fc.txt"
00448 #define GRID_CART3D_A_OUT_FC "grid_cart3d_a_out_fc.txt"
00449 
00450 //-----------------------------------------------------------------------------
00451 // FUNCTION  txiTestGrids
00452 // PURPOSE
00453 // NOTES
00454 //-----------------------------------------------------------------------------
00455 int txiTestGrids()
00456 {
00457   int status = 1;
00458   int compression = NONE;
00459 
00460   printf("\n\nWriting grid data.\n\n");
00461  
00462   status = tgWriteTestGridCart2D(GRID_CART2D_A_FILE_C, compression);
00463   if (status < 0) {
00464     printf("Error writing grid Cartesian 2D A\n");
00465   }
00466   printf("Finished writing grid Cartesian 2D A\n");
00467 
00468   status = tgWriteTestGridCurv2D(GRID_CURV2D_A_FILE_C, compression);
00469   if (status < 0) {
00470     printf("Error writing grid Curvilinear 2D A\n");
00471   }
00472   printf("Finished writing grid Curvilinear 2D A\n");
00473 
00474   status = tgWriteTestGridCart3D(GRID_CART3D_A_FILE_C, compression);
00475   if (status < 0) {
00476     printf("Error writing grid Cartesian 3D A\n");
00477   }
00478   printf("Finished writing grid Cartesian 3D A\n"); 
00479   
00480 
00481   // read the files back in
00482   status = txiReadXFormatFile(GRID_CART2D_A_FILE_C, GRID_CART2D_A_OUT_C);
00483   if (status < 0) {
00484     printf("Error reading grid Cartesian 2D A\n");
00485   }
00486   printf("Finished reading grid Cartesian 2D A\n");
00487 
00488   status = txiReadXFormatFile(GRID_CURV2D_A_FILE_C, GRID_CURV2D_A_OUT_C);
00489   if (status < 0) {
00490     printf("Error reading grid Curvilinear 2D A\n");
00491   }
00492   printf("Finished reading grid Curvilinear 2D A\n");
00493 
00494   status = txiReadXFormatFile(GRID_CART3D_A_FILE_C, GRID_CART3D_A_OUT_C);
00495   if (status < 0) {
00496     printf("Error reading grid Cartesian 3D A\n");
00497   }
00498   printf("Finished reading grid Cartesian 3D A\n"); 
00499  
00500 
00501   return status;
00502 } // txiTestGrids
00503 
00504 //-----------------------------------------------------------------------------
00505 // #defines used in txiTestMeshs
00506 //-----------------------------------------------------------------------------
00507 
00508 #define MESH_A_FILE_C  "mesh_a_file_c.h5"
00509 #define MESH_B_FILE_C  "mesh_b_file_c.h5"
00510 #define MESH_A_OUT_C   "mesh_a_file_c.txt"
00511 #define MESH_B_OUT_C   "mesh_b_file_c.txt"
00512 
00513 #define MESH_A_FILE_F  "mesh_a_file_f.h5"
00514 #define MESH_B_FILE_F  "mesh_b_file_f.h5"
00515 #define MESH_A_OUT_FC  "mesh_a_file_fc.txt"
00516 #define MESH_B_OUT_FC  "mesh_b_file_fc.txt"
00517 
00518 // ---------------------------------------------------------------------------
00519 // FUNCTION  txiTestMeshs
00520 // PURPOSE   
00521 // NOTES     
00522 // ---------------------------------------------------------------------------
00523 int txiTestMeshs ()
00524 {
00525   int status = 1;
00526   int compression = NONE;
00527 
00528   status = tmWriteTestMeshA(MESH_A_FILE_C, compression);
00529   if (status != TRUE) {
00530     printf("Error writing TestMeshA\n");
00531     return status;
00532   }
00533 
00534   status = tmWriteTestMeshB(MESH_B_FILE_C, compression);
00535   if (status != TRUE) {
00536     printf("Error writing TestMeshB\n");
00537     return status;
00538   }
00539 
00540   printf("Finished writing meshes.\n");
00541 
00542   // read the files back in
00543   status = txiReadXFormatFile(MESH_A_FILE_C, MESH_A_OUT_C);
00544   if (status != TRUE) {
00545     printf("Error reading TestMeshA\n");
00546     return status;
00547   }
00548 
00549   // read the files back in
00550   status = txiReadXFormatFile(MESH_B_FILE_C, MESH_B_OUT_C);
00551   if (status != TRUE) {
00552     printf("Error reading TestMeshB\n");
00553     return status;
00554   }
00555 
00556   printf("Finished reading meshes.\n");
00557 
00558   return status;
00559 } // txiTestMeshs
00560 // ---------------------------------------------------------------------------
00561 // FUNCTION  txiTestFortran
00562 // PURPOSE   test to see if C code can read file written with fortran.
00563 // NOTES     
00564 // ---------------------------------------------------------------------------
00565 int txiTestFortran ()
00566 {
00567   xid    xFileId = 0;
00568   herr_t (*old_func)(void*);
00569   int     status = 1;
00570   int     nStatus = 1;
00571   void    *old_client_data;
00572 
00573     // Check to see if files written with C exist
00574   H5Eget_auto(&old_func, &old_client_data);
00575     // Turn off error handling
00576   H5Eset_auto(NULL, NULL);
00577 
00578     // Try opening a file written with C to see if one exists.
00579   nStatus = xfOpenFile(SCALAR_A_FILE_F, &xFileId, XTRUE);
00580     // If the file written with FORTRAN doesn't exist, return.
00581   if (nStatus < 0) {
00582     xfCloseFile(xFileId);
00583       // Restore previous error handler
00584     H5Eset_auto(old_func, old_client_data);
00585     return FALSE;
00586       // If the file written with C does exist, assume all C files exist.
00587   }
00588   else {
00589     xfCloseFile(xFileId);
00590       // Restore previous error handler
00591     H5Eset_auto(old_func, old_client_data);
00592   }
00593 
00594   // Read the files back in
00595   status = txiReadXFormatFile(SCALAR_A_FILE_F, SCALAR_A_TEXT_FC);
00596   if (status < 0) {
00597     return status;
00598   }
00599   status = txiReadXFormatFile(SCALAR_B_FILE_F, SCALAR_B_TEXT_FC);
00600   if (status < 0) {
00601     return status;
00602   }
00603 
00604   status = txiReadXFormatFile(VECTOR2D_A_FILE_F, VECTOR2D_A_TEXT_FC);
00605   if (status < 0) {
00606     return status;
00607   }
00608   status = txiReadXFormatFile(VECTOR2D_B_FILE_F, VECTOR2D_B_TEXT_FC);
00609   if (status < 0) {
00610     return status;
00611   }
00612 
00613   printf("Done reading fortran datasets...\n");
00614 
00615   status = txiReadXFormatFile(GRID_CART2D_A_FILE_F, GRID_CART2D_A_OUT_FC);
00616   if (status < 0) {
00617     printf("Error reading fortran grid Cartesian 2D A\n");
00618   }
00619   printf("Finished reading fortran grid Cartesian 2D A\n");
00620 
00621   status = txiReadXFormatFile(GRID_CURV2D_A_FILE_F, GRID_CURV2D_A_OUT_FC);
00622   if (status < 0) {
00623     printf("Error reading fortran grid Curvilinear 2D A\n");
00624   }
00625   printf("Finished reading fortran grid Curvilinear 2D A\n");
00626 
00627   status = txiReadXFormatFile(GRID_CART3D_A_FILE_F, GRID_CART3D_A_OUT_FC);
00628   if (status < 0) {
00629     printf("Error reading grid fortran Cartesian 3D A\n");
00630   }
00631   printf("Finished reading fortran grid Cartesian 3D A\n");
00632 
00633 
00634   // read the files back in
00635   status = txiReadXFormatFile(MESH_A_FILE_F, MESH_A_OUT_FC);
00636   if (status != TRUE) {
00637     printf("Error reading fortran TestMeshA\n");
00638     return status;
00639   }
00640 
00641   // read the files back in
00642   status = txiReadXFormatFile(MESH_B_FILE_F, MESH_B_OUT_FC);
00643   if (status != TRUE) {
00644     printf("Error reading fortran TestMeshB\n");
00645     return status;
00646   }
00647 
00648   printf("Finished reading fortran meshes.\n");
00649   
00650   return status;
00651 } // txiTestFortran
00652 // --------------------------------------------------------------------------
00653 // FUNCTION txiReadXFormatFile
00654 // PURPOSE  Read a file using XMDF and write information about the data
00655 //          contained in the file to a output file
00656 // --------------------------------------------------------------------------
00657 int txiReadXFormatFile (LPCSTR a_XmdfFile, LPCSTR a_OutFile)
00658 {
00659   int    nMeshGroups, nMaxPathLength, nGridGroups;
00660   char  *Paths = NULL, *IndividualPath = NULL;
00661   int    nStatus, i;
00662   float  Version;
00663   xid    xFileId = NONE, xGroupId = NONE;
00664   FILE  *fp = NULL;
00665 //  int    NameSize;
00666 //  char  *Name = NULL;
00667 //  H5I_type_t IdentifierType;
00668 
00669   // Open the XMDF file
00670   nStatus = xfOpenFile(a_XmdfFile, &xFileId, XTRUE);
00671   if (nStatus < 0) {
00672     return -1;
00673   }
00674 
00675   // open the status file
00676   fp = fopen(a_OutFile, "w");
00677   if (fp == NULL) {
00678     xfCloseFile(xFileId);
00679     return -1;
00680   }
00681 
00682   fprintf(fp, "File %s opened.\n", a_XmdfFile);
00683 
00684   // write the version number to the file
00685   xfGetLibraryVersionFile(xFileId, &Version);
00686   fprintf(fp, "XMDF Version: %f\n", Version);
00687 
00688   // Write Coordinate System Informatioin to the .txt file
00689   nStatus = txiTestCoordSystem(xFileId, fp);
00690   fprintf(fp, "\n");
00691   if (nStatus < 0) {
00692     xfCloseFile(xFileId);
00693     return -1;
00694   }
00695 
00696   // read all datasets not beneath a mesh, grid, or cross-sections
00697   nStatus = tdReadDatasets(xFileId, fp);
00698   if (nStatus < 0) {
00699     xfCloseFile(xFileId);
00700     return -1;
00701   } 
00702 
00703   // Get the number and paths of datasets in the file.
00704   nStatus = xfGetGroupPathsSizeForMeshes(xFileId, &nMeshGroups,
00705                                                     &nMaxPathLength);
00706   if (nStatus >= 0) {
00707     Paths = (char *)malloc(nMaxPathLength*nMeshGroups*sizeof(char));
00708     nStatus = xfGetGroupPathsForMeshes(xFileId, nMeshGroups, 
00709                                          nMaxPathLength, Paths);
00710   }
00711   if (nStatus < 0) {
00712     xfCloseFile(xFileId);
00713     return -1;
00714   }
00715 
00716   // Report the number and paths to individual meshes in the file.
00717   fprintf(fp, "Number of meshes in file: %d\n", nMeshGroups);
00718   fprintf(fp, "Paths:\n");
00719   for (i = 0; i < nMeshGroups; i++) {
00720     IndividualPath = &Paths[i*nMaxPathLength];  
00721     fprintf(fp, "  %s\n", IndividualPath);
00722   }
00723   fprintf(fp, "\n");
00724 
00725   // Open each mesh group
00726   for (i = 0; i < nMeshGroups; i++) {
00727     IndividualPath = &Paths[i*nMaxPathLength];  
00728     
00729     fprintf(fp, "Reading mesh in group: %s\n", IndividualPath);
00730     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00731     if (nStatus >= 0) {
00732       // RDJ to delete
00733 //      IdentifierType = H5Iget_type(xGroupId);
00734 //      NameSize = H5Iget_name(xGroupId, NULL, NULL);
00735 //      Name = new char[NameSize + 1];
00736 //      NameSize = H5Iget_name(xGroupId, Name, NULL);
00737 //      if (Name) {
00738 //        delete [] Name;
00739 //      }
00740 
00741       nStatus = tmReadMesh(xGroupId, fp);
00742     }
00743     if (nStatus < 0) {
00744       printf("Error reading mesh..\n");
00745     }
00746   }
00747 
00748   if (Paths) {
00749     free(Paths);
00750     Paths = NULL;
00751   }
00752 
00753   // Grid stuff
00754   nStatus = xfGetGroupPathsSizeForGrids(xFileId, &nGridGroups,
00755                                                     &nMaxPathLength);
00756   if (nStatus >= 0) {
00757     Paths = (char *)malloc(nMaxPathLength*nGridGroups*sizeof(char));
00758     nStatus = xfGetGroupPathsForGrids(xFileId, nGridGroups, 
00759                                          nMaxPathLength, Paths);
00760   }
00761   if (nStatus < 0) {
00762     xfCloseFile(xFileId);
00763     return -1;
00764   }
00765 
00766   // Report the number and paths to individual meshes in the file.
00767   fprintf(fp, "Number of grids in file: %d\n", nGridGroups);
00768   fprintf(fp, "Paths:\n");
00769   for (i = 0; i < nGridGroups; i++) {
00770     IndividualPath = &Paths[i*nMaxPathLength];  
00771     fprintf(fp, "  %s\n", IndividualPath);
00772   }
00773   fprintf(fp, "\n");
00774 
00775   // Open each grid group
00776   for (i = 0; i < nGridGroups; i++) {
00777     IndividualPath = &Paths[i*nMaxPathLength];  
00778     
00779     fprintf(fp, "Reading grid in group: %s\n", IndividualPath);
00780     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00781     if (nStatus >= 0) {
00782       nStatus = tgReadGrid(xGroupId, fp);
00783     }
00784     if (nStatus < 0) {
00785       printf("Error reading grid..\n");
00786     }
00787   }
00788 
00789   if (Paths) {
00790     free(Paths);
00791     Paths = NULL;
00792   }
00793   
00794   // TODO do grid, and cross-section stuff.
00795    
00796 
00797   // close the files
00798   xfCloseFile(xFileId);
00799   fclose(fp);
00800   
00801   return TRUE;
00802 } // txiReadXFormatFile
00803 
00804 // --------------------------------------------------------------------------
00805 // FUNCTION txiReadXFormatFileT
00806 // PURPOSE  Read a file using XMDF and write information about the data
00807 //          contained in the file to a output file
00808 // --------------------------------------------------------------------------
00809 int txiReadXFormatFileT (LPCSTR a_XmdfFile, LPCSTR a_OutFile)
00810 {
00811   int    nMeshGroups, nMaxPathLength, nGridGroups;
00812   char  *Paths = NULL, *IndividualPath = NULL;
00813   int    nStatus, i;
00814   float  Version;
00815   xid    xFileId = NONE, xGroupId = NONE;
00816   FILE  *fp = NULL;
00817 
00818   // Open the XMDF file
00819   nStatus = xfOpenFile(a_XmdfFile, &xFileId, XTRUE);
00820   if (nStatus < 0) {
00821     return -1;
00822   }
00823 
00824   // open the status file
00825   fp = fopen(a_OutFile, "w");
00826   if (fp == NULL) {
00827     xfCloseFile(xFileId);
00828     return -1;
00829   }
00830 
00831   fprintf(fp, "File %s opened.\n", a_XmdfFile);
00832 
00833   // write the version number to the file
00834   xfGetLibraryVersionFile(xFileId, &Version);
00835   fprintf(fp, "XMDF Version: %f\n", Version);
00836 
00837   // Write Coordinate System Informatioin to the .txt file
00838   nStatus = txiTestCoordSystem(xFileId, fp);
00839   fprintf(fp, "\n");
00840   if (nStatus < 0) {
00841     xfCloseFile(xFileId);
00842     return -1;
00843   }
00844 
00845   // read all datasets not beneath a mesh, grid, or cross-sections
00846   nStatus = ttReadDatasets(xFileId, fp);
00847   if (nStatus < 0) {
00848     xfCloseFile(xFileId);
00849     return -1;
00850   } 
00851 
00852   // Get the number and paths of datasets in the file.
00853   nStatus = xfGetGroupPathsSizeForMeshes(xFileId, &nMeshGroups,
00854                                                     &nMaxPathLength);
00855   if (nStatus >= 0) {
00856     Paths = (char *)malloc(nMaxPathLength*nMeshGroups*sizeof(char));
00857     nStatus = xfGetGroupPathsForMeshes(xFileId, nMeshGroups, 
00858                                          nMaxPathLength, Paths);
00859   }
00860   if (nStatus < 0) {
00861     xfCloseFile(xFileId);
00862     return -1;
00863   }
00864 
00865   // Report the number and paths to individual meshes in the file.
00866   fprintf(fp, "Number of meshes in file: %d\n", nMeshGroups);
00867   fprintf(fp, "Paths:\n");
00868   for (i = 0; i < nMeshGroups; i++) {
00869     IndividualPath = &Paths[i*nMaxPathLength];  
00870     fprintf(fp, "  %s\n", IndividualPath);
00871   }
00872   fprintf(fp, "\n");
00873 
00874   // Open each mesh group
00875   for (i = 0; i < nMeshGroups; i++) {
00876     IndividualPath = &Paths[i*nMaxPathLength];  
00877     
00878     fprintf(fp, "Reading mesh in group: %s\n", IndividualPath);
00879     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00880     if (nStatus >= 0) {
00881       nStatus = tmReadMesh(xGroupId, fp);
00882     }
00883     if (nStatus < 0) {
00884       printf("Error reading mesh..\n");
00885     }
00886   }
00887 
00888   if (Paths) {
00889     free(Paths);
00890     Paths = NULL;
00891   }
00892 
00893   // Grid stuff
00894   nStatus = xfGetGroupPathsSizeForGrids(xFileId, &nGridGroups,
00895                                                     &nMaxPathLength);
00896   if (nStatus >= 0) {
00897     Paths = (char *)malloc(nMaxPathLength*nGridGroups*sizeof(char));
00898     nStatus = xfGetGroupPathsForGrids(xFileId, nGridGroups, 
00899                                          nMaxPathLength, Paths);
00900   }
00901   if (nStatus < 0) {
00902     xfCloseFile(xFileId);
00903     return -1;
00904   }
00905 
00906   // Report the number and paths to individual meshes in the file.
00907   fprintf(fp, "Number of grids in file: %d\n", nGridGroups);
00908   fprintf(fp, "Paths:\n");
00909   for (i = 0; i < nGridGroups; i++) {
00910     IndividualPath = &Paths[i*nMaxPathLength];  
00911     fprintf(fp, "  %s\n", IndividualPath);
00912   }
00913   fprintf(fp, "\n");
00914 
00915   // Open each grid group
00916   for (i = 0; i < nGridGroups; i++) {
00917     IndividualPath = &Paths[i*nMaxPathLength];  
00918     
00919     fprintf(fp, "Reading grid in group: %s\n", IndividualPath);
00920     nStatus = xfOpenGroup(xFileId, IndividualPath, &xGroupId);
00921     if (nStatus >= 0) {
00922       nStatus = tgReadGrid(xGroupId, fp);
00923     }
00924     if (nStatus < 0) {
00925       printf("Error reading grid..\n");
00926     }
00927   }
00928 
00929   if (Paths) {
00930     free(Paths);
00931     Paths = NULL;
00932   }
00933   
00934   // TODO do grid, and cross-section stuff.
00935    
00936 
00937   // close the files
00938   xfCloseFile(xFileId);
00939   fclose(fp);
00940   
00941   return TRUE;
00942 } // txiReadXFormatFileT
00943 
00944 //-----------------------------------------------------------------------------
00945 // FUNCTION TXI_WRITE_XMDF_VERSION
00946 // PURPOSE  Write the XMDF version number to the screen
00947 // NOTES
00948 //-----------------------------------------------------------------------------
00949 int txiTestVersion ()
00950 {
00951   float    Version;
00952 
00953   printf("\n");
00954 
00955   xfGetLibraryVersion(&Version);
00956   printf("The current version of XMDF is: %f\n\n", Version);
00957 
00958   return 1;
00959 }  // txiTestVersion
00960 
00961 //-----------------------------------------------------------------------------
00962 // #defines used in txiTestCalendar
00963 //-----------------------------------------------------------------------------
00964 
00965 #define CALENDAR_OUT_C "Calendar_c.txt"
00966 
00967 //----------------------------------------------------------------------------
00968 // SUBROUTINE txiTestCalendar
00969 // PURPOSE    Check the Calculations of Julian date from calendar date or  
00970 //            vice-versa.
00971 // NOTES      Use #defines: ERA_IS_BCE (BC), and ERA_IS_CE (AD).
00972 //----------------------------------------------------------------------------
00973 int txiTestCalendar ()
00974 {
00975   FILE    *fp = NULL;
00976   xmbool   era1, era2, era3, era4;
00977   int     yr1, mo1, day1, hr1, min1, sec1;
00978   int     yr2, mo2, day2, hr2, min2, sec2;
00979   int     yr3, mo3, day3, hr3, min3, sec3;
00980   int     yr4, mo4, day4, hr4, min4, sec4, calendarworks;
00981   double  julian1, julian2, julian3, julian4;
00982 
00983   calendarworks = 0;
00984 
00985   // open the status file
00986   fp = fopen(CALENDAR_OUT_C, "w");
00987   if (fp == NULL) {
00988     return FALSE;
00989   }
00990 
00991 
00992   fprintf(fp, "Calendar conversion:\n\n");
00993 
00994   era1 = ERA_IS_BCE;
00995   yr1 = mo1 = day1 = hr1 = min1 = sec1 = 0;
00996   julian1 = 2655.5;
00997   xfJulianToCalendar(&era1, &yr1, &mo1, &day1, &hr1, &min1, &sec1, julian1);
00998 
00999   yr2  = 4706;
01000   mo2  = 4;
01001   day2 = 10;
01002   era2 = ERA_IS_BCE;
01003   hr2  = min2 = sec2 = 0;
01004   julian2 = 0.0;
01005   xfCalendarToJulian(era2, yr2, mo2, day2, hr2, min2, sec2, &julian2);
01006 
01007   era3 = ERA_IS_CE;
01008   yr3  = 2004;
01009   mo3  = 6;
01010   day3 = 3;
01011   hr3  = 2;
01012   min3 = 8;
01013   sec3 = 32;
01014   julian3 = 0.0;
01015   xfCalendarToJulian(era3, yr3, mo3, day3, hr3, min3, sec3, &julian3);
01016 
01017   era4 = ERA_IS_BCE;
01018   yr4 = mo4 = day4 = hr4 = min4 = sec4 = 0;
01019   julian4 = 2453159.58926;
01020   xfJulianToCalendar(&era4, &yr4, &mo4, &day4, &hr4, &min4, &sec4, julian4);
01021 
01022 fprintf(fp, "Dates #1 & #2  were calculated with the same date:\n\n");
01023 fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
01024         era1, yr1, mo1, day1, hr1, min1, sec1, julian1);
01025 fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n\n",
01026         era2, yr2, mo2, day2, hr2, min2, sec2, julian2);
01027 fprintf(fp, "Dates #3 & #4  were calculated with the same date:\n\n");
01028 fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
01029         era3, yr3, mo3, day3, hr3, min3, sec3, julian3);
01030 fprintf(fp, "%d / %d / %d / %d / %d / %d / %d --- Julian = %f\n\n",
01031         era4, yr4, mo4, day4, hr4, min4, sec4, julian4);
01032 
01033   if (era1==era2 && era3==era4) {
01034     if (yr1==yr2 && yr3==yr4) {
01035       if (mo1==mo2 && mo3==mo4) {
01036         if (day1==day2 && day3==day4) {
01037           if (hr1==hr2 && hr3==hr4) {
01038             if (min1==min2 && min3==min4) {
01039               if (EQ_EPS(julian1, julian2, DBL_EPS) && 
01040                   EQ_EPS(julian3, julian4, DBL_EPS)) {
01041                                   printf("\n");
01042                                   printf("Calendar conversion works correctly.\n");
01043                                         calendarworks = 1;
01044               }
01045             }
01046           }
01047         }
01048       }
01049     }
01050   }
01051 
01052   if (calendarworks != 1) {
01053     printf("\n");
01054     printf("Calendar Conversion DOES NOT Work Correctly.\n");
01055           return -1;
01056   }
01057   else {
01058     return 1;
01059   }
01060 
01061 }
01062 //----------------------------------------------------------------------------
01063 // SUBROUTINE txiTestCoordSystem
01064 // PURPOSE    Reads a file's Coordinate Group and prints coordinate data out
01065 //            to each text file.
01066 // NOTES
01067 //----------------------------------------------------------------------------
01068 int txiTestCoordSystem (xid xFileId, FILE *a_OutFile)
01069 {
01070   int     iHorizDatum, iHorizUnits, iVertDatum, iVertUnits;
01071   int     iLat, iLon, iUtmZone, iSpcZone, iHpgnArea, iEllipse;
01072   int     bHorizDatum, nStatus;
01073   double  dCppLat, dCppLon, dMajorR, dMinorR;
01074   xid     xCoordId = NONE;
01075   char    strHorizUnits[256], strVertDatum[256], strVertUnits[256];
01076 
01077   // Coordinate stuff
01078   // Read Coordinate Info
01079     // Open the Coordinate group
01080   nStatus = xfOpenCoordinateGroup(xFileId, &xCoordId);
01081   if (nStatus <= 0) {
01082     fprintf(a_OutFile, "\n");
01083     fprintf(a_OutFile, "Coordinate Group not found\n");
01084     fprintf(a_OutFile, "\n");
01085     return -1;
01086   }
01087 
01088   fprintf(a_OutFile, "\n");
01089   fprintf(a_OutFile, "Coordinate System:\n");
01090 
01091   bHorizDatum = xfGetHorizDatum(xCoordId, &iHorizDatum);
01092   xfGetHorizUnits(xCoordId, &iHorizUnits);
01093   xfGetVertDatum(xCoordId, &iVertDatum);
01094   xfGetVertUnits(xCoordId, &iVertUnits);
01095     // set horizontal units
01096   if (iHorizUnits == 0) {
01097     strcpy(strHorizUnits, "Horizontal units = US Survey Feet (=0)");
01098   }
01099   else if (iHorizUnits == 1) {
01100     strcpy(strHorizUnits, "Horizontal units = International Feet (=1)");
01101   }
01102   else if (iHorizUnits == 2) {
01103     strcpy(strHorizUnits, "Horizontal units = Meters (=2)");
01104   }
01105   else {
01106     strcpy(strHorizUnits, "ERROR in reading Horizontal units");
01107   }
01108     // set vertical datum
01109   if (iVertDatum == 0) {
01110     strcpy(strVertDatum, "Vertical datum = Local (=0)");
01111   }
01112   else if (iVertDatum == 1) {
01113     strcpy(strVertDatum, "Vertical datum = NGVD 29 (=1)");
01114   }
01115   else if (iVertDatum == 2) {
01116     strcpy(strVertDatum, "Vertical datum = NGVD 88 (=2)");
01117   }
01118   else {
01119     strcpy(strVertDatum, "ERROR in reading the Vertical datum\n");
01120   }
01121     // set vertocal units
01122   if (iVertUnits == 0) {
01123     strcpy(strVertUnits, "Vertical units = US Survey Feet (=0)");
01124   }
01125   else if (iVertUnits == 1) {
01126     strcpy(strVertUnits, "Vertical units = International Feet (=1)");
01127   }
01128   else if (iVertUnits == 2) {
01129     strcpy(strVertUnits, "Vertical units = Meters (=2)");
01130   }
01131   else {
01132     strcpy(strVertUnits, "ERROR in reading the Vertical units");
01133   }
01134 
01135   if (bHorizDatum >= 0) {
01136     switch (iHorizDatum) {
01137       case HORIZ_DATUM_GEOGRAPHIC:
01138         xfGetEllipse(xCoordId, &iEllipse);
01139         xfGetLat(xCoordId, &iLat);
01140         xfGetLon(xCoordId, &iLon);
01141           // Write Horizontal and Vertical Info
01142         fprintf(a_OutFile, "Horizontal datum = Geographic\n");
01143         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01144         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01145         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01146           // Write Latitude data
01147         if (iLat == 0) {
01148           fprintf(a_OutFile, "  Latitude = North (=%d)\n", iLat);
01149         }
01150         else if (iLat == 1) {
01151           fprintf(a_OutFile, "  Latitude = South (=%d)\n", iLat);
01152         }
01153         else {
01154           fprintf(a_OutFile, "  LATITUDE INFO INCORRECT\n");
01155         }
01156           // Longitude
01157         if (iLon == 0) {
01158           fprintf(a_OutFile, "  Longitude = East (=%d)\n", iLon);
01159         }
01160         else if (iLon == 1) {
01161           fprintf(a_OutFile, "  Longitude = West (=%d)\n", iLon);
01162         }
01163         else {
01164           fprintf(a_OutFile, "  LONGITUDE INFO INCORRECT\n");
01165         }
01166           // Ellipse Information
01167           // User-defined Ellipse (==32)
01168         if (iEllipse == 32) {
01169           fprintf(a_OutFile, "Ellipse = User-defined:\n");
01170           xfGetMajorR(xCoordId, &dMajorR);
01171           xfGetMinorR(xCoordId, &dMinorR);
01172           fprintf(a_OutFile, "  MajorR = %lf\n", dMajorR);
01173           fprintf(a_OutFile, "  MinorR = %lf\n\n", dMinorR);
01174         }
01175         else {
01176           fprintf(a_OutFile, "Ellipse = %d\n\n", iEllipse);
01177         }
01178         break;
01179       case HORIZ_DATUM_UTM:
01180       case HORIZ_DATUM_UTM_NAD27:
01181       case HORIZ_DATUM_UTM_NAD83:
01182         xfGetUTMZone(xCoordId, &iUtmZone);
01183           // output info to text file
01184         if (iHorizDatum == HORIZ_DATUM_UTM) {
01185           fprintf(a_OutFile, "Horizontal datum = UTM\n");
01186         }
01187         else if (iHorizDatum == HORIZ_DATUM_UTM_NAD27) {
01188           fprintf(a_OutFile, "Horizontal datum = UTM NAD27 (US)\n");
01189         }
01190         else {
01191           fprintf(a_OutFile, "Horizontal datum = UTM NAD83 (US)\n");
01192         }
01193         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01194         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01195         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01196         fprintf(a_OutFile, "UTM Zone = %d\n\n", iUtmZone);
01197         break;
01198       case HORIZ_DATUM_STATE_PLANE_NAD27:
01199       case HORIZ_DATUM_STATE_PLANE_NAD83:
01200         xfGetSPCZone(xCoordId, &iSpcZone);
01201           // output info to text file
01202         if (iHorizDatum == HORIZ_DATUM_STATE_PLANE_NAD27) {
01203           fprintf(a_OutFile, "Horizontal datum = State Plane NAD27 (US)\n");
01204         }
01205         else {
01206           fprintf(a_OutFile, "Horizontal datum = State Plane NAD83 (US)\n");
01207         }
01208         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01209         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01210         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01211         fprintf(a_OutFile, "SPC Zone = %d\n\n", iSpcZone);
01212         break;
01213       case HORIZ_DATUM_UTM_HPGN:
01214       case HORIZ_DATUM_STATE_PLANE_HPGN:
01215       case HORIZ_DATUM_GEOGRAPHIC_HPGN:
01216         xfGetHPGNArea(xCoordId, &iHpgnArea);
01217         if (iHorizDatum == HORIZ_DATUM_UTM_HPGN) {
01218           fprintf(a_OutFile, "Horizontal datum = UTM HPGN (US)\n");
01219         }
01220         else if (iHorizDatum == HORIZ_DATUM_STATE_PLANE_HPGN) {
01221           fprintf(a_OutFile, "Horizontal datum = State Plane HPGN (US)\n");
01222         }
01223         else {
01224           fprintf(a_OutFile, "Horizontal datum = Geographic HPGN (US)\n");
01225         }
01226         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01227         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01228         fprintf(a_OutFile, "Vertical units = %s\n", strVertUnits);
01229         fprintf(a_OutFile, "HPGN Area = %d\n\n", iHpgnArea);
01230         break;
01231       case HORIZ_DATUM_CPP:
01232         xfGetCPPLat(xCoordId, &dCppLat);
01233         xfGetCPPLon(xCoordId, &dCppLon);
01234         fprintf(a_OutFile, "Horizontal datum = CPP (Carte Parallelo-Grammatique Projection)\n");
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", strVertUnits);
01238         fprintf(a_OutFile, "CPP Latitude = %lf\n", dCppLat);
01239         fprintf(a_OutFile, "CPP Longitude = %lf\n\n", dCppLon);
01240         break;
01241       default:
01242         // do other systems
01243         if (iHorizDatum == HORIZ_DATUM_LOCAL) {
01244           fprintf(a_OutFile, "Horizontal datum = Local\n");
01245         }
01246         else if (iHorizDatum == HORIZ_DATUM_GEOGRAPHIC_NAD27) {
01247           fprintf(a_OutFile, "Horizontal datum = Geographic NAD27 (US)\n");
01248         }
01249         else if (iHorizDatum == HORIZ_DATUM_GEOGRAPHIC_NAD83) {
01250           fprintf(a_OutFile, "Horizontal datum = Geographic NAD83 (US)\n");
01251         }
01252         else {
01253           fprintf(a_OutFile, "ERROR: The Horizontal Datum in the .h5 file is not recognizable\n");
01254           return -1;
01255         }
01256         fprintf(a_OutFile, "Horizontal units = %s\n", strHorizUnits);
01257         fprintf(a_OutFile, "Vertical datum = %s\n", strVertDatum);
01258         fprintf(a_OutFile, "Vertical units = %s\n\n", strVertUnits);
01259         break;
01260     }
01261   }
01262   else {
01263     fprintf(a_OutFile, "Coordinate information in HDF5 file is incomplete.");
01264     fprintf(a_OutFile, "\n");
01265   }
01266 
01267   xfCloseGroup(xCoordId);
01268   xCoordId = 0;
01269 
01270   return TRUE;
01271 } // txiTestCoordSystem

Generated on Fri Mar 7 10:09:32 2008 for XMDF by  doxygen 1.4.6-NO