LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
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 "boost/make_shared.hpp"
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 : private boost::noncopyable {
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 private:
51  GaussianPsfPersistenceHelper() :
52  schema(),
53  dimensions(
54  afw::table::PointKey<int>::addFields(
55  schema,
56  "dimensions",
57  "width/height of realization of Psf", "pixels"
58  )
59  ),
60  sigma(schema.addField<double>("sigma", "radius of Gaussian", "pixels"))
61  {
62  schema.getCitizen().markPersistent();
63  }
64 };
65 
66 class GaussianPsfFactory : public afw::table::io::PersistableFactory {
67 public:
68 
69  virtual PTR(afw::table::io::Persistable)
70  read(InputArchive const & archive, CatalogVector const & catalogs) const {
71  static GaussianPsfPersistenceHelper const & keys = GaussianPsfPersistenceHelper::get();
72  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
73  LSST_ARCHIVE_ASSERT(catalogs.front().size() == 1u);
74  afw::table::BaseRecord const & record = catalogs.front().front();
75  LSST_ARCHIVE_ASSERT(record.getSchema() == keys.schema);
76  return boost::make_shared<GaussianPsf>(
77  record.get(keys.dimensions.getX()),
78  record.get(keys.dimensions.getY()),
79  record.get(keys.sigma)
80  );
81  }
82 
83  GaussianPsfFactory(std::string const & name) : afw::table::io::PersistableFactory(name) {}
84 
85 };
86 
87 GaussianPsfFactory registration("GaussianPsf");
88 
89 void checkDimensions(geom::Extent2I const & dimensions) {
90  if (dimensions.getX() % 2 == 0 || dimensions.getY() % 2 == 2) {
91  throw LSST_EXCEPT(
92  pex::exceptions::InvalidParameterError,
93  "GaussianPsf dimensions must be odd"
94  );
95  }
96 }
97 
98 } // anonymous
99 
100 GaussianPsf::GaussianPsf(int width, int height, double sigma) :
101  Psf(true), _dimensions(width, height), _sigma(sigma)
102 {
103  checkDimensions(_dimensions);
104 }
105 
106 GaussianPsf::GaussianPsf(geom::Extent2I const & dimensions, double sigma) :
107  Psf(true), _dimensions(dimensions), _sigma(sigma)
108 {
109  checkDimensions(_dimensions);
110 }
111 
113  return boost::make_shared<GaussianPsf>(_dimensions, _sigma);
114 }
115 
116 std::string GaussianPsf::getPersistenceName() const { return "GaussianPsf"; }
117 
118 std::string GaussianPsf::getPythonModule() const { return "lsst.afw.detection"; }
119 
121  static GaussianPsfPersistenceHelper const & keys = GaussianPsfPersistenceHelper::get();
122  afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
123  PTR(afw::table::BaseRecord) record = catalog.addNew();
124  (*record)[keys.dimensions.getX()] = _dimensions.getX();
125  (*record)[keys.dimensions.getY()] = _dimensions.getY();
126  (*record)[keys.sigma] = getSigma();
127  handle.saveCatalog(catalog);
128 }
129 
130 PTR(GaussianPsf::Image) GaussianPsf::doComputeKernelImage(
131  geom::Point2D const &, image::Color const &
132 ) const {
133  PTR(Image) r(new Image(_dimensions));
134  Image::Array array = r->getArray();
135  r->setXY0(geom::Point2I(-_dimensions / 2)); // integer truncation intentional
136  double sum = 0.0;
137  for (int yIndex = 0, y = r->getY0(); yIndex < _dimensions.getY(); ++yIndex, ++y) {
138  Image::Array::Reference row = array[yIndex];
139  for (int xIndex = 0, x = r->getX0(); xIndex < _dimensions.getX(); ++xIndex, ++x) {
140  sum += row[xIndex] = std::exp(-0.5*(x*x + y*y)/(_sigma*_sigma));
141  }
142  }
143  array.asEigen() /= sum;
144  return r;
145 }
146 
148  double radius, geom::Point2D const & position, image::Color const & color
149 ) const {
150  return 1.0 - std::exp(-0.5*radius*radius/(_sigma*_sigma));
151 }
152 
154  geom::Point2D const & position, image::Color const & color
155 ) const {
156  return geom::ellipses::Quadrupole(_sigma*_sigma, _sigma*_sigma, 0.0);
157 }
158 
159 }}} // namespace lsst::afw::detection
int y
An ellipse core with quadrupole moments as parameters.
Definition: Quadrupole.h:45
#define PTR(...)
Definition: base.h:41
table::Key< std::string > name
Definition: ApCorrMap.cc:71
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
Eigen matrix objects that present a view into an ndarray::Array.
An object passed to Persistable::write to allow it to persist itself.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:47
A custom container class for records, based on std::vector.
Definition: Catalog.h:94
double _sigma
Definition: SincCoeffs.cc:196
virtual geom::ellipses::Quadrupole doComputeShape(geom::Point2D const &position, image::Color const &color) const
Definition: GaussianPsf.cc:153
EigenView< Element, ND::value, RMC::value, XprKind, Rows, Cols > asEigen() const
boost::enable_if< typename ExpressionTraits< Scalar >::IsScalar, Scalar >::type sum(Scalar const &scalar)
Definition: operators.h:1250
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:469
double getSigma() const
Return the radius of the Gaussian.
Definition: GaussianPsf.h:68
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
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:118
GaussianPsf(int width, int height, double sigma)
Constructor for a GaussianPsf.
Definition: GaussianPsf.cc:100
virtual void write(OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
Definition: GaussianPsf.cc:120
tbl::Schema schema
int x
int row
Definition: CR.cc:153
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
virtual double doComputeApertureFlux(double radius, geom::Point2D const &position, image::Color const &color) const
Definition: GaussianPsf.cc:147
A multidimensional strided array.
Definition: Array.h:47
Base class for all records.
Definition: BaseRecord.h:27
Point< double, 2 > Point2D
Definition: Point.h:286
A polymorphic base class for representing an image&#39;s Point Spread Function.
Definition: Psf.h:68
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.
Definition: GaussianPsf.cc:116
A circularly symmetric Gaussian Psf class with no spatial variation, intended mostly for testing purp...
Definition: GaussianPsf.h:41