00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef COLUMNDATA_H
00013 #define COLUMNDATA_H 1
00014 #include "CCfits.h"
00015
00016
00017 #include "Column.h"
00018
00019 #include <vector>
00020 #ifdef _MSC_VER
00021 #include "MSconfig.h"
00022 #endif
00023
00024 #include <complex>
00025 #include <memory>
00026 #include "FITSUtil.h"
00027 using std::complex;
00028 #include "FITS.h"
00029
00030
00031 namespace CCfits {
00032
00033
00034
00035 template <typename T>
00036 class ColumnData : public Column
00037 {
00038
00039 public:
00040 ColumnData(const ColumnData< T > &right);
00041 ColumnData (Table* p = 0, T nullVal = FITSUtil::FitsNullValue<T>()());
00042 ColumnData (int columnIndex, const string &columnName, ValueType type, const String &format, const String &unit, Table* p, int rpt = 1, long w = 1, const String &comment = "", T nullVal = FITSUtil::FitsNullValue<T>()());
00043 ~ColumnData();
00044
00045 virtual ColumnData<T>* clone () const;
00046 virtual void readData (long firstRow, long nelements, long firstElem = 1);
00047 void setDataLimits (T* limits);
00048 const T minLegalValue () const;
00049 void minLegalValue (T value);
00050 const T maxLegalValue () const;
00051 void maxLegalValue (T value);
00052 const T minDataValue () const;
00053 void minDataValue (T value);
00054 const T maxDataValue () const;
00055 void maxDataValue (T value);
00056 const std::vector<T>& data () const;
00057 void setData (const std::vector<T>& value);
00058 T data (int i);
00059 void data (int i, T value);
00060
00061
00062 friend class Column;
00063 protected:
00064
00065
00066 private:
00067 ColumnData< T > & operator=(const ColumnData< T > &right);
00068
00069 void readColumnData (long firstRow, long nelements, T* nullValue = 0);
00070 virtual bool compare (const Column &right) const;
00071 virtual std::ostream& put (std::ostream& s) const;
00072 void writeData (T* indata, long nRows = 1, long firstRow = 1, T* nullValue = 0);
00073 void writeData (const std::vector<T>& indata, long firstRow = 1, T* nullValue = 0);
00074
00075 virtual void insertRows (long first, long number = 1);
00076 virtual void deleteRows (long first, long number = 1);
00077 const T nullValue () const;
00078 void nullValue (T value);
00079
00080
00081
00082 private:
00083
00084 T m_nullValue;
00085 T m_minLegalValue;
00086 T m_maxLegalValue;
00087 T m_minDataValue;
00088 T m_maxDataValue;
00089
00090
00091 std::vector<T> m_data;
00092
00093
00094
00095 };
00096
00097
00098
00099 template <typename T>
00100 inline void ColumnData<T>::readData (long firstRow, long nelements, long firstElem)
00101 {
00102 readColumnData(firstRow,nelements,static_cast<T*>(0));
00103 }
00104
00105 template <typename T>
00106 inline const T ColumnData<T>::nullValue () const
00107 {
00108 return m_nullValue;
00109 }
00110
00111 template <typename T>
00112 inline void ColumnData<T>::nullValue (T value)
00113 {
00114 m_nullValue = value;
00115 }
00116
00117 template <typename T>
00118 inline const T ColumnData<T>::minLegalValue () const
00119 {
00120 return m_minLegalValue;
00121 }
00122
00123 template <typename T>
00124 inline void ColumnData<T>::minLegalValue (T value)
00125 {
00126 m_minLegalValue = value;
00127 }
00128
00129 template <typename T>
00130 inline const T ColumnData<T>::maxLegalValue () const
00131 {
00132 return m_maxLegalValue;
00133 }
00134
00135 template <typename T>
00136 inline void ColumnData<T>::maxLegalValue (T value)
00137 {
00138 m_maxLegalValue = value;
00139 }
00140
00141 template <typename T>
00142 inline const T ColumnData<T>::minDataValue () const
00143 {
00144 return m_minDataValue;
00145 }
00146
00147 template <typename T>
00148 inline void ColumnData<T>::minDataValue (T value)
00149 {
00150 m_minDataValue = value;
00151 }
00152
00153 template <typename T>
00154 inline const T ColumnData<T>::maxDataValue () const
00155 {
00156 return m_maxDataValue;
00157 }
00158
00159 template <typename T>
00160 inline void ColumnData<T>::maxDataValue (T value)
00161 {
00162 m_maxDataValue = value;
00163 }
00164
00165 template <typename T>
00166 inline const std::vector<T>& ColumnData<T>::data () const
00167 {
00168 return m_data;
00169 }
00170
00171 template <typename T>
00172 inline void ColumnData<T>::setData (const std::vector<T>& value)
00173 {
00174 m_data = value;
00175 }
00176
00177 template <typename T>
00178 inline T ColumnData<T>::data (int i)
00179 {
00180
00181 return m_data[i - 1];
00182 }
00183
00184 template <typename T>
00185 inline void ColumnData<T>::data (int i, T value)
00186 {
00187
00188 m_data[i - 1] = value;
00189 }
00190
00191
00192
00193 template <typename T>
00194 ColumnData<T>::ColumnData(const ColumnData<T> &right)
00195 :Column(right),
00196 m_nullValue(right.m_nullValue),
00197 m_minLegalValue(right.m_minLegalValue),
00198 m_maxLegalValue(right.m_maxLegalValue),
00199 m_minDataValue(right.m_minDataValue),
00200 m_maxDataValue(right.m_maxDataValue),
00201 m_data(right.m_data)
00202 {
00203 }
00204
00205 template <typename T>
00206 ColumnData<T>::ColumnData (Table* p, T nullVal)
00207 : Column(p), m_nullValue(nullVal),
00208 m_minLegalValue(),
00209 m_maxLegalValue(),
00210 m_minDataValue(),
00211 m_maxDataValue(),
00212 m_data()
00213 {
00214 }
00215
00216 template <typename T>
00217 ColumnData<T>::ColumnData (int columnIndex, const string &columnName, ValueType type, const String &format, const String &unit, Table* p, int rpt, long w, const String &comment, T nullVal)
00218 : Column(columnIndex,columnName,type,format,unit,p,rpt,w,comment),
00219 m_nullValue(nullVal),
00220 m_minLegalValue(),
00221 m_maxLegalValue(),
00222 m_minDataValue(),
00223 m_maxDataValue(),
00224 m_data()
00225 {
00226 }
00227
00228
00229 template <typename T>
00230 ColumnData<T>::~ColumnData()
00231 {
00232 }
00233
00234
00235 template <typename T>
00236 void ColumnData<T>::readColumnData (long firstRow, long nelements, T* nullValue)
00237 {
00238 if ( rows() < nelements )
00239 {
00240 std::cerr << "CCfits: More data requested than contained in table. ";
00241 std::cerr << "Extracting complete column.\n";
00242 nelements = rows();
00243 }
00244
00245 int status(0);
00246 int anynul(0);
00247
00248 FITSUtil::auto_array_ptr<T> array(new T[nelements]);
00249
00250 makeHDUCurrent();
00251
00252 if ( fits_read_col(fitsPointer(),type(), index(), firstRow, 1,
00253 nelements, nullValue, array.get(), &anynul, &status) ) throw FitsError(status);
00254
00255
00256 if (m_data.size() != static_cast<size_t>( rows() ) ) m_data.resize(rows());
00257
00258 std::copy(&array[0],&array[nelements],m_data.begin()+firstRow-1);
00259 if (nelements == rows()) isRead(true);
00260 }
00261
00262 template <typename T>
00263 bool ColumnData<T>::compare (const Column &right) const
00264 {
00265 if ( !Column::compare(right) ) return false;
00266 const ColumnData<T>& that = static_cast<const ColumnData<T>&>(right);
00267 unsigned int n = m_data.size();
00268 if ( that.m_data.size() != n ) return false;
00269 for (unsigned int i = 0; i < n ; i++)
00270 {
00271 if (m_data[i] != that.m_data[i]) return false;
00272 }
00273 return true;
00274 }
00275
00276 template <typename T>
00277 ColumnData<T>* ColumnData<T>::clone () const
00278 {
00279 return new ColumnData<T>(*this);
00280 }
00281
00282 template <typename T>
00283 std::ostream& ColumnData<T>::put (std::ostream& s) const
00284 {
00285 Column::put(s);
00286 if (FITS::verboseMode() && type() != Tstring)
00287 {
00288 s << " Column Legal limits: ( " << m_minLegalValue << "," << m_maxLegalValue << " )\n"
00289 << " Column Data limits: ( " << m_minDataValue << "," << m_maxDataValue << " )\n";
00290 }
00291 if (!m_data.empty())
00292 {
00293 std::ostream_iterator<T> output(s,"\n");
00294
00295
00296 std::copy(m_data.begin(),m_data.end(),output);
00297 }
00298
00299 return s;
00300 }
00301
00302 template <typename T>
00303 void ColumnData<T>::writeData (T* indata, long nRows, long firstRow, T* nullValue)
00304 {
00305
00306
00307
00308
00309
00310 int status(0);
00311 long elementsToWrite(nRows + firstRow -1);
00312
00313 std::vector<T> __tmp(m_data);
00314
00315 if (nullValue) m_nullValue = *nullValue;
00316
00317 if (elementsToWrite != static_cast<long>(m_data.size()))
00318 {
00319
00320 m_data.resize(elementsToWrite,T());
00321 }
00322
00323 std::copy(&indata[0],&indata[nRows],m_data.begin()+firstRow-1);
00324
00325
00326
00327 try
00328 {
00329
00330 if (fits_write_colnull(fitsPointer(), type(), index(), firstRow, 1, nRows,
00331 indata, nullValue, &status) != 0) throw FitsError(status);
00332
00333
00334 parent()->updateRows();
00335 }
00336 catch (FitsError)
00337 {
00338
00339 m_data = __tmp;
00340 if (status == NO_NULL) throw NoNullValue(name());
00341 else throw;
00342 }
00343 }
00344
00345 template <typename T>
00346 void ColumnData<T>::writeData (const std::vector<T>& indata, long firstRow, T* nullValue)
00347 {
00348 FITSUtil::CVarray<T> convert;
00349 FITSUtil::auto_array_ptr<T> pcolData (convert(indata));
00350 T* columnData = pcolData.get();
00351 writeData(columnData,indata.size(),firstRow,nullValue);
00352 }
00353
00354 template <typename T>
00355 void ColumnData<T>::insertRows (long first, long number)
00356 {
00357 FITSUtil::FitsNullValue<T> blank;
00358 typename std::vector<T>::iterator in;
00359 if (first !=0)
00360 {
00361 in = m_data.begin()+first;
00362 }
00363 else
00364 {
00365 in = m_data.begin();
00366 }
00367
00368
00369 m_data.insert(in,number,blank());
00370 }
00371
00372 template <typename T>
00373 void ColumnData<T>::deleteRows (long first, long number)
00374 {
00375 m_data.erase(m_data.begin()+first-1,m_data.begin()+first-1+number);
00376 }
00377
00378 template <typename T>
00379 void ColumnData<T>::setDataLimits (T* limits)
00380 {
00381 m_minLegalValue = limits[0];
00382 m_maxLegalValue = limits[1];
00383 m_minDataValue = std::max(limits[2],limits[0]);
00384 m_maxDataValue = std::min(limits[3],limits[1]);
00385 }
00386
00387
00388
00389
00390
00391
00392 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00393 template <>
00394 inline void ColumnData<complex<float> >::setDataLimits (complex<float>* limits)
00395 {
00396 m_minLegalValue = limits[0];
00397 m_maxLegalValue = limits[1];
00398 m_minDataValue = limits[2];
00399 m_maxDataValue = limits[3];
00400 }
00401 #else
00402 template <>
00403 void ColumnData<complex<float> >::setDataLimits (complex<float>* limits);
00404 #endif
00405
00406 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00407 template <>
00408 inline void ColumnData<complex<double> >::setDataLimits (complex<double>* limits)
00409 {
00410 m_minLegalValue = limits[0];
00411 m_maxLegalValue = limits[1];
00412 m_minDataValue = limits[2];
00413 m_maxDataValue = limits[3];
00414 }
00415 #else
00416 template <>
00417 void ColumnData<complex<double> >::setDataLimits (complex<double>* limits);
00418 #endif
00419
00420
00421 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00422 template <>
00423 inline void ColumnData<string>::readColumnData (long firstRow,
00424 long nelements,
00425 string* nullValue)
00426 {
00427 int status = 0;
00428
00429 int anynul = 0;
00430 char** array = new char*[nelements];
00431
00432 int j(0);
00433 for ( ; j < nelements; ++j)
00434 {
00435 array[j] = new char[width() + 1];
00436 }
00437
00438 char* nulval = 0;
00439 if (nullValue)
00440 {
00441 nulval = const_cast<char*>(nullValue->c_str());
00442 }
00443 else
00444 {
00445 nulval = new char;
00446 *nulval = '\0';
00447 }
00448
00449
00450 try
00451 {
00452 makeHDUCurrent();
00453 if (fits_read_col_str(fitsPointer(),index(), firstRow,1,nelements,
00454 nulval,array, &anynul,&status) ) throw FitsError(status);
00455 }
00456 catch (FitsError)
00457 {
00458
00459 for (int jj = 0; jj < nelements; ++jj)
00460 {
00461 delete [] array[jj];
00462 }
00463
00464 delete [] array;
00465 delete nulval;
00466 throw;
00467 }
00468
00469
00470 if (m_data.size() == 0) setData(std::vector<string>(rows(),string(nulval)));
00471
00472
00473
00474 for ( j = 0; j < nelements; j++)
00475 {
00476 m_data[j - 1 + firstRow] = string(array[j]);
00477 }
00478
00479 for ( j = 0; j < nelements; j++)
00480 {
00481 delete [] array[j];
00482 }
00483
00484 delete [] array;
00485 delete nulval;
00486
00487 }
00488 #else
00489 template <>
00490 void ColumnData<string>::readColumnData (long firstRow, long nelements, string* nullValue);
00491 #endif
00492
00493
00494 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00495 template <>
00496 inline void ColumnData<complex<float> >::readColumnData (long firstRow,
00497 long nelements,
00498 complex<float>* nullValue)
00499 {
00500
00501 int status(0);
00502 int anynul(0);
00503 FITSUtil::auto_array_ptr<float> pArray(new float[nelements*2]);
00504 float* array = pArray.get();
00505 float nulval(0);
00506 makeHDUCurrent();
00507
00508
00509 if (fits_read_col_cmp(fitsPointer(),index(), firstRow,1,nelements,
00510 nulval,array, &anynul,&status) ) throw FitsError(status);
00511
00512
00513 if (m_data.size() == 0) m_data.resize(rows());
00514
00515
00516
00517 for (int j = firstRow; j < nelements; ++j)
00518 {
00519
00520 m_data[j - 1] = std::complex<float>(array[2*j],array[2*j+1]);
00521 }
00522
00523 }
00524 #else
00525 template <>
00526 void ColumnData<complex<float> >::readColumnData (long firstRow, long nelements,complex<float>* nullValue );
00527 #endif
00528
00529 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00530 template <>
00531 inline void ColumnData<complex<double> >::readColumnData (long firstRow,
00532 long nelements,
00533 complex<double>* nullValue)
00534 {
00535
00536 int status(0);
00537 int anynul(0);
00538 FITSUtil::auto_array_ptr<double> pArray(new double[nelements*2]);
00539 double* array = pArray.get();
00540 double nulval(0);
00541 makeHDUCurrent();
00542
00543
00544 if (fits_read_col_dblcmp(fitsPointer(), index(), firstRow,1,nelements,
00545 nulval,array, &anynul,&status) ) throw FitsError(status);
00546
00547
00548
00549
00550 if (m_data.size() == 0) setData(std::vector<complex<double> >(rows(),nulval));
00551
00552
00553
00554 for (int j = firstRow; j < nelements; j++)
00555 {
00556
00557 m_data[j - 1] = std::complex<double>(array[2*j],array[2*j+1]);
00558 }
00559
00560 }
00561 #else
00562 template <>
00563 void ColumnData<complex<double> >::readColumnData (long firstRow, long nelements,complex<double>* nullValue);
00564 #endif
00565
00566 #if SPEC_TEMPLATE_DECL_DEFECT
00567 template <>
00568 inline void ColumnData<string>::writeData (const std::vector<string>& indata,
00569 long firstRow, string* nullValue)
00570 {
00571 int status=0;
00572 char** columnData=FITSUtil::CharArray(indata);
00573
00574 if ( fits_write_colnull(fitsPointer(), TSTRING, index(), firstRow, 1, indata.size(),
00575 columnData, 0, &status) != 0 )
00576 throw FitsError(status);
00577 unsigned long elementsToWrite (indata.size() + firstRow - 1);
00578 std::vector<string> __tmp(m_data);
00579 if (m_data.size() < elementsToWrite)
00580 {
00581 m_data.resize(elementsToWrite,"");
00582 std::copy(__tmp.begin(),__tmp.end(),m_data.begin());
00583 }
00584 std::copy(indata.begin(),indata.end(),m_data.begin()+firstRow-1);
00585
00586
00587 for (size_t i = 0; i < indata.size(); ++i)
00588 {
00589 delete [] columnData[i];
00590 }
00591 delete [] columnData;
00592 }
00593 #else
00594 template <>
00595 void ColumnData<string>::writeData (const std::vector<string>& inData, long firstRow, string* nullValue);
00596 #endif
00597
00598 #ifdef SPEC_TEMPLATE_DECL_DEFECT
00599 template <>
00600 inline void ColumnData<complex<float> >::writeData (const std::vector<complex<float> >& inData,
00601 long firstRow,
00602 complex<float>* nullValue)
00603 {
00604 int status(0);
00605 int nRows (inData.size());
00606 FITSUtil::auto_array_ptr<float> pData(new float[nRows*2]);
00607 float* Data = pData.get();
00608 std::vector<complex<float> > __tmp(m_data);
00609 for (int j = firstRow; j < nRows; ++j)
00610 {
00611 Data[ 2*j] = inData[j].real();
00612 Data[ 2*j + 1] = inData[j].imag();
00613 }
00614
00615 try
00616 {
00617
00618 if (fits_write_col_cmp(fitsPointer(), index(), firstRow, 1,
00619 nRows,Data, &status) != 0) throw FitsError(status);
00620 long elementsToWrite(nRows + firstRow -1);
00621 if (elementsToWrite > static_cast<long>(m_data.size()))
00622 {
00623
00624 m_data.resize(elementsToWrite);
00625 }
00626
00627 std::copy(inData.begin(),inData.end(),m_data.begin()+firstRow-1);
00628
00629
00630 parent()->updateRows();
00631 }
00632 catch (FitsError)
00633 {
00634
00635 m_data.resize(__tmp.size());
00636 m_data = __tmp;
00637 }
00638
00639 }
00640
00641 #else
00642 template <>
00643 void ColumnData<complex<float> >::writeData (const std::vector<complex<float> >& inData, long firstRow,
00644 complex<float>* nullValue);
00645 #endif
00646
00647 #ifdef SPEC_TEMPLATE_DECL_DEFECT
00648 template <>
00649 inline void ColumnData<complex<double> >::writeData (const std::vector<complex<double> >& inData,
00650 long firstRow,
00651 complex<double>* nullValue)
00652 {
00653 int status(0);
00654 int nRows (inData.size());
00655 FITSUtil::auto_array_ptr<double> pData(new double[nRows*2]);
00656 double* Data = pData.get();
00657 std::vector<complex<double> > __tmp(m_data);
00658 for (int j = firstRow; j < nRows; ++j)
00659 {
00660 pData[ 2*j] = inData[j].real();
00661 pData[ 2*j + 1] = inData[j].imag();
00662 }
00663
00664 try
00665 {
00666
00667 if (fits_write_col_dblcmp(fitsPointer(), index(), firstRow, 1,
00668 nRows,Data, &status) != 0) throw FitsError(status);
00669 long elementsToWrite(nRows + firstRow -1);
00670 if (elementsToWrite > static_cast<long>(m_data.size()))
00671 {
00672
00673 m_data.resize(elementsToWrite);
00674 }
00675
00676 std::copy(inData.begin(),inData.end(),m_data.begin()+firstRow-1);
00677
00678
00679 parent()->updateRows();
00680 }
00681 catch (FitsError)
00682 {
00683
00684 m_data.resize(__tmp.size());
00685 m_data = __tmp;
00686 }
00687
00688 }
00689
00690 #else
00691 template <>
00692 void ColumnData<complex<double> >::writeData (const std::vector<complex<double> >& inData, long firstRow,
00693 complex<double>* nullValue);
00694
00695 #endif
00696 }
00697
00698
00699 #endif