CCfits
2.5
|
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