FitsFile.cxx
Go to the documentation of this file.
1 
12 #include "FitsFile.h"
13 
14 #include "pattern/string_convert.h"
15 
16 #include <algorithm>
17 #include <stdexcept>
18 
19 #include <cassert>
20 
21 #include <cstring>
22 
23 using std::string;
24 using std::vector;
25 
26 using namespace hippodraw;
27 
28 FitsFile::FitsFile ( const std::string & filename, bool write )
29  : FitsFileBase ( filename, write )
30 {
31 }
32 
33 void
35 fillHDUNames ( std::vector < std::string > & names )
36 {
37  names.clear ();
38  int number = getNumberOfHDU ( );
39 
40  for ( int i = 0; i < number; i++ ) {
41  moveToHDU ( i );
42  string value = stringValueForKey ( "EXTNAME" );
43 
44  if ( value == "" ) {
45  if ( i == 0 ) {
46  int number = intValueForKey ( "NAXIS" );
47  if ( number == 0 ) {
48  value = "Empty image";
49  }
50  }
51  }
52 
53  if ( value == "" ) value = "<no name>";
54  names.push_back ( value );
55  }
56 }
57 
58 int
60 fillColumnNames ( std::vector < std::string > & labels )
61 {
62  HduType type = getHduType ();
63  if ( type == Image ) {
65  }
66  else {
68  }
69 
70  return m_status;
71 }
72 
73 int
75 fillColumnNamesFromTable ( std::vector < std::string > & labels )
76 {
77  labels.clear ();
78  int columns = getNumberOfColumns ();
79 
80  if ( columns != 0 ) {
81  m_status = 0; // must NOT be reset on each fits call, else matchs
82  // same column on each call
83  for ( int i = 0; i < columns; i++ ) { // count like Fortran
84  char colname [ FLEN_VALUE ];
85  int col;
86  fits_get_colname ( m_fptr, CASEINSEN, const_cast< char * > ("*"),
87  colname, &col, &m_status );
88  labels.push_back ( string ( colname ) );
89  }
90  }
91  else { // must be image
92  labels.push_back ( string ( "none" ) );
93  }
94 
95  return m_status;
96 }
97 
98 int
100 fillColumnNamesFromImage ( std::vector < std::string > & labels )
101 {
102  labels.clear ();
103  int dimension = getImageDimensions ();
104  if ( dimension == 2 ) {
105  labels.push_back ( "Values" );
106  }
107  else if ( dimension == 3 ) {
108  const char type[] = "CTYPE3";
109  bool yes = hasKey ( type );
110  if ( yes ) {
111  const string name = stringValueForKey ( type );
112  int number = intValueForKey ( "NAXIS3" );
113  for ( int i = 0; i < number; i++ ) {
114  const string iv = String::convert ( i );
115  labels.push_back ( name + " " + iv );
116  }
117  }
118  }
119 
120  return m_status;
121 }
122 
123 int
125 fillDoubleVectorFromColumn ( std::vector < double > & vec,
126  int column )
127 {
128  int retval = 0;
129 
130  HduType type = getHduType ();
131  if ( type == Btable || type == Atable ) {
132  retval = fillFromTableColumn ( vec, column );
133  }
134  else {
135  retval = fillFromImage ( vec, column );
136  }
137 
138  return retval;
139 }
140 
141 int
143 fillFromTableColumn ( std::vector < double > & vec, int column )
144 {
145  int anynul;
146  double nulval = 0;
147  long nelements = vec.size();
148  vector<double>::iterator it = vec.begin();
149  double * ptr = &*it;
150  // Careful, counting columns like Fortran
151  m_status = 0;
152  fits_read_col_dbl( m_fptr, column+1, 1, 1, nelements, nulval,
153  ptr, &anynul, &m_status);
154 
155  return m_status;
156 }
157 
158 void
160 fillShape ( std::vector < intptr_t > & shape, int column )
161 {
162  m_status = 0; // must always set
163 
164  string tdimn ( "TDIM" );
165  tdimn += String::convert ( column+1 ); // a la Fortran
166  char value[80]; // max length of keyword record
167  fits_read_keyword ( m_fptr,
168  const_cast < char * > ( tdimn.c_str() ),
169  value,
170  NULL, & m_status );
171 
172  long rows = getNumberOfRows ();
173  if ( value[0] != 0 ) {
174  const string dims = value;
175  unsigned int count = std::count ( dims.begin(), dims.end(), ',' );
176  count += 1; // one for simple vector
177  int icount = 0;
178  vector < long > naxes ( count );
179  fits_read_tdim ( m_fptr, column+1, count, // input
180  &icount, &naxes[0], & m_status ); //output
181  shape.resize ( count + 1 );
182  shape [0] = rows;
183  std::copy ( naxes.begin(), naxes.end(), shape.begin() + 1 );
184  }
185  else { // no array
186  shape.resize ( 1, rows );
187  }
188 }
189 
190 int
192 fillAxisSizes ( std::vector < long > & vec ) const
193 {
194  vec.clear ();
195  int naxis = getImageDimensions ();
196  vec.resize ( naxis );
197 
198  vector < long > ::iterator first = vec.begin();
199  long * ptr = & *first;
200  m_status = 0;
201  fits_get_img_size ( m_fptr, naxis, ptr, & m_status );
202  assert ( m_status == 0 );
203 
204  return m_status;
205 }
206 
207 void
209 fillImageDeltas ( std::vector < double > & deltas ) const
210 {
211  deltas.clear ();
212  int naxis = getImageDimensions ();
213  deltas.reserve ( naxis );
214 
215  char key [ FLEN_KEYWORD];
216  char * keyroot = const_cast < char * > ("CDELT");
217  for ( int i = 0; i < naxis; i++ ) {
218  m_status = 0;
219  fits_make_keyn ( keyroot, i+1, key, & m_status );
220  bool yes = hasKey ( key );
221 
222  if ( yes ) {
223  double value = doubleValueForKey ( key );
224  deltas.push_back ( value );
225  }
226  else { // no key, take default
227  deltas.push_back ( 1.0 );
228  }
229  }
230 }
231 
232 void
234 fillRefPixelIndices ( std::vector < int > & indices ) const
235 {
236  indices.clear ();
237  int naxis = getImageDimensions ();
238  indices.reserve ( naxis );
239 
240  char key [ FLEN_KEYWORD];
241  char * keyroot = const_cast < char * > ( "CRPIX" );
242  for ( int i = 0; i < naxis; i++ ) {
243  m_status = 0;
244  fits_make_keyn ( keyroot, i+1, key, & m_status );
245  bool yes = hasKey ( key );
246 
247  if ( yes ) {
248  int value = intValueForKey ( key );
249  indices.push_back ( value );
250  }
251  else { // no key, take default
252  indices.push_back ( 1 );
253  }
254  }
255 }
256 
257 void
259 fillRefPixelValues ( std::vector < double > & values ) const
260 {
261  values.clear ();
262  int naxis = getImageDimensions ();
263  values.reserve ( naxis );
264 
265  char key [ FLEN_KEYWORD];
266  char * keyroot = const_cast < char * > ( "CRVAL" );
267  for ( int i = 0; i < naxis; i++ ) {
268  m_status = 0;
269  fits_make_keyn ( keyroot, i+1, key, & m_status );
270  bool yes = hasKey ( key );
271 
272  if ( yes ) {
273  double value = doubleValueForKey ( key );
274  values.push_back ( value );
275  }
276  else { // no key, take default
277  values.push_back ( 0. );
278  }
279  }
280 }
281 
282 bool
285 {
286  bool hammer = true;
287 
288  char key [FLEN_KEYWORD];
289  char * keyroot = const_cast < char * > ( "CTYPE" );
290  for ( int i = 0; i < 2; i++ ) {
291  fits_make_keyn ( keyroot, i+1, key, & m_status );
292  bool yes = hasKey ( key );
293 
294  if ( yes ) {
295  string value = stringValueForKey ( key );
296  if ( value.find ( "-AIT" ) == string::npos ) {
297  hammer = false;
298  }
299  } else {
300  hammer = false;
301  }
302  }
303 
304  return hammer;
305 }
306 
307 int
309 fillFromImage ( std::vector < double > & vec, unsigned int zplane )
310 {
311  vector < long > naxes;
312  fillAxisSizes ( naxes );
313 
314  int datatype = Double;
315  long nelements = naxes[0] * naxes[1];
316  double nulval = 0;
317  vector < double >::iterator first = vec.begin();
318  double * ptr = & *first;
319  int anynul;
320  m_status = 0;
321  if ( naxes.size () == 2 ) {
322  long fpixel[2] = { 1, 1 }; // index like Fortran
323  fits_read_pix ( m_fptr, datatype, fpixel, nelements,
324  & nulval, ptr, & anynul, & m_status );
325  } else {
326  long fpixel[] = { 1, 1, 1 }; // index like Fortran
327  fpixel[2] = zplane + 1; // like Fortran
328  fits_read_pix ( m_fptr, datatype, fpixel, nelements,
329  & nulval, ptr, & anynul, & m_status );
330  }
331 
332  return m_status;
333 }
334 
335 int
337 fillIntVectorFromColumn( std::vector < int > & vec, int column )
338 {
339  int anynul, status = 0;
340  int nulval = 0;
341  long nelements = vec.size();
342  vector<int>::iterator it = vec.begin();
343  int * ptr = new int [ nelements ];
344  // Careful, counting columns like Fortran
345  m_status = 0;
346  fits_read_col_int( m_fptr, column+1, 1, 1, nelements, nulval,
347  ptr, &anynul, &status);
348  copy ( ptr, ptr+nelements, it );
349 
350  return status;
351 }
352 
353 void
355 writeHDU ( long rows, int columns,
356  const std::vector < std::string > & names,
357  const std::vector < std::vector < int > > & shapes,
358  const std::string & extname )
359 {
360  char ** types = new char * [ columns ];
361  char ** tform = new char * [ columns ];
362  char ** tunits = 0;
363  char * m_extname;
364 
365  vector < string > forms;
366  for ( int i = 0; i < columns; i ++ ) {
367  types[i]=const_cast<char*> (names[i].c_str());
368  int size = 1;
369  const vector < int > & shape = shapes [ i ];
370  unsigned int rank = shape.size();
371  if ( rank > 1 ) {
372  for ( unsigned int j = 1; j < rank; j++ ) { // strip row index
373  int dim = shape [ j ];
374  size *= dim;
375  }
376  }
377  string form = String::convert ( size );
378  form += "D";
379  forms.push_back ( form );
380 // unsigned int n = form.size();
381  tform[i] = strdup ( form.c_str() );
382 
383 // tform [i] = const_cast <char *> ( forms[i].c_str() ); // will stay in scope
384  }
385 
386  m_extname = const_cast<char*> (extname.c_str());
387 
388  fits_create_tbl( m_fptr, BINARY_TBL, 0, columns,
389  types, tform, tunits, m_extname, &m_status);
390 //fits_report_error ( stdout, m_status );
391  for ( int i = 0; i < columns; i ++ ) {
392  const vector < int > & shape = shapes [ i ];
393  unsigned int rank = shape.size();
394  if ( rank > 1 ) {
395  vector < long > naxes;
396  for ( unsigned int j = 1; j < rank; j++ ) { // strip row index
397  naxes.push_back ( shape [ j ] );
398  }
399  fits_write_tdim ( m_fptr, i+1, // like Fortran
400  rank -1, &naxes [0], &m_status );
401  }
402  }
403  // clean up
404  delete types;
405  delete tform;
406 }
407 
408 void
410 writeImageHDU ( long x, long y )
411 {
412  long naxes[2]={x,y};
413  fits_create_img ( m_fptr, DOUBLE_IMG, 2, naxes, &m_status );
414 }
415 
416 
417 void
419 writeColumn ( int col, const std::vector < double > & data )
420 {
421  LONGLONG nelements = data.size ();
422 LONGLONG firstrow = 1;
423 LONGLONG firstelem = 1;
424  fits_write_col( m_fptr, TDOUBLE, col+1, firstrow, firstelem, nelements,
425  const_cast < double * > ( &data[0] ), &m_status);
426 }
427 
428 void
430 writePix ( long x, long y, const std::vector < double > & data )
431 {
432  long fpixel[2]={1,1};
433  long nelements = x * y;
434  fits_write_pix ( m_fptr, TDOUBLE, fpixel, nelements,
435  const_cast < double * > ( &data[0] ), &m_status );
436 }
437 
438 void
441 {
442  fits_close_file( m_fptr, &m_status );
443  m_fptr = 0; // to remember its already closed.
444 }
445 
446 bool
448 pixCenter () const
449 {
450 
451  char * key = const_cast < char * > ( "PIXCENT" );
452  bool yes = hasKey ( key );
453  if ( yes )
454  {
455  if ( stringValueForKey ( key ) == "T" ) return true;
456  }
457 
458  return false;
459 
460 }
461 
462 void
464 writeRefPixelValues ( double value1, double value2 )
465 {
466  char * key1 = const_cast < char * > ( "CRVAL1" );
467  char * key2 = const_cast < char * > ( "CRVAL2" );
468 
469  fits_write_key( m_fptr, TDOUBLE, key1, &value1, NULL, &m_status );
470  fits_write_key( m_fptr, TDOUBLE, key2, &value2, NULL, &m_status );
471 }
int m_status
The status return code from the last cfitsio operation.
Definition: FitsFileBase.h:87
unsigned int i
bool pixCenter() const
Definition: FitsFile.cxx:448
int fillIntVectorFromColumn(std::vector< int > &vec, int column)
Read elements from an ASCII or binary table column (in the CDU) and fill STL vector&lt;int&gt; with its con...
Definition: FitsFile.cxx:337
void fillRefPixelIndices(std::vector< int > &indices) const
Clears and fills the vector with the reference pixel&#39;s indexes.
Definition: FitsFile.cxx:234
int fillColumnNamesFromTable(std::vector< std::string > &labels)
Clears and fills the vector with the column labels of binary or ASCII table.
Definition: FitsFile.cxx:75
A base class for the concrete classes that wrap the cfitsio library.
Definition: FitsFileBase.h:32
void writeRefPixelValues(double value1, double value2)
Definition: FitsFile.cxx:464
long getNumberOfRows() const
Returns the number of rows in the table.
void * data(numeric::array arr)
Definition: num_util.cpp:389
int fillFromImage(std::vector< double > &vec, unsigned int axis)
Fills the vector vec from an image HDU.
Definition: FitsFile.cxx:309
column
The column indices for 2 dimension data point tuple.
Displays on the Z axis the values of a single column treated as a matrix of values.
Definition: Image.h:45
std::vector< intptr_t > shape(numeric::array arr)
Definition: num_util.cpp:317
void writeColumn(int c, const std::vector< double > &data)
Writes the vector to FITS table.
Definition: FitsFile.cxx:419
int fillFromTableColumn(std::vector< double > &v, int column)
Fills the vector v from a table column.
Definition: FitsFile.cxx:143
The namespace for conversion to string.
HduType getHduType() const
Returns the type of HDU.
return yes
Definition: CanvasView.cxx:883
int moveToHDU(int hdunum)
Move to a specified absolute HDU number in the FITS file and return the cfitsio status.
PyArray_TYPES type(numeric::array arr)
Definition: num_util.cpp:249
int fillColumnNamesFromImage(std::vector< std::string > &labels)
Clears and fills the vector with the column labels of a image.
Definition: FitsFile.cxx:100
int getImageDimensions() const
Returns the number of dimensions (axes) of an image.
void fillImageDeltas(std::vector< double > &deltas) const
Clears and fills the vector with the delta values of an image.
Definition: FitsFile.cxx:209
void writeHDU(long rows, int columns, const std::vector< std::string > &names, const std::vector< std::vector< int > > &shapes, const std::string &extname)
Definition: FitsFile.cxx:355
intp size(numeric::array arr)
Definition: num_util.cpp:296
int rank(numeric::array arr)
Definition: num_util.cpp:271
int fillDoubleVectorFromColumn(std::vector< double > &vec, int column)
Read elements from an ASCII or binary table column (in the CDU) and fill the vector with its contents...
Definition: FitsFile.cxx:125
static Type types[]
An array to allow conversion of integer to enumeration.
Definition: AxesType.cxx:30
string convert(int i)
Converts an integer to a string.
void fillHDUNames(std::vector< std::string > &names)
Clears and fills the vector with the HDU names.
Definition: FitsFile.cxx:35
int status() const
Returns the cfitsio status code for the last operation.
int fillColumnNames(std::vector< std::string > &labels)
Clears and fills the vector with the column labels of the current HDU table.
Definition: FitsFile.cxx:60
void writePix(long x, long y, const std::vector< double > &data)
Definition: FitsFile.cxx:430
int getNumberOfColumns() const
Returns the number of columns in a table.
double doubleValueForKey(const char *key) const
Read a specified keyword value and return it as a double.
FitsFile(const std::string &filename, bool write=false)
Public construction taking a filename as argument.
Definition: FitsFile.cxx:28
fitsfile * m_fptr
Pointer to the fits file data structure.
Definition: FitsFileBase.h:90
std::string stringValueForKey(const char *key) const
Read a specified keyword value and returns it as a string.
int fillAxisSizes(std::vector< long > &vec) const
Clears and fills the vector vec with the size of each dimension of an image.
Definition: FitsFile.cxx:192
HduType
The type of HDU.
Definition: FitsFileBase.h:38
int intValueForKey(const char *key) const
Read a specified keyword value and returns it as a int.
void fillRefPixelValues(std::vector< double > &values) const
Clears and fills the vector with the reference pixel&#39;s values.
Definition: FitsFile.cxx:259
void writeImageHDU(long x, long y)
Definition: FitsFile.cxx:410
hippodraw::FitsFile interface
int write(const std::vector< double > &a)
Given the vector it writes it to std stream.
Definition: NumLinAlg.cxx:421
bool isHammerAitoff() const
Returns true if coordinate system of the axis is should undergo Hammer-Aitoff transformation.
Definition: FitsFile.cxx:284
int getNumberOfHDU() const
Returns the number of HDU in the file.
void fillShape(std::vector< intptr_t > &shape, int column)
Fills the vector with the shape of the column.
Definition: FitsFile.cxx:160
64 bit floating point
Definition: FitsFileBase.h:68
list< QAction * >::iterator it
bool hasKey(const char *key) const
Returns true if the keyword key exists, otherwise returns false.

Generated for HippoDraw Class Library by doxygen