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
254 // get first 64 eigenvalues and eigenvectors
255 Eigen::VectorXd ev = evals.head(cleaner.n_calc);
256 Eigen::MatrixXd evc = evecs.leftCols(cleaner.n_calc);
257
258 logger->debug("evals {}", ev);
259 logger->debug("evecs {}", evc);
260
261 // copy evals and evecs to ptcdata
262 out.evals.data[indx].push_back(std::move(ev));
263 out.evecs.data[indx].push_back(std::move(evc));
264 }
265
266 // remove eigenvalues from the data and reconstruct the tod
267 cleaner.remove_eig_values<timestream::Cleaner::SpectraBackend>(in_scans_block, masked_flags, evals, evecs, out_scans_block,
268 cleaner.n_eig_to_cut[arr_index](indx));
269
270 if (in.kernel.data.size()!=0) {
271 // check if any good flags
272 logger->debug("cleaning kernel");
273 auto in_kernel_block = in.kernel.data.block(0, start_index, n_pts, n_dets);
274 auto out_kernel_block = in.kernel.data.block(0, start_index, n_pts, n_dets);
275
276 // remove eigenvalues from the kernel and reconstruct the tod
277 cleaner.remove_eig_values<timestream::Cleaner::SpectraBackend>(in_kernel_block, masked_flags, evals, evecs, out_kernel_block,
278 cleaner.n_eig_to_cut[arr_index](indx));
279 }
280 }
281 // otherwise just copy the data
282 else {
283 logger->debug("no good detectors found. skipping clean.");
284 // copy scans
285 out.scans.data.block(0, start_index, n_pts, n_dets) = in.scans.data.block(0, start_index, n_pts, n_dets);
286 // copy kernel
287 if (in.kernel.data.size()!=0) {
288 out.kernel.data.block(0, start_index, n_pts, n_dets) = in.kernel.data.block(0, start_index, n_pts, n_dets);
289 }
290 }
291 }
292 indx++;
293 // set as cleaned
294 out.status.cleaned = true;
295 }
296 }
297}
298
299template <typename apt_type, class tel_type>
300void PTCProc::calc_weights(TCData<TCDataKind::PTC, Eigen::MatrixXd> &in, apt_type &apt, tel_type &telescope) {
301 // number of detectors
302 Eigen::Index n_dets = in.scans.data.cols();
303
304 // resize weights to number of detectors
305 in.weights.data = Eigen::VectorXd::Zero(n_dets);
306
307 // approximate weighting
308 if (weighting_type == "approximate") {
309 logger->debug("calculating weights using detector sensitivities");
310 // unit conversion x flux calibration factor x 1/exp(-tau)
311 double conversion_factor;
312
313 // loop through detectors and calculate weights
314 for (Eigen::Index i=0; i<n_dets; ++i) {
315 // current detector index
316 Eigen::Index det_index = i;
317 // if flux calibrated, get flux conversion factor
318 if (in.status.calibrated) {
319 conversion_factor = in.fcf.data(i);
320 }
321 // otherwise fcf is unity
322 else {
323 conversion_factor = 1;
324 }
325 // make sure flux conversion is not zero (otherwise weight=0)
326 if (conversion_factor*apt["sens"](det_index)!=0) {
327 // calculate weights while applying flux calibration
328 in.weights.data(i) = pow(sqrt(telescope.d_fsmp)*apt["sens"](det_index)*conversion_factor,-2.0);
329 }
330 else {
331 in.weights.data(i) = 0;
332 }
333 }
334 }
335 // use full weighting
336 else if (weighting_type == "full"){
337 logger->debug("calculating weights using timestream variance");
338
339 // loop through detectors
340 for (Eigen::Index i=0; i<n_dets; ++i) {
341 // only calculate weights if detector is unflagged
342 if (apt["flag"](i)==0) {
343 // make Eigen::Maps for each detector's scan
344 Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, 1>> scans(
345 in.scans.data.col(i).data(), in.scans.data.rows());
346 Eigen::Map<Eigen::Matrix<bool, Eigen::Dynamic, 1>> flags(
347 in.flags.data.col(i).data(), in.flags.data.rows());
348
349 // unflagged detector stddev
350 double det_std_dev = engine_utils::calc_std_dev(scans, flags);
351 // if stddev is not zero
352 if (det_std_dev !=0) {
353 // weight = 1/(stddev)^2
354 in.weights.data(i) = pow(det_std_dev,-2);
355 }
356 // otherwise weight = 0 (not included in maps)
357 else {
358 in.weights.data(i) = 0;
359 }
360 }
361 // otherwise weight = 0 (not included in maps)
362 else {
363 in.weights.data(i) = 0;
364 }
365 }
366 }
367 // constant weighting
368 else if (weighting_type == "const") {
369 for (Eigen::Index i=0; i<n_dets; ++i) {
370 // only calculate weights if detector is unflagged
371 if (apt["flag"](i)==0) {
372 in.weights.data(i) = 1;
373 }
374 // otherwise set to zero
375 else {
376 in.weights.data(i) = 0;
377 }
378 }
379 }
380}
381
382template <typename calib_t>
383auto PTCProc::reset_weights(TCData<TCDataKind::PTC, Eigen::MatrixXd> &in, calib_t &calib, std::string map_grouping) {
384
385 // make a copy of the calib class for flagging
386 calib_t calib_scan = calib;
387
388 // only need to run if median weight factor >=1
390 // number of detectors
391 Eigen::Index n_dets = in.scans.data.cols();
392
393 // get group limits
394 auto grp_limits = get_grouping("array", calib, n_dets);
395
396 // collect detectors that are un-flagged and have non-zero weights
397 for (auto const& [key, val] : grp_limits) {
398 // weights for current group
399 auto grp_weights = in.weights.data(Eigen::seq(std::get<0>(grp_limits[key]),
400 std::get<1>(grp_limits[key])-1));
401 // number of good detectors
402 Eigen::Index n_good_dets = 0;
403 // start index of current group
404 Eigen::Index j = std::get<0>(grp_limits[key]);
405
406 // loop through detectors in current group
407 for (Eigen::Index m=0; m<grp_weights.size(); ++m) {
408 // if detector is good and weight is not zero
409 if (calib.apt["flag"](j)==0 && grp_weights(m)>0) {
410 n_good_dets++;
411 }
412 j++;
413 }
414
415 // to hold good detectors
416 Eigen::VectorXd good_wt;
417
418 // if good detectors were found
419 if (n_good_dets>0) {
420 good_wt.resize(n_good_dets);
421
422 // remove flagged dets
423 j = std::get<0>(grp_limits[key]);
424 Eigen::Index k = 0;
425 for (Eigen::Index m=0; m<grp_weights.size(); ++m) {
426 if (calib.apt["flag"](j)==0 && grp_weights(m)>0) {
427 good_wt(k) = grp_weights(m);
428 k++;
429 }
430 j++;
431 }
432 }
433 // otherwise just use all detectors
434 else {
435 good_wt = grp_weights;
436 }
437
438 // get median weight
439 auto med_wt = tula::alg::median(good_wt);
440 // store median weights
441 in.median_weights.data.push_back(med_wt);
442
443 int outliers = 0;
444 int n_dets_low = 0;
445 int n_dets_high = 0;
446
447 // start index of current group
448 j = std::get<0>(grp_limits[key]);
449 // loop through detectors in current group
450 for (Eigen::Index m=0; m<grp_weights.size(); ++m) {
451 // if detector weight is med_weight_factor times larger than med_wt
452 if (med_weight_factor >=1 && in.weights.data(j) > med_weight_factor*med_wt) {
453 // reset high weights to median
454 in.weights.data(j) = med_wt;
455 outliers++;
456 }
457
458 // only run if unflagged already
459 if (calib.apt["flag"](j)==0) {
460 // flag those below limit
461 if ((in.weights.data(j) < (lower_weight_factor*med_wt)) && lower_weight_factor!=0) {
462 if (map_grouping!="detector") {
463 in.flags.data.col(j).setOnes();
464 }
465 else {
466 calib_scan.apt["flag"](j) = 1;
467 }
468 in.n_dets_low++;
469 n_dets_low++;
470 }
471
472 // flag those above limit
473 if ((in.weights.data(j) > (upper_weight_factor*med_wt)) && upper_weight_factor!=0) {
474 if (map_grouping!="detector") {
475 in.flags.data.col(j).setOnes();
476 }
477 else {
478 calib_scan.apt["flag"](j) = 1;
479 }
480 in.n_dets_high++;
481 n_dets_high++;
482 }
483 }
484 j++;
485 }
486 logger->info("array {} had {} outlier weights", key, outliers);
487 logger->info("array {}: {}/{} dets below weight limit. {}/{} dets above weight limit.", key,
488 n_dets_low, n_good_dets, n_dets_high, n_good_dets);
489 }
490
491 // set up scan calib
492 calib_scan.setup();
493 }
494 return std::move(calib_scan);
495}
496
497template <typename calib_t, typename pointing_offset_t>
498void PTCProc::append_to_netcdf(TCData<TCDataKind::PTC, Eigen::MatrixXd> &in, std::string filepath, std::string map_grouping,
499 std::string &pixel_axes, pointing_offset_t &pointing_offsets_arcsec, calib_t &calib) {
500
501 using netCDF::NcDim;
502 using netCDF::NcFile;
503 using netCDF::NcType;
504 using netCDF::NcVar;
505 using namespace netCDF::exceptions;
506
507 try {
508 // open netcdf file
509 NcFile fo(filepath, netCDF::NcFile::write);
510
511 // append common time chunk variables
512 append_base_to_netcdf(fo, in, map_grouping, pixel_axes, pointing_offsets_arcsec, calib);
513
514 // get dimensions
515 NcDim n_dets_dim = fo.getDim("n_dets");
516
517 // number of detectors currently in file
518 unsigned long n_dets_exists = n_dets_dim.getSize();
519
520 // append weights
521 std::vector<std::size_t> start_index_weights = {static_cast<unsigned long>(in.index.data), 0};
522 std::vector<std::size_t> size_weights = {1, n_dets_exists};
523
524 // get weight variable
525 NcVar weights_v = fo.getVar("weights");
526
527 // add weights to tod output
528 weights_v.putVar(start_index_weights, size_weights, in.weights.data.data());
529
530 if (write_evals) {
531 // get number of eigenvalues to save
532 NcDim n_eigs_dim = fo.getDim("n_eigs");
533 netCDF::NcDim n_eig_grp_dim = fo.getDim("n_eig_grp");
534
535 // if eigenvalue dimension is null, add it
536 if (n_eig_grp_dim.isNull()) {
537 n_eig_grp_dim = fo.addDim("n_eig_grp",in.evals.data[0].size());
538 }
539
540 // dimensions for eigenvalue data
541 std::vector<netCDF::NcDim> eval_dims = {n_eig_grp_dim, n_eigs_dim};
542
543 // loop through cleaner gropuing
544 for (Eigen::Index i=0; i<in.evals.data.size(); ++i) {
545 NcVar eval_v = fo.addVar("evals_" + cleaner.grouping[i] + "_" + std::to_string(i) +
546 "_chunk_" + std::to_string(in.index.data), netCDF::ncDouble,eval_dims);
547 std::vector<std::size_t> start_eig_index = {0, 0};
548 std::vector<std::size_t> size = {1, TULA_SIZET(cleaner.n_calc)};
549
550 // loop through eigenvalues in current group
551 for (const auto &evals: in.evals.data[i]) {
552 eval_v.putVar(start_eig_index,size,evals.data());
553 start_eig_index[0] += 1;
554 }
555 }
556
557 // number of dimensions for eigenvectors
558 std::vector<netCDF::NcDim> eig_dims = {n_dets_dim, n_eigs_dim};
559
560 // loop through cleaner gropuing
561 for (Eigen::Index i=0; i<in.evecs.data.size(); ++i) {
562 // start at first row and col
563 std::vector<std::size_t> start_eig_index = {0, 0};
564
565 NcVar evec_v = fo.addVar("evecs_" + cleaner.grouping[i] + "_" + std::to_string(i) + "_chunk_" +
566 std::to_string(in.index.data),netCDF::ncDouble,eig_dims);
567
568 // loop through eigenvectors in current group
569 for (const auto &evecs: in.evecs.data[i]) {
570 std::vector<std::size_t> size = {TULA_SIZET(evecs.rows()), TULA_SIZET(cleaner.n_calc)};
571
572 // transpose eigenvectors
573 Eigen::MatrixXd ev = evecs.transpose();
574 evec_v.putVar(start_eig_index, size, ev.data());
575
576 // increment start
577 start_eig_index[0] += TULA_SIZET(evecs.rows());
578 }
579 }
580 }
581
582 // sync file to make sure it gets updated
583 fo.sync();
584 // close file
585 fo.close();
586 logger->info("tod chunk written to {}", filepath);
587
588 } catch (NcException &e) {
589 logger->error("{}", e.what());
590 }
591}
592
593} // 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:498
void calc_weights(TCData< TCDataKind::PTC, Eigen::MatrixXd > &, apt_type &, tel_type &)
Definition ptcproc.h:300
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:383
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