00001
00002
00003
00004
00005
00006
00007 #ifndef TABLEDATA_H
00008 #define TABLEDATA_H
00009
00010 #include <cstdlib>
00011 #include <map>
00012 #include <sstream>
00013 #include <string>
00014 #include <typeinfo>
00015
00016 #include "DataTypes.h"
00017 #include "FitsFile.h"
00018 #include "MyException.h"
00019 #include "SchemaException.h"
00020 #include "StringOps.h"
00021 #include "Logger.h"
00022
00023
00024
00025
00027 extern inline void convertType(const Metadata& in, Numeric& out)
00028 {
00029
00030
00031 out = std::strtod(in.c_str(), 0);
00032 }
00033
00035 extern inline void convertType(const Metadata& in, Metadata& out)
00036 {
00037
00038
00039 out = in;
00040 }
00041
00043 extern inline void convertType(const Numeric& in, Numeric& out)
00044 {
00045
00046 out = in;
00047 }
00048
00050 extern inline void convertType(const Numeric& in, Metadata& out)
00051 {
00052
00053 out = StringOps::NumToString(in);
00054 }
00055
00057 extern inline void convertType(int in, Metadata& out)
00058 {
00059
00060 out = StringOps::NumToString(in);
00061 }
00062
00065 template<typename DataType>
00066 class TableData
00067 {
00068 public:
00071 TableData(unsigned aNumCols, unsigned aNumRows)
00072 : mNumCols(aNumCols),
00073 mNumRows(aNumRows),
00074 mNumExts(0),
00075 mBufferAry(0),
00076 mDefinedAry(0)
00077 {
00078
00079 mBufferAry = new DataType*[mNumCols];
00080 mDefinedAry = new bool*[mNumCols];
00081 for (unsigned col = 0; col < mNumCols; ++col)
00082 {
00083 mBufferAry[col] = new DataType[mNumRows];
00084 mDefinedAry[col] = new bool[mNumRows];
00085
00086
00087 for (unsigned row = 0; row < mNumRows; ++row)
00088 {
00089 mDefinedAry[col][row] = false;
00090 }
00091 }
00092 }
00093
00095 ~TableData()
00096 {
00097 for (unsigned col = 0; col < mNumCols; ++col)
00098 {
00099 delete[] mBufferAry[col];
00100 delete[] mDefinedAry[col];
00101 }
00102 delete[] mBufferAry;
00103 delete[] mDefinedAry;
00104 }
00105
00106
00107
00109 unsigned qNumRows() const { return mNumRows; }
00110
00112 unsigned qNumCols() const { return mNumCols; }
00113
00115 unsigned qNumExts() const { return mNumExts; }
00116
00121 template <typename ADataType>
00122 void assign(unsigned aCol, unsigned aRow, ADataType v)
00123 {
00124 DataType useVal;
00125 convertType(v, useVal);
00126 writeToBuffer(aCol, aRow, useVal);
00127 }
00128
00130 const DataType& at(unsigned aCol, unsigned aRow) const
00131 {
00132 return readBuffer(aCol, aRow);
00133 }
00134
00136 template <typename ADataType>
00137 void value(unsigned aCol, unsigned aRow, ADataType& aValue) const
00138 {
00139 convertType(readBuffer(aCol, aRow), aValue);
00140 }
00141
00143 bool isDefined(unsigned aCol, unsigned aRow) const
00144 {
00145 return readDefined(aCol, aRow);
00146 }
00147
00148 void setundef(unsigned aCol, unsigned aRow)
00149 {
00150 writeToDefined(aCol, aRow, false);
00151 }
00152
00153 void setNumExts(unsigned aNum)
00154 {
00155 writeToNumExts(aNum);
00156 }
00157
00162 int getFirstDefinedRow(unsigned aCol)
00163 {
00164 unsigned row = 0;
00165 while (row < mNumRows && !isDefined(aCol, row))
00166 {
00167 ++row;
00168 }
00169 if (row == mNumRows)
00170 {
00171 return -1;
00172 }
00173 return row;
00174 }
00175
00180 void loadFitsColumn(FitsFile& ff, const std::string &fitsColName,
00181 unsigned aCol, unsigned firstRow)
00182 {
00183 ff.readColumn(fitsColName, &mBufferAry[aCol][firstRow]);
00184 for (unsigned aRow = firstRow;
00185 aRow < firstRow + ff.getNumRows();
00186 ++aRow)
00187 {
00188 writeToDefined(aCol, aRow, true);
00189 }
00190 }
00191
00197 bool testRange(unsigned aCol,
00198 unsigned aRow,
00199 StringMap aRange)
00200 {
00201 unsigned noRng = aRange.size();
00202 Numeric useData;
00203 convertType(readBuffer(aCol, aRow), useData);
00204 if (noRng != 2)
00205 {
00206 std::string mess = "Range tag should contain exactly 2 values, but";
00207 mess += "contains " + StringOps::NumToString(noRng) + " values";
00208 throw SchemaException(mess);
00209 return false;
00210 }
00211 else
00212 {
00213 if (aRange[0] == "None" && aRange[1] != "None")
00214 {
00215 Numeric useVal[noRng];
00216 convertType(aRange[1], useVal[1]);
00217 return (useData <= useVal[1]);
00218 }
00219 else if (aRange[0] != "None" && aRange[1] == "None")
00220 {
00221 Numeric useVal[noRng];
00222 convertType(aRange[0], useVal[0]);
00223 return (useData >= useVal[0]);
00224 }
00225 else if (aRange[0] != "None" && aRange[1] != "None")
00226 {
00227 Numeric useVal[noRng];
00228 for (unsigned n = 0; n < noRng; n++)
00229 {
00230 convertType(aRange[n], useVal[n]);
00231 }
00232 return (useData >= useVal[0] && useData <= useVal[1]);
00233 }
00234 else
00235 {
00236 return true;
00237 }
00238 }
00239 }
00240
00246 template <typename ADataType>
00247 bool testDiscrValues(unsigned aCol,
00248 unsigned aRow,
00249 std::map<int, ADataType> aValues)
00250 {
00251 std::string useData;
00252 convertType(readBuffer(aCol, aRow), useData);
00253 unsigned noVals = aValues.size();
00254 std::string useVal[noVals];
00255 bool testVal = false;
00256 for (unsigned n = 0; n < noVals; ++n)
00257 {
00258 convertType(aValues[n], useVal[n]);
00259 testVal = testVal || (useData==useVal[n]);
00260 }
00261 return testVal;
00262 }
00263
00264
00265 private:
00267 unsigned mNumCols;
00268 unsigned mNumRows;
00269 unsigned mNumExts;
00271 DataType **mBufferAry;
00272
00275 bool **mDefinedAry;
00276
00277
00278 void checkIsInRange(unsigned aCol, unsigned aRow) const
00279 {
00280 if (aCol >= mNumCols || aRow >= mNumRows)
00281 {
00282 std::stringstream errMsg;
00283 errMsg << "Error!: TableData: Cannot access data at "
00284 << aCol << ":" << aRow;
00285 throw MyException(errMsg.str());
00286 }
00287 }
00288
00289 void writeToBuffer(unsigned aCol, unsigned aRow, DataType aValue)
00290 {
00291 checkIsInRange(aCol, aRow);
00292 mBufferAry[aCol][aRow] = aValue;
00293 mDefinedAry[aCol][aRow] = true;
00294 }
00295
00296 void writeToDefined(unsigned aCol, unsigned aRow, bool aState)
00297 {
00298 checkIsInRange(aCol, aRow);
00299 mDefinedAry[aCol][aRow] = aState;
00300 }
00301
00302 void writeToNumExts(unsigned aNum)
00303 {
00304 mNumExts = aNum;
00305 }
00306
00307 const DataType& readBuffer(unsigned aCol, unsigned aRow) const
00308 {
00309 checkIsInRange(aCol, aRow);
00310 return mBufferAry[aCol][aRow];
00311 }
00312
00313 bool readDefined(unsigned aCol, unsigned aRow) const
00314 {
00315 checkIsInRange(aCol, aRow);
00316 return mDefinedAry[aCol][aRow];
00317 }
00318 };
00319
00320 #endif
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333