CCfits 2.7

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List

ColumnT.h

    00001 //  Astrophysics Science Division,
    00002 //  NASA/ Goddard Space Flight Center
    00003 //  HEASARC
    00004 //  http://heasarc.gsfc.nasa.gov
    00005 //  e-mail: ccfits@legacy.gsfc.nasa.gov
    00006 //
    00007 //  Original author: Ben Dorman
    00008
    00009 #ifndef COLUMNT_H
    00010 #define COLUMNT_H
    00011
    00012 #ifdef _MSC_VER
    00013 #include "MSconfig.h"
    00014 #endif
    00015
    00016 #include "ColumnData.h"
    00017 #include "ColumnVectorData.h"
    00018 #include "FITSUtil.h"
    00019 #include <typeinfo>
    00020 #include <vector>
    00021 #include <algorithm>
    00022 #include "NewKeyword.h"
    00023
    00024 #ifdef SSTREAM_DEFECT
    00025 #       include <strstream>
    00026 #else
    00027 #       include <sstream>
    00028 #endif
    00029
    00030
    00031 // by design, if the data are not read yet we will return an exception.
    00032 // here the test is if the entire column has already been read.
    00033 using std::complex;
    00034 using std::valarray;
    00035
    00036 // get specified elements of a scalar column. These two functions allow the
    00037 // user to return either a vector or a valarray depending on the input container.
    00038
    00039 namespace CCfits
    00040 {
    00041    template <typename S>
    00042    void Column::read(std::vector<S>& vals, long first, long last)
    00043    {
    00044            read(vals,first,last,static_cast<S*>(0));
    00045    }
    00046
    00047
    00048    template <typename S>
    00049    void Column::read(std::vector<S>& vals, long first, long last, S* nullValue)
    00050    {
    00051            // problem: S does not give the type of the Column, but the return type,
    00052            // so the user must specify this.
    00053            parent()->makeThisCurrent();
    00054            long nelements = numberOfElements(first,last);
    00055
    00056            if  (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
    00057            {
    00058                    // fails if user requested outputType different from input type.
    00059
    00060
    00061                    if (!isRead()) col->readColumnData(first,nelements,nullValue);
    00062                    // scalar column with vector output can just be assigned.
    00063                    FITSUtil::fill(vals,col->data(),first,last);
    00064            }
    00065            else
    00066            {
    00067                    FITSUtil::MatchType<S> outputType;
    00068                    if ( outputType() == type() )
    00069                    {
    00070                            // in this case user tried to read vector data from scalar,
    00071                            // (i.e. first argument was vector<valarray<S> >.
    00072                            // since the cast won't fail on template parameter grounds.
    00073                            throw Column::WrongColumnType(name());
    00074                    }
    00075
    00076                    try
    00077                    {
    00078                        // about exceptions. The dynamic_casts could throw
    00079                        // std::bad_cast. If this happens something is seriously
    00080                        // wrong since the Column stores the value of type()
    00081                        // appropriate to each of the casts on construction.
    00082                        //
    00083                        // the InvalidDataType exception should not be possible.
    00084                        if  ( type() == Tdouble )
    00085                {
    00086                                ColumnData<double>& col
    00087                                          = dynamic_cast<ColumnData<double>&>(*this);
    00088                                if (!isRead()) col.readColumnData(first,nelements);
    00089                                FITSUtil::fill(vals,col.data(),first,last);
    00090
    00091                        }
    00092                else if (type() == Tfloat)
    00093                {
    00094                                ColumnData<float>& col
    00095                                        = dynamic_cast<ColumnData<float>&>(*this);
    00096                                if (!isRead()) col.readColumnData(first,nelements);
    00097                                FITSUtil::fill(vals,col.data(),first,last);
    00098                        }
    00099                else if (type() == Tint)
    00100                {
    00101                                int nullVal(0);
    00102                                if (nullValue) nullVal = static_cast<int>(*nullValue);
    00103                                ColumnData<int>& col
    00104                                   = dynamic_cast<ColumnData<int>&>(*this);
    00105                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00106                                FITSUtil::fill(vals,col.data(),first,last);
    00107                }
    00108                else if (type() == Tshort)
    00109                        {
    00110                                short nullVal(0);
    00111                                if (nullValue) nullVal = static_cast<short>(*nullValue);
    00112                                ColumnData<short>& col
    00113                                 = dynamic_cast<ColumnData<short>&>(*this);
    00114                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00115                                FITSUtil::fill(vals,col.data(),first,last);
    00116                        }
    00117                else if (type() == Tlong)
    00118                {
    00119                                long nullVal(0);
    00120                                if (nullValue) nullVal = static_cast<long>(*nullValue);
    00121                                ColumnData<long>& col
    00122                                  = dynamic_cast<ColumnData<long>&>(*this);
    00123                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00124                                FITSUtil::fill(vals,col.data(),first,last);
    00125                        }
    00126                else if (type() == Tlonglong)
    00127                {
    00128                                LONGLONG nullVal(0);
    00129                                if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
    00130                                ColumnData<LONGLONG>& col
    00131                                  = dynamic_cast<ColumnData<LONGLONG>&>(*this);
    00132                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00133                                FITSUtil::fill(vals,col.data(),first,last);
    00134                        }
    00135                else if (type() == Tlogical)
    00136                {
    00137                                bool nullVal(0);
    00138                                if (nullValue) nullVal = static_cast<bool>(*nullValue);
    00139                                ColumnData<bool>& col
    00140                                  = dynamic_cast<ColumnData<bool>&>(*this);
    00141                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00142                                FITSUtil::fill(vals,col.data(),first,last);
    00143                }
    00144                else if (type() == Tbit || type() == Tbyte)
    00145                {
    00146                                unsigned char nullVal(0);
    00147                                if (nullValue) nullVal = static_cast<unsigned char>(*nullValue);
    00148                                ColumnData<unsigned char>& col
    00149                                        = dynamic_cast<ColumnData<unsigned char>&>(*this);
    00150                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00151                                FITSUtil::fill(vals,col.data(),first,last);
    00152                        }
    00153                else if (type() == Tushort)
    00154                        {
    00155                                unsigned short nullVal(0);
    00156                                if (nullValue) nullVal= static_cast<unsigned short>(*nullValue);
    00157                                ColumnData<unsigned short>& col
    00158                                        = dynamic_cast<ColumnData<unsigned short>&>(*this);
    00159                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00160                                FITSUtil::fill(vals,col.data(),first,last);
    00161                        }
    00162                else if (type() == Tuint)
    00163                        {
    00164                                unsigned int nullVal(0);
    00165                                if (nullValue) nullVal = static_cast<unsigned int>(*nullValue);
    00166                                ColumnData<unsigned int>& col
    00167                                        = dynamic_cast<ColumnData<unsigned int>&>(*this);
    00168                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00169                                FITSUtil::fill(vals,col.data(),first,last);
    00170                }
    00171                else if (type() == Tulong)
    00172                        {
    00173                                unsigned long nullVal(0);
    00174                                if (nullValue) nullVal = static_cast<unsigned long>(*nullValue);
    00175                                ColumnData<unsigned long>& col
    00176                                         = dynamic_cast<ColumnData<unsigned long>&>(*this);
    00177                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00178                                FITSUtil::fill(vals,col.data(),first,last);
    00179                        }
    00180                else
    00181                        {
    00182                                  throw InvalidDataType(name());
    00183
    00184                        }
    00185
    00186                    }
    00187                    catch (std::bad_cast&)
    00188                    {
    00189                throw WrongColumnType(name());
    00190                    }
    00191            }
    00192
    00193    }
    00194
    00195    template <typename S>
    00196    void Column::read(std::valarray<S>& vals, long first, long last)
    00197    {
    00198            read(vals,first,last,static_cast<S*>(0));
    00199    }
    00200
    00201
    00202    template <typename S>
    00203    void Column::read(std::valarray<S>& vals, long first, long last, S* nullValue)
    00204    {
    00205            // require the whole scalar column to have been read.
    00206
    00207
    00208            long nelements = numberOfElements(first,last);
    00209            parent()->makeThisCurrent();
    00210            if ( ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
    00211            {
    00212                    // fails if user requested outputType different from input type.
    00213
    00214
    00215                    if (!isRead()) col->readColumnData(first,nelements,nullValue);
    00216                    FITSUtil::fill(vals,col->data(),first,last);
    00217
    00218            }
    00219            else
    00220            {
    00221                    FITSUtil::MatchType<S> outputType;
    00222                    if ( outputType() == type() )
    00223                    {
    00224                            // in this case user tried to read vector data from scalar,
    00225                            // (i.e. first argument was vector<valarray<S> >.
    00226                            // since the cast won't fail on template parameter grounds.
    00227                            throw Column::WrongColumnType(name());
    00228                    }
    00229
    00230                    try
    00231                    {
    00232                        // about exceptions. The dynamic_casts could throw
    00233                        // std::bad_cast. If this happens something is seriously
    00234                        // wrong since the Column stores the value of type()
    00235                        // appropriate to each of the casts on construction.
    00236                        //
    00237                        // the InvalidDataType exception should not be possible.
    00238                        if  ( type() == Tdouble )
    00239                {
    00240                                ColumnData<double>& col
    00241                                          = dynamic_cast<ColumnData<double>&>(*this);
    00242                                if (!isRead()) col.readColumnData(first,nelements);
    00243                                FITSUtil::fill(vals,col.data(),first,last);
    00244                        }
    00245                else if (type() == Tfloat)
    00246                {
    00247                                ColumnData<float>& col
    00248                                        = dynamic_cast<ColumnData<float>&>(*this);
    00249                                if (!isRead()) col.readColumnData(first,nelements);
    00250                                FITSUtil::fill(vals,col.data(),first,last);
    00251                        }
    00252                else if (type() == Tint)
    00253                {
    00254                                int nullVal(0);
    00255                                if (nullValue) nullVal = static_cast<int>(*nullValue);
    00256                                ColumnData<int>& col
    00257                                        = dynamic_cast<ColumnData<int>&>(*this);
    00258                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00259                                FITSUtil::fill(vals,col.data(),first,last);
    00260                }
    00261                else if (type() == Tshort)
    00262                        {
    00263                                short nullVal(0);
    00264                                if (nullValue) nullVal = static_cast<short>(*nullValue);
    00265                                ColumnData<short>& col
    00266                                        = dynamic_cast<ColumnData<short>&>(*this);
    00267                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00268                                FITSUtil::fill(vals,col.data(),first,last);
    00269                        }
    00270                else if (type() == Tlong)
    00271                {
    00272                                long nullVal(0);
    00273                                if (nullValue) nullVal = static_cast<long>(*nullValue);
    00274                                ColumnData<long>& col
    00275                                        = dynamic_cast<ColumnData<long>&>(*this);
    00276                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00277                                FITSUtil::fill(vals,col.data(),first,last);
    00278                        }
    00279                else if (type() == Tlonglong)
    00280                {
    00281                                LONGLONG nullVal(0);
    00282                                if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
    00283                                ColumnData<LONGLONG>& col
    00284                                        = dynamic_cast<ColumnData<LONGLONG>&>(*this);
    00285                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00286                                FITSUtil::fill(vals,col.data(),first,last);
    00287                        }
    00288                else if (type() == Tlogical)
    00289                {
    00290                                bool nullVal(0);
    00291                                if (nullValue) nullVal = static_cast<bool>(*nullValue);
    00292                                ColumnData<bool>& col
    00293                                        = dynamic_cast<ColumnData<bool>&>(*this);
    00294                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00295                                FITSUtil::fill(vals,col.data(),first,last);
    00296                }
    00297                else if (type() == Tbit || type() == Tbyte)
    00298                {
    00299                                unsigned char nullVal(0);
    00300                                if (nullValue) nullVal = static_cast<unsigned char>(*nullValue);
    00301                                ColumnData<unsigned char>& col
    00302                                        = dynamic_cast<ColumnData<unsigned char>&>(*this);
    00303                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00304                                FITSUtil::fill(vals,col.data(),first,last);
    00305                        }
    00306                else if (type() == Tushort)
    00307                        {
    00308                                unsigned short nullVal(0);
    00309                                if (nullValue) nullVal
    00310                                        = static_cast<unsigned short>(*nullValue);
    00311                                ColumnData<unsigned short>& col
    00312                                        = dynamic_cast<ColumnData<unsigned short>&>(*this);
    00313                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00314                                FITSUtil::fill(vals,col.data(),first,last);
    00315                        }
    00316                else if (type() == Tuint)
    00317                        {
    00318                                unsigned int nullVal(0);
    00319                                if (nullValue) nullVal
    00320                                        = static_cast<unsigned int>(*nullValue);
    00321                                ColumnData<unsigned int>& col
    00322                                        = dynamic_cast<ColumnData<unsigned int>&>(*this);
    00323                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00324                                FITSUtil::fill(vals,col.data(),first,last);
    00325                }
    00326                else if (type() == Tulong)
    00327                        {
    00328                                unsigned long nullVal(0);
    00329                                if (nullValue) nullVal
    00330                                        = static_cast<unsigned long>(*nullValue);
    00331                                ColumnData<unsigned long>& col
    00332                                        = dynamic_cast<ColumnData<unsigned long>&>(*this);
    00333                                if (!isRead()) col.readColumnData(first,nelements,&nullVal);
    00334                                FITSUtil::fill(vals,col.data(),first,last);
    00335                        }
    00336                else
    00337                        {
    00338                                  throw InvalidDataType(name());
    00339
    00340                        }
    00341
    00342                    }
    00343                    catch (std::bad_cast&)
    00344                    {
    00345                 throw WrongColumnType(name());
    00346                    }
    00347                }
    00348
    00349    }
    00350
    00351    // get a single row from a vector column. There's no default row number, must
    00352    // be specified.
    00353    template <typename S>
    00354    void Column::read(std::valarray<S>& vals, long row)
    00355    {
    00356            read(vals,row,static_cast<S*>(0));
    00357    }
    00358    template <typename S>
    00359    void Column::read(std::vector<S>& vals, long row)
    00360    {
    00361            read(vals,row,static_cast<S*>(0));
    00362    }
    00363
    00364    template <typename S>
    00365    void Column::read(std::vector<S>& vals, long row, S* nullValue)
    00366    {
    00367            if (row > parent()->rows())
    00368            {
    00369               throw Column::InvalidRowNumber(name());
    00370            }
    00371            parent()->makeThisCurrent();
    00372            // isRead() returns true if the data were read in the ctor.
    00373            if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
    00374            {
    00375                    // fails if user requested outputType different from input type.
    00376
    00377
    00378                    if (!isRead()) col->readRow(row,nullValue);
    00379                    FITSUtil::fill(vals,col->data(row));
    00380            }
    00381            else
    00382            {
    00383                    FITSUtil::MatchType<S> outputType;
    00384                    if ( outputType() == type() )
    00385                    {
    00386                            // in this case user tried to read vector row from scalar column.
    00387                            // one could be charitable and return a valarray of size 1,
    00388                            // but... I'm going to throw an exception suggesting the user
    00389                            // might not have meant that.
    00390
    00391                            throw Column::WrongColumnType(name());
    00392                    }
    00393
    00394                    // the InvalidDataType exception should not be possible.
    00395                    try
    00396                    {
    00397                        // about exceptions. The dynamic_casts could throw
    00398                        // std::bad_cast. If this happens something is seriously
    00399                        // wrong since the Column stores the value of type()
    00400                        // appropriate to each of the casts on construction.
    00401                        //
    00402                        // the InvalidDataType exception should not be possible.
    00403                        if  ( type() == Tdouble || type() == VTdouble )
    00404                {
    00405                                ColumnVectorData<double>& col
    00406                                          = dynamic_cast<ColumnVectorData<double>&>(*this);
    00407                                if (!isRead()) col.readRow(row);
    00408                                FITSUtil::fill(vals,col.data(row));
    00409
    00410                        }
    00411                else if (type() == Tfloat  || type() == VTfloat )
    00412                {
    00413                                ColumnVectorData<float>& col
    00414                                      = dynamic_cast<ColumnVectorData<float>&>(*this);
    00415                                if (!isRead()) col.readRow(row);
    00416                                FITSUtil::fill(vals,col.data(row));
    00417                        }
    00418                else if (type() == Tint  || type() == VTint )
    00419                {
    00420                                int nullVal(0);
    00421                                if (nullValue) nullVal = static_cast<int>(*nullValue);
    00422                                ColumnVectorData<int>& col
    00423                                        = dynamic_cast<ColumnVectorData<int>&>(*this);
    00424                                if (!isRead()) col.readRow(row,&nullVal);
    00425                                FITSUtil::fill(vals,col.data(row));
    00426                }
    00427                else if (type() == Tshort  || type() == VTshort  )
    00428                        {
    00429                                short nullVal(0);
    00430                                if (nullValue) nullVal = static_cast<short>(*nullValue);
    00431                                ColumnVectorData<short>& col
    00432                                        = dynamic_cast<ColumnVectorData<short>&>(*this);
    00433                                if (!isRead()) col.readRow(row,&nullVal);
    00434                                FITSUtil::fill(vals,col.data(row));
    00435                        }
    00436                else if (type() == Tlong  || type() == VTlong )
    00437                {
    00438                                long nullVal(0);
    00439                                if (nullValue) nullVal = static_cast<long>(*nullValue);
    00440                                ColumnVectorData<long>& col
    00441                                        = dynamic_cast<ColumnVectorData<long>&>(*this);
    00442                                if (!isRead()) col.readRow(row,&nullVal);
    00443                                FITSUtil::fill(vals,col.data(row));
    00444                        }
    00445                else if (type() == Tlonglong  || type() == VTlonglong )
    00446                {
    00447                                LONGLONG nullVal(0);
    00448                                if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
    00449                                ColumnVectorData<LONGLONG>& col
    00450                                        = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
    00451                                if (!isRead()) col.readRow(row,&nullVal);
    00452                                FITSUtil::fill(vals,col.data(row));
    00453                        }
    00454                else if (type() == Tlogical  || type() == VTlogical )
    00455                {
    00456                                bool nullVal(0);
    00457                                if (nullValue) nullVal = static_cast<bool>(*nullValue);
    00458                                ColumnVectorData<bool>& col
    00459                                        = dynamic_cast<ColumnVectorData<bool>&>(*this);
    00460                                if (!isRead()) col.readRow(row,&nullVal);
    00461                                FITSUtil::fill(vals,col.data(row));
    00462                }
    00463                else if (type() == Tbit || type() == Tbyte ||
    00464                                type() == VTbit || type() == VTbyte )
    00465                {
    00466                                unsigned char nullVal(0);
    00467                                if (nullValue) nullVal
    00468                                            = static_cast<unsigned char>(*nullValue);
    00469                                ColumnVectorData<unsigned char>& col
    00470                                      = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
    00471                                if (!isRead()) col.readRow(row,&nullVal);
    00472                                FITSUtil::fill(vals,col.data(row));
    00473                        }
    00474                else if (type() == Tushort || type() == VTushort)
    00475                        {
    00476                                unsigned short nullVal(0);
    00477                                if (nullValue) nullVal
    00478                                            = static_cast<unsigned short>(*nullValue);
    00479                                ColumnVectorData<unsigned short>& col
    00480                                      = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
    00481                                if (!isRead()) col.readRow(row,&nullVal);
    00482                                FITSUtil::fill(vals,col.data(row));
    00483                        }
    00484                else if (type() == Tuint || type() == VTuint)
    00485                        {
    00486                                unsigned int nullVal(0);
    00487                                if (nullValue) nullVal
    00488                                            = static_cast<unsigned int>(*nullValue);
    00489                                ColumnVectorData<unsigned int>& col
    00490                                      = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
    00491                                if (!isRead()) col.readRow(row,&nullVal);
    00492                                FITSUtil::fill(vals,col.data(row));
    00493                }
    00494                else if (type() == Tulong || type() == VTulong)
    00495                        {
    00496                                unsigned long nullVal(0);
    00497                                if (nullValue) nullVal
    00498                                            = static_cast<unsigned long>(*nullValue);
    00499                                ColumnVectorData<unsigned long>& col
    00500                                        = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
    00501                                if (!isRead()) col.readRow(row,&nullVal);
    00502                                FITSUtil::fill(vals,col.data(row));
    00503                        }
    00504                else
    00505                        {
    00506                                throw InvalidDataType(name());
    00507
    00508                        }
    00509
    00510                    }
    00511                    catch (std::bad_cast&)
    00512                    {
    00513                        throw WrongColumnType(name());
    00514                    }
    00515             }
    00516    }
    00517
    00518    template <typename S>
    00519    void Column::read(std::valarray<S>& vals, long row, S* nullValue)
    00520    {
    00521            if (row > parent()->rows())
    00522            {
    00523               throw Column::InvalidRowNumber(name());
    00524            }
    00525            parent()->makeThisCurrent();
    00526            // isRead() returns true if the data were read in the ctor.
    00527            if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
    00528            {
    00529                    // fails if user requested outputType different from input type.
    00530
    00531
    00532
    00533                    // input and output are both valarrays. Since one should not
    00534                    // be able to call a constructor for a non-numeric valarray type,
    00535                    // there shouldn't be any InvalidType problems. However, there
    00536                    // is still the vector/scalar possibility and the implicit
    00537                    // conversion request to deal with.
    00538
    00539                    if (!isRead()) col->readRow(row,nullValue);
    00540                    FITSUtil::fill(vals,col->data(row));
    00541            }
    00542            else
    00543            {
    00544                    FITSUtil::MatchType<S> outputType;
    00545                    if ( outputType() == type() )
    00546                    {
    00547                            // in this case user tried to read vector row from scalar column.
    00548                            // one could be charitable and return a valarray of size 1,
    00549                            // but... I'm going to throw an exception suggesting the user
    00550                            // might not have meant that.
    00551
    00552                            throw Column::WrongColumnType(name());
    00553                    }
    00554
    00555                    // the InvalidDataType exception should not be possible.
    00556                    try
    00557                    {
    00558                        // about exceptions. The dynamic_casts could throw
    00559                        // std::bad_cast. If this happens something is seriously
    00560                        // wrong since the Column stores the value of type()
    00561                        // appropriate to each of the casts on construction.
    00562                        //
    00563                        // the InvalidDataType exception should not be possible.
    00564                        if  ( type() == Tdouble || type() == VTdouble )
    00565                {
    00566                                ColumnVectorData<double>& col
    00567                                          = dynamic_cast<ColumnVectorData<double>&>(*this);
    00568                                if (!isRead()) col.readRow(row);
    00569                                FITSUtil::fill(vals,col.data(row));
    00570
    00571                        }
    00572                else if (type() == Tfloat  || type() == VTfloat )
    00573                {
    00574                                ColumnVectorData<float>& col
    00575                                      = dynamic_cast<ColumnVectorData<float>&>(*this);
    00576                                if (!isRead()) col.readRow(row);
    00577                                FITSUtil::fill(vals,col.data(row));
    00578                        }
    00579                else if (type() == Tint  || type() == VTint )
    00580                {
    00581                                int nullVal(0);
    00582                                if (nullValue) nullVal = static_cast<int>(*nullValue);
    00583                                ColumnVectorData<int>& col
    00584                                        = dynamic_cast<ColumnVectorData<int>&>(*this);
    00585                                if (!isRead()) col.readRow(row,&nullVal);
    00586                                FITSUtil::fill(vals,col.data(row));
    00587                }
    00588                else if (type() == Tshort  || type() == VTshort  )
    00589                        {
    00590                                short nullVal(0);
    00591                                if (nullValue) nullVal = static_cast<short>(*nullValue);
    00592                                ColumnVectorData<short>& col
    00593                                        = dynamic_cast<ColumnVectorData<short>&>(*this);
    00594                                if (!isRead()) col.readRow(row,&nullVal);
    00595                                FITSUtil::fill(vals,col.data(row));
    00596                        }
    00597                else if (type() == Tlong  || type() == VTlong )
    00598                {
    00599                                long nullVal(0);
    00600                                if (nullValue) nullVal = static_cast<long>(*nullValue);
    00601                                ColumnVectorData<long>& col
    00602                                        = dynamic_cast<ColumnVectorData<long>&>(*this);
    00603                                if (!isRead()) col.readRow(row,&nullVal);
    00604                                FITSUtil::fill(vals,col.data(row));
    00605                        }
    00606                else if (type() == Tlonglong  || type() == VTlonglong )
    00607                {
    00608                                LONGLONG nullVal(0);
    00609                                if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
    00610                                ColumnVectorData<LONGLONG>& col
    00611                                        = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
    00612                                if (!isRead()) col.readRow(row,&nullVal);
    00613                                FITSUtil::fill(vals,col.data(row));
    00614                        }
    00615                else if (type() == Tlogical  || type() == VTlogical )
    00616                {
    00617                                bool nullVal(0);
    00618                                if (nullValue) nullVal = static_cast<bool>(*nullValue);
    00619                                ColumnVectorData<bool>& col
    00620                                        = dynamic_cast<ColumnVectorData<bool>&>(*this);
    00621                                if (!isRead()) col.readRow(row,&nullVal);
    00622                                FITSUtil::fill(vals,col.data(row));
    00623                }
    00624                else if (type() == Tbit || type() == Tbyte ||
    00625                                type() == VTbit || type() == VTbyte )
    00626                {
    00627                                unsigned char nullVal(0);
    00628                                if (nullValue) nullVal
    00629                                            = static_cast<unsigned char>(*nullValue);
    00630                                ColumnVectorData<unsigned char>& col
    00631                                      = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
    00632                                if (!isRead()) col.readRow(row,&nullVal);
    00633                                FITSUtil::fill(vals,col.data(row));
    00634                        }
    00635                else if (type() == Tushort || type() == VTushort)
    00636                        {
    00637                                unsigned short nullVal(0);
    00638                                if (nullValue) nullVal
    00639                                            = static_cast<unsigned short>(*nullValue);
    00640                                ColumnVectorData<unsigned short>& col
    00641                                      = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
    00642                                if (!isRead()) col.readRow(row,&nullVal);
    00643                                FITSUtil::fill(vals,col.data(row));
    00644                        }
    00645                else if (type() == Tuint || type() == VTuint)
    00646                        {
    00647                                unsigned int nullVal(0);
    00648                                if (nullValue) nullVal
    00649                                            = static_cast<unsigned int>(*nullValue);
    00650                                ColumnVectorData<unsigned int>& col
    00651                                      = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
    00652                                if (!isRead()) col.readRow(row,&nullVal);
    00653                                FITSUtil::fill(vals,col.data(row));
    00654                }
    00655                else if (type() == Tulong || type() == VTulong)
    00656                        {
    00657                                unsigned long nullVal(0);
    00658                                if (nullValue) nullVal
    00659                                            = static_cast<unsigned long>(*nullValue);
    00660                                ColumnVectorData<unsigned long>& col
    00661                                        = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
    00662                                if (!isRead()) col.readRow(row,&nullVal);
    00663                                FITSUtil::fill(vals,col.data(row));
    00664                        }
    00665                else
    00666                        {
    00667                                throw InvalidDataType(name());
    00668
    00669                        }
    00670
    00671                    }
    00672                    catch (std::bad_cast&)
    00673                    {
    00674                        throw WrongColumnType(name());
    00675                    }
    00676             }
    00677    }
    00678
    00679    template <typename S>
    00680    void Column::readArrays(std::vector<std::valarray<S> >& vals, long first, long last)
    00681    {
    00682            readArrays(vals,first,last,static_cast<S*>(0));
    00683    }
    00684
    00685    template <typename S>
    00686    void Column::readArrays(std::vector<std::valarray<S> >& vals,
    00687                            long first, long last, S* nullValue)
    00688    {
    00689
    00690            parent()->makeThisCurrent();
    00691            // again, can only call this if the entire column has been read from disk.
    00692            // user expects 1 based indexing. If 0 based indices are supplied,
    00693            // add one to both ranges.
    00694            long range = numberOfElements(first,last);
    00695
    00696            vals.resize(range);
    00697
    00698
    00699            if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
    00700            {
    00701                    for (int j = 0; j < range; ++j)
    00702                    {
    00703                            if (!isRead()) col->readRow(j + first,nullValue);
    00704                            FITSUtil::fill(vals[j],col->data(j+first));
    00705                    }
    00706            }
    00707            else
    00708            {
    00709                    FITSUtil::MatchType<S> outputType;
    00710                    if ( outputType() == type() )
    00711                    {
    00712                            // in this case user tried to read vector data from scalar,
    00713                            // (i.e. first argument was vector<valarray<S> >.
    00714                            // since the cast won't fail on template parameter grounds.
    00715                            throw Column::WrongColumnType(name());
    00716                    }
    00717                    // the InvalidDataType exception should not be possible.
    00718                    try
    00719                    {
    00720                        if  ( type() == Tdouble || type() == VTdouble )
    00721                {
    00722                                ColumnVectorData<double>& col
    00723                                        = dynamic_cast<ColumnVectorData<double>&>(*this);
    00724                                for (int j = 0; j < range; ++j)
    00725                                {
    00726                                    if (!isRead()) col.readRow(j + first);
    00727                                    FITSUtil::fill(vals[j],col.data(j+first));
    00728                                }
    00729                        }
    00730                        else if  ( type() == Tfloat || type() == VTfloat  )
    00731                {
    00732                                ColumnVectorData<float>& col
    00733                                        = dynamic_cast<ColumnVectorData<float>&>(*this);
    00734                                for (int j = 0; j < range; ++j)
    00735                                {
    00736                                    if (!isRead()) col.readRow(j + first);
    00737                                    FITSUtil::fill(vals[j],col.data(j+first));
    00738                                }
    00739                        }
    00740                        else if  ( type() == Tint   || type() == VTint )
    00741                {
    00742                                int nullVal(0);
    00743                                if (nullValue) nullVal  = static_cast<int>(*nullValue);
    00744                                ColumnVectorData<int>& col
    00745                                        = dynamic_cast<ColumnVectorData<int>&>(*this);
    00746                                for (int j = 0; j < range; ++j)
    00747                                {
    00748                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00749                                    FITSUtil::fill(vals[j],col.data(j+first));
    00750                                }
    00751                        }
    00752                        else if  ( type() == Tshort  || type() == VTshort )
    00753                {
    00754                                short nullVal(0);
    00755                                if (nullValue) nullVal  = static_cast<short>(*nullValue);
    00756                                ColumnVectorData<short>& col
    00757                                        = dynamic_cast<ColumnVectorData<short>&>(*this);
    00758                                for (int j = 0; j < range; ++j)
    00759                                {
    00760                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00761                                    FITSUtil::fill(vals[j],col.data(j+first));
    00762                                }
    00763                        }
    00764                        else if  ( type() == Tlong   || type() == VTlong )
    00765                {
    00766                                long nullVal(0);
    00767                                if (nullValue) nullVal  = static_cast<long>(*nullValue);
    00768                                ColumnVectorData<long>& col
    00769                                        = dynamic_cast<ColumnVectorData<long>&>(*this);
    00770                                for (int j = 0; j < range; ++j)
    00771                                {
    00772                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00773                                    FITSUtil::fill(vals[j],col.data(j+first));
    00774                                }
    00775                        }
    00776                        else if  ( type() == Tlonglong   || type() == VTlonglong )
    00777                {
    00778                                LONGLONG nullVal(0);
    00779                                if (nullValue) nullVal  = static_cast<LONGLONG>(*nullValue);
    00780                                ColumnVectorData<LONGLONG>& col
    00781                                        = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
    00782                                for (int j = 0; j < range; ++j)
    00783                                {
    00784                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00785                                    FITSUtil::fill(vals[j],col.data(j+first));
    00786                                }
    00787                        }
    00788                        else if  ( type() == Tlogical   || type() == VTlogical )
    00789                {
    00790                                bool nullVal(0);
    00791                                if (nullValue) nullVal   = static_cast<bool>(*nullValue);
    00792                                ColumnVectorData<bool>& col
    00793                                        = dynamic_cast<ColumnVectorData<bool>&>(*this);
    00794                                for (int j = 0; j < range; ++j)
    00795                                {
    00796                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00797                                    FITSUtil::fill(vals[j],col.data(j+first));
    00798                                }
    00799                        }
    00800                else if (type() == Tbit || type() == Tbyte ||
    00801                                type() == VTbit || type() == VTbyte )
    00802                {
    00803                                unsigned char nullVal(0);
    00804                                if (nullValue) nullVal
    00805                                            = static_cast<unsigned char>(*nullValue);
    00806                                ColumnVectorData<unsigned char>& col
    00807                                       = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
    00808                                for (int j = 0; j < range; ++j)
    00809                                {
    00810                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00811                                    FITSUtil::fill(vals[j],col.data(j+first));
    00812                    }
    00813                        }
    00814                        else if  ( type() == Tushort   || type() == VTushort )
    00815                {
    00816                                unsigned short nullVal(0);
    00817                                if (nullValue) nullVal
    00818                                            = static_cast<unsigned short>(*nullValue);
    00819                                ColumnVectorData<unsigned short>& col
    00820                                    = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
    00821                                for (int j = 0; j < range; ++j)
    00822                                {
    00823                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00824                                    FITSUtil::fill(vals[j],col.data(j+first));
    00825                                }
    00826                        }
    00827                        else if  ( type() == Tuint   || type() == VTuint )
    00828                {
    00829                                unsigned int nullVal(0);
    00830                                if (nullValue) nullVal
    00831                                            = static_cast<unsigned int>(*nullValue);
    00832                                ColumnVectorData<unsigned int>& col
    00833                                        = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
    00834                                for (int j = 0; j < range; ++j)
    00835                                {
    00836                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00837                                    FITSUtil::fill(vals[j],col.data(j+first));
    00838                                }
    00839                        }
    00840                        else if  ( type() == Tulong   || type() == VTulong  )
    00841                {
    00842                                unsigned long nullVal(0);
    00843                                if (nullValue) nullVal
    00844                                            = static_cast<unsigned long>(*nullValue);
    00845                                ColumnVectorData<unsigned long>& col
    00846                                      = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
    00847                                for (int j = 0; j < range; ++j)
    00848                                {
    00849                                    if (!isRead()) col.readRow(j + first,&nullVal);
    00850                                    FITSUtil::fill(vals[j],col.data(j+first));
    00851                                }
    00852                        }
    00853                        else
    00854                        {
    00855                                throw InvalidDataType(name());
    00856                        }
    00857
    00858                    }
    00859                    catch (std::bad_cast&)
    00860                    {
    00861                        throw WrongColumnType(name());
    00862
    00863                    }
    00864
    00865            }
    00866    }
    00867
    00868    template <typename S>
    00869    void Column::write (const std::vector<S>& indata, long firstRow)
    00870    {
    00871       // nullValue is now a pointer, so this is ok.
    00872       // got to cast the 0 to a pointer to S to avoid
    00873       // overloading ambiguities.
    00874       write(indata,firstRow,static_cast<S*>(0));
    00875    }
    00876
    00877    template <typename S>
    00878    void Column::write (const std::valarray<S>& indata, long firstRow)
    00879    {
    00880       size_t n(indata.size());
    00881       std::vector<S> __tmp(n);
    00882       for (size_t j = 0; j < n; ++j) __tmp[j] = indata[j];
    00883       write(__tmp,firstRow,static_cast<S*>(0));
    00884    }
    00885
    00886    template <typename S>
    00887    void Column::write (S* indata, long nRows, long firstRow)
    00888    {
    00889       write(indata,nRows,firstRow,static_cast<S*>(0));
    00890    }
    00891
    00892
    00893    template <typename S>
    00894    void Column::write (const std::vector<S>& indata, long firstRow, S* nullValue)
    00895    {
    00896       // although underlying code needs to convert the input vector
    00897       // into a C array, this must be the underlying implementation
    00898       // [which the others call] because it accepts string arguments
    00899       // which the version with a pointer won't. [no version that
    00900       // translates to a char** argument].
    00901
    00902
    00903       parent()->makeThisCurrent();
    00904       firstRow = std::max(firstRow,static_cast<long>(1));
    00905       if (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
    00906       {
    00907          col->writeData(indata,firstRow,nullValue);
    00908       }
    00909       else
    00910       {
    00911          // alright, input data type has to be rewritten as output
    00912          // data type.
    00913          FITSUtil::MatchType<S> inType;
    00914          if ( inType() == type())
    00915          {
    00916                  String msg("Incorrect call: writing to vector column ");
    00917                  msg += name();
    00918                  msg += " requires specification of # rows or vector lengths";
    00919                  throw WrongColumnType(msg);
    00920          }
    00921          else
    00922          {
    00923              if  ( type() == Tdouble )
    00924          {
    00925                  ColumnData<double>& col
    00926                          = dynamic_cast<ColumnData<double>&>(*this);
    00927                  std::vector<double> __tmp;
    00928                  FITSUtil::fill(__tmp,indata,1,indata.size());
    00929                  col.writeData(__tmp,firstRow);
    00930              }
    00931              else if  ( type() == Tfloat )
    00932          {
    00933                  ColumnData<float>& col
    00934                          = dynamic_cast<ColumnData<float>&>(*this);
    00935                  std::vector<float> __tmp;
    00936                  FITSUtil::fill(__tmp,indata,1,indata.size());
    00937                  col.writeData(__tmp,firstRow);
    00938              }
    00939              else if  ( type() == Tint )
    00940          {
    00941                  int nullVal = 0;
    00942                  int* pNullVal = 0;
    00943                  if (nullValue)
    00944                  {
    00945                     nullVal = static_cast<int>(*nullValue);
    00946                     pNullVal = &nullVal;
    00947                  }
    00948                  if (nullValue) nullVal = static_cast<int>(*nullValue);
    00949                  ColumnData<int>& col
    00950                          = dynamic_cast<ColumnData<int>&>(*this);
    00951                  std::vector<int> __tmp;
    00952                  FITSUtil::fill(__tmp,indata,1,indata.size());
    00953                  col.writeData(__tmp,firstRow,pNullVal);
    00954              }
    00955              else if  ( type() == Tshort )
    00956          {
    00957                  short nullVal(0);
    00958                  short* pNullVal = 0;
    00959                  if (nullValue)
    00960                  {
    00961                     nullVal = static_cast<short>(*nullValue);
    00962                     pNullVal = &nullVal;
    00963                  }
    00964                  ColumnData<short>& col
    00965                          = dynamic_cast<ColumnData<short>&>(*this);
    00966                  std::vector<short> __tmp;
    00967                  FITSUtil::fill(__tmp,indata,1,indata.size());
    00968                  col.writeData(__tmp,firstRow,pNullVal);
    00969              }
    00970              else if  ( type() == Tlong )
    00971          {
    00972                  long nullVal(0);
    00973                  long* pNullVal = 0;
    00974                  if (nullValue)
    00975                  {
    00976                     nullVal = static_cast<long>(*nullValue);
    00977                     pNullVal = &nullVal;
    00978                  }
    00979                  ColumnData<long>& col
    00980                          = dynamic_cast<ColumnData<long>&>(*this);
    00981                  std::vector<long> __tmp;
    00982                  FITSUtil::fill(__tmp,indata,1,indata.size());
    00983                  col.writeData(__tmp,firstRow,pNullVal);
    00984              }
    00985              else if  ( type() == Tlonglong )
    00986          {
    00987                  LONGLONG nullVal(0);
    00988                  LONGLONG* pNullVal = 0;
    00989                  if (nullValue)
    00990                  {
    00991                     nullVal = static_cast<LONGLONG>(*nullValue);
    00992                     pNullVal = &nullVal;
    00993                  }
    00994                  ColumnData<LONGLONG>& col
    00995                          = dynamic_cast<ColumnData<LONGLONG>&>(*this);
    00996                  std::vector<LONGLONG> __tmp;
    00997                  FITSUtil::fill(__tmp,indata,1,indata.size());
    00998                  col.writeData(__tmp,firstRow,pNullVal);
    00999              }
    01000              else if  ( type() == Tlogical )
    01001          {
    01002                  bool nullVal(0);
    01003                  bool* pNullVal = 0;
    01004                  if (nullValue)
    01005                  {
    01006                     nullVal = static_cast<bool>(*nullValue);
    01007                     pNullVal = &nullVal;
    01008                  }
    01009                  ColumnData<bool>& col
    01010                          = dynamic_cast<ColumnData<bool>&>(*this);
    01011                  std::vector<bool> __tmp;
    01012                  FITSUtil::fill(__tmp,indata,1,indata.size());
    01013                  col.writeData(__tmp,firstRow,pNullVal);
    01014              }
    01015              else if  ( type() == Tbyte )
    01016          {
    01017                  unsigned char nullVal(0);
    01018                  unsigned char* pNullVal = 0;
    01019                  if (nullValue)
    01020                  {
    01021                     nullVal = static_cast<unsigned char>(*nullValue);
    01022                     pNullVal = &nullVal;
    01023                  }
    01024                  ColumnData<unsigned char>& col
    01025                          = dynamic_cast<ColumnData<unsigned char>&>(*this);
    01026                  std::vector<unsigned char> __tmp;
    01027                  FITSUtil::fill(__tmp,indata,1,indata.size());
    01028                  col.writeData(__tmp,firstRow,pNullVal);
    01029              }
    01030              else if  ( type() == Tushort )
    01031          {
    01032                  unsigned short nullVal(0);
    01033                  unsigned short* pNullVal = 0;
    01034                  if (nullValue)
    01035                  {
    01036                     nullVal = static_cast<unsigned short>(*nullValue);
    01037                     pNullVal = &nullVal;
    01038                  }
    01039                  ColumnData<unsigned short>& col
    01040                          = dynamic_cast<ColumnData<unsigned short>&>(*this);
    01041                  std::vector<unsigned short> __tmp;
    01042                  FITSUtil::fill(__tmp,indata,1,indata.size());
    01043                  col.writeData(__tmp,firstRow,pNullVal);
    01044              }
    01045              else if  ( type() == Tuint )
    01046          {
    01047                  unsigned int nullVal(0);
    01048                  unsigned int* pNullVal = 0;
    01049                  if (nullValue)
    01050                  {
    01051                     nullVal = static_cast<unsigned int>(*nullValue);
    01052                     pNullVal = &nullVal;
    01053                  }
    01054                  ColumnData<unsigned int>& col
    01055                          = dynamic_cast<ColumnData<unsigned int>&>(*this);
    01056                  std::vector<unsigned int> __tmp;
    01057                  FITSUtil::fill(__tmp,indata,1,indata.size());
    01058                  col.writeData(__tmp,firstRow,pNullVal);
    01059              }
    01060              else if  ( type() == Tulong )
    01061          {
    01062                  unsigned long nullVal(0);
    01063                  unsigned long* pNullVal = 0;
    01064                  if (nullValue)
    01065                  {
    01066                     nullVal = static_cast<unsigned long>(*nullValue);
    01067                     pNullVal = &nullVal;
    01068                  }
    01069                  ColumnData<unsigned long>& col
    01070                          = dynamic_cast<ColumnData<unsigned long>&>(*this);
    01071                  std::vector<unsigned long> __tmp;
    01072                  FITSUtil::fill(__tmp,indata,1,indata.size());
    01073                  col.writeData(__tmp,firstRow,pNullVal);
    01074              }
    01075              else
    01076              {
    01077                      throw InvalidDataType(name());
    01078              }
    01079          }
    01080       }
    01081    }
    01082
    01083
    01084    template <typename S>
    01085    void Column::write (const std::valarray<S>& indata, long firstRow, S* nullValue)
    01086    {
    01087       // for scalar columns.
    01088       std::vector<S> __tmp;
    01089       FITSUtil::fill(__tmp,indata);
    01090       write(__tmp,firstRow,nullValue);
    01091    }
    01092
    01093    template <typename S>
    01094    void Column::write (S* indata, long nRows, long firstRow, S* nullValue)
    01095    {
    01096       // for scalar columns, data specified with C array
    01097       if (nRows <= 0) throw InvalidNumberOfRows(nRows);
    01098       std::vector<S> __tmp(nRows);
    01099       std::copy(&indata[0],&indata[nRows],__tmp.begin());
    01100       write(__tmp,firstRow, nullValue);
    01101
    01102    }
    01103
    01104    template <typename S>
    01105    void Column::write (const std::valarray<S>& indata, const std::vector<long>& vectorLengths,
    01106                            long firstRow)
    01107    {
    01108       // variable length arrays written from an input valarray.
    01109       // does not allow NULL value.
    01110
    01111       using namespace std;
    01112       const size_t nRows = vectorLengths.size();
    01113       // Calculate the sums of the vector lengths first simply to do a
    01114       //   check against the size of indata.
    01115       vector<long> sums(nRows+1);
    01116       sums[0] = 0;
    01117       vector<long>::iterator itSums = sums.begin() + 1;
    01118       partial_sum(vectorLengths.begin(), vectorLengths.end(), itSums);
    01119       if (indata.size() < static_cast<size_t>(sums[nRows]))
    01120       {
    01121 #ifdef SSTREAM_DEFECT
    01122          ostrstream msgStr;
    01123 #else
    01124          ostringstream msgStr;
    01125 #endif
    01126          msgStr << " input data size: " << indata.size() << " vector length sum: " << sums[nRows];
    01127 #ifdef SSTREAM_DEFECT
    01128          msgStr << std::ends;
    01129 #endif
    01130
    01131          String msg(msgStr.str());
    01132          throw Column::InsufficientElements(msg);
    01133       }
    01134       vector<valarray<S> > vvArray(nRows);
    01135       for (size_t iRow=0; iRow<nRows; ++iRow)
    01136       {
    01137          valarray<S>& vArray = vvArray[iRow];
    01138          long first = sums[iRow];
    01139          long last = sums[iRow+1];
    01140          vArray.resize(last - first);
    01141          for (long iElem=first; iElem<last; ++iElem)
    01142          {
    01143             vArray[iElem - first] = indata[iElem];
    01144          }
    01145       }
    01146       writeArrays(vvArray, firstRow, static_cast<S*>(0));
    01147    }
    01148
    01149 template <typename S>
    01150 void Column::write (const std::vector<S>& indata,const std::vector<long>& vectorLengths,
    01151                       long firstRow)
    01152    {
    01153       // variable length write
    01154       // implement as valarray version
    01155       std::valarray<S> __tmp(indata.size());
    01156       std::copy(indata.begin(),indata.end(),&__tmp[0]);
    01157       write(__tmp,vectorLengths,firstRow);
    01158
    01159    }
    01160
    01161    template <typename S>
    01162    void Column::write (S* indata, long nelements, const std::vector<long>& vectorLengths,
    01163                                    long firstRow)
    01164    {
    01165       // implement as valarray version, which will also check array size.
    01166       std::valarray<S> __tmp(indata,nelements);
    01167       write(__tmp,vectorLengths,firstRow);
    01168    }
    01169
    01170    template <typename S>
    01171    void Column::write (const std::valarray<S>& indata, long nRows, long firstRow)
    01172    {
    01173       write(indata,nRows,firstRow,static_cast<S*>(0));
    01174    }
    01175
    01176    template <typename S>
    01177    void Column::write (const std::vector<S>& indata, long nRows, long firstRow)
    01178    {
    01179       write(indata,nRows,firstRow,static_cast<S*>(0));
    01180    }
    01181
    01182    template <typename S>
    01183    void Column::write (S* indata, long nelements, long nRows, long firstRow)
    01184    {
    01185       write(indata,nelements,nRows,firstRow,static_cast<S*>(0));
    01186    }
    01187
    01188
    01189
    01190    template <typename S>
    01191    void Column::write (const std::valarray<S>& indata, long nRows, long firstRow,
    01192                            S* nullValue)
    01193    {
    01194       // Write equivalent lengths of data to rows of a vector column.
    01195       // The column may be either fixed or variable width, but if it's fixed
    01196       // width the lengths must equal the column's repeat value or an
    01197       // exception is thrown.
    01198       if (nRows <= 0)
    01199          throw InvalidNumberOfRows(nRows);
    01200       firstRow = std::max(firstRow,static_cast<long>(1));
    01201 #ifdef SSTREAM_DEFECT
    01202       std::ostrstream msgStr;
    01203 #else
    01204       std::ostringstream msgStr;
    01205 #endif
    01206       const size_t numRows = static_cast<size_t>(nRows);
    01207       if (indata.size() % numRows)
    01208       {
    01209          msgStr << "To use this write function, input array size"
    01210             <<"\n must be exactly divisible by requested num rows: "
    01211             << nRows;
    01212          throw InsufficientElements(msgStr.str());
    01213       }
    01214
    01215       const size_t cellsize = indata.size()/numRows;
    01216       if (!varLength() && cellsize != repeat() )
    01217       {
    01218          msgStr << "column: " << name()
    01219                 <<  "\n input data size: " << indata.size()
    01220                 << " required: " << nRows*repeat();
    01221          String msg(msgStr.str());
    01222          throw InsufficientElements(msg);
    01223       }
    01224
    01225       std::vector<std::valarray<S> > vvArray(numRows);
    01226       for (size_t i=0; i<numRows; ++i)
    01227       {
    01228          vvArray[i].resize(cellsize);
    01229          vvArray[i] = indata[std::slice(cellsize*i,cellsize,1)];
    01230       }
    01231       writeArrays(vvArray, firstRow, nullValue);
    01232    }
    01233
    01234    template <typename S>
    01235    void Column::write (const std::vector<S>& indata, long nRows, long firstRow, S* nullValue)
    01236    {
    01237       // fixed length write of vector
    01238       // implement as valarray version
    01239       if (nRows <= 0) throw InvalidNumberOfRows(nRows);
    01240       std::valarray<S> __tmp(indata.size());
    01241       std::copy(indata.begin(),indata.end(),&__tmp[0]);
    01242       write(__tmp,nRows,firstRow, nullValue);
    01243    }
    01244
    01245    template <typename S>
    01246    void Column::write (S* indata, long nelements, long nRows, long firstRow, S* nullValue)
    01247    {
    01248       // fixed length write of C-array
    01249       // implement as valarray version
    01250       if (nRows <= 0) throw InvalidNumberOfRows(nRows);
    01251       std::valarray<S> __tmp(indata,nelements);
    01252       write(__tmp,nRows,firstRow, nullValue);
    01253    }
    01254
    01255
    01256    template <typename S>
    01257    void Column::writeArrays (const std::vector<std::valarray<S> >& indata, long firstRow)
    01258    {
    01259       // vector<valarray>, no null value.
    01260       writeArrays(indata,firstRow,static_cast<S*>(0));
    01261    }
    01262
    01263    template <typename S>
    01264    void Column::writeArrays (const std::vector<std::valarray<S> >& indata, long firstRow,
    01265                                    S* nullValue)
    01266    {
    01267       // vector<valarray>, null value. primary
    01268
    01269
    01270       using std::valarray;
    01271       using std::vector;
    01272       parent()->makeThisCurrent();
    01273       firstRow = std::max(firstRow,static_cast<long>(1));
    01274       if (ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
    01275       {
    01276           col->writeData(indata,firstRow,nullValue);
    01277       }
    01278       else
    01279       {
    01280          // alright, input data type has to be rewritten as output
    01281          // data type.
    01282          FITSUtil::MatchType<S> inType;
    01283          if ( inType() == type())
    01284          {
    01285                  String msg("Incorrect call: writing vectors to scalar column ");
    01286                  throw WrongColumnType(msg);
    01287          }
    01288          else
    01289          {
    01290              size_t n(indata.size());
    01291              if  ( type() == Tdouble || type() == VTdouble)
    01292          {
    01293                  ColumnVectorData<double>& col
    01294                          = dynamic_cast<ColumnVectorData<double>&>(*this);
    01295                  vector<valarray<double> > __tmp(n);
    01296                  for (size_t i = 0; i < n; ++i)
    01297                  {
    01298                          FITSUtil::fill(__tmp[i],indata[i]);
    01299                  }
    01300                  col.writeData(__tmp,firstRow);
    01301              }
    01302              else if  ( type() == Tfloat || type() == VTfloat)
    01303          {
    01304                  ColumnVectorData<float>& col
    01305                          = dynamic_cast<ColumnVectorData<float>&>(*this);
    01306                  vector<valarray<float> > __tmp(n);
    01307                  for (size_t i = 0; i < n; ++i)
    01308                  {
    01309                          FITSUtil::fill(__tmp[i],indata[i]);
    01310                  }
    01311                  col.writeData(__tmp,firstRow);
    01312              }
    01313              else if  ( type() == Tint || type() == VTint)
    01314          {
    01315                  ColumnVectorData<int>& col
    01316                          = dynamic_cast<ColumnVectorData<int>&>(*this);
    01317                  vector<valarray<int> > __tmp(n);
    01318                  int nullVal(0);
    01319                  int* pNullVal = 0;
    01320                  if (nullValue)
    01321                  {
    01322                     nullVal = static_cast<int>(*nullValue);
    01323                     pNullVal = &nullVal;
    01324                  }
    01325                  for (size_t i = 0; i < n; ++i)
    01326                  {
    01327                          FITSUtil::fill(__tmp[i],indata[i]);
    01328                  }
    01329                  col.writeData(__tmp,firstRow,pNullVal);
    01330              }
    01331              else if  ( type() == Tshort || type() == VTshort)
    01332          {
    01333                  ColumnVectorData<short>& col
    01334                          = dynamic_cast<ColumnVectorData<short>&>(*this);
    01335                  vector<valarray<short> > __tmp(n);
    01336                  short nullVal(0);
    01337                  short* pNullVal = 0;
    01338                  if (nullValue)
    01339                  {
    01340                     nullVal = static_cast<short>(*nullValue);
    01341                     pNullVal = &nullVal;
    01342                  }
    01343                  for (size_t i = 0; i < n; ++i)
    01344                  {
    01345                          FITSUtil::fill(__tmp[i],indata[i]);
    01346                  }
    01347                  col.writeData(__tmp,firstRow,pNullVal);
    01348              }
    01349              else if  ( type() == Tlong || type() == VTlong)
    01350          {
    01351                  ColumnVectorData<long>& col
    01352                          = dynamic_cast<ColumnVectorData<long>&>(*this);
    01353                  vector<valarray<long> > __tmp(n);
    01354                  long nullVal(0);
    01355                  long* pNullVal = 0;
    01356                  if (nullValue)
    01357                  {
    01358                     nullVal = static_cast<long>(*nullValue);
    01359                     pNullVal = &nullVal;
    01360                  }
    01361                  for (size_t i = 0; i < n; ++i)
    01362                  {
    01363                          FITSUtil::fill(__tmp[i],indata[i]);
    01364                  }
    01365                  col.writeData(__tmp,firstRow,pNullVal);
    01366              }
    01367              else if  ( type() == Tlonglong || type() == VTlonglong)
    01368          {
    01369                  ColumnVectorData<LONGLONG>& col
    01370                          = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
    01371                  vector<valarray<LONGLONG> > __tmp(n);
    01372                  LONGLONG nullVal(0);
    01373                  LONGLONG* pNullVal = 0;
    01374                  if (nullValue)
    01375                  {
    01376                     nullVal = static_cast<LONGLONG>(*nullValue);
    01377                     pNullVal = &nullVal;
    01378                  }
    01379                  for (size_t i = 0; i < n; ++i)
    01380                  {
    01381                          FITSUtil::fill(__tmp[i],indata[i]);
    01382                  }
    01383                  col.writeData(__tmp,firstRow,pNullVal);
    01384              }
    01385              else if  ( type() == Tlogical || type() == VTlogical)
    01386          {
    01387                  ColumnVectorData<bool>& col
    01388                          = dynamic_cast<ColumnVectorData<bool>&>(*this);
    01389                  bool nullVal(0);
    01390                  bool* pNullVal = 0;
    01391                  if (nullValue)
    01392                  {
    01393                     nullVal = static_cast<bool>(*nullValue);
    01394                     pNullVal = &nullVal;
    01395                  }
    01396                  vector<valarray<bool> > __tmp(n);
    01397                  for (size_t i = 0; i < n; ++i)
    01398                  {
    01399                          FITSUtil::fill(__tmp[i],indata[i]);
    01400                  }
    01401                  col.writeData(__tmp,firstRow,pNullVal);
    01402              }
    01403              else if  ( type() == Tbyte || type() == VTbyte)
    01404          {
    01405                  ColumnVectorData<unsigned char>& col
    01406                          = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
    01407                  unsigned char nullVal(0);
    01408                  unsigned char* pNullVal = 0;
    01409                  if (nullValue)
    01410                  {
    01411                     nullVal = static_cast<unsigned char>(*nullValue);
    01412                     pNullVal = &nullVal;
    01413                  }
    01414                  vector<valarray<unsigned char> > __tmp(n);
    01415                  for (size_t i = 0; i < n; ++i)
    01416                  {
    01417                          FITSUtil::fill(__tmp[i],indata[i]);
    01418                  }
    01419                  col.writeData(__tmp,firstRow,pNullVal);
    01420              }
    01421              else if  ( type() == Tushort || type() == VTushort)
    01422          {
    01423                  ColumnVectorData<unsigned short>& col
    01424                          = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
    01425                  unsigned short nullVal(0);
    01426                  unsigned short* pNullVal = 0;
    01427                  if (nullValue)
    01428                  {
    01429                     nullVal = static_cast<unsigned short>(*nullValue);
    01430                     pNullVal = &nullVal;
    01431                  }
    01432                  vector<valarray<unsigned short> > __tmp(n);
    01433                  for (size_t i = 0; i < n; ++i)
    01434                  {
    01435                          FITSUtil::fill(__tmp[i],indata[i]);
    01436                  }
    01437                  col.writeData(__tmp,firstRow,pNullVal);
    01438              }
    01439              else if  ( type() == Tuint || type() == VTuint)
    01440          {
    01441                  ColumnVectorData<unsigned int>& col
    01442                          = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
    01443                  unsigned int nullVal(0);
    01444                  unsigned int* pNullVal = 0;
    01445                  if (nullValue)
    01446                  {
    01447                     nullVal = static_cast<unsigned int>(*nullValue);
    01448                     pNullVal = &nullVal;
    01449                  }
    01450                  vector<valarray<unsigned int> > __tmp(n);
    01451                  for (size_t i = 0; i < n; ++i)
    01452                  {
    01453                          FITSUtil::fill(__tmp[i],indata[i]);
    01454                  }
    01455                  col.writeData(__tmp,firstRow,pNullVal);
    01456              }
    01457              else if  ( type() == Tulong || type() == VTulong)
    01458          {
    01459                  ColumnVectorData<unsigned long>& col
    01460                          = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
    01461                  unsigned long nullVal(0);
    01462                  unsigned long* pNullVal = 0;
    01463                  if (nullValue)
    01464                  {
    01465                     nullVal = static_cast<unsigned long>(*nullValue);
    01466                     pNullVal = &nullVal;
    01467                  }
    01468                  vector<valarray<unsigned long> > __tmp(n);
    01469                  for (size_t i = 0; i < n; ++i)
    01470                  {
    01471                          FITSUtil::fill(__tmp[i],indata[i]);
    01472                  }
    01473                  col.writeData(__tmp,firstRow,pNullVal);
    01474              }
    01475              else
    01476              {
    01477                      throw InvalidDataType(name());
    01478              }
    01479          }
    01480       }
    01481    }
    01482
    01483
    01484    template <typename T>
    01485    void Column::addNullValue(T nullVal)
    01486    {
    01487       parent()->makeThisCurrent();
    01488       int status(0);
    01489 #ifdef SSTREAM_DEFECT
    01490       std::ostrstream keyName;
    01491       keyName << "TNULL" << index() << std::ends;
    01492       char* nullKey = const_cast<char*>(keyName.str());
    01493 #else
    01494       std::ostringstream keyName;
    01495       keyName << "TNULL" << index();
    01496       String keyNameStr = keyName.str();
    01497       char* nullKey = const_cast<char*>(keyNameStr.c_str());
    01498 #endif
    01499
    01500
    01501       FITSUtil::MatchType<T> inputType;
    01502       int dataType = static_cast<int>(inputType());
    01503       if (dataType == static_cast<int>(Tstring))
    01504          throw InvalidDataType("attempting to set TNULLn to a string.");
    01505
    01506       // update key but don't add to keyword list because it's really a column
    01507       // property not a table metadata property. And it needs to be automatically
    01508       // renumbered if columns are inserted or deleted.
    01509       if (fits_update_key(fitsPointer(),dataType,nullKey,&nullVal,0,&status))
    01510               throw FitsError(status);
    01511
    01512       // The following is called to make sure the HDU struct is immediately
    01513       // updated in case a column write operation is performed shortly after this
    01514       // function exits.
    01515       if (fits_set_hdustruc(fitsPointer(),&status)) throw FitsError(status);
    01516
    01517    }
    01518
    01519    template <typename T>
    01520    bool Column::getNullValue(T* nullVal) const
    01521    {
    01522       parent()->makeThisCurrent();
    01523 #ifdef SSTREAM_DEFECT
    01524       std::ostrstream keyName;
    01525       keyName << "TNULL" << index() << std::ends;
    01526       char* nullKey = const_cast<char*>(keyName.str());
    01527 #else
    01528       std::ostringstream keyName;
    01529       keyName << "TNULL" << index();
    01530       String keyNameStr = keyName.str();
    01531       char* nullKey = const_cast<char*>(keyNameStr.c_str());
    01532 #endif
    01533
    01534       int status=0;
    01535       FITSUtil::MatchType<T> inputType;
    01536       int dataType = static_cast<int>(inputType());
    01537       if (dataType == static_cast<int>(Tstring))
    01538          throw InvalidDataType("attempting to read TNULLn into a string.");
    01539       T tmpVal(*nullVal);
    01540
    01541       bool keyExists = false;
    01542       if (fits_read_key(m_parent->fitsPointer(), dataType, nullKey, &tmpVal, 0, &status))
    01543       {
    01544          if (status == KEY_NO_EXIST  || status == VALUE_UNDEFINED)
    01545             return keyExists;
    01546          else
    01547             throw FitsError(status);
    01548       }
    01549       keyExists = true;
    01550       *nullVal = tmpVal;
    01551       return keyExists;
    01552    }
    01553
    01554 } // namespace CCfits
    01555
    01556 #endif