Citlali
Loading...
Searching...
No Matches
kidsproc.h
Go to the documentation of this file.
1#pragma once
2
3#include <kids/core/kidsdata.h>
4#include <kids/sweep/fitter.h>
5#include <kids/timestream/solver.h>
6#include <kids/toltec/toltec.h>
7#include <kidscpp_config/gitversion.h>
8
9#include <tula/datatable.h>
10
12
18bool extra_output = 0;
19struct KidsDataProc : ConfigMapper<KidsDataProc> {
21 using Fitter = kids::SweepFitter;
22 using Solver = kids::TimeStreamSolver;
23
24 // get logger
25 std::shared_ptr<spdlog::logger> logger = spdlog::get("citlali_logger");
26
27 KidsDataProc(config_t config)
28 : Base{std::move(config)},
30 {"weight_window_type", this->config().get_str(std::tuple{
31 "fitter", "weight_window", "type"})},
32 {"weight_window_fwhm", this->config().get_typed<double>(
33 std::tuple{"fitter", "weight_window", "fwhm_Hz"})},
34 {"modelspec", config.get_str(std::tuple{"fitter", "modelspec"})}}},
35 m_solver{Solver::Config{
36 {"fitreportdir", this->config().get_str(std::tuple{"solver", "fitreportdir"})},
37 {"exmode", this->config().get_str(std::tuple{"solver", "parallel_policy"})},
38 {"extra_output", extra_output},
39 }} {}
40
41 static auto check_config(const config_t &config)
42 -> std::optional<std::string> {
43 // get logger
44 std::shared_ptr<spdlog::logger> logger = spdlog::get("citlali_logger");
45
46 std::vector<std::string> missing_keys;
47 logger->debug("check kids data proc config\n{}", config);
48 if (!config.has("fitter")) {
49 missing_keys.push_back("fitter");
50 }
51 if (!config.has("solver")) {
52 missing_keys.push_back("solver");
53 }
54 if (missing_keys.empty()) {
55 return std::nullopt;
56 }
57 return fmt::format("invalid or missing keys={}", missing_keys);
58 }
59
60 // get data item meta data
61 auto get_data_item_meta(const RawObs::DataItem &);
62
63 // get meta data from rawobs
64 std::vector<kids::KidsData<>::meta_t> get_rawobs_meta(const RawObs &);
65
66 // populate rtc meta data
67 auto populate_rtc_meta(const RawObs &);
68
69 // reduce data item
70 auto reduce_data_item(const RawObs::DataItem &,
71 const tula::container_utils::Slice<int> &);
72 // reduce rawobs
73 auto reduce_rawobs(const RawObs &rawobs,
74 const tula::container_utils::Slice<int> &);
75 // load data item
76 auto load_data_item(const RawObs::DataItem &,
77 const tula::container_utils::Slice<int> &);
78 // load kids fit report
79 auto load_fit_report(const RawObs &);
80
81 // load rawobs
82 template <typename Derived>
83 auto load_rawobs(const RawObs &, const Eigen::Index,
84 Eigen::DenseBase<Derived> &,
85 std::vector<Eigen::Index> &,
86 std::vector<Eigen::Index> &);
87
88 // populate rtc
89 template <typename loaded_t>
90 auto populate_rtc(loaded_t &, const int, const int,
91 const std::string);
92
93 // TODO fix the const correctness
94 Fitter &fitter() { return m_fitter; }
95 Solver &solver() { return m_solver; }
96
97 const Fitter &fitter() const { return m_fitter; }
98 const Solver &solver() const { return m_solver; }
99
100 template <typename OStream>
101 friend OStream &operator<<(OStream &os, const KidsDataProc &kidsproc) {
102 return os << fmt::format("KidsDataProc(fitter={}, solver={})",
103 kidsproc.fitter().config.pformat(),
104 kidsproc.solver().config.pformat());
105 }
106
107private:
108 // fitter and solver
111};
112
114 namespace kidsdata = predefs::kidsdata;
115 auto source = data_item.filepath();
116 auto [kind, meta] = kidsdata::get_meta<>(source);
117 return meta;
118}
119
120std::vector<kids::KidsData<>::meta_t> KidsDataProc::get_rawobs_meta(const RawObs &rawobs) {
121 std::vector<kids::KidsData<>::meta_t> result;
122 for (const auto &data_item : rawobs.kidsdata()) {
123 result.push_back(get_data_item_meta(data_item));
124 }
125 return result;
126}
127
129 std::vector<kids::KidsData<>::meta_t> result;
130 for (const auto &data_item : rawobs.kidsdata()) {
131 result.push_back(get_data_item_meta(data_item));
132 }
133 return result;
134}
135
137 const tula::container_utils::Slice<int> &slice) {
138 logger->debug("kids reduce data_item {}", data_item);
139 // read data
140 namespace kidsdata = predefs::kidsdata;
141 auto source = data_item.filepath();
142 auto [kind, meta] = kidsdata::get_meta<>(source);
143 if (!(kind & kids::KidsDataKind::TimeStream)) {
144 throw std::runtime_error(
145 fmt::format("wrong type of kids data {}", kind));
146 }
147 auto rts = kidsdata::read_data_slice<kids::KidsDataKind::RawTimeStream>(
148 source, slice);
149 auto result = this->solver()(rts, Solver::Config{});
150 return result;
151}
152
154 const tula::container_utils::Slice<int> &slice) {
155 logger->debug("kids reduce rawobs {}", rawobs);
156 std::vector<kids::TimeStreamSolverResult> result;
157 for (const auto &data_item : rawobs.kidsdata()) {
158 result.push_back(reduce_data_item(data_item, slice));
159 }
160 return result;
161}
162
164 const tula::container_utils::Slice<int> &slice) {
165 logger->debug("kids reduce data_item {}", data_item);
166 // read data
167 namespace kidsdata = predefs::kidsdata;
168 auto source = data_item.filepath();
169 auto [kind, meta] = kidsdata::get_meta<>(source);
170 if (!(kind & kids::KidsDataKind::TimeStream)) {
171 throw std::runtime_error(
172 fmt::format("wrong type of kids data {}", kind));
173 }
174 auto rts = kidsdata::read_data_slice<kids::KidsDataKind::RawTimeStream>(
175 source, slice);
176 return rts;
177}
178
180 std::vector<Eigen::MatrixXd> kids_models;
181 std::vector<std::string> header;
182
183 for (const auto &data_item : rawobs.kidsdata()) {
184 auto meta = get_data_item_meta(data_item);
185 //auto fitreport = this->solver().loadfitreport(this->config(),meta);
186
187 namespace fs = std::filesystem;
188 auto pattern = meta.get_str("cal_file");
189 std::string filepath{};
190 if (this->solver().config.has("fitreportfile")) {
191 filepath = this->solver().config.get_str("fitreportfile");
192 } else if (this->solver().config.has("fitreportdir")) {
193 auto dir = this->solver().config.get_str("fitreportdir");
194 logger->info("look for fitreport dir {} with pattern {}", dir, pattern);
195 auto candidates = tula::filename_utils::find_regex(dir, pattern);
196 if (!candidates.empty()) {
197 filepath = candidates[0];
198 } else {
199 throw std::runtime_error(fmt::format(
200 "no fit report found in {} that matches {}", dir, pattern));
201 }
202 } else {
203 throw std::runtime_error(
204 fmt::format("no fit report location specified."));
205 }
206 logger->info("use fitreport file {}", filepath);
207 //std::vector<std::string> header;
208 header.clear();
209 Eigen::MatrixXd table;
210 using meta_t = kids::KidsData<>::meta_t;
211 meta_t meta_cal{};
212
213 try {
214 YAML::Node meta_;
215 table = datatable::read<double, datatable::Format::ecsv>(
216 filepath, &header, &meta_);
217 auto meta_map =
218 tula::ecsv::meta_to_map<typename meta_t::storage_t::key_type,
219 typename meta_t::storage_t::mapped_type>(
220 meta_, &meta_);
221 meta_cal = meta_t{std::move(meta_map)};
222
223 kids_models.push_back(std::move(table));
224 if (!meta_.IsNull()) {
225 logger->warn("un recongnized meta:\n{}", YAML::Dump(meta_));
226 }
227 } catch (datatable::ParseError &e) {
228 logger->warn("unable to read fitreport file as ECSV {}: {}", filepath,
229 e.what());
230 try {
231 table = datatable::read<double, datatable::Format::ascii>(filepath,
232 &header);
233 kids_models.push_back(std::move(table));
234
235 } catch (datatable::ParseError &e) {
236 logger->warn("unable to read fitreport file as ASCII {}: {}",
237 filepath, e.what());
238 throw e;
239 }
240 }
241 logger->info("meta_cal: {}", meta_cal.pformat());
242 logger->info("table {}",table);
243 logger->info("header {}",header);
244
245 //return std::tuple{
246 // kids::ToneAxis(std::move(table).transpose(), std::move(header)),
247 // std::move(meta_cal)};
248 }
249
250 return std::tuple{std::move(kids_models), std::move(header)};
251}
252
253template <typename Derived>
254auto KidsDataProc::load_rawobs(const RawObs &rawobs, const Eigen::Index scan,
255 Eigen::DenseBase<Derived> &scan_indices,
256 std::vector<Eigen::Index> &start_indices,
257 std::vector<Eigen::Index> &end_indices) {
258
259 std::vector<kids::KidsData<kids::KidsDataKind::RawTimeStream>> result;
260 Eigen::Index i = 0;
261 for (const auto &data_item : rawobs.kidsdata()) {
262 // get slice of data for current scan
263 auto slice = tula::container_utils::Slice<int>{scan_indices(2,scan) + start_indices[i],
264 scan_indices(3,scan) + 1 + start_indices[i],
265 std::nullopt};
266 result.push_back(load_data_item(data_item, slice));
267
268 i++;
269 }
270
271 return result;
272}
273
274template <typename loaded_t>
275auto KidsDataProc::populate_rtc(loaded_t &loaded,
276 const int n_pts, const int n_det,
277 const std::string data_type) {
278 // resize data
279 Eigen::MatrixXd data(n_pts, n_det);
280
281 Eigen::Index i = 0;
282 // loop through raw timestream objects
283 for (std::vector<kids::KidsData<kids::KidsDataKind::RawTimeStream>>::
284 iterator it = loaded.begin(); it != loaded.end(); ++it) {
285 // run the solver
286 auto result = this->solver()(*it, Solver::Config{});
287 // get number of rows
288 Eigen::Index n_rows = result.data_out.xs.data.rows();
289 // get number of cols
290 Eigen::Index n_cols = result.data_out.xs.data.cols();
291
292 // get xs
293 if (data_type == "xs") {
294 data.block(0, i, n_rows, n_cols) = result.data_out.xs.data;
295 }
296 // get rs
297 else if (data_type == "rs") {
298 data.block(0, i, n_rows, n_cols) = result.data_out.rs.data;
299 }
300 // get is
301 else if (data_type == "is") {
302 data.block(0, i, n_rows, n_cols) = result.data.is.data;
303 }
304 // get qs
305 else if (data_type == "qs") {
306 data.block(0, i, n_rows, n_cols) = result.data.qs.data;
307 }
308 // increment columns
309 i += n_cols;
310 }
311
312 // check for nans
313 if ((data.array().isNaN()).any()) {
314 logger->error("nan found in data! Check that your KIDs data dir is correct.");
315 std::exit(EXIT_FAILURE);
316 }
317 // check for infs
318 if ((data.array().isInf()).any()) {
319 logger->error("inf found in data! Check that your KIDs data dir is correct.");
320 std::exit(EXIT_FAILURE);
321 }
322
323 return data;
324}
config::Config Config
Definition kids_main.cpp:17
bool extra_output
The KIDs data solver struct This wraps around the kids config.
Definition kidsproc.h:18
config::ConfigValidatorMixin< Derived, config::YamlConfig > ConfigMapper
Definition main_old.cpp:124
Definition timestream.h:59
Definition kidsproc.h:19
Solver & solver()
Definition kidsproc.h:95
auto reduce_rawobs(const RawObs &rawobs, const tula::container_utils::Slice< int > &)
Definition kidsproc.h:153
Solver m_solver
Definition kidsproc.h:110
const Solver & solver() const
Definition kidsproc.h:98
Fitter & fitter()
Definition kidsproc.h:94
static auto check_config(const config_t &config) -> std::optional< std::string >
Definition kidsproc.h:41
auto get_data_item_meta(const RawObs::DataItem &)
Definition kidsproc.h:113
auto load_fit_report(const RawObs &)
Definition kidsproc.h:179
auto populate_rtc_meta(const RawObs &)
Definition kidsproc.h:128
friend OStream & operator<<(OStream &os, const KidsDataProc &kidsproc)
Definition kidsproc.h:101
std::shared_ptr< spdlog::logger > logger
Definition kidsproc.h:25
kids::SweepFitter Fitter
Definition kidsproc.h:21
auto reduce_data_item(const RawObs::DataItem &, const tula::container_utils::Slice< int > &)
Definition kidsproc.h:136
ConfigMapper< KidsDataProc > Base
Definition kidsproc.h:20
std::vector< kids::KidsData<>::meta_t > get_rawobs_meta(const RawObs &)
Definition kidsproc.h:120
auto load_data_item(const RawObs::DataItem &, const tula::container_utils::Slice< int > &)
Definition kidsproc.h:163
auto load_rawobs(const RawObs &, const Eigen::Index, Eigen::DenseBase< Derived > &, std::vector< Eigen::Index > &, std::vector< Eigen::Index > &)
Definition kidsproc.h:254
KidsDataProc(config_t config)
Definition kidsproc.h:27
const Fitter & fitter() const
Definition kidsproc.h:97
auto populate_rtc(loaded_t &, const int, const int, const std::string)
Definition kidsproc.h:275
kids::TimeStreamSolver Solver
Definition kidsproc.h:22
Fitter m_fitter
Definition kidsproc.h:109
The DataItem struct This represent a single data item that belongs to a particular observation.
Definition io.h:58
const std::string & filepath() const
Definition io.h:81
The raw obs struct This represents a single observation that contains a set of data items and calibra...
Definition io.h:50
auto kidsdata() const -> decltype(auto)
Definition io.h:283