26#include "ElementsKernel/Exception.h"
29#include <CCfits/CCfits>
31#include <boost/lexical_cast.hpp>
35using Euclid::Table::operator<<;
50 size_t width = table.getColumnInfo()->getDescription(column_index).size;
51 for (
const auto& row : table) {
59 for (
const auto& row : table) {
66 auto column_info = table.getColumnInfo();
68 for (
size_t column_index = 0; column_index < column_info->size(); ++column_index) {
69 auto type = column_info->getDescription(column_index).type;
70 if (type ==
typeid(
bool)) {
71 format_list.emplace_back(
"I1");
72 }
else if (type ==
typeid(int32_t) || type ==
typeid(int64_t)) {
73 size_t width =
maxWidth(table, column_index);
74 format_list.emplace_back(
"I" + boost::lexical_cast<std::string>(
std::max(
static_cast<size_t>(1), width)));
75 }
else if (type ==
typeid(
float) || type ==
typeid(
double)) {
77 format_list.emplace_back(
"E" + boost::lexical_cast<std::string>(
std::max(
static_cast<size_t>(1), width)));
79 size_t width =
maxWidth(table, column_index);
80 format_list.emplace_back(
"A" + boost::lexical_cast<std::string>(
std::max(
static_cast<size_t>(1), width)));
82 throw Elements::Exception() <<
"Unsupported column format for FITS ASCII table export: " << type.name();
90 if (table.size() == 0) {
93 size_t size = boost::get<std::vector<T>>(table[0][column_index]).size();
94 for (
const auto& row : table) {
95 if (boost::get<
std::vector<T>>(row[column_index]).size() != size) {
96 throw Elements::Exception() <<
"Binary FITS table variable length vector columns are not supported";
104 if (table.size() == 0) {
107 const auto& ndarray = boost::get<NdArray<T>>(table[0][column_index]);
108 size_t size = ndarray.size();
109 auto shape = ndarray.shape();
110 for (
const auto& row : table) {
111 if (boost::get<
NdArray<T>>(row[column_index]).shape() != shape) {
112 throw Elements::Exception() <<
"Binary FITS table variable shape array columns are not supported";
126 throw Elements::Exception() <<
"Unsupported column format for FITS binary table export: " <<
typeid(T).name();
158 [](
const Table& table,
size_t column) {
159 size_t width =
maxWidth(table, column);
161 return boost::lexical_cast<std::string>(
std::max(
static_cast<size_t>(1), width)) +
"A";
171 auto column_info = table.getColumnInfo();
173 format_list.
reserve(column_info->size());
175 for (
size_t column_index = 0; column_index < column_info->size(); ++column_index) {
176 auto type = column_info->getDescription(column_index).type;
180 throw Elements::Exception() <<
"Unsupported column format for FITS binary table export: " << type.name();
183 format_list.
emplace_back(i->second(table, column_index));
192 [column_index](
const Row& row) { return boost::get<T>(row[column_index]); });
199 for (
auto& row : table) {
200 const auto& vec = boost::get<std::vector<T>>(row[column_index]);
201 result.emplace_back(vec.data(), vec.size());
209 for (
auto& row : table) {
210 const auto& vec = boost::get<std::vector<T>>(row[column_index]);
211 result.push_back(vec.front());
219 for (
auto& row : table) {
220 const auto& ndarray = boost::get<NdArray<T>>(row[column_index]);
231 for (
auto& row : table) {
232 const auto& nd = boost::get<NdArray<T>>(row[column_index]);
234 result.push_back(*nd.begin());
243 const auto& vec = boost::get<std::vector<T>>(table[0][column_index]);
244 if (vec.size() > 1) {
253 const auto& nd = boost::get<NdArray<T>>(table[0][column_index]);
262 if (table.size() == 0) {
266 auto& first_row = table[0];
267 auto& cell = first_row[column_index];
268 auto type = table.getColumnInfo()->getDescription(column_index).type;
272 shape = boost::get<NdArray<int32_t>>(cell).shape();
274 shape = boost::get<NdArray<int64_t>>(cell).shape();
276 shape = boost::get<NdArray<float>>(cell).shape();
278 shape = boost::get<NdArray<double>>(cell).shape();
292 for (j = shape.
size() - 1; j > 0; --j) {
293 stream << shape[j] <<
",";
296 stream << shape[j] <<
')';
300void populateColumn(
const Table& table,
int column_index,
const CCfits::ExtHDU& table_hdu,
long first_row) {
301 if (table.size() == 0) {
304 auto type = table.getColumnInfo()->getDescription(column_index).type;
306 if (type ==
typeid(
bool)) {
308 }
else if (type ==
typeid(int32_t)) {
310 }
else if (type ==
typeid(int64_t)) {
312 }
else if (type ==
typeid(
float)) {
314 }
else if (type ==
typeid(
double)) {
335 throw Elements::Exception() <<
"Cannot populate FITS column with data of type " << type.name();
NdArray(std::vector< size_t > shape_)
Represents one row of a Table.
T emplace_back(T... args)
const std::map< std::type_index, std::function< std::string(const Table &, size_t)> > BinaryFormatter
std::vector< std::string > getAsciiFormatList(const Table &table)
Returns a vector with strings representing the FITS ASCII table formats for the given table.
std::vector< T > createSingleNdArrayVectorColumnData(const Euclid::Table::Table &table, size_t column_index)
std::vector< std::valarray< T > > createVectorColumnData(const Euclid::Table::Table &table, size_t column_index)
static std::string GenericVectorFormat(const Table &table, size_t column_index)
std::vector< T > createSingleValueVectorColumnData(const Euclid::Table::Table &table, size_t column_index)
void populateColumn(const Table &table, int column_index, const CCfits::ExtHDU &table_hdu, long first_row)
static std::string GenericNdFormat(const Table &table, size_t column_index)
size_t maxWidthScientific(const Table &table, size_t column_index)
size_t maxWidth(const Table &table, size_t column_index)
const std::vector< std::pair< char, std::type_index > > ScalarTypeMap
size_t ndArraySize(const Table &table, size_t column_index)
std::vector< std::string > getBinaryFormatList(const Table &table)
Returns a vector with strings representing the FITS binary table formats for the given table.
std::vector< std::valarray< T > > createNdArrayColumnData(const Euclid::Table::Table &table, size_t column_index)
std::string scientificFormat(const T &value)
size_t vectorSize(const Table &table, size_t column_index)
void populateVectorColumn(const Table &table, int column_index, const CCfits::ExtHDU &table_hdu, long first_row)
static std::string GenericScalarFormat(const Table &, size_t)
std::vector< T > createColumnData(const Table &table, size_t column_index)
std::string getTDIM(const Table &table, int column_index)
void populateNdArrayColumn(const Table &table, int column_index, const CCfits::ExtHDU &table_hdu, long first_row)