26 #include "lsst/pex/exceptions.h"
27 #include "lsst/afw/math/FunctionLibrary.h"
28 #include "lsst/afw/image/ImageUtils.h"
29 #include "lsst/afw/table/io/OutputArchive.h"
30 #include "lsst/afw/table/io/InputArchive.h"
31 #include "lsst/afw/table/io/CatalogVector.h"
32 #include "lsst/afw/table/aggregates.h"
33 #include "lsst/afw/detection/PsfFormatter.h"
38 namespace lsst {
namespace meas {
namespace algorithms {
44 struct DoubleGaussianPsfPersistenceHelper {
49 afw::table::Key<double>
b;
51 static DoubleGaussianPsfPersistenceHelper
const &
get() {
52 static DoubleGaussianPsfPersistenceHelper instance;
57 DoubleGaussianPsfPersistenceHelper (
const DoubleGaussianPsfPersistenceHelper&) =
delete;
58 DoubleGaussianPsfPersistenceHelper& operator=(
const DoubleGaussianPsfPersistenceHelper&) =
delete;
61 DoubleGaussianPsfPersistenceHelper (DoubleGaussianPsfPersistenceHelper&&) =
delete;
62 DoubleGaussianPsfPersistenceHelper& operator=(DoubleGaussianPsfPersistenceHelper&&) =
delete;
65 DoubleGaussianPsfPersistenceHelper() :
68 afw::table::PointKey<int>::addFields(
schema,
"dimensions",
"width/height of kernel",
"pixel")
70 sigma1(
schema.addField<double>(
"sigma1",
"radius of inner Gaussian",
"pixel")),
71 sigma2(
schema.addField<double>(
"sigma2",
"radius of outer Gaussian",
"pixel")),
72 b(
schema.addField<double>(
"b",
"central amplitude of outer Gaussian (inner amplitude == 1)"))
74 schema.getCitizen().markPersistent();
78 class DoubleGaussianPsfFactory :
public afw::table::io::PersistableFactory {
81 virtual PTR(afw::table::io::Persistable)
82 read(InputArchive const & archive, CatalogVector const & catalogs)
const {
83 static DoubleGaussianPsfPersistenceHelper
const & keys = DoubleGaussianPsfPersistenceHelper::get();
84 LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
85 LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
86 afw::table::BaseRecord
const & record = catalogs.front().front();
87 LSST_ARCHIVE_ASSERT(record.getSchema() == keys.schema);
88 return std::make_shared<DoubleGaussianPsf>(
89 record.get(keys.dimensions.getX()),
90 record.get(keys.dimensions.getY()),
91 record.get(keys.sigma1),
92 record.get(keys.sigma2),
97 DoubleGaussianPsfFactory(std::string
const & name) : afw::table::io::PersistableFactory(name) {}
102 PTR(afw::math::Kernel) makeDoubleGaussianKernel(
103 int width,
int height,
double sigma1,
double &
sigma2,
double b
105 if (b == 0.0 && sigma2 == 0.0) {
108 if (sigma1 <= 0 || sigma2 <= 0) {
109 throw LSST_EXCEPT(lsst::pex::exceptions::DomainError,
110 (boost::format(
"sigma may not be 0: %g, %g") % sigma1 % sigma2).str());
112 afw::math::DoubleGaussianFunction2<double> dg(sigma1, sigma2, b);
113 PTR(afw::math::Kernel) kernel(new afw::math::AnalyticKernel(width, height, dg));
117 std::
string getDoubleGaussianPsfPersistenceName() {
return "DoubleGaussianPsf"; }
119 DoubleGaussianPsfFactory registration(getDoubleGaussianPsfPersistenceName());
123 DoubleGaussianPsf::DoubleGaussianPsf(
int width,
int height,
double sigma1,
double sigma2,
double b) :
124 KernelPsf(makeDoubleGaussianKernel(width, height, sigma1, sigma2, b)),
125 _sigma1(sigma1), _sigma2(sigma2),
_b(b)
129 return std::make_shared<DoubleGaussianPsf>(
130 getKernel()->getWidth(),
131 getKernel()->getHeight(),
146 static DoubleGaussianPsfPersistenceHelper
const & keys = DoubleGaussianPsfPersistenceHelper::get();
147 afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
148 PTR(afw::table::BaseRecord) record = catalog.addNew();
149 (*record).set(keys.dimensions.getX(),
getKernel()->getWidth());
150 (*record).set(keys.dimensions.getY(),
getKernel()->getHeight());
153 (*record).set(keys.b,
getB());
154 handle.saveCatalog(catalog);
159 namespace lsst {
namespace afw {
namespace detection {
162 daf::persistence::FormatterRegistration
163 PsfFormatter::doubleGaussianPsfRegistration(
164 "DoubleGaussianPsf",
typeid(meas::algorithms::DoubleGaussianPsf), createInstance
DoubleGaussianPsf resized(int width, int height) const
Return a clone with specified kernel dimensions.
A Psf defined by a Kernel.
double getSigma2() const
Return the radius of the outer Gaussian.
DoubleGaussianPsf(int width, int height, double sigma1, double sigma2=0.0, double b=0.0)
Constructor for a DoubleGaussianPsf.
Represent a Psf as a circularly symmetrical double Gaussian.
afw::table::PointKey< int > dimensions
boost::shared_ptr< afw::math::Kernel const > getKernel() const
Return the Kernel used to define this Psf.
double getB() const
Return the ratio of Gaussian peak amplitudes: outer/inner.
afw::table::Key< double > sigma1
virtual void write(OutputArchiveHandle &handle) const
afw::table::Key< double > b
virtual std::string getPersistenceName() const
double getSigma1() const
Return the radius of the inner Gaussian.
afw::table::Key< double > sigma2