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