00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "Hdf5DataReader.hpp"
00029 #include "Exception.hpp"
00030 #include "OutputFileHandler.hpp"
00031
00032 #include <cassert>
00033
00034
00035 Hdf5DataReader::Hdf5DataReader(const std::string& rDirectory,
00036 const std::string& rBaseName,
00037 bool makeAbsolute)
00038 : mBaseName(rBaseName),
00039 mIsUnlimitedDimensionSet(false),
00040 mNumberTimesteps(1),
00041 mIsDataComplete(true)
00042 {
00043 RelativeTo::Value relative_to;
00044 if (makeAbsolute)
00045 {
00046 relative_to = RelativeTo::ChasteTestOutput;
00047 }
00048 else
00049 {
00050 relative_to = RelativeTo::Absolute;
00051 }
00052 FileFinder directory(rDirectory, relative_to);
00053 CommonConstructor(directory, rBaseName);
00054 }
00055
00056 Hdf5DataReader::Hdf5DataReader(const FileFinder& rDirectory,
00057 const std::string& rBaseName)
00058 : mBaseName(rBaseName),
00059 mIsUnlimitedDimensionSet(false),
00060 mNumberTimesteps(1),
00061 mIsDataComplete(true)
00062 {
00063 CommonConstructor(rDirectory, rBaseName);
00064 }
00065
00066 void Hdf5DataReader::CommonConstructor(const FileFinder& rDirectory, const std::string& rBaseName)
00067 {
00068 std::string results_dir = rDirectory.GetAbsolutePath();
00069 if (!rDirectory.IsDir() || !rDirectory.Exists())
00070 {
00071 EXCEPTION("Directory does not exist: " + results_dir);
00072 }
00073 mDirectory = results_dir;
00074 assert(*(mDirectory.end()-1) == '/');
00075
00076 std::string file_name = results_dir + mBaseName + ".h5";
00077
00078
00079 mFileId = H5Fopen(file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
00080
00081 if (mFileId <= 0)
00082 {
00083 EXCEPTION("Hdf5DataReader could not open " + file_name);
00084 }
00085 mVariablesDatasetId = H5Dopen(mFileId, "Data");
00086
00087 hid_t variables_dataspace = H5Dget_space(mVariablesDatasetId);
00088 mVariablesDatasetRank = H5Sget_simple_extent_ndims(variables_dataspace);
00089
00090
00091 hsize_t dataset_max_sizes[MAX_DATASET_RANK];
00092 H5Sget_simple_extent_dims(variables_dataspace, mVariablesDatasetSizes, dataset_max_sizes);
00093
00094 for (unsigned i=1; i<MAX_DATASET_RANK; i++)
00095 {
00096 assert(mVariablesDatasetSizes[i] == dataset_max_sizes[i]);
00097 }
00098
00099
00100 if (dataset_max_sizes[0] == H5S_UNLIMITED)
00101 {
00102 mIsUnlimitedDimensionSet = true;
00103 mTimeDatasetId = H5Dopen(mFileId, "Time");
00104
00105 hid_t timestep_dataspace = H5Dget_space(mTimeDatasetId);
00106
00107
00108 H5Sget_simple_extent_dims(timestep_dataspace, &mNumberTimesteps, NULL);
00109
00110 }
00111
00112
00113 hid_t attribute_id = H5Aopen_name(mVariablesDatasetId, "Variable Details");
00114
00115
00116 hid_t attribute_type = H5Aget_type(attribute_id);
00117 hid_t attribute_space = H5Aget_space(attribute_id);
00118
00119 hsize_t attr_dataspace_dim;
00120 H5Sget_simple_extent_dims(attribute_space, &attr_dataspace_dim, NULL);
00121
00122 unsigned num_columns = H5Sget_simple_extent_npoints(attribute_space);
00123 char* string_array = (char *)malloc(sizeof(char)*MAX_STRING_SIZE*(int)num_columns);
00124 H5Aread(attribute_id, attribute_type, string_array);
00125
00126
00127 for (unsigned index=0; index < num_columns; index++)
00128 {
00129
00130 std::string column_name_unit(&string_array[MAX_STRING_SIZE*index]);
00131
00132
00133 size_t name_length = column_name_unit.find('(');
00134 size_t unit_length = column_name_unit.find(')') - name_length - 1;
00135
00136 std::string column_name = column_name_unit.substr(0, name_length);
00137 std::string column_unit = column_name_unit.substr(name_length+1, unit_length);
00138
00139 mVariableNames.push_back(column_name);
00140 mVariableToColumnIndex[column_name] = index;
00141 mVariableToUnit[column_name] = column_unit;
00142 }
00143
00144
00145 H5Tclose(attribute_type);
00146 H5Sclose(attribute_space);
00147 H5Aclose(attribute_id);
00148
00149
00150 free(string_array);
00151
00152
00153 attribute_id = H5Aopen_name(mVariablesDatasetId, "IsDataComplete");
00154 if (attribute_id < 0)
00155 {
00156
00157
00158 return;
00159 }
00160
00161 attribute_type = H5Aget_type(attribute_id);
00162 attribute_space = H5Aget_space(attribute_id);
00163 unsigned is_data_complete;
00164 H5Aread(attribute_id, H5T_NATIVE_UINT, &is_data_complete);
00165
00166
00167 H5Tclose(attribute_type);
00168 H5Sclose(attribute_space);
00169 H5Aclose(attribute_id);
00170 mIsDataComplete = (is_data_complete == 1) ? true : false;
00171
00172 if (is_data_complete)
00173 {
00174 return;
00175 }
00176
00177
00178
00179 attribute_id = H5Aopen_name(mVariablesDatasetId, "NodeMap");
00180 attribute_type = H5Aget_type(attribute_id);
00181 attribute_space = H5Aget_space(attribute_id);
00182
00183
00184 unsigned num_node_indices = H5Sget_simple_extent_npoints(attribute_space);
00185
00186
00187 mIncompleteNodeIndices.clear();
00188 mIncompleteNodeIndices.resize(num_node_indices);
00189 H5Aread(attribute_id, H5T_NATIVE_UINT, &mIncompleteNodeIndices[0]);
00190
00191 H5Tclose(attribute_type);
00192 H5Sclose(attribute_space);
00193 H5Aclose(attribute_id);
00194 }
00195
00196 std::vector<double> Hdf5DataReader::GetVariableOverTime(const std::string& rVariableName,
00197 unsigned nodeIndex)
00198 {
00199 if (!mIsUnlimitedDimensionSet)
00200 {
00201 EXCEPTION("The file does not contain time dependent data");
00202 }
00203
00204 unsigned actual_node_index = nodeIndex;
00205 if (!mIsDataComplete)
00206 {
00207 unsigned node_index = 0;
00208 for (node_index=0; node_index<mIncompleteNodeIndices.size(); node_index++)
00209 {
00210 if (mIncompleteNodeIndices[node_index]==nodeIndex)
00211 {
00212 actual_node_index = node_index;
00213 break;
00214 }
00215 }
00216 if ( node_index == mIncompleteNodeIndices.size())
00217 {
00218 std::stringstream ss;
00219 ss << "The incomplete file does not contain info of node " << nodeIndex ;
00220 EXCEPTION(ss.str());
00221 }
00222 }
00223 if (actual_node_index >= mVariablesDatasetSizes[1])
00224 {
00225 std::stringstream ss;
00226 ss << "The file doesn't contain info of node " << actual_node_index ;
00227 EXCEPTION(ss.str());
00228 }
00229
00230 std::map<std::string, unsigned>::iterator col_iter = mVariableToColumnIndex.find(rVariableName);
00231 if (col_iter == mVariableToColumnIndex.end())
00232 {
00233 EXCEPTION("The file doesn't contain data for variable " + rVariableName);
00234 }
00235 int column_index = (*col_iter).second;
00236
00237
00238 hsize_t offset[3] = {0, actual_node_index, column_index};
00239 hsize_t count[3] = {mVariablesDatasetSizes[0], 1, 1};
00240 hid_t variables_dataspace = H5Dget_space(mVariablesDatasetId);
00241 H5Sselect_hyperslab(variables_dataspace, H5S_SELECT_SET, offset, NULL, count, NULL);
00242
00243
00244 hid_t memspace = H5Screate_simple(1, &mVariablesDatasetSizes[0] ,NULL);
00245
00246
00247 std::vector<double> ret(mVariablesDatasetSizes[0]);
00248
00249
00250 H5Dread(mVariablesDatasetId, H5T_NATIVE_DOUBLE, memspace, variables_dataspace, H5P_DEFAULT, &ret[0]);
00251
00252 H5Sclose(variables_dataspace);
00253 H5Sclose(memspace);
00254
00255 return ret;
00256 }
00257
00258 void Hdf5DataReader::GetVariableOverNodes(Vec data,
00259 const std::string& rVariableName,
00260 unsigned timestep)
00261 {
00262 if (!mIsDataComplete)
00263 {
00264 EXCEPTION("You can only get a vector for complete data");
00265 }
00266 if (!mIsUnlimitedDimensionSet && timestep!=0)
00267 {
00268 EXCEPTION("The file does not contain time dependent data");
00269 }
00270
00271 std::map<std::string, unsigned>::iterator col_iter = mVariableToColumnIndex.find(rVariableName);
00272 if (col_iter == mVariableToColumnIndex.end())
00273 {
00274 EXCEPTION("The file does not contain data for variable " + rVariableName);
00275 }
00276 int column_index = (*col_iter).second;
00277
00278
00279 if (timestep >= mNumberTimesteps)
00280 {
00281 std::stringstream ss;
00282 ss << "The file does not contain data for timestep number " << timestep;
00283 EXCEPTION(ss.str());
00284 }
00285
00287 int lo, hi, size;
00288 VecGetSize(data, &size);
00289 if ((unsigned)size != mVariablesDatasetSizes[1])
00290 {
00291 EXCEPTION("Could not read data because Vec is the wrong size");
00292 }
00293
00294 VecGetOwnershipRange(data, &lo, &hi);
00295
00296 if (hi > lo)
00297 {
00298
00299 hsize_t v_size[1] = {hi-lo};
00300 hid_t memspace = H5Screate_simple(1, v_size, NULL);
00301
00302
00303 hsize_t offset[3] = {timestep, lo, column_index};
00304 hsize_t count[3] = {1, hi-lo, 1};
00305 hid_t hyperslab_space = H5Dget_space(mVariablesDatasetId);
00306 H5Sselect_hyperslab(hyperslab_space, H5S_SELECT_SET, offset, NULL, count, NULL);
00307
00308 double* p_petsc_vector;
00309 VecGetArray(data, &p_petsc_vector);
00310 herr_t err;
00311 err=H5Dread(mVariablesDatasetId, H5T_NATIVE_DOUBLE, memspace, hyperslab_space, H5P_DEFAULT, p_petsc_vector);
00312 assert(err==0);
00313 VecRestoreArray(data, &p_petsc_vector);
00314
00315 H5Sclose(hyperslab_space);
00316 H5Sclose(memspace);
00317 }
00318 }
00319
00320 std::vector<double> Hdf5DataReader::GetUnlimitedDimensionValues()
00321 {
00322
00323 std::vector<double> ret(mNumberTimesteps);
00324
00325 if (!mIsUnlimitedDimensionSet)
00326 {
00327
00328 assert(mNumberTimesteps==1);
00329 ret[0] = 0.0;
00330 return ret;
00331 }
00332
00333 hid_t time_dataspace = H5Dget_space(mTimeDatasetId);
00334
00335
00336 hid_t memspace = H5Screate_simple(1, &mNumberTimesteps ,NULL);
00337
00338
00339 H5Dread(mTimeDatasetId, H5T_NATIVE_DOUBLE, memspace, time_dataspace, H5P_DEFAULT, &ret[0]);
00340
00341 H5Sclose(time_dataspace);
00342 H5Sclose(memspace);
00343
00344 return ret;
00345 }
00346
00347 void Hdf5DataReader::Close()
00348 {
00350 H5Dclose(mVariablesDatasetId);
00351
00352 if (mIsUnlimitedDimensionSet)
00353 {
00354 H5Dclose(mTimeDatasetId);
00355 }
00356
00357 H5Fclose(mFileId);
00358 }
00359
00360 Hdf5DataReader::~Hdf5DataReader()
00361 {
00362 Close();
00363 }
00364
00365 unsigned Hdf5DataReader::GetNumberOfRows()
00366 {
00367 return mVariablesDatasetSizes[1];
00368 }
00369
00370 std::vector<std::string> Hdf5DataReader::GetVariableNames()
00371 {
00372 return mVariableNames;
00373 }
00374
00375 std::string Hdf5DataReader::GetUnit(const std::string& rVariableName)
00376 {
00377 return mVariableToUnit[rVariableName];
00378 }
00379
00380 bool Hdf5DataReader::IsDataComplete()
00381 {
00382 return mIsDataComplete;
00383 }
00384
00385 std::vector<unsigned> Hdf5DataReader::GetIncompleteNodeMap()
00386 {
00387 return mIncompleteNodeIndices;
00388 }