TestXmdf.cpp

TestXmdf.cpp provides C++ code examples for many XMDF APIs.
00001 // This file has functions that can be used to test reading and writing of
00002 // datasets using HDF5.  This code is intended to be used as tests for the
00003 // XMDF library as well as sample code for distribution.
00004 
00005 #include "stdafx.h"
00006 #include <Xmdf.h>
00007 #include <stdio.h>
00008 #include <windows.h>
00009 #include <string.h>
00010 #include <stdlib.h>
00011 
00012 #define    DATASETS_LOCATION "Datasets"
00013 #define    SCALAR_A_LOCATION "Scalars/ScalarA"
00014 #define    SCALAR_B_LOCATION "Scalars/ScalarB"
00015 #define    VECTOR2D_A_LOCATION "Vectors/Vector2D_A"
00016 #define    VECTOR2D_B_LOCATION "Vectors/Vector2D_B"
00017 
00018 void tdiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
00019                      int a_SeedMultiplier, int a_nValues, float *a_Array);
00020 double tdiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed);
00021 int tdiReadScalar (xid a_xScalarId, FILE *a_fp);
00022 int tdiReadVector (xid a_xVectorId, FILE *a_fp);
00023 
00024 // --------------------------------------------------------------------------
00025 // FUNCTION tdReadDatasets
00026 // PURPOSE  Read a dataset group from an XMDF file and output information to
00027 //          to a text file
00028 // NOTES    
00029 // --------------------------------------------------------------------------
00030 int tdReadDatasets (xid a_xGroupId, FILE *a_fp)
00031 {
00032   int   nPaths=0, nMaxPathLength=0, nMultiDatasets=0;
00033   char *Paths = NULL, *IndividualPath = NULL;
00034   int   nStatus, i, j;
00035   xid   xScalarId = NONE, xVectorId = NONE, xMultiId = NONE;
00036 
00037   // Look for scalar datasets
00038   nStatus = xfGetScalarDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00039   if (nStatus >= 0) {
00040     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00041     xfGetScalarDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00042   }
00043   if (nStatus < 0) {
00044     return -1;
00045   }
00046   
00047   // Output number and paths to scalar datasets
00048   fprintf(a_fp, "Number of Scalars %d\n", nPaths);
00049   for (i = 0; i < nPaths; i++) {
00050     IndividualPath = &Paths[i*nMaxPathLength];
00051     fprintf(a_fp, "Reading scalar: %s\n", IndividualPath);
00052    
00053     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xScalarId);
00054     if (nStatus < 0) {
00055       return -1; 
00056     }
00057 
00058     nStatus = tdiReadScalar(xScalarId, a_fp);
00059     xfCloseGroup(xScalarId);
00060     if (nStatus < 0) {
00061       printf("Error reading scalar dataset.");
00062       return -1;
00063     }
00064   }
00065 
00066   if (Paths) {
00067     free(Paths);
00068     Paths = NULL;
00069   }
00070 
00071   // Look for vector datasets
00072   nStatus = xfGetVectorDatasetsInfo(a_xGroupId, &nPaths, &nMaxPathLength);
00073   if (nStatus >= 0 && nPaths > 0) {
00074     Paths = (char *)malloc(nPaths*nMaxPathLength*sizeof(char));
00075     xfGetVectorDatasetPaths(a_xGroupId, nPaths, nMaxPathLength, Paths);
00076   }
00077   if (nStatus < 0) {
00078     return -1;
00079   }
00080 
00081 
00082   // Output number and paths to scalar datasets
00083   fprintf(a_fp, "Number of Vectors %d\n", nPaths);
00084   for (i = 0; i < nPaths; i++) {
00085     IndividualPath = &Paths[i*nMaxPathLength];
00086     fprintf(a_fp, "Reading Vector: %s\n", IndividualPath);
00087    
00088     nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xVectorId);
00089     if (nStatus < 0) {
00090       return -1; 
00091     }
00092 
00093     nStatus = tdiReadVector(xVectorId, a_fp);
00094     xfCloseGroup(xVectorId);
00095     if (nStatus < 0) {
00096       printf("Error reading vector dataset.");
00097       return -1;
00098     }
00099   }
00100 
00101   // find multidataset folders
00102   nStatus = xfGetGroupPathsSizeForMultiDatasets(a_xGroupId, &nMultiDatasets,
00103                                                       &nMaxPathLength);
00104   if (nStatus >= 0 && nMultiDatasets > 0) {
00105     Paths = (char *)malloc(nMultiDatasets*nMaxPathLength*sizeof(char));
00106     nStatus = xfGetAllGroupPathsForMultiDatasets(a_xGroupId, nMultiDatasets, 
00107                                                  nMaxPathLength, Paths);
00108     if (nStatus < 0) {
00109       return -1;
00110     }
00111 
00112   // Output number and paths to multidatasets
00113     fprintf(a_fp, "Number of Multidatasets: %d\n", nMultiDatasets);
00114     for (i=0; i<nMultiDatasets; i++) {
00115       IndividualPath = "";
00116       for (j=0; j<nMaxPathLength-1; j++) {
00117         IndividualPath = &Paths[i*nMaxPathLength];
00118       }
00119       fprintf(a_fp, "Reading multidataset: %s\n", IndividualPath);
00120       nStatus = xfOpenGroup(a_xGroupId, IndividualPath, &xMultiId);
00121       if (nStatus < 0) {
00122             return -1;
00123       }
00124 
00125       nStatus = tdReadDatasets(xMultiId, a_fp);
00126       nStatus = xfCloseGroup(xMultiId);
00127       if (nStatus < 0) {
00128         printf("Error reading multidatasets.");
00129             return -1;
00130       }
00131     }
00132   }
00133 
00134   if (Paths) {
00135     free(Paths);
00136     Paths = NULL;
00137   }
00138 
00139   return 1;
00140 } // tdReadDatasets
00141 // --------------------------------------------------------------------------
00142 // FUNCTION tdReadActivityScalarAIndex
00143 // PURPOSE  Read all timestep values for a particular index
00144 // NOTES    
00145 // --------------------------------------------------------------------------
00146 int tdReadActivityScalarAIndex (LPCSTR a_Filename, int a_Index)
00147 {
00148   int     status;
00149   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00150   int     nTimesteps;
00151   xmbool  *bActive;
00152 
00153   // open the file
00154   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00155   if (status < 0) {
00156     return FALSE;
00157   }
00158 
00159   // open the dataset group
00160   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00161   if (status >= 0) {
00162     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00163   }
00164   if (status < 0) {
00165     return status;
00166   }
00167 
00168   // Find out the number of timesteps in the file
00169   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00170   if (status < 0) {
00171     return status;
00172   }
00173   if (nTimesteps < 1) {
00174     return -1;
00175   }
00176 
00177   // Read the values for the index
00178   bActive = new xmbool[nTimesteps];
00179   status = xfReadActivityValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00180                                        bActive);
00181 
00182   // output the data
00183   printf("\nReading activity for scalar A slice at index: %d\n", a_Index);
00184   for (int i = 0; i < nTimesteps; i++) {
00185     printf("%d ", bActive[i]);
00186   }
00187   printf("\n");
00188 
00189   delete [] bActive;
00190 
00191   return status;
00192 } // tdReadActivityScalarAtIndex
00193 // --------------------------------------------------------------------------
00194 // FUNCTION tdReadScalarAIndex
00195 // PURPOSE  Read all timestep values for a particular index
00196 // NOTES    
00197 // --------------------------------------------------------------------------
00198 int tdReadScalarAIndex (LPCSTR a_Filename, int a_Index)
00199 {
00200   int     status;
00201   xid     xFileId = NONE, xDsetsId = NONE, xScalarAId = NONE;
00202   int     nTimesteps;
00203   float  *fValues;
00204 
00205   // open the file
00206   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00207   if (status < 0) {
00208     return FALSE;
00209   }
00210 
00211   // open the dataset group
00212   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00213   if (status >= 0) {
00214     status = xfOpenGroup(xDsetsId, SCALAR_A_LOCATION, &xScalarAId);
00215   }
00216   if (status < 0) {
00217     return status;
00218   }
00219 
00220   // Find out the number of timesteps in the file
00221   status = xfGetDatasetNumTimes(xScalarAId, &nTimesteps);
00222   if (status < 0) {
00223     return status;
00224   }
00225   if (nTimesteps < 1) {
00226     return -1;
00227   }
00228 
00229   // Read the values for the index
00230   fValues = new float[nTimesteps];
00231   status = xfReadScalarValuesAtIndex(xScalarAId, a_Index, 1, nTimesteps,
00232                                      fValues);
00233 
00234   // output the data
00235   printf("\nReading scalar A slice at index: %d\n", a_Index);
00236   for (int i = 0; i < nTimesteps; i++) {
00237     printf("%f ", fValues[i]);
00238   }
00239   printf("\n");
00240 
00241   delete [] fValues;
00242 
00243   return status;
00244 } // tdReadScalarAtIndex
00245 // --------------------------------------------------------------------------
00246 // FUNCTION tdWriteScalarA
00247 // PURPOSE  Write scalar Dataset to an HDF5 File
00248 // NOTES    This tests dynamic data sets, and activity
00249 //          This dataset is dynamic concentrations (mg/L) with output times
00250 //          in minutes.
00251 //          Dataset is for a mesh and so nActive is the number of elements
00252 //          which is not the same as the nValues which would be number of nodes
00253 //          reads/writes a reference time in julian days
00254 // --------------------------------------------------------------------------
00255 int tdWriteScalarA (LPCSTR a_Filename, int a_Compression)
00256 {
00257   xid      xFileId, xDsetsId, xScalarAId, xCoordId = NONE;
00258   int      nValues = 10, nTimes = 3, nActive = 8;
00259   double   dTime = 0.0;
00260   int      iTimestep, iActive;
00261   float    fValues[10]; // nValues
00262   xmbool    bActivity[10]; // activity
00263   int      status, iHpgnZone;
00264   double   dJulianReftime;
00265   int      nErrors = 0, i = 0;
00266   char     **Errors = NULL;
00267 
00268   // 5th item in data set is always inactive, others active
00269   for (iActive = 0; iActive < nActive; iActive++) {
00270     bActivity[iActive] = XTRUE;
00271   }
00272   bActivity[5] = XFALSE;
00273 
00274   // create the file
00275   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00276   if (status < 0) {
00277     return FALSE;
00278   }
00279 
00280   // create the group where we will put all the datasets 
00281   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00282   if (status < 0) {
00283     xfCloseFile(xFileId);
00284     return FALSE;
00285   }
00286 
00287   // uncomment next line to test error handling function
00288   // xfCloseGroup(xDsetsId);
00289 
00290   // Create the scalar A dataset group
00291   status = xfCreateScalarDataset(xDsetsId, SCALAR_A_LOCATION,
00292                                  "mg/L", TS_HOURS, a_Compression,
00293                                  &xScalarAId);
00294   if (status < 0) {
00295     // print the error stack
00296     xfGetNumErrorMessages(&nErrors);
00297     if (nErrors > 0) {
00298       Errors = new char*[nErrors];
00299       for (i = 0; i < nErrors; i++) {
00300         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00301       }
00302       status = xfGetErrorMessages(nErrors, Errors);
00303       if (status > 0) {
00304         for (i = 0; i < nErrors; i++) {
00305           printf("%s\n", Errors[i]);
00306         }
00307       }
00308       for (i = 0; i < nErrors; i++) {
00309         delete Errors[i];
00310       }
00311       delete Errors;
00312     }
00313 
00314     xfCloseGroup(xDsetsId);
00315     xfCloseFile(xFileId);
00316     return FALSE;
00317   }
00318 
00319   // Add in a reftime.  This is a julian day for:
00320   // noon July 1, 2003
00321   dJulianReftime = 2452822.0;
00322   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00323   if (status < 0) {
00324     xfCloseGroup(xScalarAId);
00325     xfCloseGroup(xDsetsId);
00326     xfCloseFile(xFileId);
00327   }
00328 
00329   // Loop through timesteps adding them to the file
00330   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00331     // We will have an 0.5 hour timestep
00332     dTime = (iTimestep + 1) * 0.5;
00333 
00334     fValues[0] = (float)dTime;
00335     for (i = 1; i < nValues; i++) {
00336       fValues[i] = float(fValues[i-1]*2.5);
00337     }
00338 
00339     // write the dataset array values
00340     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00341     if (status >= 0) {
00342       // write activity array
00343       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00344     }
00345     if (status < 0) {
00346       xfCloseGroup(xScalarAId);
00347       xfCloseGroup(xDsetsId);
00348       xfCloseFile(xFileId);
00349     }
00350   }
00351 
00352   // Write Coordinate file - for ScalarA, we will set the coordinate system
00353   //   to be Geographic HPGN, with HPGN settings written to the file.
00354   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00355   if (status <= 0) {
00356     xfCloseGroup(xScalarAId);
00357     xfCloseGroup(xDsetsId);
00358     xfCloseFile(xFileId);
00359         return -1;
00360   }
00361 
00362     // set HPGN Zone for test
00363   iHpgnZone = 29;      // Utah
00364 
00365     // Write Coordinate Information to file
00366   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00367   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00368   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00369   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00370 
00371     // write additional information
00372   xfSetHPGNArea(xCoordId, iHpgnZone);
00373 
00374   xfCloseGroup(xCoordId);
00375   xCoordId = 0;
00376 
00377   // close the dataset
00378   xfCloseGroup(xScalarAId);
00379   xfCloseGroup(xDsetsId);
00380   xfCloseFile(xFileId);
00381 
00382   return FALSE;
00383 } // tdWriteScalarA
00384 
00385 // --------------------------------------------------------------------------
00386 // FUNCTION tdWriteScalarB
00387 // PURPOSE  Write scalar Dataset to an HDF5 File
00388 // NOTES    This tests dynamic data sets, and activity
00389 //          This dataset is dynamic concentrations (mg/L) with output times
00390 //          in minutes.
00391 //          Dataset is for a mesh and so nActive is the number of elements
00392 //          which is not the same as the nValues which would be number of nodes
00393 //          reads/writes a reference time in julian days
00394 // --------------------------------------------------------------------------
00395 int tdWriteScalarB (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00396 {
00397   xid      xFileId, xDsetsId, xScalarBId, xCoordId = NONE;
00398   int      nValues = 10, nTimes = 3, nActive = 8;
00399   double   dTime = 0.0, dJulianReftime;
00400   int      iTimestep, iActive;
00401   float    fValues[10]; // nValues
00402   xmbool    bActivity[10]; // activity
00403   int      status, nErrors = 0, i = 0;
00404   char     **Errors = NULL;
00405 
00406   // 5th item in data set is always inactive, others active
00407   for (iActive = 0; iActive < nActive; iActive++) {
00408     bActivity[iActive] = XTRUE;
00409   }
00410   bActivity[5] = XFALSE;
00411 
00412   if (a_Overwrite) {
00413       // open the already-existing file
00414     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00415     if (status < 0) {
00416       return -1;
00417     }
00418       // open the group where we have all the datasets 
00419     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00420     if (status < 0) {
00421       xfCloseFile(xFileId);
00422       return -1;
00423     }
00424   }
00425   else {
00426       // create the file
00427     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00428     if (status < 0) {
00429       return -1;
00430     }
00431       // create the group where we will put all the datasets 
00432     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00433     if (status < 0) {
00434       xfCloseFile(xFileId);
00435       return -1;
00436     }
00437   }
00438 
00439   // uncomment next line to test error handling function
00440   // xfCloseGroup(xDsetsId);
00441 
00442   // Create/Overwrite the scalar B dataset group
00443   status = xfCreateScalarDataset(xDsetsId, SCALAR_B_LOCATION,
00444                                  "mg/L", TS_HOURS, a_Compression,
00445                                  &xScalarBId);
00446   if (status < 0) {
00447     // print the error stack
00448     xfGetNumErrorMessages(&nErrors);
00449     if (nErrors > 0) {
00450       Errors = new char*[nErrors];
00451       for (i = 0; i < nErrors; i++) {
00452         Errors[i] = new char[XF_MAX_ERROR_MSG_SIZE];
00453       }
00454       status = xfGetErrorMessages(nErrors, Errors);
00455       if (status > 0) {
00456         for (i = 0; i < nErrors; i++) {
00457           printf("%s\n", Errors[i]);
00458         }
00459       }
00460       for (i = 0; i < nErrors; i++) {
00461         delete Errors[i];
00462       }
00463       delete Errors;
00464     }
00465 
00466     xfCloseGroup(xDsetsId);
00467     xfCloseFile(xFileId);
00468     return -1;
00469   }
00470 
00471   // Add in a reftime.  This is a julian day for:
00472   // noon July 1, 2003
00473   dJulianReftime = 2452822.0;
00474   status = xfDatasetReftime(xScalarBId, dJulianReftime);
00475   if (status < 0) {
00476     xfCloseGroup(xScalarBId);
00477     xfCloseGroup(xDsetsId);
00478     xfCloseFile(xFileId);
00479   }
00480 
00481   if (!a_Overwrite) {
00482     // Loop through timesteps adding them to the file
00483     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00484       // We will have an 0.5 hour timestep
00485       dTime = (iTimestep + 1) * 0.5;
00486 
00487       fValues[0] = (float)dTime;
00488       for (i = 1; i < nValues; i++) {
00489         fValues[i] = float(fValues[i-1]*2.5);
00490       }
00491 
00492       // write the dataset array values
00493       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00494       if (status >= 0) {
00495         // write activity array
00496         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00497       }
00498       if (status < 0) {
00499         xfCloseGroup(xScalarBId);
00500         xfCloseGroup(xDsetsId);
00501         xfCloseFile(xFileId);
00502       }
00503     }
00504   }
00505   else {
00506     // Loop through timesteps adding them to the file
00507     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00508       // We will have an 1.5 hour timestep
00509       dTime = (iTimestep + 1) * 1.5;
00510 
00511       fValues[0] = (float)dTime;
00512       for (i = 1; i < nValues; i++) {
00513         fValues[i] = float(fValues[i-1]*1.5);
00514       }
00515 
00516       // write the dataset array values
00517       status = xfWriteScalarTimestep(xScalarBId, dTime, nValues, fValues);
00518       if (status >= 0) {
00519         // write activity array
00520         xfWriteActivityTimestep(xScalarBId, nActive, bActivity);
00521       }
00522       if (status < 0) {
00523         xfCloseGroup(xScalarBId);
00524         xfCloseGroup(xDsetsId);
00525         xfCloseFile(xFileId);
00526       }
00527     }
00528   }
00529 
00530   if (!a_Overwrite) {
00531     // Write Coordinate file
00532     status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00533     if (status <= 0) {
00534       xfCloseGroup(xScalarBId);
00535       xfCloseGroup(xDsetsId);
00536       xfCloseFile(xFileId);
00537       return -1;
00538     }
00539 
00540     // For ScalarB, we will set the coordinate system
00541     // to be UTM, with UTM Zone settings written to the file.
00542       // Write Coord Info to file
00543     xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00544     xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00545 
00546     xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00547     xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00548 
00549       // write additional information - we'll use the max value for this test
00550     xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00551 
00552     xfCloseGroup(xCoordId);
00553     xCoordId = 0;
00554   }
00555 
00556   // close the dataset
00557   xfCloseGroup(xScalarBId);
00558   xfCloseGroup(xDsetsId);
00559   xfCloseFile(xFileId);
00560 
00561   return 1;
00562 } // tdWriteScalarB
00563 // --------------------------------------------------------------------------
00564 // FUNCTION tdWriteCoordsToMulti
00565 // PURPOSE  Write coordinate system to a multidataset file
00566 // NOTES
00567 // --------------------------------------------------------------------------
00568 int tdWriteCoordsToMulti (xid a_xFileId)
00569 {
00570   xid   xCoordId = NONE;
00571   int   status;
00572 
00573   // Write Coordinate file - for Multidatasets, we will set the coordinate system
00574   //   to be UTM, with UTM Zone settings written to the file.
00575   status = xfCreateCoordinateGroup(a_xFileId, &xCoordId);
00576   if (status <= 0) {
00577     return -1;
00578   }
00579 
00580    // Write Coord Info to file
00581   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00582   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00583 
00584   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00585   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00586 
00587     // write additional information - we'll use the max value for this test
00588   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00589 
00590   xfCloseGroup(xCoordId);
00591   xCoordId = 0;
00592 
00593   return XTRUE;
00594 } // tdWriteCoordsToMulti
00595 // --------------------------------------------------------------------------
00596 // FUNCTION tdWriteScalarAToMulti
00597 // PURPOSE  Write scalar Dataset to a multidataset
00598 // NOTES    This tests dynamic data sets, and activity
00599 //          This dataset is dynamic concentrations (mg/L) with output times
00600 //          in minutes.
00601 //          Dataset is for a mesh and so nActive is the number of elements
00602 //          which is not the same as the nValues which would be number of nodes
00603 //          reads/writes a reference time in julian days
00604 // --------------------------------------------------------------------------
00605 int tdWriteScalarAToMulti (xid a_GroupId)
00606 {
00607   xid      xScalarAId;
00608   int      nValues = 10, nTimes = 3, nActive = 8;
00609   double   dTime = 0.0;
00610   int      iTimestep, iActive;
00611   float    fValues[10]; // nValues
00612   xmbool    bActivity[10]; // activity
00613   int      status;
00614   double   dJulianReftime;
00615   int      i = 0;
00616 
00617   // 5th item in data set is always inactive, others active
00618   for (iActive = 0; iActive < nActive; iActive++) {
00619     bActivity[iActive] = XTRUE;
00620   }
00621   bActivity[5] = XFALSE;
00622 
00623   // Create the scalar A dataset group
00624   status = xfCreateScalarDataset(a_GroupId, SCALAR_A_LOCATION,
00625                                  "mg/L", TS_HOURS, NONE,
00626                                  &xScalarAId);
00627   
00628   // Add in a reftime.  This is a julian day for:
00629   // noon July 1, 2003
00630   dJulianReftime = 2452822.0;
00631   status = xfDatasetReftime(xScalarAId, dJulianReftime);
00632   if (status < 0) {
00633     xfCloseGroup(xScalarAId);
00634   }
00635 
00636   // Loop through timesteps adding them to the file
00637   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00638     // We will have an 0.5 hour timestep
00639     dTime = (iTimestep + 1) * 0.5;
00640 
00641     fValues[0] = (float)dTime;
00642     for (i = 1; i < nValues; i++) {
00643       fValues[i] = float(fValues[i-1]*2.5);
00644     }
00645 
00646     // write the dataset array values
00647     status = xfWriteScalarTimestep(xScalarAId, dTime, nValues, fValues);
00648     if (status >= 0) {
00649       // write activity array
00650       xfWriteActivityTimestep(xScalarAId, nActive, bActivity);
00651     }
00652     if (status < 0) {
00653       xfCloseGroup(xScalarAId);
00654     }
00655   }
00656 
00657   // close the dataset
00658   xfCloseGroup(xScalarAId);
00659 
00660   return FALSE;
00661 } // tdWriteScalarAToMulti
00662 // --------------------------------------------------------------------------
00663 // FUNCTION tdReadVector2DAIndex
00664 // PURPOSE  Read all timestep values for a particular index
00665 // NOTES    
00666 // --------------------------------------------------------------------------
00667 int tdReadVector2DAIndex (LPCSTR a_Filename, int a_Index)
00668 {
00669   int     status;
00670   xid     xFileId = NONE, xDsetsId = NONE, xVector2DA = NONE;
00671   int     nTimesteps;
00672   float  *fValues;
00673 
00674   // open the file
00675   status = xfOpenFile(a_Filename, &xFileId, XTRUE);
00676   if (status < 0) {
00677     return FALSE;
00678   }
00679 
00680   // open the dataset group
00681   status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00682   if (status >= 0) {
00683     status = xfOpenGroup(xDsetsId, VECTOR2D_A_LOCATION, &xVector2DA);
00684   }
00685   if (status < 0) {
00686     return status;
00687   }
00688 
00689   // Find out the number of timesteps in the file
00690   status = xfGetDatasetNumTimes(xVector2DA, &nTimesteps);
00691   if (status < 0) {
00692     return status;
00693   }
00694   if (nTimesteps < 1) {
00695     return -1;
00696   }
00697 
00698   // Read the values for the index
00699   fValues = new float[nTimesteps*2];
00700   status = xfReadVectorValuesAtIndex(xVector2DA, a_Index, 1, nTimesteps, 2,
00701                                      fValues);
00702 
00703   // output the data
00704   printf("\nReading vector 2D A slice at index: %d\n", a_Index);
00705   for (int i = 0; i < nTimesteps; i++) {
00706     printf("%f %f \n", fValues[i*2], fValues[i*2 + 1]);
00707   }
00708   printf("\n");
00709 
00710   delete [] fValues;
00711 
00712   return status;
00713 } // tdReadVector2DAIndex
00714 // --------------------------------------------------------------------------
00715 // FUNCTION tdWriteVector2D_A
00716 // PURPOSE  Write 2D vector dataset to an HDF5 File
00717 // NOTES    This tests dynamic data sets, and activity
00718 //          Add reftime when it is completed
00719 //          This dataset is dynamic water velocities with output times
00720 //          in minutes.
00721 //          Dataset is for a mesh and so nActive is the number of elements
00722 //          which is not the same as the nValues which would be number of nodes
00723 // --------------------------------------------------------------------------
00724 int tdWriteVector2D_A (LPCSTR a_Filename, int a_Compression)
00725 {
00726   xid      xFileId, xDsetsId, xVectorA, xCoordId = NONE;
00727   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00728   double   dTime = 0.0;
00729   int      iTimestep, iActive;
00730   float    fValues[100*2]; // nValues*nComponents
00731   xmbool    bActivity[75]; // activity
00732 //  double   dMin = 0.5, dMax = 3.5;
00733 //  int      nSeedMultiplier = 138592;
00734   int      i, j, status;
00735   int      iHpgnZone;
00736 
00737   // 5th item in data set is always inactive, others active
00738   for (iActive = 0; iActive < nActive; iActive++) {
00739     if (iActive % 3 == 0) {
00740       bActivity[iActive] = XFALSE;
00741     }
00742     else {
00743       bActivity[iActive] = XTRUE;
00744     }
00745   }
00746 
00747   // create the file
00748   status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00749   if (status < 0) {
00750     return FALSE;
00751   }
00752 
00753   // create the group to store all datasets 
00754   status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00755   if (status < 0) {
00756     xfCloseFile(xFileId);
00757     return FALSE;
00758   }
00759 
00760   // Create the scalar A dataset group
00761   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_A_LOCATION, "ft/s",
00762                TS_SECONDS, a_Compression, &xVectorA);
00763   if (status < 0) {
00764     xfCloseGroup(xDsetsId);
00765     xfCloseFile(xFileId);
00766     return FALSE;
00767   }
00768 
00769   // Loop through timesteps adding them to the file
00770   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00771     // We will have an 0.5 hour timestep
00772     dTime = (iTimestep + 1) * 0.5;
00773 
00774     for (i = 0; i < nValues; i++) {
00775       for (j = 0; j < nComponents; j++) {
00776         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00777       }
00778     }
00779 //    // generate values array using random numbers between dMin and dMax
00780 //    tdiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
00781 //                    nValues*nComponents, fValues);
00782 
00783     // write the dataset array values
00784     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
00785                                    fValues);
00786     if (status >= 0) {
00787       // write activity array
00788       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
00789     }
00790     if (status < 0) {
00791       xfCloseGroup(xVectorA);
00792       xfCloseGroup(xDsetsId);
00793       xfCloseFile(xFileId);
00794     }
00795   }
00796 
00797   // Write Coordinate file - for Vector2D_A, we will set the coordinate system
00798   //   to be Geographic HPGN, with HPGN settings written to the file.
00799   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00800   if (status <= 0) {
00801     xfCloseGroup(xVectorA);
00802     xfCloseGroup(xDsetsId);
00803     xfCloseFile(xFileId);
00804         return -1;
00805   }
00806 
00807     // set HPGN info for test
00808   iHpgnZone = 29;      // Utah
00809 
00810   xfSetHorizDatum(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN);
00811   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00812   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00813   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00814 
00815     // write additional information
00816   xfSetHPGNArea(xCoordId, iHpgnZone);
00817 
00818   xfCloseGroup(xCoordId);
00819   xCoordId = 0;
00820 
00821   // close the dataset
00822   xfCloseGroup(xVectorA);
00823   xfCloseGroup(xDsetsId);
00824   xfCloseFile(xFileId);
00825 
00826   return FALSE;
00827 } // tdWriteVector2D_A
00828 // --------------------------------------------------------------------------
00829 // FUNCTION tdWriteVector2D_B
00830 // PURPOSE  Write 2D vector dataset to an HDF5 File
00831 // NOTES    This tests dynamic data sets, and activity
00832 //          Add reftime when it is completed
00833 //          This dataset is dynamic water velocities with output times
00834 //          in minutes.
00835 //          Dataset is for a mesh and so nActive is the number of elements
00836 //          which is not the same as the nValues which would be number of nodes
00837 // --------------------------------------------------------------------------
00838 int tdWriteVector2D_B (LPCSTR a_Filename, int a_Compression, int a_Overwrite)
00839 {
00840   xid      xFileId, xDsetsId, xVectorB, xCoordId = NONE;
00841   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00842   double   dTime = 0.0;
00843   int      iTimestep, iActive;
00844   float    fValues[100*2]; // nValues*nComponents
00845   xmbool    bActivity[75]; // activity
00846 //  double   dMin = 0.5, dMax = 3.5;
00847 //  int      nSeedMultiplier = 138592;
00848   int      i, j, status;
00849 
00850   // 5th item in data set is always inactive, others active
00851   for (iActive = 0; iActive < nActive; iActive++) {
00852     if (iActive % 3 == 0) {
00853       bActivity[iActive] = XFALSE;
00854     }
00855     else {
00856       bActivity[iActive] = XTRUE;
00857     }
00858   }
00859 
00860   if (a_Overwrite) {
00861       //open the already-existing file
00862     status = xfOpenFile(a_Filename, &xFileId, XFALSE);
00863     if (status < 0) {
00864       return -1;
00865     }
00866       // open the group where we have all the datasets
00867     status = xfOpenGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00868     if (status < 0) {
00869       xfCloseFile(xFileId);
00870       return -1;
00871     }
00872   }
00873   else {
00874       // create the file
00875     status = xfCreateFile(a_Filename, &xFileId, XTRUE);
00876     if (status < 0) {
00877       return FALSE;
00878     }
00879       // create the group to store all datasets 
00880     status = xfCreateGenericGroup(xFileId, DATASETS_LOCATION, &xDsetsId);
00881     if (status < 0) {
00882       xfCloseFile(xFileId);
00883       return FALSE;
00884     }
00885   }
00886 
00887   // Create the Vector B dataset group
00888   status = xfCreateVectorDataset(xDsetsId, VECTOR2D_B_LOCATION, "ft/s",
00889                TS_SECONDS, a_Compression, &xVectorB);
00890   if (status < 0) {
00891     xfCloseGroup(xDsetsId);
00892     xfCloseFile(xFileId);
00893     return FALSE;
00894   }
00895 
00896   if (!a_Overwrite) {
00897     // Loop through timesteps adding them to the file
00898     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00899       // We will have an 0.5 hour timestep
00900       dTime = (iTimestep + 1) * 0.5;
00901 
00902       for (i = 0; i < nValues; i++) {
00903         for (j = 0; j < nComponents; j++) {
00904           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00905         }
00906       }
00907 
00908       // write the dataset array values
00909       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
00910                                      fValues);
00911       if (status >= 0) {
00912         // write activity array
00913         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
00914       }
00915       if (status < 0) {
00916         xfCloseGroup(xVectorB);
00917         xfCloseGroup(xDsetsId);
00918         xfCloseFile(xFileId);
00919       }
00920     }
00921   }
00922   else {
00923     // Loop through timesteps adding them to the file
00924     for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
00925       // We will have an 1.5 hour timestep
00926       dTime = (iTimestep + 1) * 1.5;
00927 
00928       for (i = 0; i < nValues; i++) {
00929         for (j = 0; j < nComponents; j++) {
00930           fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
00931         }
00932       }
00933 
00934       // write the dataset array values
00935       status = xfWriteVectorTimestep(xVectorB, dTime, nValues, nComponents,
00936                                      fValues);
00937       if (status >= 0) {
00938         // write activity array
00939         xfWriteActivityTimestep(xVectorB, nActive, bActivity);
00940       }
00941       if (status < 0) {
00942         xfCloseGroup(xVectorB);
00943         xfCloseGroup(xDsetsId);
00944         xfCloseFile(xFileId);
00945       }
00946     }
00947   }
00948 
00949   // Write Coordinate file - for ScalarB, we will set the coordinate system
00950   //   to be UTM, with UTM Zone settings written to the file.
00951   status = xfCreateCoordinateGroup(xFileId, &xCoordId);
00952   if (status <= 0) {
00953     xfCloseGroup(xVectorB);
00954     xfCloseGroup(xDsetsId);
00955     xfCloseFile(xFileId);
00956         return -1;
00957   }
00958 
00959     // write the coordinate data to the file
00960   xfSetHorizDatum(xCoordId, HORIZ_DATUM_UTM);
00961   xfSetHorizUnits(xCoordId, COORD_UNITS_METERS);
00962   xfSetVertDatum(xCoordId, VERT_DATUM_LOCAL);
00963   xfSetVertUnits(xCoordId, COORD_UNITS_METERS);
00964 
00965     // write additional information - we'll use the max UTM zone for the test
00966   xfSetUTMZone(xCoordId, UTM_ZONE_MAX);
00967 
00968   xfCloseGroup(xCoordId);
00969   xCoordId = 0;
00970 
00971   // close the dataset
00972   xfCloseGroup(xVectorB);
00973   xfCloseGroup(xDsetsId);
00974   xfCloseFile(xFileId);
00975 
00976   return 1;
00977 } // tdWriteVector2D_B
00978 // --------------------------------------------------------------------------
00979 // FUNCTION tdWriteVector2DAToMulti
00980 // PURPOSE  Write 2D vector dataset to an HDF5 File
00981 // NOTES    This tests dynamic data sets, and activity
00982 //          Add reftime when it is completed
00983 //          This dataset is dynamic water velocities with output times
00984 //          in minutes.
00985 //          Dataset is for a mesh and so nActive is the number of elements
00986 //          which is not the same as the nValues which would be number of nodes
00987 // --------------------------------------------------------------------------
00988 int tdWriteVector2DAToMulti (xid a_GroupId)
00989 {
00990   xid      xVectorA;
00991   int      nTimes = 6, nValues = 100, nComponents = 2, nActive = 75;
00992   double   dTime = 0.0;
00993   int      iTimestep, iActive;
00994   float    fValues[100*2]; // nValues*nComponents
00995   xmbool    bActivity[75]; // activity
00996 //  double   dMin = 0.5, dMax = 3.5;
00997 //  int      nSeedMultiplier = 138592;
00998   int      i, j, status;
00999 
01000   // 5th item in data set is always inactive, others active
01001   for (iActive = 0; iActive < nActive; iActive++) {
01002     if (iActive % 3 == 0) {
01003       bActivity[iActive] = XFALSE;
01004     }
01005     else {
01006       bActivity[iActive] = XTRUE;
01007     }
01008   }
01009 
01010   // Create the scalar A dataset group
01011   status = xfCreateVectorDataset(a_GroupId, VECTOR2D_A_LOCATION, "ft/s",
01012                TS_SECONDS, NONE, &xVectorA);
01013   if (status < 0) {
01014     return FALSE;
01015   }
01016 
01017   // Loop through timesteps adding them to the file
01018   for (iTimestep = 0; iTimestep < nTimes; iTimestep++) {
01019     // We will have an 0.5 hour timestep
01020     dTime = (iTimestep + 1) * 0.5;
01021 
01022     for (i = 0; i < nValues; i++) {
01023       for (j = 0; j < nComponents; j++) {
01024         fValues[i*nComponents + j] = (float)(((i)*nComponents + (j+1))*dTime);
01025       }
01026     }
01027 //    // generate values array using random numbers between dMin and dMax
01028 //    tdiDatasetArray(dMin, dMax, iTimestep + 1, nSeedMultiplier,
01029 //                    nValues*nComponents, fValues);
01030 
01031     // write the dataset array values
01032     status = xfWriteVectorTimestep(xVectorA, dTime, nValues, nComponents,
01033                                    fValues);
01034     if (status >= 0) {
01035       // write activity array
01036       xfWriteActivityTimestep(xVectorA, nActive, bActivity);
01037     }
01038     if (status < 0) {
01039       xfCloseGroup(xVectorA);
01040     }
01041   }
01042 
01043   // close the dataset
01044   xfCloseGroup(xVectorA);
01045 
01046   return FALSE;
01047 } // tdWriteVector2DAToMulti
01048 // --------------------------------------------------------------------------
01049 // FUNCTION tdiRandomNumberInRange
01050 // PURPOSE  generate Psuedo Random numbers.  We use the same seeds every
01051 //          time so we end up with consistent values for testing purposes.
01052 // --------------------------------------------------------------------------
01053 double tdiRandomNumberInRange (double a_dMin, double a_dMax, int a_nSeed)
01054 {
01055   int nRandom;
01056   double dValue;
01057 
01058   srand(a_nSeed);
01059   nRandom = rand();
01060 
01061   dValue = a_dMin + ((double)(nRandom)*(a_dMax - a_dMin))/RAND_MAX;
01062 
01063   return dValue;
01064 } // tdiRandomNumberInRange
01065 // --------------------------------------------------------------------------
01066 // FUNCTION tdDatasetArray
01067 // PURPOSE  Get dataset data to use in a dataset
01068 // NOTES    Generates random numbers between a range to fill in the array
01069 // --------------------------------------------------------------------------
01070 void tdiDatasetArray (double a_dMin, double a_dMax, int a_nCycle, 
01071                      int a_SeedMultiplier, int a_nValues, float *a_Array)
01072 {
01073   int       i, nSeedBase;
01074 
01075   for (i = 0; i < a_nValues; i++) {
01076     nSeedBase = a_nCycle*a_nValues + i;
01077     a_Array[i] = (float)tdiRandomNumberInRange(a_dMin, a_dMax, 
01078                                               nSeedBase*a_SeedMultiplier);
01079   }
01080 } // tdDatasetArray
01081 // --------------------------------------------------------------------------
01082 // FUNCTION tdiReadScalar
01083 // PURPOSE  Read a scalar from an XMDF file and output information to
01084 //          to a text file
01085 // NOTES    
01086 // --------------------------------------------------------------------------
01087 int tdiReadScalar (xid a_xScalarId, FILE *a_fp)
01088 {
01089   int    nTimes = NONE, nValues = NONE, nActive = NONE;
01090   int    nStatus = TRUE, iTime, iVal, iActive;
01091   char   TimeUnits[100], Units[100];
01092   double *Times = NULL;
01093   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01094   xmbool  *Active = NULL;
01095   xmbool  bUseReftime;
01096   double Reftime;
01097 
01098   // read the time units
01099   nStatus = xfGetDatasetTimeUnits(a_xScalarId, TimeUnits);
01100   if (nStatus < 0) {
01101     return nStatus;
01102   }
01103   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01104 
01105   // see if we are using a reftime
01106   nStatus = xfUseDatasetReftime(a_xScalarId, &bUseReftime);
01107   if (nStatus < 0) {
01108     return nStatus;
01109   }
01110   if (bUseReftime) {
01111     nStatus = xfReadDatasetReftime(a_xScalarId, &Reftime);
01112     if (nStatus < 0) {
01113       return nStatus;
01114     }
01115     fprintf(a_fp, "Reftime: %f\n", Reftime);
01116   }
01117 
01118   // read the units
01119   nStatus = xfGetDatasetUnits(a_xScalarId, Units);
01120   if (nStatus < 0) { 
01121     return nStatus;
01122   }
01123   fprintf(a_fp, "units: %s\n", Units);
01124 
01125   // read in the number of values and number of active values
01126   nStatus = xfGetDatasetNumVals(a_xScalarId, &nValues);
01127   if (nStatus >= 0) {
01128     nStatus = xfGetDatasetNumActive(a_xScalarId, &nActive);
01129   }
01130   if (nStatus < 0) {
01131     return nStatus;
01132   }
01133 
01134   if (nValues <= 0) {
01135     printf("No data to read in.");
01136     return -1;
01137   }
01138 
01139   // read in the number of times
01140   nStatus = xfGetDatasetNumTimes(a_xScalarId, &nTimes);
01141   if (nStatus < 0) {
01142     return nStatus;
01143   }
01144 
01145   // Read in the individual time values
01146   Times = (double *)malloc(nTimes*sizeof(double));
01147   if (Times == NULL) {
01148     printf("Out of memory");
01149     return -1;
01150   }
01151   nStatus = xfGetDatasetTimes(a_xScalarId, nTimes, Times);
01152   if (nStatus < 0) {
01153     return nStatus;
01154   }
01155 
01156   // Read in the minimum and maximum values
01157   Mins = (float *)malloc(nTimes*sizeof(float));
01158   Maxs = (float *)malloc(nTimes*sizeof(float));
01159   if (Mins == NULL || Maxs == NULL) {
01160     free(Times);
01161     printf("Out of memory");
01162     return -1;
01163   }
01164 
01165   nStatus = xfGetDatasetMins(a_xScalarId, nTimes, Mins);
01166   if (nStatus >= 0) {
01167     nStatus = xfGetDatasetMaxs(a_xScalarId, nTimes, Maxs);
01168   }
01169   if (nStatus < 0) {
01170     free(Times);
01171     free(Mins);
01172     free(Maxs);
01173     return nStatus;
01174   }
01175 
01176   Values = (float *)malloc(nValues*sizeof(float));
01177   if (nActive > 0) {
01178     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01179   }
01180 
01181   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01182   fprintf(a_fp, "Number Values: %d\n", nValues);
01183   fprintf(a_fp, "Number Active: %d\n", nActive);
01184 
01185   // loop through the timesteps, read the values and active values and write
01186   // them to the text file
01187   for (iTime = 0; iTime < nTimes; iTime++) {
01188       // indices should be 1 based
01189     nStatus = xfReadScalarValuesTimestep(a_xScalarId, iTime + 1,
01190                                          nValues, Values);
01191     if (nStatus >= 0 && nActive > 0) {
01192         // indices should be 1 based
01193       nStatus = xfReadActivityTimestep(a_xScalarId, iTime + 1, nActive, Active);
01194     }
01195 
01196     // Write the time, min, max, values and active values to the text output
01197     // file.
01198     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01199                   Times[iTime], Mins[iTime], Maxs[iTime]);
01200 
01201     fprintf(a_fp, "Values:\n");
01202     // print 5 values per line
01203     for (iVal = 0; iVal < nValues; iVal++) {
01204       fprintf(a_fp, "%6.3f ", Values[iVal]);
01205       if ((iVal + 1) % 5 == 0) {
01206         fprintf(a_fp, "\n");
01207       }
01208     }
01209     fprintf(a_fp, "\n");
01210 
01211     fprintf(a_fp, "Activity:\n");
01212     // print 5 values per line
01213     for (iActive = 0; iActive < nActive; iActive++) {
01214       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01215       if ((iActive + 1) % 5 == 0) {
01216         fprintf(a_fp, "\n");
01217       }
01218     }
01219     fprintf(a_fp, "\n\n");
01220   }
01221 
01222   if (Times) {
01223     free(Times);
01224     Times = NULL;
01225   }
01226   
01227   if (Mins) {
01228     free(Mins);
01229     Mins = NULL;
01230   }
01231 
01232   if (Maxs) {
01233     free(Maxs);
01234     Maxs = NULL;
01235   }
01236 
01237   if (Values) {
01238     free(Values);
01239     Values = NULL;
01240   }
01241 
01242   if (Active) {
01243     free(Active);
01244     Active = NULL;
01245   }
01246 
01247   return TRUE;
01248 } // tdiReadScalar
01249 // --------------------------------------------------------------------------
01250 // FUNCTION tdiReadVector
01251 // PURPOSE  Read a vector from an XMDF file and output information to
01252 //          to a text file
01253 // NOTES    
01254 // --------------------------------------------------------------------------
01255 int tdiReadVector (xid a_xVectorId, FILE *a_fp)
01256 {
01257   int    nTimes = NONE, nValues = NONE, nComponents = NONE, nActive = NONE;
01258   int    nStatus = TRUE, iTime, iVal, iActive;
01259   char   TimeUnits[100];
01260   double *Times = NULL;
01261   float  *Values = NULL, *Mins = NULL, *Maxs = NULL;
01262   xmbool  *Active = NULL;
01263   xmbool  bUseReftime;
01264   double Reftime;
01265 
01266   // read the time units
01267   nStatus = xfGetDatasetTimeUnits(a_xVectorId, TimeUnits);
01268   if (nStatus < 0) {
01269     return nStatus;
01270   }
01271   fprintf(a_fp, "Time units: %s\n", TimeUnits);
01272 
01273   // see if we are using a reftime
01274   nStatus = xfUseDatasetReftime(a_xVectorId, &bUseReftime);
01275   if (nStatus < 0) {
01276     return nStatus;
01277   }
01278   if (bUseReftime) {
01279     nStatus = xfReadDatasetReftime(a_xVectorId, &Reftime);
01280     if (nStatus < 0) {
01281       return nStatus;
01282     }
01283     fprintf(a_fp, "Reftime: %f", Reftime);
01284   }
01285 
01286   // read in the number of values and number of active values
01287   nStatus = xfGetDatasetNumVals(a_xVectorId, &nValues);
01288   if (nStatus >= 0) {
01289     nStatus = xfGetDatasetVecNumComponents(a_xVectorId, &nComponents);
01290     if (nStatus >= 0) {
01291       nStatus = xfGetDatasetNumActive(a_xVectorId, &nActive);
01292     }
01293   }
01294   if (nStatus < 0) {
01295     return nStatus;
01296   }
01297 
01298   if (nValues <= 0) {
01299     printf("No data to read in.");
01300     return -1;
01301   }
01302 
01303   // read in the number of times
01304   nStatus = xfGetDatasetNumTimes(a_xVectorId, &nTimes);
01305   if (nStatus < 0) {
01306     return nStatus;
01307   }
01308 
01309   // Read in the individual time values
01310   Times = (double *)malloc(nTimes*sizeof(double));
01311   if (Times == NULL) {
01312     printf("Out of memory");
01313     return -1;
01314   }
01315   nStatus = xfGetDatasetTimes(a_xVectorId, nTimes, Times);
01316   if (nStatus < 0) {
01317     return nStatus;
01318   }
01319 
01320   // Read in the minimum and maximum values
01321   Mins = (float *)malloc(nTimes*sizeof(float));
01322   Maxs = (float *)malloc(nTimes*sizeof(float));
01323   if (Mins == NULL || Maxs == NULL) {
01324     free(Times);
01325     printf("Out of memory");
01326     return -1;
01327   }
01328 
01329   nStatus = xfGetDatasetMins(a_xVectorId, nTimes, Mins);
01330   if (nStatus >= 0) {
01331     nStatus = xfGetDatasetMaxs(a_xVectorId, nTimes, Maxs);
01332   }
01333   if (nStatus < 0) {
01334     free(Times);
01335     free(Mins);
01336     free(Maxs);
01337     return nStatus;
01338   }
01339 
01340   Values = (float *)malloc(nValues*nComponents*sizeof(float));
01341   if (nActive > 0) {
01342     Active = (xmbool *)malloc(nActive*sizeof(xmbool));
01343   }
01344 
01345   fprintf(a_fp, "Number Timesteps: %d\n", nTimes);
01346   fprintf(a_fp, "Number Values: %d\n", nValues);
01347   fprintf(a_fp, "Number Components: %d\n", nComponents);
01348   fprintf(a_fp, "Number Active: %d\n", nActive);
01349 
01350   // loop through the timesteps, read the values and active values and write
01351   // them to the text file
01352   for (iTime = 0; iTime < nTimes; iTime++) {
01353     nStatus = xfReadVectorValuesTimestep(a_xVectorId, iTime + 1,
01354                                          nValues, nComponents, Values);
01355     if (nStatus >= 0 && nActive > 0) {
01356       nStatus = xfReadActivityTimestep(a_xVectorId, iTime + 1, nActive, Active);
01357     }
01358 
01359     // Write the time, min, max, values and active values to the text output
01360     // file.
01361     fprintf(a_fp, "\nTimestep at  %6.3lf\nMin: %6.3lf\nMax: %6.3lf\n", 
01362                   Times[iTime], Mins[iTime], Maxs[iTime]);
01363 
01364     fprintf(a_fp, "Values:\n");
01365     // print a set of vector values per line
01366     for (iVal = 0; iVal < nValues; iVal++) {
01367       fprintf(a_fp, "%6.3f %6.3f\n", Values[iVal*nComponents], 
01368                                      Values[(iVal*nComponents) + 1]);
01369     }
01370     fprintf(a_fp, "\n");
01371 
01372     fprintf(a_fp, "Activity:\n");
01373     // print 5 values per line
01374     for (iActive = 0; iActive < nActive; iActive++) {
01375       fprintf(a_fp, "%4d ", (int)Active[iActive]);
01376       if ((iActive + 1) % 5 == 0) {
01377         fprintf(a_fp, "\n");
01378       }
01379     }
01380     fprintf(a_fp, "\n\n");
01381   }
01382 
01383   if (Times) {
01384     free(Times);
01385     Times = NULL;
01386   }
01387   
01388   if (Mins) {
01389     free(Mins);
01390     Mins = NULL;
01391   }
01392 
01393   if (Maxs) {
01394     free(Maxs);
01395     Maxs = NULL;
01396   }
01397 
01398   if (Values) {
01399     free(Values);
01400     Values = NULL;
01401   }
01402 
01403   if (Active) {
01404     free(Active);
01405     Active = NULL;
01406   }
01407 
01408   return TRUE;
01409 } // tdiReadVector
TestDatasets.cpp tests datasets
00001 #include "stdafx.h"
00002 #include <Xmdf.h>
00003 #include <stdio.h>
00004 #include <windows.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007 #include "TestGeomPaths.h"
00008 
00009 /* tmReadTestPaths */
00010 int tmReadTestPaths(LPCSTR Filename, LPCSTR OutFilename)
00011 {
00012   int         nGroups, nMaxPathLength, nDims, nPaths, nTimes, i, j;
00013   int         PathIndices[2];
00014   char       *Paths = NULL, *IndividualPath = NULL;
00015   double     *times, *locs, NullVal = 0;
00016   xid         xFileId = NONE, xGroupId = NONE;
00017   int         nStatus;
00018   FILE       *fp = NULL;
00019 
00020   // open the XMDF file 
00021   nStatus = xfOpenFile(Filename, &xFileId, TRUE);
00022   if (nStatus < 0) {
00023     printf("Unable to open XMDF file tmReadTestPaths.");
00024     return nStatus;
00025   }
00026 
00027   // open the Output file 
00028   fp = fopen(OutFilename, "w");
00029   if (fp == NULL) {
00030     printf("Unable to open output file tmReadTestPaths.");
00031     return nStatus;
00032   }
00033 
00034   // find the geomotric path groups
00035   // Get the number and paths of datasets in the file.
00036   nStatus = xfGetGroupPathsSizeForGeomPaths(xFileId, &nGroups,
00037                                                     &nMaxPathLength);
00038   if (nStatus >= 0) {
00039     Paths = (char *)malloc(nMaxPathLength*nGroups*sizeof(char));
00040     nStatus =