LSSTApplications  11.0-13-gbb96280,12.1.rc1,12.1.rc1+1,12.1.rc1+2,12.1.rc1+5,12.1.rc1+8,12.1.rc1-1-g06d7636+1,12.1.rc1-1-g253890b+5,12.1.rc1-1-g3d31b68+7,12.1.rc1-1-g3db6b75+1,12.1.rc1-1-g5c1385a+3,12.1.rc1-1-g83b2247,12.1.rc1-1-g90cb4cf+6,12.1.rc1-1-g91da24b+3,12.1.rc1-2-g3521f8a,12.1.rc1-2-g39433dd+4,12.1.rc1-2-g486411b+2,12.1.rc1-2-g4c2be76,12.1.rc1-2-gc9c0491,12.1.rc1-2-gda2cd4f+6,12.1.rc1-3-g3391c73+2,12.1.rc1-3-g8c1bd6c+1,12.1.rc1-3-gcf4b6cb+2,12.1.rc1-4-g057223e+1,12.1.rc1-4-g19ed13b+2,12.1.rc1-4-g30492a7
LSSTDataManagementBasePackage
DoubleGaussianPsf.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 <cmath>
25 
26 #include "lsst/pex/exceptions.h"
35 
37 
38 namespace lsst { namespace meas { namespace algorithms {
39 
40 namespace {
41 
42 // Read-only singleton struct containing the schema and keys that a double-Gaussian Psf is mapped
43 // to in record persistence.
44 struct DoubleGaussianPsfPersistenceHelper {
45  afw::table::Schema schema;
46  afw::table::PointKey<int> dimensions;
47  afw::table::Key<double> sigma1;
48  afw::table::Key<double> sigma2;
49  afw::table::Key<double> b;
50 
51  static DoubleGaussianPsfPersistenceHelper const & get() {
52  static DoubleGaussianPsfPersistenceHelper instance;
53  return instance;
54  }
55 
56  // No copying
57  DoubleGaussianPsfPersistenceHelper (const DoubleGaussianPsfPersistenceHelper&) = delete;
58  DoubleGaussianPsfPersistenceHelper& operator=(const DoubleGaussianPsfPersistenceHelper&) = delete;
59 
60  // No moving
61  DoubleGaussianPsfPersistenceHelper (DoubleGaussianPsfPersistenceHelper&&) = delete;
62  DoubleGaussianPsfPersistenceHelper& operator=(DoubleGaussianPsfPersistenceHelper&&) = delete;
63 
64 private:
65  DoubleGaussianPsfPersistenceHelper() :
66  schema(),
67  dimensions(
68  afw::table::PointKey<int>::addFields(schema, "dimensions", "width/height of kernel", "pixel")
69  ),
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)"))
73  {
74  schema.getCitizen().markPersistent();
75  }
76 };
77 
78 class DoubleGaussianPsfFactory : public afw::table::io::PersistableFactory {
79 public:
80 
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),
93  record.get(keys.b)
94  );
95  }
96 
97  DoubleGaussianPsfFactory(std::string const & name) : afw::table::io::PersistableFactory(name) {}
98 };
99 
100 // Helper function for ctor: need to construct the kernel to pass to KernelPsf, because we
101 // can't change it after construction.
102 PTR(afw::math::Kernel) makeDoubleGaussianKernel(
103  int width, int height, double sigma1, double & sigma2, double b
104 ) {
105  if (b == 0.0 && sigma2 == 0.0) {
106  sigma2 = 1.0; // avoid 0/0 at centre of Psf
107  }
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());
111  }
112  afw::math::DoubleGaussianFunction2<double> dg(sigma1, sigma2, b);
113  PTR(afw::math::Kernel) kernel(new afw::math::AnalyticKernel(width, height, dg));
114  return kernel;
115 }
116 
117 std::string getDoubleGaussianPsfPersistenceName() { return "DoubleGaussianPsf"; }
118 
119 DoubleGaussianPsfFactory registration(getDoubleGaussianPsfPersistenceName());
120 
121 } // anonymous
122 
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)
126 {}
127 
129  return std::make_shared<DoubleGaussianPsf>(
130  getKernel()->getWidth(),
131  getKernel()->getHeight(),
132  _sigma1, _sigma2, _b
133  );
134 }
135 
136 std::string DoubleGaussianPsf::getPersistenceName() const { return getDoubleGaussianPsfPersistenceName(); }
137 
139  static DoubleGaussianPsfPersistenceHelper const & keys = DoubleGaussianPsfPersistenceHelper::get();
140  afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
141  PTR(afw::table::BaseRecord) record = catalog.addNew();
142  (*record).set(keys.dimensions.getX(), getKernel()->getWidth());
143  (*record).set(keys.dimensions.getY(), getKernel()->getHeight());
144  (*record).set(keys.sigma1, getSigma1());
145  (*record).set(keys.sigma2, getSigma2());
146  (*record).set(keys.b, getB());
147  handle.saveCatalog(catalog);
148 }
149 
150 }}} // namespace lsst::meas::algorithms
151 
152 namespace lsst { namespace afw { namespace detection {
153 
155 daf::persistence::FormatterRegistration
156 PsfFormatter::doubleGaussianPsfRegistration(
157  "DoubleGaussianPsf", typeid(meas::algorithms::DoubleGaussianPsf), createInstance
158 );
160 
161 }}} // namespace lsst::afw::detection
162 
A Psf defined by a Kernel.
Definition: KernelPsf.h:33
table::Key< std::string > name
Definition: ApCorrMap.cc:71
double getSigma2() const
Return the radius of the outer Gaussian.
An object passed to Persistable::write to allow it to persist itself.
A custom container class for records, based on std::vector.
Definition: Catalog.h:95
afw::table::Schema schema
Definition: GaussianPsf.cc:41
Define a collection of useful Functions.
Image utility functions.
Represent a Psf as a circularly symmetrical double Gaussian.
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:42
boost::shared_ptr< afw::math::Kernel const > getKernel() const
Return the Kernel used to define this Psf.
Definition: KernelPsf.h:52
double getB() const
Return the ratio of Gaussian peak amplitudes: outer/inner.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
Base class for all records.
Definition: BaseRecord.h:27
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:45
Interface for PsfFormatter class.
afw::table::Key< double > sigma1
virtual void write(OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
#define PTR(...)
Definition: base.h:41
boost::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
Definition: Catalog.h:470
double const _b
Definition: RandomImage.cc:78
afw::table::Key< double > b
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
double getSigma1() const
Return the radius of the inner Gaussian.
Include files required for standard LSST Exception handling.
A polymorphic base class for representing an image&#39;s Point Spread Function.
Definition: Psf.h:68
afw::table::Key< double > sigma2