source: branches/pixel-map-branch/src/Cubes/saveImage.cc

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

Large raft of changes. Most are minor ones related to fixing up the use of std::string and std::vector (whether they are declared as using, or not...). Other changes include:

  • Moving the reconstruction filter class Filter into its own header/implementation files filter.{hh,cc}. As a result, the atrous.cc file is removed, but atrous.hh remains with just the function prototypes.
  • Incorporating a Filter object into the Param set, so that the reconstruction routines can see it without the messy "extern" call. The define() function is now called in both the Param() and Param::readParams() functions, and no longer in the main body.
  • Col functions in columns.cc moved into the Column namespace, while the template function printEntry is moved into the columns.hh file -- it would not compile on delphinus with it in the columns.cc, even though all the implementations were present.
  • Improved the introductory section of the Guide, with a bit more detail about each of the execution steps. This way the reader can read this section and have a reasonably good idea about what is happening.
  • Other minor changes to the Guide.
File size: 11.4 KB
Line 
1#include <iostream>
2#include <sstream>
3#include <string>
4#include <wcs.h>
5#include <wcshdr.h>
6#define WCSLIB_GETWCSTAB
7// define this so that we don't try and redefine wtbarr
8// (this is a problem when using cfitsio v.3 and g++ v.4)
9
10#include <fitsio.h>
11#include <duchamp.hh>
12#include <Cubes/cubes.hh>
13
14/** Write FITS headers in correct format for reconstructed array output */
15void writeReconHeaderInfo(fitsfile *fptr, Param &par, std::string nature);
16
17/** Write FITS headers in correct format for smoothed array output */
18void writeSmoothHeaderInfo(fitsfile *fptr, Param &par);
19
20void Cube::saveSmoothedCube()
21{
22  /**
23   *   A function to save the Hanning-smoothed arrays to a FITS file.
24   *   Additional header keywords are written as well, indicating the
25   *    width of the Hanning filter.
26   *   The file is always written -- if the filename (as calculated
27   *    based on the parameters) exists, then it is overwritten.
28   */
29 
30  int newbitpix = FLOAT_IMG;
31
32  float blankval = this->par.getBlankPixVal();
33
34  long *fpixel = new long[this->numDim];
35  for(int i=0;i<this->numDim;i++) fpixel[i]=1;
36  int status = 0;  /* MUST initialize status */
37  fitsfile *fptrOld, *fptrNew;         
38  fits_open_file(&fptrOld,this->par.getImageFile().c_str(),READONLY,&status);
39  if (status) fits_report_error(stderr, status);
40 
41  if(this->par.getFlagOutputSmooth()){
42    std::string fileout = "!" + this->par.outputSmoothFile();
43    // the ! is there so that it writes over an existing file.
44
45    status = 0;
46    fits_create_file(&fptrNew,fileout.c_str(),&status);
47    if (status)
48      fits_report_error(stderr, status);
49    else {
50      status = 0;
51      fits_movabs_hdu(fptrOld, 1, NULL, &status);
52      if (status) fits_report_error(stderr, status);
53      status = 0;
54      fits_copy_header(fptrOld, fptrNew, &status);
55      if (status) fits_report_error(stderr, status);
56      char *comment = new char[80];
57      long dud;
58      status = 0;
59      fits_update_key(fptrNew, TINT, "BITPIX", &newbitpix,
60                      "number of bits per data pixel", &status);
61      if (status) fits_report_error(stderr, status);
62      status = 0;
63      float bscale=1., bzero=0.;
64      fits_update_key(fptrNew, TFLOAT, "BSCALE", &bscale,
65                      "PHYSICAL = PIXEL*BSCALE + BZERO", &status);
66      fits_update_key(fptrNew, TFLOAT, "BZERO", &bzero, "", &status);
67      fits_set_bscale(fptrNew, 1., 0., &status);
68      if (status) fits_report_error(stderr, status);
69      // Need to correct the dimensions, if we have subsectioned the image
70      if(this->par.getFlagSubsection()){
71        fits_read_key(fptrOld, TLONG, "NAXIS1", &dud, comment, &status);
72        fits_update_key(fptrNew, TLONG, "NAXIS1",
73                        &(this->axisDim[0]), comment, &status);
74        fits_read_key(fptrOld, TLONG, "NAXIS2", &dud, comment, &status);
75        fits_update_key(fptrNew, TLONG, "NAXIS2",
76                        &(this->axisDim[1]), comment, &status);
77        fits_read_key(fptrOld, TLONG, "NAXIS3", &dud, comment, &status);
78        fits_update_key(fptrNew, TLONG, "NAXIS3",
79                        &(this->axisDim[2]), comment, &status);
80      }
81
82      writeSmoothHeaderInfo(fptrNew, this->par);
83
84      if(this->par.getFlagBlankPix())
85        fits_write_pixnull(fptrNew, TFLOAT, fpixel, this->numPixels,
86                           this->recon, &blankval, &status);
87      else fits_write_pix(fptrNew, TFLOAT, fpixel, this->numPixels,
88                          this->recon, &status);
89
90      status = 0;
91      fits_close_file(fptrNew, &status);
92      if (status) fits_report_error(stderr, status);
93    }
94  }
95
96}
97
98
99void Cube::saveReconstructedCube()
100{
101  /**
102   *  A function to save the reconstructed and/or residual arrays.
103   *   A number of header keywords are written as well, indicating the
104   *    nature of the reconstruction that has been done.
105   *   The file is always written -- if the filename (as calculated
106   *    based on the recon parameters) exists, then it is overwritten.
107   */
108 
109  int newbitpix = FLOAT_IMG;
110
111  float *resid = new float[this->numPixels];
112  for(int i=0;i<this->numPixels;i++)
113    resid[i] = this->array[i] - this->recon[i];
114  float blankval = this->par.getBlankPixVal();
115
116  long *fpixel = new long[this->numDim];
117  for(int i=0;i<this->numDim;i++) fpixel[i]=1;
118  int status = 0;  /* MUST initialize status */
119  fitsfile *fptrOld, *fptrNew;         
120  fits_open_file(&fptrOld,this->par.getImageFile().c_str(),READONLY,&status);
121  if (status) fits_report_error(stderr, status);
122 
123  if(this->par.getFlagOutputRecon()){
124    std::string fileout = "!" + this->par.outputReconFile();
125    // the ! is there so that it writes over an existing file.
126
127    status = 0;
128    fits_create_file(&fptrNew,fileout.c_str(),&status);
129    if (status)
130      fits_report_error(stderr, status);
131    else
132      {
133        status = 0;
134        fits_movabs_hdu(fptrOld, 1, NULL, &status);
135        if (status) fits_report_error(stderr, status);
136        status = 0;
137        fits_copy_header(fptrOld, fptrNew, &status);
138        if (status) fits_report_error(stderr, status);
139        char *comment = new char[80];
140        long dud;
141        status = 0;
142        fits_update_key(fptrNew, TINT, "BITPIX", &newbitpix,
143                        "number of bits per data pixel", &status);
144        if (status) fits_report_error(stderr, status);
145        status = 0;
146        float bscale=1., bzero=0.;
147        fits_update_key(fptrNew, TFLOAT, "BSCALE", &bscale,
148                        "PHYSICAL = PIXEL*BSCALE + BZERO", &status);
149        fits_update_key(fptrNew, TFLOAT, "BZERO", &bzero, "", &status);
150        fits_set_bscale(fptrNew, 1., 0., &status);
151        if (status) fits_report_error(stderr, status);
152        // Need to correct the dimensions, if we have subsectioned the image
153        if(this->par.getFlagSubsection()){
154          fits_read_key(fptrOld, TLONG, "NAXIS1", &dud, comment, &status);
155          fits_update_key(fptrNew, TLONG, "NAXIS1",
156                          &(this->axisDim[0]), comment, &status);
157          fits_read_key(fptrOld, TLONG, "NAXIS2", &dud, comment, &status);
158          fits_update_key(fptrNew, TLONG, "NAXIS2",
159                          &(this->axisDim[1]), comment, &status);
160          fits_read_key(fptrOld, TLONG, "NAXIS3", &dud, comment, &status);
161          fits_update_key(fptrNew, TLONG, "NAXIS3",
162                          &(this->axisDim[2]), comment, &status);
163        }
164
165        writeReconHeaderInfo(fptrNew, this->par, "recon");
166
167        if(this->par.getFlagBlankPix())
168          fits_write_pixnull(fptrNew, TFLOAT, fpixel, this->numPixels,
169                             this->recon, &blankval, &status);
170        else  fits_write_pix(fptrNew, TFLOAT, fpixel, this->numPixels,
171                             this->recon, &status);
172
173        status = 0;
174        fits_close_file(fptrNew, &status);
175        if (status) fits_report_error(stderr, status);
176      }
177  }
178
179
180  if(this->par.getFlagOutputResid()){
181    std::string fileout = "!" + this->par.outputResidFile();
182    // the ! is there so that it writes over an existing file.
183    status = 0;
184    fits_create_file(&fptrNew,fileout.c_str(),&status);
185    if (status)
186      fits_report_error(stderr, status);
187    else
188      {
189        status = 0;
190        fits_movabs_hdu(fptrOld, 1, NULL, &status);
191        if (status) fits_report_error(stderr, status);
192        status = 0;
193        fits_copy_header(fptrOld, fptrNew, &status);
194        if (status) fits_report_error(stderr, status);
195
196        status = 0;
197        fits_update_key(fptrNew, TINT, "BITPIX", &newbitpix,
198                        "number of bits per data pixel", &status);
199        if (status) fits_report_error(stderr, status);
200        status = 0;
201        float bscale=1., bzero=0.;
202        fits_update_key(fptrNew, TFLOAT, "BSCALE", &bscale,
203                        "PHYSICAL = PIXEL*BSCALE + BZERO", &status);
204        fits_update_key(fptrNew, TFLOAT, "BZERO", &bzero, "", &status);
205        fits_set_bscale(fptrNew, 1., 0., &status);
206        if (status) fits_report_error(stderr, status);
207
208        // Need to correct the dimensions, if we have subsectioned the image...
209        char *comment = new char[80];
210        long dud;
211        if(this->pars().getFlagSubsection()){
212          fits_read_key(fptrOld, TLONG, "NAXIS1", &dud, comment, &status);
213          fits_update_key(fptrNew, TLONG, "NAXIS1",
214                          &(this->axisDim[0]), comment, &status);
215          fits_read_key(fptrOld, TLONG, "NAXIS2", &dud, comment, &status);
216          fits_update_key(fptrNew, TLONG, "NAXIS2",
217                          &(this->axisDim[1]), comment, &status);
218          fits_read_key(fptrOld, TLONG, "NAXIS3", &dud, comment, &status);
219          fits_update_key(fptrNew, TLONG, "NAXIS3",
220                          &(this->axisDim[2]), comment, &status);
221        }
222
223        writeReconHeaderInfo(fptrNew, this->par, "resid");
224
225        if(this->par.getFlagBlankPix())
226          fits_write_pixnull(fptrNew, TFLOAT, fpixel, this->numPixels,
227                             resid, &blankval, &status);
228        else  fits_write_pix(fptrNew, TFLOAT, fpixel, this->numPixels,
229                             resid, &status);
230
231        fits_close_file(fptrNew, &status);
232      }
233  }
234
235  delete [] resid;
236  delete [] fpixel;
237
238}
239
240
241void writeReconHeaderInfo(fitsfile *fptr, Param &par, std::string nature)
242{
243  /**
244   *   A simple function that writes all the necessary keywords and comments
245   *    to the FITS header pointed to by fptr.
246   *   The keyword names and comments are taken from duchamp.hh
247   *   The parameter "nature" indicates what type of file is being written:
248   *    should be either "recon" or "resid".
249   */
250
251
252  int status = 0;
253  char *comment, *keyword;
254  std::string explanation = "",ReconResid="";
255
256  fits_write_history(fptr, (char *)header_reconHistory1.c_str(), &status);
257                                   
258  fits_write_history(fptr, (char *)header_reconHistory2.c_str(), &status);
259
260  fits_write_history(fptr, (char *)header_reconHistory_input.c_str(), &status);
261
262  fits_write_history(fptr, (char *)par.getImageFile().c_str(), &status);
263
264  if(par.getFlagSubsection()){
265    fits_write_comment(fptr,(char *)header_reconSubsection_comment.c_str(),
266                       &status);
267    fits_write_key(fptr, TSTRING, (char *)keyword_subsection.c_str(),
268                   (char *)par.getSubsection().c_str(),
269                   (char *)comment_subsection.c_str(), &status);
270  }
271   
272  fits_write_comment(fptr, (char *)header_atrous_comment.c_str(), &status);
273
274  float valf = par.getAtrousCut();
275  fits_write_key(fptr, TFLOAT, (char *)keyword_snrRecon.c_str(), &valf,
276                 (char *)comment_snrRecon.c_str(), &status);
277
278  int vali = par.getReconDim();
279  fits_write_key(fptr, TINT, (char *)keyword_reconDim.c_str(), &vali,
280                 (char *)comment_reconDim.c_str(), &status);
281
282  vali = par.getMinScale();
283  fits_write_key(fptr, TINT, (char *)keyword_scaleMin.c_str(), &vali,
284                 (char *)comment_scaleMin.c_str(), &status);
285
286  vali = par.getFilterCode();
287  fits_write_key(fptr, TINT, (char *)keyword_filterCode.c_str(), &vali,
288                 (char *)comment_filterCode.c_str(), &status);
289
290  if(nature == "recon"){
291    explanation = "Duchamp: This is the RECONSTRUCTED cube";
292    ReconResid = "RECON";
293  }
294  else if(nature == "resid"){
295    explanation = "Duchamp: This is the RESIDUAL cube";
296    ReconResid = "RESID";
297  }
298  else duchampWarning("write_header_info","explanation not present!\n");
299  fits_write_comment(fptr, (char *)explanation.c_str(), &status);
300  fits_write_key(fptr, TSTRING, (char *)keyword_ReconResid.c_str(),
301                 (char *)ReconResid.c_str(),
302                 (char *)comment_ReconResid.c_str(), &status);
303
304}
305
306void writeSmoothHeaderInfo(fitsfile *fptr, Param &par)
307{
308  /**
309   *   A simple function that writes all the necessary keywords and comments
310   *    to the FITS header pointed to by fptr.
311   *   The keyword names and comments are taken from duchamp.hh
312   */
313
314
315  int status = 0;
316  char *comment, *keyword;
317
318  fits_write_history(fptr, (char *)header_smoothHistory.c_str(), &status);
319  status = 0;
320  fits_write_history(fptr, (char *)header_smoothHistory_input.c_str(),&status);
321  status = 0;
322  fits_write_history(fptr, (char *)par.getImageFile().c_str(), &status);
323
324  if(par.getFlagSubsection()){
325    status = 0;
326    fits_write_comment(fptr,(char *)header_smoothSubsection_comment.c_str(),
327                       &status);
328    status = 0;
329    fits_write_key(fptr, TSTRING, (char *)keyword_subsection.c_str(),
330                   (char *)par.getSubsection().c_str(),
331                   (char *)comment_subsection.c_str(), &status);
332  }
333   
334  int val = par.getHanningWidth();
335  fits_write_key(fptr, TINT, (char *)keyword_hanningwidth.c_str(), &val,
336                 (char *)comment_hanningwidth.c_str(), &status);
337
338}
Note: See TracBrowser for help on using the repository browser.