source: trunk/src/fitsHeader.cc @ 299

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

Adding distribution text at the start of each file...

File size: 8.1 KB
Line 
1// -----------------------------------------------------------------------
2// fitsHeader.cc: Information about the FITS file's header.
3// -----------------------------------------------------------------------
4// Copyright (C) 2006, Matthew Whiting, ATNF
5//
6// This program is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2 of the License, or (at your
9// option) any later version.
10//
11// Duchamp is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14// for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with Duchamp; if not, write to the Free Software Foundation,
18// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19//
20// Correspondence concerning Duchamp may be directed to:
21//    Internet email: Matthew.Whiting [at] atnf.csiro.au
22//    Postal address: Dr. Matthew Whiting
23//                    Australia Telescope National Facility, CSIRO
24//                    PO Box 76
25//                    Epping NSW 1710
26//                    AUSTRALIA
27// -----------------------------------------------------------------------
28#include <iostream>
29#include <sstream>
30#include <string>
31#include <wcs.h>
32#include <wcsunits.h>
33#include <duchamp.hh>
34#include <param.hh>
35#include <fitsHeader.hh>
36#include <Utils/utils.hh>
37
38FitsHeader::FitsHeader()
39{
40  this->wcs = (struct wcsprm *)calloc(1,sizeof(struct wcsprm));
41  this->wcs->flag=-1;
42  wcsini(true, 3, this->wcs);
43  this->wcsIsGood = false;
44  this->nwcs = 0;
45  this->scale=1.;
46  this->offset=0.;
47  this->power=1.;
48  this->fluxUnits="counts";
49}
50
51FitsHeader::~FitsHeader()
52{
53  /**
54   *  Uses the WCSLIB function wcsvfree to clear the wcsprm struct.
55   */
56  wcsvfree(&nwcs,&wcs);
57}
58
59FitsHeader::FitsHeader(const FitsHeader& h)
60{
61  this->wcs = (struct wcsprm *)calloc(1,sizeof(struct wcsprm));
62  this->wcs->flag     = -1;
63  wcsini(true, h.wcs->naxis, this->wcs);
64  wcscopy(true, h.wcs, this->wcs);
65  wcsset(this->wcs);
66  this->nwcs          = h.nwcs;
67  this->wcsIsGood     = h.wcsIsGood;
68  this->spectralUnits = h.spectralUnits;
69  this->fluxUnits     = h.fluxUnits;
70  this->intFluxUnits  = h.intFluxUnits;
71  this->beamSize      = h.beamSize;
72  this->bmajKeyword   = h.bmajKeyword;
73  this->bminKeyword   = h.bminKeyword;
74  this->bpaKeyword    = h.bpaKeyword;
75  this->blankKeyword  = h.blankKeyword;
76  this->bzeroKeyword  = h.bzeroKeyword;
77  this->bscaleKeyword = h.bscaleKeyword;
78  this->scale         = h.scale;
79  this->offset        = h.offset;
80  this->power         = h.power;
81}
82
83FitsHeader& FitsHeader::operator= (const FitsHeader& h)
84{
85  if(this == &h) return *this;
86  this->wcs = (struct wcsprm *)calloc(1,sizeof(struct wcsprm));
87  this->wcs->flag     = -1;
88  wcsini(true, h.wcs->naxis, this->wcs);
89  wcscopy(true, h.wcs, this->wcs);
90  wcsset(this->wcs);
91  this->nwcs          = h.nwcs;
92  this->wcsIsGood     = h.wcsIsGood;
93  this->spectralUnits = h.spectralUnits;
94  this->fluxUnits     = h.fluxUnits;
95  this->intFluxUnits  = h.intFluxUnits;
96  this->beamSize      = h.beamSize;
97  this->bmajKeyword   = h.bmajKeyword;
98  this->bminKeyword   = h.bminKeyword;
99  this->bpaKeyword    = h.bpaKeyword;
100  this->blankKeyword  = h.blankKeyword;
101  this->bzeroKeyword  = h.bzeroKeyword;
102  this->bscaleKeyword = h.bscaleKeyword;
103  this->scale         = h.scale;
104  this->offset        = h.offset;
105  this->power         = h.power;
106  return *this;
107}
108
109void FitsHeader::setWCS(struct wcsprm *w)
110{
111  /**
112   *  A function that assigns the wcs parameters, and runs
113   *   wcsset to set it up correctly.
114   *  Performs a check to see if the WCS is good (by looking at
115   *   the lng and lat wcsprm parameters), and sets the wcsIsGood
116   *   flag accordingly.
117   * \param w A WCSLIB wcsprm struct with the correct parameters.
118   */
119  wcscopy(true, w, this->wcs);
120  wcsset(this->wcs);
121  if( (w->lng!=-1) && (w->lat!=-1) ) this->wcsIsGood = true;
122}
123
124struct wcsprm *FitsHeader::getWCS()
125{
126  /**
127   *  A function that returns a properly initilized wcsprm object
128   *  corresponding to the WCS.
129   */
130  struct wcsprm *wNew = (struct wcsprm *)calloc(1,sizeof(struct wcsprm));
131  wNew->flag=-1;
132  wcsini(true, this->wcs->naxis, wNew);
133  wcscopy(true, this->wcs, wNew);
134  wcsset(wNew);
135  return wNew;
136}
137
138int FitsHeader::wcsToPix(const double *world, double *pix)
139{     
140  return wcsToPixSingle(this->wcs, world, pix); 
141};
142int FitsHeader::wcsToPix(const double *world, double *pix, const int npts)
143{
144  return wcsToPixMulti(this->wcs, world, pix, npts); 
145};
146int FitsHeader::pixToWCS(const double *pix, double *world)
147{   
148  return pixToWCSSingle(this->wcs, pix, world); 
149};
150int FitsHeader::pixToWCS(const double *pix, double *world, const int npts)
151{
152  return pixToWCSMulti(this->wcs, pix,world, npts); 
153};
154
155
156double FitsHeader::pixToVel(double &x, double &y, double &z)
157{
158  double vel;
159  if(this->wcsIsGood){
160    double *pix   = new double[3];
161    double *world = new double[3];
162    pix[0] = x; pix[1] = y; pix[2] = z;
163    pixToWCSSingle(this->wcs,pix,world);
164    vel = this->specToVel(world[2]);
165    delete [] pix;
166    delete [] world;
167  }
168  else vel = z;
169  return vel;
170}
171
172double* FitsHeader::pixToVel(double &x, double &y, double *zarray, int size)
173{
174  double *newzarray = new double[size];
175  if(this->wcsIsGood){
176    double *pix   = new double[size*3];
177    for(int i=0;i<size;i++){
178      pix[3*i]   = x;
179      pix[3*i+1] = y;
180      pix[3*i+2] = zarray[i];
181    }
182    double *world = new double[size*3];
183    pixToWCSMulti(this->wcs,pix,world,size);
184    delete [] pix;
185    for(int i=0;i<size;i++) newzarray[i] = this->specToVel(world[3*i+2]);
186    delete [] world;
187  }
188  else{
189    for(int i=0;i<size;i++) newzarray[i] = zarray[i];
190  }
191  return newzarray;
192}
193
194double FitsHeader::specToVel(const double &coord)
195{
196  double vel;
197  if(power==1.0) vel =  coord*this->scale + this->offset;
198  else vel = pow( (coord*this->scale + this->offset), this->power);
199  return vel;
200}
201
202double FitsHeader::velToSpec(const float &velocity)
203{
204//   return velToCoord(this->wcs,velocity,this->spectralUnits);};
205  return (pow(velocity, 1./this->power) - this->offset) / this->scale;
206}
207
208std::string FitsHeader::getIAUName(double ra, double dec)
209{
210  if(strcmp(this->wcs->lngtyp,"RA")==0)
211    return getIAUNameEQ(ra, dec, this->wcs->equinox);
212  else
213    return getIAUNameGAL(ra, dec);
214}
215
216void FitsHeader::fixUnits(Param &par)
217{
218  // define spectral units from the param set
219  this->spectralUnits = par.getSpectralUnits();
220
221  double sc=1.;
222  double of=0.;
223  double po=1.;
224  if(this->wcsIsGood){
225    int status = wcsunits( this->wcs->cunit[this->wcs->spec],
226                           this->spectralUnits.c_str(),
227                           &sc, &of, &po);
228    if(status > 0){
229      std::stringstream errmsg;
230      errmsg << "WCSUNITS Error, Code = " << status
231             << ": " << wcsunits_errmsg[status];
232      if(status == 10)
233        errmsg << "\nTried to get conversion from \""
234               << this->wcs->cunit[this->wcs->spec] << "\" to \""
235               << this->spectralUnits.c_str() << "\".\n";
236      this->spectralUnits = this->wcs->cunit[this->wcs->spec];
237      if(this->spectralUnits==""){
238        errmsg << "Spectral units not specified. "
239               << "For data presentation, we will use dummy units of \"SPC\".\n"
240               << "Please report this occurence -- it should not happen now!"
241               << "In the meantime, you may want to set the CUNIT"
242               << this->wcs->spec + 1 <<" keyword to make this work.\n";
243        this->spectralUnits = "SPC";
244      }
245      duchampError("fixUnits", errmsg.str());
246     
247    }
248  }
249  this->scale = sc;
250  this->offset= of;
251  this->power = po;
252
253  // Work out the integrated flux units, based on the spectral units.
254  // If flux is per beam, trim the /beam from the flux units and multiply
255  //  by the spectral units.
256  // Otherwise, just muliply by the spectral units.
257  if(this->fluxUnits.size()>0){
258    if(this->fluxUnits.substr(this->fluxUnits.size()-5,
259                              this->fluxUnits.size()   ) == "/beam"){
260      this->intFluxUnits = this->fluxUnits.substr(0,this->fluxUnits.size()-5)
261        +" " +this->spectralUnits;
262    }
263    else this->intFluxUnits = this->fluxUnits + " " + this->spectralUnits;
264  }
265
266}
Note: See TracBrowser for help on using the repository browser.