NAPISD
PAHdb website C++ backend
Loading...
Searching...
No Matches
FileInput.cpp
1#include "FileInput.h"
2
3FileInput::FileInput(const std::string_view filename) : _filename(filename) {}
4
5std::tuple<std::vector<double>, std::vector<double>, std::vector<double>>
6FileInput::readFileFromDisk(FileInput::Filetype filetype) {
7
8 switch (filetype) {
9
10 case FileInput::Filetype::ASCII:
11
12 return readASCIIFileFromDisk();
13 break;
14
15 case FileInput::Filetype::YAAAR:
16
17 return readYAAARFileFromDisk();
18 break;
19
20 case FileInput::Filetype::VOTABLE:
21
22 return readVOTableFileFromDisk();
23 break;
24
25 case FileInput::Filetype::GUESS:
26
27 return readGuessedFileFromDisk();
28 break;
29
30 default:
31
32 throw(Exception("Unable to resolve filetype or filetype not supported"));
33 }
34}
35
36std::tuple<std::vector<double>, std::vector<double>, std::vector<double>>
37FileInput::readASCIIFileFromDisk() {
38
39 std::vector<double> xdata;
40 xdata.reserve(64);
41
42 std::vector<double> ydata;
43 ydata.reserve(64);
44
45 std::vector<double> yerrdata;
46 yerrdata.reserve(64);
47
48 int column = 1;
49
50 char c;
51
52 std::string value;
53
54 double d;
55
56 char *endptr;
57
58 std::ifstream ifstr;
59
60 ifstr.exceptions(std::ifstream::failbit | std::ifstream::badbit);
61
62 try {
63
64 ifstr.open(_filename, std::ios::in);
65
66 while (ifstr.get(c).good()) {
67
68 if (isdigit(c) || c == '.' || c == '-' || c == '+') {
69
70 value += c;
71 } else if (c == '#') {
72
73 while (ifstr.get(c).good()) {
74
75 if (c == '\n') {
76 break;
77 }
78 }
79 } else if (isspace(c)) {
80
81 if (!value.empty()) {
82
83 d = strtod(value.c_str(), &endptr);
84
85 if (*endptr != '\0') {
86
87 throw Exception("Unable to convert string to double");
88 }
89
90 if (column > 3) {
91
92 throw Exception("Extraneous number of columns");
93 } else if (column == 1) {
94
95 xdata.push_back(1e4 / d);
96 } else if (column == 2) {
97
98 ydata.push_back(d);
99 } else if (column == 3) {
100
101 yerrdata.push_back(d);
102 }
103
104 if (c == '\r' || c == '\n') {
105 column = 1;
106 } else {
107
108 ++column;
109 }
110
111 value.erase();
112 }
113 } else {
114
115 throw Exception("Extraneous data");
116 }
117 }
118 } catch (const std::ifstream::failure &e) {
119
120 if (!ifstr.eof()) {
121
122 throw Exception(e.what());
123 }
124 } catch (const Exception &e) {
125
126 throw;
127 }
128
129 return std::make_tuple(xdata, ydata, yerrdata);
130}
131
132std::tuple<std::vector<double>, std::vector<double>, std::vector<double>>
133FileInput::readYAAARFileFromDisk() {
134
135 std::vector<double> xdata;
136 xdata.reserve(64);
137
138 std::vector<double> ydata;
139 ydata.reserve(64);
140
141 std::vector<double> yerrdata;
142 yerrdata.reserve(64);
143
144 CCfits::FITS::setVerboseMode(true);
145
146 std::unique_ptr<CCfits::FITS> fits;
147
148 try {
149
150 fits = std::make_unique<CCfits::FITS>(_filename, CCfits::Read);
151
152 CCfits::ExtHDU &table = fits->extension(1);
153
154 table.column(1).read(xdata, 1, table.column(1).rows());
155
156 table.column(2).read(ydata, 1, table.column(2).rows());
157
158 table.column(3).read(yerrdata, 1, table.column(3).rows());
159
160 } catch (CCfits::FitsException &e) {
161
162 throw Exception(e.message());
163 }
164
165 for (auto &x : xdata) {
166
167 x = 1e4 / x;
168 }
169
170 return std::make_tuple(xdata, ydata, yerrdata);
171}
172
173std::tuple<std::vector<double>, std::vector<double>, std::vector<double>>
174FileInput::readVOTableFileFromDisk() {
175
176 std::vector<double> xdata;
177 xdata.reserve(64);
178
179 std::vector<double> ydata;
180 ydata.reserve(64);
181
182 std::vector<double> yerrdata;
183 yerrdata.reserve(64);
184
185 double d;
186
187 char *endptr;
188
189 tinyxml2::XMLDocument doc;
190
191 if (doc.LoadFile(_filename.c_str()) != tinyxml2::XML_SUCCESS) {
192
193 throw Exception(doc.ErrorStr());
194 }
195
196 tinyxml2::XMLElement *root = doc.RootElement();
197
198 if (strcmp(root->Name(), "VOTABLE") != 0) {
199
200 throw Exception("Incorrect document root");
201 }
202
203 tinyxml2::XMLElement *resource = root->FirstChildElement("RESOURCE");
204
205 if (nullptr == resource) {
206
207 throw Exception("VOTABLE has no resource");
208 }
209
210 tinyxml2::XMLElement *table = resource->FirstChildElement("TABLE");
211
212 if (nullptr == table) {
213
214 throw Exception("VOTABLE resource has no table");
215 }
216
217 tinyxml2::XMLElement *data = table->FirstChildElement("DATA");
218
219 if (nullptr == data) {
220
221 throw Exception("VOTABLE resource table has no data");
222 }
223
224 tinyxml2::XMLElement *tabledata = data->FirstChildElement("TABLEDATA");
225
226 if (nullptr == tabledata) {
227
228 throw Exception("VOTABLE resource table data has no tabledata");
229 }
230
231 tinyxml2::XMLElement *tr = tabledata->FirstChildElement();
232
233 while (true) {
234
235 if (strcmp(tr->Name(), "TR") != 0) {
236
237 throw Exception("VOTABLE resource table data tabledata expects row");
238 }
239
240 tinyxml2::XMLElement *td = tr->FirstChildElement();
241
242 if (strcmp(td->Name(), "TD") != 0) {
243
244 throw Exception(
245 "VOTABLE resource table data tabledata row expects table data");
246 }
247
248 d = strtod(td->GetText(), &endptr);
249
250 if (*endptr != '\0') {
251
252 throw Exception("Unable to convert string to double");
253 }
254
255 xdata.push_back(1e4 / d);
256
257 td = td->NextSiblingElement();
258
259 if (strcmp(td->Name(), "TD") != 0) {
260
261 throw Exception(
262 "VOTABLE resource table data tabledata row expects table data");
263 }
264
265 d = strtod(td->GetText(), &endptr);
266
267 if (*endptr != '\0') {
268
269 throw Exception("Unable to convert string to double");
270 }
271
272 ydata.push_back(d);
273
274 tr = tr->NextSiblingElement();
275
276 if (nullptr == tr) {
277
278 break;
279 }
280 }
281
282 return std::make_tuple(xdata, ydata, yerrdata);
283}
284
285std::tuple<std::vector<double>, std::vector<double>, std::vector<double>>
286FileInput::readGuessedFileFromDisk() {
287
288 std::unique_ptr<CCfits::FITS> fits;
289
290 try {
291
292 fits = std::make_unique<CCfits::FITS>(_filename);
293 } catch (CCfits::FitsError &e) {
294
295 std::ifstream ifstr(_filename);
296
297 std::string line;
298
299 getline(ifstr, line);
300
301 if (line.compare(0, 5, "<?xml") == 0) {
302
303 return FileInput::readVOTableFileFromDisk();
304 } else {
305
306 return FileInput::readASCIIFileFromDisk();
307 }
308 }
309
310 return FileInput::readYAAARFileFromDisk();
311}

Since FY2019 the NASA Ames PAH IR Spectroscopic Database is being supported through a directed Work Package at NASA Ames titled: "Laboratory Astrophysics - The NASA Ames PAH IR Spectroscopic Database".
Since FY2023 the NASA Ames PAH IR Spectroscopic Database is being supported through the Laboratory Astrophysics Rd 2 directed Work Package at NASA Ames.
© Copyright 2021-2025, Christiaan Boersma