40ndarray::Array<double, 1, 1> BoundedField::evaluate(ndarray::Array<double const, 1>
const &
x,
41 ndarray::Array<double const, 1>
const &
y)
const {
42 ndarray::Array<double, 1, 1> out = ndarray::allocate(
x.getSize<0>());
43 for (
int i = 0, n =
x.getSize<0>(); i < n; ++i) {
44 out[i] = evaluate(
x[i],
y[i]);
62 template <
typename T,
typename U>
63 void operator()(T &out, U
a)
const {
69 explicit ScaledAdd(
double s) :
scaleBy(s) {}
71 template <
typename T,
typename U>
72 void operator()(T &out, U
a)
const {
80 template <
typename T,
typename U>
81 void operator()(
T &out, U
a)
const {
87 template <
typename T,
typename U>
88 void operator()(T &out, U
a)
const {
110 explicit Bounds(
int step_) :
step(step_),
min(0),
max(0),
end(0) {}
113 void reset(
int min_) {
121 Interpolator(BoundedField
const *field,
lsst::geom::Box2I const *region,
int xStep,
int yStep)
126 _z00(
std::numeric_limits<double>::quiet_NaN()),
127 _z01(
std::numeric_limits<double>::quiet_NaN()),
128 _z10(
std::numeric_limits<double>::quiet_NaN()),
129 _z11(
std::numeric_limits<double>::quiet_NaN()) {}
135 template <
typename T,
typename F>
138 while (_y.end < _region->
getEndY()) {
139 _runRow(img, functor);
147 _runRow(img, functor);
153 template <
typename T,
typename F>
156 _z00 = _field->evaluate(_x.min, _y.min);
157 _z01 = _field->evaluate(_x.min, _y.max);
158 while (_x.max < _region->
getEndX()) {
159 _z10 = _field->evaluate(_x.max, _y.min);
160 _z11 = _field->evaluate(_x.max, _y.max);
161 _runCell(img, functor);
171 _z10 = _field->evaluate(_x.max, _y.min);
172 _z11 = _field->evaluate(_x.max, _y.max);
173 _runCell(img, functor);
181 template <
typename T,
typename F>
183 int dy = _y.max - _y.min;
184 int dx = _x.max - _x.min;
191 auto rowIter = img.
x_at(_x.min - img.
getX0(), _y.min - img.
getY0());
193 functor(*rowIter, _z00);
196 for (
int x = _x.min + 1;
x < _x.end; ++
x, ++rowIter) {
197 functor(*rowIter, ((_x.max -
x) * _z00 + (
x - _x.min) * _z10) / dx);
200 for (
int y = _y.min + 1;
y < _y.end; ++
y) {
202 double z0 = ((_y.max -
y) * _z00 + (
y - _y.min) * _z01) / dy;
203 double z1 = ((_y.max -
y) * _z10 + (
y - _y.min) * _z11) / dy;
205 functor(*rowIter, z0);
208 for (
int x = _x.min + 1;
x < _x.end; ++
x, ++rowIter) {
209 functor(*rowIter, ((_x.max -
x) * z0 + (
x - _x.min) * z1) / dx);
214 BoundedField
const *_field;
218 double _z00, _z01, _z10, _z11;
221template <
typename T,
typename F>
222void applyToImage(BoundedField
const &field,
image::Image<T> &img, F functor,
bool overlapOnly,
int xStep,
226 region.clip(img.
getBBox(image::PARENT));
227 }
else if (region != img.
getBBox(image::PARENT)) {
229 "Image bounding box does not match field bounding box");
232 if (yStep > 1 || xStep > 1) {
233 Interpolator interpolator(&field, ®ion, xStep, yStep);
234 interpolator.run(img, functor);
238 auto subImage = img.
subset(region);
240 ndarray::Array<double, 1> xx = ndarray::allocate(ndarray::makeVector(size));
241 ndarray::Array<double, 1> yy = ndarray::allocate(ndarray::makeVector(size));
243 std::iota(xx.begin(), xx.end(), region.getBeginX());
244 auto outRowIter = subImage.getArray().begin();
245 for (
int y = region.getBeginY();
y < region.getEndY(); ++
y, ++outRowIter) {
247 functor(*outRowIter,
field.evaluate(xx, yy));
259void BoundedField::fillImage(
image::Image<T> &img,
bool overlapOnly,
int xStep,
int yStep)
const {
260 applyToImage(*
this, img, Assign(), overlapOnly, xStep, yStep);
266 applyToImage(*
this, img, ScaledAdd(
scaleBy), overlapOnly, xStep, yStep);
270void BoundedField::multiplyImage(
image::Image<T> &img,
bool overlapOnly,
int xStep,
int yStep)
const {
271 applyToImage(*
this, img, Multiply(), overlapOnly, xStep, yStep);
275void BoundedField::divideImage(
image::Image<T> &img,
bool overlapOnly,
int xStep,
int yStep)
const {
276 applyToImage(*
this, img, Divide(), overlapOnly, xStep, yStep);
279#define INSTANTIATE(T) \
280 template void BoundedField::fillImage(image::Image<T> &, bool, int, int) const; \
281 template void BoundedField::addToImage(image::Image<T> &, double, bool, int, int) const; \
282 template void BoundedField::multiplyImage(image::Image<T> &, bool, int, int) const; \
283 template void BoundedField::divideImage(image::Image<T> &, bool, int, int) const
#define INSTANTIATE(FROMSYS, TOSYS)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
int getX0() const
Return the image's column-origin.
int getWidth() const
Return the number of columns in the image.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
int getY0() const
Return the image's row-origin.
x_iterator x_at(int x, int y) const
Return an x_iterator to the point (x, y) in the image.
A class to represent a 2-dimensional array of pixels.
Image subset(lsst::geom::Box2I const &bbox, ImageOrigin origin=PARENT) const
Return a subimage corresponding to the given box.
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
Dynamically cast a shared_ptr.
An integer coordinate rectangle.
int getBeginX() const noexcept
int getEndY() const noexcept
int getBeginY() const noexcept
int getMaxX() const noexcept
int getMaxY() const noexcept
int getEndX() const noexcept
Reports errors in the logical structure of the program.
def run(self, coaddExposures, bbox, wcs, dataIds, **kwargs)