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