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

Last change on this file since 258 was 232, checked in by Matthew Whiting, 17 years ago

Large raft of changes. Most are minor ones related to fixing up the use of std::string and std::vector (whether they are declared as using, or not...). Other changes include:

  • Moving the reconstruction filter class Filter into its own header/implementation files filter.{hh,cc}. As a result, the atrous.cc file is removed, but atrous.hh remains with just the function prototypes.
  • Incorporating a Filter object into the Param set, so that the reconstruction routines can see it without the messy "extern" call. The define() function is now called in both the Param() and Param::readParams() functions, and no longer in the main body.
  • Col functions in columns.cc moved into the Column namespace, while the template function printEntry is moved into the columns.hh file -- it would not compile on delphinus with it in the columns.cc, even though all the implementations were present.
  • Improved the introductory section of the Guide, with a bit more detail about each of the execution steps. This way the reader can read this section and have a reasonably good idea about what is happening.
  • Other minor changes to the Guide.
File size: 6.4 KB
Line 
1#include <iostream>
2#include <string>
3#include <stdlib.h>
4#include <wcs.h>
5#include <wcshdr.h>
6#include <fitshdr.h>
7#include <wcsfix.h>
8#include <wcsunits.h>
9#define WCSLIB_GETWCSTAB // define this so that we don't try and redefine
10                         //  wtbarr (this is a problem when using gcc v.4+
11#include <fitsio.h>
12#include <math.h>
13#include <duchamp.hh>
14#include <Cubes/cubes.hh>
15
16int FitsHeader::defineWCS(std::string fname, Param &par)
17{
18  /**
19   *   A function that reads the WCS header information from the
20   *    FITS file given by fname
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   * \param fname Fits file to read.
26   * \param par Param set to help fix the units with.
27   */
28
29  fitsfile *fptr;
30  int bitpix,numAxes;
31  int noComments = 1; //so that fits_hdr2str will ignore COMMENT, HISTORY etc
32  int nExc = 0,nkeys;
33  char *hdr;
34
35  // Open the FITS file
36  int status = 0;
37  if( fits_open_file(&fptr,fname.c_str(),READONLY,&status) ){
38    fits_report_error(stderr, status);
39    return FAILURE;
40  }
41
42  // Get the dimensions of the FITS file -- number of axes and size of each.
43  status = 0;
44  if(fits_get_img_dim(fptr, &numAxes, &status)){
45    fits_report_error(stderr, status);
46    return FAILURE;
47  }
48  long *dimAxes = new long[numAxes];
49  for(int i=0;i<numAxes;i++) dimAxes[i]=1;
50  status = 0;
51  if(fits_get_img_size(fptr, numAxes, dimAxes, &status)){
52    fits_report_error(stderr, status);
53    return FAILURE;
54  }
55
56  // Read in the entire PHU of the FITS file to a std::string.
57  // This will be read by the wcslib functions to extract the WCS.
58  status = 0;
59  fits_hdr2str(fptr, noComments, NULL, nExc, &hdr, &nkeys, &status);
60  if( status ){
61    duchampWarning("defineWCS","Error whilst reading FITS header to string: ");
62    fits_report_error(stderr, status);
63    return FAILURE;
64  }
65
66  // Close the FITS file -- not needed any more in this function.
67  status = 0;
68  fits_close_file(fptr, &status);
69  if (status){
70    duchampWarning("defineWCS","Error closing file: ");
71    fits_report_error(stderr, status);
72  }
73 
74  struct wcsprm *localwcs;
75  localwcs = (struct wcsprm *)calloc(1,sizeof(struct wcsprm));
76  localwcs->flag=-1;
77
78  // Initialise the wcsprm structure
79  if(status = wcsini(true, numAxes, localwcs)){
80    std::stringstream errmsg;
81    errmsg << "wcsini failed! Code=" << status
82           << ": " << wcs_errmsg[status] << std::endl;
83    duchampError("defineWCS",errmsg.str());
84    return FAILURE;
85  }
86
87  int relax=1; // for wcspih -- admit all recognised informal WCS extensions
88  int ctrl=2;  // for wcspih -- report each rejected card and its reason for
89               //               rejection
90  int localnwcs, nreject;
91  // Parse the FITS header to fill in the wcsprm structure
92  if(status=wcspih(hdr, nkeys, relax, ctrl, &nreject, &localnwcs, &localwcs)){
93    // if here, something went wrong -- report what.
94    std::stringstream errmsg;
95    errmsg << "wcspih failed!\nWCSLIB error code=" << status
96           << ": " << wcs_errmsg[status] << std::endl;
97    duchampWarning("defineWCS",errmsg.str());
98  }
99  else{ 
100    int stat[NWCSFIX];
101    // Applies all necessary corrections to the wcsprm structure
102    //  (missing cards, non-standard units or spectral types, ...)
103    if(status = wcsfix(1, (const int*)dimAxes, localwcs, stat)) {
104      std::stringstream errmsg;
105      errmsg << "wcsfix failed:\n";
106      for(int i=0; i<NWCSFIX; i++)
107        if (stat[i] > 0)
108          errmsg << "WCSLIB error code=" << status << ": "
109                 << wcsfix_errmsg[stat[i]] << std::endl;
110      duchampWarning("defineWCS", errmsg.str() );
111    }
112
113    // Set up the wcsprm struct. Report if something goes wrong.
114    if(status = wcsset(localwcs)){
115      std::stringstream errmsg;
116      errmsg<<"wcsset failed!\n"
117            <<"WCSLIB error code=" << status
118            <<": "<<wcs_errmsg[status] << std::endl;
119      duchampWarning("defineWCS",errmsg.str());
120    }
121
122    if(localwcs->naxis>2){  // if there is a spectral axis
123
124      int index = localwcs->spec;
125      std::string desiredType,specType = localwcs->ctype[index];
126//            << "  " << localwcs->ctype[localwcs->spec] << "\n";
127      if(localwcs->restfrq != 0){
128        // Set the spectral axis to a standard specification: VELO-F2V
129        desiredType = duchampVelocityType;
130        if(localwcs->restwav == 0)
131          localwcs->restwav = 299792458.0 /  localwcs->restfrq;
132        this->spectralDescription = duchampSpectralDescription[VELOCITY];
133      }
134      else{
135        // No rest frequency defined, so put spectral dimension in frequency.
136        // Set the spectral axis to a standard specification: FREQ
137        duchampWarning("defineWCS",
138       "No rest frequency defined. Using frequency units in spectral axis.\n");
139        desiredType = duchampFrequencyType;
140        par.setSpectralUnits("MHz");
141        if(strcmp(localwcs->cunit[index],"")==0){
142          duchampWarning("defineWCS",
143          "No frequency unit given. Assuming frequency axis is in Hz.\n");
144          strcpy(localwcs->cunit[index],"Hz");
145        }
146        this->spectralDescription = duchampSpectralDescription[FREQUENCY];
147      }
148
149
150      // Now we need to make sure the spectral axis has the correct setup.
151      //  We use wcssptr to translate it if it is not of the desired type,
152      //  or if the spectral units are not defined.
153
154      bool needToTranslate = false;
155
156      if(strncmp(specType.c_str(),desiredType.c_str(),4)!=0)
157        needToTranslate = true;
158
159      std::string blankstring = "";
160      if(strcmp(localwcs->cunit[localwcs->spec],blankstring.c_str())==0)
161        needToTranslate = true;
162
163      if(needToTranslate){
164
165        if(strcmp(localwcs->ctype[localwcs->spec],"VELO")==0)
166          strcpy(localwcs->ctype[localwcs->spec],"VELO-F2V");
167
168        index = localwcs->spec;
169       
170        if(status = wcssptr(localwcs, &index, (char *)desiredType.c_str())){
171          std::stringstream errmsg;
172          errmsg<< "WCSSPTR failed! Code=" << status << ": "
173                << wcs_errmsg[status] << std::endl
174                << "(wanted to convert from type \"" << specType
175                << "\" to type \"" << desiredType << "\")\n";
176          duchampWarning("defineWCS",errmsg.str());
177
178        }
179
180      }
181   
182    } // end of if(numAxes>2)
183   
184    // Save the wcs to the FitsHeader class that is running this function
185    this->setWCS(localwcs);
186    this->setNWCS(localnwcs);
187
188  }
189
190  wcsvfree(&localnwcs,&localwcs);
191  delete [] dimAxes;
192
193  // Get the brightness unit, so that we can set the units for the
194  //  integrated flux when we go to fixUnits.
195  this->readBUNIT(fname);
196
197  this->fixUnits(par);
198
199  return SUCCESS;
200
201}
Note: See TracBrowser for help on using the repository browser.