source: tags/release-0.9.2/Cubes/getImage.cc @ 1377

Last change on this file since 1377 was 71, checked in by Matthew Whiting, 18 years ago

A swag of changes, centred around the addition of functionality to read
in an already saved FITS file containing the reconstructed array.

duchamp.hh -- const strings containing new keywords for saved FITS files.
Cubes/saveImage.cc -- improved methods for saving the FITS files, including

header keywords indicating origin.

Cubes/readRecon.cc -- new function to read in reconstructed array from FITS file.
Cubes/cubes.cc -- recon array now declared if recon file exists.
Cubes/cubes.hh -- prototype for readReconCube
Cubes/trimImage.cc -- allow for case of recon file existing.
Cubes/getImage.cc -- improved error/warning reporting to match new function.
param.hh -- new parameters to deal with reconFile
param.cc -- IO and default values for new parameters.
docs/Guide.tex -- Describing new option. Also added instal guide.
InputComplete? -- Added new parameters, and set values shown to be default values.
mainDuchamp.cc -- code related to new function.
ATrous/ReconSearch.cc -- will now not do reconstruction if recon array exists.

Fixed bug in output.

ATrous/baselineSubtract.cc -- Subtract baseline from recon array if it exists.
Utils/wcsFunctions.cc -- Fixed error/warning reporting in line with new standards.

