CCfits  2.6
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  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  }
371  parent()->makeThisCurrent();
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  }
525  parent()->makeThisCurrent();
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 
552  throw Column::WrongColumnType(name());
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 
690  parent()->makeThisCurrent();
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.
715  throw Column::WrongColumnType(name());
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 
903  parent()->makeThisCurrent();
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.
913  FITSUtil::MatchType<S> inType;
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 
1149 template <typename S>
1150 void 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;
1272  parent()->makeThisCurrent();
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.
1282  FITSUtil::MatchType<S> inType;
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  {
1487  parent()->makeThisCurrent();
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  {
1522  parent()->makeThisCurrent();
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
const String & name() const
return name of Column (TTYPEn keyword)
Definition: Column.h:1532
Exception thrown for invalid data type inputs.
Definition: Column.h:860
size_t repeat() const
get the repeat count for the rows
Definition: Column.h:1390
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:1520
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:869
Exception thrown if user enters a non-positive number for the number of rows to write.
Definition: Column.h:944
Exception thrown if the data supplied for a write operation is less than declared.
Definition: Column.h:920
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:1370
fitsfile * fitsPointer() const
return the fitsfile pointer for the FITS object containing the HDU
Definition: HDU.cxx:308
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
virtual void makeThisCurrent() const
move the fitsfile pointer to this current HDU.
Definition: ExtHDU.cxx:208
function object that returns the FITS ValueType corresponding to an input intrinsic type ...
Definition: FITSUtil.h:505
void writeArrays(const std::vector< std::valarray< S > > &indata, long firstRow)
write a vector of valarray objects to the column, starting at row firstRow &gt;= 1
Definition: ColumnT.h:1257
Exception thrown on attempting to access a scalar column as vector data.
Definition: Column.h:884
void addNullValue(T nullVal)
Set the TNULLn keyword for the column.
Definition: ColumnT.h:1485
int index() const
get the Column index (the n in TTYPEn etc).
Definition: Column.h:1360
Exception thrown on attempting to read a row number beyond the end of a table.
Definition: Column.h:908
ValueType type() const
returns the data type of the column
Definition: Column.h:1437
bool varLength() const
boolean, set to true if Column has variable length vector rows.
Definition: Column.h:1395
Table * parent() const
return a pointer to the Table which owns this Column
Definition: Column.cxx:312