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