CCfits  2.4
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.
33 using std::complex;
34 using 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 
39 namespace 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);
209  parent()->makeThisCurrent();
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.
227  throw Column::WrongColumnType(name());
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 
359 
360  template <typename S>
361  void Column::read(std::valarray<S>& vals, long row, S* nullValue)
362  {
363  if (row > parent()->rows())
364  {
366  }
367  parent()->makeThisCurrent();
368  // isRead() returns true if the data were read in the ctor.
369  if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
370  {
371  // fails if user requested outputType different from input type.
372 
373 
374 
375  // input and output are both valarrays. Since one should not
376  // be able to call a constructor for a non-numeric valarray type,
377  // there shouldn't be any InvalidType problems. However, there
378  // is still the vector/scalar possibility and the implicit
379  // conversion request to deal with.
380 
381  if (!isRead()) col->readRow(row,nullValue);
382  FITSUtil::fill(vals,col->data(row));
383  }
384  else
385  {
386  FITSUtil::MatchType<S> outputType;
387  if ( outputType() == type() )
388  {
389  // in this case user tried to read vector row from scalar column.
390  // one could be charitable and return a valarray of size 1,
391  // but... I'm going to throw an exception suggesting the user
392  // might not have meant that.
393 
394  throw Column::WrongColumnType(name());
395  }
396 
397  // the InvalidDataType exception should not be possible.
398  try
399  {
400  // about exceptions. The dynamic_casts could throw
401  // std::bad_cast. If this happens something is seriously
402  // wrong since the Column stores the value of type()
403  // appropriate to each of the casts on construction.
404  //
405  // the InvalidDataType exception should not be possible.
406  if ( type() == Tdouble || type() == VTdouble )
407  {
408  ColumnVectorData<double>& col
409  = dynamic_cast<ColumnVectorData<double>&>(*this);
410  if (!isRead()) col.readRow(row);
411  FITSUtil::fill(vals,col.data(row));
412 
413  }
414  else if (type() == Tfloat || type() == VTfloat )
415  {
416  ColumnVectorData<float>& col
417  = dynamic_cast<ColumnVectorData<float>&>(*this);
418  if (!isRead()) col.readRow(row);
419  FITSUtil::fill(vals,col.data(row));
420  }
421  else if (type() == Tint || type() == VTint )
422  {
423  int nullVal(0);
424  if (nullValue) nullVal = static_cast<int>(*nullValue);
425  ColumnVectorData<int>& col
426  = dynamic_cast<ColumnVectorData<int>&>(*this);
427  if (!isRead()) col.readRow(row,&nullVal);
428  FITSUtil::fill(vals,col.data(row));
429  }
430  else if (type() == Tshort || type() == VTshort )
431  {
432  short nullVal(0);
433  if (nullValue) nullVal = static_cast<short>(*nullValue);
434  ColumnVectorData<short>& col
435  = dynamic_cast<ColumnVectorData<short>&>(*this);
436  if (!isRead()) col.readRow(row,&nullVal);
437  FITSUtil::fill(vals,col.data(row));
438  }
439  else if (type() == Tlong || type() == VTlong )
440  {
441  long nullVal(0);
442  if (nullValue) nullVal = static_cast<long>(*nullValue);
443  ColumnVectorData<long>& col
444  = dynamic_cast<ColumnVectorData<long>&>(*this);
445  if (!isRead()) col.readRow(row,&nullVal);
446  FITSUtil::fill(vals,col.data(row));
447  }
448  else if (type() == Tlonglong || type() == VTlonglong )
449  {
450  LONGLONG nullVal(0);
451  if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
452  ColumnVectorData<LONGLONG>& col
453  = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
454  if (!isRead()) col.readRow(row,&nullVal);
455  FITSUtil::fill(vals,col.data(row));
456  }
457  else if (type() == Tlogical || type() == VTlogical )
458  {
459  bool nullVal(0);
460  if (nullValue) nullVal = static_cast<bool>(*nullValue);
461  ColumnVectorData<bool>& col
462  = dynamic_cast<ColumnVectorData<bool>&>(*this);
463  if (!isRead()) col.readRow(row,&nullVal);
464  FITSUtil::fill(vals,col.data(row));
465  }
466  else if (type() == Tbit || type() == Tbyte ||
467  type() == VTbit || type() == VTbyte )
468  {
469  unsigned char nullVal(0);
470  if (nullValue) nullVal
471  = static_cast<unsigned char>(*nullValue);
472  ColumnVectorData<unsigned char>& col
473  = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
474  if (!isRead()) col.readRow(row,&nullVal);
475  FITSUtil::fill(vals,col.data(row));
476  }
477  else if (type() == Tushort || type() == VTushort)
478  {
479  unsigned short nullVal(0);
480  if (nullValue) nullVal
481  = static_cast<unsigned short>(*nullValue);
482  ColumnVectorData<unsigned short>& col
483  = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
484  if (!isRead()) col.readRow(row,&nullVal);
485  FITSUtil::fill(vals,col.data(row));
486  }
487  else if (type() == Tuint || type() == VTuint)
488  {
489  unsigned int nullVal(0);
490  if (nullValue) nullVal
491  = static_cast<unsigned int>(*nullValue);
492  ColumnVectorData<unsigned int>& col
493  = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
494  if (!isRead()) col.readRow(row,&nullVal);
495  FITSUtil::fill(vals,col.data(row));
496  }
497  else if (type() == Tulong || type() == VTulong)
498  {
499  unsigned long nullVal(0);
500  if (nullValue) nullVal
501  = static_cast<unsigned long>(*nullValue);
502  ColumnVectorData<unsigned long>& col
503  = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
504  if (!isRead()) col.readRow(row,&nullVal);
505  FITSUtil::fill(vals,col.data(row));
506  }
507  else
508  {
509  throw InvalidDataType(name());
510 
511  }
512 
513  }
514  catch (std::bad_cast)
515  {
516  throw WrongColumnType(name());
517  }
518  }
519  }
520 
521  template <typename S>
522  void Column::readArrays(std::vector<std::valarray<S> >& vals, long first, long last)
523  {
524  readArrays(vals,first,last,static_cast<S*>(0));
525  }
526 
527  template <typename S>
528  void Column::readArrays(std::vector<std::valarray<S> >& vals,
529  long first, long last, S* nullValue)
530  {
531 
532  parent()->makeThisCurrent();
533  // again, can only call this if the entire column has been read from disk.
534  // user expects 1 based indexing. If 0 based indices are supplied,
535  // add one to both ranges.
536  long range = numberOfElements(first,last);
537 
538  vals.resize(range);
539 
540 
541  if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
542  {
543  for (int j = 0; j < range; ++j)
544  {
545  if (!isRead()) col->readRow(j + first,nullValue);
546  FITSUtil::fill(vals[j],col->data(j+first));
547  }
548  }
549  else
550  {
551  FITSUtil::MatchType<S> outputType;
552  if ( outputType() == type() )
553  {
554  // in this case user tried to read vector data from scalar,
555  // (i.e. first argument was vector<valarray<S> >.
556  // since the cast won't fail on template parameter grounds.
557  throw Column::WrongColumnType(name());
558  }
559  // the InvalidDataType exception should not be possible.
560  try
561  {
562  if ( type() == Tdouble || type() == VTdouble )
563  {
564  ColumnVectorData<double>& col
565  = dynamic_cast<ColumnVectorData<double>&>(*this);
566  for (int j = 0; j < range; ++j)
567  {
568  if (!isRead()) col.readRow(j + first);
569  FITSUtil::fill(vals[j],col.data(j+first));
570  }
571  }
572  else if ( type() == Tfloat || type() == VTfloat )
573  {
574  ColumnVectorData<float>& col
575  = dynamic_cast<ColumnVectorData<float>&>(*this);
576  for (int j = 0; j < range; ++j)
577  {
578  if (!isRead()) col.readRow(j + first);
579  FITSUtil::fill(vals[j],col.data(j+first));
580  }
581  }
582  else if ( type() == Tint || type() == VTint )
583  {
584  int nullVal(0);
585  if (nullValue) nullVal = static_cast<int>(*nullValue);
586  ColumnVectorData<int>& col
587  = dynamic_cast<ColumnVectorData<int>&>(*this);
588  for (int j = 0; j < range; ++j)
589  {
590  if (!isRead()) col.readRow(j + first,&nullVal);
591  FITSUtil::fill(vals[j],col.data(j+first));
592  }
593  }
594  else if ( type() == Tshort || type() == VTshort )
595  {
596  short nullVal(0);
597  if (nullValue) nullVal = static_cast<short>(*nullValue);
598  ColumnVectorData<short>& col
599  = dynamic_cast<ColumnVectorData<short>&>(*this);
600  for (int j = 0; j < range; ++j)
601  {
602  if (!isRead()) col.readRow(j + first,&nullVal);
603  FITSUtil::fill(vals[j],col.data(j+first));
604  }
605  }
606  else if ( type() == Tlong || type() == VTlong )
607  {
608  long nullVal(0);
609  if (nullValue) nullVal = static_cast<long>(*nullValue);
610  ColumnVectorData<long>& col
611  = dynamic_cast<ColumnVectorData<long>&>(*this);
612  for (int j = 0; j < range; ++j)
613  {
614  if (!isRead()) col.readRow(j + first,&nullVal);
615  FITSUtil::fill(vals[j],col.data(j+first));
616  }
617  }
618  else if ( type() == Tlonglong || type() == VTlonglong )
619  {
620  LONGLONG nullVal(0);
621  if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue);
622  ColumnVectorData<LONGLONG>& col
623  = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
624  for (int j = 0; j < range; ++j)
625  {
626  if (!isRead()) col.readRow(j + first,&nullVal);
627  FITSUtil::fill(vals[j],col.data(j+first));
628  }
629  }
630  else if ( type() == Tlogical || type() == VTlogical )
631  {
632  bool nullVal(0);
633  if (nullValue) nullVal = static_cast<bool>(*nullValue);
634  ColumnVectorData<bool>& col
635  = dynamic_cast<ColumnVectorData<bool>&>(*this);
636  for (int j = 0; j < range; ++j)
637  {
638  if (!isRead()) col.readRow(j + first,&nullVal);
639  FITSUtil::fill(vals[j],col.data(j+first));
640  }
641  }
642  else if (type() == Tbit || type() == Tbyte ||
643  type() == VTbit || type() == VTbyte )
644  {
645  unsigned char nullVal(0);
646  if (nullValue) nullVal
647  = static_cast<unsigned char>(*nullValue);
648  ColumnVectorData<unsigned char>& col
649  = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
650  for (int j = 0; j < range; ++j)
651  {
652  if (!isRead()) col.readRow(j + first,&nullVal);
653  FITSUtil::fill(vals[j],col.data(j+first));
654  }
655  }
656  else if ( type() == Tushort || type() == VTushort )
657  {
658  unsigned short nullVal(0);
659  if (nullValue) nullVal
660  = static_cast<unsigned short>(*nullValue);
661  ColumnVectorData<unsigned short>& col
662  = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
663  for (int j = 0; j < range; ++j)
664  {
665  if (!isRead()) col.readRow(j + first,&nullVal);
666  FITSUtil::fill(vals[j],col.data(j+first));
667  }
668  }
669  else if ( type() == Tuint || type() == VTuint )
670  {
671  unsigned int nullVal(0);
672  if (nullValue) nullVal
673  = static_cast<unsigned int>(*nullValue);
674  ColumnVectorData<unsigned int>& col
675  = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
676  for (int j = 0; j < range; ++j)
677  {
678  if (!isRead()) col.readRow(j + first,&nullVal);
679  FITSUtil::fill(vals[j],col.data(j+first));
680  }
681  }
682  else if ( type() == Tulong || type() == VTulong )
683  {
684  unsigned long nullVal(0);
685  if (nullValue) nullVal
686  = static_cast<unsigned long>(*nullValue);
687  ColumnVectorData<unsigned long>& col
688  = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
689  for (int j = 0; j < range; ++j)
690  {
691  if (!isRead()) col.readRow(j + first,&nullVal);
692  FITSUtil::fill(vals[j],col.data(j+first));
693  }
694  }
695  else
696  {
697  throw InvalidDataType(name());
698  }
699 
700  }
701  catch (std::bad_cast)
702  {
703  throw WrongColumnType(name());
704 
705  }
706 
707  }
708  }
709 
710  template <typename S>
711  void Column::write (const std::vector<S>& indata, long firstRow)
712  {
713  // nullValue is now a pointer, so this is ok.
714  // got to cast the 0 to a pointer to S to avoid
715  // overloading ambiguities.
716  write(indata,firstRow,static_cast<S*>(0));
717  }
718 
719  template <typename S>
720  void Column::write (const std::valarray<S>& indata, long firstRow)
721  {
722  size_t n(indata.size());
723  std::vector<S> __tmp(n);
724  for (size_t j = 0; j < n; ++j) __tmp[j] = indata[j];
725  write(__tmp,firstRow,static_cast<S*>(0));
726  }
727 
728  template <typename S>
729  void Column::write (S* indata, long nRows, long firstRow)
730  {
731  write(indata,nRows,firstRow,static_cast<S*>(0));
732  }
733 
734 
735  template <typename S>
736  void Column::write (const std::vector<S>& indata, long firstRow, S* nullValue)
737  {
738  // although underlying code needs to convert the input vector
739  // into a C array, this must be the underlying implementation
740  // [which the others call] because it accepts string arguments
741  // which the version with a pointer won't. [no version that
742  // translates to a char** argument].
743 
744 
745  parent()->makeThisCurrent();
746  firstRow = std::max(firstRow,static_cast<long>(1));
747  if (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this))
748  {
749  col->writeData(indata,firstRow,nullValue);
750  }
751  else
752  {
753  // alright, input data type has to be rewritten as output
754  // data type.
755  FITSUtil::MatchType<S> inType;
756  if ( inType() == type())
757  {
758  String msg("Incorrect call: writing to vector column ");
759  msg += name();
760  msg += " requires specification of # rows or vector lengths";
761  throw WrongColumnType(msg);
762  }
763  else
764  {
765  if ( type() == Tdouble )
766  {
767  ColumnData<double>& col
768  = dynamic_cast<ColumnData<double>&>(*this);
769  std::vector<double> __tmp;
770  FITSUtil::fill(__tmp,indata,1,indata.size());
771  col.writeData(__tmp,firstRow);
772  }
773  else if ( type() == Tfloat )
774  {
775  ColumnData<float>& col
776  = dynamic_cast<ColumnData<float>&>(*this);
777  std::vector<float> __tmp;
778  FITSUtil::fill(__tmp,indata,1,indata.size());
779  col.writeData(__tmp,firstRow);
780  }
781  else if ( type() == Tint )
782  {
783  int nullVal = 0;
784  int* pNullVal = 0;
785  if (nullValue)
786  {
787  nullVal = static_cast<int>(*nullValue);
788  pNullVal = &nullVal;
789  }
790  if (nullValue) nullVal = static_cast<int>(*nullValue);
791  ColumnData<int>& col
792  = dynamic_cast<ColumnData<int>&>(*this);
793  std::vector<int> __tmp;
794  FITSUtil::fill(__tmp,indata,1,indata.size());
795  col.writeData(__tmp,firstRow,pNullVal);
796  }
797  else if ( type() == Tshort )
798  {
799  short nullVal(0);
800  short* pNullVal = 0;
801  if (nullValue)
802  {
803  nullVal = static_cast<short>(*nullValue);
804  pNullVal = &nullVal;
805  }
806  ColumnData<short>& col
807  = dynamic_cast<ColumnData<short>&>(*this);
808  std::vector<short> __tmp;
809  FITSUtil::fill(__tmp,indata,1,indata.size());
810  col.writeData(__tmp,firstRow,pNullVal);
811  }
812  else if ( type() == Tlong )
813  {
814  long nullVal(0);
815  long* pNullVal = 0;
816  if (nullValue)
817  {
818  nullVal = static_cast<long>(*nullValue);
819  pNullVal = &nullVal;
820  }
821  ColumnData<long>& col
822  = dynamic_cast<ColumnData<long>&>(*this);
823  std::vector<long> __tmp;
824  FITSUtil::fill(__tmp,indata,1,indata.size());
825  col.writeData(__tmp,firstRow,pNullVal);
826  }
827  else if ( type() == Tlonglong )
828  {
829  LONGLONG nullVal(0);
830  LONGLONG* pNullVal = 0;
831  if (nullValue)
832  {
833  nullVal = static_cast<LONGLONG>(*nullValue);
834  pNullVal = &nullVal;
835  }
836  ColumnData<LONGLONG>& col
837  = dynamic_cast<ColumnData<LONGLONG>&>(*this);
838  std::vector<LONGLONG> __tmp;
839  FITSUtil::fill(__tmp,indata,1,indata.size());
840  col.writeData(__tmp,firstRow,pNullVal);
841  }
842  else if ( type() == Tlogical )
843  {
844  bool nullVal(0);
845  bool* pNullVal = 0;
846  if (nullValue)
847  {
848  nullVal = static_cast<bool>(*nullValue);
849  pNullVal = &nullVal;
850  }
851  ColumnData<bool>& col
852  = dynamic_cast<ColumnData<bool>&>(*this);
853  std::vector<bool> __tmp;
854  FITSUtil::fill(__tmp,indata,1,indata.size());
855  col.writeData(__tmp,firstRow,pNullVal);
856  }
857  else if ( type() == Tbyte )
858  {
859  unsigned char nullVal(0);
860  unsigned char* pNullVal = 0;
861  if (nullValue)
862  {
863  nullVal = static_cast<unsigned char>(*nullValue);
864  pNullVal = &nullVal;
865  }
866  ColumnData<unsigned char>& col
867  = dynamic_cast<ColumnData<unsigned char>&>(*this);
868  std::vector<unsigned char> __tmp;
869  FITSUtil::fill(__tmp,indata,1,indata.size());
870  col.writeData(__tmp,firstRow,pNullVal);
871  }
872  else if ( type() == Tushort )
873  {
874  unsigned short nullVal(0);
875  unsigned short* pNullVal = 0;
876  if (nullValue)
877  {
878  nullVal = static_cast<unsigned short>(*nullValue);
879  pNullVal = &nullVal;
880  }
881  ColumnData<unsigned short>& col
882  = dynamic_cast<ColumnData<unsigned short>&>(*this);
883  std::vector<unsigned short> __tmp;
884  FITSUtil::fill(__tmp,indata,1,indata.size());
885  col.writeData(__tmp,firstRow,pNullVal);
886  }
887  else if ( type() == Tuint )
888  {
889  unsigned int nullVal(0);
890  unsigned int* pNullVal = 0;
891  if (nullValue)
892  {
893  nullVal = static_cast<unsigned int>(*nullValue);
894  pNullVal = &nullVal;
895  }
896  ColumnData<unsigned int>& col
897  = dynamic_cast<ColumnData<unsigned int>&>(*this);
898  std::vector<unsigned int> __tmp;
899  FITSUtil::fill(__tmp,indata,1,indata.size());
900  col.writeData(__tmp,firstRow,pNullVal);
901  }
902  else if ( type() == Tulong )
903  {
904  unsigned long nullVal(0);
905  unsigned long* pNullVal = 0;
906  if (nullValue)
907  {
908  nullVal = static_cast<unsigned long>(*nullValue);
909  pNullVal = &nullVal;
910  }
911  ColumnData<unsigned long>& col
912  = dynamic_cast<ColumnData<unsigned long>&>(*this);
913  std::vector<unsigned long> __tmp;
914  FITSUtil::fill(__tmp,indata,1,indata.size());
915  col.writeData(__tmp,firstRow,pNullVal);
916  }
917  else
918  {
919  throw InvalidDataType(name());
920  }
921  }
922  }
923  }
924 
925 
926  template <typename S>
927  void Column::write (const std::valarray<S>& indata, long firstRow, S* nullValue)
928  {
929  // for scalar columns.
930  std::vector<S> __tmp;
931  FITSUtil::fill(__tmp,indata);
932  write(__tmp,firstRow,nullValue);
933  }
934 
935  template <typename S>
936  void Column::write (S* indata, long nRows, long firstRow, S* nullValue)
937  {
938  // for scalar columns, data specified with C array
939  if (nRows <= 0) throw InvalidNumberOfRows(nRows);
940  std::vector<S> __tmp(nRows);
941  std::copy(&indata[0],&indata[nRows],__tmp.begin());
942  write(__tmp,firstRow, nullValue);
943 
944  }
945 
946  template <typename S>
947  void Column::write (const std::valarray<S>& indata, const std::vector<long>& vectorLengths,
948  long firstRow)
949  {
950  // variable length arrays written from an input valarray.
951  // does not allow NULL value.
952 
953  using namespace std;
954  const size_t nRows = vectorLengths.size();
955  // Calculate the sums of the vector lengths first simply to do a
956  // check against the size of indata.
957  vector<long> sums(nRows+1);
958  sums[0] = 0;
959  vector<long>::iterator itSums = sums.begin() + 1;
960  partial_sum(vectorLengths.begin(), vectorLengths.end(), itSums);
961  if (indata.size() < static_cast<size_t>(sums[nRows]))
962  {
963 #ifdef SSTREAM_DEFECT
964  ostrstream msgStr;
965 #else
966  ostringstream msgStr;
967 #endif
968  msgStr << " input data size: " << indata.size() << " vector length sum: " << sums[nRows];
969 #ifdef SSTREAM_DEFECT
970  msgStr << std::ends;
971 #endif
972 
973  String msg(msgStr.str());
974  throw Column::InsufficientElements(msg);
975  }
976  vector<valarray<S> > vvArray(nRows);
977  for (size_t iRow=0; iRow<nRows; ++iRow)
978  {
979  valarray<S>& vArray = vvArray[iRow];
980  long first = sums[iRow];
981  long last = sums[iRow+1];
982  vArray.resize(last - first);
983  for (long iElem=first; iElem<last; ++iElem)
984  {
985  vArray[iElem - first] = indata[iElem];
986  }
987  }
988  writeArrays(vvArray, firstRow, static_cast<S*>(0));
989  }
990 
991 template <typename S>
992 void Column::write (const std::vector<S>& indata,const std::vector<long>& vectorLengths,
993  long firstRow)
994  {
995  // variable length write
996  // implement as valarray version
997  std::valarray<S> __tmp(indata.size());
998  std::copy(indata.begin(),indata.end(),&__tmp[0]);
999  write(__tmp,vectorLengths,firstRow);
1000 
1001  }
1002 
1003  template <typename S>
1004  void Column::write (S* indata, long nelements, const std::vector<long>& vectorLengths,
1005  long firstRow)
1006  {
1007  // implement as valarray version, which will also check array size.
1008  size_t n(vectorLengths.size());
1009  std::valarray<S> __tmp(indata,nelements);
1010  write(__tmp,vectorLengths,firstRow);
1011  }
1012 
1013  template <typename S>
1014  void Column::write (const std::valarray<S>& indata, long nRows, long firstRow)
1015  {
1016  write(indata,nRows,firstRow,static_cast<S*>(0));
1017  }
1018 
1019  template <typename S>
1020  void Column::write (const std::vector<S>& indata, long nRows, long firstRow)
1021  {
1022  write(indata,nRows,firstRow,static_cast<S*>(0));
1023  }
1024 
1025  template <typename S>
1026  void Column::write (S* indata, long nelements, long nRows, long firstRow)
1027  {
1028  write(indata,nelements,nRows,firstRow,static_cast<S*>(0));
1029  }
1030 
1031 
1032 
1033  template <typename S>
1034  void Column::write (const std::valarray<S>& indata, long nRows, long firstRow,
1035  S* nullValue)
1036  {
1037  // Write equivalent lengths of data to rows of a vector column.
1038  // The column may be either fixed or variable width, but if it's fixed
1039  // width the lengths must equal the column's repeat value or an
1040  // exception is thrown.
1041  if (nRows <= 0)
1042  throw InvalidNumberOfRows(nRows);
1043  firstRow = std::max(firstRow,static_cast<long>(1));
1044 #ifdef SSTREAM_DEFECT
1045  std::ostrstream msgStr;
1046 #else
1047  std::ostringstream msgStr;
1048 #endif
1049  const size_t numRows = static_cast<size_t>(nRows);
1050  if (indata.size() % numRows)
1051  {
1052  msgStr << "To use this write function, input array size"
1053  <<"\n must be exactly divisible by requested num rows: "
1054  << nRows;
1055  throw InsufficientElements(msgStr.str());
1056  }
1057 
1058  const size_t cellsize = indata.size()/numRows;
1059  if (!varLength() && cellsize != repeat() )
1060  {
1061  msgStr << "column: " << name()
1062  << "\n input data size: " << indata.size()
1063  << " required: " << nRows*repeat();
1064  String msg(msgStr.str());
1065  throw InsufficientElements(msg);
1066  }
1067 
1068  std::vector<std::valarray<S> > vvArray(numRows);
1069  for (size_t i=0; i<numRows; ++i)
1070  {
1071  vvArray[i].resize(cellsize);
1072  vvArray[i] = indata[std::slice(cellsize*i,cellsize,1)];
1073  }
1074  writeArrays(vvArray, firstRow, nullValue);
1075  }
1076 
1077  template <typename S>
1078  void Column::write (const std::vector<S>& indata, long nRows, long firstRow, S* nullValue)
1079  {
1080  // fixed length write of vector
1081  // implement as valarray version
1082  if (nRows <= 0) throw InvalidNumberOfRows(nRows);
1083  std::valarray<S> __tmp(indata.size());
1084  std::copy(indata.begin(),indata.end(),&__tmp[0]);
1085  write(__tmp,nRows,firstRow, nullValue);
1086  }
1087 
1088  template <typename S>
1089  void Column::write (S* indata, long nelements, long nRows, long firstRow, S* nullValue)
1090  {
1091  // fixed length write of C-array
1092  // implement as valarray version
1093  if (nRows <= 0) throw InvalidNumberOfRows(nRows);
1094  std::valarray<S> __tmp(indata,nelements);
1095  write(__tmp,nRows,firstRow, nullValue);
1096  }
1097 
1098 
1099  template <typename S>
1100  void Column::writeArrays (const std::vector<std::valarray<S> >& indata, long firstRow)
1101  {
1102  // vector<valarray>, no null value.
1103  writeArrays(indata,firstRow,static_cast<S*>(0));
1104  }
1105 
1106  template <typename S>
1107  void Column::writeArrays (const std::vector<std::valarray<S> >& indata, long firstRow,
1108  S* nullValue)
1109  {
1110  // vector<valarray>, null value. primary
1111 
1112 
1113  using std::valarray;
1114  using std::vector;
1115  parent()->makeThisCurrent();
1116  firstRow = std::max(firstRow,static_cast<long>(1));
1117  if (ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this))
1118  {
1119  col->writeData(indata,firstRow,nullValue);
1120  }
1121  else
1122  {
1123  // alright, input data type has to be rewritten as output
1124  // data type.
1125  FITSUtil::MatchType<S> inType;
1126  if ( inType() == type())
1127  {
1128  String msg("Incorrect call: writing vectors to scalar column ");
1129  throw WrongColumnType(msg);
1130  }
1131  else
1132  {
1133  size_t n(indata.size());
1134  if ( type() == Tdouble || type() == VTdouble)
1135  {
1136  ColumnVectorData<double>& col
1137  = dynamic_cast<ColumnVectorData<double>&>(*this);
1138  vector<valarray<double> > __tmp(n);
1139  for (size_t i = 0; i < n; ++i)
1140  {
1141  FITSUtil::fill(__tmp[i],indata[i]);
1142  }
1143  col.writeData(__tmp,firstRow);
1144  }
1145  else if ( type() == Tfloat || type() == VTfloat)
1146  {
1147  ColumnVectorData<float>& col
1148  = dynamic_cast<ColumnVectorData<float>&>(*this);
1149  vector<valarray<float> > __tmp(n);
1150  for (size_t i = 0; i < n; ++i)
1151  {
1152  FITSUtil::fill(__tmp[i],indata[i]);
1153  }
1154  col.writeData(__tmp,firstRow);
1155  }
1156  else if ( type() == Tint || type() == VTint)
1157  {
1158  ColumnVectorData<int>& col
1159  = dynamic_cast<ColumnVectorData<int>&>(*this);
1160  vector<valarray<int> > __tmp(n);
1161  int nullVal(0);
1162  int* pNullVal = 0;
1163  if (nullValue)
1164  {
1165  nullVal = static_cast<int>(*nullValue);
1166  pNullVal = &nullVal;
1167  }
1168  for (size_t i = 0; i < n; ++i)
1169  {
1170  FITSUtil::fill(__tmp[i],indata[i]);
1171  }
1172  col.writeData(__tmp,firstRow,pNullVal);
1173  }
1174  else if ( type() == Tshort || type() == VTshort)
1175  {
1176  ColumnVectorData<short>& col
1177  = dynamic_cast<ColumnVectorData<short>&>(*this);
1178  vector<valarray<short> > __tmp(n);
1179  short nullVal(0);
1180  short* pNullVal = 0;
1181  if (nullValue)
1182  {
1183  nullVal = static_cast<short>(*nullValue);
1184  pNullVal = &nullVal;
1185  }
1186  for (size_t i = 0; i < n; ++i)
1187  {
1188  FITSUtil::fill(__tmp[i],indata[i]);
1189  }
1190  col.writeData(__tmp,firstRow,pNullVal);
1191  }
1192  else if ( type() == Tlong || type() == VTlong)
1193  {
1194  ColumnVectorData<long>& col
1195  = dynamic_cast<ColumnVectorData<long>&>(*this);
1196  vector<valarray<long> > __tmp(n);
1197  long nullVal(0);
1198  long* pNullVal = 0;
1199  if (nullValue)
1200  {
1201  nullVal = static_cast<long>(*nullValue);
1202  pNullVal = &nullVal;
1203  }
1204  for (size_t i = 0; i < n; ++i)
1205  {
1206  FITSUtil::fill(__tmp[i],indata[i]);
1207  }
1208  col.writeData(__tmp,firstRow,pNullVal);
1209  }
1210  else if ( type() == Tlonglong || type() == VTlonglong)
1211  {
1212  ColumnVectorData<LONGLONG>& col
1213  = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this);
1214  vector<valarray<LONGLONG> > __tmp(n);
1215  LONGLONG nullVal(0);
1216  LONGLONG* pNullVal = 0;
1217  if (nullValue)
1218  {
1219  nullVal = static_cast<LONGLONG>(*nullValue);
1220  pNullVal = &nullVal;
1221  }
1222  for (size_t i = 0; i < n; ++i)
1223  {
1224  FITSUtil::fill(__tmp[i],indata[i]);
1225  }
1226  col.writeData(__tmp,firstRow,pNullVal);
1227  }
1228  else if ( type() == Tlogical || type() == VTlogical)
1229  {
1230  ColumnVectorData<bool>& col
1231  = dynamic_cast<ColumnVectorData<bool>&>(*this);
1232  bool nullVal(0);
1233  bool* pNullVal = 0;
1234  if (nullValue)
1235  {
1236  nullVal = static_cast<bool>(*nullValue);
1237  pNullVal = &nullVal;
1238  }
1239  vector<valarray<bool> > __tmp(n);
1240  for (size_t i = 0; i < n; ++i)
1241  {
1242  FITSUtil::fill(__tmp[i],indata[i]);
1243  }
1244  col.writeData(__tmp,firstRow,pNullVal);
1245  }
1246  else if ( type() == Tbyte || type() == VTbyte)
1247  {
1248  ColumnVectorData<unsigned char>& col
1249  = dynamic_cast<ColumnVectorData<unsigned char>&>(*this);
1250  unsigned char nullVal(0);
1251  unsigned char* pNullVal = 0;
1252  if (nullValue)
1253  {
1254  nullVal = static_cast<unsigned char>(*nullValue);
1255  pNullVal = &nullVal;
1256  }
1257  vector<valarray<unsigned char> > __tmp(n);
1258  for (size_t i = 0; i < n; ++i)
1259  {
1260  FITSUtil::fill(__tmp[i],indata[i]);
1261  }
1262  col.writeData(__tmp,firstRow,&nullVal);
1263  }
1264  else if ( type() == Tushort || type() == VTushort)
1265  {
1266  ColumnVectorData<unsigned short>& col
1267  = dynamic_cast<ColumnVectorData<unsigned short>&>(*this);
1268  unsigned short nullVal(0);
1269  unsigned short* pNullVal = 0;
1270  if (nullValue)
1271  {
1272  nullVal = static_cast<unsigned short>(*nullValue);
1273  pNullVal = &nullVal;
1274  }
1275  vector<valarray<unsigned short> > __tmp(n);
1276  for (size_t i = 0; i < n; ++i)
1277  {
1278  FITSUtil::fill(__tmp[i],indata[i]);
1279  }
1280  col.writeData(__tmp,firstRow,pNullVal);
1281  }
1282  else if ( type() == Tuint || type() == VTuint)
1283  {
1284  ColumnVectorData<unsigned int>& col
1285  = dynamic_cast<ColumnVectorData<unsigned int>&>(*this);
1286  unsigned int nullVal(0);
1287  unsigned int* pNullVal = 0;
1288  if (nullValue)
1289  {
1290  nullVal = static_cast<unsigned int>(*nullValue);
1291  pNullVal = &nullVal;
1292  }
1293  vector<valarray<unsigned int> > __tmp(n);
1294  for (size_t i = 0; i < n; ++i)
1295  {
1296  FITSUtil::fill(__tmp[i],indata[i]);
1297  }
1298  col.writeData(__tmp,firstRow,pNullVal);
1299  }
1300  else if ( type() == Tulong || type() == VTulong)
1301  {
1302  ColumnVectorData<unsigned long>& col
1303  = dynamic_cast<ColumnVectorData<unsigned long>&>(*this);
1304  unsigned long nullVal(0);
1305  unsigned long* pNullVal = 0;
1306  if (nullValue)
1307  {
1308  nullVal = static_cast<unsigned long>(*nullValue);
1309  pNullVal = &nullVal;
1310  }
1311  vector<valarray<unsigned long> > __tmp(n);
1312  for (size_t i = 0; i < n; ++i)
1313  {
1314  FITSUtil::fill(__tmp[i],indata[i]);
1315  }
1316  col.writeData(__tmp,firstRow,pNullVal);
1317  }
1318  else
1319  {
1320  throw InvalidDataType(name());
1321  }
1322  }
1323  }
1324  }
1325 
1326 
1327  template <typename T>
1328  void Column::addNullValue(T nullVal)
1329  {
1330  parent()->makeThisCurrent();
1331  int status(0);
1332 #ifdef SSTREAM_DEFECT
1333  std::ostrstream keyName;
1334  keyName << "TNULL" << index() << std::ends;
1335  char* nullKey = const_cast<char*>(keyName.str());
1336 #else
1337  std::ostringstream keyName;
1338  keyName << "TNULL" << index();
1339  String keyNameStr = keyName.str();
1340  char* nullKey = const_cast<char*>(keyNameStr.c_str());
1341 #endif
1342 
1343 
1344  FITSUtil::MatchType<T> inputType;
1345  int dataType = static_cast<int>(inputType());
1346  if (dataType == static_cast<int>(Tstring))
1347  throw InvalidDataType("attempting to set TNULLn to a string.");
1348 
1349  // update key but don't add to keyword list because it's really a column
1350  // property not a table metadata property. And it needs to be automatically
1351  // renumbered if columns are inserted or deleted.
1352  if (fits_update_key(fitsPointer(),dataType,nullKey,&nullVal,0,&status))
1353  throw FitsError(status);
1354 
1355  // The following is called to make sure the HDU struct is immediately
1356  // updated in case a column write operation is performed shortly after this
1357  // function exits.
1358  if (fits_set_hdustruc(fitsPointer(),&status)) throw FitsError(status);
1359 
1360  }
1361 
1362  template <typename T>
1363  bool Column::getNullValue(T* nullVal) const
1364  {
1365  parent()->makeThisCurrent();
1366 #ifdef SSTREAM_DEFECT
1367  std::ostrstream keyName;
1368  keyName << "TNULL" << index() << std::ends;
1369  char* nullKey = const_cast<char*>(keyName.str());
1370 #else
1371  std::ostringstream keyName;
1372  keyName << "TNULL" << index();
1373  String keyNameStr = keyName.str();
1374  char* nullKey = const_cast<char*>(keyNameStr.c_str());
1375 #endif
1376 
1377  int status=0;
1378  FITSUtil::MatchType<T> inputType;
1379  int dataType = static_cast<int>(inputType());
1380  if (dataType == static_cast<int>(Tstring))
1381  throw InvalidDataType("attempting to read TNULLn into a string.");
1382  T tmpVal(*nullVal);
1383 
1384  bool keyExists = false;
1385  if (fits_read_key(m_parent->fitsPointer(), dataType, nullKey, &tmpVal, 0, &status))
1386  {
1387  if (status == KEY_NO_EXIST || status == VALUE_UNDEFINED)
1388  return keyExists;
1389  else
1390  throw FitsError(status);
1391  }
1392  keyExists = true;
1393  *nullVal = tmpVal;
1394  return keyExists;
1395  }
1396 
1397 } // namespace CCfits
1398 
1399 #endif
const String & name() const
return name of Column (TTYPEn keyword)
Definition: Column.h:1505
Exception thrown for invalid data type inputs.
Definition: Column.h:846
size_t repeat() const
get the repeat count for the rows
Definition: Column.h:1363
fitsfile * fitsPointer()
fits pointer corresponding to fits file containing column data.
Definition: Column.cxx:264
int rows() const
return the number of rows in the table.
Definition: Column.cxx:275
bool getNullValue(T *nullVal) const
Get the value of the TNULLn keyword for the column.
Definition: ColumnT.h:1363
FitsError is the exception thrown by non-zero cfitsio status codes.
Definition: FitsError.h:112
void write(const std::vector< S > &indata, long firstRow)
write a vector of values into a scalar column starting with firstRow
Definition: ColumnT.h:711
Exception thrown if user enters a non-positive number for the number of rows to write.
Definition: Column.h:930
Exception thrown if the data supplied for a write operation is less than declared.
Definition: Column.h:906
Definition: MSconfig.h:123
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 isRead() const
flag set to true if the entire column data has been read from disk
Definition: Column.h:1343
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:522
virtual void makeThisCurrent() const
move the fitsfile pointer to this current HDU.
Definition: ExtHDU.cxx:212
function object that returns the FITS ValueType corresponding to an input intrinsic type ...
Definition: FITSUtil.h:505
Namespace enclosing all CCfits classes and globals definitions.
Definition: AsciiTable.cxx:26
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:1100
Exception thrown on attempting to access a scalar column as vector data.
Definition: Column.h:870
void addNullValue(T nullVal)
Set the TNULLn keyword for the column.
Definition: ColumnT.h:1328
int index() const
get the Column index (the n in TTYPEn etc).
Definition: Column.h:1333
Exception thrown on attempting to read a row number beyond the end of a table.
Definition: Column.h:894
ValueType type() const
returns the data type of the column
Definition: Column.h:1410
bool varLength() const
boolean, set to true if Column has variable length vector rows.
Definition: Column.h:1368
Table * parent() const
return a pointer to the Table which owns this Column
Definition: Column.cxx:312