SourceXtractorPlusPlus  0.11
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LdacWriter.cpp
Go to the documentation of this file.
1 
18 #include <sstream>
23 #include "SOURCEXTRACTORPLUSPLUS_VERSION.h"
24 
25 #if BOOST_VERSION < 107300
26 #include <boost/io/detail/quoted_manip.hpp>
27 #else
28 #include <boost/io/quoted.hpp>
29 #endif
30 
31 namespace SourceXtractor {
32 
35 using namespace Euclid::Table;
36 
37 
39  : m_config_manager(manager), m_filename(filename), m_rms(0) {
40 }
41 
42 void LdacWriter::addComment(const std::string& comment) {
43  if (m_objects_writer) {
44  throw Elements::Exception() << "Can not add comments once the output table has been initialized";
45  }
46  m_comments.emplace_back(comment);
47 }
48 
49 // Handle sources instead of table records, so before writing anything
50 // we can recover useful information
52  if (m_objects_writer)
53  return;
54 
55  const auto& detection_frame = source.getProperty<DetectionFrame>();
56  m_rms = detection_frame.getFrame()->getBackgroundMedianRms();
57 }
58 
59 template<typename T>
60 std::string generateHeader(const std::string& name, T value, const std::string& comment) {
62 
63  str << std::setw(8) << std::left << name << "= "
64  << std::scientific << std::setw(20) << std::right << value
65  << " / ";
66 
67  size_t remaining = 80 - str.str().size();
68  str << comment << std::string(remaining-comment.size(), ' ');
69 
70  if (str.str().size() != 80) {
71  throw Elements::Exception() << "Header must be exactly 80 characters long: \"" << str.str() << "\"";
72  }
73 
74  return str.str();
75 }
76 
77 template<>
78 std::string generateHeader<std::string>(const std::string& name, std::string value, const std::string& comment) {
79  std::stringstream str, quoted_value;
80 
81  quoted_value << boost::io::quoted(value, '\'', '\'');
82 
83  str << std::setw(8) << std::left << name << "= "
84  << std::setw(20) << std::left << quoted_value.str()
85  << " / ";
86 
87  size_t remaining = 80 - str.str().size();
88  str << comment << std::string(remaining-comment.size(), ' ');
89 
90  if (str.str().size() != 80) {
91  throw Elements::Exception() << "Header must be exactly 80 characters long: \"" << str.str() << "\"";
92  }
93 
94  return str.str();
95 }
96 
100 
101  str << "Version " << SOURCEXTRACTORPLUSPLUS_VERSION_STRING;
102  entries.emplace_back(str.str());
103  str.str("");
104 
105  auto t = std::time(nullptr);
106  auto now = *std::gmtime(&t);
107 
108  char date_str[32];
109  strftime(date_str, sizeof(date_str), "%Y-%m-%dT%H:%M:%SZ", &now);
110  str << "Called at " << date_str;
111  entries.emplace_back(str.str());
112  str.str("");
113 
114  for (auto& e : entries) {
115  std::stringstream padder;
116  padder << "HISTORY s++: " << std::setw(67) << std::left << e;
117  headers.emplace_back(padder.str());
118  }
119 }
120 
122  auto& detection_image_config = m_config_manager.getConfiguration<DetectionImageConfig>();
123  auto imhead_writer = Euclid::make_unique<FitsWriter>(m_filename, true);
124  imhead_writer->setHduName("LDAC_IMHEAD");
125 
126  // Headers from the image
127  std::vector<std::string> ldac_imhead;
128  auto img_source = detection_image_config.getImageSource();
129  auto img_metadata = img_source->getMetadata();
130  for (const auto &p : img_metadata) {
131  std::string comment;
132  if (p.second.m_extra.count("comment"))
133  comment = p.second.m_extra.at("comment");
134  if (p.second.m_value.type() == typeid(std::string))
135  ldac_imhead.emplace_back(generateHeader(p.first, boost::get<std::string>(p.second.m_value), comment));
136  else
137  ldac_imhead.emplace_back(generateHeader(p.first, p.second.m_value, comment));
138  }
139 
140  // Headers from the configuration and detection
141  auto gain = detection_image_config.getGain();
142  ldac_imhead.emplace_back(generateHeader("SPPGAIN", gain, "Gain used"));
143  ldac_imhead.emplace_back(generateHeader("SPPBKDEV", m_rms, "Median background RMS"));
144 
145  // History, why not
146  generateHistory(ldac_imhead);
147 
148  // END
149  ldac_imhead.emplace_back("END" + std::string(77, ' '));
150 
151  // Write the table
152  auto column_info = std::make_shared<ColumnInfo>(std::vector<ColumnInfo::info_type>{
153  {"Field Header Card", typeid(std::string)}
154  });
155  std::vector<Row> rows;
156  for (const auto& header : ldac_imhead) {
157  rows.emplace_back(std::vector<Row::cell_type>{header}, column_info);
158  }
159  imhead_writer->addData(Table{std::vector<Row>{rows}});
160 }
161 
162 void LdacWriter::init(const Table&) {
163  // Initialize LDAC_IMHEAD HDU
164  writeImHead();
165 
166  // Initialize LDAC_OBJECTS HDU
167  m_objects_writer = Euclid::make_unique<FitsWriter>(m_filename, false);
168  m_objects_writer->setHduName("LDAC_OBJECTS");
169  for (auto& comment: m_comments) {
170  m_objects_writer->addComment(comment);
171  }
172  m_comments.clear();
173 }
174 
175 void LdacWriter::append(const Table& table) {
176  assert(m_objects_writer);
177  m_objects_writer->addData(table);
178 }
179 
180 } // end of namespace SourceXtractor
static void generateHistory(std::vector< std::string > &headers)
Definition: LdacWriter.cpp:97
Euclid::Configuration::ConfigManager & m_config_manager
Definition: LdacWriter.h:46
const PropertyType & getProperty(unsigned int index=0) const
Convenience template method to call getProperty() with a more user-friendly syntax.
LdacWriter(const std::string &filename, Euclid::Configuration::ConfigManager &manager)
Definition: LdacWriter.cpp:38
void init(const Euclid::Table::Table &table) override
Definition: LdacWriter.cpp:162
void append(const Euclid::Table::Table &table) override
Definition: LdacWriter.cpp:175
constexpr double e
T left(T...args)
std::string generateHeader(const std::string &name, T value, const std::string &comment)
Definition: LdacWriter.cpp:60
std::unique_ptr< Euclid::Table::FitsWriter > m_objects_writer
Definition: LdacWriter.h:48
Provides the detection image.
T time(T...args)
T setw(T...args)
STL class.
T at(T...args)
std::vector< std::string > m_comments
Definition: LdacWriter.h:49
T gmtime(T...args)
T strftime(T...args)
string filename
Definition: conf.py:63
T str(T...args)
DetectionImage::PixelType m_rms
Definition: LdacWriter.h:50
T scientific(T...args)
T size(T...args)
std::unique_ptr< T > make_unique(Args &&...args)
void notifySource(const SourceInterface &source)
Definition: LdacWriter.cpp:51
void addComment(const std::string &comment) override
Definition: LdacWriter.cpp:42
The SourceInterface is an abstract &quot;source&quot; that has properties attached to it.
T emplace_back(T...args)