-
Notifications
You must be signed in to change notification settings - Fork 1
/
ExtHDU.cxx
320 lines (261 loc) · 7.33 KB
/
ExtHDU.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
// Astrophysics Science Division,
// NASA/ Goddard Space Flight Center
// HEASARC
// http://heasarc.gsfc.nasa.gov
// e-mail: [email protected]
//
// Original author: Ben Dorman
#ifdef _MSC_VER
#include "MSconfig.h" // for truncation warning
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef SSTREAM_DEFECT
#include <strstream>
using std::ostrstream;
#else
#include <sstream>
#endif
#include <cstring>
// Column
#include "Column.h"
// FITS
#include "FITS.h"
// ExtHDU
#include "ExtHDU.h"
// FitsError
#include "FitsError.h"
// FITSUtil
#include "FITSUtil.h"
namespace CCfits {
// Class CCfits::ExtHDU::WrongExtensionType
ExtHDU::WrongExtensionType::WrongExtensionType (const String& msg, bool silent)
: FitsException("Fits Error: wrong extension type: ",silent)
{
addToMessage(msg);
std::cerr << msg << '\n';
}
// Class CCfits::ExtHDU
String ExtHDU::s_missHDU = "$HDU$";
ExtHDU::ExtHDU(const ExtHDU &right)
: HDU(right),
m_pcount(right.m_pcount),
m_gcount(right.m_gcount),
m_version(right.m_version),
m_xtension(right.m_xtension),
m_name(right.m_name)
{
}
ExtHDU::ExtHDU (FITS* p, HduType xtype, const String &hduName, int version)
: HDU(p),
m_pcount(0),
m_gcount(1),
m_version(version),
m_xtension(xtype),
m_name(hduName)
{
int number = -1;
if ( hduName.substr(0,5) == s_missHDU )
{
#ifdef SSTREAM_DEFECT
std::istrstream fakeName( hduName.substr(5).c_str() );
#else
std::istringstream fakeName(hduName.substr(5));
#endif
fakeName >> number;
}
else
{
fits_get_hdu_num(fitsPointer(),&number);
// Retrieve the HDU number. checkXtension tests against this.
index(number-1);
}
// check we got the right kind of extension, since otherwise
// we cannot proceed. CheckXtension throws an exception if
// not, which is caught by the concrete class ctors.
checkXtension();
}
ExtHDU::ExtHDU (FITS* p, HduType xtype, const String &hduName, int bitpix, int naxis, const std::vector<long>& axes, int version)
: HDU(p, bitpix, naxis, axes),
m_pcount(0),
m_gcount(1),
m_version(version),
m_xtension(xtype),
m_name(hduName)
{
// writing constructor. Extension must be supplied
// since we must know what type of object to instantiate.
}
ExtHDU::ExtHDU (FITS* p, HduType xtype, int number)
: HDU(p),
m_pcount(0),
m_gcount(1),
m_version(1),
m_xtension(xtype),
m_name("")
{
// set current HDU number. This is required for makeThisCurrent.
index(number+1);
makeThisCurrent();
// set name and version.
readHduName(fitsPointer(),number,m_name,m_version);
// finally, check we got the right type of extension and throw an
// exception otherwise.
checkXtension();
}
ExtHDU::~ExtHDU()
{
}
void ExtHDU::checkXtension ()
{
int status=0;
int hType = -1;
if (fits_get_hdu_type(fitsPointer(), &hType, &status) ) throw FitsError(status);
if (HduType(hType) != m_xtension)
throw HDU::InvalidExtensionType
(" extension type mismatch between request and disk file ",true);
}
void ExtHDU::readHduName (const fitsfile* fptr, int hduIndex, String& hduName, int& hduVersion)
{
// get the name of the extension. If there is neither a HDUNAME
// or an EXTNAME, make a name key for the multimap from the HDU number.
int status=0;
FITSUtil::auto_array_ptr<char> pHduCstr(new char[FLEN_KEYWORD]);
char* hduCstr = pHduCstr.get();
int htype = -1;
String key = "EXTNAME";
char* extnm = const_cast<char*>(key.c_str());
// C requires fptr to be non-const, because the fitsfile pointer
// saves the file state.
fitsfile* cfptr = const_cast<fitsfile*>(fptr);
if (fits_movabs_hdu(cfptr,hduIndex+1,&htype,&status) != 0) throw FitsError(status);
status = fits_read_key_str(cfptr, extnm, hduCstr, NULL, &status);
if (status != 0)
{
strcpy(hduCstr,"");
status = 0;
key = String("HDUNAME");
extnm = const_cast<char*>(key.c_str());
status = fits_read_key_str(cfptr, extnm, hduCstr, NULL, &status);
}
if (strlen(hduCstr) > 0)
{
hduName = String(hduCstr);
long hduV = 1;
hduVersion = hduV;
// get the version number.
key = String("EXTVER");
char* extv = const_cast<char*>(key.c_str());
status = fits_read_key_lng(cfptr, extv, &hduV, NULL, &status);
if (status == 0) hduVersion = hduV;
}
else
{
#ifdef SSTREAM_DEFECT
std::ostrstream fakeKey;
#else
std::ostringstream fakeKey;
#endif
fakeKey << s_missHDU << hduIndex;
#ifdef SSTREAM_DEFECT
msg << std::ends;
#endif
hduName = fakeKey.str();
}
}
void ExtHDU::makeThisCurrent () const
{
HDU::makeThisCurrent();
String tname("");
int tvers = 0;
ExtHDU::readHduName(fitsPointer(),index(),tname,tvers);
parent()->currentExtensionName(tname);
}
Column& ExtHDU::column (const String& colName, bool caseSensitive) const
{
// if not overridden, throw an exception.
// there might be a similar default implementation for function
// that returns image data.
throw WrongExtensionType(name());
}
void ExtHDU::setColumn (const String& colname, Column* value)
{
throw WrongExtensionType(name());
}
Column& ExtHDU::column (int colIndex) const
{
throw WrongExtensionType(name());
}
long ExtHDU::rows () const
{
String msg(" rows function can only be called for Tables - HDU: ");
msg += name();
throw WrongExtensionType(msg);
}
void ExtHDU::checkExtensionType () const
{
// throw if not overridden.
throw WrongExtensionType(name());
}
void ExtHDU::addColumn (ValueType type, const String& columnName, long repeatWidth, const String& colUnit, long decimals, size_t columnNumber)
{
// overridden separately in AsciiTable and BinTable
throw WrongExtensionType(name());
}
void ExtHDU::copyColumn(const Column& inColumn, int colIndx, bool insertNewCol)
{
throw WrongExtensionType(name());
}
void ExtHDU::deleteColumn (const String& columnName)
{
// overridden in Table.
throw WrongExtensionType(name());
}
int ExtHDU::getVersion ()
{
// the version keyword is not stored as a keyword object but
// as a data attribute so we don't "addKeyword" but fits_read_key instead.
static char EXTVER[] = {"EXTVER"};
int status(0);
long vers(1);
fits_read_key_lng(fitsPointer(),EXTVER,&vers,0,&status);
if (status == 0)
{
m_version = vers;
}
else
{
if (status == KEY_NO_EXIST)
{
m_version = 1;
}
else throw FitsError(status);
}
return m_version;
}
long ExtHDU::getRowsize () const
{
// This should be overridden for Table classes, otherwise throw.
throw WrongExtensionType("getRowsize can only be called for Table files");
return 0;
}
int ExtHDU::numCols () const
{
// overridden in Table.
throw WrongExtensionType(name());
return 0;
}
const ColMap& ExtHDU::column () const
{
// overridden in Table.
throw WrongExtensionType(name());
}
bool ExtHDU::isCompressed() const
{
int status=0;
checkExtensionType();
return static_cast<bool>(fits_is_compressed_image(fitsPointer(), &status));
}
// Additional Declarations
} // namespace CCfits