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