LSSTApplications  18.1.0
LSSTDataManagementBasePackage
SimpleAstrometryMapping.h
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 /*
3  * This file is part of jointcal.
4  *
5  * Developed for the LSST Data Management System.
6  * This product includes software developed by the LSST Project
7  * (https://www.lsst.org).
8  * See the COPYRIGHT file at the top-level directory of this distribution
9  * for details of code ownership.
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
23  */
24 
25 #ifndef LSST_JOINTCAL_SIMPLE_ASTROMETRY_MAPPING_H
26 #define LSST_JOINTCAL_SIMPLE_ASTROMETRY_MAPPING_H
27 
28 #include <memory> // for unique_ptr
29 
32 #include "lsst/jointcal/CcdImage.h"
33 
35 
39 namespace lsst {
40 namespace jointcal {
41 
43 public:
45  : toBeFit(toBeFit),
46  transform(astrometryTransform.clone()),
49  // in this order:
50  // take a copy of the input transform,
51  // assign the transformation used to propagate errors to the transform itself
52  // reserve some memory space to compute the derivatives (efficiency).
53  }
54 
60 
61  virtual void freezeErrorTransform() {
62  // from there on, updating the transform does not change the errors.
63  errorProp = transform->clone();
64  }
65 
66  // interface Mapping functions:
67 
69  std::size_t getNpar() const {
70  if (toBeFit)
71  return transform->getNpar();
72  else
73  return 0;
74  }
75 
77  void getMappingIndices(IndexVector &indices) const {
78  if (indices.size() < getNpar()) indices.resize(getNpar());
79  for (std::size_t k = 0; k < getNpar(); ++k) indices[k] = index + k;
80  }
81 
83  void transformPosAndErrors(FatPoint const &where, FatPoint &outPoint) const {
84  transform->transformPosAndErrors(where, outPoint);
85  FatPoint tmp;
86  errorProp->transformPosAndErrors(where, tmp);
87  outPoint.vx = tmp.vx;
88  outPoint.vy = tmp.vy;
89  outPoint.vxy = tmp.vxy;
90  }
91 
93  void positionDerivative(Point const &where, Eigen::Matrix2d &derivative, double epsilon) const {
94  errorProp->computeDerivative(where, *lin, epsilon);
95  derivative(0, 0) = lin->coeff(1, 0, 0);
96  //
97  /* This does not work : it was proved by rotating the frame
98  see the compilation switch ROTATE_T2 in constrainedAstrometryModel.cc
99  derivative(1,0) = lin->coeff(1,0,1);
100  derivative(0,1) = lin->coeff(0,1,0);
101  */
102  derivative(1, 0) = lin->coeff(0, 1, 0);
103  derivative(0, 1) = lin->coeff(1, 0, 1);
104  derivative(1, 1) = lin->coeff(0, 1, 1);
105  }
106 
108  void offsetParams(Eigen::VectorXd const &delta) {
109  if (toBeFit) transform->offsetParams(delta);
110  }
111 
113  Eigen::Index getIndex() const { return index; }
114 
116  void setIndex(Eigen::Index i) { index = i; }
117 
118  virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint,
119  Eigen::MatrixX2d &H) const {
120  transformPosAndErrors(where, outPoint);
121  transform->paramDerivatives(where, &H(0, 0), &H(0, 1));
122  }
123 
125  virtual AstrometryTransform const &getTransform() const { return *transform; }
126 
128  bool getToBeFit() const { return toBeFit; }
130  void setToBeFit(bool value) { toBeFit = value; }
131 
132 protected:
133  // Whether this Mapping is fit as part of a Model.
134  bool toBeFit;
135  Eigen::Index index;
136  /* inheritance may also work. Perhaps with some trouble because
137  some routines in Mapping and AstrometryTransform have the same name */
139 
141  /* to avoid allocation at every call of positionDerivative.
142  use a pointer for constness */
144 };
145 
148 public:
150 
151  // ! contructor.
156  : SimpleAstrometryMapping(transform), _centerAndScale(CenterAndScale) {
157  // We assume that the initialization was done properly, for example that
158  // transform = pixToTangentPlane*CenterAndScale.inverted(), so we do not touch transform.
159  /* store the (spatial) derivative of _centerAndScale. For the extra
160  diagonal terms, just copied the ones in positionDerivatives */
161  preDer(0, 0) = _centerAndScale.coeff(1, 0, 0);
162  preDer(1, 0) = _centerAndScale.coeff(0, 1, 0);
163  preDer(0, 1) = _centerAndScale.coeff(1, 0, 1);
164  preDer(1, 1) = _centerAndScale.coeff(0, 1, 1);
165 
166  // check of matrix indexing (once for all)
167  MatrixX2d H(3, 2);
168  assert((&H(1, 0) - &H(0, 0)) == 1);
169  }
170 
172  SimplePolyMapping(SimplePolyMapping const &) = delete;
174  SimplePolyMapping &operator=(SimplePolyMapping const &) = delete;
176 
177  /* The SimpleAstrometryMapping version does not account for the
178  _centerAndScale transform */
179 
180  void positionDerivative(Point const &where, Eigen::Matrix2d &derivative, double epsilon) const {
181  Point tmp = _centerAndScale.apply(where);
182  errorProp->computeDerivative(tmp, *lin, epsilon);
183  derivative(0, 0) = lin->coeff(1, 0, 0);
184  //
185  /* This does not work : it was proved by rotating the frame
186  see the compilation switch ROTATE_T2 in constrainedAstrometryModel.cc
187  derivative(1,0) = lin->coeff(1,0,1);
188  derivative(0,1) = lin->coeff(0,1,0);
189  */
190  derivative(1, 0) = lin->coeff(0, 1, 0);
191  derivative(0, 1) = lin->coeff(1, 0, 1);
192  derivative(1, 1) = lin->coeff(0, 1, 1);
193  derivative = preDer * derivative;
194  }
195 
197  /* We should put the computation of error propagation and
198  parameter derivatives into the same AstrometryTransform routine because
199  it could be significantly faster */
200  virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint,
201  Eigen::MatrixX2d &H) const {
202  FatPoint mid;
203  _centerAndScale.transformPosAndErrors(where, mid);
204  transform->transformPosAndErrors(mid, outPoint);
205  FatPoint tmp;
206  errorProp->transformPosAndErrors(mid, tmp);
207  outPoint.vx = tmp.vx;
208  outPoint.vy = tmp.vy;
209  outPoint.vxy = tmp.vxy;
210  transform->paramDerivatives(mid, &H(0, 0), &H(0, 1));
211  }
212 
214  void transformPosAndErrors(FatPoint const &where, FatPoint &outPoint) const {
215  FatPoint mid;
216  _centerAndScale.transformPosAndErrors(where, mid);
217  transform->transformPosAndErrors(mid, outPoint);
218  FatPoint tmp;
219  errorProp->transformPosAndErrors(mid, tmp);
220  outPoint.vx = tmp.vx;
221  outPoint.vy = tmp.vy;
222  outPoint.vxy = tmp.vxy;
223  }
224 
227  // Cannot fail given the contructor:
228  const AstrometryTransformPolynomial *fittedPoly =
229  dynamic_cast<const AstrometryTransformPolynomial *>(&(*transform));
230  actualResult = (*fittedPoly) * _centerAndScale;
231  return actualResult;
232  }
233 
234 private:
235  /* to better condition the 2nd derivative matrix, the
236  transformed coordinates are mapped (roughly) on [-1,1].
237  We need both the transform and its derivative. */
238  AstrometryTransformLinear _centerAndScale;
239  Eigen::Matrix2d preDer;
240 
241  /* Where we store the combination. */
242  mutable AstrometryTransformPolynomial actualResult;
243 };
244 
245 #ifdef STORAGE
246 
248 class SimpleIdentityMapping : public SimpleAstrometryMapping<AstrometryTransformIdentity> {
249 public:
251  virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint,
252  Eigen::MatrixX2d &H) const {
253  outPoint = where;
254  }
255 };
256 #endif
257 } // namespace jointcal
258 } // namespace lsst
259 
260 #endif // LSST_JOINTCAL_SIMPLE_ASTROMETRY_MAPPING_H
SimpleAstrometryMapping & operator=(SimpleAstrometryMapping const &)=delete
std::shared_ptr< AstrometryTransform > transform
void offsetParams(Eigen::VectorXd const &delta)
Remember the error scale and freeze it.
SimpleAstrometryMapping(AstrometryTransform const &astrometryTransform, bool toBeFit=true)
implements the linear transformations (6 real coefficients).
A point in a plane.
Definition: Point.h:36
std::size_t getNpar() const
Number of parameters in total.
Mapping implementation for a polynomial transformation.
Eigen::Index getIndex() const
position of the parameters within the grand fitting scheme
A Point with uncertainties.
Definition: FatPoint.h:34
T resize(T... args)
SimplePolyMapping(AstrometryTransformLinear const &CenterAndScale, AstrometryTransformPolynomial const &transform)
The transformation will be initialized to transform, so that the effective transformation reads trans...
std::unique_ptr< AstrometryTransformLinear > lin
virtual AstrometryTransform const & getTransform() const
Access to the (fitted) transform.
A base class for image defects.
void transformPosAndErrors(FatPoint const &where, FatPoint &outPoint) const
Implements as well the centering and scaling of coordinates.
void transformPosAndErrors(FatPoint const &where, FatPoint &outPoint) const
The same as above but without the parameter derivatives (used to evaluate chi^2)
Eigen::Matrix< double, Eigen::Dynamic, 2 > MatrixX2d
Definition: Eigenstuff.h:33
std::shared_ptr< AstrometryTransform > errorProp
T size(T... args)
STL class.
void setToBeFit(bool value)
Set whether this Mapping is to be fit as part of a Model.
STL class.
a virtual (interface) class for geometric transformations.
bool getToBeFit() const
Get whether this mapping is fit as part of a Model.
virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint, Eigen::MatrixX2d &H) const
Calls the transforms and implements the centering and scaling of coordinates.
void positionDerivative(Point const &where, Eigen::Matrix2d &derivative, double epsilon) const
The derivative w.r.t. position.
void positionDerivative(Point const &where, Eigen::Matrix2d &derivative, double epsilon) const
The derivative w.r.t. position.
virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint, Eigen::MatrixX2d &H) const
Actually applies the AstrometryMapping and evaluates the derivatives w.r.t the fitted parameters...
virtual class needed in the abstraction of the distortion model
void getMappingIndices(IndexVector &indices) const
Sets how this set of parameters (of length Npar()) map into the "grand" fit Expects that indices has ...
AstrometryTransform const & getTransform() const
Access to the (fitted) transform.