LSST Applications g0265f82a02+0e5473021a,g02d81e74bb+bd2ed33bd6,g1470d8bcf6+de7501a2e0,g14a832a312+ff425fae3c,g2079a07aa2+86d27d4dc4,g2305ad1205+91a32aca49,g295015adf3+762506a1ad,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g3ddfee87b4+c34e8be1fa,g487adcacf7+5fae3daba8,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+ea1711114f,g5a732f18d5+53520f316c,g64a986408d+bd2ed33bd6,g858d7b2824+bd2ed33bd6,g8a8a8dda67+585e252eca,g99cad8db69+016a06b37a,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,ga8c6da7877+ef4e3a5875,gb0e22166c9+60f28cb32d,gb6a65358fc+0e5473021a,gba4ed39666+c2a2e4ac27,gbb8dafda3b+09e12c87ab,gc120e1dc64+bc2e06c061,gc28159a63d+0e5473021a,gcf0d15dbbd+c34e8be1fa,gdaeeff99f8+f9a426f77a,ge6526c86ff+508d0e0a30,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gf18bd8381d+8d59551888,gf1cff7945b+bd2ed33bd6,w.2024.16
LSST Data Management Base Package
Loading...
Searching...
No Matches
psf.cc
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2/*
3 * LSST Data Management System
4 * Copyright 2008-2013 LSST Corporation.
5 *
6 * This product includes software developed by the
7 * LSST Project (http://www.lsst.org/).
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the LSST License Statement and
20 * the GNU General Public License along with this program. If not,
21 * see <http://www.lsstcorp.org/LegalNotices/>.
22 */
23
24#include "pybind11/pybind11.h"
26
28
31
32namespace py = pybind11;
33using namespace pybind11::literals;
34
35namespace lsst {
36namespace meas {
37namespace modelfit {
38namespace {
39
40void declareDoubleShapelet(lsst::cpputils::python::WrapperCollection &wrappers) {
41 using Control = DoubleShapeletPsfApproxControl;
42 using Algorithm = DoubleShapeletPsfApproxAlgorithm;
43
44 using PyControl = py::class_<Control, std::shared_ptr<Control>>;
45 using PyAlgorithm = py::class_<Algorithm, std::shared_ptr<Algorithm>, meas::base::SimpleAlgorithm>;
46
47 static auto clsControl =
48 wrappers.wrapType(PyControl(wrappers.module, "DoubleShapeletPsfApproxControl"), [](auto &mod, auto &cls) {
49 cls.def(py::init<>());
50 LSST_DECLARE_CONTROL_FIELD(cls, Control, innerOrder);
51 LSST_DECLARE_CONTROL_FIELD(cls, Control, outerOrder);
52 LSST_DECLARE_CONTROL_FIELD(cls, Control, radiusRatio);
53 LSST_DECLARE_CONTROL_FIELD(cls, Control, peakRatio);
54 LSST_DECLARE_CONTROL_FIELD(cls, Control, minRadius);
55 LSST_DECLARE_CONTROL_FIELD(cls, Control, minRadiusDiff);
56 LSST_DECLARE_CONTROL_FIELD(cls, Control, maxRadiusBoxFraction);
57 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, Control, optimizer);
58 });
59
60 wrappers.wrapType(PyAlgorithm(wrappers.module, "DoubleShapeletPsfApproxAlgorithm"), [](auto &mod, auto &cls) {
61 // wrap anonymous enum values as ints because we'll need to use them as ints
62 cls.attr("Control") = clsControl;
63 cls.attr("FAILURE") = py::cast(Algorithm::FAILURE);
64 cls.attr("INVALID_POINT_FOR_PSF") = py::cast(Algorithm::INVALID_POINT_FOR_PSF);
65 cls.attr("INVALID_MOMENTS") = py::cast(Algorithm::INVALID_MOMENTS);
66 cls.attr("MAX_ITERATIONS") = py::cast(Algorithm::MAX_ITERATIONS);
67
68 cls.def(py::init<Control const &, std::string const &, afw::table::Schema &>(), "ctrl"_a,
69 "name"_a, "schema"_a);
70 cls.def_static("initializeResult", &Algorithm::initializeResult, "ctrl"_a);
71 cls.def_static("fitMoments", &Algorithm::fitMoments, "result"_a, "ctrl"_a, "psfImage"_a);
72 cls.def_static("makeObjective", &Algorithm::makeObjective, "moments"_a, "ctrl"_a, "psfImage"_a);
73 cls.def_static("fitProfile", &Algorithm::fitProfile, "result"_a, "ctrl"_a, "psfImage"_a);
74 cls.def_static("fitShapelets", &Algorithm::fitShapelets, "result"_a, "ctrl"_a, "psfImage"_a);
75 cls.def("measure", &Algorithm::measure, "measRecord"_a, "exposure"_a);
76 cls.def("fail", &Algorithm::fail, "measRecord"_a, "error"_a = nullptr);
77 });
78}
79
80void declareGeneral(lsst::cpputils::python::WrapperCollection &wrappers) {
81 using ComponentControl = GeneralPsfFitterComponentControl;
82 using Control = GeneralPsfFitterControl;
83 using Fitter = GeneralPsfFitter;
84 using Algorithm = GeneralPsfFitterAlgorithm;
85
86 using PyComponentControl = py::class_<ComponentControl, std::shared_ptr<ComponentControl>>;
87 using PyControl = py::class_<Control, std::shared_ptr<Control>>;
88 using PyFitter = py::class_<Fitter, std::shared_ptr<Fitter>>;
89 using PyAlgorithm = py::class_<Algorithm, std::shared_ptr<Algorithm>, Fitter>;
90
91 wrappers.wrapType(PyComponentControl(wrappers.module, "GeneralPsfFitterComponentControl"), [](auto &mod, auto &cls) {
92 cls.def(py::init<int, double>(), "order"_a = 0, "radius"_a = 1.0);
93 LSST_DECLARE_CONTROL_FIELD(cls, ComponentControl, order);
94 LSST_DECLARE_CONTROL_FIELD(cls, ComponentControl, positionPriorSigma);
95 LSST_DECLARE_CONTROL_FIELD(cls ,ComponentControl, ellipticityPriorSigma);
96 LSST_DECLARE_CONTROL_FIELD(cls, ComponentControl, radiusFactor);
97 LSST_DECLARE_CONTROL_FIELD(cls, ComponentControl, radiusPriorSigma);
98 });
99
100 static auto clsControl =
101 wrappers.wrapType(PyControl(wrappers.module, "GeneralPsfFitterControl"), [](auto &mod, auto &cls) {
102 cls.def(py::init<>());
103 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, Control, inner);
104 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, Control, primary);
105 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, Control, wings);
106 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, Control, outer);
107 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, Control, optimizer);
108 LSST_DECLARE_CONTROL_FIELD(cls, Control, defaultNoiseSigma);
109 });
110
111 wrappers.wrapType(PyFitter(wrappers.module, "GeneralPsfFitter"), [](auto &mod, auto &cls) {
112 cls.def(py::init<Control const &>(), "ctrl"_a);
113 cls.def("addFields", &Fitter::addFields, "schema"_a, "prefix"_a);
114 cls.def("getModel", &Fitter::getModel);
115 cls.def("getPrior", &Fitter::getPrior);
116 cls.def("adapt", &Fitter::adapt, "previousFit"_a, "previousModel"_a);
117 // We use lambdas here because the C++ signature has an optional int*
118 // argument not relevant for Python (which confuses pybind11).
119 cls.def("apply", [](Fitter const &self, afw::image::Image<Pixel> const &image,
120 afw::geom::ellipses::Quadrupole const &moments,
121 Scalar noiseSigma) { return self.apply(image, moments, noiseSigma); },
122 "image"_a, "moments"_a, "noiseSigma"_a = -1);
123 cls.def("apply", [](Fitter const &self, afw::image::Image<double> const &image,
124 afw::geom::ellipses::Quadrupole const &moments,
125 Scalar noiseSigma) { return self.apply(image, moments, noiseSigma); },
126 "image"_a, "moments"_a, "noiseSigma"_a = -1);
127 cls.def("apply", [](Fitter const &self, afw::image::Image<Pixel> const &image,
128 shapelet::MultiShapeletFunction const &initial,
129 Scalar noiseSigma) { return self.apply(image, initial, noiseSigma); },
130 "image"_a, "initial"_a, "noiseSigma"_a = -1);
131 cls.def("apply", [](Fitter const &self, afw::image::Image<double> const &image,
132 shapelet::MultiShapeletFunction const &initial,
133 Scalar noiseSigma) { return self.apply(image, initial, noiseSigma); },
134 "image"_a, "initial"_a, "noiseSigma"_a = -1);
135 });
136
137 wrappers.wrapType(PyAlgorithm(wrappers.module, "GeneralPsfFitterAlgorithm"), [](auto &mod, auto &cls) {
138 cls.attr("Control") = clsControl;
139 cls.attr("FAILURE") = py::cast(Algorithm::FAILURE);
140 cls.attr("MAX_INNER_ITERATIONS") = py::cast(Algorithm::MAX_INNER_ITERATIONS);
141 cls.attr("MAX_OUTER_ITERATIONS") = py::cast(Algorithm::MAX_OUTER_ITERATIONS);
142 cls.attr("EXCEPTION") = py::cast(Algorithm::EXCEPTION);
143 cls.attr("CONTAINS_NAN") = py::cast(Algorithm::CONTAINS_NAN);
144 cls.def(py::init<Control const &, afw::table::Schema &, std::string const &>(), "ctrl"_a,
145 "schema"_a, "prefix"_a);
146 cls.def("getKey", &Algorithm::getKey);
147 cls.def("measure",
148 (void (Algorithm::*)(afw::table::SourceRecord &, afw::image::Image<double> const &,
149 shapelet::MultiShapeletFunction const &) const) &
150 Algorithm::measure,
151 "measRecord"_a, "image"_a, "initial"_a);
152 cls.def("measure",
153 (void (Algorithm::*)(afw::table::SourceRecord &, afw::image::Image<double> const &,
154 afw::geom::ellipses::Quadrupole const &) const) &
155 Algorithm::measure,
156 "measRecord"_a, "image"_a, "moments"_a);
157 cls.def("fail", &Algorithm::fail, "measRecord"_a, "error"_a = nullptr);
158 });
159 // MultiShapeletPsfLikelihood intentionally not exposed to Python.
160}
161
162} // namespace
163
165 declareDoubleShapelet(wrappers);
166 declareGeneral(wrappers);
167}
168
169} // namespace modelfit
170} // namespace emeas
171} // namespace lsst:
A helper class for subdividing pybind11 module across multiple translation units (i....
Definition python.h:242
PyType wrapType(PyType cls, ClassWrapperCallback function, bool setModuleName=true)
Add a type (class or enum) wrapper, deferring method and other attribute definitions until finish() i...
Definition python.h:391
double Scalar
Typedefs to be used for probability and parameter values.
Definition common.h:44
VectorQ moments