lsst.jointcal  master-g9041cab851+12
SimplePolyMapping.h
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 #ifndef LSST_JOINTCAL_SIMPLE_POLY_MAPPING_H
3 #define LSST_JOINTCAL_SIMPLE_POLY_MAPPING_H
4 
5 #include <memory> // for unique_ptr
6 
10 
12 
16 namespace lsst {
17 namespace jointcal {
18 
20 protected:
21  bool toFit;
22  unsigned index;
23  /* inheritance may also work. Perhaps with some trouble because
24  some routines in Mapping and Gtransfo have the same name */
25  std::shared_ptr<Gtransfo> transfo;
26 
27  std::shared_ptr<Gtransfo> errorProp;
28  /* to avoid allocation at every call of positionDerivative.
29  use a pointer for constness */
30  std::unique_ptr<GtransfoLin> lin;
31 
32 public:
33  SimpleGtransfoMapping(Gtransfo const &gtransfo, bool toFit = true)
34  : toFit(toFit), transfo(gtransfo.clone()), errorProp(transfo), lin(new GtransfoLin) {
35  // in this order:
36  // take a copy of the input transfo,
37  // assign the transformation used to propagate errors to the transfo itself
38  // reserve some memory space to compute the derivatives (efficiency).
39  }
40 
46 
47  virtual void freezeErrorScales() {
48  // from there on, updating the transfo does not change the errors.
49  errorProp = transfo->clone();
50  }
51 
52  // interface Mapping functions:
53 
55  unsigned getNpar() const {
56  if (toFit)
57  return transfo->getNpar();
58  else
59  return 0;
60  }
61 
63  void setMappingIndices(std::vector<unsigned> &indices) const {
64  if (indices.size() < getNpar()) indices.resize(getNpar());
65  for (unsigned k = 0; k < getNpar(); ++k) indices[k] = index + k;
66  }
67 
69  void transformPosAndErrors(FatPoint const &where, FatPoint &outPoint) const {
70  transfo->transformPosAndErrors(where, outPoint);
71  FatPoint tmp;
72  errorProp->transformPosAndErrors(where, tmp);
73  outPoint.vx = tmp.vx;
74  outPoint.vy = tmp.vy;
75  outPoint.vxy = tmp.vxy;
76  }
77 
79  void positionDerivative(Point const &where, Eigen::Matrix2d &derivative, double epsilon) const {
80  errorProp->computeDerivative(where, *lin, epsilon);
81  derivative(0, 0) = lin->coeff(1, 0, 0);
82  //
83  /* This does not work : it was proved by rotating the frame
84  see the compilation switch ROTATE_T2 in constrainedpolymodel.cc
85  derivative(1,0) = lin->coeff(1,0,1);
86  derivative(0,1) = lin->coeff(0,1,0);
87  */
88  derivative(1, 0) = lin->coeff(0, 1, 0);
89  derivative(0, 1) = lin->coeff(1, 0, 1);
90  derivative(1, 1) = lin->coeff(0, 1, 1);
91  }
92 
94  void offsetParams(double const *delta) { transfo->offsetParams(delta); }
95 
97  unsigned getIndex() const { return index; }
98 
100  void setIndex(unsigned i) { index = i; }
101 
102  virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint,
103  Eigen::MatrixX2d &H) const {
104  transformPosAndErrors(where, outPoint);
105  transfo->paramDerivatives(where, &H(0, 0), &H(0, 1));
106  }
107 
109  virtual Gtransfo const &getTransfo() const { return *transfo; }
110 };
111 
114  /* to better condition the 2nd derivative matrix, the
115  transformed coordinates are mapped (roughly) on [-1,1].
116  We need both the transform and its derivative. */
117  GtransfoLin _centerAndScale;
118  Eigen::Matrix2d preDer;
119 
120  /* Where we store the combination. */
121  mutable GtransfoPoly actualResult;
122 
123 public:
125 
126  // ! contructor.
129  SimplePolyMapping(GtransfoLin const &CenterAndScale, GtransfoPoly const &gtransfo)
130  : SimpleGtransfoMapping(gtransfo), _centerAndScale(CenterAndScale) {
131  // We assume that the initialization was done properly, for example that
132  // gtransfo = pix2TP*CenterAndScale.invert(), so we do not touch transfo.
133  /* store the (spatial) derivative of _centerAndScale. For the extra
134  diagonal terms, just copied the ones in positionDerivatives */
135  preDer(0, 0) = _centerAndScale.coeff(1, 0, 0);
136  preDer(1, 0) = _centerAndScale.coeff(0, 1, 0);
137  preDer(0, 1) = _centerAndScale.coeff(1, 0, 1);
138  preDer(1, 1) = _centerAndScale.coeff(0, 1, 1);
139 
140  // check of matrix indexing (once for all)
141  MatrixX2d H(3, 2);
142  assert((&H(1, 0) - &H(0, 0)) == 1);
143  }
144 
146  SimplePolyMapping(SimplePolyMapping const &) = delete;
148  SimplePolyMapping &operator=(SimplePolyMapping const &) = delete;
150 
151  /* The SimpleGtransfoMapping version does not account for the
152  _centerAndScale transfo */
153 
154  void positionDerivative(Point const &where, Eigen::Matrix2d &derivative, double epsilon) const {
155  Point tmp = _centerAndScale.apply(where);
156  errorProp->computeDerivative(tmp, *lin, epsilon);
157  derivative(0, 0) = lin->coeff(1, 0, 0);
158  //
159  /* This does not work : it was proved by rotating the frame
160  see the compilation switch ROTATE_T2 in constrainedpolymodel.cc
161  derivative(1,0) = lin->coeff(1,0,1);
162  derivative(0,1) = lin->coeff(0,1,0);
163  */
164  derivative(1, 0) = lin->coeff(0, 1, 0);
165  derivative(0, 1) = lin->coeff(1, 0, 1);
166  derivative(1, 1) = lin->coeff(0, 1, 1);
167  derivative = preDer * derivative;
168  }
169 
171  /* We should put the computation of error propagation and
172  parameter derivatives into the same Gtransfo routine because
173  it could be significantly faster */
174  virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint,
175  Eigen::MatrixX2d &H) const {
176  FatPoint mid;
177  _centerAndScale.transformPosAndErrors(where, mid);
178  transfo->transformPosAndErrors(mid, outPoint);
179  FatPoint tmp;
180  errorProp->transformPosAndErrors(mid, tmp);
181  outPoint.vx = tmp.vx;
182  outPoint.vy = tmp.vy;
183  outPoint.vxy = tmp.vxy;
184  transfo->paramDerivatives(mid, &H(0, 0), &H(0, 1));
185  }
186 
188  void transformPosAndErrors(FatPoint const &where, FatPoint &outPoint) const {
189  FatPoint mid;
190  _centerAndScale.transformPosAndErrors(where, mid);
191  transfo->transformPosAndErrors(mid, outPoint);
192  FatPoint tmp;
193  errorProp->transformPosAndErrors(mid, tmp);
194  outPoint.vx = tmp.vx;
195  outPoint.vy = tmp.vy;
196  outPoint.vxy = tmp.vxy;
197  }
198 
200  Gtransfo const &getTransfo() const {
201  // Cannot fail given the contructor:
202  const GtransfoPoly *fittedPoly = dynamic_cast<const GtransfoPoly *>(&(*transfo));
203  actualResult = (*fittedPoly) * _centerAndScale;
204  return actualResult;
205  }
206 };
207 
208 #ifdef STORAGE
209 
211 class SimpleIdentityMapping : public SimpleGtransfoMapping<GtransfoIdentity> {
212 public:
214  virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint,
215  Eigen::MatrixX2d &H) const {
216  outPoint = where;
217  }
218 };
219 #endif
220 } // namespace jointcal
221 } // namespace lsst
222 
223 #endif // LSST_JOINTCAL_SIMPLE_POLY_MAPPING_H
implements the linear transformations (6 real coefficients).
Definition: Gtransfo.h:292
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
Definition: Gtransfo.cc:485
virtual class needed in the abstraction of the distortion model
Definition: Mapping.h:15
SimpleGtransfoMapping & operator=(SimpleGtransfoMapping const &)=delete
A point in a plane.
Definition: Point.h:13
Mapping implementation for a polynomial transformation.
virtual Gtransfo const & getTransfo() const
Access to the (fitted) transfo.
SimplePolyMapping(GtransfoLin const &CenterAndScale, GtransfoPoly const &gtransfo)
The transformation will be initialized to gtransfo, so that the effective transformation reads gtrans...
void positionDerivative(Point const &where, Eigen::Matrix2d &derivative, double epsilon) const
The derivative w.r.t. position.
Polynomial transformation class.
Definition: Gtransfo.h:191
A Point with uncertainties.
Definition: FatPoint.h:11
void offsetParams(double const *delta)
Remember the error scale and freeze it.
unsigned getNpar() const
Number of parameters in total.
Class for a simple mapping implementing a generic Gtransfo.
Definition: Associations.h:24
void transformPosAndErrors(FatPoint const &where, FatPoint &outPoint) const
Implements as well the centering and scaling of coordinates.
SimpleGtransfoMapping(Gtransfo const &gtransfo, bool toFit=true)
virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint, Eigen::MatrixX2d &H) const
Actually applies the mapping and evaluates the derivatives w.r.t the fitted parameters.
Eigen::Matrix< double, Eigen::Dynamic, 2 > MatrixX2d
Definition: Eigenstuff.h:9
virtual void transformPosAndErrors(const FatPoint &in, FatPoint &out) const
a mix of apply and Derivative
Definition: Gtransfo.cc:566
unsigned getIndex() const
position of the parameters within the grand fitting scheme
virtual void computeTransformAndDerivatives(FatPoint const &where, FatPoint &outPoint, Eigen::MatrixX2d &H) const
Calls the transforms and implements the centering and scaling of coordinates.
a virtual (interface) class for geometric transformations.
Definition: Gtransfo.h:37
Gtransfo const & getTransfo() const
Access to the (fitted) transfo.
void positionDerivative(Point const &where, Eigen::Matrix2d &derivative, double epsilon) const
The derivative w.r.t. position.
double coeff(const unsigned powX, const unsigned powY, const unsigned whichCoord) const
access to coefficients (read only)
Definition: Gtransfo.cc:650
void setMappingIndices(std::vector< unsigned > &indices) const
Sets how this set of parameters (of length Npar()) map into the "grand" fit Expects that indices has ...
void transformPosAndErrors(FatPoint const &where, FatPoint &outPoint) const
The same as above but without the parameter derivatives (used to evaluate chi^2)
std::unique_ptr< GtransfoLin > lin
std::shared_ptr< Gtransfo > errorProp
std::shared_ptr< Gtransfo > transfo