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
GaussianPsf.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008-2014 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 <memory>
25 
26 #include "ndarray/eigen.h"
27 
33 
34 namespace lsst { namespace afw { namespace detection {
35 
36 namespace {
37 
38 // Read-only singleton struct containing the schema and keys that a GaussianPsf is mapped
39 // to in record persistence.
40 struct GaussianPsfPersistenceHelper {
41  afw::table::Schema schema;
42  afw::table::PointKey<int> dimensions;
43  afw::table::Key<double> sigma;
44 
45  static GaussianPsfPersistenceHelper const & get() {
46  static GaussianPsfPersistenceHelper instance;
47  return instance;
48  }
49 
50  // No copying
51  GaussianPsfPersistenceHelper (const GaussianPsfPersistenceHelper&) = delete;
52  GaussianPsfPersistenceHelper& operator=(const GaussianPsfPersistenceHelper&) = delete;
53 
54  // No moving
55  GaussianPsfPersistenceHelper (GaussianPsfPersistenceHelper&&) = delete;
56  GaussianPsfPersistenceHelper& operator=(GaussianPsfPersistenceHelper&&) = delete;
57 
58 private:
59  GaussianPsfPersistenceHelper() :
60  schema(),
61  dimensions(
62  afw::table::PointKey<int>::addFields(
63  schema,
64  "dimensions",
65  "width/height of realization of Psf", "pixel"
66  )
67  ),
68  sigma(schema.addField<double>("sigma", "radius of Gaussian", "pixel"))
69  {
70  schema.getCitizen().markPersistent();
71  }
72 };
73 
74 class GaussianPsfFactory : public afw::table::io::PersistableFactory {
75 public:
76 
77  virtual PTR(afw::table::io::Persistable)
78  read(InputArchive const & archive, CatalogVector const & catalogs) const {
79  static GaussianPsfPersistenceHelper const & keys = GaussianPsfPersistenceHelper::get();
80  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
81  LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
82  afw::table::BaseRecord const & record = catalogs.front().front();
83  LSST_ARCHIVE_ASSERT(record.getSchema() == keys.schema);
84  return std::make_shared<GaussianPsf>(
85  record.get(keys.dimensions.getX()),
86  record.get(keys.dimensions.getY()),
87  record.get(keys.sigma)
88  );
89  }
90 
91  GaussianPsfFactory(std::string const & name) : afw::table::io::PersistableFactory(name) {}
92 
93 };
94 
95 GaussianPsfFactory registration("GaussianPsf");
96 
97 void checkDimensions(geom::Extent2I const & dimensions) {
98  if (dimensions.getX() % 2 == 0 || dimensions.getY() % 2 == 2) {
99  throw LSST_EXCEPT(
100  pex::exceptions::InvalidParameterError,
101  "GaussianPsf dimensions must be odd"
102  );
103  }
104 }
105 
106 } // anonymous
107 
108 GaussianPsf::GaussianPsf(int width, int height, double sigma) :
109  Psf(true), _dimensions(width, height), _sigma(sigma)
110 {
111  checkDimensions(_dimensions);
112 }
113 
114 GaussianPsf::GaussianPsf(geom::Extent2I const & dimensions, double sigma) :
115  Psf(true), _dimensions(dimensions), _sigma(sigma)
116 {
117  checkDimensions(_dimensions);
118 }
119 
121  return std::make_shared<GaussianPsf>(_dimensions, _sigma);
122 }
123 
124 std::string GaussianPsf::getPersistenceName() const { return "GaussianPsf"; }
125 
126 std::string GaussianPsf::getPythonModule() const { return "lsst.afw.detection"; }
127 
129  static GaussianPsfPersistenceHelper const & keys = GaussianPsfPersistenceHelper::get();
130  afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
131  PTR(afw::table::BaseRecord) record = catalog.addNew();
132  (*record)[keys.dimensions.getX()] = _dimensions.getX();
133  (*record)[keys.dimensions.getY()] = _dimensions.getY();
134  (*record)[keys.sigma] = getSigma();
135  handle.saveCatalog(catalog);
136 }
137 
138 PTR(GaussianPsf::Image) GaussianPsf::doComputeKernelImage(
139  geom::Point2D const &, image::Color const &
140 ) const {
141  PTR(Image) r(new Image(_dimensions));
142  Image::Array array = r->getArray();
143  r->setXY0(geom::Point2I(-_dimensions / 2)); // integer truncation intentional
144  double sum = 0.0;
145  for (int yIndex = 0, y = r->getY0(); yIndex < _dimensions.getY(); ++yIndex, ++y) {
146  Image::Array::Reference row = array[yIndex];
147  for (int xIndex = 0, x = r->getX0(); xIndex < _dimensions.getX(); ++xIndex, ++x) {
148  sum += row[xIndex] = std::exp(-0.5*(x*x + y*y)/(_sigma*_sigma));
149  }
150  }
151  array.asEigen() /= sum;
152  return r;
153 }
154 
156  double radius, geom::Point2D const & position, image::Color const & color
157 ) const {
158  return 1.0 - std::exp(-0.5*radius*radius/(_sigma*_sigma));
159 }
160 
162  geom::Point2D const & position, image::Color const & color
163 ) const {
164  return geom::ellipses::Quadrupole(_sigma*_sigma, _sigma*_sigma, 0.0);
165 }
166 
167 }}} // namespace lsst::afw::detection
int y
An ellipse core with quadrupole moments as parameters.
Definition: Quadrupole.h:45
table::Key< std::string > name
Definition: ApCorrMap.cc:71
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
Definition: GaussianPsf.cc:124
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
double _sigma
Definition: SincCoeffs.cc:196
GaussianPsf(int width, int height, double sigma)
Constructor for a GaussianPsf.
Definition: GaussianPsf.cc:108
virtual geom::ellipses::Quadrupole doComputeShape(geom::Point2D const &position, image::Color const &color) const
Definition: GaussianPsf.cc:161
Point< double, 2 > Point2D
Definition: Point.h:288
afw::table::Key< double > sigma
Definition: GaussianPsf.cc:43
table::Key< table::Array< Kernel::Pixel > > image
Definition: FixedKernel.cc:117
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:42
virtual std::string getPythonModule() const
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
Definition: GaussianPsf.cc:126
double x
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
int row
Definition: CR.cc:159
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
double getSigma() const
Return the radius of the Gaussian.
Definition: GaussianPsf.h:68
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
#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
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
A polymorphic base class for representing an image&#39;s Point Spread Function.
Definition: Psf.h:68
ndarray::Array< PixelT, 2, 1 > Array
A mutable ndarray representation of the image.
Definition: Image.h:166
virtual void write(OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
Definition: GaussianPsf.cc:128
A circularly symmetric Gaussian Psf class with no spatial variation, intended mostly for testing purp...
Definition: GaussianPsf.h:41
virtual double doComputeApertureFlux(double radius, geom::Point2D const &position, image::Color const &color) const
Definition: GaussianPsf.cc:155