LSST Applications g0afe43252f+b86e4b8053,g0e535e6de9+ad13c1b82d,g11f7dcd041+017865fdd3,g1ce3e0751c+f991eae79d,g25e82e299b+da9c58a417,g28da252d5a+9a4345bd89,g2bbee38e9b+b6588ad223,g2bc492864f+b6588ad223,g2cdde0e794+8523d0dbb4,g347aa1857d+b6588ad223,g35bb328faa+b86e4b8053,g3a166c0a6a+b6588ad223,g461a3dce89+b86e4b8053,g52b1c1532d+b86e4b8053,g7d11c3e888+3343bff751,g80478fca09+f22f659b46,g8543c18506+fadcf71ecf,g858d7b2824+c704b22fcc,g8cd86fa7b1+497903d09f,g965a9036f2+c704b22fcc,g979bb04a14+43c1c4070b,g9ddcbc5298+f24b38b85a,gae0086650b+b86e4b8053,gb781091699+0f9934ae6f,gbb886bcc26+486567bf06,gc28159a63d+b6588ad223,gc30aee3386+a2f0f6cab9,gc9f6898e11+66e322ebb3,gcaf7e4fdec+c704b22fcc,gcd45df26be+c704b22fcc,gcdd4ae20e8+02080e1d2d,gcf0d15dbbd+02080e1d2d,gdaeeff99f8+006e14e809,gdbce86181e+42405ade82,ge3d4d395c2+224150c836,ge79ae78c31+b6588ad223,gf048a9a2f4+69e41b07e6,gf0baf85859+b4cca3d10f,w.2024.30
LSST Data Management Base Package
Loading...
Searching...
No Matches
ellipse.cc
Go to the documentation of this file.
1/*
2 * This file is part of gauss2d.
3 *
4 * Developed for the LSST Data Management System.
5 * This product includes software developed by the LSST Project
6 * (https://www.lsst.org).
7 * See the COPYRIGHT file at the top-level directory of this distribution
8 * for details of code ownership.
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#ifndef LSST_GAUSS2D_ELLIPSE_H
25
26#include <cmath>
27#include <stdexcept>
28#include <string>
29
33
34namespace lsst::gauss2d {
35template <class S>
37 return {std::sin(arg), std::cos(arg)};
38}
39
40Covariance::Covariance(double sigma_x_sq, double sigma_y_sq, double cov_xy) {
41 set(sigma_x_sq, sigma_y_sq, cov_xy);
42}
43
44Covariance::Covariance(const Ellipse& ell) { set(ell); }
45
46void Covariance::check(double sigma_x_sq, double sigma_y_sq, double cov_xy) {
47 double offdiag_max = sqrt(sigma_x_sq) * sqrt(sigma_y_sq);
48 // Define implied rho as -1 for negative cov and +1 for positive cov if zero size
49 // This enforces cov_xy == 0 if sigma_x_sq == sigma_y_sq == 0
50 double rho = offdiag_max > 0 ? cov_xy / offdiag_max : (cov_xy > 0) - (cov_xy < 0);
51 if (!(sigma_x_sq >= 0) || !(sigma_y_sq >= 0) || !(rho >= -1 && rho <= 1)) {
52 throw std::invalid_argument("Invalid sigma_x_sq, sigma_y_sq, cov_xy=" + to_string_float(sigma_x_sq)
53 + "," + to_string_float(sigma_y_sq) + "," + to_string_float(cov_xy)
54 + " with implied rho=" + to_string_float(rho)
55 + "; sigma_x,y_sq >= 0 and -1 < rho < 1 required.");
56 }
57}
58
60 double sigma_x_sq = this->get_sigma_x_sq() + cov.get_sigma_x_sq();
61 double sigma_y_sq = this->get_sigma_y_sq() + cov.get_sigma_y_sq();
62 double cov_xy = this->get_cov_xy() + cov.get_cov_xy();
63 this->set(sigma_x_sq, sigma_y_sq, cov_xy);
64}
65
67 std::shared_ptr<Covariance> cov_ret = std::make_shared<Covariance>(
68 this->get_sigma_x_sq(), this->get_sigma_y_sq(), this->get_cov_xy());
69 cov_ret->convolve(cov);
70 return cov_ret;
71}
72
73void Covariance::set(const Ellipse& ellipse) {
74 double sigma_x = ellipse.get_sigma_x();
75 double sigma_y = ellipse.get_sigma_y();
76 double rho = ellipse.get_rho();
77 this->_sigma_x_sq = sigma_x * sigma_x;
78 this->_sigma_y_sq = sigma_y * sigma_y;
79 // Must be done like so in case sigma_x/y^2 round to zero, and check after
80 this->set_cov_xy(sigma_x * sigma_y * (_sigma_x_sq > 0) * (_sigma_y_sq > 0) * rho);
81}
82
83void Covariance::set(double sigma_x_sq, double sigma_y_sq, double cov_xy) {
84 set_sigma_x_sq(sigma_x_sq);
85 set_sigma_y_sq(sigma_y_sq);
86 set_cov_xy(cov_xy);
87}
88
89void Covariance::set_sigma_x_sq(double sigma_x_sq) {
90 if (!(sigma_x_sq >= 0)) {
91 throw std::invalid_argument(this->str() + " can't set invalid sigma_x_sq="
92 + to_string_float(sigma_x_sq) + "; sigma_x_sq >= 0 required.");
93 }
94 _sigma_x_sq = sigma_x_sq;
95}
96
97void Covariance::set_sigma_y_sq(double sigma_y_sq) {
98 if (!(sigma_y_sq >= 0)) {
99 throw std::invalid_argument(this->str() + " can't set invalid sigma_y_sq="
100 + to_string_float(sigma_y_sq) + "; sigma_y_sq >= 0 required.");
101 }
102 _sigma_y_sq = sigma_y_sq;
103}
104
105void Covariance::set_cov_xy(double cov_xy) {
106 // Take individual sqrt just to be safe and avoid potential overflow
107 double offdiag_max = sqrt(_sigma_x_sq) * sqrt(_sigma_y_sq);
108 // If offdiag_max is zero, we can only accept cov_xy exactly zero
109 double rho = offdiag_max > 0 ? cov_xy / offdiag_max : -!(cov_xy >= 0) + !(cov_xy <= 0);
110 if (!(rho > -1 && rho < 1)) {
111 throw std::invalid_argument(this->str() + "can't set invalid cov_xy=" + to_string_float(cov_xy)
112 + " (>0=" + to_string_float(cov_xy > 0)
113 + ", <0=" + to_string_float(cov_xy < 0)
114 + ", offdiag_max=" + to_string_float(offdiag_max) + " with implied rho="
115 + to_string_float(rho) + "; -1 < rho < 1 required.");
116 }
117 _cov_xy = cov_xy;
118}
119
120void Covariance::set_xyc(const std::array<double, 3>& xyc) { this->set(xyc[0], xyc[1], xyc[2]); }
121
122std::string Covariance::repr(bool name_keywords, std::string_view namespace_separator) const {
123 return type_name_str<Covariance>(false, namespace_separator) + "(" + (name_keywords ? "sigma_x_sq=" : "")
124 + to_string_float(_sigma_x_sq) + ", " + (name_keywords ? "sigma_y_sq=" : "")
125 + to_string_float(_sigma_y_sq) + ", " + (name_keywords ? "cov_xy=" : "") + to_string_float(_cov_xy)
126 + ")";
127}
128
130 return type_name_str<Covariance>(true) + "(sigma_x_sq=" + to_string_float(_sigma_x_sq)
131 + ", sigma_y_sq=" + to_string_float(_sigma_y_sq) + ", cov_xy=" + to_string_float(_cov_xy) + ")";
132}
133
134bool Covariance::operator==(const Covariance& other) const { return get_xyc() == other.get_xyc(); }
135bool Covariance::operator!=(const Covariance& other) const { return !(*this == other); }
136
138 out << obj.str();
139 return out;
140}
141
142double EllipseData::get_area() const {
143 double rho = this->get_rho();
144 return M_PI * this->get_sigma_xy() * sqrt(1 - rho * rho);
145}
146
147double EllipseData::get_sigma_xy() const { return this->get_sigma_x() * this->get_sigma_y(); }
148
150 double sigma_x_ell = ell.get_sigma_x();
151 double sigma_y_ell = ell.get_sigma_y();
152 double sigma_x = this->get_sigma_x();
153 sigma_x = sqrt(sigma_x * sigma_x + sigma_x_ell * sigma_x_ell);
154 double sigma_y = this->get_sigma_y();
155 sigma_y = sqrt(sigma_y * sigma_y + sigma_y_ell * sigma_y_ell);
156 double rho = (this->get_cov_xy() + ell.get_cov_xy()) / (sigma_x * sigma_y);
157 this->set(sigma_x, sigma_y, rho);
158}
159
160double EllipseData::get_cov_xy() const { return this->get_sigma_x() * this->get_sigma_y() * this->get_rho(); }
161
162double EllipseData::get_hwhm_x() const { return M_SIGMA_HWHM * this->get_sigma_x(); };
163
164double EllipseData::get_hwhm_y() const { return M_SIGMA_HWHM * this->get_sigma_y(); };
165
167 return {this->get_hwhm_x(), this->get_hwhm_y(), this->get_rho()};
168}
170 return {this->get_sigma_x(), this->get_sigma_y(), this->get_rho()};
171}
172
173double EllipseData::get_radius_trace() const { return sqrt(this->get_sigma_x_sq() + this->get_sigma_y_sq()); }
174
176 double sigma = this->get_sigma_x();
177 return sigma * sigma;
178}
179
181 double sigma = this->get_sigma_y();
182 return sigma * sigma;
183}
184
185double EllipseValues::get_sigma_x() const { return *_sigma_x; }
186double EllipseValues::get_sigma_y() const { return *_sigma_y; }
187double EllipseValues::get_rho() const { return *_rho; }
188std::array<double, 3> EllipseValues::get_xyr() const { return {*_sigma_x, *_sigma_y, *_rho}; }
189
190void EllipseValues::set_sigma_x(double sigma_x) {
191 EllipseData::check_size(sigma_x, "(size=sigma_x)");
192 *_sigma_x = sigma_x;
193}
194
195void EllipseValues::set_sigma_y(double sigma_y) {
196 EllipseData::check_size(sigma_y, "(size=sigma_y)");
197 *_sigma_y = sigma_y;
198}
199
200void EllipseValues::set_rho(double rho) {
202 *_rho = rho;
203}
204
205void EllipseValues::set(double sigma_x, double sigma_y, double rho) {
206 Ellipse::check(sigma_x, sigma_y, rho);
207 *_sigma_x = sigma_x;
208 *_sigma_y = sigma_y;
209 *_rho = rho;
210}
211
212void EllipseValues::set_h(double hwhm_x, double hwhm_y, double rho) {
213 Ellipse::check(hwhm_x, hwhm_y, rho);
214 *_sigma_x = M_HWHM_SIGMA * hwhm_x;
215 *_sigma_y = M_HWHM_SIGMA * hwhm_y;
216 *_rho = rho;
217}
218
219std::string EllipseValues::repr(bool name_keywords, std::string_view namespace_separator) const {
220 return type_name_str<EllipseValues>(false, namespace_separator) + "(" + (name_keywords ? "sigma_x=" : "")
221 + to_string_float(this->get_sigma_x()) + ", " + (name_keywords ? "sigma_y=" : "")
222 + to_string_float(this->get_sigma_y()) + ", " + (name_keywords ? "rho=" : "")
223 + to_string_float(this->get_rho()) + ")";
224}
225
227 return type_name_str<EllipseValues>(true) + "(sigma_x=" + to_string_float(this->get_sigma_x())
228 + ", sigma_y=" + to_string_float(this->get_sigma_y()) + ", rho=" + to_string_float(this->get_rho())
229 + ")";
230}
231
233 : _data(data == nullptr ? std::make_shared<EllipseValues>() : std::move(data)) {};
234
235Ellipse::Ellipse(double sigma_x, double sigma_y, double rho) : _data(std::make_shared<EllipseValues>()) {
236 _data->set(sigma_x, sigma_y, rho);
237}
238
239Ellipse::Ellipse(const Covariance& covar) : _data(std::make_shared<EllipseValues>()) { this->set(covar); }
240
241Ellipse::Ellipse(const EllipseMajor& ellipse) : _data(std::make_shared<EllipseValues>()) {
242 this->set(ellipse);
243}
244
249 // TODO: Replace with cloning derived data
251 = std::make_unique<Ellipse>(this->get_sigma_x(), this->get_sigma_y(), this->get_rho());
252 ell_ret->convolve(ell);
253 return ell_ret;
254}
255
256void EllipseData::set(double sigma_x, double sigma_y, double rho) {
257 this->check(sigma_x, sigma_y, rho);
258 this->set_sigma_x(sigma_x);
259 this->set_sigma_y(sigma_y);
260 this->set_rho(rho);
261}
262
263void EllipseData::set(const Covariance& covar) {
264 double sigma_x = covar.get_sigma_x_sq();
265 double sigma_y = covar.get_sigma_y_sq();
266 sigma_x = sqrt(sigma_x);
267 sigma_y = sqrt(sigma_y);
268 double rho = (sigma_x == 0 || sigma_y == 0) ? 0 : covar.get_cov_xy() / (sigma_x * sigma_y);
269 this->set(sigma_x, sigma_y, rho);
270}
271
272void EllipseData::set(const EllipseMajor& ellipse) {
273 const double r_major = ellipse.get_r_major();
274 if (r_major == 0) {
275 this->set(0, 0, 0);
276 return;
277 }
278 const double axrat = ellipse.get_axrat();
279 if (axrat == 1) {
280 this->set(r_major, r_major, 0);
281 return;
282 }
283 const auto [sin_th, cos_th] = sincos(ellipse.get_angle_radians());
284 const double sin_th_sq = sin_th * sin_th;
285 const double cos_th_sq = cos_th * cos_th;
286
287 const double r_major_sq = r_major * r_major;
288 const double r_minor_sq = r_major_sq * axrat * axrat;
289 const double sigma_x = sqrt(cos_th_sq * r_major_sq + sin_th_sq * r_minor_sq);
290 const double sigma_y = sqrt(sin_th_sq * r_major_sq + cos_th_sq * r_minor_sq);
291 double rho = (sigma_x == 0 || sigma_y == 0)
292 ? 0
293 : sin_th * cos_th * (r_major_sq - r_minor_sq) / (sigma_x * sigma_y);
294 this->set(sigma_x, sigma_y, rho);
295}
296
297void EllipseData::set_h(double hwhm_x, double hwhm_y, double rho) {
298 EllipseData::check(hwhm_x, hwhm_y, rho);
299 this->set_hwhm_x(hwhm_x);
300 this->set_hwhm_y(hwhm_y);
301 this->set_rho(rho);
302}
303void EllipseData::set_hwhm_x(double hwhm_x) { this->set_sigma_x(M_HWHM_SIGMA * hwhm_x); }
304void EllipseData::set_hwhm_y(double hwhm_y) { this->set_sigma_y(M_HWHM_SIGMA * hwhm_y); }
305void EllipseData::set_hxyr(const std::array<double, 3>& hxyr) { this->set_h(hxyr[0], hxyr[1], hxyr[2]); }
306void EllipseData::set_xyr(const std::array<double, 3>& xyr) { this->set(xyr[0], xyr[1], xyr[2]); }
307
308std::string Ellipse::repr(bool name_keywords, std::string_view namespace_separator) const {
309 return type_name_str<Ellipse>(false, namespace_separator) + "(" + (name_keywords ? "data=" : "")
310 + _data->repr(name_keywords, namespace_separator) + ")";
311}
312
313std::string Ellipse::str() const { return type_name_str<Ellipse>(true) + "(data=" + _data->str() + ")"; }
314
315bool Ellipse::operator==(const Ellipse& other) const { return get_data() == other.get_data(); };
316bool Ellipse::operator!=(const Ellipse& other) const { return !(*this == other); }
317
318const EllipseData& Ellipse::get_data() const { return *this->_data; }
319double Ellipse::get_rho() const { return this->_data->get_rho(); }
320double Ellipse::get_sigma_x() const { return this->_data->get_sigma_x(); }
321double Ellipse::get_sigma_y() const { return this->_data->get_sigma_y(); }
322
323void Ellipse::set_rho(double rho) { this->_data->set_rho(rho); }
324void Ellipse::set_sigma_x(double sigma_x) { this->_data->set_sigma_x(sigma_x); }
325void Ellipse::set_sigma_y(double sigma_y) { this->_data->set_sigma_y(sigma_y); }
326
327std::pair<double, double> get_x_pm(double sigma_x_sq, double sigma_y_sq, double cov_xy) {
328 double apc = sigma_x_sq + sigma_y_sq;
329 double x = apc / 2;
330 // TODO: Write tests for this with inputs returning close to zero
331 // Probably most efficient but unstable, e.g.:
332 // sigma_x, sigma_y, rho = 1.58113883008419, 1.5811388300841895, 0
333 // ... yields -3.552713678800501e-15 inside the sqrt
334 // double pm = sqrt(apc*apc - 4*(sigma_x_sq*sigma_y_sq - cov_xy*cov_xy))/2;
335 // Two more multiplications, but seemingly more stable
336 // Cancels out cross term from apc (2*sigma_x_sq*sigma_y_sq)
337 double pm = (sigma_x_sq * sigma_x_sq + sigma_y_sq * sigma_y_sq
338 - 2 * (sigma_x_sq * sigma_y_sq - 2 * cov_xy * cov_xy));
339 // Return zero if the result is negative
340 // TODO: Consider checking if < -machine_eps?
341 pm = (pm > 0) ? sqrt(pm) / 2 : 0;
342 return {x, pm};
343}
344
345void init(EllipseMajor& ellipse, const Covariance& covar, bool degrees) {
346 double sigma_x_sq = covar.get_sigma_x_sq();
347 double sigma_y_sq = covar.get_sigma_y_sq();
348 if (sigma_x_sq == 0 && sigma_y_sq == 0) return;
349 double cov_xy = covar.get_cov_xy();
350 auto [x, pm] = get_x_pm(sigma_x_sq, sigma_y_sq, cov_xy);
351 double r_major = x + pm;
352 if (r_major == 0) return;
353
354 double axrat = sqrt((x - pm) / r_major);
355 r_major = sqrt(r_major);
356 double ang = atan2(2 * cov_xy, sigma_x_sq - sigma_y_sq) / 2;
357 if (degrees) ang *= M_180_PI;
358 ellipse.set(r_major, axrat, ang);
359}
360
361EllipseMajor::EllipseMajor(double r_major, double axrat, double angle, bool degrees)
362 : _r_major(r_major), _axrat(axrat), _angle(angle), _degrees(degrees) {
363 EllipseMajor::check(r_major, axrat, angle);
364}
365
366EllipseMajor::EllipseMajor(const Covariance& covar, bool degrees) : _degrees(degrees) {
367 init(*this, covar, degrees);
368}
369
370EllipseMajor::EllipseMajor(const Ellipse& ellipse, bool degrees) : _degrees(degrees) {
371 init(*this, Covariance(ellipse), degrees);
372}
373
374void EllipseMajor::set(double r_major, double axrat, double angle) {
375 check(r_major, axrat, angle);
376 _r_major = r_major;
377 _axrat = axrat;
378 _angle = angle;
379}
380
381void EllipseMajor::set_r_major(double r_major) {
382 if (!(r_major >= 0)) {
383 throw std::invalid_argument("Invalid r_major=" + to_string_float(r_major)
384 + "; r_major >= 0 required.");
385 }
386 _r_major = r_major;
387}
388
389void EllipseMajor::set_axrat(double axrat) {
390 if (!(axrat >= 0 && axrat <= 1)) {
391 throw std::invalid_argument("Invalid axrat=" + to_string_float(axrat)
392 + "; 1 >= axrat >= 0 required.");
393 }
394 _axrat = axrat;
395}
396
397void EllipseMajor::set_angle(double angle) { _angle = angle; }
398
399void EllipseMajor::set_degrees(bool degrees) {
400 if (degrees && !_degrees) {
401 _degrees = true;
402 _angle *= M_180_PI;
403 } else if (!degrees && _degrees) {
404 _degrees = false;
405 _angle *= M_PI_180;
406 }
407}
408
409void EllipseMajor::set_rqa(const std::array<double, 3>& rqa) { this->set(rqa[0], rqa[1], rqa[2]); }
410
411std::string EllipseMajor::repr(bool name_keywords, std::string_view namespace_separator) const {
412 return type_name_str<EllipseMajor>(false, namespace_separator) + "(" + (name_keywords ? "r_major=" : "")
413 + to_string_float(_r_major) + ", " + (name_keywords ? "axrat=" : "") + to_string_float(_axrat)
414 + ", " + (name_keywords ? "angle=" : "") + to_string_float(_angle) + ", "
415 + (name_keywords ? "degrees=" : "") + to_string_float(_degrees) + ")";
416}
417
419 return type_name_str<EllipseMajor>(true) + "(r_major=" + to_string_float(_r_major)
420 + ", axrat=" + to_string_float(_axrat) + ", angle=" + to_string_float(_angle)
421 + ", degrees=" + to_string_float(_degrees) + ")";
422}
423
424bool EllipseMajor::operator==(const EllipseMajor& other) const {
425 return (get_r_major() == other.get_r_major()) && (get_axrat() == other.get_axrat())
426 && (get_angle_degrees() == other.get_angle_degrees());
427}
428
429bool EllipseMajor::operator!=(const EllipseMajor& other) const { return !(*this == other); }
430
431} // namespace lsst::gauss2d
432
433#endif
char * data
Definition BaseRecord.cc:61
table::Key< double > angle
afw::table::Key< double > sigma
#define M_PI
Definition ListMatch.cc:31
A representation of a 2D Gaussian with x and y standard deviations and a covariance value.
Definition ellipse.h:57
bool operator!=(const Covariance &other) const
Definition ellipse.cc:135
std::shared_ptr< Covariance > make_convolution(const Covariance &cov) const
Return the convolution of this with another covariance.
Definition ellipse.cc:66
double get_cov_xy() const
Get the covariance.
Definition ellipse.h:79
double get_sigma_x_sq() const
Get the square of sigma_x.
Definition ellipse.h:75
std::string repr(bool name_keywords=false, std::string_view namespace_separator=Object::CC_NAMESPACE_SEPARATOR) const override
Return a full, callable string representation of this.
Definition ellipse.cc:122
void set_sigma_y_sq(double sigma_y_sq)
Set the square of sigma_y.
Definition ellipse.cc:97
void set_sigma_x_sq(double sigma_x_sq)
Set the square of sigma_x.
Definition ellipse.cc:89
void set_xyc(const std::array< double, 3 > &xyc)
Set sigma_x_sq, sigma_y_sq and cov_xy from an array ref.
Definition ellipse.cc:120
std::array< double, 3 > get_xyc() const
Get the array of sigma_x^2, sigma_y^2, covariance.
Definition ellipse.h:81
std::string str() const override
Return a brief, human-readable string representation of this.
Definition ellipse.cc:129
double get_sigma_y_sq() const
Get the square of sigma_y.
Definition ellipse.h:77
void convolve(const Covariance &cov)
Convolve with another covariance, adding the values of each parameter to this.
Definition ellipse.cc:59
static void check(double sigma_x_sq, double sigma_y_sq, double cov_xy)
Check whether the supplied values are valid, throwing if not.
Definition ellipse.cc:46
void set_cov_xy(double cov_xy)
Set the off-diagonal (covariance) term.
Definition ellipse.cc:105
void set(const Ellipse &ellipse)
Set values from an ellipse instance.
Definition ellipse.cc:73
Covariance(double sigma_x_sq=0, double sigma_y_sq=0, double cov_xy=0)
Construct a new Covariance object.
Definition ellipse.cc:40
bool operator==(const Covariance &other) const
Definition ellipse.cc:134
Interface for an object storing Ellipse data.
Definition ellipse.h:132
virtual double get_sigma_x_sq() const
Get the square of sigma_x.
Definition ellipse.cc:175
static void check_rho(double rho, std::string_view error_suffix="")
Check whether a rho value is valid.
Definition ellipse.h:153
virtual double get_rho() const =0
Get rho.
virtual void set_rho(double rho)=0
Set the correlation parameter (rho)
static void check_size(double size, std::string_view error_suffix="")
Check whether an x- or x-yaxis size value is valid.
Definition ellipse.h:146
virtual void set_hwhm_y(double hwhm_y)
Set the y-axis half-width at half-max (FWHM/2)
Definition ellipse.cc:304
virtual void set(double sigma_x, double sigma_y, double rho)
Set sigma_x, sigma_y, rho.
Definition ellipse.cc:256
virtual void set_h(double hwhm_x, double hwhm_y, double rho)
Set hwhm_x, hwhm_y, rho (half-width at half-max)
Definition ellipse.cc:297
virtual void convolve(const Ellipse &ell)
Convolve this ellipse with another.
Definition ellipse.cc:149
virtual void set_hwhm_x(double hwhm_x)
Set the x-axis half-width at half-max (FWHM/2)
Definition ellipse.cc:303
virtual double get_sigma_xy() const
Return sigma_x*sigma_y.
Definition ellipse.cc:147
virtual double get_sigma_y_sq() const
Get the square of sigma_y.
Definition ellipse.cc:180
virtual void set_xyr(const std::array< double, 3 > &xyr)
Set sigma_x, sigma_y, rho from an array.
Definition ellipse.cc:306
virtual void set_sigma_y(double sigma_y)=0
Set the y-axis dispersion (sigma)
virtual std::array< double, 3 > get_hxyr() const
Get hwhm_x, hwhm_y, rho.
Definition ellipse.cc:166
virtual double get_cov_xy() const
Return the covariance, equal to sigma_x*sigma_y*rho.
Definition ellipse.cc:160
static void check(double size_x, double size_y, double rho, std::string_view error_suffix="")
Check whether Ellipse parameter values are valid, throwing if not.
Definition ellipse.h:137
virtual double get_radius_trace() const
Return the trace radius, equal to sqrt(sigma_x^2 + sigma_y^2)
Definition ellipse.cc:173
virtual void set_hxyr(const std::array< double, 3 > &hxyr)
Set hwhm_x, hwhm_y, rho from an array.
Definition ellipse.cc:305
virtual double get_hwhm_y() const
Get the y-axis half-width at half-maximum.
Definition ellipse.cc:164
virtual double get_area() const
Return the area of this ellipse, equal to pi*sigma_major*sigma_minor.
Definition ellipse.cc:142
virtual std::array< double, 3 > get_xyr() const
Get sigma_x, sigma_y, rho.
Definition ellipse.cc:169
virtual double get_sigma_y() const =0
Get sigma_y.
virtual double get_hwhm_x() const
Get the x-axis half-width at half-maximum.
Definition ellipse.cc:162
virtual void set_sigma_x(double sigma_x)=0
Set the x-axis dispersion (sigma)
virtual double get_sigma_x() const =0
Get sigma_x.
An Ellipse with sigma_x, sigma_y, and rho values.
Definition ellipse.h:283
std::shared_ptr< Ellipse > make_convolution(const Ellipse &ell) const
Return the convolution of this with another ellipse.
Definition ellipse.cc:245
double get_rho() const override
Get rho.
Definition ellipse.cc:319
std::unique_ptr< Ellipse > make_convolution_uniq(const Ellipse &ell) const
Same as make_convolution(), but returning a unique_ptr.
Definition ellipse.cc:248
bool operator!=(const Ellipse &other) const
Definition ellipse.cc:316
bool operator==(const Ellipse &other) const
Definition ellipse.cc:315
void set_rho(double rho) override
Set the correlation parameter (rho)
Definition ellipse.cc:323
void set_sigma_y(double sigma_y) override
Set the y-axis dispersion (sigma)
Definition ellipse.cc:325
Ellipse(std::shared_ptr< EllipseData > data)
Definition ellipse.cc:232
void set_sigma_x(double sigma_x) override
Set the x-axis dispersion (sigma)
Definition ellipse.cc:324
const EllipseData & get_data() const
Return a const ref to this ellipse's data.
Definition ellipse.cc:318
double get_sigma_x() const override
Get sigma_x.
Definition ellipse.cc:320
std::string repr(bool name_keywords=false, std::string_view namespace_separator=Object::CC_NAMESPACE_SEPARATOR) const override
Return a full, callable string representation of this.
Definition ellipse.cc:308
std::string str() const override
Return a brief, human-readable string representation of this.
Definition ellipse.cc:313
double get_sigma_y() const override
Get sigma_y.
Definition ellipse.cc:321
An Ellipse with r_major, axrat and angle values.
Definition ellipse.h:337
bool operator!=(const EllipseMajor &other) const
Definition ellipse.cc:429
void set_degrees(bool degrees)
Definition ellipse.cc:399
double get_axrat() const
Get the axis ratio.
Definition ellipse.h:364
double get_r_major() const
Get the major axis length.
Definition ellipse.h:362
double get_angle_radians() const
Get the position angle in radians.
Definition ellipse.h:370
static void check(double r_major, double axrat, double angle)
Check whether the supplied values are valid, throwing if not.
Definition ellipse.h:352
void set_angle(double angle)
Definition ellipse.cc:397
void set_rqa(const std::array< double, 3 > &rqa)
Definition ellipse.cc:409
bool operator==(const EllipseMajor &other) const
Definition ellipse.cc:424
void set_r_major(double r_major)
Definition ellipse.cc:381
std::string repr(bool name_keywords=false, std::string_view namespace_separator=Object::CC_NAMESPACE_SEPARATOR) const override
Return a full, callable string representation of this.
Definition ellipse.cc:411
void set_axrat(double axrat)
Definition ellipse.cc:389
void set(double r_major, double axrat, double angle)
Definition ellipse.cc:374
double get_angle_degrees() const
Get the position angle in degrees.
Definition ellipse.h:368
std::string str() const override
Return a brief, human-readable string representation of this.
Definition ellipse.cc:418
EllipseMajor(double r_major, double axrat, double angle, bool degrees=false)
Construct a new EllipseMajor object with default float values.
Definition ellipse.cc:361
An EllipseData storing sigma_x, sigma_y, rho values as shared_ptrs.
Definition ellipse.h:232
void set_rho(double rho) override
Set the correlation parameter (rho)
Definition ellipse.cc:200
void set_h(double hwhm_x, double hwhm_y, double rho) override
Set hwhm_x, hwhm_y, rho (half-width at half-max)
Definition ellipse.cc:212
double get_rho() const override
Get rho.
Definition ellipse.cc:187
std::string str() const override
Return a brief, human-readable string representation of this.
Definition ellipse.cc:226
std::array< double, 3 > get_xyr() const override
Get sigma_x, sigma_y, rho.
Definition ellipse.cc:188
void set(double sigma_x, double sigma_y, double rho) override
Set sigma_x, sigma_y, rho.
Definition ellipse.cc:205
std::string repr(bool name_keywords=false, std::string_view namespace_separator=Object::CC_NAMESPACE_SEPARATOR) const override
Return a full, callable string representation of this.
Definition ellipse.cc:219
void set_sigma_x(double sigma_x) override
Set the x-axis dispersion (sigma)
Definition ellipse.cc:190
double get_sigma_y() const override
Get sigma_y.
Definition ellipse.cc:186
void set_sigma_y(double sigma_y) override
Set the y-axis dispersion (sigma)
Definition ellipse.cc:195
double get_sigma_x() const override
Get sigma_x.
Definition ellipse.cc:185
T cos(T... args)
daf::base::PropertySet * set
Definition fits.cc:931
const double M_PI_180
Definition ellipse.h:40
const double M_SIGMA_HWHM
Definition ellipse.h:39
void init(EllipseMajor &ellipse, const Covariance &covar, bool degrees)
Definition ellipse.cc:345
std::ostream & operator<<(std::ostream &out, const Covariance &obj)
Definition ellipse.cc:137
const double M_HWHM_SIGMA
Definition ellipse.h:38
const double M_180_PI
Definition ellipse.h:41
std::string to_string_float(const T value, const int precision=6, const bool scientific=true)
Definition to_string.h:15
std::pair< S, S > sincos(S arg)
Definition ellipse.cc:36
std::pair< double, double > get_x_pm(double sigma_x_sq, double sigma_y_sq, double cov_xy)
Definition ellipse.cc:327
STL namespace.
T sin(T... args)