29 #include <boost/lexical_cast.hpp> 30 #include <CCfits/CCfits> 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) {
103 if (boost::get<
NdArray<T>>(row[column_index]).shape() != shape) {
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<bool>(table, column_index);
145 format_list.push_back(boost::lexical_cast<std::string>(size) +
"L");
147 size_t size = ndArraySize<int32_t>(table, column_index);
148 format_list.push_back(boost::lexical_cast<std::string>(size) +
"J");
150 size_t size = ndArraySize<int64_t>(table, column_index);
151 format_list.push_back(boost::lexical_cast<std::string>(size) +
"K");
153 size_t size = ndArraySize<float>(table, column_index);
154 format_list.push_back(boost::lexical_cast<std::string>(size) +
"E");
156 size_t size = ndArraySize<double>(table, column_index);
157 format_list.push_back(boost::lexical_cast<std::string>(size) +
"D");
159 throw Elements::Exception() <<
"Unsupported column format for FITS binary table export: " << type.name();
168 for (
const auto& row : table) {
169 data.
push_back(boost::get<T>(row[column_index]));
174 template <
typename T>
177 for (
auto& row : table) {
178 const auto& vec = boost::get<std::vector<T>>(row[column_index]);
184 template <
typename T>
187 for (
auto& row : table) {
188 const auto& vec = boost::get<std::vector<T>>(row[column_index]);
194 template <
typename T>
197 for (
auto& row : table) {
198 const auto& ndarray = boost::get<NdArray<T>>(row[column_index]);
199 result.
emplace_back(ndarray.data().data(), ndarray.size());
204 template <
typename T>
207 for (
auto& row : table) {
208 const auto& nd = boost::get<NdArray<T>>(row[column_index]);
217 template <
typename T>
219 const auto& vec = boost::get<std::vector<T>>(table[0][column_index]);
220 if (vec.size() > 1) {
221 table_hdu.column(column_index+1).writeArrays(createVectorColumnData<T>(table, column_index), first_row);
223 table_hdu.column(column_index+1).write(createSingleValueVectorColumnData<T>(table, column_index), first_row);
227 template <
typename T>
229 const auto& nd = boost::get<NdArray<T>>(table[0][column_index]);
231 table_hdu.column(column_index + 1).writeArrays(createNdArrayColumnData<T>(table, column_index), first_row);
234 table_hdu.column(column_index+1).write(createSingleNdArrayVectorColumnData<T>(table, column_index), first_row);
239 auto& first_row = table[0];
240 auto& cell = first_row[column_index];
241 auto type = table.getColumnInfo()->getDescription(column_index).type;
245 shape = boost::get<NdArray<bool>>(cell).shape();
247 shape = boost::get<NdArray<int32_t>>(cell).shape();
249 shape = boost::get<NdArray<int64_t>>(cell).shape();
251 shape = boost::get<NdArray<float>>(cell).shape();
253 shape = boost::get<NdArray<double>>(cell).shape();
259 for (
auto &axis : shape) {
270 for (j = shape.size() - 1; j > 0; --j) {
271 stream << shape[j] <<
",";
274 stream << shape[j] <<
')';
279 auto type = table.getColumnInfo()->getDescription(column_index).type;
281 if (type ==
typeid(
bool)) {
282 table_hdu.column(column_index+1).write(createColumnData<bool>(table, column_index), first_row);
283 }
else if (type ==
typeid(int32_t)) {
284 table_hdu.column(column_index+1).write(createColumnData<int32_t>(table, column_index), first_row);
285 }
else if (type ==
typeid(int64_t)) {
286 table_hdu.column(column_index+1).write(createColumnData<int64_t>(table, column_index), first_row);
287 }
else if (type ==
typeid(
float)) {
288 table_hdu.column(column_index+1).write(createColumnData<float>(table, column_index), first_row);
289 }
else if (type ==
typeid(
double)) {
290 table_hdu.column(column_index+1).write(createColumnData<double>(table, column_index), first_row);
292 table_hdu.column(column_index+1).write(createColumnData<std::string>(table, column_index), first_row);
294 populateVectorColumn<int32_t>(table, column_index, table_hdu, first_row);
296 populateVectorColumn<int64_t>(table, column_index, table_hdu, first_row);
298 populateVectorColumn<float>(table, column_index, table_hdu, first_row);
300 populateVectorColumn<double>(table, column_index, table_hdu, first_row);
302 populateNdArrayColumn<int32_t>(table, column_index, table_hdu, first_row);
304 populateNdArrayColumn<int64_t>(table, column_index, table_hdu, first_row);
306 populateNdArrayColumn<float>(table, column_index, table_hdu, first_row);
308 populateNdArrayColumn<double>(table, column_index, table_hdu, first_row);
310 throw Elements::Exception() <<
"Cannot populate FITS column with data of type " << type.name();
std::vector< T > createSingleNdArrayVectorColumnData(const Euclid::Table::Table &table, size_t column_index)
std::vector< T > createColumnData(const Euclid::Table::Table &table, size_t column_index)
std::vector< std::valarray< T > > createNdArrayColumnData(const Euclid::Table::Table &table, size_t column_index)
void populateColumn(const Table &table, size_t column_index, CCfits::ExtHDU &table_hdu, long first_row)
std::vector< T > createSingleValueVectorColumnData(const Euclid::Table::Table &table, size_t column_index)
size_t maxWidthScientific(const Table &table, size_t column_index)
NdArray(const std::vector< size_t > &shape)
std::string scientificFormat(T value)
void populateNdArrayColumn(const Table &table, size_t column_index, CCfits::ExtHDU &table_hdu, long first_row)
std::vector< std::valarray< T > > createVectorColumnData(const Euclid::Table::Table &table, size_t column_index)
std::string getTDIM(const Table &table, size_t column_index)
size_t ndArraySize(const Table &table, size_t column_index)
size_t vectorSize(const Table &table, size_t column_index)
std::vector< std::string > getAsciiFormatList(const Table &table)
Returns a vector with strings representing the FITS ASCII table formats for the given table.
void populateVectorColumn(const Table &table, size_t column_index, CCfits::ExtHDU &table_hdu, long first_row)
std::vector< std::string > getBinaryFormatList(const Table &table)
Returns a vector with strings representing the FITS binary table formats for the given table.
size_t maxWidth(const Table &table, size_t column_index)
T emplace_back(T... args)