Citlali
Loading...
Searching...
No Matches
jinc_mm.h
Go to the documentation of this file.
1#pragma once
2
3#include <thread>
4
5#include <boost/math/special_functions/bessel.hpp>
6
7#include <unsupported/Eigen/Splines>
8#include <Eigen/Sparse>
9
12
14
17
18
20
21// selects the type of TCData
22using timestream::TCDataKind;
23
24namespace mapmaking {
25
27public:
28 // get logger
29 std::shared_ptr<spdlog::logger> logger = spdlog::get("citlali_logger");
30 std::unique_ptr<std::mutex> jinc_mutex = std::make_unique<std::mutex>();
31
32 // toltec array mounting angle
33 std::map<int, double> install_ang = {
34 {-1,-1},
35 {0,pi/2},
36 {1,-pi/2},
37 {2,-pi/2},
38 };
39
40 // toltec detector orientation angles
41 std::map<int, double> fgs = {
42 {-1,-1},
43 {0,0},
44 {1,pi/4},
45 {2,pi/2},
46 {3,3*pi/4}
47 };
48
49 // run polarization?
51
52 // parallel policy
53 std::string parallel_policy;
54
55 // method to calculate jinc weights
56 std::string mode = "matrix";
57
58 // lambda over diameter
59 std::map<Eigen::Index,double> l_d;
60
61 // maximum radius
62 double r_max;
63
64 // number of points for spline
65 int n_pts_splines = 1000;
66
67 // jinc filter shape parameters
68 std::map<Eigen::Index,Eigen::VectorXd> shape_params;
69
70 // matrices to hold precomputed jinc function
71 std::map<Eigen::Index,Eigen::MatrixXd> jinc_weights_mat;
72
73 // splines for jinc function
74 std::map<Eigen::Index, engine_utils::SplineFunction> jinc_splines;
75
76 // calculate jinc weight at a given radius
77 auto jinc_func(double, double, double, double, double, double);
78
79 // precompute jinc weight matrix
80 void allocate_jinc_matrix(double);
81
82 // calculate spline function for jinc weights
84
85 // allocate pointing matrix for polarization reduction
86 template <class map_buffer_t>
87 void allocate_pointing(map_buffer_t &, double, double, double, Eigen::Index, int, int);
88
89 // populate maps with a time chunk (signal, kernel, coverage, and noise)
90 template<class map_buffer_t, typename Derived, typename apt_t>
91 void populate_maps_jinc(TCData<TCDataKind::PTC, Eigen::MatrixXd> &, map_buffer_t &, map_buffer_t &,
92 Eigen::DenseBase<Derived> &, std::string &, apt_t &, double, bool, bool);
93
94 // populate maps with a time chunk (signal, kernel, coverage, and noise)
95 template<class map_buffer_t, typename Derived, typename apt_t>
96 void populate_maps_jinc_parallel(TCData<TCDataKind::PTC, Eigen::MatrixXd> &, map_buffer_t &, map_buffer_t &,
97 Eigen::DenseBase<Derived> &, std::string &, apt_t &, double, bool, bool);
98};
99
100auto JincMapmaker::jinc_func(double r, double a, double b, double c, double r_max, double l_d) {
101 if (r!=0) {
102 // unitless radius
103 r = r/l_d;
104 // first jinc function
105 auto jinc_1 = 2.*boost::math::cyl_bessel_j(1,2.*pi*r/a)/(2.*pi*r/a);
106 // exponential
107 auto exp_func = exp(-pow(2.*r/b,c));
108 // second jinc function
109 auto jinc_2 = 2.*boost::math::cyl_bessel_j(1,3.831706*r/r_max)/(3.831706*r/r_max);
110 // jinc1 x exp x jinc2
111 return jinc_1*exp_func*jinc_2;
112 }
113 else {
114 return 1.0;
115 }
116}
117
118void JincMapmaker::allocate_jinc_matrix(double pixel_size_rad) {
119 l_d[0] = (1.1/1000)/50;
120 l_d[1] = (1.4/1000)/50;
121 l_d[2] = (2.0/1000)/50;
122
123 // loop through lambda/diameters
124 for (const auto &ld: l_d) {
125 // get shape params
126 auto a = shape_params[ld.first](0);
127 auto b = shape_params[ld.first](1);
128 auto c = shape_params[ld.first](2);
129
130 // maximum radius in pixels
131 int r_max_pix = std::floor(r_max*ld.second/pixel_size_rad);
132
133 // pixel centers within max radius
134 Eigen::VectorXd pixels = Eigen::VectorXd::LinSpaced(2*r_max_pix + 1,-r_max_pix, r_max_pix);
135
136 // allocate jinc weights
137 jinc_weights_mat[ld.first].setZero(2*r_max_pix + 1,2*r_max_pix + 1);
138
139 // loop through matrix rows
140 for (Eigen::Index i=0; i<pixels.size(); ++i) {
141 // loop through matrix cols
142 for (Eigen::Index j=0; j<pixels.size(); ++j) {
143 // radius of current pixel in radians
144 double r = pixel_size_rad*sqrt(pow(pixels(i),2) + pow(pixels(j),2));
145 // calculate jinc weight at pixel
146 jinc_weights_mat[ld.first](i,j) = jinc_func(r,a,b,c,r_max,ld.second);
147 }
148 }
149 }
150}
151
153 l_d[0] = (1.1/1000)/50;
154 l_d[1] = (1.4/1000)/50;
155 l_d[2] = (2.0/1000)/50;
156
157 // loop through lambda/diameters
158 for (const auto &ld: l_d) {
159 // get shape params
160 auto a = shape_params[ld.first](0);
161 auto b = shape_params[ld.first](1);
162 auto c = shape_params[ld.first](2);
163
164 // radius vector in radians
165 auto radius = Eigen::VectorXd::LinSpaced(n_pts_splines, 0, r_max*ld.second);
166 // jinc weights on dense vector
167 Eigen::VectorXd jinc_weights(radius.size());
168
169 Eigen::Index j = 0;
170
171 for (const auto &r: radius) {
172 // calculate jinc weights
173 jinc_weights(j) = jinc_func(r,a,b,c,r_max,ld.second);
174 ++j;
175 }
176 // create spline class
178 // spline interpolate
179 s.interpolate(radius, jinc_weights);
180 // store jinc spline
181 jinc_splines[ld.first] = s;
182 }
183}
184
185template <class map_buffer_t>
186void JincMapmaker::allocate_pointing(map_buffer_t &mb, double weight, double cos_2angle, double sin_2angle,
187 Eigen::Index map_index, int ir, int ic) {
188 int pix = mb.n_rows * ic + ir;
189 Eigen::MatrixXd& matrix = mb.pointing[map_index];
190
191 // calculate reused expressions
192 double weight_cos_2angle = weight * cos_2angle;
193 double weight_sin_2angle = weight * sin_2angle;
194 double weight_cos2_2angle = weight * std::pow(cos_2angle, 2);
195 double weight_sin2_2angle = weight * std::pow(sin_2angle, 2);
196 double weight_cos_sin_2angle = weight * cos_2angle * sin_2angle;
197
198 // update pointing matrix
199 matrix(pix, 0) += weight;
200 matrix(pix, 1) += weight_cos_2angle;
201 matrix(pix, 2) += weight_sin_2angle;
202 matrix(pix, 3) = matrix(pix, 1); // previously set to += weight*cos_2angle, then directly assigned here
203 matrix(pix, 4) += weight_cos2_2angle;
204 matrix(pix, 5) += weight_cos_sin_2angle;
205 matrix(pix, 6) = matrix(pix, 2); // previously set to += weight*sin_2angle, then directly assigned here
206 matrix(pix, 7) = matrix(pix, 5); // reuse the result from matrix(pix,5)
207 matrix(pix, 8) += weight_sin2_2angle;
208}
209
210template<class map_buffer_t, typename Derived, typename apt_t>
212 map_buffer_t &omb, map_buffer_t &cmb, Eigen::DenseBase<Derived> &map_indices,
213 std::string &pixel_axes, apt_t &apt, double d_fsmp, bool run_omb, bool run_noise) {
214
215 const bool use_cmb = !cmb.noise.empty();
216 const bool use_omb = !omb.noise.empty();
217 const bool run_kernel = !omb.kernel.empty();
218 const bool run_coverage = !omb.coverage.empty();
219 const bool run_hwpr = in.hwpr_angle.data.size()!=0;
220
221 // dimensions of data
222 Eigen::Index n_dets = in.scans.data.cols();
223 Eigen::Index n_pts = in.scans.data.rows();
224
225 // step to skip to reach next stokes param
226 int step = omb.pointing.size();
227
228 map_buffer_t omb_copy;
229 omb_copy.n_rows = omb.n_rows;
230 omb_copy.n_cols = omb.n_cols;
231
232 for (Eigen::Index i=0; i<omb.signal.size(); ++i) {
233 if (run_omb) {
234 omb_copy.signal.emplace_back(Eigen::MatrixXd::Zero(omb.n_rows, omb.n_cols));
235 omb_copy.weight.emplace_back(Eigen::MatrixXd::Zero(omb.n_rows, omb.n_cols));
236
237 // clear coverage
238 if (run_coverage) {
239 omb_copy.coverage.emplace_back(Eigen::MatrixXd::Zero(omb.n_rows, omb.n_cols));
240 }
241 // clear kernel
242 if (run_kernel) {
243 omb_copy.kernel.emplace_back(Eigen::MatrixXd::Zero(omb.n_rows, omb.n_cols));
244 }
245 }
246 }
247 // clear noise
248 if (use_omb) {
249 omb_copy.noise = omb.noise;
250 for (Eigen::Index i=0; i<omb.signal.size(); ++i) {
251 omb_copy.noise[i].setZero();
252 }
253 }
254
255 map_buffer_t cmb_copy;
256
257 if (use_cmb) {
258 cmb_copy.n_rows = cmb.n_rows;
259 cmb_copy.n_cols = cmb.n_cols;
260
261 cmb_copy.noise = cmb.noise;
262
263 for (Eigen::Index i=0; i<cmb.noise.size(); ++i) {
264 cmb_copy.noise[i].setZero();
265 }
266 }
267
268 // pointer to map buffer with noise maps
269 map_buffer_t *nmb, *nmb_copy;
270
271 if (run_noise) {
272 nmb = use_cmb ? &cmb : (use_omb ? &omb : nullptr);
273 nmb_copy = use_cmb ? &cmb_copy : (use_omb ? &omb_copy : nullptr);
274 }
275
276 // add detector to map?
277 bool run_det;
278
279 // parallelize over detectors
280 for (Eigen::Index i=0; i<n_dets; ++i) {
281 // skip fg = -1 if in polarization mode
282 if (run_polarization && apt["fg"](i)==-1) {
283 run_det = false;
284 }
285 else {
286 run_det = true;
287 }
288
289 // skip completely flagged detectors
290 if ((in.flags.data.col(i).array()==false).any()) {
291 // get detector positions from apt table if not in detector mapmaking mode
292 auto det_index = i;
293
294 // which map to assign detector to
295 Eigen::Index map_index = map_indices(i);
296 // indices for Q and U maps
297 int q_index = map_index + step;
298 int u_index = map_index + 2 * step;
299 Eigen::Index array_index = apt["array"](det_index);
300 Eigen::Index mat_rows = jinc_weights_mat[array_index].rows();
301 Eigen::Index mat_cols = jinc_weights_mat[array_index].cols();
302 Eigen::Index mat_rows_center = (mat_rows - 1.)/2.;
303 Eigen::Index mat_cols_center = (mat_cols - 1.)/2.;
304
305 // get detector pointing
306 auto [lat, lon] = engine_utils::calc_det_pointing(in.tel_data.data, apt["x_t"](det_index), apt["y_t"](det_index),
307 pixel_axes, in.pointing_offsets_arcsec.data, omb.map_grouping);
308
309 // get map buffer row and col indices for lat and lon vectors
310 Eigen::VectorXd omb_irow = lat.array()/omb.pixel_size_rad + (omb.n_rows)/2.;
311 Eigen::VectorXd omb_icol = lon.array()/omb.pixel_size_rad + (omb.n_cols)/2.;
312
313 Eigen::VectorXd cmb_irow, cmb_icol;
314 if (use_cmb) {
315 // get coadded map buffer row and col indices for lat and lon vectors
316 cmb_irow = lat.array()/cmb.pixel_size_rad + (cmb.n_rows)/2.;
317 cmb_icol = lon.array()/cmb.pixel_size_rad + (cmb.n_cols)/2.;
318 }
319
320 // signal map value
321 double signal;
322
323 // noise map value
324 double noise_v;
325
326 // noise map indices
327 Eigen::Index nmb_ir, nmb_ic;
328
329 // cosine and sine of angles
330 double angle, cos_2angle, sin_2angle;
331
332 // loop through the samples
333 for (Eigen::Index j=0; j<n_pts; ++j) {
334 // check if sample is flagged, ignore if so
335 if (!in.flags.data(j,i)) {
336 Eigen::Index omb_ir = omb_irow(j);
337 Eigen::Index omb_ic = omb_icol(j);
338
339 if (run_polarization) {
340 auto fg_index = apt["fg"](det_index);
341 if (run_hwpr) {
342 angle = 2*in.hwpr_angle.data(j) - (in.angle.data(j) + fgs[fg_index] + install_ang[array_index]);
343 }
344 else {
345 angle = in.angle.data(j) + fgs[fg_index] + install_ang[array_index];
346 }
347
348 cos_2angle = cos(2.*angle);
349 sin_2angle = sin(2.*angle);
350 }
351
352 if (run_omb) {
353 // make sure the data point is within the map
354 if ((omb_ir >= 0) && (omb_ir < omb.n_rows) && (omb_ic >= 0) && (omb_ic < omb.n_cols)) {
355
356 int lower_row = omb_ir - mat_rows_center;
357 int upper_row = omb_ir + mat_rows - 1 - mat_rows_center;
358 int lower_col = omb_ic - mat_cols_center;
359 int upper_col = omb_ic + mat_cols - 1 - mat_cols_center;
360
361 int jinc_lower_row = abs(std::min(0, lower_row));
362 int jinc_lower_col = abs(std::min(0, lower_col));
363
364 lower_row = std::max(0,lower_row);
365 upper_row = std::min(static_cast<int>(omb.n_rows - 1),upper_row);
366 lower_col = std::max(0,lower_col);
367 upper_col = std::min(static_cast<int>(omb.n_cols - 1),upper_col);
368
369 int size_rows = upper_row - lower_row + 1;
370 int size_cols = upper_col - lower_col + 1;
371
372 const auto mat_block = jinc_weights_mat[array_index].block(jinc_lower_row,jinc_lower_col,size_rows,size_cols);
373
374 auto sig_block = omb_copy.signal[map_index].block(lower_row,lower_col,size_rows,size_cols);
375 auto wt_block = omb_copy.weight[map_index].block(lower_row,lower_col,size_rows,size_cols);
376
377 // populate signal map
378 sig_block += (mat_block * in.weights.data(i) * in.scans.data(j,i)).eval();
379
380 // populate weight map
381 wt_block += (mat_block * in.weights.data(i)).eval();
382
383 // populate coverage map
384 if (run_coverage) {
385 auto cov_block = omb_copy.coverage[map_index].block(lower_row,lower_col,size_rows,size_cols);
386 cov_block += mat_block/d_fsmp;
387 }
388
389 // populate kernel map
390 if (run_kernel) {
391 auto ker_block = omb_copy.kernel[map_index].block(lower_row,lower_col,size_rows,size_cols);
392 ker_block += mat_block*in.weights.data(i)*in.kernel.data(j,i);
393 }
394 }
395 }
396
397 // check if noise maps requested
398 if (run_noise) {
399 // if coaddition is enabled
400 if (use_cmb) {
401 nmb_ir = cmb_irow(j);
402 nmb_ic = cmb_icol(j);
403 }
404
405 // else make noise maps for obs
406 else {
407 nmb_ir = omb_irow(j);
408 nmb_ic = omb_icol(j);
409 }
410
411 // make sure pixel is in the map
412 if ((nmb_ir >= 0) && (nmb_ir < nmb->n_rows) && (nmb_ic >= 0) && (nmb_ic < nmb->n_cols)) {
413
414 int lower_row = nmb_ir - mat_rows_center;
415 int upper_row = nmb_ir + mat_rows - 1 - mat_rows_center;
416 int lower_col = nmb_ic - mat_cols_center;
417 int upper_col = nmb_ic + mat_cols - 1 - mat_cols_center;
418
419 int jinc_lower_row = abs(std::min(0, lower_row));
420 int jinc_lower_col = abs(std::min(0, lower_col));
421
422 lower_row = std::max(0,lower_row);
423 upper_row = std::min(static_cast<int>(nmb->n_rows - 1),upper_row);
424 lower_col = std::max(0,lower_col);
425 upper_col = std::min(static_cast<int>(nmb->n_cols - 1),upper_col);
426
427 int size_rows = upper_row - lower_row + 1;
428 int size_cols = upper_col - lower_col + 1;
429
430 const auto mat_block = jinc_weights_mat[array_index].block(jinc_lower_row,jinc_lower_col,size_rows,size_cols);
431 signal = in.scans.data(j,i)*in.weights.data(i);
432
433 for (Eigen::Index nn=0; nn<nmb->n_noise; ++nn) {
434 // randomizing on dets
435 if (nmb->randomize_dets) {
436 noise_v = in.noise.data(nn,i)*signal;
437 }
438 else {
439 noise_v = in.noise.data(nn)*signal;
440 }
441 Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> noise_matrix(nmb_copy->noise[map_index].data() + nn * nmb->n_rows * nmb->n_cols,
442 nmb->n_rows, nmb->n_cols);
443 auto noise_block = noise_matrix.block(lower_row,lower_col,size_rows,size_cols);
444 noise_block += mat_block*noise_v;
445 }
446 }
447 }
448 }
449 }
450 }
451 }
452
453 {
454 std::scoped_lock<std::mutex> lk(*jinc_mutex);
455 if (run_omb) {
456 for (int i=0; i<omb.signal.size(); ++i) {
457 omb.signal[i] += omb_copy.signal[i];
458 omb.weight[i] += omb_copy.weight[i];
459
460 if (run_coverage) {
461 omb.coverage[i] += omb_copy.coverage[i];
462 }
463
464 if (run_kernel) {
465 omb.kernel[i] += omb_copy.kernel[i];
466 }
467 }
468 }
469
470 if (run_noise) {
471 for (int i=0; i<nmb->noise.size(); ++i) {
472 nmb->noise[i] += nmb_copy->noise[i];
473 }
474 }
475 }
476
477 if (run_noise) {
478 nmb = nullptr;
479 nmb_copy = nullptr;
480 }
481}
482
483
484template<class map_buffer_t, typename Derived, typename apt_t>
486 map_buffer_t &omb, map_buffer_t &cmb, Eigen::DenseBase<Derived> &map_indices,
487 std::string &pixel_axes, apt_t &apt, double d_fsmp, bool run_omb, bool run_noise) {
488
489 const bool use_cmb = !cmb.noise.empty();
490 const bool use_omb = !omb.noise.empty();
491 const bool run_kernel = !omb.kernel.empty();
492 const bool run_coverage = !omb.coverage.empty();
493 const bool run_hwpr = in.hwpr_angle.data.size()!=0;
494
495 // dimensions of data
496 Eigen::Index n_dets = in.scans.data.cols();
497 Eigen::Index n_pts = in.scans.data.rows();
498
499 // step to skip to reach next stokes param
500 int step = omb.pointing.size();
501
502 // pointer to map buffer with noise maps
503 map_buffer_t *nmb;
504
505 if (run_noise) {
506 nmb = use_cmb ? &cmb : (use_omb ? &omb : nullptr);
507 }
508
509 // add detector to map?
510 bool run_det;
511
512 // placeholder vectors of size ndet for grppi maps
513 std::vector<int> map_in_vec, map_out_vec;
514 map_in_vec.resize(omb.signal.size());
515 std::iota(map_in_vec.begin(), map_in_vec.end(), 0);
516 map_out_vec.resize(map_in_vec.size());
517
518 // parallelize over detectors
519 //for (Eigen::Index i=0; i<n_dets; ++i) {
520 grppi::map(tula::grppi_utils::dyn_ex(omb.parallel_policy), map_in_vec, map_out_vec, [&](auto i) {
521 // skip fg = -1 if in polarization mode
522 if (run_polarization && apt["fg"](i)==-1) {
523 run_det = false;
524 }
525 else {
526 run_det = true;
527 }
528
529 // skip completely flagged detectors
530 if ((in.flags.data.col(i).array()==false).any()) {
531 // get detector positions from apt table if not in detector mapmaking mode
532 auto det_index = i;
533
534 // which map to assign detector to
535 Eigen::Index map_index = map_indices(i);
536 // indices for Q and U maps
537 int q_index = map_index + step;
538 int u_index = map_index + 2 * step;
539 Eigen::Index array_index = apt["array"](det_index);
540 Eigen::Index mat_rows = jinc_weights_mat[array_index].rows();
541 Eigen::Index mat_cols = jinc_weights_mat[array_index].cols();
542 Eigen::Index mat_rows_center = (mat_rows - 1.)/2.;
543 Eigen::Index mat_cols_center = (mat_cols - 1.)/2.;
544
545 // get detector pointing
546 auto [lat, lon] = engine_utils::calc_det_pointing(in.tel_data.data, apt["x_t"](det_index), apt["y_t"](det_index),
547 pixel_axes, in.pointing_offsets_arcsec.data, omb.map_grouping);
548
549 // get map buffer row and col indices for lat and lon vectors
550 Eigen::VectorXd omb_irow = lat.array()/omb.pixel_size_rad + (omb.n_rows)/2.;
551 Eigen::VectorXd omb_icol = lon.array()/omb.pixel_size_rad + (omb.n_cols)/2.;
552
553 Eigen::VectorXd cmb_irow, cmb_icol;
554 if (use_cmb) {
555 // get coadded map buffer row and col indices for lat and lon vectors
556 cmb_irow = lat.array()/cmb.pixel_size_rad + (cmb.n_rows)/2.;
557 cmb_icol = lon.array()/cmb.pixel_size_rad + (cmb.n_cols)/2.;
558 }
559
560 // signal map value
561 double signal;
562
563 // noise map value
564 double noise_v;
565
566 // noise map indices
567 Eigen::Index nmb_ir, nmb_ic;
568
569 // cosine and sine of angles
570 double angle, cos_2angle, sin_2angle;
571
572 // loop through the samples
573 for (Eigen::Index j=0; j<n_pts; ++j) {
574 // check if sample is flagged, ignore if so
575 if (!in.flags.data(j,i)) {
576 Eigen::Index omb_ir = omb_irow(j);
577 Eigen::Index omb_ic = omb_icol(j);
578
579 if (run_polarization) {
580 auto fg_index = apt["fg"](det_index);
581 if (run_hwpr) {
582 angle = 2*in.hwpr_angle.data(j) - (in.angle.data(j) + fgs[fg_index] + install_ang[array_index]);
583 }
584 else {
585 angle = in.angle.data(j) + fgs[fg_index] + install_ang[array_index];
586 }
587
588 cos_2angle = cos(2.*angle);
589 sin_2angle = sin(2.*angle);
590 }
591
592 if (run_omb) {
593 // make sure the data point is within the map
594 if ((omb_ir >= 0) && (omb_ir < omb.n_rows) && (omb_ic >= 0) && (omb_ic < omb.n_cols)) {
595
596 int lower_row = omb_ir - mat_rows_center;
597 int upper_row = omb_ir + mat_rows - 1 - mat_rows_center;
598 int lower_col = omb_ic - mat_cols_center;
599 int upper_col = omb_ic + mat_cols - 1 - mat_cols_center;
600
601 int jinc_lower_row = abs(std::min(0, lower_row));
602 int jinc_lower_col = abs(std::min(0, lower_col));
603
604 lower_row = std::max(0,lower_row);
605 upper_row = std::min(static_cast<int>(omb.n_rows - 1),upper_row);
606 lower_col = std::max(0,lower_col);
607 upper_col = std::min(static_cast<int>(omb.n_cols - 1),upper_col);
608
609 int size_rows = upper_row - lower_row + 1;
610 int size_cols = upper_col - lower_col + 1;
611
612 const auto mat_block = jinc_weights_mat[array_index].block(jinc_lower_row,jinc_lower_col,size_rows,size_cols);
613
614 auto sig_block = omb.signal[map_index].block(lower_row,lower_col,size_rows,size_cols);
615 auto wt_block = omb.weight[map_index].block(lower_row,lower_col,size_rows,size_cols);
616
617 // populate signal map
618 sig_block += (mat_block * in.weights.data(i) * in.scans.data(j,i)).eval();
619
620 // populate weight map
621 wt_block += (mat_block * in.weights.data(i)).eval();
622
623 // populate coverage map
624 if (run_coverage) {
625 auto cov_block = omb.coverage[map_index].block(lower_row,lower_col,size_rows,size_cols);
626 cov_block += mat_block/d_fsmp;
627 }
628
629 // populate kernel map
630 if (run_kernel) {
631 auto ker_block = omb.kernel[map_index].block(lower_row,lower_col,size_rows,size_cols);
632 ker_block += mat_block*in.weights.data(i)*in.kernel.data(j,i);
633 }
634 }
635 }
636
637 // check if noise maps requested
638 if (run_noise) {
639 // if coaddition is enabled
640 if (use_cmb) {
641 nmb_ir = cmb_irow(j);
642 nmb_ic = cmb_icol(j);
643 }
644
645 // else make noise maps for obs
646 else {
647 nmb_ir = omb_irow(j);
648 nmb_ic = omb_icol(j);
649 }
650
651 // make sure pixel is in the map
652 if ((nmb_ir >= 0) && (nmb_ir < nmb->n_rows) && (nmb_ic >= 0) && (nmb_ic < nmb->n_cols)) {
653
654 int lower_row = nmb_ir - mat_rows_center;
655 int upper_row = nmb_ir + mat_rows - 1 - mat_rows_center;
656 int lower_col = nmb_ic - mat_cols_center;
657 int upper_col = nmb_ic + mat_cols - 1 - mat_cols_center;
658
659 int jinc_lower_row = abs(std::min(0, lower_row));
660 int jinc_lower_col = abs(std::min(0, lower_col));
661
662 lower_row = std::max(0,lower_row);
663 upper_row = std::min(static_cast<int>(nmb->n_rows - 1),upper_row);
664 lower_col = std::max(0,lower_col);
665 upper_col = std::min(static_cast<int>(nmb->n_cols - 1),upper_col);
666
667 int size_rows = upper_row - lower_row + 1;
668 int size_cols = upper_col - lower_col + 1;
669
670 const auto mat_block = jinc_weights_mat[array_index].block(jinc_lower_row,jinc_lower_col,size_rows,size_cols);
671 signal = in.scans.data(j,i)*in.weights.data(i);
672
673 for (Eigen::Index nn=0; nn<nmb->n_noise; ++nn) {
674 // randomizing on dets
675 if (nmb->randomize_dets) {
676 noise_v = in.noise.data(nn,i)*signal;
677 }
678 else {
679 noise_v = in.noise.data(nn)*signal;
680 }
681 Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> noise_matrix(nmb->noise[map_index].data() + nn * nmb->n_rows * nmb->n_cols,
682 nmb->n_rows, nmb->n_cols);
683 auto noise_block = noise_matrix.block(lower_row,lower_col,size_rows,size_cols);
684 noise_block += mat_block*noise_v;
685 }
686 }
687 }
688 }
689 }
690 }
691 return 0;
692 });
693
694 if (run_noise) {
695 nmb = nullptr;
696 nmb = nullptr;
697 }
698}
699} // namespace mapmaking
Definition utils.h:972
void interpolate(Eigen::VectorXd const &x_vec, Eigen::VectorXd const &y_vec)
Definition utils.h:990
Definition jinc_mm.h:26
void calculate_jinc_splines()
Definition jinc_mm.h:152
void populate_maps_jinc(TCData< TCDataKind::PTC, Eigen::MatrixXd > &, map_buffer_t &, map_buffer_t &, Eigen::DenseBase< Derived > &, std::string &, apt_t &, double, bool, bool)
Definition jinc_mm.h:211
void allocate_pointing(map_buffer_t &, double, double, double, Eigen::Index, int, int)
Definition jinc_mm.h:186
std::map< int, double > install_ang
Definition jinc_mm.h:33
std::map< Eigen::Index, engine_utils::SplineFunction > jinc_splines
Definition jinc_mm.h:74
std::unique_ptr< std::mutex > jinc_mutex
Definition jinc_mm.h:30
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
auto jinc_func(double, double, double, double, double, double)
Definition jinc_mm.h:100
std::shared_ptr< spdlog::logger > logger
Definition jinc_mm.h:29
void allocate_jinc_matrix(double)
Definition jinc_mm.h:118
std::map< Eigen::Index, double > l_d
Definition jinc_mm.h:59
std::map< int, double > fgs
Definition jinc_mm.h:41
std::map< Eigen::Index, Eigen::MatrixXd > jinc_weights_mat
Definition jinc_mm.h:71
std::string parallel_policy
Definition jinc_mm.h:53
int n_pts_splines
Definition jinc_mm.h:65
void populate_maps_jinc_parallel(TCData< TCDataKind::PTC, Eigen::MatrixXd > &, map_buffer_t &, map_buffer_t &, Eigen::DenseBase< Derived > &, std::string &, apt_t &, double, bool, bool)
Definition jinc_mm.h:485
bool run_polarization
Definition jinc_mm.h:50
constexpr auto pi
Definition constants.h:6
auto calc_det_pointing(tel_data_t &tel_data, double az_off, double el_off, const std::string pixel_axes, pointing_offset_t &pointing_offsets, const std::string map_grouping)
Definition pointing.h:11
Definition jinc_mm.h:24
TC data class.
Definition timestream.h:55