4#include "sys/sysinfo.h"
15#include <citlali_config/config.h>
16#include <citlali_config/gitversion.h>
17#include <citlali_config/default_config.h>
18#include <kids/core/kidsdata.h>
19#include <kids/sweep/fitter.h>
20#include <kids/timestream/solver.h>
21#include <kids/toltec/toltec.h>
22#include <kidscpp_config/gitversion.h>
23#include <tula_config/gitversion.h>
25#include <tula/config/core.h>
26#include <tula/config/flatconfig.h>
27#include <tula/config/yamlconfig.h>
29#include <tula/filesystem.h>
30#include <tula/formatter/container.h>
31#include <tula/formatter/enum.h>
32#include <tula/grppi.h>
33#include <tula/logging.h>
34#include <tula/switch_invoke.h>
156 using key_vec_t = std::vector<std::vector<std::string>>;
159 std::shared_ptr<spdlog::logger>
logger = spdlog::get(
"citlali_logger");
168 std::map<std::string,int>
gaps;
250 template<
typename CT>
254 template<
typename CT>
258 template<
typename CT>
262 template<
typename CT>
266 template<
typename CT>
270 template<
typename CT>
274 template<
typename CT>
278 template<
typename CT>
282 template<
typename CT>
292 template <engine_utils::toltecIO::ProdType prod_t>
299 template <TCDataKind tc_t>
303 template <
typename map_buffer_t>
315 template <
typename fits_io_type,
class map_buffer_t>
316 void add_phdu(fits_io_type &, map_buffer_t &, Eigen::Index);
319 template <
typename fits_io_type,
class map_buffer_t>
320 void write_maps(fits_io_type &, fits_io_type &, map_buffer_t &, Eigen::Index);
323 template <mapmaking::MapType map_t,
class map_buffer_t>
324 void write_psd(map_buffer_t &, std::string);
327 template <mapmaking::MapType map_t,
class map_buffer_t>
334 template <mapmaking::MapType map_t,
class map_buffer_t>
338 template <mapmaking::MapType map_t,
class map_buffer_t>
342 template <mapmaking::MapType map_t,
class map_buffer_t>
355 Eigen::VectorXd tau_el(1);
361 for (
auto const& [key, val] : tau_freq) {
364 std::exit(EXIT_FAILURE);
375 if ((
calib.
apt[
"fg"].array()==-1).all()) {
376 logger->error(
"no matched freq groups. cannot run in polarized mode");
377 std::exit(EXIT_FAILURE);
424 create_tod_files<engine_utils::toltecIO::rtc_timestream>();
428 create_tod_files<engine_utils::toltecIO::ptc_timestream>();
438 logger->warn(
"tod output mode require sequential policy. "
439 "parallelization will be disabled for some stages.");
455 std::map<Eigen::Index, std::vector<std::vector<Eigen::VectorXd>>>().swap(
diagnostics.
evals);
460 logger->info(
"getting rtc config options");
475 std::tuple{
"timestream",
"polarimetry",
"ignore_hwpr"});
480 logger->info(
"getting ptc config options");
491 logger->info(
"getting timestream config options");
494 std::tuple{
"timestream",
"enabled"});
497 std::tuple{
"timestream",
"type"});
500 bool run_tod_output_rtc, run_tod_output_ptc;
503 std::tuple{
"timestream",
"raw_time_chunk",
"output",
"enabled"});
506 std::tuple{
"timestream",
"processed_time_chunk",
"output",
"enabled"});
511 if (run_tod_output_rtc) {
516 if (run_tod_output_ptc) {
530 std::tuple{
"timestream",
"output",
"subdir_name"});
533 std::tuple{
"timestream",
"output",
"stats",
"eigenvalues"});
536 std::tuple{
"timestream",
"chunking",
"chunk_mode"});
539 std::tuple{
"timestream",
"chunking",
"value"});
542 std::tuple{
"timestream",
"chunking",
"force_chunking"});
553 logger->info(
"getting mapmaking config options");
556 std::tuple{
"mapmaking",
"enabled"});
559 std::tuple{
"mapmaking",
"grouping"},{
"auto",
"array",
"nw",
"detector",
"fg"});
563 logger->error(
"Detector grouping reductions do not currently support polarimetry mode");
564 std::exit(EXIT_FAILURE);
572 std::tuple{
"mapmaking",
"method"},{
"naive",
"jinc",
"maximum_likelihood"});
576 std::tuple{
"mapmaking",
"pixel_axes"},{
"radec",
"altaz",
"galactic"});
579 logger->info(
"getting omb config options");
584 std::tuple{
"coadd",
"enabled"});
588 logger->info(
"getting cmb config options");
606 std::tuple{
"mapmaking",
"jinc_filter",
"r_max"});
609 auto jinc_shape_vec = config.template get_typed<std::vector<double>>(std::tuple{
"mapmaking",
"jinc_filter",
"shape_params",arr_name});
610 jinc_mm.
shape_params[arr_index] = Eigen::Map<Eigen::VectorXd>(jinc_shape_vec.data(),jinc_shape_vec.size());
625 std::tuple{
"mapmaking",
"maximum_likelihood",
"tolerance"});
627 std::tuple{
"mapmaking",
"maximum_likelihood",
"max_iterations"});
632 std::tuple{
"noise_maps",
"enabled"});
636 std::tuple{
"noise_maps",
"n_noise_maps"},{},{0},{});
639 std::tuple{
"noise_maps",
"randomize_dets"});
661 logger->info(
"getting beammap config options");
664 std::tuple{
"beammap",
"iter_max"});
667 std::tuple{
"beammap",
"iter_tolerance"});
670 std::tuple{
"beammap",
"reference_det"});
673 std::tuple{
"beammap",
"subtract_reference_det"});
676 std::tuple{
"beammap",
"derotate"});
679 auto lower_fwhm_arcsec_vec = config.template get_typed<std::vector<double>>(std::tuple{
"beammap",
"flagging",
"array_lower_fwhm_arcsec"});
681 auto upper_fwhm_arcsec_vec = config.template get_typed<std::vector<double>>(std::tuple{
"beammap",
"flagging",
"array_upper_fwhm_arcsec"});
683 auto lower_sig2noise_vec = config.template get_typed<std::vector<double>>(std::tuple{
"beammap",
"flagging",
"array_lower_sig2noise"});
685 auto upper_sig2noise_vec = config.template get_typed<std::vector<double>>(std::tuple{
"beammap",
"flagging",
"array_upper_sig2noise"});
687 auto max_dist_arcsec_vec = config.template get_typed<std::vector<double>>(std::tuple{
"beammap",
"flagging",
"array_max_dist_arcsec"});
706 auto sens_factors_vec = config.template get_typed<std::vector<double>>(std::tuple{
"beammap",
"flagging",
"sens_factors"});
713 auto sens_psd_limits_Hz_vec = config.template get_typed<std::vector<double>>(std::tuple{
"beammap",
"sens_psd_limits_Hz"});
715 sens_psd_limits_Hz = (Eigen::Map<Eigen::VectorXd>(sens_psd_limits_Hz_vec.data(), sens_psd_limits_Hz_vec.size()));
731 logger->info(
"getting map filtering config options");
746 logger->error(
"wiener filter kernel template requires kernel");
747 std::exit(EXIT_FAILURE);
756 logger->error(
"wiener filter requires noise maps");
757 std::exit(EXIT_FAILURE);
767 if (config.has(std::tuple{
"interface_sync_offset"})) {
768 auto interface_node = config.get_node(std::tuple{
"interface_sync_offset"});
770 std::vector<std::string> interface_keys = {
787 for (Eigen::Index i=0; i<interface_node.size(); ++i) {
788 auto offset = config.template get_typed<double>(std::tuple{
"interface_sync_offset",i, interface_keys[i]});
795 std::tuple{
"runtime",
"verbose"});
798 std::tuple{
"runtime",
"output_dir"});
801 std::tuple{
"runtime",
"n_threads"});
804 std::tuple{
"runtime",
"parallel_policy"},{
"seq",
"omp"});
807 std::tuple{
"runtime",
"reduction_type"},{
"science",
"pointing",
"beammap"});
810 std::tuple{
"runtime",
"use_subdir"});
820 std::tuple{
"post_processing",
"map_filtering",
"enabled"});
824 std::tuple{
"post_processing",
"source_finding",
"enabled"});
830 std::tuple{
"post_processing",
"source_fitting",
"bounding_box_arcsec"},{},{0});
833 std::tuple{
"post_processing",
"source_fitting",
"fitting_radius_arcsec"});
836 std::tuple{
"post_processing",
"source_fitting",
"gauss_model",
"fit_rotation_angle"});
847 map_fitter.
flux_limits(i) = config.template get_typed<double>(std::tuple{
"post_processing",
"source_fitting",
848 "gauss_model",
"amp_limit_factors",i});
850 map_fitter.
fwhm_limits(i) = config.template get_typed<double>(std::tuple{
"post_processing",
"source_fitting",
851 "gauss_model",
"fwhm_limit_factors",i});
882 std::tuple{
"post_processing",
"source_finding",
"source_sigma"});
885 std::tuple{
"post_processing",
"source_finding",
"source_window_arcsec"});
888 std::tuple{
"post_processing",
"source_finding",
"mode"});
924 std::tuple{
"beammap_source",
"name"});
927 std::tuple{
"beammap_source",
"ra_deg"});
933 std::tuple{
"beammap_source",
"dec_deg"});
938 Eigen::Index n_fluxes = config.get_node(std::tuple{
"beammap_source",
"fluxes"}).size();
941 for (Eigen::Index i=0; i<n_fluxes; ++i) {
942 auto array = config.get_str(std::tuple{
"beammap_source",
"fluxes",i,
"array_name"});
944 auto flux = config.template get_typed<double>(std::tuple{
"beammap_source",
"fluxes",i,
"value_mJy"});
946 auto uncertainty_mJy = config.template get_typed<double>(std::tuple{
"beammap_source",
"fluxes",i,
"uncertainty_mJy"});
957 if (config.has(
"pointing_offsets")) {
958 std::vector<double> offset;
960 offset = config.template get_typed<std::vector<double>>(std::tuple{
"pointing_offsets",0,
"value_arcsec"});
963 offset = config.template get_typed<std::vector<double>>(std::tuple{
"pointing_offsets",1,
"value_arcsec"});
968 offset = config.template get_typed<std::vector<double>>(std::tuple{
"pointing_offsets",2,
"modified_julian_date"});
976 logger->error(
"pointing_offsets not found in config");
977 std::exit(EXIT_FAILURE);
1047 netCDF::NcFile fo(fval, netCDF::NcFile::write);
1090 add_netcdf_var(fo,
"to_Jy_pixel_"+name, (1/mJy_beam_to_uK)*mJy_beam_to_Jy_px);
1098 add_netcdf_var(fo,
"to_uK_"+name, mJy_beam_to_uK/mJy_beam_to_Jy_px);
1106 add_netcdf_var<std::string>(fo,
"DATEOBS0",
date_obs.back());
1135 add_netcdf_var<std::string>(fo,
"INSTRUME",
"TolTEC");
1137 add_netcdf_var<std::string>(fo,
"TELESCOP",
"LMT");
1138 add_netcdf_var<std::string>(fo,
"PIPELINE",
"CITLALI");
1139 add_netcdf_var<std::string>(fo,
"VERSION", CITLALI_GIT_VERSION);
1140 add_netcdf_var<std::string>(fo,
"KIDS", KIDSCPP_GIT_VERSION);
1141 add_netcdf_var<std::string>(fo,
"TULA", TULA_GIT_VERSION);
1143 add_netcdf_var<std::string>(fo,
"GOAL",
redu_type);
1145 add_netcdf_var<std::string>(fo,
"TYPE",
tod_type);
1146 add_netcdf_var<std::string>(fo,
"GROUPING",
map_grouping);
1147 add_netcdf_var<std::string>(fo,
"METHOD",
map_method);
1184 Eigen::VectorXd tau_el(1);
1189 for (
auto const& [key, val] : tau_freq) {
1195 for (Eigen::Index i=0; i<
calib.
arrays.size(); ++i) {
1204 std::vector<string> apt_filename;
1209 while (getline (ss, item, delim)) {
1210 apt_filename.push_back(item);
1212 add_netcdf_var<std::string>(fo,
"APT", apt_filename.back());
1236 for (Eigen::Index i=0; i<
calib.
arrays.size(); ++i) {
1250 for (Eigen::Index i=0; i<
calib.
arrays.size(); ++i) {
1265template <engine_utils::toltecIO::ProdType prod_t>
1300 netCDF::NcFile fo(
tod_filename[name], netCDF::NcFile::replace);
1303 netCDF::NcDim n_tod_output_type_dim = fo.addDim(
"n_tod_output_type",1);
1304 netCDF::NcVar tod_output_type_var = fo.addVar(
"tod_output_type",netCDF::ncString, n_tod_output_type_dim);
1305 const std::vector<size_t> tod_output_type_index = {0};
1308 std::string tod_output_type_name =
"rtc";
1309 tod_output_type_var.putVar(tod_output_type_index,tod_output_type_name);
1312 std::string tod_output_type_name =
"ptc";
1313 tod_output_type_var.putVar(tod_output_type_index,tod_output_type_name);
1320 netCDF::NcVar obsnum_v = fo.addVar(
"obsnum",netCDF::ncInt);
1321 obsnum_v.putAtt(
"units",
"N/A");
1322 int obsnum_int = std::stoi(
obsnum);
1323 obsnum_v.putVar(&obsnum_int);
1326 netCDF::NcVar source_ra_v = fo.addVar(
"SourceRa",netCDF::ncDouble);
1327 source_ra_v.putAtt(
"units",
"rad");
1331 netCDF::NcVar source_dec_v = fo.addVar(
"SourceDec",netCDF::ncDouble);
1332 source_dec_v.putAtt(
"units",
"rad");
1335 netCDF::NcDim n_pts_dim = fo.addDim(
"n_pts");
1336 netCDF::NcDim n_raw_scan_indices_dim = fo.addDim(
"n_raw_scan_indices",
telescope.
scan_indices.rows());
1337 netCDF::NcDim n_scan_indices_dim = fo.addDim(
"n_scan_indices", 2);
1340 netCDF::NcDim n_dets_dim = fo.addDim(
"n_dets",
calib.
n_dets);
1342 std::vector<netCDF::NcDim> dims = {n_pts_dim, n_dets_dim};
1343 std::vector<netCDF::NcDim> raw_scans_dims = {n_scans_dim, n_raw_scan_indices_dim};
1344 std::vector<netCDF::NcDim> scans_dims = {n_scans_dim, n_scan_indices_dim};
1347 netCDF::NcVar raw_scan_indices_v = fo.addVar(
"raw_scan_indices",netCDF::ncInt, raw_scans_dims);
1348 raw_scan_indices_v.putAtt(
"units",
"N/A");
1352 netCDF::NcVar scan_indices_v = fo.addVar(
"scan_indices",netCDF::ncInt, scans_dims);
1353 scan_indices_v.putAtt(
"units",
"N/A");
1356 netCDF::NcVar signal_v = fo.addVar(
"signal",netCDF::ncDouble, dims);
1360 std::vector<std::size_t> chunkSizes;
1362 netCDF::NcVar::ChunkMode chunkMode = netCDF::NcVar::nc_CHUNKED;
1369 signal_v.setChunking(chunkMode, chunkSizes);
1372 netCDF::NcVar flags_v = fo.addVar(
"flags",netCDF::ncDouble, dims);
1373 flags_v.putAtt(
"units",
"N/A");
1374 flags_v.setChunking(chunkMode, chunkSizes);
1378 netCDF::NcVar kernel_v = fo.addVar(
"kernel",netCDF::ncDouble, dims);
1379 kernel_v.putAtt(
"units",
"N/A");
1380 kernel_v.setChunking(chunkMode, chunkSizes);
1384 netCDF::NcVar det_lat_v = fo.addVar(
"det_lat",netCDF::ncDouble, dims);
1385 det_lat_v.putAtt(
"units",
"rad");
1386 det_lat_v.setChunking(chunkMode, chunkSizes);
1389 netCDF::NcVar det_lon_v = fo.addVar(
"det_lon",netCDF::ncDouble, dims);
1390 det_lon_v.putAtt(
"units",
"rad");
1391 det_lon_v.setChunking(chunkMode, chunkSizes);
1396 netCDF::NcVar det_ra_v = fo.addVar(
"det_ra",netCDF::ncDouble, dims);
1397 det_ra_v.putAtt(
"units",
"rad");
1398 det_ra_v.setChunking(chunkMode, chunkSizes);
1401 netCDF::NcVar det_dec_v = fo.addVar(
"det_dec",netCDF::ncDouble, dims);
1402 det_dec_v.putAtt(
"units",
"rad");
1403 det_dec_v.setChunking(chunkMode, chunkSizes);
1408 netCDF::NcVar apt_v = fo.addVar(
"apt_" + x.first,netCDF::ncDouble, n_dets_dim);
1414 netCDF::NcVar tel_data_v = fo.addVar(x.first,netCDF::ncDouble, n_pts_dim);
1415 tel_data_v.putAtt(
"units",
"rad");
1416 tel_data_v.setChunking(chunkMode, chunkSizes);
1421 logger->info(
"pointing_offsets_arcsec.second {} {}",x.first, x.second);
1422 netCDF::NcVar offsets_v = fo.addVar(
"pointing_offset_"+x.first,netCDF::ncDouble, n_pts_dim);
1423 offsets_v.putAtt(
"units",
"arcsec");
1424 offsets_v.setChunking(chunkMode, chunkSizes);
1429 std::vector<netCDF::NcDim> weight_dims = {n_scans_dim, n_dets_dim};
1430 netCDF::NcVar weights_v = fo.addVar(
"weights",netCDF::ncDouble, weight_dims);
1431 weights_v.putAtt(
"units",
"("+
omb.
sig_unit+
")^-2");
1437 netCDF::NcVar hwpr_v = fo.addVar(
"hwpr",netCDF::ncDouble, n_pts_dim);
1438 hwpr_v.putAtt(
"units",
"rad");
1443 netCDF::NcDim tel_header_dim = fo.addDim(
"tel_header_n_pts", 1);
1445 netCDF::NcVar tel_header_v = fo.addVar(key,netCDF::ncDouble, tel_header_dim);
1446 tel_header_v.putVar(&val(0));
1454 logger->info(
"reduction info");
1463 double mb_size_total = 0;
1469 logger->info(
"estimated size of map buffer {} GB", omb_size);
1471 mb_size_total = mb_size_total + omb_size;
1482 logger->info(
"estimated size of coadd buffer {} GB", cmb_size);
1484 mb_size_total = mb_size_total + cmb_size;
1491 logger->info(
"estimated size of noise buffer {} GB", nmb_size);
1492 mb_size_total = mb_size_total + nmb_size;
1501 logger->info(
"estimated size of noise buffer {} GB", nmb_size);
1502 mb_size_total = mb_size_total + nmb_size;
1506 logger->info(
"estimated size of all maps {} GB", mb_size_total);
1518template <TCDataKind tc_t>
1521 logger->debug(
"writing summary files for chunk {}",in.index.data);
1523 std::string filename =
"chunk_summary_" + std::to_string(in.index.data);
1529 f <<
"Summary file for scan " << in.index.data <<
"\n";
1530 f <<
"-Citlali version: " << CITLALI_GIT_VERSION <<
"\n";
1531 f <<
"-Kidscpp version: " << KIDSCPP_GIT_VERSION <<
"\n";
1532 f <<
"-Time of time chunk creation: " + in.creation_time +
"\n";
1535 f <<
"-Reduction type: " <<
redu_type <<
"\n";
1536 f <<
"-TOD type: " <<
tod_type <<
"\n";
1538 f <<
"-TOD chunk type: " << in.name <<
"\n";
1540 f <<
"-Calibrated: " << in.status.calibrated <<
"\n";
1541 f <<
"-Extinction Corrected: " << in.status.extinction_corrected <<
"\n";
1542 f <<
"-Demodulated: " << in.status.demodulated <<
"\n";
1543 f <<
"-Kernel Generated: " << in.status.kernel_generated <<
"\n";
1544 f <<
"-Despiked: " << in.status.despiked <<
"\n";
1545 f <<
"-TOD filtered: " << in.status.tod_filtered <<
"\n";
1546 f <<
"-Downsampled: " << in.status.downsampled <<
"\n";
1547 f <<
"-Cleaned: " << in.status.cleaned <<
"\n";
1549 f <<
"-Scan length: " << in.scans.data.rows() <<
"\n";
1551 f <<
"-Number of detectors: " << in.scans.data.cols() <<
"\n";
1552 f <<
"-Number of detectors flagged in APT table: " << (
calib.
apt[
"flag"].array()!=0).count() <<
"\n";
1553 f <<
"-Number of detectors flagged below weight limit: " << in.n_dets_low <<
"\n";
1554 f <<
"-Number of detectors flagged above weight limit: " << in.n_dets_high <<
"\n";
1555 Eigen::Index n_flagged = in.n_dets_low + in.n_dets_high + (
calib.
apt[
"flag"].array()!=0).count();
1556 f <<
"-Number of detectors flagged: " << n_flagged <<
" (" << 100*float(n_flagged)/float(in.scans.data.cols()) <<
"%)\n";
1558 f <<
"-NaNs found: " << in.scans.data.array().isNaN().count() <<
"\n";
1559 f <<
"-Infs found: " << in.scans.data.array().isInf().count() <<
"\n";
1560 f <<
"-Data min: " << in.scans.data.minCoeff() <<
" " <<
omb.
sig_unit <<
"\n";
1561 f <<
"-Data max: " << in.scans.data.maxCoeff() <<
" " <<
omb.
sig_unit <<
"\n";
1562 f <<
"-Data mean: " << in.scans.data.mean() <<
" " <<
omb.
sig_unit <<
"\n";
1563 f <<
"-Data median: " << tula::alg::median(in.scans.data) <<
" " <<
omb.
sig_unit <<
"\n";
1566 if (in.status.kernel_generated) {
1567 f <<
"-Kernel max: " << in.kernel.data.maxCoeff() <<
" " <<
omb.
sig_unit <<
"\n";
1573template <
typename map_buffer_t>
1576 logger->debug(
"writing map summary files");
1578 std::string filename =
"map_summary";
1582 f <<
"Summary file for maps\n";
1583 f <<
"-Citlali version: " << CITLALI_GIT_VERSION <<
"\n";
1584 f <<
"-Kidscpp version: " << KIDSCPP_GIT_VERSION <<
"\n";
1587 f <<
"-Reduction type: " <<
redu_type <<
"\n";
1588 f <<
"-Map type: " <<
tod_type <<
"\n";
1590 f <<
"-Rows: " << mb.n_rows <<
"\n";
1591 f <<
"-Cols: " << mb.n_cols <<
"\n";
1592 f <<
"-Number of maps: " <<
n_maps <<
"\n";
1593 f <<
"-Signal map unit: " << mb.sig_unit <<
"\n";
1594 f <<
"-Weight map unit: " <<
"1/(" + mb.sig_unit +
")^2" <<
"\n";
1595 f <<
"-Kernel maps generated: " << !mb.kernel.empty() <<
"\n";
1596 f <<
"-Coverage maps generated: " << !mb.coverage.empty() <<
"\n";
1597 f <<
"-Noise maps generated: " << !mb.noise.empty() <<
"\n";
1598 f <<
"-Number of noise maps: " << mb.noise.size() <<
"\n";
1601 std::map<std::string,int> n_nans;
1602 n_nans[
"signal"] = 0;
1603 n_nans[
"weight"] = 0;
1604 n_nans[
"kernel"] = 0;
1605 n_nans[
"coverage"] = 0;
1606 n_nans[
"noise"] = 0;
1609 std::map<std::string,int> n_infs;
1610 n_infs[
"signal"] = 0;
1611 n_infs[
"weight"] = 0;
1612 n_nans[
"kernel"] = 0;
1613 n_infs[
"coverage"] = 0;
1614 n_infs[
"noise"] = 0;
1617 for (Eigen::Index i=0; i<mb.signal.size(); ++i) {
1618 n_nans[
"signal"] = n_nans[
"signal"] + mb.signal[i].array().isNaN().count();
1619 n_nans[
"weight"] = n_nans[
"weight"] + mb.weight[i].array().isNaN().count();
1622 if (!mb.kernel.empty()) {
1623 n_nans[
"kernel"] = n_nans[
"kernel"] + mb.kernel[i].array().isNaN().count();
1626 if (!mb.coverage.empty()) {
1627 n_nans[
"coverage"] = n_nans[
"coverage"] + mb.coverage[i].array().isNaN().count();
1630 n_infs[
"signal"] = n_infs[
"signal"] + mb.signal[i].array().isInf().count();
1631 n_infs[
"weight"] = n_infs[
"weight"] + mb.weight[i].array().isInf().count();
1634 if (!mb.kernel.empty()) {
1635 n_infs[
"kernel"] = n_infs[
"kernel"] + mb.kernel[i].array().isInf().count();
1638 if (!mb.coverage.empty()) {
1639 n_infs[
"coverage"] = n_infs[
"coverage"] + mb.coverage[i].array().isInf().count();
1643 if (!mb.noise.empty()) {
1644 for (Eigen::Index j=0; j<mb.noise.size(); ++j) {
1645 Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> noise_matrix(mb.noise[i].data() + j * mb.n_rows * mb.n_cols,
1646 mb.n_rows, mb.n_cols);
1648 n_nans[
"noise"] = n_nans[
"noise"] + noise_matrix.array().isNaN().count();
1649 n_infs[
"noise"] = n_infs[
"noise"] + noise_matrix.array().isInf().count();
1654 for (
auto const& [key, val] : n_nans) {
1655 f <<
"-Number of "+ key +
" NaNs: " << val <<
"\n";
1658 for (
auto const& [key, val] : n_infs) {
1659 f <<
"-Number of "+ key +
" Infs: " << val <<
"\n";
1663template <mapmaking::MapType map_t, engine_utils::toltecIO::DataType data_t, engine_utils::toltecIO::ProdType prod_t>
1666 std::string filename;
1694 std::string map_name =
"";
1700 map_name = map_name +
"nw_" + std::to_string(
calib.
nws(i)) +
"_";
1708 for (Eigen::Index m=0; m<
calib.
fg.size(); ++m) {
1709 array_indices(k) =
calib.
fg(m);
1715 map_name = map_name +
"fg_" + std::to_string(array_indices(i)) +
"_";
1719 map_name = map_name +
"det_" + std::to_string(i) +
"_";
1726template <
typename fits_io_type,
class map_buffer_t>
1731 logger->debug(
"adding unit conversions");
1740 auto mJy_beam_to_Jy_px = 1e-3/beam_area_rad*pow(mb->pixel_size_rad,2);
1744 if (mb->sig_unit ==
"mJy/beam") {
1746 fits_io->at(i).pfits->pHDU().addKey(
"to_mJy/beam", 1,
"Conversion to mJy/beam");
1749 "Conversion to MJy/sr");
1751 fits_io->at(i).pfits->pHDU().addKey(
"to_uK", mJy_beam_to_uK,
"Conversion to uK");
1753 fits_io->at(i).pfits->pHDU().addKey(
"to_Jy/pixel", mJy_beam_to_Jy_px,
"Conversion to Jy/pixel");
1755 else if (mb->sig_unit ==
"MJy/sr") {
1758 "Conversion to mJy/beam");
1760 fits_io->at(i).pfits->pHDU().addKey(
"to_MJy/sr", 1,
"Conversion to MJy/sr");
1763 "Conversion to uK");
1766 "Conversion to Jy/pixel");
1768 else if (mb->sig_unit ==
"uK") {
1770 fits_io->at(i).pfits->pHDU().addKey(
"to_mJy/beam", 1/mJy_beam_to_uK,
"Conversion to mJy/beam");
1773 "Conversion to MJy/sr");
1775 fits_io->at(i).pfits->pHDU().addKey(
"to_uK", 1,
"Conversion to uK");
1777 fits_io->at(i).pfits->pHDU().addKey(
"to_Jy/pixel", (1/mJy_beam_to_uK)*mJy_beam_to_Jy_px,
"Conversion to Jy/pixel");
1779 else if (mb->sig_unit ==
"Jy/pixel") {
1781 fits_io->at(i).pfits->pHDU().addKey(
"to_mJy/beam", 1/mJy_beam_to_Jy_px,
"Conversion to mJy/beam");
1784 "Conversion to MJy/sr");
1786 fits_io->at(i).pfits->pHDU().addKey(
"to_uK", mJy_beam_to_uK/mJy_beam_to_Jy_px,
"Conversion to uK");
1788 fits_io->at(i).pfits->pHDU().addKey(
"to_Jy/pixel", 1,
"Conversion to Jy/pixel");
1793 fits_io->at(i).pfits->pHDU().addKey(
"to_mJy/beam",
"N/A",
"Conversion to mJy/beam");
1794 fits_io->at(i).pfits->pHDU().addKey(
"to_MJy/sr",
"N/A",
"Conversion to MJy/sr");
1795 fits_io->at(i).pfits->pHDU().addKey(
"to_uK",
"N/A",
"Conversion to uK");
1796 fits_io->at(i).pfits->pHDU().addKey(
"to_Jy/pixel",
"N/A",
"Conversion to Jy/pixel");
1801 fits_io->at(i).pfits->pHDU().addKey(
"HEADER.SOURCE.FLUX_MJYPERBEAM",
beammap_fluxes_mJy_beam[name],
"Source flux (mJy/beam)");
1802 fits_io->at(i).pfits->pHDU().addKey(
"HEADER.SOURCE.FLUX_MJYPERSR",
beammap_fluxes_MJy_Sr[name],
"Source flux (MJy/sr)");
1804 fits_io->at(i).pfits->pHDU().addKey(
"BEAMMAP.ITER_TOLERANCE",
beammap_iter_tolerance,
"Beammap iteration tolerance");
1805 fits_io->at(i).pfits->pHDU().addKey(
"BEAMMAP.ITER_MAX",
beammap_iter_max,
"Beammap max iterations");
1806 fits_io->at(i).pfits->pHDU().addKey(
"BEAMMAP.IS_DEROTATED",
beammap_derotate,
"Beammap derotated");
1809 fits_io->at(i).pfits->pHDU().addKey(
"BEAMMAP.REF_DET_INDEX",
beammap_reference_det,
"Beammap Reference det (rotation center)");
1814 fits_io->at(i).pfits->pHDU().addKey(
"BEAMMAP.REF_DET_INDEX", -99,
"Beammap Reference det (rotation center)");
1815 fits_io->at(i).pfits->pHDU().addKey(
"BEAMMAP.REF_X_T",
"N/A",
"Az rotation center (arcsec)");
1816 fits_io->at(i).pfits->pHDU().addKey(
"BEAMMAP.REF_Y_T",
"N/A",
"Alt rotation center (arcsec)");
1820 logger->debug(
"adding obsnums");
1823 for (Eigen::Index j=0; j<mb->obsnums.size(); ++j) {
1824 fits_io->at(i).pfits->pHDU().addKey(
"OBSNUM"+std::to_string(j), mb->obsnums.at(j),
"Observation Number " + std::to_string(j));
1828 if (mb->obsnums.size()==1) {
1829 fits_io->at(i).pfits->pHDU().addKey(
"DATEOBS0",
date_obs.back(),
"Date and time of observation 0");
1832 for (Eigen::Index j=0; j<mb->obsnums.size(); ++j) {
1833 fits_io->at(i).pfits->pHDU().addKey(
"DATEOBS"+std::to_string(j),
date_obs[j],
"Date and time of observation "+std::to_string(j));
1837 logger->debug(
"adding obs info");
1842 fits_io->at(i).pfits->pHDU().addKey(
"INSTRUME",
"TolTEC",
"Instrument");
1844 fits_io->at(i).pfits->pHDU().addKey(
"HWPR",
calib.
run_hwpr,
"HWPR installed");
1846 fits_io->at(i).pfits->pHDU().addKey(
"TELESCOP",
"LMT",
"Telescope");
1848 fits_io->at(i).pfits->pHDU().addKey(
"WAV", name,
"Wavelength");
1850 fits_io->at(i).pfits->pHDU().addKey(
"PIPELINE",
"CITLALI",
"Redu pipeline");
1852 fits_io->at(i).pfits->pHDU().addKey(
"VERSION", CITLALI_GIT_VERSION,
"CITLALI_GIT_VERSION");
1854 fits_io->at(i).pfits->pHDU().addKey(
"KIDS", KIDSCPP_GIT_VERSION,
"KIDSCPP_GIT_VERSION");
1856 fits_io->at(i).pfits->pHDU().addKey(
"TULA", TULA_GIT_VERSION,
"TULA_GIT_VERSION");
1860 fits_io->at(i).pfits->pHDU().addKey(
"GOAL",
redu_type,
"Reduction type");
1864 fits_io->at(i).pfits->pHDU().addKey(
"TYPE",
tod_type,
"TOD Type");
1866 fits_io->at(i).pfits->pHDU().addKey(
"GROUPING",
map_grouping,
"Map grouping");
1868 fits_io->at(i).pfits->pHDU().addKey(
"METHOD",
map_method,
"Map method");
1870 fits_io->at(i).pfits->pHDU().addKey(
"EXPTIME", mb->exposure_time,
"Exposure time (sec)");
1872 fits_io->at(i).pfits->pHDU().addKey(
"RADESYS",
telescope.
pixel_axes,
"Coord Reference Frame");
1874 fits_io->at(i).pfits->pHDU().addKey(
"SRC_RA",
telescope.
tel_header[
"Header.Source.Ra"][0],
"Source RA (radians)");
1876 fits_io->at(i).pfits->pHDU().addKey(
"SRC_DEC",
telescope.
tel_header[
"Header.Source.Dec"][0],
"Source Dec (radians)");
1878 fits_io->at(i).pfits->pHDU().addKey(
"TAN_RA",
telescope.
tel_header[
"Header.Source.Ra"][0],
"Map Tangent Point RA (radians)");
1880 fits_io->at(i).pfits->pHDU().addKey(
"TAN_DEC",
telescope.
tel_header[
"Header.Source.Dec"][0],
"Map Tangent Point Dec (radians)");
1886 fits_io->at(i).pfits->pHDU().addKey(
"MEAN_PA",
RAD_TO_DEG*
telescope.
tel_data[
"ActParAng"].mean(),
"Mean Parallactic angle (deg)");
1888 logger->debug(
"adding beamsizes");
1902 fits_io->at(i).pfits->pHDU().addKey(
"BUNIT", mb->sig_unit,
"bunit");
1906 logger->debug(
"adding jinc params");
1908 fits_io->at(i).pfits->pHDU().addKey(
"JINC_R",
jinc_mm.
r_max,
"Jinc filter R_max");
1915 logger->debug(
"adding extinction");
1917 Eigen::VectorXd tau_el(1);
1921 fits_io->at(i).pfits->pHDU().addKey(
"MEAN_TAU", tau_freq[i](0),
"mean tau (" + name +
")");
1924 fits_io->at(i).pfits->pHDU().addKey(
"MEAN_TAU", 0.,
"mean tau (" + name +
")");
1928 fits_io->at(i).pfits->pHDU().addKey(
"SAMPRATE",
telescope.
fsmp,
"sample rate (Hz)");
1931 if (mb->obsnums.size()==1) {
1932 std::vector<string> apt_filename;
1937 while (getline (ss, item, delim)) {
1938 apt_filename.push_back(item);
1940 fits_io->at(i).pfits->pHDU().addKey(
"APT", apt_filename.back(),
"APT table used");
1947 rms = pow(mb->median_err(i),0.5);
1954 logger->debug(
"adding oof params");
1955 fits_io->at(i).pfits->pHDU().addKey(
"OOF_RMS", rms,
"rms of map background (" + mb->sig_unit +
")");
1958 fits_io->at(i).pfits->pHDU().addKey(
"OOF_T", 3.0,
"taper (dB)");
1959 fits_io->at(i).pfits->pHDU().addKey(
"OOF_M2X",
telescope.
tel_header[
"Header.M2.XReq"](0)/1000.*1e6,
"oof m2x (microns)");
1960 fits_io->at(i).pfits->pHDU().addKey(
"OOF_M2Y",
telescope.
tel_header[
"Header.M2.YReq"](0)/1000.*1e6,
"oof m2y (microns)");
1961 fits_io->at(i).pfits->pHDU().addKey(
"OOF_M2Z",
telescope.
tel_header[
"Header.M2.ZReq"](0)/1000.*1e6,
"oof m2z (microns)");
1963 fits_io->at(i).pfits->pHDU().addKey(
"OOF_RO", 25.,
"outer diameter of the antenna (m)");
1964 fits_io->at(i).pfits->pHDU().addKey(
"OOF_RI", 1.65,
"inner diameter of the antenna (m)");
1966 fits_io->at(i).pfits->pHDU().addKey(
"FRUITLOOPS_ITER",
fruit_iter,
"Current fruit loops iteration");
1969 logger->debug(
"adding config params");
1970 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.VERBOSE",
verbose_mode,
"Reduced in verbose mode");
1972 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.DESPIKED",
rtcproc.
run_despike,
"Despiked");
1976 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.EXTINCTION",
rtcproc.
run_extinction,
"Extinction corrected");
1978 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.WEIGHT.TYPE",
ptcproc.
weighting_type,
"Weighting scheme");
1985 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.WEIGHT.MEDWTFACTOR",
ptcproc.
med_weight_factor,
"Median weight factor");
1986 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.CLEANED",
ptcproc.
run_clean,
"Cleaned");
1989 "Number of eigenvalues removed");
1992 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.CLEANED.NEIG", 0,
"Number of eigenvalues removed");
2003 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.FRUITLOOPS.FLUX", 0,
"Fruit loops flux (" + mb->sig_unit +
")");
2005 fits_io->at(i).pfits->pHDU().addKey(
"CONFIG.FRUITLOOPS.MAXITER",
ptcproc.
fruit_loops_iters,
"Fruit loops iterations");
2008 if (mb->obsnums.size()==1) {
2009 logger->debug(
"adding tel params");
2011 logger->debug(
"adding {}: {}", key, val);
2012 fits_io->at(i).pfits->pHDU().addKey(key, val(0), key);
2017template <
typename fits_io_type,
class map_buffer_t>
2018void Engine::write_maps(fits_io_type &fits_io, fits_io_type &noise_fits_io, map_buffer_t &mb, Eigen::Index i) {
2029 mb->wcs.crval[3] = stokes_index;
2033 fits_io->at(map_index).add_wcs(fits_io->at(map_index).hdus.back(), mb->wcs,
telescope.
tel_header[
"Header.Source.Epoch"](0));
2034 fits_io->at(map_index).hdus.back()->addKey(
"UNIT", mb->sig_unit,
"Unit of map");
2038 fits_io->at(map_index).add_wcs(fits_io->at(map_index).hdus.back(), mb->wcs,
telescope.
tel_header[
"Header.Source.Epoch"](0));
2039 fits_io->at(map_index).hdus.back()->addKey(
"UNIT",
"1/("+mb->sig_unit+
")^2",
"Unit of map");
2040 if (
redu_type !=
"beammap" && std::fabs(mb->median_err(i)) > std::numeric_limits<double>::epsilon()) {
2041 fits_io->at(map_index).hdus.back()->addKey(
"MEDERR", pow(mb->median_err(i),0.5),
"Median Error ("+mb->sig_unit+
")");
2044 fits_io->at(map_index).hdus.back()->addKey(
"MEDERR", 0.0,
"Median Error ("+mb->sig_unit+
")");
2050 fits_io->at(map_index).hdus.back()->addKey(
"TYPE",
rtcproc.
kernel.
type,
"Kernel type");
2062 fits_io->at(map_index).hdus.back()->addKey(
"FWHM",fwhm,
"Kernel fwhm (arcsec)");
2063 fits_io->at(map_index).add_wcs(fits_io->at(map_index).hdus.back(), mb->wcs,
telescope.
tel_header[
"Header.Source.Epoch"](0));
2064 fits_io->at(map_index).hdus.back()->addKey(
"UNIT", mb->sig_unit,
"Unit of map");
2068 if (!mb->coverage.empty()) {
2070 fits_io->at(map_index).add_wcs(fits_io->at(map_index).hdus.back(), mb->wcs,
telescope.
tel_header[
"Header.Source.Epoch"](0));
2071 fits_io->at(map_index).hdus.back()->addKey(
"UNIT",
"sec",
"Unit of map");
2075 if (!mb->coverage.empty()) {
2077 Eigen::MatrixXd ones, zeros;
2078 ones.setOnes(mb->weight[i].rows(), mb->weight[i].cols());
2079 zeros.setZero(mb->weight[i].rows(), mb->weight[i].cols());
2082 auto [weight_threshold, cov_ranges, cov_n_rows, cov_n_cols] = mb->calc_cov_region(i);
2084 Eigen::MatrixXd coverage_bool = (mb->weight[i].array() < weight_threshold).select(zeros,ones);
2088 fits_io->at(map_index).add_wcs(fits_io->at(map_index).hdus.back(), mb->wcs,
telescope.
tel_header[
"Header.Source.Epoch"](0));
2089 fits_io->at(map_index).hdus.back()->addKey(
"UNIT",
"N/A",
"Unit of map");
2090 fits_io->at(map_index).hdus.back()->addKey(
"WTTHRESH", weight_threshold,
"Weight threshold");
2093 Eigen::MatrixXd sig2noise = mb->signal[i].array()*sqrt(mb->weight[i].array());
2095 fits_io->at(map_index).add_wcs(fits_io->at(map_index).hdus.back(), mb->wcs,
telescope.
tel_header[
"Header.Source.Epoch"](0));
2096 fits_io->at(map_index).hdus.back()->addKey(
"UNIT",
"N/A",
"Unit of map");
2100 if (!mb->noise.empty()) {
2101 for (Eigen::Index n=0; n<mb->n_noise; ++n) {
2102 Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> noise_matrix(mb->noise[i].data() + n * mb->n_rows * mb->n_cols,
2103 mb->n_rows, mb->n_cols);
2107 noise_fits_io->at(map_index).add_wcs(noise_fits_io->at(map_index).hdus.back(), mb->wcs,
telescope.
tel_header[
"Header.Source.Epoch"](0));
2108 noise_fits_io->at(map_index).hdus.back()->addKey(
"UNIT", mb->sig_unit,
"Unit of map");
2109 noise_fits_io->at(map_index).hdus.back()->addKey(
"MEDRMS", mb->median_rms[i],
"Median RMS of noise maps");
2114template <mapmaking::MapType map_t,
class map_buffer_t>
2117 std::string filename = setup_filenames<map_t,engine_utils::toltecIO::toltec,engine_utils::toltecIO::psd>(dir_name);
2120 netCDF::NcFile fo(filename +
".nc", netCDF::NcFile::replace);
2123 for (Eigen::Index i=0; i<mb->psds.size(); ++i) {
2136 netCDF::NcDim psd_dim = fo.addDim(name +
"_nfreq",mb->psds[i].size());
2137 netCDF::NcDim pds_2d_row_dim = fo.addDim(name +
"_rows",mb->psd_2ds[i].rows());
2138 netCDF::NcDim pds_2d_col_dim = fo.addDim(name +
"_cols",mb->psd_2ds[i].cols());
2140 std::vector<netCDF::NcDim> dims;
2141 dims.push_back(pds_2d_row_dim);
2142 dims.push_back(pds_2d_col_dim);
2145 netCDF::NcVar psd_v = fo.addVar(name +
"_psd",netCDF::ncDouble, psd_dim);
2146 psd_v.putVar(mb->psds[i].data());
2149 netCDF::NcVar psd_freq_v = fo.addVar(name +
"_psd_freq",netCDF::ncDouble, psd_dim);
2150 psd_freq_v.putVar(mb->psd_freqs[i].data());
2153 Eigen::MatrixXd psd_2d_transposed = mb->psd_2ds[i].transpose();
2154 Eigen::MatrixXd psd_2d_freq_transposed = mb->psd_2d_freqs[i].transpose();
2157 netCDF::NcVar psd_2d_v = fo.addVar(name +
"_psd_2d",netCDF::ncDouble, dims);
2158 psd_2d_v.putVar(psd_2d_transposed.data());
2161 netCDF::NcVar psd_2d_freq_v = fo.addVar(name +
"_psd_2d_freq",netCDF::ncDouble, dims);
2162 psd_2d_freq_v.putVar(psd_2d_freq_transposed.data());
2164 if (!mb->noise.empty()) {
2166 netCDF::NcDim noise_psd_dim = fo.addDim(name +
"_noise_nfreq",mb->noise_psds[i].size());
2167 netCDF::NcDim noise_pds_2d_row_dim = fo.addDim(name +
"_noise_rows",mb->noise_psd_2ds[i].rows());
2168 netCDF::NcDim noise_pds_2d_col_dim = fo.addDim(name +
"_noise_cols",mb->noise_psd_2ds[i].cols());
2170 std::vector<netCDF::NcDim> noise_dims;
2171 noise_dims.push_back(noise_pds_2d_row_dim);
2172 noise_dims.push_back(noise_pds_2d_col_dim);
2175 netCDF::NcVar noise_psd_v = fo.addVar(name +
"_noise_psd",netCDF::ncDouble, noise_psd_dim);
2176 noise_psd_v.putVar(mb->noise_psds[i].data());
2179 netCDF::NcVar noise_psd_freq_v = fo.addVar(name +
"_noise_psd_freq",netCDF::ncDouble, noise_psd_dim);
2180 noise_psd_freq_v.putVar(mb->noise_psd_freqs[i].data());
2183 Eigen::MatrixXd noise_psd_2d_transposed = mb->noise_psd_2ds[i].transpose();
2184 Eigen::MatrixXd noise_psd_2d_freq_transposed = mb->noise_psd_2d_freqs[i].transpose();
2187 netCDF::NcVar noise_psd_2d_v = fo.addVar(name +
"_noise_psd_2d",netCDF::ncDouble, noise_dims);
2188 noise_psd_2d_v.putVar(noise_psd_2d_transposed.data());
2191 netCDF::NcVar noise_psd_2d_freq_v = fo.addVar(name +
"_noise_psd_2d_freq",netCDF::ncDouble, noise_dims);
2192 noise_psd_2d_freq_v.putVar(noise_psd_2d_freq_transposed.data());
2199template <mapmaking::MapType map_t,
class map_buffer_t>
2201 std::string filename = setup_filenames<map_t,engine_utils::toltecIO::toltec,engine_utils::toltecIO::hist>(dir_name);
2203 netCDF::NcFile fo(filename +
".nc", netCDF::NcFile::replace);
2204 netCDF::NcDim hist_bins_dim = fo.addDim(
"n_bins", mb->hist_n_bins);
2207 for (Eigen::Index i=0; i<mb->hists.size(); ++i) {
2222 netCDF::NcVar hist_bins_v = fo.addVar(name +
"_bins",netCDF::ncDouble, hist_bins_dim);
2223 hist_bins_v.putVar(mb->hist_bins[i].data());
2226 netCDF::NcVar hist_v = fo.addVar(name +
"_hist",netCDF::ncDouble, hist_bins_dim);
2227 hist_v.putVar(mb->hists[i].data());
2229 if (!mb->noise.empty()) {
2231 netCDF::NcVar hist_v = fo.addVar(name +
"_noise_hist",netCDF::ncDouble, hist_bins_dim);
2232 hist_v.putVar(mb->noise_hists[i].data());
2254 std::map<std::string, std::string> det_stats_header_units {
2258 {
"flagged_frac",
"N/A"},
2262 std::map<std::string, std::string> grp_stats_header_units {
2266 netCDF::NcFile fo(stats_filename +
".nc", netCDF::NcFile::replace);
2269 netCDF::NcVar obsnum_v = fo.addVar(
"obsnum",netCDF::ncInt);
2270 obsnum_v.putAtt(
"units",
"N/A");
2271 int obsnum_int = std::stoi(
obsnum);
2272 obsnum_v.putVar(&obsnum_int);
2275 netCDF::NcDim n_dets_dim = fo.addDim(
"n_dets",
calib.
n_dets);
2276 netCDF::NcDim n_arrays_dim = fo.addDim(
"n_arrays",
calib.
n_arrays);
2279 std::vector<netCDF::NcDim> dims = {n_chunks_dim, n_dets_dim};
2280 std::vector<netCDF::NcDim> grp_dims = {n_chunks_dim, n_arrays_dim};
2284 netCDF::NcVar stat_v = fo.addVar(stat,netCDF::ncDouble, dims);
2286 stat_v.putAtt(
"units",det_stats_header_units[stat]);
2290 netCDF::NcVar stat_v = fo.addVar(stat,netCDF::ncDouble, grp_dims);
2292 stat_v.putAtt(
"units",grp_stats_header_units[stat]);
2297 netCDF::NcVar apt_v = fo.addVar(
"apt_" + x.first,netCDF::ncDouble, n_dets_dim);
2298 apt_v.putVar(x.second.data());
2306 std::vector<netCDF::NcDim> dims = {adc_snap_dim, adc_snap_data_dim};
2309 netCDF::NcVar adc_snap_v = fo.addVar(
"toltec" + std::to_string(
calib.
nws(i)) +
"_adc_snap_data",netCDF::ncDouble, dims);
2310 adc_snap_v.putVar(x.data());
2318 netCDF::NcDim n_eig_grp_dim = fo.addDim(
"n_eig_grp",
diagnostics.
evals[0][0].size());
2320 std::vector<netCDF::NcDim> eval_dims = {n_eig_grp_dim, n_eigs_dim};
2325 for (Eigen::Index i=0; i<val.size(); ++i) {
2328 "_chunk_" + std::to_string(key), netCDF::ncDouble,eval_dims);
2329 std::vector<std::size_t> start_eig_index = {0, 0};
2333 for (
const auto &evals: val[i]) {
2334 eval_v.putVar(start_eig_index,size,evals.data());
2335 start_eig_index[0] += 1;
2343template <mapmaking::MapType map_t,
class map_buffer_t>
2348 std::vector<fitsIO<file_type_enum::write_fits, CCfits::ExtHDU*>>* f_io =
nullptr;
2350 std::vector<fitsIO<file_type_enum::write_fits, CCfits::ExtHDU*>>* n_io =
nullptr;
2352 std::string dir_name;
2368 for (Eigen::Index i=0; i<f_io->size(); ++i) {
2374 if (!pmb->
noise.empty()) {
2380 for (Eigen::Index i=0; i<
n_maps; ++i) {
2394 tula::logging::progressbar pb(
2395 [&](
const auto &msg) {
logger->info(
"{}", msg); }, 100,
2398 for (Eigen::Index j=0; j<mb.n_noise; ++j) {
2400 pb.count(mb.n_noise, mb.n_noise / 100);
2404 logger->info(
"renormalizing errors");
2406 mb.calc_median_err();
2408 mb.calc_median_rms();
2411 auto noise_factor = (1./pow(mb.median_rms.array(),2.))*mb.median_err.array();
2413 mb.weight[i].noalias() = mb.weight[i]*noise_factor(i);
2415 logger->info(
"median rms {} ({})",
static_cast<float>(mb.median_rms(i)), mb.sig_unit);
2424 logger->info(
"file has been written to:");
2425 logger->info(
"{}.fits",f_io->at(map_index).filepath);
2428 bool close_file =
true;
2437 f_io->at(map_index).pfits->destroy();
2450template <mapmaking::MapType map_t,
class map_buffer_t>
2453 mb.n_sources.clear();
2454 mb.row_source_locs.clear();
2455 mb.col_source_locs.clear();
2457 for (Eigen::Index i=0; i<
n_maps; ++i) {
2459 mb.n_sources.push_back(0);
2460 mb.row_source_locs.push_back(Eigen::VectorXi::Ones(1));
2461 mb.col_source_locs.push_back(Eigen::VectorXi::Ones(1));
2464 mb.row_source_locs.back()*=-99;
2465 mb.col_source_locs.back()*=-99;
2468 auto sources_found = mb.find_sources(i);
2471 if (sources_found) {
2472 logger->info(
"{} source(s) found", mb.n_sources.back());
2475 logger->info(
"no sources found");
2480 Eigen::Index n_sources = 0;
2481 for (
const auto &sources: mb.n_sources) {
2482 n_sources += sources;
2493 for (Eigen::Index i=0; i<
n_maps; ++i) {
2495 if (mb.n_sources[i] > 0) {
2502 std::vector<int> source_in_vec, source_out_vec;
2504 source_in_vec.resize(mb.n_sources[i]);
2505 std::iota(source_in_vec.begin(), source_in_vec.end(), 0);
2506 source_out_vec.resize(mb.n_sources[i]);
2509 grppi::map(tula::grppi_utils::dyn_ex(
parallel_policy), source_in_vec, source_out_vec, [&](
auto j) {
2511 double init_row = mb.row_source_locs[i](j);
2512 double init_col = mb.col_source_locs[i](j);
2515 auto [params, perrors, good_fit] =
2517 init_fwhm, init_row, init_col);
2520 params(1) =
RAD_TO_ASEC*mb.pixel_size_rad*(params(1) - (mb.n_cols)/2);
2521 params(2) =
RAD_TO_ASEC*mb.pixel_size_rad*(params(2) - (mb.n_rows)/2);
2526 perrors(1) =
RAD_TO_ASEC*mb.pixel_size_rad*(perrors(1));
2527 perrors(2) =
RAD_TO_ASEC*mb.pixel_size_rad*(perrors(2));
2533 Eigen::VectorXd lat(1), lon(1);
2547 mb.source_params.row(k+j) = params;
2548 mb.source_perror.row(k+j) = perrors;
2554 k += mb.n_sources[i];
2559template <mapmaking::MapType map_t,
class map_buffer_t>
2566 std::vector<std::string> source_header = {
2587 std::map<std::string,std::string> source_header_units = {
2589 {
"amp", mb->sig_unit},
2590 {
"amp_err", mb->sig_unit},
2592 {
"x_t_err", pos_units},
2594 {
"y_t_err", pos_units},
2595 {
"a_fwhm",
"arcsec"},
2596 {
"a_fwhm_err",
"arcsec"},
2597 {
"b_fwhm",
"arcsec"},
2598 {
"b_fwhm_err",
"arcsec"},
2600 {
"angle_err",
"rad"},
2601 {
"sig2noise",
"N/A"}
2605 YAML::Node source_meta;
2608 for (Eigen::Index i=0; i<mb->obsnums.size(); ++i) {
2610 source_meta[
"obsnum" + std::to_string(i)] = mb->obsnums[i];
2620 source_meta[
"date"] =
date_obs.back();
2624 for (
const auto &[key,val]: source_header_units) {
2625 source_meta[key].push_back(
"units: " + val);
2628 source_meta[key].push_back(description);
2632 Eigen::Index n_sources = 0;
2633 for (
const auto &sources: mb->n_sources) {
2634 n_sources += sources;
2642 for (Eigen::Index i=0; i<mb->n_sources.size(); ++i) {
2643 if (mb->n_sources[i]!=0) {
2647 for (Eigen::Index j=0; j<mb->n_sources[i]; ++j) {
2660 source_table.col(i) = mb->source_params.col(j).template cast <float> ();
2661 source_table.col(i+1) = mb->source_perror.col(j).template cast <float> ();
Eigen::Index hwpr_start_indices
Definition engine.h:201
void obsnum_setup()
Definition engine.h:346
std::string obsnum_dir_name
Definition engine.h:177
void write_stats()
Definition engine.h:2239
std::string parallel_policy
Definition engine.h:189
void write_map_summary(map_buffer_t &)
Definition engine.h:1574
std::string redu_dir_name
Definition engine.h:171
std::map< std::string, Eigen::VectorXd > pointing_offsets_arcsec
Definition engine.h:234
std::vector< fitsIO< file_type_enum::write_fits, CCfits::ExtHDU * > > filtered_coadd_fits_io_vec
Definition engine.h:244
std::vector< Eigen::Index > start_indices
Definition engine.h:198
void create_tod_files()
Definition engine.h:1266
void write_psd(map_buffer_t &, std::string)
Definition engine.h:2115
int redu_dir_num
Definition engine.h:174
auto get_map_name(int)
Definition engine.h:1692
std::vector< fitsIO< file_type_enum::write_fits, CCfits::ExtHDU * > > noise_fits_io_vec
Definition engine.h:239
std::vector< fitsIO< file_type_enum::write_fits, CCfits::ExtHDU * > > coadd_noise_fits_io_vec
Definition engine.h:243
void get_beammap_config(CT &)
Definition engine.h:660
key_vec_t invalid_keys
Definition engine.h:183
std::string tod_output_type
Definition engine.h:216
auto setup_filenames(std::string dir_name)
Definition engine.h:1664
std::string tod_output_subdir_name
Definition engine.h:216
void create_obs_map_files()
Definition engine.h:981
key_vec_t missing_keys
Definition engine.h:183
std::string coadd_dir_name
Definition engine.h:177
std::vector< fitsIO< file_type_enum::write_fits, CCfits::ExtHDU * > > filtered_noise_fits_io_vec
Definition engine.h:240
void get_mapmaking_config(CT &)
Definition engine.h:552
Eigen::VectorXI maps_to_arrays
Definition engine.h:225
int fruit_iter
Definition engine.h:231
bool verbose_mode
Definition engine.h:165
int n_maps
Definition engine.h:222
Eigen::VectorXI arrays_to_maps
Definition engine.h:225
std::vector< fitsIO< file_type_enum::write_fits, CCfits::ExtHDU * > > filtered_fits_io_vec
Definition engine.h:240
void run_wiener_filter(map_buffer_t &)
Definition engine.h:2344
std::string output_dir
Definition engine.h:171
int n_scans_done
Definition engine.h:192
void add_tod_header()
Definition engine.h:1044
bool write_filtered_maps_partial
Definition engine.h:213
Eigen::Index hwpr_end_indices
Definition engine.h:201
std::vector< Eigen::Index > end_indices
Definition engine.h:198
void write_hist(map_buffer_t &, std::string)
Definition engine.h:2200
std::vector< fitsIO< file_type_enum::write_fits, CCfits::ExtHDU * > > filtered_coadd_noise_fits_io_vec
Definition engine.h:244
void add_phdu(fits_io_type &, map_buffer_t &, Eigen::Index)
Definition engine.h:1727
std::string redu_type
Definition engine.h:207
std::map< std::string, int > gaps
Definition engine.h:168
std::string map_grouping
Definition engine.h:219
std::shared_ptr< spdlog::logger > logger
Definition engine.h:159
void get_citlali_config(CT &)
Definition engine.h:765
std::map< std::string, std::string > tod_filename
Definition engine.h:180
void write_sources(map_buffer_t &, std::string)
Definition engine.h:2560
void get_timestream_config(CT &)
Definition engine.h:490
std::string tod_type
Definition engine.h:204
void cli_summary()
Definition engine.h:1453
Eigen::VectorXI maps_to_stokes
Definition engine.h:228
void get_astrometry_config(CT &)
Definition engine.h:955
void get_photometry_config(CT &)
Definition engine.h:921
void get_rtc_config(CT &)
Definition engine.h:459
std::string obsnum
Definition engine.h:210
std::vector< fitsIO< file_type_enum::write_fits, CCfits::ExtHDU * > > coadd_fits_io_vec
Definition engine.h:243
void find_sources(map_buffer_t &)
Definition engine.h:2451
std::map< std::string, double > interface_sync_offset
Definition engine.h:195
std::vector< std::string > date_obs
Definition engine.h:162
void write_chunk_summary(TCData< tc_t, Eigen::MatrixXd > &)
Definition engine.h:1519
Eigen::ArrayXd pointing_offsets_modified_julian_date
Definition engine.h:236
void get_ptc_config(CT &)
Definition engine.h:479
std::vector< fitsIO< file_type_enum::write_fits, CCfits::ExtHDU * > > fits_io_vec
Definition engine.h:239
int n_threads
Definition engine.h:186
std::string map_method
Definition engine.h:219
std::vector< std::vector< std::string > > key_vec_t
Definition engine.h:156
void get_map_filter_config(CT &)
Definition engine.h:730
void write_maps(fits_io_type &, fits_io_type &, map_buffer_t &, Eigen::Index)
Definition engine.h:2018
Eigen::VectorXI fg
Definition calib.h:29
bool run_hwpr
Definition calib.h:41
std::string ignore_hwpr
Definition calib.h:32
Eigen::Index n_arrays
Definition calib.h:53
std::map< Eigen::Index, double > array_pas
Definition calib.h:62
std::map< Eigen::Index, double > array_beam_areas
Definition calib.h:65
Eigen::VectorXI nws
Definition calib.h:44
Eigen::VectorXI arrays
Definition calib.h:44
std::map< std::string, std::string > apt_header_units
Definition calib.h:116
std::string apt_filepath
Definition calib.h:20
std::map< std::string, Eigen::VectorXd > apt
Definition calib.h:22
std::map< std::string, std::string > apt_header_description
Definition calib.h:151
std::map< Eigen::Index, std::tuple< double, double > > array_fwhms
Definition calib.h:59
Eigen::Index n_dets
Definition calib.h:47
Definition diagnostics.h:14
std::map< Eigen::Index, std::vector< std::vector< Eigen::VectorXd > > > evals
Definition diagnostics.h:45
bool write_evals
Definition diagnostics.h:25
std::vector< std::string > grp_stats_header
Definition diagnostics.h:40
std::map< std::string, Eigen::MatrixXd > stats
Definition diagnostics.h:16
std::vector< std::string > det_stats_header
Definition diagnostics.h:31
std::vector< Eigen::Matrix< short, Eigen::Dynamic, Eigen::Dynamic > > adc_snap_data
Definition diagnostics.h:19
Definition telescope.h:12
bool sim_obs
Definition telescope.h:20
std::map< std::string, Eigen::VectorXd > tel_data
Definition telescope.h:54
double fsmp
Definition telescope.h:42
std::string chunk_mode
Definition telescope.h:30
std::string obs_goal
Definition telescope.h:23
std::string source_name
Definition telescope.h:23
double tau_225_GHz
Definition telescope.h:45
Eigen::MatrixXI scan_indices
Definition telescope.h:51
std::string project_id
Definition telescope.h:23
bool force_chunk
Definition telescope.h:36
std::string pixel_axes
Definition telescope.h:59
std::map< std::string, Eigen::VectorXd > tel_header
Definition telescope.h:56
double chunking_value
Definition telescope.h:33
Eigen::Index inner_scans_chunk
Definition telescope.h:48
double bounding_box_pix
Definition fitting.h:26
auto fit_to_gaussian(Eigen::DenseBase< Derived > &, Eigen::DenseBase< Derived > &, double, double, double)
Definition fitting.h:172
int n_params
Definition fitting.h:23
double fwhm_low
Definition fitting.h:38
double flux_low
Definition fitting.h:33
double fitting_region_pix
Definition fitting.h:27
bool fit_angle
Definition fitting.h:43
@ pointing
Definition fitting.h:18
double fwhm_high
Definition fitting.h:40
double flux_high
Definition fitting.h:35
Eigen::VectorXd fwhm_limits
Definition fitting.h:30
Eigen::VectorXd flux_limits
Definition fitting.h:30
Definition toltec_io.h:10
ProdType
Definition toltec_io.h:21
@ map
Definition toltec_io.h:22
@ stats
Definition toltec_io.h:28
@ ptc_timestream
Definition toltec_io.h:27
@ rtc_timestream
Definition toltec_io.h:26
@ noise
Definition toltec_io.h:23
std::map< Eigen::Index, std::string > array_name_map
Definition toltec_io.h:54
std::map< Eigen::Index, double > array_freq_map
Definition toltec_io.h:68
std::map< Eigen::Index, double > array_wavelength_map
Definition toltec_io.h:61
DataType
Definition toltec_io.h:13
@ source
Definition toltec_io.h:17
@ toltec
Definition toltec_io.h:14
@ filtered
Definition toltec_io.h:34
@ raw
Definition toltec_io.h:33
std::string create_filename(const std::string, const std::string, std::string, std::string, const bool)
Definition toltec_io.h:86
std::map< Eigen::Index, double > array_fwhm_arcsec
Definition toltec_io.h:75
void calculate_jinc_splines()
Definition jinc_mm.h:152
std::string mode
Definition jinc_mm.h:56
std::map< Eigen::Index, Eigen::VectorXd > shape_params
Definition jinc_mm.h:68
double r_max
Definition jinc_mm.h:62
void allocate_jinc_matrix(double)
Definition jinc_mm.h:118
std::string parallel_policy
Definition jinc_mm.h:53
bool run_polarization
Definition jinc_mm.h:50
double tolerance
Definition ml_mm.h:27
int max_iterations
Definition ml_mm.h:28
WCS wcs
Definition map.h:48
double exposure_time
Definition map.h:75
std::string sig_unit
Definition map.h:73
double source_window_rad
Definition map.h:128
Eigen::Index n_rows
Definition map.h:65
std::string parallel_policy
Definition map.h:59
Eigen::Index n_cols
Definition map.h:65
std::vector< Eigen::MatrixXd > coverage
Definition map.h:78
std::vector< Eigen::MatrixXd > signal
Definition map.h:78
std::string source_finder_mode
Definition map.h:123
std::vector< Eigen::MatrixXd > weight
Definition map.h:78
bool randomize_dets
Definition map.h:87
std::vector< Eigen::MatrixXd > kernel
Definition map.h:78
Eigen::Index n_noise
Definition map.h:67
void get_config(tula::config::YamlConfig &, std::vector< std::vector< std::string > > &, std::vector< std::vector< std::string > > &, std::string, std::string)
Definition map.cpp:15
double source_sigma
Definition map.h:126
std::vector< Eigen::Tensor< double, 3 > > noise
Definition map.h:81
double pixel_size_rad
Definition map.h:69
bool run_polarization
Definition naive_mm.h:52
Definition wiener_filter.h:23
void filter_noise(MB &mb, const int, const int)
Definition wiener_filter.h:939
std::string template_type
Definition wiener_filter.h:29
std::string parallel_policy
Definition wiener_filter.h:59
std::map< std::string, double > template_fwhm_rad
Definition wiener_filter.h:50
std::string filter_type
Definition wiener_filter.h:29
bool normalize_error
Definition wiener_filter.h:31
void filter_maps(MB &, const int)
Definition wiener_filter.h:870
double init_fwhm
Definition wiener_filter.h:47
engine_utils::mapFitter map_fitter
Definition wiener_filter.h:69
void get_config(config_t &, std::vector< std::vector< std::string > > &, std::vector< std::vector< std::string > > &)
Definition wiener_filter.h:126
void make_template(MB &, CD &c, const double, const int)
Definition wiener_filter.h:694
bool run_lowpass
Definition wiener_filter.h:35
auto calc_tau(Eigen::DenseBase< Derived > &, double)
Definition calibrate.h:128
void setup(double tau_225_zenith)
Definition calibrate.h:30
std::string extinction_model
Definition calibrate.h:18
std::map< Eigen::Index, Eigen::VectorXI > n_eig_to_cut
Definition clean.h:27
int n_calc
Definition clean.h:30
std::vector< std::string > grouping
Definition clean.h:36
double fsmp
Definition despike.h:22
void make_filter(double)
Definition filter.h:34
Eigen::Index n_terms
Definition filter.h:19
std::string type
Definition kernel.h:15
std::string map_grouping
Definition kernel.h:28
double fwhm_rad
Definition kernel.h:22
void setup(Eigen::Index)
Definition kernel.h:50
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
double lower_weight_factor
Definition ptcproc.h:26
std::string weighting_type
Definition ptcproc.h:28
double med_weight_factor
Definition ptcproc.h:24
std::map< int, std::string > stokes_params
Definition polarization.h:15
bool run_polarization
Definition rtcproc.h:23
bool run_kernel
Definition rtcproc.h:24
void get_config(config_t &, std::vector< std::vector< std::string > > &, std::vector< std::vector< std::string > > &)
Definition rtcproc.h:71
bool run_calibrate
Definition rtcproc.h:28
bool run_downsample
Definition rtcproc.h:27
timestream::Filter filter
Definition rtcproc.h:35
bool run_tod_filter
Definition rtcproc.h:26
bool run_despike
Definition rtcproc.h:25
bool run_extinction
Definition rtcproc.h:29
timestream::Calibration calibration
Definition rtcproc.h:37
timestream::Despiker despiker
Definition rtcproc.h:34
timestream::Kernel kernel
Definition rtcproc.h:33
timestream::Polarization polarization
Definition rtcproc.h:32
std::string fruit_loops_path
Definition timestream.h:281
double upper_inv_var_factor
Definition timestream.h:302
double fruit_loops_sig2noise
Definition timestream.h:289
bool run_tod_output
Definition timestream.h:276
bool write_evals
Definition timestream.h:276
int fruit_loops_iters
Definition timestream.h:287
bool run_fruit_loops
Definition timestream.h:279
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 ¶m, 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
#define DEG_TO_RAD
Definition constants.h:27
#define MJY_SR_TO_mJY_ASEC
Definition constants.h:51
#define STD_TO_FWHM
Definition constants.h:45
#define FWHM_TO_STD
Definition constants.h:48
#define RAD_TO_ASEC
Definition constants.h:36
#define ASEC_TO_RAD
Definition constants.h:33
#define RAD_TO_DEG
Definition constants.h:30
#define ASEC_TO_DEG
Definition constants.h:24
constexpr auto pi
Definition constants.h:6
void to_ecsv_from_matrix(std::string filepath, Eigen::DenseBase< Derived > &table, std::vector< std::string > header, YAML::Node meta)
Definition ecsv_io.h:50
static const double mJy_beam_to_uK(const double flux_mjy_beam, const double freq_Hz, const double fwhm)
Definition utils.h:77
auto tangent_to_abs(Eigen::DenseBase< Derived > &lat, Eigen::DenseBase< Derived > &lon, const double cra, const double cdec)
Definition pointing.h:88
static const int get_phys_memory()
Definition utils.h:56
static const std::string current_date_time()
Definition utils.h:91
auto calc_std_dev(Eigen::DenseBase< DerivedA > &data)
Definition utils.h:336
MapType
Definition map.h:17
@ FilteredObs
Definition map.h:19
@ FilteredCoadd
Definition map.h:21
@ RawObs
Definition map.h:18
@ RawCoadd
Definition map.h:20
void add_netcdf_var(netCDF::NcFile &fo, std::string name, T data)
Definition netcdf_io.h:11
bool beammap_subtract_reference
Definition engine.h:131
std::map< std::string, double > lower_sig2noise
Definition engine.h:146
std::map< std::string, double > beammap_fluxes_mJy_beam
Definition engine.h:121
Eigen::Index beammap_reference_det
Definition engine.h:134
std::map< std::string, double > upper_fwhm_arcsec
Definition engine.h:146
std::map< std::string, double > max_dist_arcsec
Definition engine.h:147
double lower_sens_factor
Definition engine.h:150
std::map< std::string, double > lower_fwhm_arcsec
Definition engine.h:146
double beammap_dec_rad
Definition engine.h:118
Eigen::VectorXd sens_psd_limits_Hz
Definition engine.h:143
int beammap_tod_output_iter
Definition engine.h:140
std::string beammap_source_name
Definition engine.h:115
std::map< std::string, double > beammap_err_MJy_Sr
Definition engine.h:122
double beammap_ra_rad
Definition engine.h:118
std::map< std::string, double > beammap_fluxes_MJy_Sr
Definition engine.h:122
int beammap_iter_max
Definition engine.h:125
bool beammap_derotate
Definition engine.h:137
std::map< std::string, double > upper_sig2noise
Definition engine.h:147
double beammap_iter_tolerance
Definition engine.h:128
std::map< std::string, double > beammap_err_mJy_beam
Definition engine.h:121
double upper_sens_factor
Definition engine.h:150
std::vector< float > crval
Definition map.h:36
mapmaking::NaiveMapmaker naive_mm
Definition engine.h:107
engine::Telescope telescope
Definition engine.h:94
engine_utils::mapFitter map_fitter
Definition engine.h:97
mapmaking::MLMapmaker ml_mm
Definition engine.h:109
mapmaking::WienerFilter wiener_filter
Definition engine.h:110
engine::Diagnostics diagnostics
Definition engine.h:96
engine_utils::toltecIO toltec_io
Definition engine.h:95
timestream::PTCProc ptcproc
Definition engine.h:103
mapmaking::JincMapmaker jinc_mm
Definition engine.h:108
mapmaking::MapBuffer omb
Definition engine.h:106
mapmaking::MapBuffer cmb
Definition engine.h:106
timestream::RTCProc rtcproc
Definition engine.h:100
engine::Calib calib
Definition engine.h:93
bool run_noise
Definition engine.h:84
bool use_subdir
Definition engine.h:73
bool run_coadd
Definition engine.h:83
bool run_map_filter
Definition engine.h:85
bool run_source_finder
Definition engine.h:88
bool run_tod_output
Definition engine.h:79
bool run_mapmaking
Definition engine.h:82
bool run_tod
Definition engine.h:76
TC data class.
Definition timestream.h:55