source: trunk/src/FitsIO/headerIO.cc @ 415

Last change on this file since 415 was 415, checked in by MatthewWhiting, 16 years ago

Fixed determination of beam size, so that it doesn't just rely on CDELT? keywords

File size: 8.6 KB
Line 
1// -----------------------------------------------------------------------
2// headerIO.cc: Read in various PHU keywords from a FITS file.
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 <string>
30#include <string.h>
31#include <wcslib/wcsunits.h>
32#define WCSLIB_GETWCSTAB // define this so that we don't try and redefine
33                         //  wtbarr (this is a problem when using gcc v.4+
34#include <fitsio.h>
35#include <longnam.h>
36#include <math.h>
37#include <duchamp/duchamp.hh>
38#include <duchamp/Cubes/cubes.hh>
39
40namespace duchamp
41{
42
43  int FitsHeader::readHeaderInfo(std::string fname, Param &par)
44  {
45    /**
46     *  A simple front-end function to the three header access
47     *   functions defined below.
48     *
49     */
50
51    int returnValue = SUCCESS;
52
53    //   if(this->readBUNIT(fname)==FAILURE) returnValue=FAILURE;
54 
55    if(this->readBLANKinfo(fname, par)==FAILURE) returnValue=FAILURE;
56 
57    if(this->needBeamSize())
58      if(this->readBeamInfo(fname, par)==FAILURE) returnValue=FAILURE;
59
60    return returnValue;
61  }
62
63
64  //////////////////////////////////////////////////
65
66  int FitsHeader::readBUNIT(std::string fname)
67  {
68    /**
69     *   Read the BUNIT header keyword, to store the units of brightness (flux).
70     *  \param fname The name of the FITS file.
71     */
72    fitsfile *fptr;         
73    char *comment = new char[FLEN_COMMENT];
74    char *unit = new char[FLEN_VALUE];
75    int returnStatus = 0, status = 0;
76
77    // Open the FITS file
78    status = 0;
79    if( fits_open_file(&fptr,fname.c_str(),READONLY,&status) ){
80      fits_report_error(stderr, status);
81      return FAILURE;
82    }
83
84    // Read the BUNIT keyword, and translate to standard unit format if needs be
85    fits_read_key(fptr, TSTRING, "BUNIT", unit, comment, &returnStatus);
86    if (returnStatus){
87      duchampWarning("Cube Reader","Error reading BUNIT keyword: ");
88      fits_report_error(stderr, returnStatus);
89    }
90    else{
91      wcsutrn(0,unit);
92      this->fluxUnits = unit;
93    }
94
95    // Close the FITS file
96    status = 0;
97    fits_close_file(fptr, &status);
98    if (status){
99      duchampWarning("Cube Reader","Error closing file: ");
100      fits_report_error(stderr, status);
101    }
102
103    delete [] comment;
104    delete [] unit;
105
106    return returnStatus;
107  }
108
109  //////////////////////////////////////////////////
110
111  int FitsHeader::readBLANKinfo(std::string fname, Param &par)
112  {
113    /**
114     *    Reading in the Blank pixel value keywords, which is only done
115     *    if requested via the flagBlankPix parameter.
116     *
117     *    If the BLANK keyword is in the header, use that and store the relevant
118     *     values. Also copy them into the parameter set.
119     *    If not, use the default value (either the default from param.cc or
120     *     from the param file) and assume simple values for the keywords:
121     *     <ul><li> The scale keyword is the same as the blank value,
122     *         <li> The blank keyword (which is an int) is 1 and
123     *         <li> The bzero (offset) is 0.
124     *    </ul>
125     * \param fname The name of the FITS file.
126     * \param par The Param set: to know the flagBlankPix value and to
127     * store the keywords.
128     */
129    int returnStatus = 0, status = 0;
130
131    fitsfile *fptr;         
132    char *comment = new char[FLEN_COMMENT];
133    int blank;
134    float bscale, bzero;
135   
136    // Open the FITS file.
137    if( fits_open_file(&fptr,fname.c_str(),READONLY,&status) ){
138      fits_report_error(stderr, status);
139      return FAILURE;
140    }
141
142    // Read the BLANK keyword.
143    //  If this isn't present, make sure flagTrim is false (if it is
144    //  currently true, let the user know you're doing this) and set
145    //  flagBlankPix to false so that the isBlank functions all return
146    //  false
147    //  If it is, read the other two necessary keywords, and then set
148    //     the values accordingly.
149
150    if(fits_read_key(fptr, TINT, "BLANK", &blank, comment, &returnStatus)){
151
152      par.setFlagBlankPix(false);
153
154      if(par.getFlagTrim()){
155        par.setFlagTrim(false);
156        std::stringstream errmsg;
157        if(returnStatus == KEY_NO_EXIST)
158          duchampWarning("Cube Reader",
159                         "There is no BLANK keyword present. Not doing any trimming.\n");
160        else{
161          duchampWarning("Cube Reader",
162                         "Error reading BLANK keyword, so not doing any trimming.");
163          fits_report_error(stderr, returnStatus);
164        }
165      }
166    }
167    else{
168      status = 0;
169      fits_read_key(fptr, TFLOAT, "BZERO", &bzero, comment, &status);
170      status = 0;
171      fits_read_key(fptr, TFLOAT, "BSCALE", &bscale, NULL, &status);
172      this->blankKeyword  = blank;
173      this->bscaleKeyword = bscale;
174      this->bzeroKeyword  = bzero;
175      par.setBlankKeyword(blank);
176      par.setBscaleKeyword(bscale);
177      par.setBzeroKeyword(bzero);
178      par.setBlankPixVal( blank*bscale + bzero );
179    }
180 
181    // Close the FITS file.
182    status = 0;
183    fits_close_file(fptr, &status);
184    if (status){
185      duchampWarning("Cube Reader","Error closing file: ");
186      fits_report_error(stderr, status);
187    }
188 
189    delete [] comment;
190
191    return returnStatus;
192
193  }
194
195  //////////////////////////////////////////////////
196
197  int FitsHeader::readBeamInfo(std::string fname, Param &par)
198  {
199    /**
200     *   Reading in the beam parameters from the header.
201     *   Use these, plus the basic WCS parameters to calculate the size of
202     *    the beam in pixels. Copy the beam size into the parameter set.
203     *   If information not present in FITS header, use the parameter
204     *    set to define the beam size.
205     * \param fname The name of the FITS file.
206     * \param par The Param set.
207     */
208    char *comment = new char[80];
209    std::string keyword[5]={"BMAJ","BMIN","BPA","CDELT1","CDELT2"};
210    float bmaj,bmin,bpa;
211    int status[7];
212    fitsfile *fptr;         
213
214    for(int i=0;i<7;i++) status[i] = 0;
215
216    // Open the FITS file
217    if( fits_open_file(&fptr,fname.c_str(),READONLY,&status[0]) ){
218      fits_report_error(stderr, status[0]);
219      return FAILURE;
220    }
221
222    // Read the Keywords -- first look for BMAJ. If it is present, read the
223    //   others, and calculate the beam size.
224    // If it is not, give warning and set beam size to nominal value.
225    fits_read_key(fptr, TFLOAT, (char *)keyword[0].c_str(), &bmaj,
226                  comment, &status[1]);
227    fits_read_key(fptr, TFLOAT, (char *)keyword[1].c_str(), &bmin,
228                  comment, &status[2]);
229    fits_read_key(fptr, TFLOAT, (char *)keyword[2].c_str(), &bpa,
230                  comment, &status[3]);
231
232    if(status[1]||status[2]||status[3]// ||status[4]||status[5]
233       ){ // error
234      std::stringstream errmsg;
235      errmsg << "Header keywords not present: ";
236      for(int i=0;i<3;i++) if(status[i+1]) errmsg<<keyword[i]<<" ";
237      errmsg << "\nUsing parameter beamSize to determine size of beam.\n";
238      duchampWarning("Cube Reader",errmsg.str());
239      this->setBeamSize(par.getBeamSize());
240      par.setFlagUsingBeam(true);
241    }
242    else{ // all keywords present
243      float pixScale = this->getAvPixScale();
244      this->setBeamSize( M_PI * (bmaj/2.) * (bmin/2.) / (pixScale*pixScale) );
245      this->setBmajKeyword(bmaj);
246      this->setBminKeyword(bmin);
247      this->setBpaKeyword(bpa);
248      par.setBeamSize(this->beamSize);
249    }
250   
251    // Close the FITS file.
252    fits_close_file(fptr, &status[6]);
253    if (status[6]){
254      duchampWarning("Cube Reader","Error closing file: ");
255      fits_report_error(stderr, status[6]);
256    }
257
258    delete [] comment;
259
260    int returnStatus = status[0];
261    for(int i=1;i<7;i++) if(status[i]>returnStatus) returnStatus=status[i];
262
263    return returnStatus;
264  }
265
266}
Note: See TracBrowser for help on using the repository browser.