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