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

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

A large commit based around a few changes:

  • Implemented the new SNRpeak column, defining it in columns.cc and printing it out in outputDetection.cc.
  • Corrected a bug in the subsection parsing that miscalculated the pixel offset when "*" was given as an axis range.
  • setupFDR now calculates the flux threshold so this can be reported.
  • The object flags now distinguish between spatial edge and spectral edge locations.
  • Other minor changes for clarity's sake.
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::readBUNIT 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->readBUNIT(fname);
171
172  this->fixUnits(par);
173
174  return SUCCESS;
175
176}
Note: See TracBrowser for help on using the repository browser.