| LSSTApplications
    20.0.0
    LSSTDataManagementBasePackage | 
 
 
 
Go to the documentation of this file.
   48     auto workspace = 
basis.makeWorkspace();
 
   49     Eigen::MatrixXd matrix = Eigen::MatrixXd::Zero(input.
size(), 
basis.size());
 
   50     Eigen::VectorXd xRhs(input.
size());
 
   51     Eigen::VectorXd yRhs(input.
size());
 
   52     for (
int i = 0; i < matrix.rows(); ++i) {
 
   53         basis.fill(input[i], matrix.row(i), workspace);
 
   54         auto rhs = output[i] - input[i];
 
   60     auto decomp = matrix.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV);
 
   61     if (svdThreshold >= 0) {
 
   62         decomp.setThreshold(svdThreshold);
 
   74     if (shape.getX() <= 0 || shape.getY() <= 0) {
 
   76             pex::exceptions::InvalidParameterError,
 
   77             "Grid shape must be positive." 
   81     points.
reserve(shape.getX()*shape.getY());
 
   82     double const dx = 
bbox.getWidth()/shape.getX();
 
   83     double const dy = 
bbox.getHeight()/shape.getY();
 
   84     for (
int iy = 0; iy < shape.getY(); ++iy) {
 
   85         double const y = 
bbox.getMinY() + iy*dy;
 
   86         for (
int ix = 0; ix < shape.getX(); ++ix) {
 
   95     LSST_THROW_IF_NE(coeffs.getSize<0>(), coeffs.getSize<1>(), pex::exceptions::InvalidParameterError,
 
   96                      "Coefficient matrix must be square (%d != %d).");
 
   98     Eigen::VectorXd packed(
basis.size());
 
   99     for (
auto const & i : 
basis.getIndices()) {
 
  100         packed[i.flat] = coeffs[i.nx][i.ny];
 
  129         a(a_), 
b(b_), 
ap(ap_), 
bp(bp_)
 
  133                          "A and B polynomials must have the same order (%d != %d).");
 
  136                          "A and AP polynomials must have the same order (%d != %d).");
 
  139                          "A and BP polynomials must have the same order (%d != %d).");
 
  162     dpix1(makeGrid(parent._bbox, shape)),
 
  163     siwc(parent._pixelToIwc->applyForward(dpix1))
 
  168     if (parent._useInverse) {
 
  171         dpix2 = parent._pixelToIwc->applyInverse(
siwc);
 
  189     if (
basis.size() > parent._grid->dpix1.size()) {
 
  192             (
boost::format(
"Number of parameters (%d) is larger than number of data points (%d)")
 
  193              % (2*
basis.size()) % (2*parent._grid->dpix1.size())).str()
 
  198     boxFwd.
shift(-parent._crpix);
 
  199     auto fwd = fitSipOneDirection(order, boxFwd, svdThreshold, parent._grid->dpix1, parent._grid->siwc);
 
  202     for (
auto const & point : parent._grid->siwc) {
 
  205     auto inv = fitSipOneDirection(order, boxInv, svdThreshold, parent._grid->siwc, parent._grid->dpix2);
 
  207     return std::make_unique<Solution>(fwd.first, fwd.second, inv.first, inv.second);
 
  213     Eigen::Matrix2d 
const & 
cd,
 
  220     _useInverse(useInverse),
 
  221     _pixelToIwc(
std::move(pixelToIwc)),
 
  224     _cdInv(
lsst::
geom::LinearTransform(
cd).inverted()),
 
  225     _grid(new 
Grid(gridShape, *this)),
 
  226     _solution(
Solution::
fit(order, svdThreshold, *this))
 
  232     Eigen::Matrix2d 
const & 
cd,
 
  235     ndarray::Array<double const, 2> 
const & 
a,
 
  236     ndarray::Array<double const, 2> 
const & 
b,
 
  237     ndarray::Array<double const, 2> 
const & ap,
 
  238     ndarray::Array<double const, 2> 
const & bp,
 
  241     _useInverse(useInverse),
 
  242     _pixelToIwc(
std::move(pixelToIwc)),
 
  245     _cdInv(
lsst::
geom::LinearTransform(
cd).inverted()),
 
  246     _grid(new 
Grid(gridShape, *this)),
 
  249             makePolynomialFromCoeffMatrix(
a),
 
  250             makePolynomialFromCoeffMatrix(
b),
 
  251             makePolynomialFromCoeffMatrix(ap),
 
  252             makePolynomialFromCoeffMatrix(bp)
 
  260     return _solution->a.getBasis().getOrder();
 
  264     return _solution->a[_solution->a.getBasis().index(p, q)];
 
  268     return _solution->b[_solution->b.getBasis().index(p, q)];
 
  272     return _solution->ap[_solution->ap.getBasis().index(p, q)];
 
  276     return _solution->bp[_solution->bp.getBasis().index(p, q)];
 
  281 template <
typename F>
 
  282 Eigen::MatrixXd makeCoefficientMatrix(
std::size_t order, F getter) {
 
  283     Eigen::MatrixXd 
result = Eigen::MatrixXd::Zero(order + 1, order + 1);
 
  286             result(p, q) = getter(p, q);
 
  295     return makeCoefficientMatrix(
 
  297         [
this](
int p, 
int q) { 
return getA(p, q); }
 
  302     return makeCoefficientMatrix(
 
  304         [
this](
int p, 
int q) { 
return getB(p, q); }
 
  309     return makeCoefficientMatrix(
 
  311         [
this](
int p, 
int q) { 
return getAP(p, q); }
 
  316     return makeCoefficientMatrix(
 
  318         [
this](
int p, 
int q) { 
return getBP(p, q); }
 
  324     auto ws = _solution->makeWorkspace();
 
  325     return cd(_solution->applyForward(pix - _crpix, ws));
 
  330     auto ws = _solution->makeWorkspace();
 
  334     for (
auto const & point : pix) {
 
  335         iwc.
push_back(
cd(_solution->applyForward(point - _crpix, ws)));
 
  341     auto ws = _solution->makeWorkspace();
 
  342     return _solution->applyInverse(_cdInv(iwc), ws) + _crpix;
 
  347     auto ws = _solution->makeWorkspace();
 
  350     for (
auto const & point : iwc) {
 
  351         pix.
push_back(_solution->applyInverse(_cdInv(point), ws) + _crpix);
 
  366     _grid = std::make_unique<Grid>(shape, *
this);
 
  383     auto ws = _solution->makeWorkspace();
 
  384     for (
std::size_t i = 0; i < _grid->dpix1.size(); ++i) {
 
  385         auto siwc2 = _solution->applyForward(_grid->dpix1[i], ws);
 
  386         auto dpix2 = _solution->applyInverse(_grid->siwc[i], ws);
 
  387         maxDiff.first = 
std::max(maxDiff.first, (_grid->siwc[i] - siwc2).computeNorm());
 
  388         maxDiff.second = 
std::max(maxDiff.second, (_grid->dpix2[i] - dpix2).computeNorm());
 
  
A Basis2d formed from the product of a Basis1d for each of x and y, truncated at the sum of their ord...
Basis const  & getBasis() const
Return the associated Basis2d object.
#define LSST_THROW_IF_NE(N1, N2, EXC_CLASS, MSG)
Check whether the given values are equal, and throw an LSST Exception if they are not.
Eigen::MatrixXd getA() const noexcept
Return the coefficients of the forward transform polynomial.
void refineGrid(int factor=2)
Update the grid by making it finer by a given integer factor.
lsst::geom::Extent2I getGridShape() const noexcept
Return the number of grid points in x and y.
A fitter and results class for approximating a general Transform in a form compatible with FITS WCS p...
void shift(Extent2D const &offset)
Shift the position of the box by the given offset.
static std::unique_ptr< Solution > fit(int order_, double svdThreshold, SipApproximation const &parent)
lsst::geom::Point2D applyInverse(lsst::geom::Point2D const &iwcs) const
Convert a point from intermediate world coordinates to pixels.
lsst::geom::Point2D applyForward(lsst::geom::Point2D const &pix) const
Convert a point from pixels to intermediate world coordinates.
SipApproximation(std::shared_ptr< TransformPoint2ToPoint2 > pixelToIwc, lsst::geom::Point2D const &crpix, Eigen::Matrix2d const &cd, lsst::geom::Box2D const &bbox, lsst::geom::Extent2I const &gridShape, int order, bool useInverse=true, double svdThreshold=-1)
Construct a new approximation by fitting on a grid of points.
lsst::geom::Extent2I const shape
Function2d< Basis > makeFunction2d(Basis const &basis, Eigen::VectorXd const &coefficients)
Create a Function2d of the appropriate type from a Basis2d and an Eigen object containing coefficient...
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
void updateGrid(lsst::geom::Extent2I const &shape)
Update the grid to the given number of points in x and y.
std::vector< lsst::geom::Point2D > siwc
Workspace makeWorkspace() const
Allocate workspace that can be passed to operator() to avoid repeated memory allocations.
void fit(int order, double svdThreshold=-1)
Obtain a new solution at the given order with the current grid.
poly::PolynomialFunction2dYX::Workspace Workspace
poly::PolynomialFunction2dYX a
poly::PolynomialFunction2dYX bp
poly::PolynomialFunction2dYX ap
std::vector< lsst::geom::Point2D > dpix2
double getHeight() const noexcept
1-d interval accessors
int getOrder() const noexcept
Return the polynomial order of the current solution (same for forward and reverse).
lsst::geom::Point2D applyInverse(lsst::geom::Point2D const &siwc, Workspace &ws) const
PolynomialFunction1d simplified(ScaledPolynomialFunction1d const &f)
Calculate the standard polynomial function that is equivalent to a scaled standard polynomial functio...
Eigen::MatrixXd getAP() const noexcept
Return the coefficients of the reverse transform polynomial.
table::PointKey< double > crpix
double getWidth() const noexcept
1-d interval accessors
Reports errors in the logical structure of the program.
lsst::geom::Extent2D getGridStep() const noexcept
Return the distance between grid points in pixels.
Solution(poly::PolynomialFunction2dYX const &a_, poly::PolynomialFunction2dYX const &b_, poly::PolynomialFunction2dYX const &ap_, poly::PolynomialFunction2dYX const &bp_)
typename Basis::Workspace Workspace
Type returned by makeWorkspace().
table::Key< table::Array< double > > cd
table::Key< table::Array< double > > basis
A base class for image defects.
Grid(lsst::geom::Extent2I const &shape_, SipApproximation const &parent)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Eigen::MatrixXd getBP() const noexcept
Return the coefficients of the reverse transform polynomial.
T emplace_back(T... args)
Reports invalid arguments.
lsst::geom::Point2D applyForward(lsst::geom::Point2D const &dpix, Workspace &ws) const
Workspace makeWorkspace() const
std::pair< double, double > computeMaxDeviation() const noexcept
Return the maximum deviation of the solution from the exact transform on the current grid.
void include(Point2D const &point) noexcept
Expand this to ensure that this->contains(point).
Extent< double, 2 > Extent2D
std::vector< lsst::geom::Point2D > dpix1
Eigen::MatrixXd getB() const noexcept
Return the coefficients of the forward transform polynomial.
ScaledPolynomialBasis2d< PackingOrder::YX > ScaledPolynomialBasis2dYX
A Basis2d for scaled standard polynomials, ordered via PackingOrder::YX.
A floating-point coordinate rectangle geometry.
~SipApproximation() noexcept
A 2-d function defined by a series expansion and its coefficients.
poly::PolynomialFunction2dYX b
PolynomialFunction2d< PackingOrder::YX > PolynomialFunction2dYX
A Function2d for standard polynomials, ordered via PackingOrder::YX.