LSST Applications  21.0.0+c4f5df5339,21.0.0+e70536a077,21.0.0-1-ga51b5d4+7c60f8a6ea,21.0.0-10-g560fb7b+411cd868f8,21.0.0-10-gcf60f90+8c49d86aa0,21.0.0-13-gc485e61d+38156233bf,21.0.0-16-g7a993c7b9+1041c3824f,21.0.0-2-g103fe59+d9ceee3e5a,21.0.0-2-g1367e85+0b2f7db15a,21.0.0-2-g45278ab+e70536a077,21.0.0-2-g5242d73+0b2f7db15a,21.0.0-2-g7f82c8f+feb9862f5e,21.0.0-2-g8f08a60+9c9a9cfcc8,21.0.0-2-ga326454+feb9862f5e,21.0.0-2-gde069b7+bedfc5e1fb,21.0.0-2-gecfae73+417509110f,21.0.0-2-gfc62afb+0b2f7db15a,21.0.0-3-g21c7a62+a91f7c0b59,21.0.0-3-g357aad2+062581ff1a,21.0.0-3-g4be5c26+0b2f7db15a,21.0.0-3-g65f322c+85aa0ead76,21.0.0-3-g7d9da8d+c4f5df5339,21.0.0-3-gaa929c8+411cd868f8,21.0.0-3-gc44e71e+fd4029fd48,21.0.0-3-ge02ed75+5d9b90b8aa,21.0.0-38-g070523fc+44fda2b515,21.0.0-4-g591bb35+5d9b90b8aa,21.0.0-4-g88306b8+3cdc83ea97,21.0.0-4-gc004bbf+d52368b591,21.0.0-4-gccdca77+a5c54364a0,21.0.0-5-g7ebb681+81e2098694,21.0.0-5-gdf36809+87b8d260e6,21.0.0-6-g2d4f3f3+e70536a077,21.0.0-6-g4e60332+5d9b90b8aa,21.0.0-6-g5ef7dad+3f4e29eeae,21.0.0-7-gc8ca178+0f5e56d48f,21.0.0-9-g9eb8d17+cc2c7a81aa,master-gac4afde19b+5d9b90b8aa,w.2021.07
LSST Data Management Base Package
BaseCore.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
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 LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
27 #include "lsst/geom/Angle.h"
28 #include <boost/format.hpp>
29 #include <map>
30 
31 namespace lsst {
32 namespace afw {
33 namespace geom {
34 namespace ellipses {
35 
36 namespace {
37 
39 
40 RegistryMap& getRegistry() {
41  static RegistryMap instance;
42  return instance;
43 }
44 
45 std::shared_ptr<BaseCore> getRegistryCopy(std::string const& name) {
46  RegistryMap::iterator i = getRegistry().find(name);
47  if (i == getRegistry().end()) {
49  (boost::format("Ellipse core with name '%s' not found in registry.") % name).str());
50  }
51  return i->second->clone();
52 }
53 
54 } // namespace
55 
57  std::shared_ptr<BaseCore> result = getRegistryCopy(name);
58  *result = Quadrupole();
59  return result;
60 }
61 
63  std::shared_ptr<BaseCore> result = getRegistryCopy(name);
64  result->setParameterVector(parameters);
65  return result;
66 }
67 
68 std::shared_ptr<BaseCore> BaseCore::make(std::string const& name, double v1, double v2, double v3) {
69  std::shared_ptr<BaseCore> result = getRegistryCopy(name);
70  result->setParameterVector(ParameterVector(v1, v2, v3));
71  return result;
72 }
73 
75  std::shared_ptr<BaseCore> result = getRegistryCopy(name);
76  *result = other;
77  return result;
78 }
79 
81  std::shared_ptr<BaseCore> result = getRegistryCopy(name);
82  other.apply(*result);
83  return result;
84 }
85 
87  std::shared_ptr<BaseCore> result = getRegistryCopy(name);
88  other.apply(*result);
89  return result;
90 }
91 
93  getRegistry()[example->getName()] = example;
94 }
95 
96 void BaseCore::grow(double buffer) {
97  double a, b, theta;
98  _assignToAxes(a, b, theta);
99  a += buffer;
100  b += buffer;
101  _assignFromAxes(a, b, theta);
102 }
103 
104 void BaseCore::scale(double factor) {
105  double a, b, theta;
106  _assignToAxes(a, b, theta);
107  a *= factor;
108  b *= factor;
109  _assignFromAxes(a, b, theta);
110 }
111 
112 double BaseCore::getArea() const {
113  double a, b, theta;
114  _assignToAxes(a, b, theta);
115  return a * b * lsst::geom::PI;
116 }
117 
119  double a, b, theta;
120  _assignToAxes(a, b, theta);
121  return std::sqrt(a * b);
122 }
123 
124 double BaseCore::getTraceRadius() const {
125  double ixx, iyy, ixy;
126  _assignToQuadrupole(ixx, iyy, ixy);
127  return std::sqrt(0.5 * (ixx + iyy));
128 }
129 
131  double a, b, theta;
132  _assignToAxes(a, b, theta);
133  double c = std::cos(theta);
134  double s = std::sin(theta);
135  c *= c;
136  s *= s;
137  b *= b;
138  a *= a;
139  lsst::geom::Extent2D dimensions(std::sqrt(b * s + a * c), std::sqrt(a * s + b * c));
140  dimensions *= 2;
141  return dimensions;
142 }
143 
145  ParameterVector r;
146  writeParameters(r.data());
147  return r;
148 }
149 
151 
152 bool BaseCore::operator==(BaseCore const& other) const {
153  return getParameterVector() == other.getParameterVector() && getName() == other.getName();
154 }
155 
157  if (&other != this) {
158  // We use Axes instead of Quadrupole here because it allows us to copy Axes without
159  // implicitly normalizing them.
160  double a, b, theta;
161  other._assignToAxes(a, b, theta);
162  _assignFromAxes(a, b, theta);
163  }
164  return *this;
165 }
166 // Delegate to copy-constructor for backward-compatibility
168 
170  if (getName() == other.getName()) {
171  this->operator=(other);
172  return Jacobian::Identity();
173  }
174  // We use Quadrupole instead of Axes here because the ambiguity of the position angle
175  // in the circular case causes some of the Jacobians to/from Axes to be undefined for
176  // exact circles. Quadrupoles don't have that problem, and the Axes-to-Axes case is
177  // handled by the above if block.
178  double ixx, iyy, ixy;
179  Jacobian rhs = other._dAssignToQuadrupole(ixx, iyy, ixy);
180  Jacobian lhs = _dAssignFromQuadrupole(ixx, iyy, ixy);
181  return lhs * rhs;
182 }
183 
184 void BaseCore::_assignQuadrupoleToAxes(double ixx, double iyy, double ixy, double& a, double& b,
185  double& theta) {
186  double xx_p_yy = ixx + iyy;
187  double xx_m_yy = ixx - iyy;
188  double t = std::sqrt(xx_m_yy * xx_m_yy + 4 * ixy * ixy);
189  a = std::sqrt(0.5 * (xx_p_yy + t));
190  b = std::sqrt(0.5 * (xx_p_yy - t));
191  theta = 0.5 * std::atan2(2.0 * ixy, xx_m_yy);
192 }
193 
194 BaseCore::Jacobian BaseCore::_dAssignQuadrupoleToAxes(double ixx, double iyy, double ixy, double& a,
195  double& b, double& theta) {
196  double xx_p_yy = ixx + iyy;
197  double xx_m_yy = ixx - iyy;
198  double t2 = xx_m_yy * xx_m_yy + 4.0 * ixy * ixy;
199  Eigen::Vector3d dt2(2.0 * xx_m_yy, -2.0 * xx_m_yy, 8.0 * ixy);
200  double t = std::sqrt(t2);
201  a = std::sqrt(0.5 * (xx_p_yy + t));
202  b = std::sqrt(0.5 * (xx_p_yy - t));
203  theta = 0.5 * std::atan2(2.0 * ixy, xx_m_yy);
204  Jacobian m = Jacobian::Zero();
205  m(0, 0) = 0.25 * (1.0 + 0.5 * dt2[0] / t) / a;
206  m(0, 1) = 0.25 * (1.0 + 0.5 * dt2[1] / t) / a;
207  m(0, 2) = 0.25 * (0.5 * dt2[2] / t) / a;
208  m(1, 0) = 0.25 * (1.0 - 0.5 * dt2[0] / t) / b;
209  m(1, 1) = 0.25 * (1.0 - 0.5 * dt2[1] / t) / b;
210  m(1, 2) = 0.25 * (-0.5 * dt2[2] / t) / b;
211 
212  m.row(2).setConstant(1.0 / (t * t));
213  m(2, 0) *= -ixy;
214  m(2, 1) *= ixy;
215  m(2, 2) *= xx_m_yy;
216  return m;
217 }
218 
219 void BaseCore::_assignAxesToQuadrupole(double a, double b, double theta, double& ixx, double& iyy,
220  double& ixy) {
221  a *= a;
222  b *= b;
223  double c = std::cos(theta);
224  double s = std::sin(theta);
225  ixy = (a - b) * c * s;
226  c *= c;
227  s *= s;
228  ixx = c * a + s * b;
229  iyy = s * a + c * b;
230 }
231 
232 BaseCore::Jacobian BaseCore::_dAssignAxesToQuadrupole(double a, double b, double theta, double& ixx,
233  double& iyy, double& ixy) {
234  Jacobian m;
235  m.col(0).setConstant(2 * a);
236  m.col(1).setConstant(2 * b);
237  a *= a;
238  b *= b;
239  m.col(2).setConstant(a - b);
240  double c = std::cos(theta);
241  double s = std::sin(theta);
242  double cs = c * s;
243  ixy = (a - b) * c * s;
244  c *= c;
245  s *= s;
246  ixx = c * a + s * b;
247  iyy = s * a + c * b;
248  m(0, 0) *= c;
249  m(0, 1) *= s;
250  m(0, 2) *= -2.0 * cs;
251  m(1, 0) *= s;
252  m(1, 1) *= c;
253  m(1, 2) *= 2.0 * cs;
254  m(2, 0) *= cs;
255  m(2, 1) *= -cs;
256  m(2, 2) *= (c - s);
257  return m;
258 }
259 } // namespace ellipses
260 } // namespace geom
261 } // namespace afw
262 } // namespace lsst
py::object result
Definition: _schema.cc:429
int end
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:49
ItemVariant const * other
Definition: Schema.cc:56
T atan2(T... args)
A temporary-only expression object for ellipse core convolution.
Definition: Convolution.h:46
A temporary-only expression object for ellipse core transformations.
Definition: Transformer.h:49
A base class for parametrizations of the "core" of an ellipse - the ellipticity and size.
Definition: BaseCore.h:55
virtual void writeParameters(double *iter) const =0
Return the size of the bounding box for the ellipse core.
Eigen::Vector3d ParameterVector
Parameter vector type.
Definition: BaseCore.h:61
static Jacobian _dAssignAxesToQuadrupole(double a, double b, double theta, double &ixx, double &iyy, double &ixy)
Return the size of the bounding box for the ellipse core.
Definition: BaseCore.cc:232
static void registerSubclass(std::shared_ptr< BaseCore > const &example)
Return the size of the bounding box for the ellipse core.
Definition: BaseCore.cc:92
void scale(double factor)
Scale the size of the ellipse core by the given factor.
Definition: BaseCore.cc:104
virtual void readParameters(double const *iter)=0
Return the size of the bounding box for the ellipse core.
double getArea() const
Return the area of the ellipse core.
Definition: BaseCore.cc:112
virtual void _assignToQuadrupole(double &ixx, double &iyy, double &ixy) const =0
Return the size of the bounding box for the ellipse core.
void setParameterVector(ParameterVector const &vector)
Set the core parameters from a vector.
Definition: BaseCore.cc:150
virtual std::string getName() const =0
Return a string that identifies this parametrization.
virtual void _assignToAxes(double &a, double &b, double &theta) const =0
Return the size of the bounding box for the ellipse core.
double getDeterminantRadius() const
Return the radius defined as the 4th root of the determinant of the quadrupole matrix.
Definition: BaseCore.cc:118
bool operator==(BaseCore const &other) const
Compare two ellipse cores for equality.
Definition: BaseCore.cc:152
virtual Jacobian _dAssignFromQuadrupole(double ixx, double iyy, double ixy)=0
Return the size of the bounding box for the ellipse core.
lsst::geom::Extent2D computeDimensions() const
Return the size of the bounding box for the ellipse core.
Definition: BaseCore.cc:130
static void _assignAxesToQuadrupole(double a, double b, double theta, double &ixx, double &iyy, double &ixy)
Return the size of the bounding box for the ellipse core.
Definition: BaseCore.cc:219
static Jacobian _dAssignQuadrupoleToAxes(double ixx, double iyy, double ixy, double &a, double &b, double &theta)
Return the size of the bounding box for the ellipse core.
Definition: BaseCore.cc:194
ParameterVector const getParameterVector() const
Return the core parameters as a vector.
Definition: BaseCore.cc:144
Jacobian dAssign(BaseCore const &other)
Assign other to this and return the derivative of the conversion, d(this)/d(other).
Definition: BaseCore.cc:169
virtual void _assignFromAxes(double a, double b, double theta)=0
Return the size of the bounding box for the ellipse core.
static std::shared_ptr< BaseCore > make(std::string const &name)
Definition: BaseCore.cc:56
void grow(double buffer)
Increase the major and minor radii of the ellipse core by the given buffer.
Definition: BaseCore.cc:96
Eigen::Matrix3d Jacobian
Parameter Jacobian matrix type.
Definition: BaseCore.h:64
static void _assignQuadrupoleToAxes(double ixx, double iyy, double ixy, double &a, double &b, double &theta)
Return the size of the bounding box for the ellipse core.
Definition: BaseCore.cc:184
double getTraceRadius() const
Return the radius defined as the square root of one half the trace of the quadrupole matrix.
Definition: BaseCore.cc:124
BaseCore & operator=(BaseCore const &other)
Set the parameters of this ellipse core from another.
Definition: BaseCore.cc:156
An ellipse core with quadrupole moments as parameters.
Definition: Quadrupole.h:47
Reports invalid arguments.
Definition: Runtime.h:66
T cos(T... args)
constexpr double PI
The ratio of a circle's circumference to diameter.
Definition: Angle.h:39
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
A base class for image defects.
T sin(T... args)
T sqrt(T... args)
int m
Definition: SpanSet.cc:49
table::Key< int > b
table::Key< int > a