File size: 12.0 KB
Line 
1#include <iostream>
2#include <string>
3#include <wcs.h>
4#include <wcshdr.h>
5#include <fitshdr.h>
6#include <wcsfix.h>
7#include <fitsio.h>
8#include <math.h>
9#include <duchamp.hh>
10#include <Cubes/cubes.hh>
11
12#ifdef NAN
13float nanValue = NAN;
14#endif
15
16using std::endl;
17
18string imageType[4] = {"point", "spectrum", "image", "cube"};
19
20int Cube::getCube(string fname)
21{
22  /**
23   * Cube::getCube(string )
24   *  Read in a cube from the file fname (assumed to be in FITS format).
25   *  Function reads in the following:
26   *      - axis dimensions
27   *      - pixel array
28   *      - WCS information (in form of WCSLIB wcsprm structure)
29   *      - Header keywords: BUNIT (brightness unit),
30   *                         BLANK, BZERO, BSCALE (to determine blank pixel value)
31   *                         BMAJ, BMIN, CDELT1, CDELT2 (to determine beam size)
32   */
33
34
35  short int maxdim=3;
36  long *fpixel = new long[maxdim];
37  for(int i=0;i<maxdim;i++) fpixel[i]=1;
38  long *dimAxes = new long[maxdim];
39  for(int i=0;i<maxdim;i++) dimAxes[i]=1;
40  long nelements;
41  int bitpix,numAxes;
42  int status = 0,  nkeys;  /* MUST initialize status */
43  fitsfile *fptr;         
44
45  if( fits_open_file(&fptr,fname.c_str(),READONLY,&status) ){
46    fits_report_error(stderr, status);
47    return FAILURE;
48  }
49
50  status = 0;
51  fits_get_img_param(fptr, maxdim, &bitpix, &numAxes, dimAxes, &status);
52  if(status){
53    fits_report_error(stderr, status);
54    return FAILURE;
55  }
56
57  if(numAxes<=3)  std::cout << "Dimensions of " << imageType[numAxes] << ": " << dimAxes[0];
58  else std::cout << "Dimensions of " << imageType[3] << ": " << dimAxes[0];
59  if(numAxes>1) std::cout << "x" << dimAxes[1];
60  if(numAxes>2) std::cout << "x" << dimAxes[2];
61  std::cout << endl;
62
63  int npix = dimAxes[0]*dimAxes[1]*dimAxes[2];
64  float *array = new float[npix];
65  int anynul;
66  char *nullarray = new char[npix];
67  for(int i=0;i<npix;i++) nullarray[i] = 0;
68
69  //-------------------------------------------------------------
70  // Reading in the pixel array.
71  //  The location of any blank pixels (as determined by the header keywords) is stored
72  //  in nullarray (set to 1). Also anynul will be set to 1 to indicate the presence of
73  //  blank pixels. If anynul==1 then all pixels are non-blank.
74
75  status = 0;
76  fits_read_pixnull(fptr, TFLOAT, fpixel, npix, array, nullarray, &anynul, &status);
77//   fits_read_pix(fptr, TFLOAT, fpixel, npix, NULL, array, &anynul, &status);
78  if(status){
79    fits_report_error(stderr, status);
80    return FAILURE;
81  }
82
83  if(anynul==0){    // no blank pixels, so don't bother with any trimming or checking...
84    if(this->par.getFlagBlankPix())  // if user requested fixing, inform them of change.
85      std::cerr << "WARNING <getCube> : No blank pixels, so setting flagBlankPix to false...\n";
86    this->par.setFlagBlankPix(false);
87  }
88
89  //-------------------------------------------------------------
90  // Read the header in preparation for WCS and BUNIT/BLANK/etc extraction.
91  char *hdr = new char;
92  int noComments = 1; //so that fits_hdr2str will not write out COMMENT, HISTORY etc
93  int nExc = 0;
94  status = 0;
95  fits_hdr2str(fptr, noComments, NULL, nExc, &hdr, &nkeys, &status);
96  if( status ){
97    std::cerr << "WARNING <getCube> : Error reading in header to string: ";
98    fits_report_error(stderr, status);
99  }
100
101  //-------------------------------------------------------------
102  // Read the BUNIT header keyword, to store the brightness unit.
103  int blank;
104  float bscale, bzero;
105  char *comment = new char[80];
106  char *bunit = new char[80];
107  status = 0;
108  fits_read_key(fptr, TSTRING, "BUNIT", bunit, comment, &status);
109  if (status){
110    std::cerr << "WARNING <getCube> : Error reading BUNIT keyword: ";
111    fits_report_error(stderr, status);
112  }
113  else this->setBUnit(bunit);
114
115  //-------------------------------------------------------------
116  // Reading in the Blank pixel value keywords.
117  //  If the BLANK keyword is in the header, use that and store the relevant values.
118  //  If not, use the default value (either the default from param.cc or from the param file)
119  //    and assume simple values for the keywords --> the scale keyword is the same as the
120  //    blank value, the blank keyword (which is an int) is 1 and the bzero (offset) is 0.
121  status = 0;
122  if(this->par.getFlagBlankPix()){
123    if( !fits_read_key(fptr, TINT32BIT, "BLANK", &blank, comment, &status) ){
124      fits_read_key(fptr, TFLOAT, "BZERO", &bzero, comment, &status);
125      fits_read_key(fptr, TFLOAT, "BSCALE", &bscale, comment, &status);
126      this->par.setBlankPixVal(blank*bscale+bzero);
127      this->par.setBlankKeyword(blank);
128      this->par.setBscaleKeyword(bscale);
129      this->par.setBzeroKeyword(bzero);
130    }
131    if (status){
132      std::cerr << "WARNING <getCube> : Error reading BLANK keyword: ";
133      fits_report_error(stderr, status);
134      std::cerr << "Using default BLANK (physical) value (" << this->par.getBlankPixVal() << ")." << endl;
135      for(int i=0;i<npix;i++) if(isnan(array[i])) array[i] = this->par.getBlankPixVal();
136      this->par.setBlankKeyword(1);
137      this->par.setBscaleKeyword(this->par.getBlankPixVal());
138      this->par.setBzeroKeyword(0.);
139    }
140  }
141
142  //-------------------------------------------------------------
143  // Reading in the beam parameters from the header.
144  // Use these, plus the basic WCS parameters to calculate the size of the beam in pixels.
145  float bmaj,bmin,cdelt1,cdelt2;
146  status = 0;
147  if( !fits_read_key(fptr, TFLOAT, "BMAJ", &bmaj, comment, &status) ){
148    fits_read_key(fptr, TFLOAT, "BMIN", &bmin, comment, &status);
149    fits_read_key(fptr, TFLOAT, "CDELT1", &cdelt1, comment, &status);
150    fits_read_key(fptr, TFLOAT, "CDELT2", &cdelt2, comment, &status);
151    this->par.setBeamSize( M_PI * (bmaj/2.) * (bmin/2.) / fabsf(cdelt1*cdelt2) );
152  }
153  if (status){
154    std::cerr <<
155      "WARNING <getCube> : No beam information in header. Setting size to nominal 10 pixels.\n";
156    this->par.setBeamSize(10.);
157  }
158
159  status = 0;
160  fits_close_file(fptr, &status);
161  if (status){
162    std::cerr << "WARNING <getCube> : Error closing file: ";
163    fits_report_error(stderr, status);
164  }
165
166  this->initialiseCube(dimAxes);
167  this->saveArray(array,npix);
168  //-------------------------------------------------------------
169  // Once the array is saved, change the value of the blank pixels from
170  // 0 (as they are set by fits_read_pixnull) to the correct blank value
171  // as determined by the above code.
172  for(int i=0; i<npix;i++){
173    if(nullarray[i]==1) this->array[i] = blank*bscale + bzero; 
174  }
175
176  //-------------------------------------------------------------
177  // Now convert the FITS header to a WCS structure, using the WCSLIB functions.
178  int relax=1, ctrl=2, nwcs, nreject;
179  wcsprm *wcs = new wcsprm;
180  wcsini(true,numAxes,wcs);
181  wcs->flag=-1;
182  int flag;
183  if(flag = wcspih(hdr, nkeys, relax, ctrl, &nreject, &nwcs, &wcs)) {
184    std::cerr<<"WARNING <getCube> : WCSPIH failed! Code="<<flag<<": "<<wcs_errmsg[flag]<<endl;
185  }
186  else{ 
187    int stat[6],axes[3]={dimAxes[0],dimAxes[1],dimAxes[2]};
188    if(flag=wcsfix(1,axes,wcs,stat)) {
189      std::cerr<<"WARNING <getCube> : WCSFIX failed!"<<endl;
190      for(int i=0; i<NWCSFIX; i++)
191        if (stat[i] > 0) std::cerr<<"wcsfix ERROR "<<flag<<": "<< wcsfix_errmsg[stat[i]] <<endl;
192    }
193    if(flag=wcsset(wcs)){
194      std::cerr<<"WARNING <getCube> : WCSSET failed! Code="<<flag <<": "<<wcs_errmsg[flag]<<endl;
195    }
196
197    this->setWCS(wcs);
198    this->setNWCS(nwcs);
199  }
200  wcsfree(wcs);
201
202  if(!this->flagWCS) std::cerr << "WARNING <getCube> : WCS is not good enough to be used.\n";
203
204  delete hdr;
205  delete [] array;
206  delete [] fpixel;
207  delete [] dimAxes;
208
209  return SUCCESS;
210
211}
212
213Cube getCube(string fname, Param par)
214{
215  short int maxdim=3;
216  long *fpixel = new long[maxdim];
217  for(int i=0;i<maxdim;i++) fpixel[i]=1;
218  long *dimAxes = new long[maxdim];
219  for(int i=0;i<maxdim;i++) dimAxes[i]=1;
220  long nelements;
221  int bitpix,numAxes,anynul;
222  int status = 0,  nkeys;  /* MUST initialize status */
223  fitsfile *fptr;         
224
225  if( fits_open_file(&fptr,fname.c_str(),READONLY,&status) ){
226    fits_report_error(stderr, status);
227    return 1;
228  }
229
230  fits_get_img_param(fptr, maxdim, &bitpix, &numAxes, dimAxes, &status);
231  int npix = dimAxes[0]*dimAxes[1]*dimAxes[2];
232  float *array = new float[npix];
233  fits_read_pix(fptr, TFLOAT, fpixel, npix, NULL, array, &anynul, &status);
234
235  // Read the header
236  char *hdr = new char;
237  int noComments = 1; //fits_hdr2str will not write out COMMENT, HISTORY etc
238  int nExc = 0;
239  if( fits_hdr2str(fptr, noComments, NULL, nExc, &hdr, &nkeys, &status) ){
240    fits_report_error(stderr, status);
241    return 1;
242  }
243
244  float blank, bscale, bzero;
245  char *comment = new char[80];
246  //  if( fits_movabs_hdu(fptr, 1, IMAGE_HDU, &status)) fits_report_error(stderr, status);
247  if( !fits_read_key(fptr, TFLOAT, "BLANK", &blank, comment, &status) ){
248    fits_read_key(fptr, TFLOAT, "BZERO", &bzero, comment, &status);
249    fits_read_key(fptr, TFLOAT, "BSCALE", &bscale, comment, &status);
250    par.setBlankPixVal(blank*bscale+bzero);
251  }
252  if (status) fits_report_error(stderr, status);
253  char *bunit = new char[80];
254  fits_read_key(fptr, TSTRING, "BUNIT", bunit, comment, &status);
255  if (status) fits_report_error(stderr, status);
256
257  fits_close_file(fptr, &status);
258  if (status) fits_report_error(stderr, status);
259
260  int relax=1, ctrl=2, nwcs, nreject;
261  wcsprm *wcs = new wcsprm;
262  wcsini(true,numAxes,wcs);
263  wcs->flag=-1;
264  int flag;
265  if(flag = wcspih(hdr, nkeys, relax, ctrl, &nreject, &nwcs, &wcs)) {
266    std::cerr<<"getImage.cc:: WCSPIH failed! Code="<<flag<<": "<<wcs_errmsg[flag]<<endl;
267    return 1;
268  }
269 
270  int stat[6],axes[3]={dimAxes[0],dimAxes[1],dimAxes[2]};
271  if(flag=wcsfix(1,axes,wcs,stat)) {
272    std::cerr<<"getImage.cc:: WCSFIX failed!"<<endl;
273    for(int i=0; i<NWCSFIX; i++)
274      if (stat[i] > 0) std::cerr<<"wcsfix ERROR "<<flag<<": "<< wcsfix_errmsg[stat[i]] <<endl;
275    return 1;
276  }
277  if(flag=wcsset(wcs)){
278    std::cerr<<"getImage.cc:: WCSSET failed! Code="<<flag <<": "<<wcs_errmsg[flag]<<endl;
279    return 1;
280  }
281
282  Cube *data = new Cube(dimAxes);
283  data->saveArray(array,npix);
284  data->setWCS(wcs);
285  data->setNWCS(nwcs);
286  data->setBUnit(bunit);
287
288  wcsfree(wcs);
289  delete hdr;
290  delete [] array;
291  delete [] fpixel;
292  delete [] dimAxes;
293
294
295  return *data;
296}
297
298Image getImage(string fname)
299{
300  int maxdim=2;
301  long *fpixel = new long[maxdim];
302  for(int i=0;i<maxdim;i++) fpixel[i]=1;
303  long *dimAxes = new long[maxdim];
304  for(int i=0;i<maxdim;i++) dimAxes[i]=1;
305  long nelements;
306  int bitpix,numAxes,anynul;
307  int status = 0,  nkeys;  /* MUST initialize status */
308  fitsfile *fptr;         
309
310  std::cerr << fname.c_str() << endl;
311
312  fits_open_file(&fptr,fname.c_str(),READONLY,&status);
313  if (status) fits_report_error(stderr, status);
314  fits_get_img_param(fptr, maxdim, &bitpix, &numAxes, dimAxes, &status);
315  int npix = dimAxes[0]*dimAxes[1];
316  float *cube = new float[npix];
317  fits_read_pix(fptr, TFLOAT, fpixel, npix, NULL, cube, &anynul, &status);
318  fits_close_file(fptr, &status);
319  if (status) fits_report_error(stderr, status);
320
321  Image data(dimAxes);
322  data.saveArray(cube,npix);
323
324  delete [] cube;
325  delete [] fpixel;
326  delete [] dimAxes;
327
328  //  std::cerr << data.getSize()<<"  "<<data.getDimX()<<" "<<data.getDimY()<<endl;
329
330  return data;
331}
332
333DataArray getImage(string fname, short int maxdim)
334{
335  long *fpixel = new long[maxdim];
336  for(int i=0;i<maxdim;i++) fpixel[i]=1;
337  long *dimAxes = new long[maxdim];
338  for(int i=0;i<maxdim;i++) dimAxes[i]=1;
339  long nelements;
340  int bitpix,numAxes,anynul;
341  int status = 0,  nkeys;  /* MUST initialize status */
342  fitsfile *fptr;         
343
344  std::cerr << fname.c_str() << endl;
345
346  fits_open_file(&fptr,fname.c_str(),READONLY,&status);
347  if (status) fits_report_error(stderr, status);
348  fits_get_img_param(fptr, maxdim, &bitpix, &numAxes, dimAxes, &status);
349  int npix = dimAxes[0];
350  for(int i=1;i<numAxes;i++) npix *= dimAxes[i];
351  float *cube = new float[npix];
352  fits_read_pix(fptr, TFLOAT, fpixel, npix, NULL, cube, &anynul, &status);
353  fits_close_file(fptr, &status);
354  if (status) fits_report_error(stderr, status);
355
356  DataArray data(numAxes,dimAxes);
357  data.saveArray(cube,npix);
358
359  delete [] cube;
360  delete [] fpixel;
361  delete [] dimAxes;
362
363  return data;
364}
365
Note: See TracBrowser for help on using the repository browser.