LSST Applications g070148d5b3+33e5256705,g0d53e28543+25c8b88941,g0da5cf3356+2dd1178308,g1081da9e2a+62d12e78cb,g17e5ecfddb+7e422d6136,g1c76d35bf8+ede3a706f7,g295839609d+225697d880,g2e2c1a68ba+cc1f6f037e,g2ffcdf413f+853cd4dcde,g38293774b4+62d12e78cb,g3b44f30a73+d953f1ac34,g48ccf36440+885b902d19,g4b2f1765b6+7dedbde6d2,g5320a0a9f6+0c5d6105b6,g56b687f8c9+ede3a706f7,g5c4744a4d9+ef6ac23297,g5ffd174ac0+0c5d6105b6,g6075d09f38+66af417445,g667d525e37+2ced63db88,g670421136f+2ced63db88,g71f27ac40c+2ced63db88,g774830318a+463cbe8d1f,g7876bc68e5+1d137996f1,g7985c39107+62d12e78cb,g7fdac2220c+0fd8241c05,g96f01af41f+368e6903a7,g9ca82378b8+2ced63db88,g9d27549199+ef6ac23297,gabe93b2c52+e3573e3735,gb065e2a02a+3dfbe639da,gbc3249ced9+0c5d6105b6,gbec6a3398f+0c5d6105b6,gc9534b9d65+35b9f25267,gd01420fc67+0c5d6105b6,geee7ff78d7+a14128c129,gf63283c776+ede3a706f7,gfed783d017+0c5d6105b6,w.2022.47
LSST Data Management Base Package
Loading...
Searching...
No Matches
cmodel.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"
25
26#include "ndarray/pybind11.h"
27
30
31namespace py = pybind11;
32using namespace pybind11::literals;
33
34namespace lsst {
35namespace meas {
36namespace modelfit {
37namespace {
38
39using PyCModelStageControl = py::class_<CModelStageControl, std::shared_ptr<CModelStageControl>>;
40using PyCModelControl = py::class_<CModelControl, std::shared_ptr<CModelControl>>;
41using PyCModelStageResult = py::class_<CModelStageResult, std::shared_ptr<CModelStageResult>>;
42using PyCModelResult = py::class_<CModelResult, std::shared_ptr<CModelResult>>;
43using PyCModelAlgorithm = py::class_<CModelAlgorithm, std::shared_ptr<CModelAlgorithm>>;
44
45static PyCModelStageControl declareCModelStageControl(py::module &mod) {
46 PyCModelStageControl cls(mod, "CModelStageControl");
47 cls.def(py::init<>());
48 cls.def("getProfile", &CModelStageControl::getProfile);
49 cls.def("getModel", &CModelStageControl::getModel);
50 cls.def("getPrior", &CModelStageControl::getPrior);
51 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, profileName);
52 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, priorSource);
53 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, priorName);
54 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, CModelStageControl, linearPriorConfig);
55 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, CModelStageControl, empiricalPriorConfig);
56 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, nComponents);
57 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, maxRadius);
58 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, usePixelWeights);
59 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, weightsMultiplier);
60 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, CModelStageControl, optimizer);
61 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, doRecordHistory);
62 LSST_DECLARE_CONTROL_FIELD(cls, CModelStageControl, doRecordTime);
63 return cls;
64}
65
66static PyCModelControl declareCModelControl(py::module &mod) {
67 PyCModelControl cls(mod, "CModelControl");
68 cls.def(py::init<>());
69 LSST_DECLARE_CONTROL_FIELD(cls, CModelControl, psfName);
70 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, CModelControl, region);
71 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, CModelControl, initial);
72 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, CModelControl, exp);
73 LSST_DECLARE_NESTED_CONTROL_FIELD(cls, CModelControl, dev);
74 LSST_DECLARE_CONTROL_FIELD(cls, CModelControl, minInitialRadius);
75 LSST_DECLARE_CONTROL_FIELD(cls, CModelControl, fallbackInitialMomentsPsfFactor);
76 return cls;
77}
78
79// Custom wrapper for views to std::bitset.
80template <int N>
81class BitSetView {
82public:
83 explicit BitSetView(std::bitset<N> const *target) : _target(target) {}
84
85 bool operator[](int i) const { return (*_target)[i]; }
86
87 constexpr std::size_t size() const { return N; }
88
89 template <typename PyParent>
90 static void declare(PyParent &parent) {
91 py::class_<BitSetView<N>> cls(parent, ("BitSetView" + std::to_string(N)).c_str());
92 cls.def("__getitem__", &BitSetView<N>::operator[]);
93 cls.def("__len__", &BitSetView<N>::size);
94 }
95
96private:
97 std::bitset<N> const *_target;
98};
99
100static PyCModelStageResult declareCModelStageResult(py::module &mod) {
101 PyCModelStageResult cls(mod, "CModelStageResult");
102
103 cls.def(py::init<>());
104
105 cls.attr("FAILED") = py::cast(int(CModelStageResult::FAILED));
106 cls.attr("TR_SMALL") = py::cast(int(CModelStageResult::TR_SMALL));
107 cls.attr("MAX_ITERATIONS") = py::cast(int(CModelStageResult::MAX_ITERATIONS));
108 cls.attr("NUMERIC_ERROR") = py::cast(int(CModelStageResult::NUMERIC_ERROR));
109 cls.attr("BAD_REFERENCE") = py::cast(int(CModelStageResult::BAD_REFERENCE));
110 cls.attr("NO_FLUX") = py::cast(int(CModelStageResult::NO_FLUX));
111 cls.attr("N_FLAGS") = py::cast(int(CModelStageResult::N_FLAGS));
112
113 // Data members are intentionally read-only from the Python side;
114 // they should only be set by the C++ algorithm code that uses
115 // this class to communicate its outputs.
116 cls.def_readonly("model", &CModelStageResult::model);
117 cls.def_readonly("prior", &CModelStageResult::prior);
118 cls.def_readonly("objfunc", &CModelStageResult::objfunc);
119 cls.def_readonly("likelihood", &CModelStageResult::likelihood);
120 cls.def_readonly("instFlux", &CModelStageResult::instFlux);
121 cls.def_readonly("instFluxErr", &CModelStageResult::instFluxErr);
122 cls.def_readonly("instFluxInner", &CModelStageResult::instFluxInner);
123 cls.def_readonly("objective", &CModelStageResult::objective);
124 cls.def_readonly("time", &CModelStageResult::time);
125 cls.def_readonly("ellipse", &CModelStageResult::ellipse);
126 cls.def_readonly("nonlinear", &CModelStageResult::nonlinear);
127 cls.def_readonly("amplitudes", &CModelStageResult::amplitudes);
128 cls.def_readonly("fixed", &CModelStageResult::fixed);
129
130 // Declare wrappers for a view class for the flags attribute
131 BitSetView<CModelStageResult::N_FLAGS>::declare(cls);
132 // Wrap the flag. attributes
133 cls.def_property_readonly(
134 "flags",
135 [](CModelStageResult const &self) { return BitSetView<CModelStageResult::N_FLAGS>(&self.flags); },
136 py::return_value_policy::reference_internal);
137
138 return cls;
139}
140
141static PyCModelResult declareCModelResult(py::module &mod) {
142 PyCModelResult cls(mod, "CModelResult");
143
144 cls.def(py::init<>());
145
146 cls.attr("FAILED") = py::cast(int(CModelResult::FAILED));
147 cls.attr("REGION_MAX_AREA") = py::cast(int(CModelResult::REGION_MAX_AREA));
148 cls.attr("REGION_MAX_BAD_PIXEL_FRACTION") = py::cast(int(CModelResult::REGION_MAX_BAD_PIXEL_FRACTION));
149 cls.attr("REGION_USED_FOOTPRINT_AREA") = py::cast(int(CModelResult::REGION_USED_FOOTPRINT_AREA));
150 cls.attr("REGION_USED_PSF_AREA") = py::cast(int(CModelResult::REGION_USED_PSF_AREA));
151 cls.attr("REGION_USED_INITIAL_ELLIPSE_MIN") =
153 cls.attr("REGION_USED_INITIAL_ELLIPSE_MAX") =
155 cls.attr("NO_FLUX") = py::cast(int(CModelResult::NO_FLUX));
156
157 // Data members are intentionally read-only from the Python side;
158 // they should only be set by the C++ algorithm code that uses
159 // this class to communicate its outputs.
160 cls.def_readonly("instFlux", &CModelResult::instFlux);
161 cls.def_readonly("instFluxErr", &CModelResult::instFluxErr);
162 cls.def_readonly("instFluxInner", &CModelResult::instFluxInner);
163 cls.def_readonly("fracDev", &CModelResult::fracDev);
164 cls.def_readonly("objective", &CModelResult::objective);
165 cls.def_readonly("initial", &CModelResult::initial);
166 cls.def_readonly("exp", &CModelResult::exp);
167 cls.def_readonly("dev", &CModelResult::dev);
168 cls.def_readonly("initialFitRegion", &CModelResult::initialFitRegion);
169 cls.def_readonly("finalFitRegion", &CModelResult::finalFitRegion);
170 cls.def_readonly("fitSysToMeasSys", &CModelResult::fitSysToMeasSys);
171
172 // Declare wrappers for a view class for the flags attribute
173 BitSetView<CModelResult::N_FLAGS>::declare(cls);
174 // Wrap the flag. attributes
175 cls.def_property_readonly(
176 "flags", [](CModelResult const &self) { return BitSetView<CModelResult::N_FLAGS>(&self.flags); },
177 py::return_value_policy::reference_internal);
178
179 return cls;
180}
181
182static PyCModelAlgorithm declareCModelAlgorithm(py::module &mod) {
183 PyCModelAlgorithm cls(mod, "CModelAlgorithm");
184 cls.def(py::init<std::string const &, CModelControl const &, afw::table::Schema &>(), "name"_a, "ctrl"_a,
185 "schema"_a);
186 cls.def(py::init<std::string const &, CModelControl const &, afw::table::SchemaMapper &>(), "name"_a,
187 "ctrl"_a, "schemaMapper"_a);
188 cls.def(py::init<CModelControl const &>(), "ctrl"_a);
189 cls.def("getControl", &CModelAlgorithm::getControl);
190 cls.def("apply", &CModelAlgorithm::apply, "exposure"_a, "psf"_a, "center"_a, "moments"_a,
191 "approxFlux"_a = -1, "kronRadius"_a = -1, "footprintArea"_a = -1);
192 cls.def("applyForced", &CModelAlgorithm::applyForced, "exposure"_a, "psf"_a, "center"_a, "reference"_a,
193 "approxFlux"_a = -1);
194 cls.def("measure", (void (CModelAlgorithm::*)(afw::table::SourceRecord &,
195 afw::image::Exposure<Pixel> const &) const) &
197 "measRecord"_a, "exposure"_a);
198 cls.def("measure",
199 (void (CModelAlgorithm::*)(afw::table::SourceRecord &, afw::image::Exposure<Pixel> const &,
200 afw::table::SourceRecord const &) const) &
202 "measRecord"_a, "exposure"_a, "refRecord"_a);
203 cls.def("fail", &CModelAlgorithm::fail, "measRecord"_a, "error"_a);
204 cls.def("writeResultToRecord", &CModelAlgorithm::writeResultToRecord, "result"_a, "record"_a);
205 return cls;
206}
207
208PYBIND11_MODULE(cmodel, mod) {
209 py::module::import("lsst.afw.geom.ellipses");
210 py::module::import("lsst.afw.detection");
211 py::module::import("lsst.meas.modelfit.model");
212 py::module::import("lsst.meas.modelfit.priors");
213 py::module::import("lsst.meas.modelfit.optimizer");
214 py::module::import("lsst.meas.modelfit.pixelFitRegion");
215 py::module::import("lsst.meas.modelfit.unitTransformedLikelihood");
216
217 declareCModelStageControl(mod);
218 auto clsControl = declareCModelControl(mod);
219 declareCModelStageResult(mod);
220 auto clsResult = declareCModelResult(mod);
221 auto clsAlgorithm = declareCModelAlgorithm(mod);
222 clsAlgorithm.attr("Control") = clsControl;
223 clsAlgorithm.attr("Result") = clsResult;
224}
225
226}
227}
228}
229} // namespace lsst::meas::modelfit::anonymous
Key< Flag > const & target
void writeResultToRecord(Result const &result, afw::table::BaseRecord &record) const
Copy values from a Result struct to a BaseRecord object.
Control const & getControl() const
Return the control object the algorithm was constructed with.
Definition: CModel.h:446
Result applyForced(afw::image::Exposure< Pixel > const &exposure, shapelet::MultiShapeletFunction const &psf, geom::Point2D const &center, Result const &reference, Scalar approxFlux=-1) const
Run the CModel algorithm in forced mode on an image, supplying inputs directly and returning outputs ...
void fail(afw::table::SourceRecord &measRecord, meas::base::MeasurementError *error) const
Handle an exception thrown by one of the measure() methods, setting the appropriate flag in the given...
void measure(afw::table::SourceRecord &measRecord, afw::image::Exposure< Pixel > const &exposure) const
Run the CModel algorithm on an image, using a SourceRecord for inputs and outputs.
Result apply(afw::image::Exposure< Pixel > const &exposure, shapelet::MultiShapeletFunction const &psf, geom::Point2D const &center, afw::geom::ellipses::Quadrupole const &moments, Scalar approxFlux=-1, Scalar kronRadius=-1, int footprintArea=-1) const
Run the CModel algorithm on an image, supplying inputs directly and returning outputs in a Result.
PYBIND11_MODULE(_cameraGeom, mod)
Definition: _cameraGeom.cc:38
def declare(module, exception_name, base, wrapped_class)
Definition: wrappers.py:153
#define LSST_DECLARE_CONTROL_FIELD(WRAPPER, CLASS, NAME)
Macro used to wrap fields declared by LSST_CONTROL_FIELD using Pybind11.
Definition: python.h:50
#define LSST_DECLARE_NESTED_CONTROL_FIELD(WRAPPER, CLASS, NAME)
Macro used to wrap fields declared by LSST_NESTED_CONTROL_FIELD using Pybind11.
Definition: python.h:72
Scalar instFlux
Flux from the final linear fit.
Definition: CModel.h:365
Scalar objective
Objective value at the best-fit point (chisq/2)
Definition: CModel.h:370
Scalar fracDev
Fraction of flux from the final linear fit in the de Vaucouleur component (always between 0 and 1).
Definition: CModel.h:368
@ REGION_USED_INITIAL_ELLIPSE_MAX
Fit region implied by the best-fit ellipse of the initial was too large, so we used the configuration...
Definition: CModel.h:350
@ REGION_USED_PSF_AREA
Kron radius was unavailable or outside bounds, so the second-moment ellipse scaled to the PSF area wa...
Definition: CModel.h:346
@ FAILED
General failure flag for the linear fit flux; set if any other CModel flag is set,...
Definition: CModel.h:338
@ REGION_USED_INITIAL_ELLIPSE_MIN
Fit region implied by the best-fit ellipse of the initial was too small, so we used the configuration...
Definition: CModel.h:348
@ REGION_USED_FOOTPRINT_AREA
Kron radius was unavailable or outside bounds, so the second-moment ellipse scaled to the footprint a...
Definition: CModel.h:343
@ REGION_MAX_BAD_PIXEL_FRACTION
Set if we aborted early because the fit region had too many bad pixels.
Definition: CModel.h:341
@ NO_FLUX
No flux was measured.
Definition: CModel.h:359
@ REGION_MAX_AREA
Set if we aborted early because the fit region was too large.
Definition: CModel.h:340
Scalar instFluxErr
Flux uncertainty from the final linear fit.
Definition: CModel.h:366
afw::geom::ellipses::Quadrupole finalFitRegion
Pixels used in the exp, dev, and linear fits.
Definition: CModel.h:377
CModelStageResult dev
Results from the de Vaucouleur (Sersic n=4) fit.
Definition: CModel.h:374
CModelStageResult initial
Results from the initial approximate nonlinear fit that feeds the others.
Definition: CModel.h:372
CModelStageResult exp
Results from the exponential (Sersic n=1) fit.
Definition: CModel.h:373
Scalar instFluxInner
Flux measured strictly within the fit region (no extrapolation).
Definition: CModel.h:367
afw::geom::ellipses::Quadrupole initialFitRegion
Pixels used in the initial fit.
Definition: CModel.h:376
LocalUnitTransform fitSysToMeasSys
Transforms to the coordinate system where parameters are defined.
Definition: CModel.h:379
std::shared_ptr< Model > getModel() const
shapelet::RadialProfile const & getProfile() const
Definition: CModel.h:156
std::shared_ptr< Prior > getPrior() const
ndarray::Array< Scalar const, 1, 1 > fixed
Opaque fixed parameters in specialized units.
Definition: CModel.h:324
std::shared_ptr< OptimizerObjective > objfunc
Objective class used by the optimizer.
Definition: CModel.h:313
Scalar instFluxErr
Flux uncertainty from just this stage fit.
Definition: CModel.h:316
std::shared_ptr< Model > model
Model object that defines the parametrization (defined fully by Control struct)
Definition: CModel.h:311
Scalar time
Time spent in this fit in seconds.
Definition: CModel.h:319
std::shared_ptr< Prior > prior
Bayesian priors on the parameters (defined fully by Control struct)
Definition: CModel.h:312
@ TR_SMALL
Whether convergence was due to the optimizer trust region getting too small (not a failure!...
Definition: CModel.h:298
@ N_FLAGS
Non-flag counter to indicate the number of flags.
Definition: CModel.h:306
@ MAX_ITERATIONS
Whether the optimizer exceeded the maximum number of iterations.
Definition: CModel.h:300
@ NUMERIC_ERROR
Optimizer encountered a numerical error (something likely went to infinity).
Definition: CModel.h:302
@ BAD_REFERENCE
Reference fit failed, so forced fit will fail as well.
Definition: CModel.h:304
@ FAILED
General flag, indicating whether the flux for this stage can be trusted.
Definition: CModel.h:297
@ NO_FLUX
No flux was measured.
Definition: CModel.h:305
std::shared_ptr< UnitTransformedLikelihood > likelihood
Object used to evaluate models and compare to data.
Definition: CModel.h:314
Scalar objective
Value of the objective function at the best fit point: chisq/2 - ln(prior)
Definition: CModel.h:318
ndarray::Array< Scalar const, 1, 1 > nonlinear
Opaque nonlinear parameters in specialized units.
Definition: CModel.h:322
Scalar instFluxInner
Flux measured strictly within the fit region (no extrapolation).
Definition: CModel.h:317
Scalar instFlux
Flux measured from just this stage fit.
Definition: CModel.h:315
afw::geom::ellipses::Quadrupole ellipse
Best fit half-light ellipse in pixel coordinates.
Definition: CModel.h:320
ndarray::Array< Scalar const, 1, 1 > amplitudes
Opaque linear parameters in specialized units.
Definition: CModel.h:323
T to_string(T... args)