Alexandria  2.27.0
SDC-CH common library for the Euclid project
FitsWriter.cpp
Go to the documentation of this file.
1 
25 #include "Table/FitsWriter.h"
27 #include "FitsWriterHelper.h"
28 #include "ReaderHelper.h"
29 #include <CCfits/CCfits>
30 #include <boost/lexical_cast.hpp>
31 
32 namespace Euclid {
33 namespace Table {
34 
35 FitsWriter::FitsWriter(const std::string& filename, bool override_flag)
36  : m_filename(filename), m_override_file(override_flag) {}
37 
39 
41  if (m_initialized) {
42  throw Elements::Exception() << "Changing the format after writing "
43  << "has started is not allowed";
44  }
45  m_format = format;
46  return *this;
47 }
48 
50  if (m_initialized) {
51  throw Elements::Exception() << "Changing the HDU name after writing "
52  << "has started is not allowed";
53  }
54  m_hdu_name = name;
55  return *this;
56 }
57 
58 void FitsWriter::addComment(const std::string& message) {
59  if (m_initialized) {
60  throw Elements::Exception() << "Adding comments after writing "
61  << "has started is not allowed";
62  }
63  m_comments.push_back(message);
64 }
65 
66 void FitsWriter::init(const Table& table) {
67 
69  if (m_fits != nullptr) {
70  fits = m_fits;
71  } else {
72  // CCfits overrides the file if the name starts with !, otherwise it opens it
73  std::string filename = (m_override_file ? "!" : "") + m_filename;
74  fits = std::make_shared<CCfits::FITS>(filename, CCfits::RWmode::Write);
75  }
76 
77  // Create the column info arrays to feed the CCfits based on the ColumnInfo object
78  auto& info = *table.getColumnInfo();
79  std::vector<std::string> column_name_list{};
80  std::vector<std::string> column_unit_list{};
81  for (size_t column_index = 0; column_index < info.size(); ++column_index) {
82  column_name_list.push_back(info.getDescription(column_index).name);
83  column_unit_list.push_back(info.getDescription(column_index).unit);
84  }
85  std::vector<std::string> column_format_list =
87 
88  CCfits::HduType hdu_type = (m_format == Format::BINARY) ? CCfits::HduType::BinaryTbl : CCfits::HduType::AsciiTbl;
89 
90  auto extension_map = fits->extension();
91  auto extension_i = extension_map.find(m_hdu_name);
92  bool new_hdu = (extension_i == extension_map.end() || extension_i->second->version() != 1);
93 
94  CCfits::Table* table_hdu;
95  if (!new_hdu) {
96  table_hdu = dynamic_cast<CCfits::Table*>(extension_i->second);
97  assert(table_hdu != nullptr);
98  } else {
99  table_hdu = fits->addTable(m_hdu_name, 0, column_name_list, column_format_list, column_unit_list, hdu_type);
100 
101  // Write the customized description header keywords, and also dimensions for multidimensional arrays
102  for (size_t column_index = 0; column_index < info.size(); ++column_index) {
103  auto& desc = info.getDescription(column_index).description;
104  table_hdu->addKey("TDESC" + std::to_string(column_index + 1), desc, "");
105 
106  auto shape_str = getTDIM(table, column_index);
107  if (!shape_str.empty()) {
108  table_hdu->addKey(CCfits::Column::TDIM() + std::to_string(column_index + 1), shape_str, "");
109  }
110  }
111 
112  for (auto& h : m_headers) {
113  table_hdu->addKey(h.m_key, boost::lexical_cast<std::string>(cell_stream_adaptor(h.m_value)), h.m_comment);
114  }
115 
116  for (auto& c : m_comments) {
117  table_hdu->writeComment(c);
118  }
119  }
120 
121  m_hdu_index = table_hdu->index();
122  m_current_line = table_hdu->rows() + 1;
123  m_initialized = true;
124 }
125 
126 void FitsWriter::append(const Table& table) {
128  if (m_fits != nullptr) {
129  fits = m_fits;
130  } else {
131  fits = std::make_shared<CCfits::FITS>(m_filename, CCfits::RWmode::Write);
132  }
133  auto& table_hdu = fits->extension(m_hdu_index);
134 
135  auto& info = *table.getColumnInfo();
136  for (size_t column_index = 0; column_index < info.size(); ++column_index) {
137  populateColumn(table, column_index, table_hdu, m_current_line);
138  }
139  m_current_line += table.size();
140 }
141 
142 } // namespace Table
143 } // namespace Euclid
TableWriter implementation for writing tables in FITS format.
Definition: FitsWriter.h:76
FitsWriter & setFormat(Format format)
Set the FITS table format.
Definition: FitsWriter.cpp:40
void addComment(const std::string &message) override
Adds a comment to the stream.
Definition: FitsWriter.cpp:58
Format
The format of the HDUs a FitsWriter creates.
Definition: FitsWriter.h:80
@ BINARY
FITS binary table HDU format.
std::vector< Header > m_headers
Definition: FitsWriter.h:220
void append(const Table &table) override
Definition: FitsWriter.cpp:126
FitsWriter(const std::string &filename, bool override_flag=false)
Creates a FitsWriter that writes to a specific file.
Definition: FitsWriter.cpp:35
std::vector< std::string > m_comments
Definition: FitsWriter.h:219
std::shared_ptr< CCfits::FITS > m_fits
Definition: FitsWriter.h:214
void init(const Table &table) override
Definition: FitsWriter.cpp:66
FitsWriter & setHduName(const std::string &name)
Set the HDU name where the table is written.
Definition: FitsWriter.cpp:49
Represents a table.
Definition: Table.h:49
std::vector< std::string > getAsciiFormatList(const Table &table)
Returns a vector with strings representing the FITS ASCII table formats for the given table.
void populateColumn(const Table &table, int column_index, const 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.
std::string getTDIM(const Table &table, int column_index)
T push_back(T... args)
T to_string(T... args)