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 | |
---|
8 | namespace 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 | const 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) naxes[this->itsCube->header().WCS().spec]=1; |
---|
79 | // write the required header keywords |
---|
80 | fits_write_imghdr(this->itsFptr, this->itsBitpix, naxis, naxes, &status); |
---|
81 | |
---|
82 | // Write beam information |
---|
83 | this->itsCube->header().beam().writeToFITS(this->itsFptr); |
---|
84 | |
---|
85 | // Write bunit information |
---|
86 | status = 0; |
---|
87 | strcpy(keyname,"BUNIT"); |
---|
88 | if (fits_update_key(this->itsFptr, TSTRING, keyname, (char *)this->itsCube->header().getFluxUnits().c_str(), NULL, &status)){ |
---|
89 | DUCHAMPWARN("saveImage","Error writing bunit info:"); |
---|
90 | fits_report_error(stderr, status); |
---|
91 | return FAILURE; |
---|
92 | } |
---|
93 | |
---|
94 | // convert the wcsprm struct to a set of 80-char keys |
---|
95 | if ((status = wcshdo(WCSHDO_all, this->itsCube->header().getWCS(), &nkeyrec, &header))) { |
---|
96 | DUCHAMPWARN("saveImage","Could not convert WCS information to FITS header. WCS Error Code = "<<status<<": "<<wcs_errmsg[status]); |
---|
97 | return FAILURE; |
---|
98 | } |
---|
99 | |
---|
100 | hptr = header; |
---|
101 | strncpy(keyname,hptr,8); |
---|
102 | for (i = 0; i < nkeyrec; i++, hptr += 80) { |
---|
103 | status=0; |
---|
104 | if(fits_update_card(this->itsFptr,keyname,hptr,&status)){ |
---|
105 | DUCHAMPWARN("saveImage","Error writing header card"); |
---|
106 | fits_report_error(stderr,status); |
---|
107 | return FAILURE; |
---|
108 | } |
---|
109 | } |
---|
110 | |
---|
111 | if(this->itsBitpix>0){ |
---|
112 | if(this->itsCube->pars().getFlagBlankPix()){ |
---|
113 | strcpy(keyname,"BSCALE"); |
---|
114 | float bscale=this->itsCube->header().getBscaleKeyword(); |
---|
115 | if(fits_update_key(this->itsFptr, TFLOAT, keyname, &bscale, NULL, &status)){ |
---|
116 | duchampFITSerror(status,"saveImage","Error writing BSCALE header:"); |
---|
117 | } |
---|
118 | strcpy(keyname,"BZERO"); |
---|
119 | float bzero=this->itsCube->header().getBzeroKeyword(); |
---|
120 | if(fits_update_key(this->itsFptr, TFLOAT, keyname, &bzero, NULL, &status)){ |
---|
121 | duchampFITSerror(status,"saveImage","Error writing BZERO header:"); |
---|
122 | } |
---|
123 | strcpy(keyname,"BLANK"); |
---|
124 | int blank=this->itsCube->header().getBlankKeyword(); |
---|
125 | if(fits_update_key(this->itsFptr, TINT, keyname, &blank, NULL, &status)){ |
---|
126 | duchampFITSerror(status,"saveImage","Error writing BLANK header:"); |
---|
127 | } |
---|
128 | if(fits_set_imgnull(this->itsFptr, blank, &status)){ |
---|
129 | duchampFITSerror(status, "saveImage", "Error setting null value:"); |
---|
130 | } |
---|
131 | if(fits_set_bscale(this->itsFptr, bscale, bzero, &status)){ |
---|
132 | duchampFITSerror(status,"saveImage","Error setting scale:"); |
---|
133 | } |
---|
134 | } |
---|
135 | } |
---|
136 | |
---|
137 | delete [] naxes; |
---|
138 | |
---|
139 | return SUCCESS; |
---|
140 | |
---|
141 | } |
---|
142 | |
---|
143 | OUTCOME WriteArray::closeFile() |
---|
144 | { |
---|
145 | OUTCOME result=SUCCESS; |
---|
146 | int status = 0; |
---|
147 | if(this->itsFptr!=0){ |
---|
148 | fits_close_file(this->itsFptr, &status); |
---|
149 | if (status){ |
---|
150 | DUCHAMPWARN("Reading Cube", "Error closing file " << this->itsFilename); |
---|
151 | fits_report_error(stderr, status); |
---|
152 | result=FAILURE; |
---|
153 | } |
---|
154 | } |
---|
155 | return result; |
---|
156 | } |
---|
157 | |
---|
158 | } |
---|