source: trunk/src/FitsIO/wcsIO.cc @ 190

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

Large suite of edits, mostly due to testing with valgrind, which clear up bad memory allocations and so on.
Improved the printing of progress bars in some routines by introducing a new ProgressBar? class, with associated functions to do the printing (now much cleaner).

File size: 5.6 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!\n"
94           << "WCSLIB error code="<<flag<<": "<<wcs_errmsg[flag]<<std::endl;
95    duchampWarning("defineWCS",errmsg.str());
96  }
97  else{ 
98    int stat[NWCSFIX];
99    // Applies all necessary corrections to the wcsprm structure
100    //  (missing cards, non-standard units or spectral types, ...)
101    if(flag=wcsfix(1,(const int*)dimAxes,wcs,stat)) {
102      std::stringstream errmsg;
103      errmsg << "wcsfix failed:\n";
104      for(int i=0; i<NWCSFIX; i++)
105        if (stat[i] > 0)
106          errmsg <<"WCSLIB error code="<<flag<<": "
107                 << 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!\n"
115            <<"WCSLIB error code="<<flag <<": "<<wcs_errmsg[flag]<<std::endl;
116      duchampWarning("defineWCS",errmsg.str());
117    }
118
119    if(wcs->naxis>2){  // if there is a spectral axis
120
121      int index = wcs->spec;
122      string desiredType,specType = wcs->ctype[index];
123      if(wcs->restfrq != 0){
124        // Set the spectral axis to a standard specification: VELO-F2V
125        desiredType = duchampVelocityType;
126        if(wcs->restwav == 0) wcs->restwav = 299792458.0 / wcs->restfrq;
127        this->spectralDescription = duchampSpectralDescription[VELOCITY];
128      }
129      else{
130        // No rest frequency defined, so put spectral dimension in frequency.
131        // Set the spectral axis to a standard specification: FREQ
132        duchampWarning("defineWCS",
133       "No rest frequency defined. Using frequency units in spectral axis.\n");
134        desiredType = duchampFrequencyType;
135        par.setSpectralUnits("MHz");
136        if(strcmp(wcs->cunit[index],"")==0){
137          duchampWarning("defineWCS",
138          "No frequency unit given. Assuming frequency axis is in Hz.\n");
139          strcpy(wcs->cunit[index],"Hz");
140        }
141        this->spectralDescription = duchampSpectralDescription[FREQUENCY];
142      }
143
144      // Check to see if the spectral type (eg VELO-F2V) matches that wanted
145      //   from duchamp.hh. Only first four characters checked.
146      if(strncmp(specType.c_str(),desiredType.c_str(),4)!=0){
147        index = -1;
148        // If not a match, translate the spectral axis to the desired type
149        if( flag = wcssptr(wcs, &index, (char *)desiredType.c_str())){
150          std::stringstream errmsg;
151          errmsg<<"wcssptr failed! Code="<<flag <<": "
152                <<wcs_errmsg[flag]<<std::endl;
153          duchampWarning("defineWCS",errmsg.str());
154        }       
155      }
156   
157    } // end of if(numAxes>2)
158   
159    // Save the wcs to the FitsHeader class that is running this function
160    this->setWCS(wcs);
161    this->setNWCS(nwcs);
162
163    wcsfree(wcs);
164
165  }
166
167  // Get the brightness unit, so that we can set the units for the
168  //  integrated flux when we go to fixUnits.
169
170  this->getBUNIT(fname);
171
172  this->fixUnits(par);
173
174  return SUCCESS;
175
176}
Note: See TracBrowser for help on using the repository browser.