28 #include <CCfits/CCfits>
30 #include <boost/lexical_cast.hpp>
49 for (
const auto& row : table) {
50 width =
std::max(width, boost::lexical_cast<std::string>(row[column_index]).size());
57 for (
const auto& row : table) {
64 auto column_info = table.getColumnInfo();
66 for (
size_t column_index = 0; column_index < column_info->size(); ++column_index) {
67 auto type = column_info->getDescription(column_index).type;
68 if (type ==
typeid(
bool)) {
70 }
else if (type ==
typeid(int32_t) || type ==
typeid(int64_t)) {
71 size_t width =
maxWidth(table, column_index);
72 format_list.push_back(
"I" + boost::lexical_cast<std::string>(width));
73 }
else if (type ==
typeid(
float) || type ==
typeid(
double)) {
75 format_list.push_back(
"E" + boost::lexical_cast<std::string>(width));
77 size_t width =
maxWidth(table, column_index);
78 format_list.push_back(
"A" + boost::lexical_cast<std::string>(width));
80 throw Elements::Exception() <<
"Unsupported column format for FITS ASCII table export: " << type.name();
88 size_t size = boost::get<std::vector<T>>(table[0][column_index]).size();
89 for (
const auto& row : table) {
90 if (boost::get<
std::vector<T>>(row[column_index]).size() != size) {
91 throw Elements::Exception() <<
"Binary FITS table variable length vector columns are not supported";
99 const auto& ndarray = boost::get<NdArray<T>>(table[0][column_index]);
100 size_t size = ndarray.size();
101 auto shape = ndarray.shape();
102 for (
const auto& row : table) {
104 throw Elements::Exception() <<
"Binary FITS table variable shape array columns are not supported";
111 auto column_info = table.getColumnInfo();
113 for (
size_t column_index = 0; column_index < column_info->size(); ++column_index) {
114 auto type = column_info->getDescription(column_index).type;
115 if (type ==
typeid(
bool)) {
117 }
else if (type ==
typeid(int32_t)) {
119 }
else if (type ==
typeid(int64_t)) {
120 format_list.push_back(
"K");
121 }
else if (type ==
typeid(
float)) {
122 format_list.push_back(
"E");
123 }
else if (type ==
typeid(
double)) {
124 format_list.push_back(
"D");
126 size_t width =
maxWidth(table, column_index);
127 format_list.push_back(boost::lexical_cast<std::string>(width) +
"A");
129 size_t size = vectorSize<bool>(table, column_index);
130 format_list.push_back(boost::lexical_cast<std::string>(size) +
"L");
132 size_t size = vectorSize<int32_t>(table, column_index);
133 format_list.push_back(boost::lexical_cast<std::string>(size) +
"J");
135 size_t size = vectorSize<int64_t>(table, column_index);
136 format_list.push_back(boost::lexical_cast<std::string>(size) +
"K");
138 size_t size = vectorSize<float>(table, column_index);
139 format_list.push_back(boost::lexical_cast<std::string>(size) +
"E");
141 size_t size = vectorSize<double>(table, column_index);
142 format_list.push_back(boost::lexical_cast<std::string>(size) +
"D");
144 size_t size = ndArraySize<int32_t>(table, column_index);
145 format_list.push_back(boost::lexical_cast<std::string>(size) +
"J");
147 size_t size = ndArraySize<int64_t>(table, column_index);
148 format_list.push_back(boost::lexical_cast<std::string>(size) +
"K");
150 size_t size = ndArraySize<float>(table, column_index);
151 format_list.push_back(boost::lexical_cast<std::string>(size) +
"E");
153 size_t size = ndArraySize<double>(table, column_index);
154 format_list.push_back(boost::lexical_cast<std::string>(size) +
"D");
156 throw Elements::Exception() <<
"Unsupported column format for FITS binary table export: " << type.name();
162 template <
typename T>
165 for (
const auto& row : table) {
166 data.
push_back(boost::get<T>(row[column_index]));
171 template <
typename T>
174 for (
auto& row : table) {
175 const auto& vec = boost::get<std::vector<T>>(row[column_index]);
181 template <
typename T>
184 for (
auto& row : table) {
185 const auto& vec = boost::get<std::vector<T>>(row[column_index]);
191 template <
typename T>
194 for (
auto& row : table) {
195 const auto& ndarray = boost::get<NdArray<T>>(row[column_index]);
203 template <
typename T>
206 for (
auto& row : table) {
207 const auto& nd = boost::get<NdArray<T>>(row[column_index]);
216 template <
typename T>
218 const auto& vec = boost::get<std::vector<T>>(table[0][column_index]);
219 if (vec.size() > 1) {
220 table_hdu.column(column_index + 1).writeArrays(createVectorColumnData<T>(table, column_index), first_row);
222 table_hdu.column(column_index + 1).write(createSingleValueVectorColumnData<T>(table, column_index), first_row);
226 template <
typename T>
228 const auto& nd = boost::get<NdArray<T>>(table[0][column_index]);
230 table_hdu.column(column_index + 1).writeArrays(createNdArrayColumnData<T>(table, column_index), first_row);
232 table_hdu.column(column_index + 1).write(createSingleNdArrayVectorColumnData<T>(table, column_index), first_row);
237 auto& first_row = table[0];
238 auto& cell = first_row[column_index];
239 auto type = table.getColumnInfo()->getDescription(column_index).type;
243 shape = boost::get<NdArray<int32_t>>(cell).shape();
245 shape = boost::get<NdArray<int64_t>>(cell).shape();
247 shape = boost::get<NdArray<float>>(cell).shape();
249 shape = boost::get<NdArray<double>>(cell).shape();
255 for (
auto& axis : shape) {
266 for (j = shape.size() - 1; j > 0; --j) {
267 stream << shape[j] <<
",";
270 stream << shape[j] <<
')';
275 auto type = table.getColumnInfo()->getDescription(column_index).type;
277 if (type ==
typeid(
bool)) {
278 table_hdu.column(column_index + 1).write(createColumnData<bool>(table, column_index), first_row);
279 }
else if (type ==
typeid(int32_t)) {
280 table_hdu.column(column_index + 1).write(createColumnData<int32_t>(table, column_index), first_row);
281 }
else if (type ==
typeid(int64_t)) {
282 table_hdu.column(column_index + 1).write(createColumnData<int64_t>(table, column_index), first_row);
283 }
else if (type ==
typeid(
float)) {
284 table_hdu.column(column_index + 1).write(createColumnData<float>(table, column_index), first_row);
285 }
else if (type ==
typeid(
double)) {
286 table_hdu.column(column_index + 1).write(createColumnData<double>(table, column_index), first_row);
288 table_hdu.column(column_index + 1).write(createColumnData<std::string>(table, column_index), first_row);
290 populateVectorColumn<int32_t>(table, column_index, table_hdu, first_row);
292 populateVectorColumn<int64_t>(table, column_index, table_hdu, first_row);
294 populateVectorColumn<float>(table, column_index, table_hdu, first_row);
296 populateVectorColumn<double>(table, column_index, table_hdu, first_row);
298 populateNdArrayColumn<int32_t>(table, column_index, table_hdu, first_row);
300 populateNdArrayColumn<int64_t>(table, column_index, table_hdu, first_row);
302 populateNdArrayColumn<float>(table, column_index, table_hdu, first_row);
304 populateNdArrayColumn<double>(table, column_index, table_hdu, first_row);
306 throw Elements::Exception() <<
"Cannot populate FITS column with data of type " << type.name();