24#ifndef LSST_GAUSS2D_ELLIPSE_H
41 set(sigma_x_sq, sigma_y_sq, cov_xy);
47 double offdiag_max = sqrt(sigma_x_sq) * sqrt(sigma_y_sq);
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)) {
55 +
"; sigma_x,y_sq >= 0 and -1 < rho < 1 required.");
63 this->
set(sigma_x_sq, sigma_y_sq, cov_xy);
69 cov_ret->convolve(cov);
77 this->_sigma_x_sq = sigma_x * sigma_x;
78 this->_sigma_y_sq = sigma_y * sigma_y;
80 this->
set_cov_xy(sigma_x * sigma_y * (_sigma_x_sq > 0) * (_sigma_y_sq > 0) * rho);
90 if (!(sigma_x_sq >= 0)) {
94 _sigma_x_sq = sigma_x_sq;
98 if (!(sigma_y_sq >= 0)) {
102 _sigma_y_sq = sigma_y_sq;
107 double offdiag_max = sqrt(_sigma_x_sq) * sqrt(_sigma_y_sq);
109 double rho = offdiag_max > 0 ? cov_xy / offdiag_max : -!(cov_xy >= 0) + !(cov_xy <= 0);
110 if (!(rho > -1 && rho < 1)) {
114 +
", offdiag_max=" +
to_string_float(offdiag_max) +
" with implied rho="
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=" :
"")
130 return type_name_str<Covariance>(
true) +
"(sigma_x_sq=" +
to_string_float(_sigma_x_sq)
153 sigma_x = sqrt(sigma_x * sigma_x + sigma_x_ell * sigma_x_ell);
155 sigma_y = sqrt(sigma_y * sigma_y + sigma_y_ell * sigma_y_ell);
157 this->
set(sigma_x, sigma_y, rho);
177 return sigma *
sigma;
182 return sigma *
sigma;
220 return type_name_str<EllipseValues>(
false, namespace_separator) +
"(" + (name_keywords ?
"sigma_x=" :
"")
236 _data->set(sigma_x, sigma_y, rho);
252 ell_ret->convolve(ell);
257 this->
check(sigma_x, sigma_y, rho);
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);
278 const double axrat = ellipse.
get_axrat();
280 this->
set(r_major, r_major, 0);
284 const double sin_th_sq = sin_th * sin_th;
285 const double cos_th_sq = cos_th * cos_th;
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)
293 : sin_th * cos_th * (r_major_sq - r_minor_sq) / (sigma_x * sigma_y);
294 this->
set(sigma_x, sigma_y, rho);
309 return type_name_str<Ellipse>(
false, namespace_separator) +
"(" + (name_keywords ?
"data=" :
"")
310 + _data->repr(name_keywords, namespace_separator) +
")";
328 double apc = 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));
341 pm = (pm > 0) ? sqrt(pm) / 2 : 0;
348 if (sigma_x_sq == 0 && sigma_y_sq == 0)
return;
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;
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;
358 ellipse.
set(r_major, axrat, ang);
362 : _r_major(r_major), _axrat(axrat), _angle(
angle), _degrees(degrees) {
367 init(*
this, covar, degrees);
382 if (!(r_major >= 0)) {
384 +
"; r_major >= 0 required.");
390 if (!(axrat >= 0 && axrat <= 1)) {
392 +
"; 1 >= axrat >= 0 required.");
400 if (degrees && !_degrees) {
403 }
else if (!degrees && _degrees) {
412 return type_name_str<EllipseMajor>(
false, namespace_separator) +
"(" + (name_keywords ?
"r_major=" :
"")
414 +
", " + (name_keywords ?
"angle=" :
"") +
to_string_float(_angle) +
", "
419 return type_name_str<EllipseMajor>(
true) +
"(r_major=" +
to_string_float(_r_major)
table::Key< double > angle
afw::table::Key< double > sigma
A representation of a 2D Gaussian with x and y standard deviations and a covariance value.
bool operator!=(const Covariance &other) const
std::shared_ptr< Covariance > make_convolution(const Covariance &cov) const
Return the convolution of this with another covariance.
double get_cov_xy() const
Get the covariance.
double get_sigma_x_sq() const
Get the square of sigma_x.
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.
void set_sigma_y_sq(double sigma_y_sq)
Set the square of sigma_y.
void set_sigma_x_sq(double sigma_x_sq)
Set the square of sigma_x.
void set_xyc(const std::array< double, 3 > &xyc)
Set sigma_x_sq, sigma_y_sq and cov_xy from an array ref.
std::array< double, 3 > get_xyc() const
Get the array of sigma_x^2, sigma_y^2, covariance.
std::string str() const override
Return a brief, human-readable string representation of this.
double get_sigma_y_sq() const
Get the square of sigma_y.
void convolve(const Covariance &cov)
Convolve with another covariance, adding the values of each parameter to this.
static void check(double sigma_x_sq, double sigma_y_sq, double cov_xy)
Check whether the supplied values are valid, throwing if not.
void set_cov_xy(double cov_xy)
Set the off-diagonal (covariance) term.
void set(const Ellipse &ellipse)
Set values from an ellipse instance.
Covariance(double sigma_x_sq=0, double sigma_y_sq=0, double cov_xy=0)
Construct a new Covariance object.
bool operator==(const Covariance &other) const
Interface for an object storing Ellipse data.
virtual double get_sigma_x_sq() const
Get the square of sigma_x.
static void check_rho(double rho, std::string_view error_suffix="")
Check whether a rho value is valid.
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.
virtual void set_hwhm_y(double hwhm_y)
Set the y-axis half-width at half-max (FWHM/2)
virtual void set(double sigma_x, double sigma_y, double rho)
Set sigma_x, sigma_y, rho.
virtual void set_h(double hwhm_x, double hwhm_y, double rho)
Set hwhm_x, hwhm_y, rho (half-width at half-max)
virtual void convolve(const Ellipse &ell)
Convolve this ellipse with another.
virtual void set_hwhm_x(double hwhm_x)
Set the x-axis half-width at half-max (FWHM/2)
virtual double get_sigma_xy() const
Return sigma_x*sigma_y.
virtual double get_sigma_y_sq() const
Get the square of sigma_y.
virtual void set_xyr(const std::array< double, 3 > &xyr)
Set sigma_x, sigma_y, rho from an array.
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.
virtual double get_cov_xy() const
Return the covariance, equal to sigma_x*sigma_y*rho.
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.
virtual double get_radius_trace() const
Return the trace radius, equal to sqrt(sigma_x^2 + sigma_y^2)
virtual void set_hxyr(const std::array< double, 3 > &hxyr)
Set hwhm_x, hwhm_y, rho from an array.
virtual double get_hwhm_y() const
Get the y-axis half-width at half-maximum.
virtual double get_area() const
Return the area of this ellipse, equal to pi*sigma_major*sigma_minor.
virtual std::array< double, 3 > get_xyr() const
Get sigma_x, sigma_y, rho.
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.
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.
std::shared_ptr< Ellipse > make_convolution(const Ellipse &ell) const
Return the convolution of this with another ellipse.
double get_rho() const override
Get rho.
std::unique_ptr< Ellipse > make_convolution_uniq(const Ellipse &ell) const
Same as make_convolution(), but returning a unique_ptr.
bool operator!=(const Ellipse &other) const
bool operator==(const Ellipse &other) const
void set_rho(double rho) override
Set the correlation parameter (rho)
void set_sigma_y(double sigma_y) override
Set the y-axis dispersion (sigma)
Ellipse(std::shared_ptr< EllipseData > data)
void set_sigma_x(double sigma_x) override
Set the x-axis dispersion (sigma)
const EllipseData & get_data() const
Return a const ref to this ellipse's data.
double get_sigma_x() const override
Get sigma_x.
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.
std::string str() const override
Return a brief, human-readable string representation of this.
double get_sigma_y() const override
Get sigma_y.
An Ellipse with r_major, axrat and angle values.
bool operator!=(const EllipseMajor &other) const
void set_degrees(bool degrees)
double get_axrat() const
Get the axis ratio.
double get_r_major() const
Get the major axis length.
double get_angle_radians() const
Get the position angle in radians.
static void check(double r_major, double axrat, double angle)
Check whether the supplied values are valid, throwing if not.
void set_angle(double angle)
void set_rqa(const std::array< double, 3 > &rqa)
bool operator==(const EllipseMajor &other) const
void set_r_major(double r_major)
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.
void set_axrat(double axrat)
void set(double r_major, double axrat, double angle)
double get_angle_degrees() const
Get the position angle in degrees.
std::string str() const override
Return a brief, human-readable string representation of this.
EllipseMajor(double r_major, double axrat, double angle, bool degrees=false)
Construct a new EllipseMajor object with default float values.
An EllipseData storing sigma_x, sigma_y, rho values as shared_ptrs.
void set_rho(double rho) override
Set the correlation parameter (rho)
void set_h(double hwhm_x, double hwhm_y, double rho) override
Set hwhm_x, hwhm_y, rho (half-width at half-max)
double get_rho() const override
Get rho.
std::string str() const override
Return a brief, human-readable string representation of this.
std::array< double, 3 > get_xyr() const override
Get sigma_x, sigma_y, rho.
void set(double sigma_x, double sigma_y, double rho) override
Set sigma_x, sigma_y, rho.
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.
void set_sigma_x(double sigma_x) override
Set the x-axis dispersion (sigma)
double get_sigma_y() const override
Get sigma_y.
void set_sigma_y(double sigma_y) override
Set the y-axis dispersion (sigma)
double get_sigma_x() const override
Get sigma_x.
daf::base::PropertySet * set
const double M_SIGMA_HWHM
void init(EllipseMajor &ellipse, const Covariance &covar, bool degrees)
std::ostream & operator<<(std::ostream &out, const Covariance &obj)
const double M_HWHM_SIGMA
std::string to_string_float(const T value, const int precision=6, const bool scientific=true)
std::pair< S, S > sincos(S arg)
std::pair< double, double > get_x_pm(double sigma_x_sq, double sigma_y_sq, double cov_xy)