65 lsst::meas::extensions::psfex::Psf
const& psf,
69 _comp(psf.impl->npix),
73 _poly = poly_copy(psf.impl->poly);
75 _pixstep = psf.impl->pixstep;
77 std::copy(psf.impl->size, psf.impl->size + psf.impl->dim, _size.
begin());
79 std::copy(psf.impl->comp, psf.impl->comp + psf.impl->npix, _comp.
begin());
81 for (
int i = 0; i != psf.impl->poly->ndim; ++i) {
82 _context[i].first = psf.impl->contextoffset[i];
83 _context[i].second = psf.impl->contextscale[i];
87 PsfexPsf::PsfexPsf() : ImagePsf(),
88 _averagePosition(
geom::Point2I(0, 0)),
105 return std::make_shared<PsfexPsf>(*
this);
116 double pos[MAXCONTEXT];
120 str(boost::format(
"Only spatial variation (ndim == 2) is supported; saw %d")
126 position = _averagePosition;
129 for (
int i = 0; i <
ndim; ++i) {
130 pos[i] = (position[i] - _context[i].first)/_context[i].second;
133 poly_func(_poly, pos);
135 int const w = _size[0], h = _size[1];
140 const int nbasis = _size.
size() > 2 ? _size[2] : 1;
144 float const vigstep = 1/_pixstep;
145 float const dx = 0.0, dy = 0.0;
150 int sampleW =
bbox.getWidth();
151 int sampleH =
bbox.getHeight();
155 for (
int i = 0; i != nbasis; ++i) {
159 vignet_resample(
const_cast<float *
>(&_comp[i*
w*h]),
w, h,
160 &sampledBasis[0], sampleW, sampleH,
161 -dx*vigstep, -dy*vigstep, vigstep, 1.0);
166 float *pl = &sampledBasis[0];
167 for (
int y = 0;
y != sampleH; ++
y) {
168 for (
int x = 0;
x != sampleW; ++
x) {
174 kernels.
push_back(std::make_shared<afw::math::FixedKernel>(kim));
178 _kernel = std::make_shared<afw::math::LinearCombinationKernel>(kernels, weights);
203 int const w = _size[0], h = _size[1];
204 int sampleW =
static_cast<int>(
w*_pixstep);
205 int sampleH =
static_cast<int>(h*_pixstep);
208 if (sampleW % 2 == 0) sampleW += 1;
209 if (sampleH % 2 == 0) sampleH += 1;
211 float dx = center[0] -
static_cast<int>(center[0]);
212 float dy = center[1] -
static_cast<int>(center[1]);
214 if (dx > 0.5) dx -= 1.0;
215 if (dy > 0.5) dy -= 1.0;
219 static_cast<int>(center[1] - dy + 0.5) - sampleH/2),
230 double pos[MAXCONTEXT];
234 str(boost::format(
"Only spatial variation (ndim == 2) is supported; saw %d")
239 for (
int i = 0; i <
ndim; ++i) {
240 pos[i] = (position[i] - _context[i].first)/_context[i].second;
243 poly_func(_poly, pos);
245 int const w = _size[0], h = _size[1];
247 const int nbasis = _size.
size() > 2 ? _size[2] : 1;
250 int const npix =
w*h;
251 for (
int i = 0; i != nbasis; ++i) {
252 float *pl = &fullresIm[0];
253 float const fac = _poly->basis[i];
254 float const *ppc = &_comp[i*
w*h];
256 for (
int j = 0; j != npix; ++j) {
264 float const vigstep = 1/_pixstep;
265 float dx = center[0] -
static_cast<int>(center[0]);
266 float dy = center[1] -
static_cast<int>(center[1]);
267 if (dx > 0.5) dx -= 1.0;
268 if (dy > 0.5) dy -= 1.0;
275 int sampleW =
bbox.getWidth();
276 int sampleH =
bbox.getHeight();
280 vignet_resample(&fullresIm[0],
w, h,
281 &sampledIm[0], sampleW, sampleH,
282 -dx*vigstep, -dy*vigstep, vigstep, 1.0);
284 float *pl = &sampledIm[0];
285 float const sum =
std::accumulate(pl, pl + sampleW*sampleH,
static_cast<float>(0));
286 for (
int y = 0;
y != sampleH; ++
y) {
287 for (
int x = 0;
x != sampleW; ++
x) {
288 (*im)(
x,
y) = *pl++/sum;
300namespace table = afw::table;
304class PsfexPsfSchema1 {
308 ndim(schema.addField<int>(
"ndim",
"Number of elements in group")),
309 ngroup(schema.addField<int>(
"ngroup",
"Number of elements in degree")),
310 ncoeff(schema.addField<int>(
"ncoeff",
"Number of coefficients")),
312 _size_size(schema.addField<int>(
"_size_size",
"Size of _size array")),
313 _comp_size(schema.addField<int>(
"_comp_size",
"Size of _comp array")),
314 _context_size(schema.addField<int>(
"_context_size",
"Size of _context array")),
316 averagePosition(
afw::table::PointKey<double>::addFields(schema,
"averagePosition",
"average position of stars used to make the PSF",
"pixel")),
317 _pixstep(schema.addField<float>(
"_pixstep",
"oversampling",
"pixel"))
337class PsfexPsfSchema2 {
340 int size_size,
int comp_size,
int context_size) :
343 group(schema.addField<table::Array<int> >(
"group",
"Groups (of coefficients?)",
ndim)),
344 degree(schema.addField<table::Array<int> >(
"degree",
"Degree in each group",
ngroup)),
345 basis(schema.addField<table::Array<double> >(
"basis",
"Values of the basis functions",
ncoeff)),
346 coeff(schema.addField<table::Array<double> >(
"coeff",
"Polynomial coefficients",
ncoeff)),
347 _size(schema.addField<table::Array<int> >(
"_size",
"PSF dimensions", size_size)),
348 _comp(schema.addField<table::Array<float> >(
"_comp",
"Complete pixel data", comp_size)),
349 _context_first( schema.addField<table::Array<double> >(
"_context_first",
350 "Offset to apply to context data", context_size)),
351 _context_second(schema.addField<table::Array<double> >(
"_context_second",
352 "Scale to apply to context data", context_size))
359 table::Key<table::Array<int> >
group;
361 table::Key<table::Array<double> >
basis;
362 table::Key<table::Array<double> >
coeff;
364 table::Key<table::Array<int> > _size;
365 table::Key<table::Array<float> >
_comp;
370std::string getPsfexPsfPersistenceName() {
return "PsfexPsf"; }
381read(InputArchive
const & archive, CatalogVector
const & catalogs)
const {
387 int size_size, comp_size, context_size;
389 PsfexPsfSchema1
const & keys = PsfexPsfSchema1();
399 result->_averagePosition = record.
get(keys.averagePosition);
400 result->_pixstep = record.
get(keys._pixstep);
402 size_size = record.
get(keys._size_size);
403 comp_size = record.
get(keys._comp_size);
404 context_size = record.
get(keys._context_size);
409 size_size, comp_size, context_size);
418 int const *begin = record.
getElement(keys.group);
421 for (
int i = 0; i !=
ndim; ++i) {
427 int const *begin = record.
getElement(keys.degree);
434 double const *begin = record.
getElement(keys.basis);
438 double const *begin = record.
getElement(keys.coeff);
443 int const *begin = record.
getElement(keys._size);
444 result->_size.assign(begin, begin + size_size);
447 float const *begin = record.
getElement(keys._comp);
448 result->_comp.assign(begin, begin + comp_size);
451 double const *begin1 = record.
getElement(keys._context_first);
452 double const *begin2 = record.
getElement(keys._context_second);
453 result->_context.resize(context_size);
454 for (
int i = 0; i != context_size; ++i) {
455 result->_context[i].first = begin1[i];
456 result->_context[i].second = begin2[i];
470 detail::PsfexPsfFactory registration(getPsfexPsfPersistenceName());
483 PsfexPsfSchema1
const keys;
488 record->set(keys.ndim, _poly->ndim);
489 record->set(keys.ngroup, _poly->ngroup);
490 record->set(keys.ncoeff, _poly->ncoeff);
492 record->set(keys.averagePosition, _averagePosition);
493 record->set(keys._pixstep, _pixstep);
494 record->set(keys._size_size, _size.
size());
495 record->set(keys._comp_size, _comp.
size());
496 record->set(keys._context_size, _context.
size());
502 PsfexPsfSchema2
const keys(_poly->ndim, _poly->ngroup, _poly->ncoeff,
508 int *begin = record->getElement(keys.group);
509 std::copy(_poly->group, _poly->group + _poly->ndim, begin);
512 int *begin = record->getElement(keys.degree);
513 std::copy(_poly->degree, _poly->degree + _poly->ngroup, begin);
516 double *begin = record->getElement(keys.basis);
517 std::copy(_poly->basis, _poly->basis + _poly->ncoeff, begin);
520 double *begin = record->getElement(keys.coeff);
521 std::copy(_poly->coeff, _poly->coeff + _poly->ncoeff, begin);
525 int *begin = record->getElement(keys._size);
529 float *begin = record->getElement(keys._comp);
533 double *begin1 = record->getElement(keys._context_first);
534 double *begin2 = record->getElement(keys._context_second);
535 for (
unsigned int i = 0; i != _context.
size(); ++i) {
536 begin1[i] = _context[i].first;
537 begin2[i] = _context[i].second;
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Utilities for persisting KernelPsf and subclasses thereof.
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Describe the colour of a source.
Base class for all records.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
Field< T >::Element * getElement(Key< T > const &key)
Return a pointer to the underlying elements of a field (non-const).
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
An object passed to Persistable::write to allow it to persist itself.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
Dynamically cast a shared_ptr.
An integer coordinate rectangle.
Represent a PSF as a linear combination of PSFEX (== Karhunen-Loeve) basis functions.
std::shared_ptr< lsst::afw::math::LinearCombinationKernel const > getKernel(lsst::geom::Point2D=lsst::geom::Point2D(std::numeric_limits< double >::quiet_NaN())) const
Return the PSF's basis functions as a spatially-invariant LinearCombinationKernel with unit weights.
void write(lsst::afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
lsst::geom::Box2I doComputeBBox(lsst::geom::Point2D const &position, lsst::afw::image::Color const &color) const override
Compute the bbox of the kernel image at the specified position/color.
std::shared_ptr< lsst::afw::detection::Psf::Image > doComputeImage(lsst::geom::Point2D const &position, lsst::afw::image::Color const &color) const override
Compute an image of the Psf at the specified position/colour, at pixel position in the output image.
std::shared_ptr< lsst::afw::detection::Psf > clone() const override
Polymorphic deep copy; should usually be unnecessary as Psfs are immutable.x.
virtual std::shared_ptr< lsst::afw::detection::Psf::Image > _doComputeImage(lsst::geom::Point2D const &position, lsst::afw::image::Color const &color, lsst::geom::Point2D const ¢er) const
Compute an image of the Psf at the specified position/colour, at pixel position in the output image.
std::shared_ptr< lsst::afw::detection::Psf::Image > doComputeKernelImage(lsst::geom::Point2D const &position, lsst::afw::image::Color const &color) const override
Compute an image of the Psf at the specified position/colour, at pixel (0.0, 0.0) in the output image...
std::string getPersistenceName() const override
Name used in table persistence.
std::shared_ptr< afw::detection::Psf > resized(int width, int height) const override
Return a clone with specified kernel dimensions.
std::string getPythonModule() const override
The python module name (for use in table persistence)
PsfexPsfFactory(std::string const &name)
virtual std::shared_ptr< table::io::Persistable > read(InputArchive const &archive, CatalogVector const &catalogs) const
Reports invalid arguments.
Reports errors in the logical structure of the program.
Low-level polynomials (including special polynomials) in C++.
afw::table::PointKey< double > averagePosition
table::Key< int > _context_size
table::Key< table::Array< int > > degree
table::Key< table::Array< float > > _comp
table::Key< float > _pixstep
table::Key< table::Array< double > > _context_first
table::Key< table::Array< double > > coeff
table::Key< table::Array< double > > basis
table::Key< table::Array< double > > _context_second
table::Key< table::Array< int > > group
table::Key< int > _comp_size
table::Key< int > _size_size