CCfits 2.7
ColumnT.h
1// Astrophysics Science Division,
2// NASA/ Goddard Space Flight Center
3// HEASARC
4// http://heasarc.gsfc.nasa.gov
5// e-mail: ccfits@legacy.gsfc.nasa.gov
6//
7// Original author: Ben Dorman
8
9#ifndef COLUMNT_H
10#define COLUMNT_H
11
12#ifdef _MSC_VER
13#include "MSconfig.h"
14#endif
15
16#include "ColumnData.h"
17#include "ColumnVectorData.h"
18#include "FITSUtil.h"
19#include <typeinfo>
20#include <vector>
21#include <algorithm>
22#include "NewKeyword.h"
23
24#ifdef SSTREAM_DEFECT
25# include <strstream>
26#else
27# include <sstream>
28#endif
29
30
31// by design, if the data are not read yet we will return an exception.
32// here the test is if the entire column has already been read.
33using std::complex;
34using std::valarray;
35
36// get specified elements of a scalar column. These two functions allow the
37// user to return either a vector or a valarray depending on the input container.
38
39namespace CCfits
40{
41 template <typename S>
42 void Column::read(std::vector<S>& vals, long first, long last)
43 {
44 read(vals,first,last,static_cast<S*>(0));
45 }
46
47
48 template <typename S>
49 void Column::read(std::vector<S>& vals, long first, long last, S* nullValue)
50 {
51 // problem: S does not give the type of the Column, but the return type,
52 // so the user must specify this.
54 long nelements = numberOfElements(first,last);
55
56 if (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
57 {
58 // fails if user requested outputType different from input type.
59
60
61 if (!isRead()) col->readColumnData(first,nelements,nullValue);
62 // scalar column with vector output can just be assigned.
63 FITSUtil::fill(vals,col->data(),first,last);
64 }
65 else
66 {
67 FITSUtil::MatchType<S> outputType;
68 if ( outputType() == type() )
69 {
70 // in this case user tried to read vector data from scalar,
71 // (i.e. first argument was vector<valarray<S> >.
72 // since the cast won't fail on template parameter grounds.
74 }
75
76 try
77 {
78 // about exceptions. The dynamic_casts could throw
79 // std::bad_cast. If this happens something is seriously
80 // wrong since the Column stores the value of type()
81 // appropriate to each of the casts on construction.
82 //
83 // the InvalidDataType exception should not be possible.
84 if ( type() == Tdouble )
85 {
86 ColumnData<double>& col
87 = dynamic_cast<ColumnData<double>&>(*this);
88 if (!isRead()) col.readColumnData(first,nelements);
89 FITSUtil::fill(vals,col.data(),first,last);
90
91 }
92 else if (type() == Tfloat)
93 {
94 ColumnData<float>& col
95 = dynamic_cast<ColumnData<float>&>(*this);
96 if (!isRead()) col.readColumnData(first,nelements);
97 FITSUtil::fill(vals,col.data(),first,last);
98 }
99 else if (type() == Tint)
100 {
101 int nullVal(0);
102 if (nullValue) nullVal = static_cast<int>(*nullValue);
103 ColumnData<int>& col
104 = dynamic_cast<ColumnData<int>&>(*this);
105 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
106 FITSUtil::fill(vals,col.data(),first,last);
107 }
108 else if (type() == Tshort)
109 {
110 short nullVal(0);
111 if (nullValue) nullVal = static_cast<short>(*nullValue);
112 ColumnData<short>& col
113 = dynamic_cast<ColumnData<short>&>(*this);
114 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
115 FITSUtil::fill(vals,col.data(),first,last);
116 }
117 else if (type() == Tlong)
118 {
119 long nullVal(0);
120 if (nullValue) nullVal = static_cast<long>(*nullValue);
121 ColumnData<long>& col
122 = dynamic_cast<ColumnData<long>&>(*this);
123 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
124 FITSUtil::fill(vals,col.data(),first,last);
125 }
126 else if (type() == Tlonglong)
127 {
128 LONGLONG nullVal(0);
129 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
130 ColumnData<LONGLONG>& col
131 = dynamic_cast<ColumnData<LONGLONG>&>(*this);
132 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
133 FITSUtil::fill(vals,col.data(),first,last);
134 }
135 else if (type() == Tlogical)
136 {
137 bool nullVal(0);
138 if (nullValue) nullVal = static_cast<bool>(*nullValue);
139 ColumnData<bool>& col
140 = dynamic_cast<ColumnData<bool>&>(*this);
141 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
142 FITSUtil::fill(vals,col.data(),first,last);
143 }
144 else if (type() == Tbit || type() == Tbyte)
145 {
146 unsigned char nullVal(0);
147 if (nullValue) nullVal = static_cast<unsigned char>(*nullValue);
148 ColumnData<unsigned char>& col
149 = dynamic_cast<ColumnData<unsigned char>&>(*this);
150 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
151 FITSUtil::fill(vals,col.data(),first,last);
152 }
153 else if (type() == Tushort)
154 {
155 unsigned short nullVal(0);
156 if (nullValue) nullVal= static_cast<unsigned short>(*nullValue);
157 ColumnData<unsigned short>& col
158 = dynamic_cast<ColumnData<unsigned short>&>(*this);
159 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
160 FITSUtil::fill(vals,col.data(),first,last);
161 }
162 else if (type() == Tuint)
163 {
164 unsigned int nullVal(0);
165 if (nullValue) nullVal = static_cast<unsigned int>(*nullValue);
166 ColumnData<unsigned int>& col
167 = dynamic_cast<ColumnData<unsigned int>&>(*this);
168 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
169 FITSUtil::fill(vals,col.data(),first,last);
170 }
171 else if (type() == Tulong)
172 {
173 unsigned long nullVal(0);
174 if (nullValue) nullVal = static_cast<unsigned long>(*nullValue);
175 ColumnData<unsigned long>& col
176 = dynamic_cast<ColumnData<unsigned long>&>(*this);
177 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
178 FITSUtil::fill(vals,col.data(),first,last);
179 }
180 else
181 {
182 throw InvalidDataType(name());
183
184 }
185
186 }
187 catch (std::bad_cast&)
188 {
189 throw WrongColumnType(name());
190 }
191 }
192
193 }
194
195 template <typename S>
196 void Column::read(std::valarray<S>& vals, long first, long last)
197 {
198 read(vals,first,last,static_cast<S*>(0));
199 }
200
201
202 template <typename S>
203 void Column::read(std::valarray<S>& vals, long first, long last, S* nullValue)
204 {
205 // require the whole scalar column to have been read.
206
207
208 long nelements = numberOfElements(first,last);
210 if ( ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
211 {
212 // fails if user requested outputType different from input type.
213
214
215 if (!isRead()) col->readColumnData(first,nelements,nullValue);
216 FITSUtil::fill(vals,col->data(),first,last);
217
218 }
219 else
220 {
221 FITSUtil::MatchType<S> outputType;
222 if ( outputType() == type() )
223 {
224 // in this case user tried to read vector data from scalar,
225 // (i.e. first argument was vector<valarray<S> >.
226 // since the cast won't fail on template parameter grounds.
228 }
229
230 try
231 {
232 // about exceptions. The dynamic_casts could throw
233 // std::bad_cast. If this happens something is seriously
234 // wrong since the Column stores the value of type()
235 // appropriate to each of the casts on construction.
236 //
237 // the InvalidDataType exception should not be possible.
238 if ( type() == Tdouble )
239 {
240 ColumnData<double>& col
241 = dynamic_cast<ColumnData<double>&>(*this);
242 if (!isRead()) col.readColumnData(first,nelements);
243 FITSUtil::fill(vals,col.data(),first,last);
244 }
245 else if (type() == Tfloat)
246 {
247 ColumnData<float>& col
248 = dynamic_cast<ColumnData<float>&>(*this);
249 if (!isRead()) col.readColumnData(first,nelements);
250 FITSUtil::fill(vals,col.data(),first,last);
251 }
252 else if (type() == Tint)
253 {
254 int nullVal(0);
255 if (nullValue) nullVal = static_cast<int>(*nullValue);
256 ColumnData<int>& col
257 = dynamic_cast<ColumnData<int>&>(*this);
258 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
259 FITSUtil::fill(vals,col.data(),first,last);
260 }
261 else if (type() == Tshort)
262 {
263 short nullVal(0);
264 if (nullValue) nullVal = static_cast<short>(*nullValue);
265 ColumnData<short>& col
266 = dynamic_cast<ColumnData<short>&>(*this);
267 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
268 FITSUtil::fill(vals,col.data(),first,last);
269 }
270 else if (type() == Tlong)
271 {
272 long nullVal(0);
273 if (nullValue) nullVal = static_cast<long>(*nullValue);
274 ColumnData<long>& col
275 = dynamic_cast<ColumnData<long>&>(*this);
276 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
277 FITSUtil::fill(vals,col.data(),first,last);
278 }
279 else if (type() == Tlonglong)
280 {
281 LONGLONG nullVal(0);
282 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
283 ColumnData<LONGLONG>& col
284 = dynamic_cast<ColumnData<LONGLONG>&>(*this);
285 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
286 FITSUtil::fill(vals,col.data(),first,last);
287 }
288 else if (type() == Tlogical)
289 {
290 bool nullVal(0);
291 if (nullValue) nullVal = static_cast<bool>(*nullValue);
292 ColumnData<bool>& col
293 = dynamic_cast<ColumnData<bool>&>(*this);
294 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
295 FITSUtil::fill(vals,col.data(),first,last);
296 }
297 else if (type() == Tbit || type() == Tbyte)
298 {
299 unsigned char nullVal(0);
300 if (nullValue) nullVal = static_cast<unsigned char>(*nullValue);
301 ColumnData<unsigned char>& col
302 = dynamic_cast<ColumnData<unsigned char>&>(*this);
303 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
304 FITSUtil::fill(vals,col.data(),first,last);
305 }
306 else if (type() == Tushort)
307 {
308 unsigned short nullVal(0);
309 if (nullValue) nullVal
310 = static_cast<unsigned short>(*nullValue);
311 ColumnData<unsigned short>& col
312 = dynamic_cast<ColumnData<unsigned short>&>(*this);
313 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
314 FITSUtil::fill(vals,col.data(),first,last);
315 }
316 else if (type() == Tuint)
317 {
318 unsigned int nullVal(0);
319 if (nullValue) nullVal
320 = static_cast<unsigned int>(*nullValue);
321 ColumnData<unsigned int>& col
322 = dynamic_cast<ColumnData<unsigned int>&>(*this);
323 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
324 FITSUtil::fill(vals,col.data(),first,last);
325 }
326 else if (type() == Tulong)
327 {
328 unsigned long nullVal(0);
329 if (nullValue) nullVal
330 = static_cast<unsigned long>(*nullValue);
331 ColumnData<unsigned long>& col
332 = dynamic_cast<ColumnData<unsigned long>&>(*this);
333 if (!isRead()) col.readColumnData(first,nelements,&nullVal);
334 FITSUtil::fill(vals,col.data(),first,last);
335 }
336 else
337 {
338 throw InvalidDataType(name());
339
340 }
341
342 }
343 catch (std::bad_cast&)
344 {
345 throw WrongColumnType(name());
346 }
347 }
348
349 }
350
351 // get a single row from a vector column. There's no default row number, must
352 // be specified.
353 template <typename S>
354 void Column::read(std::valarray<S>& vals, long row)
355 {
356 read(vals,row,static_cast<S*>(0));
357 }
358 template <typename S>
359 void Column::read(std::vector<S>& vals, long row)
360 {
361 read(vals,row,static_cast<S*>(0));
362 }
363
364 template <typename S>
365 void Column::read(std::vector<S>& vals, long row, S* nullValue)
366 {
367 if (row > parent()->rows())
368 {
370 }
372 // isRead() returns true if the data were read in the ctor.
373 if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
374 {
375 // fails if user requested outputType different from input type.
376
377
378 if (!isRead()) col->readRow(row,nullValue);
379 FITSUtil::fill(vals,col->data(row));
380 }
381 else
382 {
383 FITSUtil::MatchType<S> outputType;
384 if ( outputType() == type() )
385 {
386 // in this case user tried to read vector row from scalar column.
387 // one could be charitable and return a valarray of size 1,
388 // but... I'm going to throw an exception suggesting the user
389 // might not have meant that.
390
391 throw Column::WrongColumnType(name());
392 }
393
394 // the InvalidDataType exception should not be possible.
395 try
396 {
397 // about exceptions. The dynamic_casts could throw
398 // std::bad_cast. If this happens something is seriously
399 // wrong since the Column stores the value of type()
400 // appropriate to each of the casts on construction.
401 //
402 // the InvalidDataType exception should not be possible.
403 if ( type() == Tdouble || type() == VTdouble )
404 {
405 ColumnVectorData<double>& col
406 = dynamic_cast<ColumnVectorData<double>&>(*this);
407 if (!isRead()) col.readRow(row);
408 FITSUtil::fill(vals,col.data(row));
409
410 }
411 else if (type() == Tfloat || type() == VTfloat )
412 {
413 ColumnVectorData<float>& col
414 = dynamic_cast<ColumnVectorData<float>&>(*this);
415 if (!isRead()) col.readRow(row);
416 FITSUtil::fill(vals,col.data(row));
417 }
418 else if (type() == Tint || type() == VTint )
419 {
420 int nullVal(0);
421 if (nullValue) nullVal = static_cast<int>(*nullValue);
422 ColumnVectorData<int>& col
423 = dynamic_cast<ColumnVectorData<int>&>(*this);
424 if (!isRead()) col.readRow(row,&nullVal);
425 FITSUtil::fill(vals,col.data(row));
426 }
427 else if (type() == Tshort || type() == VTshort )
428 {
429 short nullVal(0);
430 if (nullValue) nullVal = static_cast<short>(*nullValue);
431 ColumnVectorData<short>& col
432 = dynamic_cast<ColumnVectorData<short>&>(*this);
433 if (!isRead()) col.readRow(row,&nullVal);
434 FITSUtil::fill(vals,col.data(row));
435 }
436 else if (type() == Tlong || type() == VTlong )
437 {
438 long nullVal(0);
439 if (nullValue) nullVal = static_cast<long>(*nullValue);
440 ColumnVectorData<long>& col
441 = dynamic_cast<ColumnVectorData<long>&>(*this);
442 if (!isRead()) col.readRow(row,&nullVal);
443 FITSUtil::fill(vals,col.data(row));
444 }
445 else if (type() == Tlonglong || type() == VTlonglong )
446 {
447 LONGLONG nullVal(0);
448 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
449 ColumnVectorData<LONGLONG>& col
450 = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
451 if (!isRead()) col.readRow(row,&nullVal);
452 FITSUtil::fill(vals,col.data(row));
453 }
454 else if (type() == Tlogical || type() == VTlogical )
455 {
456 bool nullVal(0);
457 if (nullValue) nullVal = static_cast<bool>(*nullValue);
458 ColumnVectorData<bool>& col
459 = dynamic_cast<ColumnVectorData<bool>&>(*this);
460 if (!isRead()) col.readRow(row,&nullVal);
461 FITSUtil::fill(vals,col.data(row));
462 }
463 else if (type() == Tbit || type() == Tbyte ||
464 type() == VTbit || type() == VTbyte )
465 {
466 unsigned char nullVal(0);
467 if (nullValue) nullVal
468 = static_cast<unsigned char>(*nullValue);
469 ColumnVectorData<unsigned char>& col
470 = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
471 if (!isRead()) col.readRow(row,&nullVal);
472 FITSUtil::fill(vals,col.data(row));
473 }
474 else if (type() == Tushort || type() == VTushort)
475 {
476 unsigned short nullVal(0);
477 if (nullValue) nullVal
478 = static_cast<unsigned short>(*nullValue);
479 ColumnVectorData<unsigned short>& col
480 = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
481 if (!isRead()) col.readRow(row,&nullVal);
482 FITSUtil::fill(vals,col.data(row));
483 }
484 else if (type() == Tuint || type() == VTuint)
485 {
486 unsigned int nullVal(0);
487 if (nullValue) nullVal
488 = static_cast<unsigned int>(*nullValue);
489 ColumnVectorData<unsigned int>& col
490 = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
491 if (!isRead()) col.readRow(row,&nullVal);
492 FITSUtil::fill(vals,col.data(row));
493 }
494 else if (type() == Tulong || type() == VTulong)
495 {
496 unsigned long nullVal(0);
497 if (nullValue) nullVal
498 = static_cast<unsigned long>(*nullValue);
499 ColumnVectorData<unsigned long>& col
500 = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
501 if (!isRead()) col.readRow(row,&nullVal);
502 FITSUtil::fill(vals,col.data(row));
503 }
504 else
505 {
506 throw InvalidDataType(name());
507
508 }
509
510 }
511 catch (std::bad_cast&)
512 {
513 throw WrongColumnType(name());
514 }
515 }
516 }
517
518 template <typename S>
519 void Column::read(std::valarray<S>& vals, long row, S* nullValue)
520 {
521 if (row > parent()->rows())
522 {
524 }
526 // isRead() returns true if the data were read in the ctor.
527 if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
528 {
529 // fails if user requested outputType different from input type.
530
531
532
533 // input and output are both valarrays. Since one should not
534 // be able to call a constructor for a non-numeric valarray type,
535 // there shouldn't be any InvalidType problems. However, there
536 // is still the vector/scalar possibility and the implicit
537 // conversion request to deal with.
538
539 if (!isRead()) col->readRow(row,nullValue);
540 FITSUtil::fill(vals,col->data(row));
541 }
542 else
543 {
544 FITSUtil::MatchType<S> outputType;
545 if ( outputType() == type() )
546 {
547 // in this case user tried to read vector row from scalar column.
548 // one could be charitable and return a valarray of size 1,
549 // but... I'm going to throw an exception suggesting the user
550 // might not have meant that.
551
553 }
554
555 // the InvalidDataType exception should not be possible.
556 try
557 {
558 // about exceptions. The dynamic_casts could throw
559 // std::bad_cast. If this happens something is seriously
560 // wrong since the Column stores the value of type()
561 // appropriate to each of the casts on construction.
562 //
563 // the InvalidDataType exception should not be possible.
564 if ( type() == Tdouble || type() == VTdouble )
565 {
566 ColumnVectorData<double>& col
567 = dynamic_cast<ColumnVectorData<double>&>(*this);
568 if (!isRead()) col.readRow(row);
569 FITSUtil::fill(vals,col.data(row));
570
571 }
572 else if (type() == Tfloat || type() == VTfloat )
573 {
574 ColumnVectorData<float>& col
575 = dynamic_cast<ColumnVectorData<float>&>(*this);
576 if (!isRead()) col.readRow(row);
577 FITSUtil::fill(vals,col.data(row));
578 }
579 else if (type() == Tint || type() == VTint )
580 {
581 int nullVal(0);
582 if (nullValue) nullVal = static_cast<int>(*nullValue);
583 ColumnVectorData<int>& col
584 = dynamic_cast<ColumnVectorData<int>&>(*this);
585 if (!isRead()) col.readRow(row,&nullVal);
586 FITSUtil::fill(vals,col.data(row));
587 }
588 else if (type() == Tshort || type() == VTshort )
589 {
590 short nullVal(0);
591 if (nullValue) nullVal = static_cast<short>(*nullValue);
592 ColumnVectorData<short>& col
593 = dynamic_cast<ColumnVectorData<short>&>(*this);
594 if (!isRead()) col.readRow(row,&nullVal);
595 FITSUtil::fill(vals,col.data(row));
596 }
597 else if (type() == Tlong || type() == VTlong )
598 {
599 long nullVal(0);
600 if (nullValue) nullVal = static_cast<long>(*nullValue);
601 ColumnVectorData<long>& col
602 = dynamic_cast<ColumnVectorData<long>&>(*this);
603 if (!isRead()) col.readRow(row,&nullVal);
604 FITSUtil::fill(vals,col.data(row));
605 }
606 else if (type() == Tlonglong || type() == VTlonglong )
607 {
608 LONGLONG nullVal(0);
609 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
610 ColumnVectorData<LONGLONG>& col
611 = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
612 if (!isRead()) col.readRow(row,&nullVal);
613 FITSUtil::fill(vals,col.data(row));
614 }
615 else if (type() == Tlogical || type() == VTlogical )
616 {
617 bool nullVal(0);
618 if (nullValue) nullVal = static_cast<bool>(*nullValue);
619 ColumnVectorData<bool>& col
620 = dynamic_cast<ColumnVectorData<bool>&>(*this);
621 if (!isRead()) col.readRow(row,&nullVal);
622 FITSUtil::fill(vals,col.data(row));
623 }
624 else if (type() == Tbit || type() == Tbyte ||
625 type() == VTbit || type() == VTbyte )
626 {
627 unsigned char nullVal(0);
628 if (nullValue) nullVal
629 = static_cast<unsigned char>(*nullValue);
630 ColumnVectorData<unsigned char>& col
631 = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
632 if (!isRead()) col.readRow(row,&nullVal);
633 FITSUtil::fill(vals,col.data(row));
634 }
635 else if (type() == Tushort || type() == VTushort)
636 {
637 unsigned short nullVal(0);
638 if (nullValue) nullVal
639 = static_cast<unsigned short>(*nullValue);
640 ColumnVectorData<unsigned short>& col
641 = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
642 if (!isRead()) col.readRow(row,&nullVal);
643 FITSUtil::fill(vals,col.data(row));
644 }
645 else if (type() == Tuint || type() == VTuint)
646 {
647 unsigned int nullVal(0);
648 if (nullValue) nullVal
649 = static_cast<unsigned int>(*nullValue);
650 ColumnVectorData<unsigned int>& col
651 = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
652 if (!isRead()) col.readRow(row,&nullVal);
653 FITSUtil::fill(vals,col.data(row));
654 }
655 else if (type() == Tulong || type() == VTulong)
656 {
657 unsigned long nullVal(0);
658 if (nullValue) nullVal
659 = static_cast<unsigned long>(*nullValue);
660 ColumnVectorData<unsigned long>& col
661 = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
662 if (!isRead()) col.readRow(row,&nullVal);
663 FITSUtil::fill(vals,col.data(row));
664 }
665 else
666 {
667 throw InvalidDataType(name());
668
669 }
670
671 }
672 catch (std::bad_cast&)
673 {
674 throw WrongColumnType(name());
675 }
676 }
677 }
678
679 template <typename S>
680 void Column::readArrays(std::vector<std::valarray<S> >& vals, long first, long last)
681 {
682 readArrays(vals,first,last,static_cast<S*>(0));
683 }
684
685 template <typename S>
686 void Column::readArrays(std::vector<std::valarray<S> >& vals,
687 long first, long last, S* nullValue)
688 {
689
691 // again, can only call this if the entire column has been read from disk.
692 // user expects 1 based indexing. If 0 based indices are supplied,
693 // add one to both ranges.
694 long range = numberOfElements(first,last);
695
696 vals.resize(range);
697
698
699 if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
700 {
701 for (int j = 0; j < range; ++j)
702 {
703 if (!isRead()) col->readRow(j + first,nullValue);
704 FITSUtil::fill(vals[j],col->data(j+first));
705 }
706 }
707 else
708 {
709 FITSUtil::MatchType<S> outputType;
710 if ( outputType() == type() )
711 {
712 // in this case user tried to read vector data from scalar,
713 // (i.e. first argument was vector<valarray<S> >.
714 // since the cast won't fail on template parameter grounds.
716 }
717 // the InvalidDataType exception should not be possible.
718 try
719 {
720 if ( type() == Tdouble || type() == VTdouble )
721 {
722 ColumnVectorData<double>& col
723 = dynamic_cast<ColumnVectorData<double>&>(*this);
724 for (int j = 0; j < range; ++j)
725 {
726 if (!isRead()) col.readRow(j + first);
727 FITSUtil::fill(vals[j],col.data(j+first));
728 }
729 }
730 else if ( type() == Tfloat || type() == VTfloat )
731 {
732 ColumnVectorData<float>& col
733 = dynamic_cast<ColumnVectorData<float>&>(*this);
734 for (int j = 0; j < range; ++j)
735 {
736 if (!isRead()) col.readRow(j + first);
737 FITSUtil::fill(vals[j],col.data(j+first));
738 }
739 }
740 else if ( type() == Tint || type() == VTint )
741 {
742 int nullVal(0);
743 if (nullValue) nullVal = static_cast<int>(*nullValue);
744 ColumnVectorData<int>& col
745 = dynamic_cast<ColumnVectorData<int>&>(*this);
746 for (int j = 0; j < range; ++j)
747 {
748 if (!isRead()) col.readRow(j + first,&nullVal);
749 FITSUtil::fill(vals[j],col.data(j+first));
750 }
751 }
752 else if ( type() == Tshort || type() == VTshort )
753 {
754 short nullVal(0);
755 if (nullValue) nullVal = static_cast<short>(*nullValue);
756 ColumnVectorData<short>& col
757 = dynamic_cast<ColumnVectorData<short>&>(*this);
758 for (int j = 0; j < range; ++j)
759 {
760 if (!isRead()) col.readRow(j + first,&nullVal);
761 FITSUtil::fill(vals[j],col.data(j+first));
762 }
763 }
764 else if ( type() == Tlong || type() == VTlong )
765 {
766 long nullVal(0);
767 if (nullValue) nullVal = static_cast<long>(*nullValue);
768 ColumnVectorData<long>& col
769 = dynamic_cast<ColumnVectorData<long>&>(*this);
770 for (int j = 0; j < range; ++j)
771 {
772 if (!isRead()) col.readRow(j + first,&nullVal);
773 FITSUtil::fill(vals[j],col.data(j+first));
774 }
775 }
776 else if ( type() == Tlonglong || type() == VTlonglong )
777 {
778 LONGLONG nullVal(0);
779 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
780 ColumnVectorData<LONGLONG>& col
781 = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
782 for (int j = 0; j < range; ++j)
783 {
784 if (!isRead()) col.readRow(j + first,&nullVal);
785 FITSUtil::fill(vals[j],col.data(j+first));
786 }
787 }
788 else if ( type() == Tlogical || type() == VTlogical )
789 {
790 bool nullVal(0);
791 if (nullValue) nullVal = static_cast<bool>(*nullValue);
792 ColumnVectorData<bool>& col
793 = dynamic_cast<ColumnVectorData<bool>&>(*this);
794 for (int j = 0; j < range; ++j)
795 {
796 if (!isRead()) col.readRow(j + first,&nullVal);
797 FITSUtil::fill(vals[j],col.data(j+first));
798 }
799 }
800 else if (type() == Tbit || type() == Tbyte ||
801 type() == VTbit || type() == VTbyte )
802 {
803 unsigned char nullVal(0);
804 if (nullValue) nullVal
805 = static_cast<unsigned char>(*nullValue);
806 ColumnVectorData<unsigned char>& col
807 = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
808 for (int j = 0; j < range; ++j)
809 {
810 if (!isRead()) col.readRow(j + first,&nullVal);
811 FITSUtil::fill(vals[j],col.data(j+first));
812 }
813 }
814 else if ( type() == Tushort || type() == VTushort )
815 {
816 unsigned short nullVal(0);
817 if (nullValue) nullVal
818 = static_cast<unsigned short>(*nullValue);
819 ColumnVectorData<unsigned short>& col
820 = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
821 for (int j = 0; j < range; ++j)
822 {
823 if (!isRead()) col.readRow(j + first,&nullVal);
824 FITSUtil::fill(vals[j],col.data(j+first));
825 }
826 }
827 else if ( type() == Tuint || type() == VTuint )
828 {
829 unsigned int nullVal(0);
830 if (nullValue) nullVal
831 = static_cast<unsigned int>(*nullValue);
832 ColumnVectorData<unsigned int>& col
833 = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
834 for (int j = 0; j < range; ++j)
835 {
836 if (!isRead()) col.readRow(j + first,&nullVal);
837 FITSUtil::fill(vals[j],col.data(j+first));
838 }
839 }
840 else if ( type() == Tulong || type() == VTulong )
841 {
842 unsigned long nullVal(0);
843 if (nullValue) nullVal
844 = static_cast<unsigned long>(*nullValue);
845 ColumnVectorData<unsigned long>& col
846 = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
847 for (int j = 0; j < range; ++j)
848 {
849 if (!isRead()) col.readRow(j + first,&nullVal);
850 FITSUtil::fill(vals[j],col.data(j+first));
851 }
852 }
853 else
854 {
855 throw InvalidDataType(name());
856 }
857
858 }
859 catch (std::bad_cast&)
860 {
861 throw WrongColumnType(name());
862
863 }
864
865 }
866 }
867
868 template <typename S>
869 void Column::write (const std::vector<S>& indata, long firstRow)
870 {
871 // nullValue is now a pointer, so this is ok.
872 // got to cast the 0 to a pointer to S to avoid
873 // overloading ambiguities.
874 write(indata,firstRow,static_cast<S*>(0));
875 }
876
877 template <typename S>
878 void Column::write (const std::valarray<S>& indata, long firstRow)
879 {
880 size_t n(indata.size());
881 std::vector<S> __tmp(n);
882 for (size_t j = 0; j < n; ++j) __tmp[j] = indata[j];
883 write(__tmp,firstRow,static_cast<S*>(0));
884 }
885
886 template <typename S>
887 void Column::write (S* indata, long nRows, long firstRow)
888 {
889 write(indata,nRows,firstRow,static_cast<S*>(0));
890 }
891
892
893 template <typename S>
894 void Column::write (const std::vector<S>& indata, long firstRow, S* nullValue)
895 {
896 // although underlying code needs to convert the input vector
897 // into a C array, this must be the underlying implementation
898 // [which the others call] because it accepts string arguments
899 // which the version with a pointer won't. [no version that
900 // translates to a char** argument].
901
902
904 firstRow = std::max(firstRow,static_cast<long>(1));
905 if (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
906 {
907 col->writeData(indata,firstRow,nullValue);
908 }
909 else
910 {
911 // alright, input data type has to be rewritten as output
912 // data type.
914 if ( inType() == type())
915 {
916 String msg("Incorrect call: writing to vector column ");
917 msg += name();
918 msg += " requires specification of # rows or vector lengths";
919 throw WrongColumnType(msg);
920 }
921 else
922 {
923 if ( type() == Tdouble )
924 {
925 ColumnData<double>& col
926 = dynamic_cast<ColumnData<double>&>(*this);
927 std::vector<double> __tmp;
928 FITSUtil::fill(__tmp,indata,1,indata.size());
929 col.writeData(__tmp,firstRow);
930 }
931 else if ( type() == Tfloat )
932 {
933 ColumnData<float>& col
934 = dynamic_cast<ColumnData<float>&>(*this);
935 std::vector<float> __tmp;
936 FITSUtil::fill(__tmp,indata,1,indata.size());
937 col.writeData(__tmp,firstRow);
938 }
939 else if ( type() == Tint )
940 {
941 int nullVal = 0;
942 int* pNullVal = 0;
943 if (nullValue)
944 {
945 nullVal = static_cast<int>(*nullValue);
946 pNullVal = &nullVal;
947 }
948 if (nullValue) nullVal = static_cast<int>(*nullValue);
949 ColumnData<int>& col
950 = dynamic_cast<ColumnData<int>&>(*this);
951 std::vector<int> __tmp;
952 FITSUtil::fill(__tmp,indata,1,indata.size());
953 col.writeData(__tmp,firstRow,pNullVal);
954 }
955 else if ( type() == Tshort )
956 {
957 short nullVal(0);
958 short* pNullVal = 0;
959 if (nullValue)
960 {
961 nullVal = static_cast<short>(*nullValue);
962 pNullVal = &nullVal;
963 }
964 ColumnData<short>& col
965 = dynamic_cast<ColumnData<short>&>(*this);
966 std::vector<short> __tmp;
967 FITSUtil::fill(__tmp,indata,1,indata.size());
968 col.writeData(__tmp,firstRow,pNullVal);
969 }
970 else if ( type() == Tlong )
971 {
972 long nullVal(0);
973 long* pNullVal = 0;
974 if (nullValue)
975 {
976 nullVal = static_cast<long>(*nullValue);
977 pNullVal = &nullVal;
978 }
979 ColumnData<long>& col
980 = dynamic_cast<ColumnData<long>&>(*this);
981 std::vector<long> __tmp;
982 FITSUtil::fill(__tmp,indata,1,indata.size());
983 col.writeData(__tmp,firstRow,pNullVal);
984 }
985 else if ( type() == Tlonglong )
986 {
987 LONGLONG nullVal(0);
988 LONGLONG* pNullVal = 0;
989 if (nullValue)
990 {
991 nullVal = static_cast<LONGLONG>(*nullValue);
992 pNullVal = &nullVal;
993 }
994 ColumnData<LONGLONG>& col
995 = dynamic_cast<ColumnData<LONGLONG>&>(*this);
996 std::vector<LONGLONG> __tmp;
997 FITSUtil::fill(__tmp,indata,1,indata.size());
998 col.writeData(__tmp,firstRow,pNullVal);
999 }
1000 else if ( type() == Tlogical )
1001 {
1002 bool nullVal(0);
1003 bool* pNullVal = 0;
1004 if (nullValue)
1005 {
1006 nullVal = static_cast<bool>(*nullValue);
1007 pNullVal = &nullVal;
1008 }
1009 ColumnData<bool>& col
1010 = dynamic_cast<ColumnData<bool>&>(*this);
1011 std::vector<bool> __tmp;
1012 FITSUtil::fill(__tmp,indata,1,indata.size());
1013 col.writeData(__tmp,firstRow,pNullVal);
1014 }
1015 else if ( type() == Tbyte )
1016 {
1017 unsigned char nullVal(0);
1018 unsigned char* pNullVal = 0;
1019 if (nullValue)
1020 {
1021 nullVal = static_cast<unsigned char>(*nullValue);
1022 pNullVal = &nullVal;
1023 }
1024 ColumnData<unsigned char>& col
1025 = dynamic_cast<ColumnData<unsigned char>&>(*this);
1026 std::vector<unsigned char> __tmp;
1027 FITSUtil::fill(__tmp,indata,1,indata.size());
1028 col.writeData(__tmp,firstRow,pNullVal);
1029 }
1030 else if ( type() == Tushort )
1031 {
1032 unsigned short nullVal(0);
1033 unsigned short* pNullVal = 0;
1034 if (nullValue)
1035 {
1036 nullVal = static_cast<unsigned short>(*nullValue);
1037 pNullVal = &nullVal;
1038 }
1039 ColumnData<unsigned short>& col
1040 = dynamic_cast<ColumnData<unsigned short>&>(*this);
1041 std::vector<unsigned short> __tmp;
1042 FITSUtil::fill(__tmp,indata,1,indata.size());
1043 col.writeData(__tmp,firstRow,pNullVal);
1044 }
1045 else if ( type() == Tuint )
1046 {
1047 unsigned int nullVal(0);
1048 unsigned int* pNullVal = 0;
1049 if (nullValue)
1050 {
1051 nullVal = static_cast<unsigned int>(*nullValue);
1052 pNullVal = &nullVal;
1053 }
1054 ColumnData<unsigned int>& col
1055 = dynamic_cast<ColumnData<unsigned int>&>(*this);
1056 std::vector<unsigned int> __tmp;
1057 FITSUtil::fill(__tmp,indata,1,indata.size());
1058 col.writeData(__tmp,firstRow,pNullVal);
1059 }
1060 else if ( type() == Tulong )
1061 {
1062 unsigned long nullVal(0);
1063 unsigned long* pNullVal = 0;
1064 if (nullValue)
1065 {
1066 nullVal = static_cast<unsigned long>(*nullValue);
1067 pNullVal = &nullVal;
1068 }
1069 ColumnData<unsigned long>& col
1070 = dynamic_cast<ColumnData<unsigned long>&>(*this);
1071 std::vector<unsigned long> __tmp;
1072 FITSUtil::fill(__tmp,indata,1,indata.size());
1073 col.writeData(__tmp,firstRow,pNullVal);
1074 }
1075 else
1076 {
1077 throw InvalidDataType(name());
1078 }
1079 }
1080 }
1081 }
1082
1083
1084 template <typename S>
1085 void Column::write (const std::valarray<S>& indata, long firstRow, S* nullValue)
1086 {
1087 // for scalar columns.
1088 std::vector<S> __tmp;
1089 FITSUtil::fill(__tmp,indata);
1090 write(__tmp,firstRow,nullValue);
1091 }
1092
1093 template <typename S>
1094 void Column::write (S* indata, long nRows, long firstRow, S* nullValue)
1095 {
1096 // for scalar columns, data specified with C array
1097 if (nRows <= 0) throw InvalidNumberOfRows(nRows);
1098 std::vector<S> __tmp(nRows);
1099 std::copy(&indata[0],&indata[nRows],__tmp.begin());
1100 write(__tmp,firstRow, nullValue);
1101
1102 }
1103
1104 template <typename S>
1105 void Column::write (const std::valarray<S>& indata, const std::vector<long>& vectorLengths,
1106 long firstRow)
1107 {
1108 // variable length arrays written from an input valarray.
1109 // does not allow NULL value.
1110
1111 using namespace std;
1112 const size_t nRows = vectorLengths.size();
1113 // Calculate the sums of the vector lengths first simply to do a
1114 // check against the size of indata.
1115 vector<long> sums(nRows+1);
1116 sums[0] = 0;
1117 vector<long>::iterator itSums = sums.begin() + 1;
1118 partial_sum(vectorLengths.begin(), vectorLengths.end(), itSums);
1119 if (indata.size() < static_cast<size_t>(sums[nRows]))
1120 {
1121#ifdef SSTREAM_DEFECT
1122 ostrstream msgStr;
1123#else
1124 ostringstream msgStr;
1125#endif
1126 msgStr << " input data size: " << indata.size() << " vector length sum: " << sums[nRows];
1127#ifdef SSTREAM_DEFECT
1128 msgStr << std::ends;
1129#endif
1130
1131 String msg(msgStr.str());
1132 throw Column::InsufficientElements(msg);
1133 }
1134 vector<valarray<S> > vvArray(nRows);
1135 for (size_t iRow=0; iRow<nRows; ++iRow)
1136 {
1137 valarray<S>& vArray = vvArray[iRow];
1138 long first = sums[iRow];
1139 long last = sums[iRow+1];
1140 vArray.resize(last - first);
1141 for (long iElem=first; iElem<last; ++iElem)
1142 {
1143 vArray[iElem - first] = indata[iElem];
1144 }
1145 }
1146 writeArrays(vvArray, firstRow, static_cast<S*>(0));
1147 }
1148
1149template <typename S>
1150void Column::write (const std::vector<S>& indata,const std::vector<long>& vectorLengths,
1151 long firstRow)
1152 {
1153 // variable length write
1154 // implement as valarray version
1155 std::valarray<S> __tmp(indata.size());
1156 std::copy(indata.begin(),indata.end(),&__tmp[0]);
1157 write(__tmp,vectorLengths,firstRow);
1158
1159 }
1160
1161 template <typename S>
1162 void Column::write (S* indata, long nelements, const std::vector<long>& vectorLengths,
1163 long firstRow)
1164 {
1165 // implement as valarray version, which will also check array size.
1166 std::valarray<S> __tmp(indata,nelements);
1167 write(__tmp,vectorLengths,firstRow);
1168 }
1169
1170 template <typename S>
1171 void Column::write (const std::valarray<S>& indata, long nRows, long firstRow)
1172 {
1173 write(indata,nRows,firstRow,static_cast<S*>(0));
1174 }
1175
1176 template <typename S>
1177 void Column::write (const std::vector<S>& indata, long nRows, long firstRow)
1178 {
1179 write(indata,nRows,firstRow,static_cast<S*>(0));
1180 }
1181
1182 template <typename S>
1183 void Column::write (S* indata, long nelements, long nRows, long firstRow)
1184 {
1185 write(indata,nelements,nRows,firstRow,static_cast<S*>(0));
1186 }
1187
1188
1189
1190 template <typename S>
1191 void Column::write (const std::valarray<S>& indata, long nRows, long firstRow,
1192 S* nullValue)
1193 {
1194 // Write equivalent lengths of data to rows of a vector column.
1195 // The column may be either fixed or variable width, but if it's fixed
1196 // width the lengths must equal the column's repeat value or an
1197 // exception is thrown.
1198 if (nRows <= 0)
1199 throw InvalidNumberOfRows(nRows);
1200 firstRow = std::max(firstRow,static_cast<long>(1));
1201#ifdef SSTREAM_DEFECT
1202 std::ostrstream msgStr;
1203#else
1204 std::ostringstream msgStr;
1205#endif
1206 const size_t numRows = static_cast<size_t>(nRows);
1207 if (indata.size() % numRows)
1208 {
1209 msgStr << "To use this write function, input array size"
1210 <<"\n must be exactly divisible by requested num rows: "
1211 << nRows;
1212 throw InsufficientElements(msgStr.str());
1213 }
1214
1215 const size_t cellsize = indata.size()/numRows;
1216 if (!varLength() && cellsize != repeat() )
1217 {
1218 msgStr << "column: " << name()
1219 << "\n input data size: " << indata.size()
1220 << " required: " << nRows*repeat();
1221 String msg(msgStr.str());
1222 throw InsufficientElements(msg);
1223 }
1224
1225 std::vector<std::valarray<S> > vvArray(numRows);
1226 for (size_t i=0; i<numRows; ++i)
1227 {
1228 vvArray[i].resize(cellsize);
1229 vvArray[i] = indata[std::slice(cellsize*i,cellsize,1)];
1230 }
1231 writeArrays(vvArray, firstRow, nullValue);
1232 }
1233
1234 template <typename S>
1235 void Column::write (const std::vector<S>& indata, long nRows, long firstRow, S* nullValue)
1236 {
1237 // fixed length write of vector
1238 // implement as valarray version
1239 if (nRows <= 0) throw InvalidNumberOfRows(nRows);
1240 std::valarray<S> __tmp(indata.size());
1241 std::copy(indata.begin(),indata.end(),&__tmp[0]);
1242 write(__tmp,nRows,firstRow, nullValue);
1243 }
1244
1245 template <typename S>
1246 void Column::write (S* indata, long nelements, long nRows, long firstRow, S* nullValue)
1247 {
1248 // fixed length write of C-array
1249 // implement as valarray version
1250 if (nRows <= 0) throw InvalidNumberOfRows(nRows);
1251 std::valarray<S> __tmp(indata,nelements);
1252 write(__tmp,nRows,firstRow, nullValue);
1253 }
1254
1255
1256 template <typename S>
1257 void Column::writeArrays (const std::vector<std::valarray<S> >& indata, long firstRow)
1258 {
1259 // vector<valarray>, no null value.
1260 writeArrays(indata,firstRow,static_cast<S*>(0));
1261 }
1262
1263 template <typename S>
1264 void Column::writeArrays (const std::vector<std::valarray<S> >& indata, long firstRow,
1265 S* nullValue)
1266 {
1267 // vector<valarray>, null value. primary
1268
1269
1270 using std::valarray;
1271 using std::vector;
1273 firstRow = std::max(firstRow,static_cast<long>(1));
1274 if (ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
1275 {
1276 col->writeData(indata,firstRow,nullValue);
1277 }
1278 else
1279 {
1280 // alright, input data type has to be rewritten as output
1281 // data type.
1283 if ( inType() == type())
1284 {
1285 String msg("Incorrect call: writing vectors to scalar column ");
1286 throw WrongColumnType(msg);
1287 }
1288 else
1289 {
1290 size_t n(indata.size());
1291 if ( type() == Tdouble || type() == VTdouble)
1292 {
1293 ColumnVectorData<double>& col
1294 = dynamic_cast<ColumnVectorData<double>&>(*this);
1295 vector<valarray<double> > __tmp(n);
1296 for (size_t i = 0; i < n; ++i)
1297 {
1298 FITSUtil::fill(__tmp[i],indata[i]);
1299 }
1300 col.writeData(__tmp,firstRow);
1301 }
1302 else if ( type() == Tfloat || type() == VTfloat)
1303 {
1304 ColumnVectorData<float>& col
1305 = dynamic_cast<ColumnVectorData<float>&>(*this);
1306 vector<valarray<float> > __tmp(n);
1307 for (size_t i = 0; i < n; ++i)
1308 {
1309 FITSUtil::fill(__tmp[i],indata[i]);
1310 }
1311 col.writeData(__tmp,firstRow);
1312 }
1313 else if ( type() == Tint || type() == VTint)
1314 {
1315 ColumnVectorData<int>& col
1316 = dynamic_cast<ColumnVectorData<int>&>(*this);
1317 vector<valarray<int> > __tmp(n);
1318 int nullVal(0);
1319 int* pNullVal = 0;
1320 if (nullValue)
1321 {
1322 nullVal = static_cast<int>(*nullValue);
1323 pNullVal = &nullVal;
1324 }
1325 for (size_t i = 0; i < n; ++i)
1326 {
1327 FITSUtil::fill(__tmp[i],indata[i]);
1328 }
1329 col.writeData(__tmp,firstRow,pNullVal);
1330 }
1331 else if ( type() == Tshort || type() == VTshort)
1332 {
1333 ColumnVectorData<short>& col
1334 = dynamic_cast<ColumnVectorData<short>&>(*this);
1335 vector<valarray<short> > __tmp(n);
1336 short nullVal(0);
1337 short* pNullVal = 0;
1338 if (nullValue)
1339 {
1340 nullVal = static_cast<short>(*nullValue);
1341 pNullVal = &nullVal;
1342 }
1343 for (size_t i = 0; i < n; ++i)
1344 {
1345 FITSUtil::fill(__tmp[i],indata[i]);
1346 }
1347 col.writeData(__tmp,firstRow,pNullVal);
1348 }
1349 else if ( type() == Tlong || type() == VTlong)
1350 {
1351 ColumnVectorData<long>& col
1352 = dynamic_cast<ColumnVectorData<long>&>(*this);
1353 vector<valarray<long> > __tmp(n);
1354 long nullVal(0);
1355 long* pNullVal = 0;
1356 if (nullValue)
1357 {
1358 nullVal = static_cast<long>(*nullValue);
1359 pNullVal = &nullVal;
1360 }
1361 for (size_t i = 0; i < n; ++i)
1362 {
1363 FITSUtil::fill(__tmp[i],indata[i]);
1364 }
1365 col.writeData(__tmp,firstRow,pNullVal);
1366 }
1367 else if ( type() == Tlonglong || type() == VTlonglong)
1368 {
1369 ColumnVectorData<LONGLONG>& col
1370 = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
1371 vector<valarray<LONGLONG> > __tmp(n);
1372 LONGLONG nullVal(0);
1373 LONGLONG* pNullVal = 0;
1374 if (nullValue)
1375 {
1376 nullVal = static_cast<LONGLONG>(*nullValue);
1377 pNullVal = &nullVal;
1378 }
1379 for (size_t i = 0; i < n; ++i)
1380 {
1381 FITSUtil::fill(__tmp[i],indata[i]);
1382 }
1383 col.writeData(__tmp,firstRow,pNullVal);
1384 }
1385 else if ( type() == Tlogical || type() == VTlogical)
1386 {
1387 ColumnVectorData<bool>& col
1388 = dynamic_cast<ColumnVectorData<bool>&>(*this);
1389 bool nullVal(0);
1390 bool* pNullVal = 0;
1391 if (nullValue)
1392 {
1393 nullVal = static_cast<bool>(*nullValue);
1394 pNullVal = &nullVal;
1395 }
1396 vector<valarray<bool> > __tmp(n);
1397 for (size_t i = 0; i < n; ++i)
1398 {
1399 FITSUtil::fill(__tmp[i],indata[i]);
1400 }
1401 col.writeData(__tmp,firstRow,pNullVal);
1402 }
1403 else if ( type() == Tbyte || type() == VTbyte)
1404 {
1405 ColumnVectorData<unsigned char>& col
1406 = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
1407 unsigned char nullVal(0);
1408 unsigned char* pNullVal = 0;
1409 if (nullValue)
1410 {
1411 nullVal = static_cast<unsigned char>(*nullValue);
1412 pNullVal = &nullVal;
1413 }
1414 vector<valarray<unsigned char> > __tmp(n);
1415 for (size_t i = 0; i < n; ++i)
1416 {
1417 FITSUtil::fill(__tmp[i],indata[i]);
1418 }
1419 col.writeData(__tmp,firstRow,pNullVal);
1420 }
1421 else if ( type() == Tushort || type() == VTushort)
1422 {
1423 ColumnVectorData<unsigned short>& col
1424 = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
1425 unsigned short nullVal(0);
1426 unsigned short* pNullVal = 0;
1427 if (nullValue)
1428 {
1429 nullVal = static_cast<unsigned short>(*nullValue);
1430 pNullVal = &nullVal;
1431 }
1432 vector<valarray<unsigned short> > __tmp(n);
1433 for (size_t i = 0; i < n; ++i)
1434 {
1435 FITSUtil::fill(__tmp[i],indata[i]);
1436 }
1437 col.writeData(__tmp,firstRow,pNullVal);
1438 }
1439 else if ( type() == Tuint || type() == VTuint)
1440 {
1441 ColumnVectorData<unsigned int>& col
1442 = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
1443 unsigned int nullVal(0);
1444 unsigned int* pNullVal = 0;
1445 if (nullValue)
1446 {
1447 nullVal = static_cast<unsigned int>(*nullValue);
1448 pNullVal = &nullVal;
1449 }
1450 vector<valarray<unsigned int> > __tmp(n);
1451 for (size_t i = 0; i < n; ++i)
1452 {
1453 FITSUtil::fill(__tmp[i],indata[i]);
1454 }
1455 col.writeData(__tmp,firstRow,pNullVal);
1456 }
1457 else if ( type() == Tulong || type() == VTulong)
1458 {
1459 ColumnVectorData<unsigned long>& col
1460 = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
1461 unsigned long nullVal(0);
1462 unsigned long* pNullVal = 0;
1463 if (nullValue)
1464 {
1465 nullVal = static_cast<unsigned long>(*nullValue);
1466 pNullVal = &nullVal;
1467 }
1468 vector<valarray<unsigned long> > __tmp(n);
1469 for (size_t i = 0; i < n; ++i)
1470 {
1471 FITSUtil::fill(__tmp[i],indata[i]);
1472 }
1473 col.writeData(__tmp,firstRow,pNullVal);
1474 }
1475 else
1476 {
1477 throw InvalidDataType(name());
1478 }
1479 }
1480 }
1481 }
1482
1483
1484 template <typename T>
1485 void Column::addNullValue(T nullVal)
1486 {
1488 int status(0);
1489#ifdef SSTREAM_DEFECT
1490 std::ostrstream keyName;
1491 keyName << "TNULL" << index() << std::ends;
1492 char* nullKey = const_cast<char*>(keyName.str());
1493#else
1494 std::ostringstream keyName;
1495 keyName << "TNULL" << index();
1496 String keyNameStr = keyName.str();
1497 char* nullKey = const_cast<char*>(keyNameStr.c_str());
1498#endif
1499
1500
1501 FITSUtil::MatchType<T> inputType;
1502 int dataType = static_cast<int>(inputType());
1503 if (dataType == static_cast<int>(Tstring))
1504 throw InvalidDataType("attempting to set TNULLn to a string.");
1505
1506 // update key but don't add to keyword list because it's really a column
1507 // property not a table metadata property. And it needs to be automatically
1508 // renumbered if columns are inserted or deleted.
1509 if (fits_update_key(fitsPointer(),dataType,nullKey,&nullVal,0,&status))
1510 throw FitsError(status);
1511
1512 // The following is called to make sure the HDU struct is immediately
1513 // updated in case a column write operation is performed shortly after this
1514 // function exits.
1515 if (fits_set_hdustruc(fitsPointer(),&status)) throw FitsError(status);
1516
1517 }
1518
1519 template <typename T>
1520 bool Column::getNullValue(T* nullVal) const
1521 {
1523#ifdef SSTREAM_DEFECT
1524 std::ostrstream keyName;
1525 keyName << "TNULL" << index() << std::ends;
1526 char* nullKey = const_cast<char*>(keyName.str());
1527#else
1528 std::ostringstream keyName;
1529 keyName << "TNULL" << index();
1530 String keyNameStr = keyName.str();
1531 char* nullKey = const_cast<char*>(keyNameStr.c_str());
1532#endif
1533
1534 int status=0;
1535 FITSUtil::MatchType<T> inputType;
1536 int dataType = static_cast<int>(inputType());
1537 if (dataType == static_cast<int>(Tstring))
1538 throw InvalidDataType("attempting to read TNULLn into a string.");
1539 T tmpVal(*nullVal);
1540
1541 bool keyExists = false;
1542 if (fits_read_key(m_parent->fitsPointer(), dataType, nullKey, &tmpVal, 0, &status))
1543 {
1544 if (status == KEY_NO_EXIST || status == VALUE_UNDEFINED)
1545 return keyExists;
1546 else
1547 throw FitsError(status);
1548 }
1549 keyExists = true;
1550 *nullVal = tmpVal;
1551 return keyExists;
1552 }
1553
1554} // namespace CCfits
1555
1556#endif
Exception thrown if the data supplied for a write operation is less than declared.
Definition Column.h:921
Exception thrown for invalid data type inputs.
Definition Column.h:861
Exception thrown if user enters a non-positive number for the number of rows to write.
Definition Column.h:945
Exception thrown on attempting to read a row number beyond the end of a table.
Definition Column.h:909
Exception thrown on attempting to access a scalar column as vector data.
Definition Column.h:885
ValueType type() const
returns the data type of the column
Definition Column.h:1437
void addNullValue(T nullVal)
Set the TNULLn keyword for the column.
Definition ColumnT.h:1485
bool getNullValue(T *nullVal) const
Get the value of the TNULLn keyword for the column.
Definition ColumnT.h:1520
void readArrays(std::vector< std::valarray< S > > &vals, long first, long last)
return a set of rows of a vector column into a vector of valarrays
Definition ColumnT.h:680
int rows() const
return the number of rows in the table.
Definition Column.cxx:275
void write(const std::vector< S > &indata, long firstRow)
write a vector of values into a scalar column starting with firstRow
Definition ColumnT.h:869
Table * parent() const
return a pointer to the Table which owns this Column
Definition Column.cxx:312
const String & name() const
return name of Column (TTYPEn keyword)
Definition Column.h:1532
size_t repeat() const
get the repeat count for the rows
Definition Column.h:1390
bool isRead() const
flag set to true if the entire column data has been read from disk
Definition Column.h:1370
int index() const
get the Column index (the n in TTYPEn etc).
Definition Column.h:1360
void read(std::vector< S > &vals, long first, long last)
Retrieve data from a scalar column into a std::vector.
Definition ColumnT.h:42
bool varLength() const
boolean, set to true if Column has variable length vector rows.
Definition Column.h:1395
fitsfile * fitsPointer()
fits pointer corresponding to fits file containing column data.
Definition Column.cxx:264
void writeArrays(const std::vector< std::valarray< S > > &indata, long firstRow)
write a vector of valarray objects to the column, starting at row firstRow >= 1
Definition ColumnT.h:1257
virtual void makeThisCurrent() const
move the fitsfile pointer to this current HDU.
Definition ExtHDU.cxx:208
FitsError is the exception thrown by non-zero cfitsio status codes.
Definition FitsError.h:113
fitsfile * fitsPointer() const
return the fitsfile pointer for the FITS object containing the HDU
Definition HDU.cxx:308
Namespace enclosing all CCfits classes and globals definitions.
Definition AsciiTable.cxx:26
function object that returns the FITS ValueType corresponding to an input intrinsic type
Definition FITSUtil.h:506