Citlali
Loading...
Searching...
No Matches
ptcproc.h
Go to the documentation of this file.
1#pragma once
2
3#include <tula/logging.h>
4#include <tula/nc.h>
5#include <tula/algorithm/ei_stats.h>
6
9
12
14
15namespace timestream {
16
18
19class PTCProc: public TCProc {
20public:
21 // controls for timestream reduction
23 // median weight factor
25 // upper and lower weight limits for outliers
27 // weight type (full, approximate, const)
28 std::string weighting_type;
29
30 // ptc tod proc
32
33 // get config file
34 template <typename config_t>
35 void get_config(config_t &, std::vector<std::vector<std::string>> &,
36 std::vector<std::vector<std::string>> &);
37
38 // subtract detector means
40
41 // run main processing stage
42 template <class calib_type>
44 calib_type &, std::string, std::string);
45
46 // calculate detector weights
47 template <typename apt_type, class tel_type>
48 void calc_weights(TCData<TCDataKind::PTC, Eigen::MatrixXd> &, apt_type &, tel_type &);
49
50 // reset outlier weights to the median
51 template <typename calib_t>
52 auto reset_weights(TCData<TCDataKind::PTC, Eigen::MatrixXd> &, calib_t &, std::string);
53
54 // append time chunk to tod netcdf file
55 template <typename calib_t, typename pointing_offset_t>
56 void append_to_netcdf(TCData<TCDataKind::PTC, Eigen::MatrixXd> &, std::string, std::string, std::string &,
57 pointing_offset_t &, calib_t &);
58};
59
60// get config file
61template <typename config_t>
62void PTCProc::get_config(config_t &config, std::vector<std::vector<std::string>> &missing_keys,
63 std::vector<std::vector<std::string>> &invalid_keys) {
64
65 // weight type
66 get_config_value(config, weighting_type, missing_keys, invalid_keys,
67 std::tuple{"timestream","processed_time_chunk","weighting","type"},{"full","approximate","const"});
68 // median weight factor
69 get_config_value(config, med_weight_factor, missing_keys, invalid_keys,
70 std::tuple{"timestream","processed_time_chunk","weighting","median_map_weight_factor"});
71 // lower inv var factor
72 get_config_value(config, lower_inv_var_factor, missing_keys, invalid_keys,
73 std::tuple{"timestream","processed_time_chunk","flagging","lower_tod_inv_var_factor"});
74 // upper inv var factor
75 get_config_value(config, upper_inv_var_factor, missing_keys, invalid_keys,
76 std::tuple{"timestream","processed_time_chunk","flagging","upper_tod_inv_var_factor"});
77
78 // lower weight factor
79 get_config_value(config, lower_weight_factor, missing_keys, invalid_keys,
80 std::tuple{"timestream","processed_time_chunk","weighting","lower_map_weight_factor"});
81 // upper weight factor
82 get_config_value(config, upper_weight_factor, missing_keys, invalid_keys,
83 std::tuple{"timestream","processed_time_chunk","weighting","upper_map_weight_factor"});
84
85 // run fruit loops?
86 get_config_value(config, run_fruit_loops, missing_keys, invalid_keys,
87 std::tuple{"timestream","fruit_loops","enabled"});
88
89 if (run_fruit_loops) {
90 // save all fruit loops iterations?
91 get_config_value(config, save_all_iters, missing_keys, invalid_keys,
92 std::tuple{"timestream","fruit_loops","save_all_iters"});
93 // fruit looops path
94 get_config_value(config, fruit_loops_path, missing_keys, invalid_keys,
95 std::tuple{"timestream","fruit_loops","path"});
96 // fruit looops type
97 get_config_value(config, fruit_loops_type, missing_keys, invalid_keys,
98 std::tuple{"timestream","fruit_loops","type"});
99 // fruit looops mode
100 get_config_value(config, fruit_mode, missing_keys, invalid_keys,
101 std::tuple{"timestream","fruit_loops","mode"}, {"upper", "lower", "both"});
102 // let user specify "coadd" or "coadded"
103 if (fruit_loops_type == "coadded") {
104 fruit_loops_type = "coadd";
105 }
106 // fruit loops signal-to-noise
107 get_config_value(config, fruit_loops_sig2noise, missing_keys, invalid_keys,
108 std::tuple{"timestream","fruit_loops", "sig2noise_limit"});
109 // fruit loops flux density limit
110 auto fruit_loops_flux_vec = config.template get_typed<std::vector<double>>(std::tuple{"timestream","fruit_loops","array_flux_limit"});
111 fruit_loops_flux = Eigen::Map<Eigen::VectorXd>(fruit_loops_flux_vec.data(), fruit_loops_flux_vec.size());
112
113 // maximum fruit loops iterations
114 get_config_value(config, fruit_loops_iters, missing_keys, invalid_keys,
115 std::tuple{"timestream","fruit_loops","max_iters"});
116 }
117
118 // run clean?
119 get_config_value(config, run_clean, missing_keys, invalid_keys,
120 std::tuple{"timestream","processed_time_chunk","clean", "enabled"});
121
122 if (run_clean) {
123 // get cleaning grouping vector
124 cleaner.grouping = config.template get_typed<std::vector<std::string>>(std::tuple{"timestream","processed_time_chunk","clean","grouping"});
125 // get cleaning number of eigenvalues vector
126 for (auto const& [arr_index, arr_name] : toltec_io.array_name_map) {
127 auto n_eig_to_cut = config.template get_typed<std::vector<Eigen::Index>>(std::tuple{"timestream","processed_time_chunk","clean",
128 "n_eig_to_cut",arr_name});
129 // add eigenvalues to cleaner class
130 cleaner.n_eig_to_cut[arr_index] = (Eigen::Map<Eigen::VectorXI>(n_eig_to_cut.data(),n_eig_to_cut.size()));
131 }
132
133 // stddev limit
134 get_config_value(config, cleaner.stddev_limit, missing_keys, invalid_keys,
135 std::tuple{"timestream","processed_time_chunk","clean","stddev_limit"});
136 // mask radius in arcseconds
137 get_config_value(config, mask_radius_arcsec, missing_keys, invalid_keys,
138 std::tuple{"timestream","processed_time_chunk","clean","mask_radius_arcsec"});
139
140 // upper weight factor
141 get_config_value(config, cleaner.tau, missing_keys, invalid_keys,
142 std::tuple{"timestream","processed_time_chunk","clean","tau"});
143 }
144}
145
147 // cast flags to double and flip 1's and 0's so we can multiply by the data
148 auto f = (in.flags.data.derived().array().cast <double> ().array() - 1).abs();
149 // mean of each detector
150 Eigen::RowVectorXd col_mean = (in.scans.data.derived().array()*f).colwise().sum()/
151 f.colwise().sum();
152
153 // remove nans from completely flagged detectors
154 Eigen::RowVectorXd dm = (col_mean).array().isNaN().select(0,col_mean);
155
156 // subtract mean from data and copy into det matrix
157 in.scans.data.noalias() = in.scans.data.derived().rowwise() - dm;
158
159 // subtract kernel mean
160 if (in.kernel.data.size()!=0) {
161 Eigen::RowVectorXd col_mean = (in.kernel.data.derived().array()*f).colwise().sum()/
162 f.colwise().sum();
163
164 // remove nans from completely flagged detectors
165 Eigen::RowVectorXd dm = (col_mean).array().isNaN().select(0,col_mean);
166
167 // subtract mean from data and copy into det matrix
168 in.kernel.data.noalias() = in.kernel.data.derived().rowwise() - dm;
169 }
170}
171
172template <class calib_type>
174 calib_type &calib, std::string pixel_axes, std::string map_grouping) {
175
176 // subtract mean from data and kernel
177 subtract_mean(in);
178
179 if (run_clean) {
180 logger->info("cleaning");
181 // number of samples
182 Eigen::Index n_pts = in.scans.data.rows();
183 // index for number of cleaning groups in vectors
184 Eigen::Index indx = 0;
185
186 // loop through config groupings
187 for (const auto & group: cleaner.grouping) {
188
189 logger->debug("cleaning with {} grouping", group);
190
192 // add current group to eval/evec vectors
193 out.evals.data.emplace_back();
194 out.evecs.data.emplace_back();
195 }
196
197 // map of tuples to hold detector limits
198 std::map<Eigen::Index, std::tuple<Eigen::Index, Eigen::Index>> grp_limits;
199
200 // use all detectors for cleaning
201 if (group == "all") {
202 grp_limits[0] = std::make_tuple(0,in.scans.data.cols());
203 }
204 else {
205 // get group limits
206 grp_limits = get_grouping(group, calib, in.scans.data.cols());
207 }
208 // loop through cleaning groups
209 for (auto const& [key, val] : grp_limits) {
210 Eigen::Index arr_index;
211 // use all detectors
212 if (group=="all") {
213 arr_index = calib.arrays(0);
214 }
215 // use network grouping
216 else if (group=="nw" || group=="network") {
217 arr_index = toltec_io.nw_to_array_map[key];
218 }
219 // use array grouping
220 else if (group=="array") {
221 arr_index = key;
222 }
223
224 // start index and number of detectors
225 auto [start_index, n_dets] = std::make_tuple(std::get<0>(val), std::get<1>(val) - std::get<0>(val));
226
227 // matrix for flags so we don't overwrite the raw flags
228 Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> masked_flags;
229
230 // mask region if radius is >0
231 if (mask_radius_arcsec > 0) {
232 // samples that were masked will be flagged
233 masked_flags = mask_region(in, calib, pixel_axes, map_grouping, n_pts, n_dets, start_index);
234 }
235 // otherwise just use input flags
236 else {
237 masked_flags = in.flags.data.block(0, start_index, n_pts, n_dets);
238 }
239
240 auto in_scans_block = in.scans.data.block(0, start_index, n_pts, n_dets);
241 auto out_scans_block = out.scans.data.block(0, start_index, n_pts, n_dets);
242
243 // get the block of out scans that corresponds to the current array
244 auto apt_flags = calib.apt["flag"].segment(start_index, n_dets);
245
246 // check if any good flags
247 if ((apt_flags.array()==0).any()) {
248 logger->info("cleaning {} {}", group, key);
249 // calculate eigenvalues and eigenvalues
250 auto [evals, evecs] = cleaner.calc_eig_values<timestream::Cleaner::SpectraBackend>(in_scans_block, masked_flags, apt_flags,
251 cleaner.n_eig_to_cut[arr_index](indx));
252
253
255 // get first 64 eigenvalues and eigenvectors
256 Eigen::VectorXd ev = evals.head(cleaner.n_calc);
257 Eigen::MatrixXd evc = evecs.leftCols(cleaner.n_calc);
258
259 logger->debug("evals {}", ev);
260 logger->debug("evecs {}", evc);
261
262 // copy evals and evecs to ptcdata
263 out.evals.data[indx].push_back(std::move(ev));
264 out.evecs.data[indx].push_back(std::move(evc));
265 }
266
267 // remove eigenvalues from the data and reconstruct the tod
268 cleaner.remove_eig_values<timestream::Cleaner::SpectraBackend>(in_scans_block, masked_flags, evals, evecs, out_scans_block,
269 cleaner.n_eig_to_cut[arr_index](indx));
270
271 if (in.kernel.data.size()!=0) {
272 // check if any good flags
273 logger->debug("cleaning kernel");
274 auto in_kernel_block = in.kernel.data.block(0, start_index, n_pts, n_dets);
275 auto out_kernel_block = in.kernel.data.block(0, start_index, n_pts, n_dets);
276
277 // remove eigenvalues from the kernel and reconstruct the tod
278 cleaner.remove_eig_values<timestream::Cleaner::SpectraBackend>(in_kernel_block, masked_flags, evals, evecs, out_kernel_block,
279 cleaner.n_eig_to_cut[arr_index](indx));
280 }
281 }
282 // otherwise just copy the data
283 else {
284 logger->debug("no good detectors found. skipping clean.");
285 // copy scans
286 out.scans.data.block(0, start_index, n_pts, n_dets) = in.scans.data.block(0, start_index, n_pts, n_dets);
287 // copy kernel
288 if (in.kernel.data.size()!=0) {
289 out.kernel.data.block(0, start_index, n_pts, n_dets) = in.kernel.data.block(0, start_index, n_pts, n_dets);
290 }
291 }
292 }
293 indx++;
294 // set as cleaned
295 out.status.cleaned = true;
296 }
297 }
298}
299
300template <typename apt_type, class tel_type>
301void PTCProc::calc_weights(TCData<TCDataKind::PTC, Eigen::MatrixXd> &in, apt_type &apt, tel_type &telescope) {
302 // number of detectors
303 Eigen::Index n_dets = in.scans.data.cols();
304
305 // resize weights to number of detectors
306 in.weights.data = Eigen::VectorXd::Zero(n_dets);
307
308 // approximate weighting
309 if (weighting_type == "approximate") {
310 logger->debug("calculating weights using detector sensitivities");
311 // unit conversion x flux calibration factor x 1/exp(-tau)
312 double conversion_factor;
313
314 // loop through detectors and calculate weights
315 for (Eigen::Index i=0; i<n_dets; ++i) {
316 // current detector index
317 Eigen::Index det_index = i;
318 // if flux calibrated, get flux conversion factor
319 if (in.status.calibrated) {
320 conversion_factor = in.fcf.data(i);
321 }
322 // otherwise fcf is unity
323 else {
324 conversion_factor = 1;
325 }
326 // make sure flux conversion is not zero (otherwise weight=0)
327 if (conversion_factor*apt["sens"](det_index)!=0) {
328 // calculate weights while applying flux calibration
329 in.weights.data(i) = pow(sqrt(telescope.d_fsmp)*apt["sens"](det_index)*conversion_factor,-2.0);
330 }
331 else {
332 in.weights.data(i) = 0;
333 }
334 }
335 }
336 // use full weighting
337 else if (weighting_type == "full"){
338 logger->debug("calculating weights using timestream variance");
339
340 // loop through detectors
341 for (Eigen::Index i=0; i<n_dets; ++i) {
342 // only calculate weights if detector is unflagged
343 if (apt["flag"](i)==0) {
344 // make Eigen::Maps for each detector's scan
345 Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, 1>> scans(
346 in.scans.data.col(i).data(), in.scans.data.rows());
347 Eigen::Map<Eigen::Matrix<bool, Eigen::Dynamic, 1>> flags(
348 in.flags.data.col(i).data(), in.flags.data.rows());
349
350 // unflagged detector stddev
351 double det_std_dev = engine_utils::calc_std_dev(scans, flags);
352 // if stddev is not zero
353 if (det_std_dev !=0) {
354 // weight = 1/(stddev)^2
355 in.weights.data(i) = pow(det_std_dev,-2);
356 }
357 // otherwise weight = 0 (not included in maps)
358 else {
359 in.weights.data(i) = 0;
360 }
361 }
362 // otherwise weight = 0 (not included in maps)
363 else {
364 in.weights.data(i) = 0;
365 }
366 }
367 }
368 // constant weighting
369 else if (weighting_type == "const") {
370 for (Eigen::Index i=0; i<n_dets; ++i) {
371 // only calculate weights if detector is unflagged
372 if (apt["flag"](i)==0) {
373 in.weights.data(i) = 1;
374 }
375 // otherwise set to zero
376 else {
377 in.weights.data(i) = 0;
378 }
379 }
380 }
381}
382
383template <typename calib_t>
384auto PTCProc::reset_weights(TCData<TCDataKind::PTC, Eigen::MatrixXd> &in, calib_t &calib, std::string map_grouping) {
385
386 // make a copy of the calib class for flagging
387 calib_t calib_scan = calib;
388
389 // only need to run if median weight factor >=1
391 // number of detectors
392 Eigen::Index n_dets = in.scans.data.cols();
393
394 // get group limits
395 auto grp_limits = get_grouping("array", calib, n_dets);
396
397 // collect detectors that are un-flagged and have non-zero weights
398 for (auto const& [key, val] : grp_limits) {
399 // weights for current group
400 auto grp_weights = in.weights.data(Eigen::seq(std::get<0>(grp_limits[key]),
401 std::get<1>(grp_limits[key])-1));
402 // number of good detectors
403 Eigen::Index n_good_dets = 0;
404 // start index of current group
405 Eigen::Index j = std::get<0>(grp_limits[key]);
406
407 // loop through detectors in current group
408 for (Eigen::Index m=0; m<grp_weights.size(); ++m) {
409 // if detector is good and weight is not zero
410 if (calib.apt["flag"](j)==0 && grp_weights(m)>0) {
411 n_good_dets++;
412 }
413 j++;
414 }
415
416 // to hold good detectors
417 Eigen::VectorXd good_wt;
418
419 // if good detectors were found
420 if (n_good_dets>0) {
421 good_wt.resize(n_good_dets);
422
423 // remove flagged dets
424 j = std::get<0>(grp_limits[key]);
425 Eigen::Index k = 0;
426 for (Eigen::Index m=0; m<grp_weights.size(); ++m) {
427 if (calib.apt["flag"](j)==0 && grp_weights(m)>0) {
428 good_wt(k) = grp_weights(m);
429 k++;
430 }
431 j++;
432 }
433 }
434 // otherwise just use all detectors
435 else {
436 good_wt = grp_weights;
437 }
438
439 // get median weight
440 auto med_wt = tula::alg::median(good_wt);
441 // store median weights
442 in.median_weights.data.push_back(med_wt);
443
444 int outliers = 0;
445 int n_dets_low = 0;
446 int n_dets_high = 0;
447
448 // start index of current group
449 j = std::get<0>(grp_limits[key]);
450 // loop through detectors in current group
451 for (Eigen::Index m=0; m<grp_weights.size(); ++m) {
452 // if detector weight is med_weight_factor times larger than med_wt
453 if (med_weight_factor >=1 && in.weights.data(j) > med_weight_factor*med_wt) {
454 // reset high weights to median
455 in.weights.data(j) = med_wt;
456 outliers++;
457 }
458
459 // only run if unflagged already
460 if (calib.apt["flag"](j)==0) {
461 // flag those below limit
462 if ((in.weights.data(j) < (lower_weight_factor*med_wt)) && lower_weight_factor!=0) {
463 if (map_grouping!="detector") {
464 in.flags.data.col(j).setOnes();
465 }
466 else {
467 calib_scan.apt["flag"](j) = 1;
468 }
469 in.n_dets_low++;
470 n_dets_low++;
471 }
472
473 // flag those above limit
474 if ((in.weights.data(j) > (upper_weight_factor*med_wt)) && upper_weight_factor!=0) {
475 if (map_grouping!="detector") {
476 in.flags.data.col(j).setOnes();
477 }
478 else {
479 calib_scan.apt["flag"](j) = 1;
480 }
481 in.n_dets_high++;
482 n_dets_high++;
483 }
484 }
485 j++;
486 }
487 logger->info("array {} had {} outlier weights", key, outliers);
488 logger->info("array {}: {}/{} dets below weight limit. {}/{} dets above weight limit.", key,
489 n_dets_low, n_good_dets, n_dets_high, n_good_dets);
490 }
491
492 // set up scan calib
493 calib_scan.setup();
494 }
495 return std::move(calib_scan);
496}
497
498template <typename calib_t, typename pointing_offset_t>
499void PTCProc::append_to_netcdf(TCData<TCDataKind::PTC, Eigen::MatrixXd> &in, std::string filepath, std::string map_grouping,
500 std::string &pixel_axes, pointing_offset_t &pointing_offsets_arcsec, calib_t &calib) {
501
502 using netCDF::NcDim;
503 using netCDF::NcFile;
504 using netCDF::NcType;
505 using netCDF::NcVar;
506 using namespace netCDF::exceptions;
507
508 try {
509 // open netcdf file
510 NcFile fo(filepath, netCDF::NcFile::write);
511
512 // append common time chunk variables
513 append_base_to_netcdf(fo, in, map_grouping, pixel_axes, pointing_offsets_arcsec, calib);
514
515 // get dimensions
516 NcDim n_dets_dim = fo.getDim("n_dets");
517
518 // number of detectors currently in file
519 unsigned long n_dets_exists = n_dets_dim.getSize();
520
521 // append weights
522 std::vector<std::size_t> start_index_weights = {static_cast<unsigned long>(in.index.data), 0};
523 std::vector<std::size_t> size_weights = {1, n_dets_exists};
524
525 // get weight variable
526 NcVar weights_v = fo.getVar("weights");
527
528 // add weights to tod output
529 weights_v.putVar(start_index_weights, size_weights, in.weights.data.data());
530
531 if (write_evals) {
532 // get number of eigenvalues to save
533 NcDim n_eigs_dim = fo.getDim("n_eigs");
534 netCDF::NcDim n_eig_grp_dim = fo.getDim("n_eig_grp");
535
536 // if eigenvalue dimension is null, add it
537 if (n_eig_grp_dim.isNull()) {
538 n_eig_grp_dim = fo.addDim("n_eig_grp",in.evals.data[0].size());
539 }
540
541 // dimensions for eigenvalue data
542 std::vector<netCDF::NcDim> eval_dims = {n_eig_grp_dim, n_eigs_dim};
543
544 // loop through cleaner gropuing
545 for (Eigen::Index i=0; i<in.evals.data.size(); ++i) {
546 NcVar eval_v = fo.addVar("evals_" + cleaner.grouping[i] + "_" + std::to_string(i) +
547 "_chunk_" + std::to_string(in.index.data), netCDF::ncDouble,eval_dims);
548 std::vector<std::size_t> start_eig_index = {0, 0};
549 std::vector<std::size_t> size = {1, TULA_SIZET(cleaner.n_calc)};
550
551 // loop through eigenvalues in current group
552 for (const auto &evals: in.evals.data[i]) {
553 eval_v.putVar(start_eig_index,size,evals.data());
554 start_eig_index[0] += 1;
555 }
556 }
557
558 // number of dimensions for eigenvectors
559 std::vector<netCDF::NcDim> eig_dims = {n_dets_dim, n_eigs_dim};
560
561 // loop through cleaner gropuing
562 for (Eigen::Index i=0; i<in.evecs.data.size(); ++i) {
563 // start at first row and col
564 std::vector<std::size_t> start_eig_index = {0, 0};
565
566 NcVar evec_v = fo.addVar("evecs_" + cleaner.grouping[i] + "_" + std::to_string(i) + "_chunk_" +
567 std::to_string(in.index.data),netCDF::ncDouble,eig_dims);
568
569 // loop through eigenvectors in current group
570 for (const auto &evecs: in.evecs.data[i]) {
571 std::vector<std::size_t> size = {TULA_SIZET(evecs.rows()), TULA_SIZET(cleaner.n_calc)};
572
573 // transpose eigenvectors
574 Eigen::MatrixXd ev = evecs.transpose();
575 evec_v.putVar(start_eig_index, size, ev.data());
576
577 // increment start
578 start_eig_index[0] += TULA_SIZET(evecs.rows());
579 }
580 }
581 }
582
583 // sync file to make sure it gets updated
584 fo.sync();
585 // close file
586 fo.close();
587 logger->info("tod chunk written to {}", filepath);
588
589 } catch (NcException &e) {
590 logger->error("{}", e.what());
591 }
592}
593
594} // namespace timestream
std::map< Eigen::Index, std::string > array_name_map
Definition toltec_io.h:54
std::map< Eigen::Index, Eigen::Index > nw_to_array_map
Definition toltec_io.h:37
Definition clean.h:12
double stddev_limit
Definition clean.h:24
auto remove_eig_values(const Eigen::DenseBase< DerivedA > &, const Eigen::DenseBase< DerivedB > &, const Eigen::DenseBase< DerivedC > &, const Eigen::DenseBase< DerivedD > &, Eigen::DenseBase< DerivedA > &, const Eigen::Index)
Definition clean.h:245
double tau
Definition clean.h:33
std::map< Eigen::Index, Eigen::VectorXI > n_eig_to_cut
Definition clean.h:27
int n_calc
Definition clean.h:30
auto calc_eig_values(const Eigen::DenseBase< DerivedA > &, const Eigen::DenseBase< DerivedB > &, Eigen::DenseBase< DerivedC > &, const Eigen::Index)
Definition clean.h:126
@ SpectraBackend
Definition clean.h:20
std::vector< std::string > grouping
Definition clean.h:36
Definition ptcproc.h:19
void get_config(config_t &, std::vector< std::vector< std::string > > &, std::vector< std::vector< std::string > > &)
Definition ptcproc.h:62
bool run_clean
Definition ptcproc.h:22
timestream::Cleaner cleaner
Definition ptcproc.h:31
double upper_weight_factor
Definition ptcproc.h:26
void append_to_netcdf(TCData< TCDataKind::PTC, Eigen::MatrixXd > &, std::string, std::string, std::string &, pointing_offset_t &, calib_t &)
Definition ptcproc.h:499
void calc_weights(TCData< TCDataKind::PTC, Eigen::MatrixXd > &, apt_type &, tel_type &)
Definition ptcproc.h:301
void run(TCData< TCDataKind::PTC, Eigen::MatrixXd > &, TCData< TCDataKind::PTC, Eigen::MatrixXd > &, calib_type &, std::string, std::string)
Definition ptcproc.h:173
double lower_weight_factor
Definition ptcproc.h:26
auto reset_weights(TCData< TCDataKind::PTC, Eigen::MatrixXd > &, calib_t &, std::string)
Definition ptcproc.h:384
std::string weighting_type
Definition ptcproc.h:28
double med_weight_factor
Definition ptcproc.h:24
void subtract_mean(TCData< TCDataKind::PTC, Eigen::MatrixXd > &)
Definition ptcproc.h:146
Definition timestream.h:257
auto mask_region(TCData< tcdata_t, Eigen::MatrixXd > &, calib_t &, std::string, std::string, int, int, int)
Definition timestream.h:918
auto get_grouping(std::string, calib_t &, int)
Definition timestream.h:572
std::string fruit_loops_path
Definition timestream.h:281
std::shared_ptr< spdlog::logger > logger
Definition timestream.h:260
double upper_inv_var_factor
Definition timestream.h:302
double fruit_loops_sig2noise
Definition timestream.h:289
bool save_all_iters
Definition timestream.h:293
double mask_radius_arcsec
Definition timestream.h:305
bool run_tod_output
Definition timestream.h:276
void append_base_to_netcdf(netCDF::NcFile &, TCData< tcdata_t, Eigen::MatrixXd > &, std::string, std::string &, pointing_offset_t &, calib_t &)
Definition timestream.h:968
bool write_evals
Definition timestream.h:276
engine_utils::toltecIO toltec_io
Definition timestream.h:263
int fruit_loops_iters
Definition timestream.h:287
bool run_fruit_loops
Definition timestream.h:279
std::string fruit_mode
Definition timestream.h:285
Eigen::VectorXd fruit_loops_flux
Definition timestream.h:291
double lower_inv_var_factor
Definition timestream.h:302
std::string fruit_loops_type
Definition timestream.h:285
void get_config_value(config_t config, param_t &param, key_vec_t &missing_keys, key_vec_t &invalid_keys, option_t option, std::vector< param_t > allowed={}, std::vector< param_t > min_val={}, std::vector< param_t > max_val={})
Definition config.h:58
auto calc_std_dev(Eigen::DenseBase< DerivedA > &data)
Definition utils.h:336
Definition clean.h:10
TC data class.
Definition timestream.h:55