source: trunk/src/Cubes/saveImage.cc @ 691

Last change on this file since 691 was 670, checked in by MatthewWhiting, 14 years ago

Substantive changes aimed at addressing ticket #72. The moment-0 map is now able to be saved to a FITS file. As far as the user is concerned, the functionality is as
for the mask cube, with equivalent parameters. The documentation has also been updated.

File size: 23.1 KB
Line 
1// -----------------------------------------------------------------------
2// saveImage.cc: Write a wavelet-reconstructed or smoothed array to a
3//               FITS file.
4// -----------------------------------------------------------------------
5// Copyright (C) 2006, Matthew Whiting, ATNF
6//
7// This program is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2 of the License, or (at your
10// option) any later version.
11//
12// Duchamp is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15// for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Duchamp; if not, write to the Free Software Foundation,
19// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20//
21// Correspondence concerning Duchamp may be directed to:
22//    Internet email: Matthew.Whiting [at] atnf.csiro.au
23//    Postal address: Dr. Matthew Whiting
24//                    Australia Telescope National Facility, CSIRO
25//                    PO Box 76
26//                    Epping NSW 1710
27//                    AUSTRALIA
28// -----------------------------------------------------------------------
29#include <iostream>
30#include <sstream>
31#include <string>
32#include <string.h>
33#include <wcslib/wcs.h>
34#include <wcslib/wcshdr.h>
35#define WCSLIB_GETWCSTAB
36// define this so that we don't try and redefine wtbarr
37// (this is a problem when using cfitsio v.3 and g++ v.4)
38
39#include <fitsio.h>
40#include <duchamp/duchamp.hh>
41#include <duchamp/Cubes/cubes.hh>
42#include <duchamp/PixelMap/Voxel.hh>
43#include <duchamp/PixelMap/Object3D.hh>
44
45namespace duchamp
46{
47
48  /// @brief Write FITS headers in correct format for reconstructed array output
49  void writeReconHeaderInfo(fitsfile *fptr, Param &par, std::string nature);
50
51  /// @brief Write FITS headers in correct format for smoothed array output
52  void writeSmoothHeaderInfo(fitsfile *fptr, Param &par);
53
54  /// @brief Write FITS headers in correct format for mask array output
55  void writeMaskHeaderInfo(fitsfile *fptr, Param &par);
56
57  /// @brief Write FITS headers in correct format for moment-0 array output
58  void writeMomentMapHeaderInfo(fitsfile *fptr, Param &par);
59
60  //---------------------------------------------------------------------------
61
62  char *numerateKeyword(std::string key, int num)
63  {
64    /// @details A utility function to combine a keyword and a
65    /// value, to produce a relevant FITS keyword for a given
66    /// axis. For example numerateKeyword(CRPIX,1) returns CRPIX1.
67    std::stringstream ss;
68    ss << key << num;
69    return (char *)ss.str().c_str();
70  }
71
72  void Cube::saveMomentMapImage()
73  {
74    /// @details
75    ///  A function to save the moment-0 map to a FITS file.
76   
77    int newbitpix = FLOAT_IMG;
78    char *comment = new char[FLEN_COMMENT];
79    strcpy(comment,"");
80    long *fpixel = new long[2];
81    for(int i=0;i<2;i++) fpixel[i]=1;
82    int status = 0;  /* MUST initialize status */
83    fitsfile *fptr;         
84
85    std::string fileout = "!" + this->par.outputMomentMapFile();
86    // the ! is there so that it writes over an existing file.
87    char *keyword = new char[FLEN_KEYWORD];
88
89    status = 0;
90    fits_create_file(&fptr,fileout.c_str(),&status);
91    if (status){
92      duchampError("saveMomentMapImage","Error creating file:");
93      fits_report_error(stderr, status);
94    }
95    else {
96      status = 0;
97      long *dim = new long[2];
98      for (uint i = 0; i < 2; i++) dim[i] = this->axisDim[i];
99      if (fits_create_img(fptr, newbitpix, 2, dim, &status)) {
100        duchampError("saveMomentMapImage","Error creating image:");
101        fits_report_error(stderr, status);
102      }
103
104      if(!this->par.getFlagUsingBeam()){   // if the cube has beam info, copy it
105        float bmaj=this->head.getBmajKeyword(), bmin=this->head.getBminKeyword(), bpa=this->head.getBpaKeyword();
106        status = 0;
107        strcpy(keyword,"BMAJ");
108        if (fits_update_key(fptr, TFLOAT, keyword, &bmaj, NULL, &status)){
109          duchampError("saveMomentMapImage","Error saving beam info:");
110          fits_report_error(stderr, status);
111        }
112        status = 0;
113        strcpy(keyword,"BMIN");
114        if (fits_update_key(fptr, TFLOAT, keyword, &bmin, NULL, &status)){
115          duchampError("saveMomentMapImage","Error saving beam info:");
116          fits_report_error(stderr, status);
117        }
118        status = 0;
119        strcpy(keyword,"BPA");
120        if (fits_update_key(fptr, TFLOAT, keyword, &bpa, NULL, &status)){
121          duchampError("saveMomentMapImage","Error saving beam info:");
122          fits_report_error(stderr, status);
123        }
124      }                 
125      status = 0;
126      strcpy(keyword,"EQUINOX");
127      if (fits_update_key(fptr, TFLOAT, keyword, &this->head.WCS().equinox, NULL, &status)){
128        duchampError("saveMomentMapImage","Error saving equinox:");
129        fits_report_error(stderr, status);
130      }
131      status = 0;
132      char unit[this->head.getIntFluxUnits().size()+1];
133      strcpy(unit, this->head.getIntFluxUnits().c_str());
134      strcpy(keyword,"BUNIT");
135      if (fits_update_key(fptr, TSTRING, keyword, unit,  NULL, &status)){
136        duchampError("saveMomentMapImage","Error saving BUNIT:");
137        fits_report_error(stderr, status);
138      }
139      float val;
140      int axisNumbers[2];
141      axisNumbers[0] = this->head.WCS().lng;
142      axisNumbers[1] = this->head.WCS().lat;
143      for (uint d = 0; d < 2; d++) {
144        int i = axisNumbers[d];
145        status = 0;
146        if (fits_update_key(fptr, TSTRING, numerateKeyword("CTYPE", d + 1), this->head.WCS().ctype[i],  NULL, &status)){
147          duchampError("saveMomentMapImage","Error saving CTYPE:");
148          fits_report_error(stderr, status);
149        }
150        status = 0;
151        if (fits_update_key(fptr, TSTRING, numerateKeyword("CUNIT", d + 1), this->head.WCS().cunit[i],  NULL, &status)){
152          duchampError("saveMomentMapImage","Error saving CUNIT:");
153          fits_report_error(stderr, status);
154        }
155        status = 0;
156        val = this->head.WCS().crval[i];
157        if (fits_update_key(fptr, TFLOAT, numerateKeyword("CRVAL", d + 1), &val, NULL, &status)){
158          duchampError("saveMomentMapImage","Error saving CRVAL:");
159          fits_report_error(stderr, status);
160        }
161        val = this->head.WCS().cdelt[i];
162        status = 0;
163        if (fits_update_key(fptr, TFLOAT, numerateKeyword("CDELT", d + 1), &val, NULL, &status)){
164          duchampError("saveMomentMapImage","Error saving CDELT:");
165          fits_report_error(stderr, status);
166        }
167        val = this->head.WCS().crpix[i];
168        status = 0;
169        if (fits_update_key(fptr, TFLOAT, numerateKeyword("CRPIX", d + 1), &val, NULL, &status)){
170          duchampError("saveMomentMapImage","Error saving CRPIX:");
171          fits_report_error(stderr, status);
172        }
173        val = this->head.WCS().crota[i];
174        status = 0;
175        if (fits_update_key(fptr, TFLOAT, numerateKeyword("CROTA", d + 1), &val, NULL, &status)){
176          duchampError("saveMomentMapImage","Error saving CROTA:");
177          fits_report_error(stderr, status);
178        }
179      }
180
181      delete [] comment;
182      delete [] keyword;
183
184      writeMomentMapHeaderInfo(fptr, this->par);
185       
186      long size = this->axisDim[0] * this->axisDim[1];
187      float *momentMap = new float[size];
188      std::vector<bool> detectionMap;
189      this->getMomentMap(momentMap,detectionMap);
190      status=0;
191      if(fits_write_pix(fptr, TFLOAT, fpixel, size, momentMap, &status)){
192        duchampError("saveMomentMapImage","Error writing data");
193        fits_report_error(stderr,status);
194      }
195      status = 0;
196      if(fits_close_file(fptr, &status)){
197        duchampError("saveMomentMapImage","Error closing file");
198        fits_report_error(stderr, status);
199      }
200
201      delete [] momentMap;
202
203    }
204
205    delete [] fpixel;
206
207
208  }
209
210  void Cube::saveMaskCube()
211  {
212    /// @details
213    ///  A function to save a mask to a FITS file, indicating where the
214    ///  detections where made. The value of the detected pixels is
215    ///  determined by the flagMaskWithObjectNum parameter: if true,
216    ///  the value of the pixels is given by the corresponding object
217    ///  ID number; if false, they take the value 1 for all
218    ///  objects. Pixels not in a detected object have the value 0.
219
220    int newbitpix = SHORT_IMG;
221    char *comment = new char[FLEN_COMMENT];
222    strcpy(comment,"");
223    long *fpixel = new long[this->header().WCS().naxis];
224    for(int i=0;i<this->header().WCS().naxis;i++) fpixel[i]=1;
225    int status = 0;  /* MUST initialize status */
226    fitsfile *fptrOld, *fptrNew;         
227    fits_open_file(&fptrOld,this->par.getImageFile().c_str(),READONLY,&status);
228    if (status){
229      duchampError("saveMask","Fits Error 1:");
230      fits_report_error(stderr, status);
231    }
232
233    std::string fileout = "!" + this->par.outputMaskFile();
234    // the ! is there so that it writes over an existing file.
235
236    status = 0;
237    fits_create_file(&fptrNew,fileout.c_str(),&status);
238    if (status){
239      duchampError("saveMask","Fits Error 2:");
240      fits_report_error(stderr, status);
241    }
242    else {
243      status = 0;
244      fits_movabs_hdu(fptrOld, 1, NULL, &status);
245      if (status){
246        duchampError("saveMask","Fits Error 3:");
247        fits_report_error(stderr, status);
248      }
249      status = 0;
250      fits_copy_header(fptrOld, fptrNew, &status);
251      if (status){
252        duchampError("saveMask","Fits Error 4:");
253        fits_report_error(stderr, status);
254      }
255      status = 0;
256      char *keyword = new char[FLEN_KEYWORD];
257      strcpy(keyword,"BITPIX");
258      strcpy(comment,"number of bits per data pixel");
259      fits_update_key(fptrNew, TINT, keyword, &newbitpix, comment, &status);
260      if (status){
261        duchampError("saveMask","Fits Error 5:");
262        fits_report_error(stderr, status);
263      }
264      float bscale=1., bzero=0.;
265      strcpy(comment,"");
266      strcpy(keyword,"BSCALE");
267      fits_update_key(fptrNew, TFLOAT, keyword, &bscale, comment, &status);
268      if (status){
269        duchampError("saveMask","Fits Error 6:");
270        fits_report_error(stderr, status);
271      }
272      strcpy(keyword,"BZERO");
273      fits_update_key(fptrNew, TFLOAT, keyword, &bzero, comment, &status);
274      if (status){
275        duchampError("saveMask","Fits Error 7:");
276        fits_report_error(stderr, status);
277      }
278      fits_set_bscale(fptrNew, 1, 0, &status);
279      if (status){
280        duchampError("saveMask","Fits Error 8:");
281        fits_report_error(stderr, status);
282      }
283      std::string newunits;
284      if(this->par.getFlagMaskWithObjectNum())
285        newunits = "Object ID";
286      else
287        newunits = "Detection flag";
288      strcpy(keyword,"BUNIT");
289      fits_update_key(fptrNew, TSTRING, keyword, (char *)newunits.c_str(), comment, &status);
290      if (status){
291        duchampError("saveMask","Fits Error 9:");
292        fits_report_error(stderr, status);
293      }
294      long dud;
295      // Need to correct the dimensions, if we have subsectioned the image
296      if(this->par.getFlagSubsection()){
297        std::stringstream naxis;
298        fits_read_key(fptrOld, TLONG, (char *)naxis.str().c_str(), &dud, comment, &status);
299        fits_update_key(fptrNew, TLONG, (char *)naxis.str().c_str(),
300                        &(this->axisDim[0]), comment, &status);
301        naxis.str("");
302        naxis << "NAXIS" << this->head.WCS().lat;
303        fits_read_key(fptrOld, TLONG, (char *)naxis.str().c_str(), &dud, comment, &status);
304        fits_update_key(fptrNew, TLONG, (char *)naxis.str().c_str(),
305                        &(this->axisDim[1]), comment, &status);
306        naxis.str("");
307        naxis << "NAXIS" << this->head.WCS().spec;
308        fits_read_key(fptrOld, TLONG, (char *)naxis.str().c_str(), &dud, comment, &status);
309        fits_update_key(fptrNew, TLONG, (char *)naxis.str().c_str(),
310                        &(this->axisDim[2]), comment, &status);
311      }
312
313      delete [] comment;
314      delete [] keyword;
315
316      writeMaskHeaderInfo(fptrNew, this->par);
317       
318      short *mask = new short[this->numPixels];
319      for(int i=0;i<this->numPixels;i++) mask[i]=0;
320      std::vector<Detection>::iterator obj;
321      for(obj=this->objectList->begin();obj<this->objectList->end();obj++){
322        std::vector<PixelInfo::Voxel> voxlist = obj->getPixelSet();
323        std::vector<PixelInfo::Voxel>::iterator vox;
324        for(vox=voxlist.begin();vox<voxlist.end();vox++){
325          int pixelpos = vox->getX() + this->axisDim[0]*vox->getY() +
326            this->axisDim[0]*this->axisDim[1]*vox->getZ();
327          if(this->par.getFlagMaskWithObjectNum()) mask[pixelpos] = obj->getID();
328          else mask[pixelpos] = 1;
329        }
330      }
331      status=0;
332      fits_write_pix(fptrNew, TSHORT, fpixel, this->numPixels, mask, &status);
333      if(status){
334        duchampError("saveMask","Fits Error 10:");
335        fits_report_error(stderr,status);
336      }
337      status = 0;
338      fits_close_file(fptrNew, &status);
339      if (status){
340        duchampError("saveMask","Fits Error 11:");
341        fits_report_error(stderr, status);
342      }
343
344      delete [] mask;
345
346    }
347
348    delete [] fpixel;
349
350  }
351 
352  //---------------------------------------------------------------------------
353
354  void Cube::saveSmoothedCube()
355  {
356    /// @brief
357    ///   A function to save the smoothed arrays to a FITS file.
358    ///   Additional header keywords are written as well, indicating the
359    ///   width of the Hanning filter or the dimensions of the Gaussian
360    ///   kernel.
361    ///   The file is always written -- if the filename (as calculated
362    ///    based on the parameters) exists, then it is overwritten.
363 
364    float blankval = this->par.getBlankPixVal();
365
366    int status = 0;  /* MUST initialize status */
367    fitsfile *fptrOld, *fptrNew;         
368    fits_open_file(&fptrOld,this->par.getFullImageFile().c_str(),READONLY,&status);
369    if (status) fits_report_error(stderr, status);
370 
371    if(this->par.getFlagOutputSmooth()){
372      std::string fileout = "!" + this->par.outputSmoothFile();
373      // the ! is there so that it writes over an existing file.
374
375      status = 0;
376      fits_create_file(&fptrNew,fileout.c_str(),&status);
377      if (status)
378        fits_report_error(stderr, status);
379      else {
380        status = 0;
381        fits_movabs_hdu(fptrOld, 1, NULL, &status);
382        if (status) fits_report_error(stderr, status);
383        status = 0;
384        fits_copy_header(fptrOld, fptrNew, &status);
385        if (status) fits_report_error(stderr, status);
386
387        writeSmoothHeaderInfo(fptrNew, this->par);
388
389        if(this->par.getFlagBlankPix())
390          fits_write_imgnull(fptrNew, TFLOAT, 1, this->numPixels, this->recon, &blankval, &status);
391        else
392          fits_write_img(fptrNew, TFLOAT, 1, this->numPixels, this->recon, &status);
393
394        status = 0;
395        fits_close_file(fptrNew, &status);
396        if (status) fits_report_error(stderr, status);
397
398      }
399    }
400
401  }
402
403  //---------------------------------------------------------------------------
404
405  void Cube::saveReconstructedCube()
406  {
407    /// @details
408    ///  A function to save the reconstructed and/or residual arrays.
409    ///   A number of header keywords are written as well, indicating the
410    ///    nature of the reconstruction that has been done.
411    ///   The file is always written -- if the filename (as calculated
412    ///    based on the recon parameters) exists, then it is overwritten.
413 
414    float blankval = this->par.getBlankPixVal();
415
416    int status = 0;  /* MUST initialize status */
417    fitsfile *fptrOld, *fptrNew;         
418    fits_open_file(&fptrOld,this->par.getFullImageFile().c_str(),READONLY,&status);
419    if (status) fits_report_error(stderr, status);
420 
421    if(this->par.getFlagOutputRecon()){
422      std::string fileout = "!" + this->par.outputReconFile();
423      // the ! is there so that it writes over an existing file.
424
425      status = 0;
426      fits_create_file(&fptrNew,fileout.c_str(),&status);
427      if (status)
428        fits_report_error(stderr, status);
429      else
430        {
431          status = 0;
432          fits_movabs_hdu(fptrOld, 1, NULL, &status);
433          if (status) fits_report_error(stderr, status);
434          status = 0;
435          fits_copy_header(fptrOld, fptrNew, &status);
436          if (status) fits_report_error(stderr, status);
437
438          writeReconHeaderInfo(fptrNew, this->par, "recon");
439
440          if(this->par.getFlagBlankPix())
441            fits_write_imgnull(fptrNew, TFLOAT, 1, this->numPixels, this->recon, &blankval, &status);
442          else 
443            fits_write_img(fptrNew, TFLOAT, 1, this->numPixels, this->recon, &status);
444
445          status = 0;
446          fits_close_file(fptrNew, &status);
447          if (status) fits_report_error(stderr, status);
448        }
449    }
450
451
452    if(this->par.getFlagOutputResid()){
453      float *resid = new float[this->numPixels];
454      for(int i=0;i<this->numPixels;i++)
455        resid[i] = this->array[i] - this->recon[i];
456
457      std::string fileout = "!" + this->par.outputResidFile();
458      // the ! is there so that it writes over an existing file.
459      status = 0;
460      fits_create_file(&fptrNew,fileout.c_str(),&status);
461      if (status)
462        fits_report_error(stderr, status);
463      else
464        {
465          status = 0;
466          fits_movabs_hdu(fptrOld, 1, NULL, &status);
467          if (status) fits_report_error(stderr, status);
468          status = 0;
469          fits_copy_header(fptrOld, fptrNew, &status);
470          if (status) fits_report_error(stderr, status);
471
472          writeReconHeaderInfo(fptrNew, this->par, "resid");
473
474          if(this->par.getFlagBlankPix())
475            fits_write_imgnull(fptrNew, TFLOAT, 1, this->numPixels, resid, &blankval, &status);
476          else 
477            fits_write_img(fptrNew, TFLOAT, 1, this->numPixels, resid, &status);
478
479          fits_close_file(fptrNew, &status);
480        }
481      delete [] resid;
482    }
483
484
485  }
486
487  //---------------------------------------------------------------------------
488
489  void writeReconHeaderInfo(fitsfile *fptr, Param &par, std::string nature)
490  {
491    /// @details
492    ///   A simple function that writes all the necessary keywords and comments
493    ///    to the FITS header pointed to by fptr.
494    ///   The keyword names and comments are taken from duchamp.hh
495    ///   The parameter "nature" indicates what type of file is being written:
496    ///    should be either "recon" or "resid".
497
498    int status = 0;
499    std::string explanation = "",ReconResid="";
500
501    fits_write_history(fptr, (char *)header_reconHistory1.c_str(), &status);
502                                   
503    fits_write_history(fptr, (char *)header_reconHistory2.c_str(), &status);
504
505    fits_write_history(fptr, (char *)header_reconHistory_input.c_str(), &status);
506
507    fits_write_history(fptr, (char *)par.getImageFile().c_str(), &status);
508
509    if(par.getFlagSubsection()){
510      fits_write_comment(fptr,(char *)header_reconSubsection_comment.c_str(),
511                         &status);
512      fits_write_key(fptr, TSTRING, (char *)keyword_subsection.c_str(),
513                     (char *)par.getSubsection().c_str(),
514                     (char *)comment_subsection.c_str(), &status);
515    }
516   
517    fits_write_comment(fptr, (char *)header_atrous_comment.c_str(), &status);
518
519    float valf = par.getAtrousCut();
520    fits_write_key(fptr, TFLOAT, (char *)keyword_snrRecon.c_str(), &valf,
521                   (char *)comment_snrRecon.c_str(), &status);
522
523    int vali = par.getReconDim();
524    fits_write_key(fptr, TINT, (char *)keyword_reconDim.c_str(), &vali,
525                   (char *)comment_reconDim.c_str(), &status);
526
527    vali = par.getMinScale();
528    fits_write_key(fptr, TINT, (char *)keyword_scaleMin.c_str(), &vali,
529                   (char *)comment_scaleMin.c_str(), &status);
530
531    vali = par.getFilterCode();
532    fits_write_key(fptr, TINT, (char *)keyword_filterCode.c_str(), &vali,
533                   (char *)comment_filterCode.c_str(), &status);
534
535    if(nature == "recon"){
536      explanation = "Duchamp: This is the RECONSTRUCTED cube";
537      ReconResid = "RECON";
538    }
539    else if(nature == "resid"){
540      explanation = "Duchamp: This is the RESIDUAL cube";
541      ReconResid = "RESID";
542    }
543    else duchampWarning("write_header_info","explanation not present!\n");
544    fits_write_comment(fptr, (char *)explanation.c_str(), &status);
545    fits_write_key(fptr, TSTRING, (char *)keyword_ReconResid.c_str(),
546                   (char *)ReconResid.c_str(),
547                   (char *)comment_ReconResid.c_str(), &status);
548
549  }
550
551  //---------------------------------------------------------------------------
552
553  void writeSmoothHeaderInfo(fitsfile *fptr, Param &par)
554  {
555    /// @details
556    ///   A simple function that writes all the necessary keywords and comments
557    ///    to the FITS header pointed to by fptr.
558    ///   The keyword names and comments are taken from duchamp.hh
559
560    int status = 0;
561
562    fits_write_history(fptr, (char *)header_smoothHistory.c_str(), &status);
563    status = 0;
564    fits_write_history(fptr, (char *)header_smoothHistory_input.c_str(),&status);
565    status = 0;
566    fits_write_history(fptr, (char *)par.getImageFile().c_str(), &status);
567
568    if(par.getFlagSubsection()){
569      status = 0;
570      fits_write_comment(fptr,(char *)header_smoothSubsection_comment.c_str(),
571                         &status);
572      status = 0;
573      fits_write_key(fptr, TSTRING, (char *)keyword_subsection.c_str(),
574                     (char *)par.getSubsection().c_str(),
575                     (char *)comment_subsection.c_str(), &status);
576    }
577   
578    if(par.getSmoothType()=="spatial"){
579      // if kernMin is negative (not defined), make it equal to kernMaj
580      if(par.getKernMin() < 0) par.setKernMin(par.getKernMaj());
581
582      fits_write_key(fptr, TSTRING, (char *)keyword_smoothtype.c_str(),
583                     (char *)header_smoothSpatial.c_str(),
584                     (char *)comment_smoothtype.c_str(), &status);
585      float valf = par.getKernMaj();
586      fits_write_key(fptr, TFLOAT, (char *)keyword_kernmaj.c_str(), &valf,
587                     (char *)comment_kernmaj.c_str(), &status);
588      valf = par.getKernMin();
589      fits_write_key(fptr, TFLOAT, (char *)keyword_kernmin.c_str(), &valf,
590                     (char *)comment_kernmin.c_str(), &status);
591      valf = par.getKernPA();
592      fits_write_key(fptr, TFLOAT, (char *)keyword_kernpa.c_str(), &valf,
593                     (char *)comment_kernpa.c_str(), &status);
594    }
595    else if(par.getSmoothType()=="spectral"){
596      fits_write_key(fptr, TSTRING, (char *)keyword_smoothtype.c_str(),
597                     (char *)header_smoothSpectral.c_str(),
598                     (char *)comment_smoothtype.c_str(), &status);
599      int vali = par.getHanningWidth();
600      fits_write_key(fptr, TINT, (char *)keyword_hanningwidth.c_str(), &vali,
601                     (char *)comment_hanningwidth.c_str(), &status);
602    }
603  }
604
605  //---------------------------------------------------------------------------
606
607  void writeMaskHeaderInfo(fitsfile *fptr, Param &par)
608  {
609    /// @details
610    ///   A simple function that writes all the necessary keywords and comments
611    ///    to the FITS header pointed to by fptr.
612    ///   The keyword names and comments are taken from duchamp.hh
613
614    int status = 0;
615
616    fits_write_history(fptr, (char *)header_maskHistory.c_str(), &status);
617    status = 0;
618    fits_write_history(fptr, (char *)header_maskHistory_input.c_str(),&status);
619    status = 0;
620    fits_write_history(fptr, (char *)par.getImageFile().c_str(), &status);
621
622    if(par.getFlagSubsection()){
623      status = 0;
624      fits_write_comment(fptr,(char *)header_maskSubsection_comment.c_str(),
625                         &status);
626      status = 0;
627      fits_write_key(fptr, TSTRING, (char *)keyword_subsection.c_str(),
628                     (char *)par.getSubsection().c_str(),
629                     (char *)comment_subsection.c_str(), &status);
630    }
631  }
632
633  //---------------------------------------------------------------------------
634
635  void writeMomentMapHeaderInfo(fitsfile *fptr, Param &par)
636  {
637    /// @details
638    ///   A simple function that writes all the necessary keywords and comments
639    ///    to the FITS header pointed to by fptr.
640    ///   The keyword names and comments are taken from duchamp.hh
641
642    int status = 0;
643
644    fits_write_history(fptr, (char *)header_moment0History.c_str(), &status);
645    status = 0;
646    fits_write_history(fptr, (char *)header_moment0History_input.c_str(),&status);
647    status = 0;
648    fits_write_history(fptr, (char *)par.getImageFile().c_str(), &status);
649
650    if(par.getFlagSubsection()){
651      status = 0;
652      fits_write_comment(fptr,(char *)header_moment0Subsection_comment.c_str(),
653                         &status);
654      status = 0;
655      fits_write_key(fptr, TSTRING, (char *)keyword_subsection.c_str(),
656                     (char *)par.getSubsection().c_str(),
657                     (char *)comment_subsection.c_str(), &status);
658    }
659  }
660
661}
Note: See TracBrowser for help on using the repository browser.