source: tags/release-1.0.5/src/FitsIO/wcsIO.cc @ 178

Last change on this file since 178 was 168, checked in by Matthew Whiting, 18 years ago

A couple of changes:

  • Removed the Fortran search in the configure script -- we don't use it.
  • Cleaned up some of the fits-I/O tasks, adding some functions that check for the existence of the FITS file (fits_file_exists).
  • This task is only in v2.5+ of cfitsio, so added notes to this effect in README and the Guide.
  • Improved the exiting and warning messages in mainDuchamp.cc.
File size: 5.5 KB
Line 
1#include <iostream>
2#include <string>
3#include <wcs.h>
4#include <wcshdr.h>
5#include <fitshdr.h>
6#include <wcsfix.h>
7#include <wcsunits.h>
8#define WCSLIB_GETWCSTAB // define this so that we don't try and redefine
9                         //  wtbarr (this is a problem when using gcc v.4+
10#include <fitsio.h>
11#include <math.h>
12#include <duchamp.hh>
13#include <Cubes/cubes.hh>
14
15int FitsHeader::defineWCS(string fname, Param &par)
16{
17  /**
18   *  FitsHeader::defineWCS(wcsprm *wcs, char *hdr, Param &par)
19   *   A function that reads the WCS header information from the
20   *    FITS file given by fptr.
21   *   It will also sort out the spectral axis, and covert to the correct
22   *    velocity type, or frequency type if need be.
23   *   It calls FitsHeader::getBUNIT so that the Integrated Flux units can
24   *    be calculated by FitsHeader::fixUnits.
25   */
26
27  fitsfile *fptr;
28  int bitpix,numAxes;
29  int noComments = 1; //so that fits_hdr2str will ignore COMMENT, HISTORY etc
30  int nExc = 0,nkeys;
31  char *hdr;
32
33  // Open the FITS file
34  int status = 0;
35  if( fits_open_file(&fptr,fname.c_str(),READONLY,&status) ){
36    fits_report_error(stderr, status);
37    return FAILURE;
38  }
39
40  // Get the dimensions of the FITS file -- number of axes and size of each.
41  status = 0;
42  if(fits_get_img_dim(fptr, &numAxes, &status)){
43    fits_report_error(stderr, status);
44    return FAILURE;
45  }
46  long *dimAxes = new long[numAxes];
47  for(int i=0;i<numAxes;i++) dimAxes[i]=1;
48  status = 0;
49  if(fits_get_img_size(fptr, numAxes, dimAxes, &status)){
50    fits_report_error(stderr, status);
51    return FAILURE;
52  }
53
54  // Read in the entire PHU of the FITS file to a string.
55  // This will be read by the wcslib functions to extract the WCS.
56  status = 0;
57  fits_hdr2str(fptr, noComments, NULL, nExc, &hdr, &nkeys, &status);
58  if( status ){
59    duchampWarning("defineWCS","Error whilst reading FITS header to string: ");
60    fits_report_error(stderr, status);
61    return FAILURE;
62  }
63
64  // Close the FITS file -- not needed any more in this function.
65  status = 0;
66  fits_close_file(fptr, &status);
67  if (status){
68    duchampWarning("defineWCS","Error closing file: ");
69    fits_report_error(stderr, status);
70  }
71 
72  wcsprm *wcs = new wcsprm;
73
74  // Initialise the wcsprm structure
75  int flag;
76  if(flag = wcsini(true,numAxes,wcs)){
77    std::stringstream errmsg;
78    errmsg << "wcsini failed! Code=" << flag
79           << ": " << wcs_errmsg[flag] << std::endl;
80    duchampError("defineWCS",errmsg.str());
81    return FAILURE;
82  }
83  wcs->flag=-1;
84
85  int relax=1; // for wcspih -- admit all recognised informal WCS extensions
86  int ctrl=2;  // for wcspih -- report each rejected card and its reason for
87               //               rejection
88  int nwcs, nreject;
89  // Parse the FITS header to fill in the wcsprm structure
90  if(flag = wcspih(hdr, nkeys, relax, ctrl, &nreject, &nwcs, &wcs)) {
91    // if here, something went wrong -- report what.
92    std::stringstream errmsg;
93    errmsg << "wcspih failed! Code="<<flag<<": "<<wcs_errmsg[flag]<<std::endl;
94    duchampWarning("defineWCS",errmsg.str());
95  }
96  else{ 
97    int stat[6];
98    int axes[3]={dimAxes[wcs->lng],dimAxes[wcs->lat],dimAxes[wcs->spec]};
99
100    // Applies all necessary corrections to the wcsprm structure
101    //  (missing cards, non-standard units or spectral types, ...)
102    if(flag=wcsfix(1,axes,wcs,stat)) {
103      std::stringstream errmsg;
104      errmsg << "wcsfix failed:\n";
105      for(int i=0; i<NWCSFIX; i++)
106        if (stat[i] > 0)
107          errmsg <<" flag="<<flag<<": "<< wcsfix_errmsg[stat[i]]<<std::endl;
108      duchampWarning("defineWCS", errmsg.str() );
109    }
110
111    // Set up the wcsprm struct. Report if something goes wrong.
112    if(flag=wcsset(wcs)){
113      std::stringstream errmsg;
114      errmsg<<"wcsset failed! Code="<<flag <<": "<<wcs_errmsg[flag]<<std::endl;
115      duchampWarning("defineWCS",errmsg.str());
116    }
117
118    if(wcs->naxis>2){  // if there is a spectral axis
119
120      int index = wcs->spec;
121      string desiredType,specType = wcs->ctype[index];
122      if(wcs->restfrq != 0){
123        // Set the spectral axis to a standard specification: VELO-F2V
124        desiredType = duchampVelocityType;
125        if(wcs->restwav == 0) wcs->restwav = 299792458.0 / wcs->restfrq;
126      }
127      else{
128        // No rest frequency defined, so put spectral dimension in frequency.
129        // Set the spectral axis to a standard specification: FREQ
130        duchampWarning("defineWCS",
131       "No rest frequency defined. Using frequency units in spectral axis.\n");
132        desiredType = duchampFrequencyType;
133        par.setSpectralUnits("MHz");
134        if(strcmp(wcs->cunit[index],"")==0){
135          duchampWarning("defineWCS",
136          "No frequency unit given. Assuming frequency axis is in Hz.\n");
137          strcpy(wcs->cunit[index],"Hz");
138        }
139      }
140
141      // Check to see if the spectral type (eg VELO-F2V) matches that wanted
142      //   from duchamp.hh. Only first four characters checked.
143      if(strncmp(specType.c_str(),desiredType.c_str(),4)!=0){
144        index = -1;
145        // If not a match, translate the spectral axis to the desired type
146        if( flag = wcssptr(wcs, &index, (char *)desiredType.c_str())){
147          std::stringstream errmsg;
148          errmsg<<"wcssptr failed! Code="<<flag <<": "
149                <<wcs_errmsg[flag]<<std::endl;
150          duchampWarning("defineWCS",errmsg.str());
151        }       
152      }
153   
154    } // end of if(numAxes>2)
155   
156    // Save the wcs to the FitsHeader class that is running this function
157    this->setWCS(wcs);
158    this->setNWCS(nwcs);
159
160    wcsfree(wcs);
161
162  }
163
164  // Get the brightness unit, so that we can set the units for the
165  //  integrated flux when we go to fixUnits.
166
167  this->getBUNIT(fname);
168
169  this->fixUnits(par);
170
171  return SUCCESS;
172
173}
Note: See TracBrowser for help on using the repository browser.