source: trunk/src/FitsIO/dataIO.cc @ 754

Last change on this file since 754 was 740, checked in by MatthewWhiting, 14 years ago

Reducing amount of memory allocation for reading in image. Also reporting size of memory being read in, to help with problems such as #90.

File size: 5.5 KB
Line 
1// -----------------------------------------------------------------------
2// dataIO.cc: Read the data array from a FITS file into 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#define WCSLIB_GETWCSTAB // define this so that we don't try and redefine
31                         //  wtbarr (this is a problem when using gcc v.4+
32#include <fitsio.h>
33#include <math.h>
34#include <duchamp/duchamp.hh>
35#include <duchamp/param.hh>
36#include <duchamp/fitsHeader.hh>
37#include <duchamp/Cubes/cubes.hh>
38
39namespace duchamp
40{
41
42  OUTCOME Cube::getFITSdata(std::string fname)
43  {
44    /// This function retrieves the data array from the FITS file at the
45    ///   location given by the string argument.
46    ///  Only the two spatial axes and the one spectral axis are stored in the
47    ///   data array. These axes are given by the wcsprm variables wcs->lng,
48    ///   wcs->lat and wcs->spec.
49    ///  All other axes are just read by their first pixel, using the
50    ///   fits_read_subsetnull_flt function
51
52    int numAxes, status = 0;  /* MUST initialize status */
53    fitsfile *fptr; 
54
55    // Open the FITS file
56    status = 0;
57    if( fits_open_file(&fptr,fname.c_str(),READONLY,&status) ){
58      fits_report_error(stderr, status);
59      return FAILURE;
60    }
61
62    // Read the size of the FITS file -- number and sizes of the axes
63    status = 0;
64    if(fits_get_img_dim(fptr, &numAxes, &status)){
65      fits_report_error(stderr, status);
66      return FAILURE;
67    }
68
69    long *dimAxes = new long[numAxes];
70    for(int i=0;i<numAxes;i++) dimAxes[i]=1;
71    status = 0;
72    if(fits_get_img_size(fptr, numAxes, dimAxes, &status)){
73      fits_report_error(stderr, status);
74      return FAILURE;
75    }
76
77    // Identify which axes are the "interesting" ones
78    int lng,lat,spc;
79    if(this->head.isWCS() && (this->head.WCS().spec>=0)){
80      lng = this->head.WCS().lng;
81      lat = this->head.WCS().lat;
82      spc = this->head.WCS().spec;
83    }
84    else{
85      lng = 0;
86      lat = 1;
87      spc = 2;
88    }
89   
90    int anynul;
91    int npix = dimAxes[lng];
92    if(numAxes>1) npix *= dimAxes[lat];
93    if((spc>=0)&&(numAxes>spc)) npix *= dimAxes[spc];
94
95
96    // define the first and last pixels for each axis.
97    // set both to 1 for the axes we don't want, and to the full
98    //  range for the ones we do.
99    long *fpixel = new long[numAxes];
100    long *lpixel = new long[numAxes];
101    long *inc = new long[numAxes];    // the data-sampling increment
102    for(int i=0;i<numAxes;i++){
103      inc[i] = fpixel[i] = lpixel[i] = 1;
104    }
105    lpixel[lng] = dimAxes[lng];
106    if(numAxes>1) lpixel[lat] = dimAxes[lat];
107    if((spc>=0)&&(numAxes>spc)) lpixel[spc] = dimAxes[spc];
108
109    int colnum = 0;  // want the first dataset in the FITS file
110
111    // read the relevant subset, defined by the first & last pixel ranges
112    if(this->initialiseCube(dimAxes) == FAILURE) return FAILURE;
113    if(this->par.isVerbose()){
114      float size = dimAxes[0];
115      for(int i=1;i<numAxes;i++) size*=dimAxes[i];
116      size *= sizeof(float) / 1024.;
117      std::string units=" kB";
118      if(size > 1024.){
119        size /= 1024.;
120        units = " MB";
121      }
122      if(size > 1024.){
123        size /= 1024.;
124        units = " GB";
125      }
126      if(size > 1024.){
127        size /= 1024.;
128        units = " TB";
129      }
130      std::cout << "\n  About to read " << size << units <<"\n";
131    }
132    status = 0;
133    if(fits_read_subset_flt(fptr, colnum, numAxes, dimAxes,
134                            fpixel, lpixel, inc,
135                            this->par.getBlankPixVal(), this->array, &anynul, &status)){
136      duchampError("Cube Reader",
137                   "There was an error reading in the data array:");
138      fits_report_error(stderr, status);
139      return FAILURE;
140    }
141
142    delete [] fpixel;
143    delete [] lpixel;
144    delete [] inc;
145
146    if(anynul==0){   
147      // no blank pixels, so don't bother with any trimming or checking...
148      if(this->par.getFlagTrim()) { 
149        // if user requested fixing, inform them of change.
150        duchampWarning("Cube Reader",
151                       "No blank pixels, so setting flagTrim to false.\n");
152      }
153      this->par.setFlagBlankPix(false);
154      this->par.setFlagTrim(false);
155    }
156
157    delete [] dimAxes;
158
159    // Close the FITS file -- not needed any more in this function.
160    status = 0;
161    fits_close_file(fptr, &status);
162    if (status){
163      duchampWarning("Cube Reader","Error closing file: ");
164      fits_report_error(stderr, status);
165    }
166
167    return SUCCESS;
168
169  }
170
171}
Note: See TracBrowser for help on using the repository browser.