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