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