Citlali
Loading...
Searching...
No Matches
io.h
Go to the documentation of this file.
1#pragma once
2
3#include <tula/cli.h>
4#include <tula/config/core.h>
5#include <tula/config/flatconfig.h>
6#include <tula/config/yamlconfig.h>
7#include <tula/enum.h>
8#include <tula/filesystem.h>
9#include <tula/formatter/container.h>
10#include <tula/formatter/enum.h>
11#include <tula/grppi.h>
12#include <tula/logging.h>
13#include <tula/switch_invoke.h>
14
16
17namespace predefs {
18
20
21// We need to be careful about the int type used here as we may
22// have very large array in the memory.
23// check eigen index type
24static_assert(std::is_same_v<std::ptrdiff_t, Eigen::Index>,
25 "UNEXPECTED EIGEN INDEX TYPE");
26using index_t = std::ptrdiff_t;
27using shape_t = Eigen::Matrix<index_t, 2, 1>;
28using data_t = double;
29
30// IO spec
31namespace kidsdata = kids::toltec;
32
33// TcData is the data structure of which RTCData and PTCData are a part
35
36// Selects the type of TCData
37using timestream::TCDataKind;
38
39} // namespace predefs
40
41template <typename Derived>
43 tula::config::ConfigValidatorMixin<Derived, tula::config::YamlConfig>;
44
50struct RawObs : ConfigMapper<RawObs> {
52
58 struct DataItem : ConfigMapper<DataItem> {
60 DataItem(config_t config)
61 : Base{std::move(config)}, m_interface(this->config().get_str(
62 std::tuple{"meta", "interface"})),
63 m_filepath(this->config().get_filepath("filepath")) {}
64
65 static auto check_config(config_t &config)
66 -> std::optional<std::string> {
67 std::vector<std::string> missing_keys;
68 SPDLOG_INFO("check data item config\n{}", config);
69 if (!config.has(std::tuple{"meta", "interface"})) {
70 missing_keys.push_back("meta.interface");
71 }
72 if (!config.has("filepath")) {
73 missing_keys.push_back("filepath");
74 }
75 if (missing_keys.empty()) {
76 return std::nullopt;
77 }
78 return fmt::format("invalid or missing keys={}", missing_keys);
79 }
80 const std::string &interface() const { return m_interface; }
81 const std::string &filepath() const { return m_filepath; }
82
83 private:
84 std::string m_interface{};
85 std::string m_filepath{};
86 };
87
88 // clang-format off
89 TULA_ENUM_DECL(CalItemType, int,
91 photometry,
92 astrometry,
93 unresolved
94 );
95 // clang-format on
96 using CalItemTypes = tula::meta::cases<CalItemType::array_prop_table,
97 CalItemType::photometry,
98 CalItemType::astrometry,
99 CalItemType::unresolved>;
100 struct ArrayPropTable;
101 struct PhotometryCalibInfo;
102 struct AstrometryCalibInfo;
103
104 struct CalItem;
105 template <auto type>
106 using cal_item_t = tula::meta::switch_t<
107 type,
108 tula::meta::case_t<CalItemType::array_prop_table, ArrayPropTable>,
109 tula::meta::case_t<CalItemType::photometry, PhotometryCalibInfo>,
110 tula::meta::case_t<CalItemType::astrometry, AstrometryCalibInfo>,
111 tula::meta::case_t<CalItemType::unresolved, CalItem>>;
113 std::variant<
114 std::monostate,
118 >;
119
120 struct ArrayPropTable : ConfigMapper<ArrayPropTable> {
122 ArrayPropTable(config_t config)
123 : Base{std::move(config)},
124 m_filepath(this->config().get_str("filepath")) {}
125
126 static auto check_config(config_t &config)
127 -> std::optional<std::string> {
128 std::vector<std::string> missing_keys;
129 SPDLOG_INFO("check array prop table config\n{}", config);
130 if (!config.has("filepath")) {
131 missing_keys.push_back("filepath");
132 }
133 if (missing_keys.empty()) {
134 return std::nullopt;
135 }
136 return fmt::format("invalid or missing keys={}", missing_keys);
137 }
138 const std::string &filepath() const { return m_filepath; }
139
140 private:
141 std::string m_filepath{};
142 };
143
144 struct PhotometryCalibInfo : ConfigMapper<PhotometryCalibInfo> {
146 PhotometryCalibInfo(config_t config)
147 : Base{std::move(config)}{}
148 static auto check_config(config_t &config)
149 -> std::optional<std::string> {
150 std::vector<std::string> missing_keys;
151 SPDLOG_INFO("check photometry calib info\n{}", config);
152 // do the checks here
153 if (missing_keys.empty()) {
154 return std::nullopt;
155 }
156 return fmt::format("invalid or missing keys={}", missing_keys);
157 }
158 template <typename OStream>
159 friend auto operator<<(OStream &os, const PhotometryCalibInfo &d)
160 -> decltype(auto) {
161 return os << fmt::format("PhotometryCalibInfo()");
162 }
163 };
164
165 struct AstrometryCalibInfo : ConfigMapper<AstrometryCalibInfo> {
167 AstrometryCalibInfo(config_t config)
168 : Base{std::move(config)}{}
169 static auto check_config(config_t &config)
170 -> std::optional<std::string> {
171 std::vector<std::string> missing_keys;
172 SPDLOG_INFO("check astrometry calib info\n{}", config);
173 // do the checks here
174 if (missing_keys.empty()) {
175 return std::nullopt;
176 }
177 return fmt::format("invalid or missing keys={}", missing_keys);
178 }
179 template <typename OStream>
180 friend auto operator<<(OStream &os, const AstrometryCalibInfo &d)
181 -> decltype(auto) {
182 return os << fmt::format("AstrometryCalibInfo()");
183 }
184 };
185
187 struct CalItem : ConfigMapper<CalItem> {
189 CalItem(config_t config)
190 : Base{std::move(config)},
191 m_typestr(this->config().get_str("type")) {
192 resolve();
193 }
194
195 static auto check_config(config_t &config)
196 -> std::optional<std::string> {
197 std::vector<std::string> missing_keys;
198 SPDLOG_INFO("check cal item config\n{}", config);
199 if (!config.has("type")) {
200 missing_keys.push_back("type");
201 }
202 if (missing_keys.empty()) {
203 return std::nullopt;
204 }
205 return fmt::format("invalid or missing keys={}", missing_keys);
206 }
207 const std::string &typestr() const { return m_typestr; }
208
209 auto type() const {
210 if (auto opt_type_meta = CalItemType_meta::from_name(typestr());
211 opt_type_meta.has_value()) {
212 return opt_type_meta.value().value;
213 }
214 return CalItemType::unresolved;
215 }
216
217 template <auto type_>
218 auto is_type() -> bool {
219 return type() == type_;
220 }
221
222 template <auto type_>
223 auto get() const -> const auto & {
224 return std::get<cal_item_t<type_>>(m_cal_item);
225 }
226
227 private:
228 std::string m_typestr{};
230 void resolve() {
231 tula::meta::switch_invoke<CalItemTypes>(
232 [&](auto _) {
233 constexpr auto type_ = std::decay_t<decltype(_)>::value;
234 if constexpr (type_ == CalItemType::unresolved) {
235 m_cal_item = std::monostate{};
236 } else {
237 m_cal_item = cal_item_t<type_>{this->config()};
238 }
239 },
240 type());
241 }
242 };
243
244 RawObs(config_t config)
245 : Base{std::move(config)}, m_name{this->config().get_str(
246 std::tuple{"meta", "name"})} {
249 }
250
251 static auto check_config(const config_t &config)
252 -> std::optional<std::string> {
253 std::vector<std::string> missing_keys;
254 SPDLOG_INFO("check raw obs config\n{}", config);
255 if (!config.has(std::tuple{"meta", "name"})) {
256 missing_keys.push_back("meta.name");
257 }
258 if (!config.has_list("data_items")) {
259 missing_keys.push_back("data_items");
260 }
261 if (!config.has_list("cal_items")) {
262 missing_keys.push_back("cal_items");
263 }
264 if (missing_keys.empty()) {
265 return std::nullopt;
266 }
267 return fmt::format("invalid or missing keys={}", missing_keys);
268 }
269 const std::string &name() const { return m_name; }
270 auto n_data_items() const { return m_data_items.size(); }
271 const std::vector<DataItem> &data_items() const { return m_data_items; }
272 const DataItem &teldata() const {
273 return m_data_items[m_teldata_index.value()];
274 }
275 std::optional<DataItem> hwpdata() const {
276 if (m_hwpdata_index) {
277 return std::optional{
279 }
280 return std::nullopt;
281 }
282
283 auto kidsdata() const -> decltype(auto) {
284 std::vector<std::reference_wrapper<const DataItem>> result{};
285 for (auto i : m_kidsdata_indices) {
286 result.push_back(std::cref(m_data_items[i]));
287 }
288 return result;
289 }
290
291 auto n_cal_items() const { return m_cal_items.size(); }
292 const std::vector<CalItem> &cal_items() const { return m_cal_items; }
294 return m_cal_items[m_apt_index.value()]
295 .get<CalItemType::array_prop_table>();
296 }
298 return m_cal_items[m_phot_cal_index.value()]
299 .get<CalItemType::photometry>();
300 }
302 return m_cal_items[m_astro_cal_index.value()]
303 .get<CalItemType::astrometry>();
304 }
305
306private:
307 inline const static std::regex re_interface_kidsdata{"toltec\\d{1,2}"};
308 inline const static std::regex re_interface_teldata{"lmt"};
309 inline const static std::regex re_interface_hwpdata{"hwpr"};
310
311 std::string m_name;
312 std::vector<DataItem> m_data_items{};
313 std::vector<std::size_t> m_kidsdata_indices{};
314 std::optional<std::size_t> m_teldata_index{std::nullopt};
315 std::optional<std::size_t> m_hwpdata_index{std::nullopt};
316
317 void collect_data_items();
318 std::vector<CalItem> m_cal_items{};
319 std::optional<std::size_t> m_apt_index{std::nullopt};
320 std::optional<std::size_t> m_phot_cal_index{std::nullopt};
321 std::optional<std::size_t> m_astro_cal_index{std::nullopt};
322
323 void collect_cal_items();
324};
325
326TULA_ENUM_REGISTER(RawObs::CalItemType);
327
328namespace fmt {
329
330template <typename T>
331struct formatter<std::reference_wrapper<T>>
332 : tula::fmt_utils::nullspec_formatter_base {
333 template <typename FormatContext>
334 auto format(const std::reference_wrapper<T> &ref,
335 FormatContext &ctx) const noexcept -> decltype(ctx.out()) {
336 return format_to(ctx.out(), "{}", ref.get());
337 }
338};
339
340template <>
341struct formatter<RawObs>
342 : tula::fmt_utils::nullspec_formatter_base {
343 template <typename FormatContext>
344 auto format(const RawObs &obs, FormatContext &ctx) const noexcept
345 -> decltype(ctx.out()) {
346 return format_to(ctx.out(), "RawObs(name={}, n_data_items={})",
347 obs.name(), obs.n_data_items());
348 }
349};
350
351template <>
352struct formatter<RawObs::DataItem>
353 : tula::fmt_utils::nullspec_formatter_base {
354 template <typename FormatContext>
355 auto format(const RawObs::DataItem &item, FormatContext &ctx) const noexcept
356 -> decltype(ctx.out()) {
357 return format_to(ctx.out(), "DataItem(interface={}, filepath={})",
358 item.interface(), item.filepath());
359 }
360};
361
362template <>
363struct formatter<RawObs::CalItem>
364 : tula::fmt_utils::nullspec_formatter_base {
365 template <typename FormatContext>
366 auto format(const RawObs::CalItem &item, FormatContext &ctx) const noexcept
367 -> decltype(ctx.out()) {
368 return format_to(ctx.out(), "CalItem(typestr={})",
369 item.typestr());
370 }
371};
372
373template <>
374struct formatter<RawObs::ArrayPropTable>
375 : tula::fmt_utils::nullspec_formatter_base {
376 template <typename FormatContext>
377 auto format(const RawObs::ArrayPropTable &apt, FormatContext &ctx) const noexcept
378 -> decltype(ctx.out()) {
379 return format_to(ctx.out(), "ArrayPropTable(filepath={})",
380 apt.filepath());
381 }
382};
383
384} // namespace fmt
385
386// collect data items impl
388 m_data_items.clear();
389 std::vector<DataItem> data_items{};
390 auto node_data_items = this->config().get_node("data_items");
391 auto n_data_items = node_data_items.size();
392 for (std::size_t i = 0; i < n_data_items; ++i) {
393 SPDLOG_INFO("add data item {} of {}", i, n_data_items);
394 data_items.emplace_back(
395 config_t{node_data_items[i], this->config().filepath()});
396 }
397 m_data_items = std::move(data_items);
398
399 sort(m_data_items.begin(), m_data_items.end(), [] (const RawObs::DataItem& a, const RawObs::DataItem& b) {
400
401 if ((a.interface().find("toltec"))!=std::string::npos && (b.interface().find("toltec"))!=std::string::npos) {
402 std::string cmp_a { a.interface().begin() + 6, a.interface().end() };
403 std::string cmp_b { b.interface().begin() + 6, b.interface().end() };
404 return std::stoi(cmp_a) < std::stoi(cmp_b);
405 }
406 else {
407 return false;
408 }
409 });
410
411 SPDLOG_DEBUG("collected n_data_items={}\n{}", this->n_data_items(),
412 this->data_items());
413 // update the data indices
414 m_kidsdata_indices.clear();
415 m_teldata_index.reset();
416 m_hwpdata_index.reset();
417 std::smatch m;
418 for (std::size_t i = 0; i < m_data_items.size(); ++i) {
419 if (std::regex_match(m_data_items[i].interface(), m,
420 re_interface_kidsdata)) {
421 m_kidsdata_indices.push_back(i);
422 }
423 if (std::regex_match(m_data_items[i].interface(), m,
424 re_interface_teldata)) {
425 if (m_teldata_index.has_value()) {
426 throw std::runtime_error("found too many telescope data items");
427 }
428 m_teldata_index = i;
429 }
430 if (std::regex_match(m_data_items[i].interface(), m,
431 re_interface_hwpdata)) {
432 if (m_hwpdata_index.has_value()) {
433 throw std::runtime_error(
434 "found too many halfwave plate data items");
435 }
436 m_hwpdata_index = i;
437 }
438 }
439 if (!m_teldata_index) {
440 throw std::runtime_error("no telescope data item found");
441 }
442 // The hwp data is optional
443 if (!m_hwpdata_index) {
444 SPDLOG_INFO("no hwp data item found");
445 }
446 SPDLOG_INFO("kidsdata_indices={} teldata_index={} hwpdata_index={}",
447 m_kidsdata_indices, m_teldata_index, m_hwpdata_index);
448 SPDLOG_INFO("kidsdata={} teldata={} hwpdata={}", kidsdata(), teldata(),
449 hwpdata());
450}
451
452// collect cal items impl
453
455 m_cal_items.clear();
456 std::vector<CalItem> cal_items{};
457 auto node_cal_items = this->config().get_node("cal_items");
458 auto n_cal_items = node_cal_items.size();
459 for (std::size_t i = 0; i < n_cal_items; ++i) {
460 cal_items.emplace_back(
461 config_t{node_cal_items[i], this->config().filepath()});
462 }
463 m_cal_items = std::move(cal_items);
464 SPDLOG_DEBUG("collected n_cal_items={}\n{}", this->n_cal_items(),
465 this->cal_items());
466 // update the data indices
467 m_apt_index.reset();
468 m_phot_cal_index.reset();
469 m_astro_cal_index.reset();
470 for (std::size_t i = 0; i < m_cal_items.size(); ++i) {
471 if (m_cal_items[i].is_type<CalItemType::array_prop_table>()) {
472 if (m_apt_index.has_value()) {
473 throw std::runtime_error("found too many array prop tables");
474 }
475 m_apt_index = i;
476 }
477 if (m_cal_items[i].is_type<CalItemType::photometry>()) {
478 if (m_phot_cal_index.has_value()) {
479 throw std::runtime_error("found too many photometry calib info.");
480 }
482 }
483 if (m_cal_items[i].is_type<CalItemType::astrometry>()) {
484 if (m_astro_cal_index.has_value()) {
485 throw std::runtime_error("found too many astrometry calib info.");
486 }
488 }
489 }
490 if (!m_apt_index) {
491 throw std::runtime_error("no array prop table found");
492 }
493 SPDLOG_INFO("apt_index={}", m_apt_index);
494 SPDLOG_INFO("apt={}", array_prop_table());
495}
502struct SeqIOCoordinator : ConfigMapper<SeqIOCoordinator> {
508
509 SeqIOCoordinator(config_t config) : Base{std::move(config)} {
511 }
512
513 // io_buffer
515
516 auto n_inputs() const { return m_inputs.size(); }
517
518 const std::vector<input_t> &inputs() const { return m_inputs; };
519
520 static auto check_config(const config_t &config)
521 -> std::optional<std::string> {
522 if (config.has_list("inputs")) {
523 return std::nullopt;
524 }
525 return fmt::format("invalid or missing key \"inputs\"");
526 }
527 friend std::ostream &operator<<(std::ostream &os,
528 const SeqIOCoordinator &co) {
529 return os << fmt::format("SeqIOCoordinator(n_inputs={})",
530 co.n_inputs());
531 }
532
533private:
534 std::vector<input_t> m_inputs{}; // stores all the inputs
535
536 // collect input data
538 m_inputs.clear();
539 std::vector<input_t> inputs;
540 auto node_inputs = this->config().get_node("inputs");
541 auto n_inputs = node_inputs.size();
542 for (std::size_t i = 0; i < n_inputs; ++i) {
543 SPDLOG_INFO("add input {} of {}", i, n_inputs);
544 inputs.emplace_back(
545 config_t{node_inputs[i], this->config().filepath()});
546 }
547 m_inputs = std::move(inputs);
548
549 SPDLOG_DEBUG("collected n_inputs={}\n{}", this->n_inputs(),
550 this->inputs());
551 }
552};
tula::config::ConfigValidatorMixin< Derived, tula::config::YamlConfig > ConfigMapper
Definition io.h:43
TULA_ENUM_REGISTER(RawObs::CalItemType)
config::ConfigValidatorMixin< Derived, config::YamlConfig > ConfigMapper
Definition main_old.cpp:124
Definition io.h:328
Definition io.h:17
std::ptrdiff_t index_t
This namespace contains global settings for common types and constants.
Definition io.h:26
double data_t
Definition io.h:28
Eigen::Matrix< index_t, 2, 1 > shape_t
Definition io.h:27
Definition timestream.h:59
Definition io.h:120
ArrayPropTable(config_t config)
Definition io.h:122
std::string m_filepath
Definition io.h:141
const std::string & filepath() const
Definition io.h:138
static auto check_config(config_t &config) -> std::optional< std::string >
Definition io.h:126
ConfigMapper< ArrayPropTable > Base
Definition io.h:121
Definition io.h:165
static auto check_config(config_t &config) -> std::optional< std::string >
Definition io.h:169
ConfigMapper< AstrometryCalibInfo > Base
Definition io.h:166
friend auto operator<<(OStream &os, const AstrometryCalibInfo &d) -> decltype(auto)
Definition io.h:180
AstrometryCalibInfo(config_t config)
Definition io.h:167
@breif a generic cal item holder
Definition io.h:187
void resolve()
Definition io.h:230
auto type() const
Definition io.h:209
auto is_type() -> bool
Definition io.h:218
ConfigMapper< CalItem > Base
Definition io.h:188
CalItem(config_t config)
Definition io.h:189
cal_item_var_t m_cal_item
Definition io.h:229
std::string m_typestr
Definition io.h:228
static auto check_config(config_t &config) -> std::optional< std::string >
Definition io.h:195
auto get() const -> const auto &
Definition io.h:223
const std::string & typestr() const
Definition io.h:207
The DataItem struct This represent a single data item that belongs to a particular observation.
Definition io.h:58
ConfigMapper< DataItem > Base
Definition io.h:59
std::string m_filepath
Definition io.h:85
const std::string & interface() const
Definition io.h:80
const std::string & filepath() const
Definition io.h:81
static auto check_config(config_t &config) -> std::optional< std::string >
Definition io.h:65
std::string m_interface
Definition io.h:84
DataItem(config_t config)
Definition io.h:60
Definition io.h:144
friend auto operator<<(OStream &os, const PhotometryCalibInfo &d) -> decltype(auto)
Definition io.h:159
ConfigMapper< PhotometryCalibInfo > Base
Definition io.h:145
static auto check_config(config_t &config) -> std::optional< std::string >
Definition io.h:148
PhotometryCalibInfo(config_t config)
Definition io.h:146
The raw obs struct This represents a single observation that contains a set of data items and calibra...
Definition io.h:50
ConfigMapper< RawObs > Base
Definition io.h:51
std::variant< std::monostate, cal_item_t< CalItemType::array_prop_table >, cal_item_t< CalItemType::photometry >, cal_item_t< CalItemType::astrometry > > cal_item_var_t
Definition io.h:118
std::optional< DataItem > hwpdata() const
Definition io.h:275
const AstrometryCalibInfo & astrometry_calib_info() const
Definition io.h:301
RawObs(config_t config)
Definition io.h:244
static const std::regex re_interface_kidsdata
Definition io.h:307
auto n_data_items() const
Definition io.h:270
const std::string & name() const
Definition io.h:269
void collect_data_items()
Definition io.h:387
const std::vector< CalItem > & cal_items() const
Definition io.h:292
const ArrayPropTable & array_prop_table() const
Definition io.h:293
tula::meta::switch_t< type, tula::meta::case_t< CalItemType::array_prop_table, ArrayPropTable >, tula::meta::case_t< CalItemType::photometry, PhotometryCalibInfo >, tula::meta::case_t< CalItemType::astrometry, AstrometryCalibInfo >, tula::meta::case_t< CalItemType::unresolved, CalItem > > cal_item_t
Definition io.h:111
std::vector< std::size_t > m_kidsdata_indices
Definition io.h:313
auto kidsdata() const -> decltype(auto)
Definition io.h:283
void collect_cal_items()
Definition io.h:454
std::optional< std::size_t > m_astro_cal_index
Definition io.h:321
const DataItem & teldata() const
Definition io.h:272
std::string m_name
Definition io.h:311
static auto check_config(const config_t &config) -> std::optional< std::string >
Definition io.h:251
TULA_ENUM_DECL(CalItemType, int, array_prop_table, photometry, astrometry, unresolved)
static const std::regex re_interface_teldata
Definition io.h:308
tula::meta::cases< CalItemType::array_prop_table, CalItemType::photometry, CalItemType::astrometry, CalItemType::unresolved > CalItemTypes
Definition io.h:99
std::vector< DataItem > m_data_items
Definition io.h:312
std::optional< std::size_t > m_apt_index
Definition io.h:319
auto n_cal_items() const
Definition io.h:291
std::optional< std::size_t > m_hwpdata_index
Definition io.h:315
const PhotometryCalibInfo & photometry_calib_info() const
Definition io.h:297
std::optional< std::size_t > m_phot_cal_index
Definition io.h:320
static const std::regex re_interface_hwpdata
Definition io.h:309
std::optional< std::size_t > m_teldata_index
Definition io.h:314
const std::vector< DataItem > & data_items() const
Definition io.h:271
std::vector< CalItem > m_cal_items
Definition io.h:318
The Coordinator struct This wraps around the config object and provides high level methods in various...
Definition io.h:502
auto n_inputs() const
Definition io.h:516
std::vector< input_t > m_inputs
Definition io.h:534
predefs::data_t payloads_buffer_data_t
Definition io.h:514
static auto check_config(const config_t &config) -> std::optional< std::string >
Definition io.h:520
const std::vector< input_t > & inputs() const
Definition io.h:518
ConfigMapper< SeqIOCoordinator > Base
Definition io.h:503
predefs::shape_t shape_t
Definition io.h:505
predefs::index_t index_t
Definition io.h:504
void collect_inputs()
Definition io.h:537
friend std::ostream & operator<<(std::ostream &os, const SeqIOCoordinator &co)
Definition io.h:527
SeqIOCoordinator(config_t config)
Definition io.h:509
auto format(const RawObs &obs, FormatContext &ctx) const noexcept -> decltype(ctx.out())
Definition io.h:344
auto format(const RawObs::ArrayPropTable &apt, FormatContext &ctx) const noexcept -> decltype(ctx.out())
Definition io.h:377
auto format(const RawObs::CalItem &item, FormatContext &ctx) const noexcept -> decltype(ctx.out())
Definition io.h:366
auto format(const RawObs::DataItem &item, FormatContext &ctx) const noexcept -> decltype(ctx.out())
Definition io.h:355
auto format(const std::reference_wrapper< T > &ref, FormatContext &ctx) const noexcept -> decltype(ctx.out())
Definition io.h:334
TC data class.
Definition timestream.h:55