00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef COLUMNVECTORDATA_H
00013 #define COLUMNVECTORDATA_H 1
00014 #ifdef _MSC_VER
00015 #include "MSconfig.h"
00016 #endif
00017 #include "CCfits.h"
00018
00019
00020 #include <vector>
00021
00022 #include <valarray>
00023
00024 #include "Column.h"
00025 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #endif
00028
00029 #ifdef SSTREAM_DEFECT
00030 #include <strstream>
00031 #else
00032 #include <sstream>
00033 #endif
00034
00035 #include <memory>
00036 #include <numeric>
00037 namespace CCfits {
00038
00039 class Table;
00040
00041 }
00042
00043 #include "FITS.h"
00044 #include "FITSUtil.h"
00045 using std::complex;
00046
00047
00048 namespace CCfits {
00049
00050
00051
00052 template <typename T>
00053 class ColumnVectorData : public Column
00054 {
00055
00056 public:
00057 ColumnVectorData(const ColumnVectorData< T > &right);
00058 ColumnVectorData (Table* p = 0, T nullVal = FITSUtil::FitsNullValue<T>()());
00059 ColumnVectorData (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>()());
00060 ~ColumnVectorData();
00061
00062 virtual void readData (long firstrow, long nelements, long firstelem = 1);
00063 virtual ColumnVectorData<T>* clone () const;
00064 virtual void setDimen ();
00065 void setDataLimits (T* limits);
00066 const T minLegalValue () const;
00067 void minLegalValue (T value);
00068 const T maxLegalValue () const;
00069 void maxLegalValue (T value);
00070 const T minDataValue () const;
00071 void minDataValue (T value);
00072 const T maxDataValue () const;
00073 void maxDataValue (T value);
00074 const std::vector<std::valarray<T> >& data () const;
00075 void setData (const std::vector<std::valarray<T> >& value);
00076 const std::valarray<T>& data (int i) const;
00077 void data (int i, const std::valarray<T>& value);
00078
00079
00080 friend class Column;
00081 protected:
00082
00083
00084 private:
00085 ColumnVectorData< T > & operator=(const ColumnVectorData< T > &right);
00086
00087 virtual bool compare (const Column &right) const;
00088 void resizeDataObject (const std::vector<std::valarray<T> >& indata, size_t firstRow);
00089
00090
00091
00092
00093
00094 virtual void readColumnData (long first, long last, T* nullValue = 0);
00095 virtual std::ostream& put (std::ostream& s) const;
00096 void writeData (const std::valarray<T>& indata, long numRows, long firstRow = 1, T* nullValue = 0);
00097 void writeData (const std::vector<std::valarray<T> >& indata, long firstRow = 1, T* nullValue = 0);
00098
00099
00100
00101
00102
00103 virtual void readRow (size_t row, T* nullValue = 0);
00104
00105 virtual void readVariableRow (size_t row, T* nullValue = 0);
00106 void readColumnData (long firstrow, long nelements, long firstelem, T* nullValue = 0);
00107 void writeData (const std::valarray<T>& indata, const std::vector<long>& vectorLengths, long firstRow = 1, T* nullValue = 0);
00108 void writeFixedRow (const std::valarray<T>& data, long row, long firstElem = 1, T* nullValue = 0);
00109 void writeFixedArray (T* data, long nElements, long nRows, long firstRow, T* nullValue = 0);
00110
00111 virtual void insertRows (long first, long number = 1);
00112 virtual void deleteRows (long first, long number = 1);
00113 void doWrite (T* array, long row, long rowSize, long firstElem = 1);
00114 const T nullValue () const;
00115 void nullValue (T value);
00116
00117
00118
00119 private:
00120
00121 T m_nullValue;
00122 T m_minLegalValue;
00123 T m_maxLegalValue;
00124 T m_minDataValue;
00125 T m_maxDataValue;
00126
00127
00128 std::vector<std::valarray<T> > m_data;
00129
00130
00131
00132 };
00133
00134
00135
00136 template <typename T>
00137 inline void ColumnVectorData<T>::readData (long firstrow, long nelements, long firstelem)
00138 {
00139 readColumnData(firstrow,nelements,firstelem,static_cast<T*>(0));
00140 }
00141
00142 template <typename T>
00143 inline const T ColumnVectorData<T>::nullValue () const
00144 {
00145 return m_nullValue;
00146 }
00147
00148 template <typename T>
00149 inline void ColumnVectorData<T>::nullValue (T value)
00150 {
00151 m_nullValue = value;
00152 }
00153
00154 template <typename T>
00155 inline const T ColumnVectorData<T>::minLegalValue () const
00156 {
00157 return m_minLegalValue;
00158 }
00159
00160 template <typename T>
00161 inline void ColumnVectorData<T>::minLegalValue (T value)
00162 {
00163 m_minLegalValue = value;
00164 }
00165
00166 template <typename T>
00167 inline const T ColumnVectorData<T>::maxLegalValue () const
00168 {
00169 return m_maxLegalValue;
00170 }
00171
00172 template <typename T>
00173 inline void ColumnVectorData<T>::maxLegalValue (T value)
00174 {
00175 m_maxLegalValue = value;
00176 }
00177
00178 template <typename T>
00179 inline const T ColumnVectorData<T>::minDataValue () const
00180 {
00181 return m_minDataValue;
00182 }
00183
00184 template <typename T>
00185 inline void ColumnVectorData<T>::minDataValue (T value)
00186 {
00187 m_minDataValue = value;
00188 }
00189
00190 template <typename T>
00191 inline const T ColumnVectorData<T>::maxDataValue () const
00192 {
00193 return m_maxDataValue;
00194 }
00195
00196 template <typename T>
00197 inline void ColumnVectorData<T>::maxDataValue (T value)
00198 {
00199 m_maxDataValue = value;
00200 }
00201
00202 template <typename T>
00203 inline const std::vector<std::valarray<T> >& ColumnVectorData<T>::data () const
00204 {
00205 return m_data;
00206 }
00207
00208 template <typename T>
00209 inline void ColumnVectorData<T>::setData (const std::vector<std::valarray<T> >& value)
00210 {
00211 m_data = value;
00212 }
00213
00214 template <typename T>
00215 inline const std::valarray<T>& ColumnVectorData<T>::data (int i) const
00216 {
00217 return m_data[i - 1];
00218 }
00219
00220 template <typename T>
00221 inline void ColumnVectorData<T>::data (int i, const std::valarray<T>& value)
00222 {
00223 if (m_data[i-1].size() != value.size())
00224 m_data[i-1].resize(value.size());
00225 m_data[i - 1] = value;
00226 }
00227
00228
00229
00230 template <typename T>
00231 ColumnVectorData<T>::ColumnVectorData(const ColumnVectorData<T> &right)
00232 :Column(right),
00233 m_nullValue(right.m_nullValue),
00234 m_minLegalValue(right.m_minLegalValue),
00235 m_maxLegalValue(right.m_maxLegalValue),
00236 m_minDataValue(right.m_minDataValue),
00237 m_maxDataValue(right.m_maxDataValue),
00238 m_data(right.m_data)
00239 {
00240 }
00241
00242 template <typename T>
00243 ColumnVectorData<T>::ColumnVectorData (Table* p, T nullVal)
00244 : Column(p), m_nullValue(nullVal),
00245 m_minLegalValue(0),
00246 m_maxLegalValue(0),
00247 m_minDataValue(0),
00248 m_maxDataValue(0),
00249 m_data()
00250 {
00251 }
00252
00253 template <typename T>
00254 ColumnVectorData<T>::ColumnVectorData (int columnIndex, const string &columnName, ValueType type, const string &format, const string &unit, Table* p, int rpt, long w, const string &comment, T nullVal)
00255 : Column(columnIndex,columnName,type,format,unit,p,rpt,w,comment),
00256 m_nullValue(nullVal),
00257 m_minLegalValue(0),
00258 m_maxLegalValue(0),
00259 m_minDataValue(0),
00260 m_maxDataValue(0),
00261 m_data()
00262 {
00263 }
00264
00265
00266 template <typename T>
00267 ColumnVectorData<T>::~ColumnVectorData()
00268 {
00269
00270 }
00271
00272
00273 template <typename T>
00274 bool ColumnVectorData<T>::compare (const Column &right) const
00275 {
00276 if ( !Column::compare(right) ) return false;
00277 const ColumnVectorData<T>& that = static_cast<const ColumnVectorData<T>&>(right);
00278 size_t n = m_data.size();
00279
00280 if ( that.m_data.size() != n ) return false;
00281 for (size_t i = 0; i < n ; i++)
00282 {
00283 size_t nn = m_data[i].size();
00284
00285
00286 if (that.m_data[i].size() != nn ) return false;
00287
00288 std::valarray<bool> test = (m_data[i] == that.m_data[i]);
00289 for (size_t j = 0; j < nn ; j++ ) if ( !test[j] ) return false;
00290 }
00291 return true;
00292 }
00293
00294 template <typename T>
00295 ColumnVectorData<T>* ColumnVectorData<T>::clone () const
00296 {
00297 return new ColumnVectorData<T>(*this);
00298 }
00299
00300 template <typename T>
00301 void ColumnVectorData<T>::resizeDataObject (const std::vector<std::valarray<T> >& indata, size_t firstRow)
00302 {
00303
00304
00305
00306
00307
00308 const size_t lastInputRow(indata.size() + firstRow - 1);
00309 const size_t newLastRow = std::max(lastInputRow,static_cast<size_t>(rows()));
00310
00311
00312
00313
00314
00315
00316 const size_t origNRows(m_data.size());
00317
00318
00319 if (newLastRow > origNRows) m_data.resize(newLastRow);
00320
00321 if (varLength())
00322 {
00323
00324
00325
00326 for (size_t iRow = firstRow-1; iRow < lastInputRow; ++iRow)
00327 {
00328 std::valarray<T>& current = m_data[iRow];
00329 const size_t newSize = indata[iRow - (firstRow-1)].size();
00330 if (current.size() != newSize)
00331 current.resize(newSize);
00332 }
00333 }
00334 else
00335 {
00336
00337
00338
00339
00340
00341
00342 for (size_t iRow = firstRow-1; iRow < lastInputRow; ++iRow)
00343 {
00344 if (m_data[iRow].size() != repeat())
00345 m_data[iRow].resize(repeat());
00346 }
00347 }
00348 }
00349
00350 template <typename T>
00351 void ColumnVectorData<T>::setDimen ()
00352 {
00353 int status(0);
00354 FITSUtil:: auto_array_ptr<char> dimValue (new char[FLEN_VALUE]);
00355
00356 #ifdef SSTREAM_DEFECT
00357 std::ostrstream key;
00358 #else
00359 std::ostringstream key;
00360 #endif
00361 key << "TDIM" << index();
00362
00363 #ifdef SSTREAM_DEFECT
00364 fits_read_key_str(fitsPointer(), key.str(), dimValue.get(),0,&status);
00365 #else
00366 fits_read_key_str(fitsPointer(),const_cast<char*>(key.str().c_str()),dimValue.get(),0,&status);
00367 #endif
00368
00369 if (status == 0)
00370 {
00371 dimen(String(dimValue.get()));
00372 }
00373 }
00374
00375 template <typename T>
00376 void ColumnVectorData<T>::readColumnData (long first, long last, T* nullValue)
00377 {
00378 makeHDUCurrent();
00379
00380
00381 if ( rows() < last )
00382 {
00383 std::cerr << "CCfits: More data requested than contained in table. ";
00384 std::cerr << "Extracting complete column.\n";
00385 last = rows();
00386 }
00387
00388 long nelements = (last - first + 1)*repeat();
00389
00390
00391 readColumnData(first,nelements,1,nullValue);
00392 if (first <= 1 && last == rows()) isRead(true);
00393 }
00394
00395 template <typename T>
00396 std::ostream& ColumnVectorData<T>::put (std::ostream& s) const
00397 {
00398
00399 Column::put(s);
00400 if ( FITS::verboseMode() )
00401 {
00402 s << " Column Legal limits: ( " << m_minLegalValue << "," << m_maxLegalValue << " )\n"
00403 << " Column Data limits: ( " << m_minDataValue << "," << m_maxDataValue << " )\n";
00404 }
00405 if (!m_data.empty())
00406 {
00407 for (size_t j = 0; j < m_data.size(); j++)
00408 {
00409 size_t n = m_data[j].size();
00410 if ( n )
00411 {
00412 s << "Row " << j + 1 << " Vector Size " << n << '\n';
00413 for (size_t k = 0; k < n - 1; k++)
00414 {
00415 s << m_data[j][k] << '\t';
00416 }
00417 s << m_data[j][n - 1] << '\n';
00418 }
00419 }
00420 }
00421
00422 return s;
00423 }
00424
00425 template <typename T>
00426 void ColumnVectorData<T>::writeData (const std::valarray<T>& indata, long numRows, long firstRow, T* nullValue)
00427 {
00428
00429
00430
00431
00432
00433
00434
00435 if (numRows <= 0) throw InvalidNumberOfRows(numRows);
00436
00437 #ifdef SSTREAM_DEFECT
00438 std::ostrstream msgStr;
00439 #else
00440 std::ostringstream msgStr;
00441 #endif
00442 if (indata.size() % static_cast<size_t>(numRows))
00443 {
00444 msgStr << "To use this write function, input array size"
00445 <<"\n must be exactly divisible by requested num rows: "
00446 << numRows;
00447 throw InsufficientElements(msgStr.str());
00448 }
00449 const size_t cellsize = indata.size()/static_cast<size_t>(numRows);
00450
00451 if (!varLength() && cellsize != repeat() )
00452 {
00453 msgStr << "column: " << name()
00454 << "\n input data size: " << indata.size()
00455 << " required: " << numRows*repeat();
00456 String msg(msgStr.str());
00457 throw InsufficientElements(msg);
00458 }
00459
00460 std::vector<std::valarray<T> > internalFormat(numRows);
00461
00462
00463
00464 for (long j = 0; j < numRows; ++j)
00465 {
00466 internalFormat[j].resize(cellsize);
00467 internalFormat[j] = indata[std::slice(cellsize*j,cellsize,1)];
00468 }
00469
00470
00471
00472
00473 writeData(internalFormat,firstRow,nullValue);
00474 }
00475
00476 template <typename T>
00477 void ColumnVectorData<T>::writeData (const std::vector<std::valarray<T> >& indata, long firstRow, T* nullValue)
00478 {
00479
00480
00481
00482 const size_t nInputRows(indata.size());
00483 using std::valarray;
00484
00485 resizeDataObject(indata,firstRow);
00486
00487
00488
00489
00490 if (varLength())
00491 {
00492
00493
00494 if (nullValue)
00495 m_nullValue = *nullValue;
00496
00497
00498 const size_t endRow = nInputRows + firstRow-1;
00499 for (size_t iRow = firstRow-1; iRow < endRow; ++iRow)
00500 {
00501 m_data[iRow] = indata[iRow - (firstRow-1)];
00502
00503 doWrite(&m_data[iRow][0], iRow+1, m_data[iRow].size());
00504 }
00505 parent()->updateRows();
00506 }
00507 else
00508 {
00509
00510
00511 const size_t colRepeat = repeat();
00512 bool allEqualRepeat = true;
00513 for (size_t i=0; i<nInputRows; ++i)
00514 {
00515 const size_t sz = indata[i].size();
00516 if (sz > colRepeat)
00517 {
00518 #ifdef SSTREAM_DEFECT
00519 std::ostrstream oss;
00520 #else
00521 std::ostringstream oss;
00522 #endif
00523 oss << " vector column length " << colRepeat
00524 <<", input valarray length " << sz;
00525 throw InvalidRowParameter(oss.str());
00526 }
00527 if (sz < colRepeat)
00528 allEqualRepeat = false;
00529 }
00530
00531 if (allEqualRepeat)
00532 {
00533
00534 const size_t nElements (colRepeat*nInputRows);
00535 FITSUtil::CVAarray<T> convert;
00536 FITSUtil::auto_array_ptr<T> pArray(convert(indata));
00537 T* array = pArray.get();
00538
00539
00540
00541
00542
00543
00544 writeFixedArray(array,nElements,nInputRows,firstRow,nullValue);
00545
00546 for (size_t j = 0; j < nInputRows ; ++j)
00547 {
00548 const valarray<T>& input = indata[j];
00549 valarray<T>& current = m_data[j + firstRow - 1];
00550
00551 current = input;
00552 }
00553 }
00554 else
00555 {
00556
00557 const size_t endRow = nInputRows + firstRow-1;
00558 for (size_t iRow = firstRow-1; iRow<endRow; ++iRow)
00559 {
00560
00561
00562 valarray<T>& current = m_data[iRow];
00563 const valarray<T>& input = indata[iRow-(firstRow-1)];
00564 writeFixedRow(input, iRow, 1, nullValue);
00565 }
00566 parent()->updateRows();
00567 }
00568
00569 }
00570 }
00571
00572 template <typename T>
00573 void ColumnVectorData<T>::readRow (size_t row, T* nullValue)
00574 {
00575 makeHDUCurrent();
00576
00577
00578
00579 if ( row > static_cast<size_t>(rows()) )
00580 {
00581 #ifdef SSTREAM_DEFECT
00582 std::ostrstream msg;
00583 #else
00584 std::ostringstream msg;
00585 #endif
00586 msg << " row requested: " << row << " row range: 1 - " << rows();
00587 #ifdef SSTREAM_DEFECT
00588 msg << std::ends;
00589 #endif
00590
00591 throw Column::InvalidRowNumber(msg.str());
00592 }
00593
00594
00595
00596 bool variable(type() < 0);
00597
00598
00599 long nelements(repeat());
00600
00601 if (variable)
00602 {
00603 readVariableRow(row,nullValue);
00604 }
00605 else
00606 {
00607 readColumnData(row,nelements,1,nullValue);
00608 }
00609 }
00610
00611 template <typename T>
00612 void ColumnVectorData<T>::readVariableRow (size_t row, T* nullValue)
00613 {
00614 int status(0);
00615 long offset(0);
00616 long repeat(0);
00617 if (fits_read_descript(fitsPointer(),index(),static_cast<long>(row),
00618 &repeat,&offset,&status)) throw FitsError(status);
00619 readColumnData(row,repeat,1,nullValue);
00620 }
00621
00622 template <typename T>
00623 void ColumnVectorData<T>::readColumnData (long firstrow, long nelements, long firstelem, T* nullValue)
00624 {
00625 int status=0;
00626
00627 FITSUtil::auto_array_ptr<T> pArray(new T[nelements]);
00628 T* array = pArray.get();
00629 int anynul(0);
00630
00631
00632
00633 if (fits_read_col(fitsPointer(), abs(type()),index(), firstrow, firstelem,
00634 nelements, nullValue, array, &anynul, &status) != 0)
00635 throw FitsError(status);
00636
00637 size_t countRead = 0;
00638 const size_t ONE = 1;
00639
00640 if (m_data.size() != static_cast<size_t>(rows())) m_data.resize(rows());
00641 size_t vectorSize(0);
00642 if (!varLength())
00643 {
00644
00645 vectorSize = std::max(repeat(),ONE);
00646
00647 }
00648 else
00649 {
00650
00651
00652
00653
00654 vectorSize = nelements;
00655 }
00656 size_t n = nelements;
00657
00658 int i = firstrow;
00659 int ii = i - 1;
00660 while ( countRead < n)
00661 {
00662 std::valarray<T>& current = m_data[ii];
00663 if (current.size() != vectorSize) current.resize(vectorSize);
00664 int elementsInFirstRow = vectorSize-firstelem + 1;
00665 bool lastRow = ( (nelements - countRead) < vectorSize);
00666 if (lastRow)
00667 {
00668 int elementsInLastRow = nelements - countRead;
00669 std::valarray<T> ttmp(array + vectorSize*(ii-firstrow) + elementsInFirstRow,
00670 elementsInLastRow);
00671 for (int kk = 0; kk < elementsInLastRow; kk++) current[kk] = ttmp[kk];
00672 countRead += elementsInLastRow;
00673
00674 }
00675
00676 else
00677 {
00678 if (firstelem == 1 || (firstelem > 1 && i > firstrow) )
00679 {
00680 std::valarray<T> ttmp(array + vectorSize*(ii - firstrow) +
00681 elementsInFirstRow,vectorSize);
00682 current = ttmp;
00683 ii++;
00684 i++;
00685 countRead += vectorSize;
00686 }
00687 else
00688 {
00689 if (i == firstrow)
00690 {
00691 std::valarray<T> ttmp(array,elementsInFirstRow);
00692 for (size_t kk = firstelem ; kk < vectorSize ; kk++)
00693 current[kk] = ttmp[kk-firstelem];
00694 countRead += elementsInFirstRow;
00695 i++;
00696 ii++;
00697 }
00698 }
00699 }
00700 }
00701 }
00702
00703 template <typename T>
00704 void ColumnVectorData<T>::writeData (const std::valarray<T>& indata, const std::vector<long>& vectorLengths, long firstRow, T* nullValue)
00705 {
00706
00707
00708 using namespace std;
00709 const size_t N(vectorLengths.size());
00710 vector<long> sums(N);
00711
00712 partial_sum(vectorLengths.begin(),vectorLengths.end(),sums.begin());
00713
00714 if (indata.size() < static_cast<size_t>(sums[N-1]) )
00715 {
00716 #ifdef SSTREAM_DEFECT
00717 ostrstream msgStr;
00718 #else
00719 ostringstream msgStr;
00720 #endif
00721 msgStr << " input data size: " << indata.size() << " vector length sum: " << sums[N-1];
00722 #ifdef SSTREAM_DEFECT
00723 msgStr << std::ends;
00724 #endif
00725
00726 String msg(msgStr.str());
00727 throw InsufficientElements(msg);
00728 }
00729
00730 vector<valarray<T> > vvArray(N);
00731 long& last = sums[0];
00732 vvArray[0].resize(last);
00733 for (long jj = 0; jj < last; ++jj) vvArray[0][jj] = indata[jj];
00734
00735 for (size_t j = 1; j < N; ++j)
00736 {
00737 valarray<T>& __tmp = vvArray[j];
00738
00739 long& first = sums[j-1];
00740 long& jlast = sums[j];
00741 __tmp.resize(jlast - first);
00742 for (long k = first; k < jlast; ++k)
00743 {
00744 __tmp[k - first] = indata[k];
00745 }
00746 }
00747
00748 writeData(vvArray,firstRow,nullValue);
00749 }
00750
00751 template <typename T>
00752 void ColumnVectorData<T>::writeFixedRow (const std::valarray<T>& data, long row, long firstElem, T* nullValue)
00753 {
00754
00755
00756
00757
00758
00759
00760 #ifdef SSTREAM_DEFECT
00761 std::ostrstream msgStr;
00762 #else
00763 std::ostringstream msgStr;
00764 #endif
00765 if (varLength())
00766 {
00767 msgStr <<"Calling ColumnVectorData::writeFixedRow for a variable length column.\n";
00768 throw FitsFatal(msgStr.str());
00769 }
00770
00771 if (nullValue) m_nullValue = *nullValue;
00772
00773 std::valarray<T>& storedRow = m_data[row];
00774 long inputSize = static_cast<long>(data.size());
00775 long storedSize(storedRow.size());
00776 if (storedSize != static_cast<long>(repeat()))
00777 {
00778 msgStr<<"stored array size vs. column width mismatch in ColumnVectorData::writeFixedRow.\n";
00779 throw FitsFatal(msgStr.str());
00780 }
00781
00782 if (inputSize + firstElem - 1 > storedSize)
00783 {
00784 msgStr << " requested write " << firstElem << " to "
00785 << firstElem + inputSize - 1 << " exceeds vector length " << repeat();
00786 throw InvalidRowParameter(msgStr.str());
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 std::valarray<T>& lvData = const_cast<std::valarray<T>&>(data);
00802 T* inPointer = &lvData[0];
00803 doWrite(inPointer, row+1, inputSize, firstElem);
00804
00805
00806 const size_t offset = static_cast<size_t>(firstElem) - 1;
00807 for (size_t iElem=0; iElem < static_cast<size_t>(inputSize); ++iElem)
00808 {
00809
00810
00811 storedRow[iElem + offset] = inPointer[iElem];
00812 }
00813 }
00814
00815 template <typename T>
00816 void ColumnVectorData<T>::writeFixedArray (T* data, long nElements, long nRows, long firstRow, T* nullValue)
00817 {
00818 int status(0);
00819
00820
00821
00822
00823
00824
00825 if ( nElements < nRows*static_cast<long>(repeat()) )
00826 {
00827 #ifdef SSTREAM_DEFECT
00828 std::ostrstream msgStr;
00829 #else
00830 std::ostringstream msgStr;
00831 #endif
00832 msgStr << " input array size: " << nElements << " required " << nRows*repeat();
00833 String msg(msgStr.str());
00834
00835 throw Column::InsufficientElements(msg);
00836 }
00837
00838 if (nullValue)
00839 {
00840 m_nullValue = *nullValue;
00841 if (fits_write_colnull(fitsPointer(),abs(type()),index(),firstRow,
00842 1,nElements,data,nullValue,&status)) throw FitsError(status);
00843 }
00844 else
00845 {
00846 if (fits_write_col(fitsPointer(),abs(type()),index(),firstRow,
00847 1,nElements,data,&status)) throw FitsError(status);
00848 }
00849
00850 parent()->updateRows();
00851 }
00852
00853 template <typename T>
00854 void ColumnVectorData<T>::insertRows (long first, long number)
00855 {
00856 typename std::vector<std::valarray<T> >::iterator in;
00857 if (first !=0)
00858 {
00859 in = m_data.begin()+first;
00860 }
00861 else
00862 {
00863 in = m_data.begin();
00864 }
00865
00866
00867 m_data.insert(in,number,std::valarray<T>(T(),0));
00868 }
00869
00870 template <typename T>
00871 void ColumnVectorData<T>::deleteRows (long first, long number)
00872 {
00873
00874
00875
00876 size_t N(m_data.size());
00877 int newSize(N - number);
00878 std::vector<std::valarray<T> > __tmp(newSize);
00879
00880 int lastDeleted( number + first - 1 );
00881 int firstDeleted(first);
00882 int count(0);
00883 {
00884 for ( size_t j = 1; j <= N; ++j)
00885 {
00886 if ( (j - firstDeleted)*(lastDeleted - j) >= 0 )
00887 { ++count;
00888 }
00889 else
00890 {
00891 __tmp[j - 1 - count].resize(m_data[j - 1].size());
00892 __tmp[j - 1 - count] = m_data[j - 1];
00893 }
00894 }
00895 }
00896
00897 m_data.clear();
00898 m_data.resize(newSize);
00899 {
00900 for (int j = 0; j < newSize; ++j)
00901 {
00902 m_data[j].resize(__tmp[j].size());
00903 m_data[j] = __tmp[j];
00904 }
00905 }
00906 }
00907
00908 template <typename T>
00909 void ColumnVectorData<T>::setDataLimits (T* limits)
00910 {
00911 m_minLegalValue = limits[0];
00912 m_maxLegalValue = limits[1];
00913 m_minDataValue = std::max(limits[2],limits[0]);
00914 m_maxDataValue = std::min(limits[3],limits[1]);
00915 }
00916
00917 template <typename T>
00918 void ColumnVectorData<T>::doWrite (T* array, long row, long rowSize, long firstElem)
00919 {
00920 int status(0);
00921
00922
00923
00924 if ( !varLength())
00925 {
00926 if (fits_write_colnull(fitsPointer(),type(),index(),row, firstElem, rowSize,
00927 array,&m_nullValue,&status)) throw FitsError(status);
00928 }
00929 else
00930 {
00931 if (fits_write_col(fitsPointer(),abs(type()),index(),row,firstElem,rowSize,
00932 array,&status)) throw FitsError(status);
00933
00934 }
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00949 template <>
00950 inline void ColumnVectorData<complex<float> >::setDataLimits (complex<float>* limits)
00951 {
00952 m_minLegalValue = limits[0];
00953 m_maxLegalValue = limits[1];
00954 m_minDataValue = limits[2];
00955 m_maxDataValue = limits[3];
00956 }
00957 #else
00958 template <>
00959 void
00960 ColumnVectorData<complex<float> >::setDataLimits (complex<float>* limits);
00961 #endif
00962
00963 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00964 template <>
00965 inline void ColumnVectorData<complex<double> >::setDataLimits (complex<double>* limits)
00966 {
00967 m_minLegalValue = limits[0];
00968 m_maxLegalValue = limits[1];
00969 m_minDataValue = limits[2];
00970 m_maxDataValue = limits[3];
00971 }
00972 #else
00973 template <>
00974 void
00975 ColumnVectorData<complex<double> >::setDataLimits (complex<double>* limits);
00976 #endif
00977
00978
00979 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00980 template <>
00981 inline void ColumnVectorData<std::complex<float> >::readColumnData(long firstRow,
00982 long nelements, long firstElem, std::complex<float>* null )
00983 {
00984 int status=0;
00985 float nulval (0);
00986 FITSUtil::auto_array_ptr<float> pArray(new float[2*nelements]);
00987 float* array = pArray.get();
00988 int anynul(0);
00989
00990 if (fits_read_col_cmp(fitsPointer(),index(),firstRow, firstElem,
00991 nelements,nulval,array,&anynul,&status) ) throw FitsError(status);
00992
00993 if (m_data.size() != static_cast<size_t>(rows())) m_data.resize(rows());
00994
00995 std::valarray<std::complex<float> > readData(nelements);
00996 for (long j = 0; j < nelements; ++j)
00997 {
00998 readData[j] = std::complex<float>(array[2*j],array[2*j+1]);
00999 }
01000 size_t countRead = 0;
01001 const size_t ONE = 1;
01002
01003 if (m_data.size() != static_cast<size_t>(rows())) m_data.resize(rows());
01004 size_t vectorSize(0);
01005 if (!varLength())
01006 {
01007 vectorSize = std::max(repeat(),ONE);
01008 }
01009 else
01010 {
01011
01012
01013
01014
01015 vectorSize = nelements;
01016 }
01017 size_t n = nelements;
01018
01019 int i = firstRow;
01020 int ii = i - 1;
01021 while ( countRead < n)
01022 {
01023 std::valarray<complex<float> >& current = m_data[ii];
01024 if (current.size() != vectorSize) current.resize(vectorSize,0.);
01025 int elementsInFirstRow = vectorSize-firstElem + 1;
01026 bool lastRow = ( (nelements - countRead) < vectorSize);
01027 if (lastRow)
01028 {
01029 int elementsInLastRow = nelements - countRead;
01030 std::copy(&readData[countRead],&readData[nelements],¤t[0]);
01031 countRead += elementsInLastRow;
01032 }
01033
01034 else
01035 {
01036 if (firstElem == 1 || (firstElem > 1 && i > firstRow) )
01037 {
01038 current = readData[std::slice(vectorSize*(ii-firstRow)+
01039 elementsInFirstRow,vectorSize,1)];
01040 ++ii;
01041 ++i;
01042 countRead += vectorSize;
01043 }
01044 else
01045 {
01046 if (i == firstRow)
01047 {
01048 std::copy(&readData[0],&readData[elementsInFirstRow],
01049 ¤t[firstElem]);
01050 countRead += elementsInFirstRow;
01051 ++i;
01052 ++ii;
01053 }
01054 }
01055 }
01056 }
01057 }
01058 #else
01059 template <>
01060 void ColumnVectorData<complex<float> >::readColumnData(long firstRow,
01061 long nelements,
01062 long firstElem, complex<float>* null);
01063 #endif
01064
01065 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
01066 template <>
01067 inline void ColumnVectorData<complex<double> >::readColumnData (long firstRow,
01068 long nelements,long firstElem,
01069 complex<double>* nullValue)
01070 {
01071
01072
01073
01074 int status=0;
01075 double nulval (0);
01076 FITSUtil::auto_array_ptr<double> pArray(new double[2*nelements]);
01077 double* array = pArray.get();
01078 int anynul(0);
01079
01080 if (fits_read_col_dblcmp(fitsPointer(),index(),firstRow, firstElem,
01081 nelements,nulval,array,&anynul,&status) ) throw FitsError(status);
01082
01083 if (m_data.size() != static_cast<size_t>(rows())) m_data.resize(rows());
01084
01085 std::valarray<std::complex<double> > readData(nelements);
01086 for (long j = 0; j < nelements; ++j)
01087 {
01088 readData[j] = std::complex<double>(array[2*j],array[2*j+1]);
01089 }
01090 size_t countRead = 0;
01091 const size_t ONE = 1;
01092
01093 if (m_data.size() != static_cast<size_t>(rows())) m_data.resize(rows());
01094 size_t vectorSize(0);
01095 if (!varLength())
01096 {
01097 vectorSize = std::max(repeat(),ONE);
01098 }
01099 else
01100 {
01101
01102
01103
01104
01105 vectorSize = nelements;
01106 }
01107 size_t n = nelements;
01108
01109 int i = firstRow;
01110 int ii = i - 1;
01111 while ( countRead < n)
01112 {
01113 std::valarray<std::complex<double> >& current = m_data[ii];
01114 if (current.size() != vectorSize) current.resize(vectorSize,0.);
01115 int elementsInFirstRow = vectorSize-firstElem + 1;
01116 bool lastRow = ( (nelements - countRead) < vectorSize);
01117 if (lastRow)
01118 {
01119 int elementsInLastRow = nelements - countRead;
01120 std::copy(&readData[countRead],&readData[nelements],¤t[0]);
01121 countRead += elementsInLastRow;
01122 }
01123
01124 else
01125 {
01126 if (firstElem == 1 || (firstElem > 1 && i > firstRow) )
01127 {
01128 current = readData[std::slice(vectorSize*(ii-firstRow)+
01129 elementsInFirstRow,vectorSize,1)];
01130 ++ii;
01131 ++i;
01132 countRead += vectorSize;
01133 }
01134 else
01135 {
01136 if (i == firstRow)
01137 {
01138 std::copy(&readData[0],&readData[elementsInFirstRow],
01139 ¤t[firstElem]);
01140 countRead += elementsInFirstRow;
01141 ++i;
01142 ++ii;
01143 }
01144 }
01145 }
01146 }
01147 }
01148 #else
01149 template <>
01150 void ColumnVectorData<complex<double> >::readColumnData (long firstRow,
01151 long nelements,
01152 long firstElem, complex<double>* null);
01153 #endif
01154
01155 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
01156 template <>
01157 inline void ColumnVectorData<complex<float> >::writeFixedArray
01158 (complex<float>* data, long nElements, long nRows, long firstRow,
01159 complex<float>* nullValue)
01160 {
01161
01162 int status(0);
01163
01164
01165
01166
01167
01168
01169 if ( nElements < nRows*static_cast<long>(repeat()) )
01170 {
01171 #ifdef SSTREAM_DEFECT
01172 std::ostrstream msgStr;
01173 #else
01174 std::ostringstream msgStr;
01175 #endif
01176 msgStr << " input array size: " << nElements
01177 << " required " << nRows*repeat();
01178 #ifdef SSTREAM_DEFECT
01179 msgStr << std::ends;
01180 #endif
01181
01182
01183 String msg(msgStr.str());
01184
01185 throw Column::InsufficientElements(msg);
01186 }
01187
01188 FITSUtil::auto_array_ptr<float> realData(new float[2*nElements]);
01189
01190 for (int j = 0; j < nElements; ++j)
01191 {
01192 realData[2*j] = data[j].real();
01193 realData[2*j+1] = data[j].imag();
01194 }
01195
01196
01197
01198 if (fits_write_col_cmp(fitsPointer(),index(),firstRow,
01199 1,nElements,realData.get(),&status)) throw FitsError(status);
01200
01201 parent()->updateRows();
01202 }
01203 #else
01204 template <>
01205 void ColumnVectorData<complex<float> >::writeFixedArray
01206 (complex<float>* data, long nElements, long nRows, long firstRow, std::complex<float>* null);
01207 #endif
01208
01209 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
01210 template <>
01211 inline void ColumnVectorData<complex<double> >::writeFixedArray
01212 (complex<double>* data, long nElements, long nRows, long firstRow,
01213 complex<double>* nullValue)
01214 {
01215 int status(0);
01216
01217
01218
01219
01220
01221
01222 if ( nElements < nRows*static_cast<long>(repeat()) )
01223 {
01224 #ifdef SSTREAM_DEFECT
01225 std::ostrstream msgStr;
01226 #else
01227 std::ostringstream msgStr;
01228 #endif
01229 msgStr << " input array size: " << nElements
01230 << " required " << nRows*repeat();
01231 #ifdef SSTREAM_DEFECT
01232 msgStr << std::ends;
01233 #endif
01234
01235 String msg(msgStr.str());
01236
01237 throw Column::InsufficientElements(msg);
01238 }
01239
01240 FITSUtil::auto_array_ptr<double> realData(new double[2*nElements]);
01241
01242 for (int j = 0; j < nElements; ++j)
01243 {
01244 realData[2*j] = data[j].real();
01245 realData[2*j+1] = data[j].imag();
01246 }
01247
01248
01249
01250 if (fits_write_col_dblcmp(fitsPointer(),index(),firstRow,
01251 1,nElements,realData.get(),&status)) throw FitsError(status);
01252
01253 parent()->updateRows();
01254
01255 }
01256 #else
01257 template <>
01258 void ColumnVectorData<complex<double> >::writeFixedArray
01259 (complex<double>* data, long nElements, long nRows, long firstRow,
01260 std::complex<double>* null);
01261 #endif
01262
01263 #ifdef SPEC_TEMPLATE_DECL_DEFECT
01264 template <>
01265 inline void
01266 ColumnVectorData<std::complex<float> >::doWrite
01267 (std::complex<float>* data, long row, long rowSize, long firstElem )
01268 {
01269 int status(0);
01270 FITSUtil::auto_array_ptr<float> carray( new float[2*rowSize]);
01271 for ( long j = 0 ; j < rowSize; ++ j)
01272 {
01273 carray[2*j] = data[j].real();
01274 carray[2*j + 1] = data[j].imag();
01275 }
01276 if (fits_write_col_cmp(fitsPointer(),index(),row,firstElem,rowSize,
01277 carray.get(),&status)) throw FitsError(status);
01278 }
01279
01280
01281 template <>
01282 inline void
01283 ColumnVectorData<std::complex<double> >::doWrite
01284 (std::complex<double>* data, long row, long rowSize, long firstElem )
01285 {
01286 int status(0);
01287 FITSUtil::auto_array_ptr<double> carray( new double[2*rowSize]);
01288 for ( long j = 0 ; j < rowSize; ++ j)
01289 {
01290 carray[2*j] = data[j].real();
01291 carray[2*j + 1] = data[j].imag();
01292 }
01293 if (fits_write_col_dblcmp(fitsPointer(),index(),row,firstElem,rowSize,
01294 carray.get(),&status)) throw FitsError(status);
01295
01296 }
01297
01298 #else
01299 template<>
01300 void
01301 ColumnVectorData<complex<float> >::doWrite
01302 ( complex<float>* data, long row, long rowSize, long firstElem );
01303
01304 template<>
01305 void
01306 ColumnVectorData<complex<double> >::doWrite
01307 ( complex<double>* data, long row, long rowSize, long firstElem );
01308 #endif
01309 }
01310
01311
01312 #endif