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
00035 #include "ColumnDataReader.hpp"
00036 #include "ColumnDataConstants.hpp"
00037
00038 #include <fstream>
00039 #include <sstream>
00040 #include <iomanip>
00041 #include <cassert>
00042 #include <climits>
00043
00044 #include "OutputFileHandler.hpp"
00045 #include "Exception.hpp"
00046
00051 const int NOT_READ = -999;
00052
00053 ColumnDataReader::ColumnDataReader(const std::string& rDirectory,
00054 const std::string& rBaseName,
00055 bool makeAbsolute)
00056 {
00057
00058 std::string directory;
00059 if (makeAbsolute)
00060 {
00061 OutputFileHandler output_file_handler(rDirectory, false);
00062 directory = output_file_handler.GetOutputDirectoryFullPath();
00063 }
00064 else
00065 {
00066
00067 if ( !(*(rDirectory.end()-1) == '/'))
00068 {
00069 directory = rDirectory + "/";
00070 }
00071 }
00072
00073
00074 mInfoFilename = directory + rBaseName + ".info";
00075 std::ifstream infofile(mInfoFilename.c_str(), std::ios::in);
00076
00077
00078 if (!infofile.is_open())
00079 {
00080 EXCEPTION("Couldn't open info file: " + mInfoFilename);
00081 }
00082 std::string junk;
00083 mNumFixedDimensions = NOT_READ;
00084 mHasUnlimitedDimension = false;
00085 mNumVariables = NOT_READ;
00086
00087 infofile >> junk;
00088 infofile >> mNumFixedDimensions >> junk;
00089 infofile >> mHasUnlimitedDimension >> junk;
00090 infofile >> mNumVariables;
00091
00092 if (mNumFixedDimensions == NOT_READ || mNumVariables == NOT_READ)
00093 {
00094 infofile.close();
00095 EXCEPTION("Couldn't read info file correctly");
00096 }
00097
00098
00099 if (mHasUnlimitedDimension)
00100 {
00101 if (mNumFixedDimensions < 1)
00102 {
00103 mDataFilename = directory + rBaseName + ".dat";
00104 }
00105 else
00106 {
00107 std::stringstream suffix;
00108 suffix << std::setfill('0') << std::setw(FILE_SUFFIX_WIDTH) << 0;
00109
00110 mDataFilename = directory + rBaseName + "_" + suffix.str() + ".dat";
00111
00112
00113
00114 mAncillaryFilename = directory + rBaseName + "_unlimited.dat";
00115
00116
00117 std::ifstream ancillaryfile(mAncillaryFilename.c_str(), std::ios::in);
00118
00119
00120 if (!ancillaryfile.is_open())
00121 {
00122 EXCEPTION("Couldn't open ancillary data file");
00123 }
00124 std::string dimension;
00125 std::getline(ancillaryfile, dimension);
00126 std::stringstream dimension_stream(dimension);
00127 std::string dimension_unit, dimension_name, header;
00128 dimension_stream >> header;
00129
00130
00131 int unitpos = header.find("(") + 1;
00132
00133 dimension_name = header.substr(0, unitpos - 1);
00134 dimension_unit = header.substr(unitpos, header.length() - unitpos - 1);
00135
00136 mVariablesToUnits[dimension_name] = dimension_unit;
00137 ancillaryfile.close();
00138 }
00139 }
00140 else
00141 {
00142 mDataFilename = directory + rBaseName + ".dat";
00143 }
00144
00145 std::ifstream datafile(mDataFilename.c_str(), std::ios::in);
00146
00147 if (!datafile.is_open())
00148 {
00149 EXCEPTION("Couldn't open data file");
00150 }
00151
00152 std::string variables;
00153 std::getline(datafile, variables);
00154 std::stringstream variable_stream(variables);
00155 std::string header, variable, unit;
00156 int column = 0;
00157
00158
00159 while (variable_stream >> header)
00160 {
00161
00162 int unitpos = header.find("(") + 1;
00163
00164 variable = header.substr(0, unitpos - 1);
00165 unit = header.substr(unitpos, header.length() - unitpos - 1);
00166
00167 mVariablesToColumns[variable] = column;
00168 mVariablesToUnits[variable] = unit;
00169
00170 column++;
00171 }
00172 infofile.close();
00173 datafile.close();
00174 }
00175
00176 std::vector<double> ColumnDataReader::GetValues(const std::string& rVariableName)
00177 {
00178 if (mNumFixedDimensions > 0)
00179 {
00180 EXCEPTION("Data file has fixed dimension which must be specified");
00181 }
00182
00183 std::map<std::string, int>::iterator col = mVariablesToColumns.find(rVariableName);
00184 if (col == mVariablesToColumns.end())
00185 {
00186 EXCEPTION("Unknown variable");
00187 }
00188
00189 int column = (*col).second;
00190 ReadColumnFromFile(mDataFilename, column);
00191
00192 return mValues;
00193 }
00194
00195 std::vector<double> ColumnDataReader::GetValues(const std::string& rVariableName,
00196 int fixedDimension)
00197 {
00198 if (mNumFixedDimensions < 1)
00199 {
00200 EXCEPTION("Data file has no fixed dimension");
00201 }
00202
00203 mValues.clear();
00204 if (mHasUnlimitedDimension)
00205 {
00206 std::string datafile = mDataFilename;
00207 std::map<std::string, int>::iterator col = mVariablesToColumns.find(rVariableName);
00208 if (col == mVariablesToColumns.end())
00209 {
00210 EXCEPTION("Unknown variable");
00211 }
00212 int column = (*col).second;
00213
00214 int counter = 1;
00215 while (true)
00216 {
00217 try
00218 {
00219 ReadValueFromFile(datafile, column, fixedDimension);
00220 }
00221 catch (Exception)
00222 {
00223 break;
00224 }
00225
00226
00227 std::string::size_type underscore_pos = datafile.rfind("_", datafile.length());
00228 std::stringstream suffix;
00229
00230 suffix << std::setfill('0') << std::setw(FILE_SUFFIX_WIDTH) << counter;
00231
00232 if (underscore_pos != std::string::npos)
00233 {
00234 datafile = datafile.substr(0, underscore_pos+1) + suffix.str() + ".dat";
00235 }
00236 counter++;
00237 }
00238 }
00239 else
00240 {
00241 int column = mVariablesToColumns[rVariableName];
00242 if (0 == column)
00243 {
00244 EXCEPTION("Unknown variable");
00245 }
00246 ReadValueFromFile(mDataFilename, column, fixedDimension);
00247 }
00248
00249 return mValues;
00250 }
00251
00252 std::vector<double> ColumnDataReader::GetUnlimitedDimensionValues()
00253 {
00254 mValues.clear();
00255 if (!mHasUnlimitedDimension)
00256 {
00257 EXCEPTION("Data file has no unlimited dimension");
00258 }
00259 if (mNumFixedDimensions > 0)
00260 {
00261
00262 ReadColumnFromFile(mAncillaryFilename, 0);
00263 }
00264 else
00265 {
00266
00267 ReadColumnFromFile(mDataFilename, 0);
00268 }
00269 return mValues;
00270 }
00271
00272 void ColumnDataReader::ReadValueFromFile(const std::string& rFilename, int col, int row)
00273 {
00274 std::ifstream datafile(rFilename.c_str(), std::ios::in);
00275
00276 if (!datafile.is_open())
00277 {
00278 EXCEPTION("Couldn't open data file");
00279 }
00280 std::string variable_values;
00281 for (int i=0; i<row+1; i++)
00282 {
00283 std::getline(datafile, variable_values);
00284 }
00285
00286 std::getline(datafile, variable_values);
00287 this->PushColumnEntryFromLine(variable_values, col);
00288
00289 datafile.close();
00290 }
00291
00292 void ColumnDataReader::ReadColumnFromFile(const std::string& rFilename, int col)
00293 {
00294
00295 mValues.clear();
00296
00297
00298 std::ifstream datafile(rFilename.c_str(), std::ios::in);
00299 std::string value;
00300
00301
00302 assert(datafile.is_open());
00303
00304
00305 bool end_of_file_reached = false;
00306
00307
00308 end_of_file_reached = std::getline(datafile, value).eof();
00309
00310 while (!end_of_file_reached)
00311 {
00312 end_of_file_reached = std::getline(datafile, value).eof();
00313 this->PushColumnEntryFromLine(value, col);
00314 }
00315 datafile.close();
00316 }
00317
00318 void ColumnDataReader::PushColumnEntryFromLine(const std::string& rLine, int col)
00319 {
00320 int startpos = col * (FIELD_WIDTH + SPACING) + SPACING - 1;
00321 std::string value = rLine.substr(startpos, FIELD_WIDTH + 1);
00322 std::stringstream variable_stream(value);
00323 double d_value;
00324 variable_stream >> d_value;
00325 if (variable_stream.fail())
00326 {
00327 d_value = DBL_MAX;
00328 }
00329
00330 mValues.push_back(d_value);
00331 }
00332
00333 bool ColumnDataReader::HasValues(const std::string& rVariableName)
00334 {
00335 std::map<std::string, int>::iterator col = mVariablesToColumns.find(rVariableName);
00336 return !(col == mVariablesToColumns.end());
00337 }