24#ifndef LSST_GAUSS2D_FIT_PYTHON_PARAMETERS_H
25#define LSST_GAUSS2D_FIT_PYTHON_PARAMETERS_H
30#include <pybind11/attr.h>
31#include <pybind11/pybind11.h>
32#include <pybind11/stl.h>
34#include "lsst/modelfit/parameters.h"
36#include "gauss2d/fit/parameters.h"
37#include "gauss2d/fit/transforms.h"
41namespace py = pybind11;
42using namespace pybind11::literals;
44namespace g2f = lsst::gauss2d::fit;
45namespace parameters = lsst::modelfit::parameters;
48void declare_limits(py::module &m) {
49 using Class = parameters::Limits<T>;
50 std::string pyclass_name = std::string(
"Limits") + g2f::suffix_type_str<T>();
51 py::classh<Class>(m, pyclass_name.c_str())
52 .def(py::init<T, T, const std::string>(),
"min"_a = -std::numeric_limits<T>::infinity(),
53 "max"_a = std::numeric_limits<T>::infinity(),
"name"_a =
"")
54 .def(
"check", &Class::check)
55 .def(
"clip", &Class::clip)
56 .def_property(
"min", &Class::get_min, &Class::set_min)
57 .def_property(
"max", &Class::get_max, &Class::set_max)
58 .def(
"__repr__", [](
const Class &self) {
return self.repr(
true); })
59 .def(
"__str__", &Class::str);
67template <
class Class,
class C,
typename... Args>
68auto declare_parameter_methods(py::classh<C, Args...> c) {
69 return c.def_property_readonly(
"default", &Class::get_default)
70 .def_property_readonly(
"desc", &Class::get_desc)
71 .def_property(
"fixed", &Class::get_fixed, &Class::set_fixed)
72 .def_property(
"free", &Class::get_free, &Class::set_free)
73 .def_property(
"label", &Class::get_label, &Class::set_label)
79 return parameters::Limits<double>{self.get_limits().get_min(),
80 self.get_limits().get_max()};
83 .def_property_readonly(
"linear", &Class::get_linear)
84 .def_property_readonly(
"min", &Class::get_min)
85 .def_property_readonly(
"max", &Class::get_max)
86 .def_property_readonly(
"name", &Class::get_name)
87 .def_property_readonly(
"ptr", &Class::ptr)
92 .def_property(
"transform", &Class::get_transform, &Class::set_transform)
93 .def_property_readonly(
"transform_derivative", &Class::get_transform_derivative)
95 .def_property(
"value", &Class::get_value, &Class::set_value)
96 .def_property(
"value_transformed", &Class::get_value_transformed, &Class::set_value_transformed)
108 .def(
"__str__", &Class::str);
111template <
typename T,
class C,
class... Bases>
112auto declare_parameter(py::module &m, std::string name, std::string suffix = g2f::suffix_type_str<T>()) {
113 using Base = parameters::ParameterBase<T>;
114 using Class = parameters::Parameter<T, C>;
115 return declare_parameter_methods<Class, C, Base>(
116 py::classh<C, Base, Bases...>(m, (name +
"Parameter" + suffix).c_str())
117 .def(py::init<T, std::shared_ptr<
const parameters::Limits<T>>,
118 std::shared_ptr<
const parameters::Transform<T>>,
119 std::shared_ptr<const parameters::Unit>,
bool, std::string>(),
120 "value"_a = Class::_get_default(),
"limits"_a =
nullptr,
"transform"_a =
nullptr,
121 "unit"_a = lsst::gauss2d::fit::unit_none,
"fixed"_a =
false,
"label"_a =
"")
122 .def(
"__repr__", [](
const C &self) {
return self.repr(
true,
"."); }));
125template <
typename T,
class C,
class... Bases>
126auto declare_sizeparameter(py::module &m, std::string name) {
127 return declare_parameter<T, C, Bases...>(m, name).def_property(
"size", &C::get_size, &C::set_size);
130template <
typename T,
class ClassX,
class ClassY>
131auto declare_sizeparameter_base(py::module &m, std::string suffix = g2f::suffix_type_str<T>()) {
132 py::classh<ClassX>(m, (
"SizeXParameter" + suffix).c_str());
133 py::classh<ClassY>(m, (
"SizeYParameter" + suffix).c_str());
137void declare_transform_base(py::module &m) {
138 using Class = parameters::Transform<T>;
139 py::classh<Class>(m,
"TransformD");
142template <
typename T,
class C,
bool has_factor,
bool has_limits,
typename... Arguments>
143void declare_transform_full(py::module &m, std::string name) {
145 auto x = py::classh<Class, parameters::Transform<T>>(
146 m, (name +
"TransformD").c_str())
147 .def(
"description", &Class::description)
148 .def(
"derivative", &Class::derivative)
149 .def(
"forward", &Class::forward)
150 .def(
"reverse", &Class::reverse)
151 .def(
"__repr__", [](
const Class &self) {
return self.repr(
true,
"."); })
152 .def(
"__str__", &Class::str);
153 if constexpr (has_factor) x.def_property(
"factor", &Class::get_factor, &Class::set_factor);
154 if constexpr (has_limits) x.def_property(
"limits", &Class::get_limits, &Class::set_limits);
155 if constexpr (has_factor && has_limits)
156 x.def(py::init<Arguments...>(),
"limits"_a =
nullptr,
"factor"_a = 1.);
157 else if constexpr (has_factor)
158 x.def(py::init<Arguments...>(),
"factor"_a = 1.);
159 else if constexpr (has_limits)
160 x.def(py::init<Arguments...>(),
"limits"_a =
nullptr);
165template <
typename T,
class C,
typename... Arguments>
166void declare_transform(py::module &m, std::string name) {
167 declare_transform_full<T, C,
false,
false, Arguments...>(m, name);