ColumnT.h

00001 //1
00002 //2
00003 //3
00004 //4
00005 
00006 //      This is version 2.0 release dated Jan 2008
00007 
00008 //      Astrophysics Science Division,
00009 //      NASA/ Goddard Space Flight Center
00010 //      HEASARC
00011 //      http://heasarc.gsfc.nasa.gov
00012 //      e-mail: ccfits@legacy.gsfc.nasa.gov
00013 //
00014 //      Original author: Ben Dorman
00015 
00016 #ifndef COLUMNT_H
00017 #define COLUMNT_H
00018 
00019 #ifdef _MSC_VER
00020 #include "MSconfig.h"
00021 #endif
00022 
00023 #include "ColumnData.h"
00024 #include "ColumnVectorData.h"
00025 #include "FITSUtil.h"
00026 #include <typeinfo>
00027 #include <vector>
00028 #include <algorithm>
00029 #include "NewKeyword.h"
00030 
00031 #ifdef SSTREAM_DEFECT
00032 #       include <strstream>
00033 #else
00034 #       include <sstream>
00035 #endif
00036 
00037 
00038 // by design, if the data are not read yet we will return an exception.
00039 // here the test is if the entire column has already been read. 
00040 using std::complex;
00041 using std::valarray;
00042 
00043 // get specified elements of a scalar column. These two functions allow the
00044 // user to return either a vector or a valarray depending on the input container.
00045 
00046 namespace CCfits 
00047 {
00048         template <typename S>
00049         void Column::read(std::vector<S>& vals, long first, long last) 
00050         {
00051                 read(vals,first,last,static_cast<S*>(0));
00052         }
00053 
00054 
00055         template <typename S>
00056         void Column::read(std::vector<S>& vals, long first, long last, S* nullValue) 
00057         {
00058                 // problem: S does not give the type of the Column, but the return type,
00059                 // so the user must specify this.
00060                 parent()->makeThisCurrent();
00061                 long nelements = numberOfElements(first,last);
00062 
00063                 if  (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
00064                 {
00065                         // fails if user requested outputType different from input type.
00066 
00067 
00068                         if (!isRead()) col->readColumnData(first,nelements,nullValue);
00069                         // scalar column with vector output can just be assigned.
00070                         FITSUtil::fill(vals,col->data(),first,last);
00071                 }
00072                 else
00073                 {
00074                         FITSUtil::MatchType<S> outputType;
00075                         if ( outputType() == type() ) 
00076                         { 
00077                                 // in this case user tried to read vector data from scalar,
00078                                 // (i.e. first argument was vector<valarray<S> >.
00079                                 // since the cast won't fail on template parameter grounds.
00080                                 throw Column::WrongColumnType(name());
00081                         }
00082 
00083                         try
00084                         {
00085                             // about exceptions. The dynamic_casts could throw
00086                             // std::bad_cast. If this happens something is seriously
00087                             // wrong since the Column stores the value of type() 
00088                             // appropriate to each of the casts on construction.
00089                             // 
00090                             // the InvalidDataType exception should not be possible.
00091                             if  ( type() == Tdouble )
00092                             {
00093                                     ColumnData<double>& col 
00094                                               = dynamic_cast<ColumnData<double>&>(*this);
00095                                     if (!isRead()) col.readColumnData(first,nelements);                                  
00096                                     FITSUtil::fill(vals,col.data(),first,last);
00097 
00098                             }
00099                             else if (type() == Tfloat)
00100                             {
00101                                     ColumnData<float>& col 
00102                                             = dynamic_cast<ColumnData<float>&>(*this);
00103                                     if (!isRead()) col.readColumnData(first,nelements);                                  
00104                                     FITSUtil::fill(vals,col.data(),first,last);
00105                             }
00106                             else if (type() == Tint)
00107                             {
00108                                     int nullVal(0);
00109                                     if (nullValue) nullVal = static_cast<int>(*nullValue);
00110                                     ColumnData<int>& col  
00111                                        = dynamic_cast<ColumnData<int>&>(*this);
00112                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                  
00113                                     FITSUtil::fill(vals,col.data(),first,last);
00114                             }
00115                             else if (type() == Tshort)
00116                             {
00117                                     short nullVal(0);
00118                                     if (nullValue) nullVal = static_cast<short>(*nullValue);
00119                                     ColumnData<short>& col 
00120                                      = dynamic_cast<ColumnData<short>&>(*this);
00121                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                  
00122                                     FITSUtil::fill(vals,col.data(),first,last);
00123                             }
00124                             else if (type() == Tlong)
00125                             {   
00126                                     long nullVal(0);
00127                                     if (nullValue) nullVal = static_cast<long>(*nullValue); 
00128                                     ColumnData<long>& col 
00129                                       = dynamic_cast<ColumnData<long>&>(*this);
00130                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                  
00131                                     FITSUtil::fill(vals,col.data(),first,last);
00132                             }
00133                             else if (type() == Tlonglong)
00134                             {   
00135                                     LONGLONG nullVal(0);
00136                                     if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue); 
00137                                     ColumnData<LONGLONG>& col 
00138                                       = dynamic_cast<ColumnData<LONGLONG>&>(*this);
00139                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                  
00140                                     FITSUtil::fill(vals,col.data(),first,last);
00141                             }
00142                             else if (type() == Tlogical)
00143                             {   
00144                                     bool nullVal(0);
00145                                     if (nullValue) nullVal = static_cast<bool>(*nullValue); 
00146                                     ColumnData<bool>& col 
00147                                       = dynamic_cast<ColumnData<bool>&>(*this);
00148                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                  
00149                                     FITSUtil::fill(vals,col.data(),first,last);
00150                             }
00151                             else if (type() == Tbit || type() == Tbyte)
00152                             {
00153                                     unsigned char nullVal(0);
00154                                     if (nullValue) nullVal = static_cast<unsigned char>(*nullValue); 
00155                                     ColumnData<unsigned char>& col 
00156                                             = dynamic_cast<ColumnData<unsigned char>&>(*this);
00157                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal); 
00158                                     FITSUtil::fill(vals,col.data(),first,last);
00159                             }
00160                             else if (type() == Tushort)
00161                             {
00162                                     unsigned short nullVal(0);
00163                                     if (nullValue) nullVal= static_cast<unsigned short>(*nullValue);
00164                                     ColumnData<unsigned short>& col 
00165                                             = dynamic_cast<ColumnData<unsigned short>&>(*this);
00166                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                  
00167                                     FITSUtil::fill(vals,col.data(),first,last);
00168                             }
00169                             else if (type() == Tuint)
00170                             {
00171                                     unsigned int nullVal(0);
00172                                     if (nullValue) nullVal = static_cast<unsigned int>(*nullValue);
00173                                     ColumnData<unsigned int>& col 
00174                                             = dynamic_cast<ColumnData<unsigned int>&>(*this);
00175                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                  
00176                                     FITSUtil::fill(vals,col.data(),first,last);
00177                             }
00178                             else if (type() == Tulong)
00179                             {
00180                                     unsigned long nullVal(0);
00181                                     if (nullValue) nullVal = static_cast<unsigned long>(*nullValue);
00182                                     ColumnData<unsigned long>& col 
00183                                              = dynamic_cast<ColumnData<unsigned long>&>(*this);
00184                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                  
00185                                     FITSUtil::fill(vals,col.data(),first,last);
00186                             }
00187                             else
00188                             {
00189                                       throw InvalidDataType(name());
00190 
00191                             }
00192 
00193                         }
00194                         catch (std::bad_cast)
00195                         {
00196                                 throw WrongColumnType(name());
00197                         }
00198                 }
00199 
00200         }
00201 
00202         template <typename S>
00203         void Column::read(std::valarray<S>& vals, long first, long last) 
00204         {
00205                 read(vals,first,last,static_cast<S*>(0));
00206         }
00207 
00208 
00209         template <typename S>
00210         void Column::read(std::valarray<S>& vals, long first, long last, S* nullValue) 
00211         {        
00212                 // require the whole scalar column to have been read.
00213 
00214 
00215                 long nelements = numberOfElements(first,last);
00216                 parent()->makeThisCurrent();                
00217                 if ( ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
00218                 {
00219                         // fails if user requested outputType different from input type.
00220 
00221 
00222                         if (!isRead()) col->readColumnData(first,nelements,nullValue);                                  
00223                         FITSUtil::fill(vals,col->data(),first,last);
00224 
00225                 }
00226                 else
00227                 {
00228                         FITSUtil::MatchType<S> outputType;
00229                         if ( outputType() == type() ) 
00230                         { 
00231                                 // in this case user tried to read vector data from scalar,
00232                                 // (i.e. first argument was vector<valarray<S> >.
00233                                 // since the cast won't fail on template parameter grounds.
00234                                 throw Column::WrongColumnType(name());
00235                         }
00236 
00237                         try
00238                         {
00239                             // about exceptions. The dynamic_casts could throw
00240                             // std::bad_cast. If this happens something is seriously
00241                             // wrong since the Column stores the value of type() 
00242                             // appropriate to each of the casts on construction.
00243                             // 
00244                             // the InvalidDataType exception should not be possible.
00245                             if  ( type() == Tdouble )
00246                             {
00247                                     ColumnData<double>& col 
00248                                               = dynamic_cast<ColumnData<double>&>(*this);
00249                                     if (!isRead()) col.readColumnData(first,nelements);                                  
00250                                     FITSUtil::fill(vals,col.data(),first,last);
00251                             }
00252                             else if (type() == Tfloat)
00253                             {
00254                                     ColumnData<float>& col 
00255                                             = dynamic_cast<ColumnData<float>&>(*this);
00256                                     if (!isRead()) col.readColumnData(first,nelements);                                  
00257                                     FITSUtil::fill(vals,col.data(),first,last);
00258                             }
00259                             else if (type() == Tint)
00260                             {
00261                                     int nullVal(0);
00262                                     if (nullValue) nullVal = static_cast<int>(*nullValue); 
00263                                     ColumnData<int>& col  
00264                                             = dynamic_cast<ColumnData<int>&>(*this);
00265                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                    
00266                                     FITSUtil::fill(vals,col.data(),first,last);
00267                             }
00268                             else if (type() == Tshort)
00269                             {
00270                                     short nullVal(0);
00271                                     if (nullValue) nullVal = static_cast<short>(*nullValue); 
00272                                     ColumnData<short>& col 
00273                                             = dynamic_cast<ColumnData<short>&>(*this);
00274                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                    
00275                                     FITSUtil::fill(vals,col.data(),first,last);
00276                             }
00277                             else if (type() == Tlong)
00278                             {   
00279                                     long nullVal(0);
00280                                     if (nullValue) nullVal = static_cast<long>(*nullValue); 
00281                                     ColumnData<long>& col 
00282                                             = dynamic_cast<ColumnData<long>&>(*this);
00283                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);
00284                                     FITSUtil::fill(vals,col.data(),first,last);
00285                             }
00286                             else if (type() == Tlonglong)
00287                             {   
00288                                     LONGLONG nullVal(0);
00289                                     if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue); 
00290                                     ColumnData<LONGLONG>& col 
00291                                             = dynamic_cast<ColumnData<LONGLONG>&>(*this);
00292                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);
00293                                     FITSUtil::fill(vals,col.data(),first,last);
00294                             }
00295                             else if (type() == Tlogical)
00296                             {   
00297                                     bool nullVal(0);
00298                                     if (nullValue) nullVal = static_cast<bool>(*nullValue); 
00299                                     ColumnData<bool>& col 
00300                                             = dynamic_cast<ColumnData<bool>&>(*this);
00301                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                    
00302                                     FITSUtil::fill(vals,col.data(),first,last);
00303                             }
00304                             else if (type() == Tbit || type() == Tbyte)
00305                             {
00306                                     unsigned char nullVal(0);
00307                                     if (nullValue) nullVal = static_cast<unsigned char>(*nullValue); 
00308                                     ColumnData<unsigned char>& col 
00309                                             = dynamic_cast<ColumnData<unsigned char>&>(*this);
00310                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                    
00311                                     FITSUtil::fill(vals,col.data(),first,last);
00312                             }
00313                             else if (type() == Tushort)
00314                             {
00315                                     unsigned short nullVal(0);
00316                                     if (nullValue) nullVal 
00317                                             = static_cast<unsigned short>(*nullValue); 
00318                                     ColumnData<unsigned short>& col 
00319                                             = dynamic_cast<ColumnData<unsigned short>&>(*this);
00320                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                    
00321                                     FITSUtil::fill(vals,col.data(),first,last);
00322                             }
00323                             else if (type() == Tuint)
00324                             {
00325                                     unsigned int nullVal(0);
00326                                     if (nullValue) nullVal 
00327                                             = static_cast<unsigned int>(*nullValue); 
00328                                     ColumnData<unsigned int>& col 
00329                                             = dynamic_cast<ColumnData<unsigned int>&>(*this);
00330                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                    
00331                                     FITSUtil::fill(vals,col.data(),first,last);
00332                             }
00333                             else if (type() == Tulong)
00334                             {
00335                                     unsigned long nullVal(0);
00336                                     if (nullValue) nullVal 
00337                                             = static_cast<unsigned long>(*nullValue); 
00338                                     ColumnData<unsigned long>& col 
00339                                             = dynamic_cast<ColumnData<unsigned long>&>(*this);
00340                                     if (!isRead()) col.readColumnData(first,nelements,&nullVal);                                    
00341                                     FITSUtil::fill(vals,col.data(),first,last);
00342                             }
00343                             else
00344                             {
00345                                       throw InvalidDataType(name());
00346 
00347                             }
00348 
00349                         }
00350                         catch (std::bad_cast)
00351                         {
00352                              throw WrongColumnType(name());
00353                         }
00354                     }
00355 
00356         }
00357 
00358         // get a single row from a vector column. There's no default row number, must
00359         // be specified.
00360         template <typename S>
00361         void Column::read(std::valarray<S>& vals, long row) 
00362         {
00363                 read(vals,row,static_cast<S*>(0));
00364         }
00365 
00366 
00367         template <typename S>
00368         void Column::read(std::valarray<S>& vals, long row, S* nullValue) 
00369         {
00370                 if (row > parent()->rows())
00371                 {
00372                    throw Column::InvalidRowNumber(name());
00373                 }
00374                 parent()->makeThisCurrent();                
00375                 // isRead() returns true if the data were read in the ctor.
00376                 if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
00377                 {
00378                         // fails if user requested outputType different from input type.
00379 
00380 
00381 
00382                         // input and output are both valarrays. Since one should not
00383                         // be able to call a constructor for a non-numeric valarray type,
00384                         // there shouldn't be any InvalidType problems. However, there
00385                         // is still the vector/scalar possibility and the implicit
00386                         // conversion request to deal with.
00387 
00388                         if (!isRead()) col->readRow(row,nullValue);
00389                         FITSUtil::fill(vals,col->data(row));
00390                 }
00391                 else
00392                 {
00393                         FITSUtil::MatchType<S> outputType;
00394                         if ( outputType() == type() ) 
00395                         { 
00396                                 // in this case user tried to read vector row from scalar column.
00397                                 // one could be charitable and return a valarray of size 1,
00398                                 // but... I'm going to throw an exception suggesting the user
00399                                 // might not have meant that.
00400 
00401                                 throw Column::WrongColumnType(name());
00402                         }
00403 
00404                         // the InvalidDataType exception should not be possible.
00405                         try
00406                         {
00407                             // about exceptions. The dynamic_casts could throw
00408                             // std::bad_cast. If this happens something is seriously
00409                             // wrong since the Column stores the value of type() 
00410                             // appropriate to each of the casts on construction.
00411                             // 
00412                             // the InvalidDataType exception should not be possible.
00413                             if  ( type() == Tdouble || type() == VTdouble )
00414                             {
00415                                     ColumnVectorData<double>& col 
00416                                               = dynamic_cast<ColumnVectorData<double>&>(*this);
00417                                     if (!isRead()) col.readRow(row);                                  
00418                                     FITSUtil::fill(vals,col.data(row));
00419 
00420                             }
00421                             else if (type() == Tfloat  || type() == VTfloat )
00422                             { 
00423                                     ColumnVectorData<float>& col 
00424                                           = dynamic_cast<ColumnVectorData<float>&>(*this);
00425                                     if (!isRead()) col.readRow(row); 
00426                                     FITSUtil::fill(vals,col.data(row));
00427                             }
00428                             else if (type() == Tint  || type() == VTint )
00429                             {
00430                                     int nullVal(0);
00431                                     if (nullValue) nullVal = static_cast<int>(*nullValue); 
00432                                     ColumnVectorData<int>& col  
00433                                             = dynamic_cast<ColumnVectorData<int>&>(*this);
00434                                     if (!isRead()) col.readRow(row,&nullVal); 
00435                                     FITSUtil::fill(vals,col.data(row));
00436                             }
00437                             else if (type() == Tshort  || type() == VTshort  )
00438                             {
00439                                     short nullVal(0);
00440                                     if (nullValue) nullVal = static_cast<short>(*nullValue); 
00441                                     ColumnVectorData<short>& col 
00442                                             = dynamic_cast<ColumnVectorData<short>&>(*this);
00443                                     if (!isRead()) col.readRow(row,&nullVal); 
00444                                     FITSUtil::fill(vals,col.data(row));
00445                             }
00446                             else if (type() == Tlong  || type() == VTlong )
00447                             {   
00448                                     long nullVal(0);
00449                                     if (nullValue) nullVal = static_cast<long>(*nullValue); 
00450                                     ColumnVectorData<long>& col 
00451                                             = dynamic_cast<ColumnVectorData<long>&>(*this);
00452                                     if (!isRead()) col.readRow(row,&nullVal); 
00453                                     FITSUtil::fill(vals,col.data(row));
00454                             }
00455                             else if (type() == Tlonglong  || type() == VTlonglong )
00456                             {   
00457                                     LONGLONG nullVal(0);
00458                                     if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue); 
00459                                     ColumnVectorData<LONGLONG>& col 
00460                                             = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
00461                                     if (!isRead()) col.readRow(row,&nullVal); 
00462                                     FITSUtil::fill(vals,col.data(row));
00463                             }
00464                             else if (type() == Tlogical  || type() == VTlogical )
00465                             {   
00466                                     bool nullVal(0);
00467                                     if (nullValue) nullVal = static_cast<bool>(*nullValue); 
00468                                     ColumnVectorData<bool>& col 
00469                                             = dynamic_cast<ColumnVectorData<bool>&>(*this);
00470                                     if (!isRead()) col.readRow(row,&nullVal); 
00471                                     FITSUtil::fill(vals,col.data(row));
00472                             }
00473                             else if (type() == Tbit || type() == Tbyte ||  
00474                                     type() == VTbit || type() == VTbyte )
00475                             {
00476                                     unsigned char nullVal(0);
00477                                     if (nullValue) nullVal 
00478                                                 = static_cast<unsigned char>(*nullValue); 
00479                                     ColumnVectorData<unsigned char>& col 
00480                                           = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
00481                                     if (!isRead()) col.readRow(row,&nullVal); 
00482                                     FITSUtil::fill(vals,col.data(row));
00483                             }
00484                             else if (type() == Tushort || type() == VTushort)
00485                             {
00486                                     unsigned short nullVal(0);
00487                                     if (nullValue) nullVal 
00488                                                 = static_cast<unsigned short>(*nullValue); 
00489                                     ColumnVectorData<unsigned short>& col 
00490                                           = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
00491                                     if (!isRead()) col.readRow(row,&nullVal); 
00492                                     FITSUtil::fill(vals,col.data(row));
00493                             }
00494                             else if (type() == Tuint || type() == VTuint)
00495                             {
00496                                     unsigned int nullVal(0);
00497                                     if (nullValue) nullVal 
00498                                                 = static_cast<unsigned int>(*nullValue); 
00499                                     ColumnVectorData<unsigned int>& col 
00500                                           = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
00501                                     if (!isRead()) col.readRow(row,&nullVal); 
00502                                     FITSUtil::fill(vals,col.data(row));
00503                             }
00504                             else if (type() == Tulong || type() == VTulong)
00505                             {
00506                                     unsigned long nullVal(0);
00507                                     if (nullValue) nullVal 
00508                                                 = static_cast<unsigned long>(*nullValue); 
00509                                     ColumnVectorData<unsigned long>& col 
00510                                             = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
00511                                     if (!isRead()) col.readRow(row,&nullVal); 
00512                                     FITSUtil::fill(vals,col.data(row));
00513                             }
00514                             else
00515                             {
00516                                     throw InvalidDataType(name());
00517 
00518                             }
00519 
00520                         }
00521                         catch (std::bad_cast)
00522                         {
00523                             throw WrongColumnType(name());
00524                         }     
00525                  }
00526         }
00527 
00528         template <typename S>
00529         void Column::readArrays(std::vector<std::valarray<S> >& vals, long first, long last)  
00530         {
00531                 readArrays(vals,first,last,static_cast<S*>(0));
00532         }
00533 
00534         template <typename S>
00535         void Column::readArrays(std::vector<std::valarray<S> >& vals, 
00536                                 long first, long last, S* nullValue)
00537         {
00538 
00539                 parent()->makeThisCurrent();
00540                 // again, can only call this if the entire column has been read from disk.
00541                 // user expects 1 based indexing. If 0 based indices are supplied,
00542                 // add one to both ranges.
00543                 long range = numberOfElements(first,last);
00544 
00545                 vals.resize(range);
00546 
00547 
00548                 if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
00549                 {
00550                         for (int j = 0; j < range; ++j) 
00551                         {
00552                                 if (!isRead()) col->readRow(j + first,nullValue);                             
00553                                 FITSUtil::fill(vals[j],col->data(j+first));
00554                         }
00555                 }
00556                 else
00557                 {
00558                         FITSUtil::MatchType<S> outputType;
00559                         if ( outputType() == type() ) 
00560                         { 
00561                                 // in this case user tried to read vector data from scalar,
00562                                 // (i.e. first argument was vector<valarray<S> >.
00563                                 // since the cast won't fail on template parameter grounds.
00564                                 throw Column::WrongColumnType(name());
00565                         }
00566                         // the InvalidDataType exception should not be possible.
00567                         try
00568                         {
00569                             if  ( type() == Tdouble || type() == VTdouble )
00570                             {
00571                                     ColumnVectorData<double>& col 
00572                                             = dynamic_cast<ColumnVectorData<double>&>(*this);
00573                                     for (int j = 0; j < range; ++j) 
00574                                     {
00575                                         if (!isRead()) col.readRow(j + first); 
00576                                         FITSUtil::fill(vals[j],col.data(j+first));
00577                                     }
00578                             }
00579                             else if  ( type() == Tfloat || type() == VTfloat  )
00580                             {
00581                                     ColumnVectorData<float>& col 
00582                                             = dynamic_cast<ColumnVectorData<float>&>(*this);
00583                                     for (int j = 0; j < range; ++j) 
00584                                     {
00585                                         if (!isRead()) col.readRow(j + first); 
00586                                         FITSUtil::fill(vals[j],col.data(j+first));
00587                                     }
00588                             }
00589                             else if  ( type() == Tint   || type() == VTint )
00590                             {
00591                                     int nullVal(0);
00592                                     if (nullValue) nullVal  = static_cast<int>(*nullValue); 
00593                                     ColumnVectorData<int>& col  
00594                                             = dynamic_cast<ColumnVectorData<int>&>(*this);
00595                                     for (int j = 0; j < range; ++j) 
00596                                     {
00597                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00598                                         FITSUtil::fill(vals[j],col.data(j+first));
00599                                     }
00600                             }
00601                             else if  ( type() == Tshort  || type() == VTshort )
00602                             {
00603                                     short nullVal(0);
00604                                     if (nullValue) nullVal  = static_cast<short>(*nullValue); 
00605                                     ColumnVectorData<short>& col 
00606                                             = dynamic_cast<ColumnVectorData<short>&>(*this);
00607                                     for (int j = 0; j < range; ++j) 
00608                                     {
00609                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00610                                         FITSUtil::fill(vals[j],col.data(j+first));
00611                                     }
00612                             }
00613                             else if  ( type() == Tlong   || type() == VTlong )
00614                             {
00615                                     long nullVal(0);
00616                                     if (nullValue) nullVal  = static_cast<long>(*nullValue); 
00617                                     ColumnVectorData<long>& col 
00618                                             = dynamic_cast<ColumnVectorData<long>&>(*this);
00619                                     for (int j = 0; j < range; ++j) 
00620                                     {
00621                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00622                                         FITSUtil::fill(vals[j],col.data(j+first));
00623                                     }
00624                             }
00625                             else if  ( type() == Tlonglong   || type() == VTlonglong )
00626                             {
00627                                     LONGLONG nullVal(0);
00628                                     if (nullValue) nullVal  = static_cast<LONGLONG>(*nullValue); 
00629                                     ColumnVectorData<LONGLONG>& col 
00630                                             = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
00631                                     for (int j = 0; j < range; ++j) 
00632                                     {
00633                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00634                                         FITSUtil::fill(vals[j],col.data(j+first));
00635                                     }
00636                             }
00637                             else if  ( type() == Tlogical   || type() == VTlogical )
00638                             {
00639                                     bool nullVal(0);
00640                                     if (nullValue) nullVal   = static_cast<bool>(*nullValue); 
00641                                     ColumnVectorData<bool>& col 
00642                                             = dynamic_cast<ColumnVectorData<bool>&>(*this);
00643                                     for (int j = 0; j < range; ++j) 
00644                                     {
00645                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00646                                         FITSUtil::fill(vals[j],col.data(j+first));
00647                                     }
00648                             }
00649                             else if (type() == Tbit || type() == Tbyte ||  
00650                                     type() == VTbit || type() == VTbyte )
00651                             {
00652                                     unsigned char nullVal(0);
00653                                     if (nullValue) nullVal 
00654                                                 = static_cast<unsigned char>(*nullValue); 
00655                                     ColumnVectorData<unsigned char>& col 
00656                                            = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
00657                                     for (int j = 0; j < range; ++j) 
00658                                     {
00659                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00660                                         FITSUtil::fill(vals[j],col.data(j+first));
00661                                     }
00662                             }                            
00663                             else if  ( type() == Tushort   || type() == VTushort )
00664                             {
00665                                     unsigned short nullVal(0);
00666                                     if (nullValue) nullVal 
00667                                                 = static_cast<unsigned short>(*nullValue); 
00668                                     ColumnVectorData<unsigned short>& col 
00669                                         = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
00670                                     for (int j = 0; j < range; ++j) 
00671                                     {
00672                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00673                                         FITSUtil::fill(vals[j],col.data(j+first));
00674                                     }
00675                             }
00676                             else if  ( type() == Tuint   || type() == VTuint )
00677                             {
00678                                     unsigned int nullVal(0);
00679                                     if (nullValue) nullVal 
00680                                                 = static_cast<unsigned int>(*nullValue); 
00681                                     ColumnVectorData<unsigned int>& col 
00682                                             = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
00683                                     for (int j = 0; j < range; ++j) 
00684                                     {
00685                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00686                                         FITSUtil::fill(vals[j],col.data(j+first));
00687                                     }
00688                             }
00689                             else if  ( type() == Tulong   || type() == VTulong  )
00690                             {
00691                                     unsigned long nullVal(0);
00692                                     if (nullValue) nullVal 
00693                                                 = static_cast<unsigned long>(*nullValue); 
00694                                     ColumnVectorData<unsigned long>& col 
00695                                           = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
00696                                     for (int j = 0; j < range; ++j) 
00697                                     {
00698                                         if (!isRead()) col.readRow(j + first,&nullVal); 
00699                                         FITSUtil::fill(vals[j],col.data(j+first));
00700                                     }
00701                             } 
00702                             else
00703                             {
00704                                     throw InvalidDataType(name());
00705                             }
00706 
00707                         }
00708                         catch (std::bad_cast)
00709                         {
00710                             throw WrongColumnType(name());
00711 
00712                         }     
00713 
00714                 }        
00715         }
00716 
00717         template <typename S>                   
00718         void Column::write (const std::vector<S>& indata, long firstRow)
00719         {
00720                 // nullValue is now a pointer, so this is ok. 
00721                 // got to cast the 0 to a pointer to S to avoid
00722                 // overloading ambiguities.      
00723                 write(indata,firstRow,static_cast<S*>(0));
00724         }
00725 
00726         template <typename S>                   
00727         void Column::write (const std::valarray<S>& indata, long firstRow)
00728         {
00729                 size_t n(indata.size());
00730                 std::vector<S> __tmp(n);
00731                 for (size_t j = 0; j < n; ++j) __tmp[j] = indata[j];
00732                 write(__tmp,firstRow,static_cast<S*>(0));
00733         }
00734 
00735         template <typename S>                   
00736         void Column::write (S* indata, long nRows, long firstRow)
00737         {
00738                 write(indata,nRows,firstRow,static_cast<S*>(0));                
00739         }
00740 
00741 
00742         template <typename S>                   
00743         void Column::write (const std::vector<S>& indata, long firstRow, S* nullValue)
00744         {
00745                 // although underlying code needs to convert the input vector
00746                 // into a C array, this must be the underlying implementation
00747                 // [which the others call] because it accepts string arguments
00748                 // which the version with a pointer won't. [no version that
00749                 // translates to a char** argument].
00750 
00751 
00752                 parent()->makeThisCurrent();
00753                 firstRow = std::max(firstRow,static_cast<long>(1));
00754                 if (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
00755                 {
00756                         col->writeData(indata,firstRow,nullValue);
00757                 }
00758                 else
00759                 {
00760                         // alright, input data type has to be rewritten as output
00761                         // data type.
00762                         FITSUtil::MatchType<S> inType;
00763                         if ( inType() == type()) 
00764                         {
00765                                 String msg("Incorrect call: writing to vector column ");
00766                                 msg += name();
00767                                 msg += " requires specification of # rows or vector lengths";
00768                                 throw WrongColumnType(msg);
00769                         }
00770                         else
00771                         {
00772                             if  ( type() == Tdouble )
00773                             {
00774                                 ColumnData<double>& col 
00775                                         = dynamic_cast<ColumnData<double>&>(*this);
00776                                 std::vector<double> __tmp;
00777                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00778                                 col.writeData(__tmp,firstRow);
00779                             }
00780                             else if  ( type() == Tfloat )
00781                             {
00782                                 ColumnData<float>& col 
00783                                         = dynamic_cast<ColumnData<float>&>(*this);
00784                                 std::vector<float> __tmp;
00785                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00786                                 col.writeData(__tmp,firstRow);
00787                             }
00788                             else if  ( type() == Tint )
00789                             {
00790                                 int nullVal = 0;
00791                                 int* pNullVal = 0;
00792                                 if (nullValue)
00793                                 {
00794                                    nullVal = static_cast<int>(*nullValue);
00795                                    pNullVal = &nullVal;
00796                                 }
00797                                 if (nullValue) nullVal = static_cast<int>(*nullValue); 
00798                                 ColumnData<int>& col  
00799                                         = dynamic_cast<ColumnData<int>&>(*this);
00800                                 std::vector<int> __tmp;
00801                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00802                                 col.writeData(__tmp,firstRow,pNullVal);
00803                             }
00804                             else if  ( type() == Tshort )
00805                             {
00806                                 short nullVal(0);
00807                                 short* pNullVal = 0;
00808                                 if (nullValue) 
00809                                 {
00810                                    nullVal = static_cast<short>(*nullValue); 
00811                                    pNullVal = &nullVal;
00812                                 }
00813                                 ColumnData<short>& col 
00814                                         = dynamic_cast<ColumnData<short>&>(*this);
00815                                 std::vector<short> __tmp;
00816                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00817                                 col.writeData(__tmp,firstRow,pNullVal);
00818                             }
00819                             else if  ( type() == Tlong )
00820                             {
00821                                 long nullVal(0);
00822                                 long* pNullVal = 0;
00823                                 if (nullValue)
00824                                 {
00825                                    nullVal = static_cast<long>(*nullValue); 
00826                                    pNullVal = &nullVal;
00827                                 }
00828                                 ColumnData<long>& col 
00829                                         = dynamic_cast<ColumnData<long>&>(*this);
00830                                 std::vector<long> __tmp;
00831                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00832                                 col.writeData(__tmp,firstRow,pNullVal);
00833                             }
00834                             else if  ( type() == Tlonglong )
00835                             {
00836                                 LONGLONG nullVal(0);
00837                                 LONGLONG* pNullVal = 0;
00838                                 if (nullValue)
00839                                 {
00840                                    nullVal = static_cast<LONGLONG>(*nullValue); 
00841                                    pNullVal = &nullVal;
00842                                 }
00843                                 ColumnData<LONGLONG>& col 
00844                                         = dynamic_cast<ColumnData<LONGLONG>&>(*this);
00845                                 std::vector<LONGLONG> __tmp;
00846                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00847                                 col.writeData(__tmp,firstRow,pNullVal);
00848                             }
00849                             else if  ( type() == Tlogical )
00850                             {
00851                                 bool nullVal(0);
00852                                 bool* pNullVal = 0;
00853                                 if (nullValue)
00854                                 {
00855                                    nullVal = static_cast<bool>(*nullValue); 
00856                                    pNullVal = &nullVal;
00857                                 }
00858                                 ColumnData<bool>& col 
00859                                         = dynamic_cast<ColumnData<bool>&>(*this);
00860                                 std::vector<bool> __tmp;
00861                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00862                                 col.writeData(__tmp,firstRow,pNullVal);
00863                             }
00864                             else if  ( type() == Tbyte )
00865                             {
00866                                 unsigned char nullVal(0);
00867                                 unsigned char* pNullVal = 0;
00868                                 if (nullValue)
00869                                 {
00870                                    nullVal = static_cast<unsigned char>(*nullValue); 
00871                                    pNullVal = &nullVal;
00872                                 }
00873                                 ColumnData<unsigned char>& col 
00874                                         = dynamic_cast<ColumnData<unsigned char>&>(*this);
00875                                 std::vector<unsigned char> __tmp;
00876                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00877                                 col.writeData(__tmp,firstRow,pNullVal);
00878                             }                            
00879                             else if  ( type() == Tushort )
00880                             {
00881                                 unsigned short nullVal(0);
00882                                 unsigned short* pNullVal = 0;
00883                                 if (nullValue)
00884                                 {
00885                                    nullVal = static_cast<unsigned short>(*nullValue);
00886                                    pNullVal = &nullVal;
00887                                 } 
00888                                 ColumnData<unsigned short>& col 
00889                                         = dynamic_cast<ColumnData<unsigned short>&>(*this);
00890                                 std::vector<unsigned short> __tmp;
00891                                 FITSUtil::fill(__tmp,indata,1,indata.size());
00892                                 col.writeData(__tmp,firstRow,pNullVal);
00893                             }
00894                             else if  ( type() == Tuint )
00895                             {
00896                                 unsigned int nullVal(0);
00897                                 unsigned int* pNullVal = 0;
00898                                 if (nullValue)
00899                                 {
00900                                    nullVal = static_cast<unsigned int>(*nullValue);
00901                                    pNullVal = &nullVal;
00902                                 } 
00903                                 ColumnData<unsigned int>& col 
00904                                         = dynamic_cast<ColumnData<unsigned int>&>