Citlali
Loading...
Searching...
No Matches
pointing.h
Go to the documentation of this file.
1#pragma once
2
3#include <map>
4
6
7namespace engine_utils {
8
9// get a single detector's pointing
10template <typename tel_data_t, typename pointing_offset_t>
11auto calc_det_pointing(tel_data_t &tel_data, double az_off, double el_off,
12 const std::string pixel_axes, pointing_offset_t &pointing_offsets,
13 const std::string map_grouping) {
14
15 // if making per detector maps, set offsets to zero
16 if (map_grouping=="detector") {
17 az_off = 0;
18 el_off = 0;
19 }
20
21 // rows, cols pointing vectors
22 Eigen::VectorXd lat, lon;
23
24 // elevation for rotation
25 auto elev = tel_data["TelElAct"].array();
26
27 // rotate altaz offsets by elevation angle and add pointing offsets
28 Eigen::VectorXd rot_az_off = cos(elev)*az_off
29 - sin(elev)*el_off + pointing_offsets["az"].array();
30 Eigen::VectorXd rot_alt_off = cos(elev)*el_off
31 + sin(elev)*az_off + pointing_offsets["alt"].array();
32
33 // radec map
34 if (pixel_axes=="radec") {
35 // get parallactic angle
36 auto& par_ang = tel_data["ActParAng"];
37
38 // dec
39 lat = (rot_az_off.array()*sin(par_ang.array()) + rot_alt_off.array()*cos(par_ang.array()))*ASEC_TO_RAD
40 + tel_data["dec_phys"].array();
41 // ra
42 lon = (-rot_az_off.array()*cos(par_ang.array()) + rot_alt_off.array()*sin(par_ang.array()))*ASEC_TO_RAD
43 + tel_data["ra_phys"].array();
44 }
45
46 // altaz map
47 else if (pixel_axes=="altaz") {
48 // alt
49 lat = (rot_alt_off.array()*ASEC_TO_RAD) + tel_data["alt_phys"].array();
50 // az
51 lon = (rot_az_off.array()*ASEC_TO_RAD) + tel_data["az_phys"].array();
52 }
53
54 else if (pixel_axes=="galactic") {
55 // get parallactic angle
56 auto ang = tel_data["ActParAng"] + tel_data["ActGalAng"];
57
58 // b
59 lat = (rot_az_off.array()*sin(ang.array()) + rot_alt_off.array()*cos(ang.array()))*ASEC_TO_RAD
60 + tel_data["b_phys"].array();
61 // l
62 lon = (-rot_az_off.array()*cos(ang.array()) + rot_alt_off.array()*sin(ang.array()))*ASEC_TO_RAD
63 + tel_data["l_phys"].array();
64 }
65
66 return std::tuple<Eigen::VectorXd, Eigen::VectorXd>{lat,lon};
67}
68
69template <typename Derived>
70auto calc_par_ang_from_coords(const double lat, const double lon, Eigen::DenseBase<Derived> &az, Eigen::DenseBase<Derived> &alt,
71 Eigen::DenseBase<Derived> &ra, Eigen::DenseBase<Derived> &dec) {
72
73 auto cosha = (sin(alt.derived().array()) - sin(dec.derived().array())* sin(lat)) /
74 (cos(dec.derived().array())* cos(lat));
75
76 auto sinha = (-sin(az.derived().array())* cos(alt.derived().array())/ cos(dec.derived().array()));
77
78 Eigen::VectorXd par_ang(alt.size());
79
80 for (Eigen::Index i=0; i<alt.size(); ++i) {
81 par_ang(i) = atan2(sinha(i), (tan(lat)* cos(dec(i)) - sin(dec(i)) * cosha(i)));
82 }
83
84 return par_ang;
85}
86
87template <typename Derived>
88auto tangent_to_abs(Eigen::DenseBase<Derived>& lat, Eigen::DenseBase<Derived>& lon, const double cra, const double cdec) {
89
90 // number of samples
91 Eigen::Index n_pts = lat.size();
92
93 // lat/lon = dec/ra = y/x (map axes)
94 Eigen::VectorXd abs_lat(n_pts), abs_lon(n_pts);
95 for (Eigen::Index i=0; i<n_pts; ++i) {
96 double rho = sqrt(pow(lat(i),2) + pow(lon(i),2));
97 double c = atan(rho);
98 if (c == 0.) {
99 abs_lat(i) = lat(i);
100 abs_lon(i) = lon(i);
101 }
102 else {
103 double ccwhn0 = cos(c);
104 double scwhn0 = sin(c);
105 double ccdec = cos(cdec);
106 double scdec = sin(cdec);
107 double a1, a2;
108 a1 = ccwhn0*scdec + lat(i)*scwhn0*ccdec/rho;
109 abs_lat(i) = asin(a1);
110 a2 = lon(i)*scwhn0/(rho*ccdec*ccwhn0 - lat(i)*scdec*scwhn0);
111 abs_lon(i) = cra + atan(a2);
112 }
113 }
114 return std::tuple<Eigen::VectorXd, Eigen::VectorXd>{abs_lat,abs_lon};
115}
116
117// function to calculate the gnomonic projection for vectors
118template <typename Derived>
119void gnomonic_projection(const Eigen::DenseBase<Derived> &l, const Eigen::DenseBase<Derived> &b,
120 double l0, double b0, Eigen::DenseBase<Derived> &x, Eigen::DenseBase<Derived> &y) {
121
122 // precompute cosines and sines
123 Eigen::VectorXd cos_b = b.derived().array().cos();
124 Eigen::VectorXd sin_b = b.derived().array().sin();
125 double cos_b0 = std::cos(b0);
126 double sin_b0 = std::sin(b0);
127
128 // calculate angular distance c
129 Eigen::VectorXd cos_c = sin_b.array() * sin_b0 + cos_b.array() * cos_b0 * (l.derived().array() - l0).cos();
130
131 // avoid division by zero or near zero
132 for (int i = 0; i < cos_c.size(); ++i) {
133 if (std::abs(cos_c(i)) < std::numeric_limits<double>::epsilon()) {
134 x(i) = 0;
135 y(i) = 0;
136 }
137 else {
138 x(i) = cos_b(i) * std::sin(l(i) - l0) / cos_c(i);
139 y(i) = (cos_b0 * sin_b(i) - sin_b0 * cos_b(i) * std::cos(l(i) - l0)) / cos_c(i);
140 }
141 }
142}
143
144// function to convert equatorial coordinates (RA, Dec) to galactic coordinates (l, b)
145static const void equatorial_to_galactic(const double ra, const double dec, double& l, double& b) {
146 // Constants (all angles in radians)
147 double ra_NGP = 192.859508*DEG_TO_RAD; // Right Ascension of North Galactic Pole
148 double dec_NGP = 27.128336*DEG_TO_RAD; // Declination of North Galactic Pole
149 double l_NCP = 122.931919*DEG_TO_RAD; // Longitude of North Celestial Pole in Galactic coordinates
150
151 // calculate b, the Galactic latitude
152 double sin_b = std::sin(dec_NGP) * std::sin(dec) + std::cos(dec_NGP) * std::cos(dec) * std::cos(ra - ra_NGP);
153 b = std::asin(sin_b); // inverse sine to get the latitude
154
155 // calculate l, the Galactic longitude
156 double sin_l_ncp_minus_l = std::cos(dec) * std::sin(ra - ra_NGP) / std::cos(b);
157 double cos_l_ncp_minus_l = (std::cos(dec_NGP) * std::sin(dec) - std::sin(dec_NGP) * std::cos(dec) * std::cos(ra - ra_NGP)) / std::cos(b);
158 double l_ncp_minus_l = std::atan2(sin_l_ncp_minus_l, cos_l_ncp_minus_l);
159 l = l_NCP - l_ncp_minus_l;
160
161 // normalize l to be within the range [0, 2*pi)
162 l = std::fmod(l, 2 * M_PI);
163}
164
165
166} // namespace engine_utils
#define DEG_TO_RAD
Definition constants.h:27
#define ASEC_TO_RAD
Definition constants.h:33
Definition fitting.h:11
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
auto tangent_to_abs(Eigen::DenseBase< Derived > &lat, Eigen::DenseBase< Derived > &lon, const double cra, const double cdec)
Definition pointing.h:88
void gnomonic_projection(const Eigen::DenseBase< Derived > &l, const Eigen::DenseBase< Derived > &b, double l0, double b0, Eigen::DenseBase< Derived > &x, Eigen::DenseBase< Derived > &y)
Definition pointing.h:119
auto calc_par_ang_from_coords(const double lat, const double lon, Eigen::DenseBase< Derived > &az, Eigen::DenseBase< Derived > &alt, Eigen::DenseBase< Derived > &ra, Eigen::DenseBase< Derived > &dec)
Definition pointing.h:70
static const void equatorial_to_galactic(const double ra, const double dec, double &l, double &b)
Definition pointing.h:145