source: trunk/src/FitsIO/WriteArray.cc @ 1135

Last change on this file since 1135 was 1135, checked in by MatthewWhiting, 12 years ago

Fixing ticket #177 - making sure the header is only written once, and that the 2D image doesn't have the spectral axis written. Also fixing the pixel units for the moment-0 map.

File size: 4.9 KB
Line 
1#include <duchamp/FitsIO/WriteArray.hh>
2#include <duchamp/duchamp.hh>
3#include <duchamp/Cubes/cubes.hh>
4#include <fitsio.h>
5#include <string.h>
6#include <wcslib/wcsunits.h>
7
8namespace duchamp {
9
10  WriteArray::WriteArray():
11    itsCube(0),itsFilename(""),itsBitpix(-32),itsFlag2D(false),itsFptr(0)
12  {
13  }
14
15  WriteArray::WriteArray(Cube *cube):
16    itsCube(cube),itsFilename(""),itsBitpix(-32),itsFlag2D(false),itsFptr(0)
17  {
18  }
19
20  WriteArray::WriteArray(Cube *cube, int bitpix):
21    itsCube(cube),itsFilename(""),itsBitpix(bitpix),itsFlag2D(false),itsFptr(0)
22  {
23  }
24
25  WriteArray::WriteArray(const WriteArray &other)
26  {
27    this->operator=(other);
28  }
29
30  WriteArray& WriteArray::operator= (const WriteArray& other)
31  {
32    if(this==&other) return *this;
33    this->itsCube = other.itsCube;
34    this->itsBitpix = other.itsBitpix;
35    this->itsFilename = other.itsFilename;
36    this->itsFptr = other.itsFptr;
37    this->itsFlag2D = other.itsFlag2D;
38    return *this;
39  }
40
41  OUTCOME WriteArray::write()
42  {
43    if(this->openFile()==FAILURE) return FAILURE;
44    if(this->writeBasicHeader()==FAILURE) return FAILURE;
45    if(this->writeHeader()==FAILURE) return FAILURE;
46    if(this->writeData()==FAILURE) return FAILURE;
47    if(this->closeFile()==FAILURE) return FAILURE;
48    return SUCCESS;
49  }
50
51  OUTCOME WriteArray::openFile()
52  {
53    OUTCOME result=SUCCESS;
54    int status=0;
55    this->itsFilename = "!"+this->itsFilename;
56    fits_create_file(&this->itsFptr,this->itsFilename.c_str(),&status);
57    if(status){
58      DUCHAMPWARN("Reading Cube", "Error creating file " << this->itsFilename);
59      fits_report_error(stderr, status);
60      result = FAILURE;
61    }
62   
63    // if(result == SUCCESS){
64    //   result = this->writeBasicHeader();
65    // }
66
67    return result;
68  }
69
70  OUTCOME WriteArray::writeBasicHeader()
71  {
72    char *header, *hptr, keyname[9];
73    int  i, nkeyrec, status = 0;
74   
75    size_t naxis=this->itsCube->getNumDim();
76    long* naxes = new long[this->itsCube->getNumDim()];
77    for(size_t i=0;i<naxis;i++) naxes[i]=this->itsCube->getDimArray()[i];
78    if(this->itsFlag2D){
79      naxes[this->itsCube->header().WCS().spec]=1;
80      naxis=2;
81    }
82    // write the required header keywords
83    fits_write_imghdr(this->itsFptr, this->itsBitpix, naxis, naxes,  &status);
84
85    // Write beam information
86    this->itsCube->header().beam().writeToFITS(this->itsFptr);
87
88    // Write bunit information
89    status = 0;
90    strcpy(keyname,"BUNIT");
91    if (fits_update_key(this->itsFptr, TSTRING, keyname, (char *)this->itsCube->header().getFluxUnits().c_str(), NULL, &status)){
92      DUCHAMPWARN("saveImage","Error writing bunit info:");
93      fits_report_error(stderr, status);
94      return FAILURE;
95    }
96
97    // convert the wcsprm struct to a set of 80-char keys
98    int oldnaxis = this->itsCube->header().WCS().naxis;
99    if(this->itsFlag2D) this->itsCube->header().WCS().naxis=2;
100    if ((status = wcshdo(WCSHDO_all, this->itsCube->header().getWCS(), &nkeyrec, &header))) {
101      DUCHAMPWARN("saveImage","Could not convert WCS information to FITS header. WCS Error Code = "<<status<<": "<<wcs_errmsg[status]);
102      return FAILURE;
103    }
104    if(this->itsFlag2D) this->itsCube->header().WCS().naxis = oldnaxis;
105
106    hptr = header;
107    strncpy(keyname,hptr,8);
108    for (i = 0; i < nkeyrec; i++, hptr += 80) {
109      status=0;
110      if(fits_update_card(this->itsFptr,keyname,hptr,&status)){
111        DUCHAMPWARN("saveImage","Error writing header card");
112        fits_report_error(stderr,status);
113        return FAILURE;
114      }
115    }
116   
117    if(this->itsBitpix>0){
118      if(this->itsCube->pars().getFlagBlankPix()){
119        strcpy(keyname,"BSCALE");
120        float bscale=this->itsCube->header().getBscaleKeyword();
121        if(fits_update_key(this->itsFptr, TFLOAT, keyname, &bscale, NULL, &status)){
122          duchampFITSerror(status,"saveImage","Error writing BSCALE header:");
123        }
124        strcpy(keyname,"BZERO");
125        float bzero=this->itsCube->header().getBzeroKeyword();
126        if(fits_update_key(this->itsFptr, TFLOAT, keyname, &bzero, NULL, &status)){
127          duchampFITSerror(status,"saveImage","Error writing BZERO header:");
128        }
129        strcpy(keyname,"BLANK");
130        int blank=this->itsCube->header().getBlankKeyword();
131        if(fits_update_key(this->itsFptr, TINT, keyname, &blank, NULL, &status)){
132          duchampFITSerror(status,"saveImage","Error writing BLANK header:");
133        }
134        if(fits_set_imgnull(this->itsFptr, blank, &status)){
135          duchampFITSerror(status, "saveImage", "Error setting null value:");
136        }
137        if(fits_set_bscale(this->itsFptr, bscale, bzero, &status)){
138          duchampFITSerror(status,"saveImage","Error setting scale:");
139        }
140      }
141    }
142
143    delete [] naxes;
144
145    return SUCCESS;
146
147  }
148
149  OUTCOME WriteArray::closeFile()
150  {
151    OUTCOME result=SUCCESS;
152    int status = 0;
153    if(this->itsFptr!=0){
154      fits_close_file(this->itsFptr, &status);
155      if (status){
156        DUCHAMPWARN("Reading Cube", "Error closing file " << this->itsFilename);
157        fits_report_error(stderr, status);
158        result=FAILURE;
159      }
160    }
161    return result;
162  }
163
164}
Note: See TracBrowser for help on using the repository browser.