source: tags/release-1.1.7/src/Cubes/getImage.cc @ 1455

Last change on this file since 1455 was 528, checked in by MatthewWhiting, 15 years ago

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

File size: 8.4 KB
Line 
1// -----------------------------------------------------------------------
2// getImage.cc: Read in a FITS file to a Cube object.
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/wcs.h>
32#include <wcslib/wcshdr.h>
33#include <wcslib/fitshdr.h>
34#include <wcslib/wcsfix.h>
35#include <wcslib/wcsunits.h>
36#define WCSLIB_GETWCSTAB // define this so that we don't try and redefine
37                         //  wtbarr (this is a problem when using gcc v.4+)
38#include <fitsio.h>
39#include <math.h>
40#include <duchamp/duchamp.hh>
41#include <duchamp/param.hh>
42#include <duchamp/fitsHeader.hh>
43#include <duchamp/Cubes/cubes.hh>
44
45namespace duchamp
46{
47
48  std::string imageType[4] = {"point", "spectrum", "image", "cube"};
49
50  int Cube::getMetadata()
51  { 
52    ///  @details
53    /// A front-end to the Cube::getMetadata() function, that does
54    ///  subsection checks. Does the flux unit conversion if the user
55    ///  has requested it. Assumes the Param is set up properly.
56
57    std::string fname = par.getImageFile();
58    if(par.getFlagSubsection()) fname+=par.getSubsection();
59
60    int result = getMetadata(fname);
61   
62    if(result==SUCCESS){
63      // Convert the flux Units if the user has so requested
64      this->convertFluxUnits();
65    }
66
67    return result;
68  }
69  //--------------------------------------------------------------------
70
71  int Cube::getMetadata(std::string fname)
72  {
73    /// @details
74    /// Read in the metadata associated with the cube from the file
75    ///  fname (assumed to be in FITS format).  Function is a front end
76    ///  to the I/O functions in the FitsIO/ directory.  This function
77    ///  will check that the file exists, report the dimensions and
78    ///  then get other functions to read the WCS and necessary header
79    ///  keywords. This function does not read in the data array --
80    ///  that is done by Cube::getCube(). Note that no conversion of
81    ///  flux units is done -- you need to call Cube::getMetadata() or
82    ///  do it separately.
83    ///  \param fname A std::string with name of FITS file.
84    ///  \return SUCCESS or FAILURE.
85
86    int numAxes, status = 0;  /* MUST initialize status */
87    fitsfile *fptr;         
88
89    int exists;
90    fits_file_exists(fname.c_str(),&exists,&status);
91    if(exists<=0){
92      fits_report_error(stderr, status);
93      std::stringstream errmsg;
94      errmsg << "Requested image (" << fname << ") does not exist!\n";
95      duchampError("Cube Reader", errmsg.str());
96      return FAILURE;
97    }
98
99    // Open the FITS file -- make sure it exists
100    status = 0;
101    if( fits_open_file(&fptr,fname.c_str(),READONLY,&status) ){
102      fits_report_error(stderr, status);
103      if(((status==URL_PARSE_ERROR)||(status==BAD_NAXIS))
104         &&(this->pars().getFlagSubsection()))
105        duchampError("Cube Reader",
106                     "It may be that the subsection you've entered is invalid.\n\
107Either it has the wrong number of axes, or one axis has too large a range.\n");
108      return FAILURE;
109    }
110
111    // Read the size information -- number and lengths of all axes.
112    // Just use this for reporting purposes.
113    status = 0;
114    if(fits_get_img_dim(fptr, &numAxes, &status)){
115      fits_report_error(stderr, status);
116      return FAILURE;
117    }
118    long *dimAxes = new long[numAxes];
119    for(int i=0;i<numAxes;i++) dimAxes[i]=1;
120    status = 0;
121    if(fits_get_img_size(fptr, numAxes, dimAxes, &status)){
122      fits_report_error(stderr, status);
123      return FAILURE;
124    }
125
126    // Close the FITS file.
127    status = 0;
128    fits_close_file(fptr, &status);
129    if (status){
130      duchampWarning("Cube Reader","Error closing file: ");
131      fits_report_error(stderr, status);
132    }
133
134    // Report the size of the FITS file
135    if(this->par.isVerbose()){
136      std::cout << "Dimensions of FITS file: ";
137      int dim = 0;
138      std::cout << dimAxes[dim];
139      while(dim+1<numAxes) std::cout << "x" << dimAxes[++dim];
140      std::cout << std::endl;
141    }
142
143    // Get the WCS information
144    this->head.defineWCS(fname, this->par);
145
146    if(!this->head.isWCS())
147      duchampWarning("Cube Reader","WCS is not good enough to be used.\n");
148
149    // allocate the dimension array in the Cube.
150    this->initialiseCube(dimAxes,false);
151
152    // Read the necessary header information, and copy some of it into the Param.
153    this->head.readHeaderInfo(fname, this->par);
154
155    delete [] dimAxes;
156
157    return SUCCESS;
158
159  }
160  //--------------------------------------------------------------------
161
162
163  int Cube::getCube(std::string fname)
164  {
165    /// @details
166    /// Read in a cube from the file fname (assumed to be in FITS
167    ///  format).  Function is a front end to the data I/O function in
168    ///  the FitsIO/ directory.  This function calls the getMetadata()
169    ///  function, then reads in the actual data array.
170    ///  \param fname A std::string with name of FITS file.
171    ///  \return SUCCESS or FAILURE.
172
173    this->getMetadata(fname);
174
175    // Get the data array from the FITS file.
176    // Report the dimensions of the data array that was read (this can be
177    //   different to the full FITS array).
178    if(this->par.isVerbose()) std::cout << "Reading data ... "<<std::flush;
179    if(this->getFITSdata(fname)) return FAILURE;
180
181    if(this->axisDim[2] == 1){
182      this->par.setMinChannels(0);
183    }
184
185    if(this->par.isVerbose()){
186      std::cout << "Done. Data array has dimensions: ";
187      std::cout << this->axisDim[0];
188      if(this->axisDim[1]>1) std::cout  <<"x"<< this->axisDim[1];
189      if(this->axisDim[2]>1) std::cout  <<"x"<< this->axisDim[2];
190      std::cout << "\n";
191    }   
192
193    // Check for 2D images
194    this->checkDim();
195    // Convert the flux Units if the user has so requested
196    this->convertFluxUnits();
197
198    return SUCCESS;   
199
200  }
201  //--------------------------------------------------------------------
202
203
204  void Cube::convertFluxUnits()
205  {
206    /// @details
207    ///  If the user has requested new flux units (via the input
208    ///  parameter newFluxUnits), this function converts the units
209    ///  given by BUNIT to those given by newFluxUnits. If no simple
210    ///  conversion can be found (by using wcsunits()) then nothing is
211    ///  done and the user is informed, otherwise the
212    ///  FitsHeader::fluxUnits parameter is updated and the pixel array
213    ///  is converted accordingly.
214
215    if(this->par.getNewFluxUnits()!=""){
216
217      std::string oldUnit = this->head.getFluxUnits();
218      std::string newUnit = this->par.getNewFluxUnits();
219
220      if(oldUnit != newUnit){
221
222        if(this->par.isVerbose()){
223          std::cout << "Converting flux units from " << oldUnit << " to " << newUnit << "... ";
224          std::cout << std::flush;
225        }
226
227        double scale,offset,power;
228        int status = wcsunits(oldUnit.c_str(), newUnit.c_str(), &scale, &offset, &power);
229
230        if(status==0){
231       
232          this->head.setFluxUnits( newUnit );
233          this->head.setIntFluxUnits();
234
235          if(this->arrayAllocated){
236            for(int i=0;i<this->numPixels;i++)
237              if(!this->isBlank(i)) this->array[i] = pow(scale * array[i] + offset, power);
238          }
239          if(this->par.isVerbose()) {
240            std::cout << " Done.\n";
241          }
242        }
243        else{
244          std::stringstream ss;
245          ss << "Could not convert units from " << oldUnit << " to " << newUnit
246             << ".\nLeaving BUNIT as " << oldUnit << "\n";
247          if(this->par.isVerbose()) std::cout << "\n";
248          duchampWarning("convertFluxUnits", ss.str());
249        }
250      }
251    }
252
253  }
254
255
256}
Note: See TracBrowser for help on using the repository browser.