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
BoundedField.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008-2014 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 #include "lsst/pex/exceptions.h"
27 
28 namespace lsst { namespace afw { namespace math {
29 
33 ) const {
35  for (int i = 0, n = x.getSize<0>(); i < n; ++i) {
36  out[i] = evaluate(x[i], y[i]);
37  }
38  return out;
39 }
40 
41 namespace {
42 
43 // We use these operator-based functors to implement the various image-modifying routines
44 // in BoundedField. I don't think this is necessarily the best way to add interoperability
45 // with images, but it seems like a reasonable point on the simplicity vs. featurefulness
46 // scale, and I don't have time to explore more complex solutions (expression templates!).
47 // Of course, in C++11, we could replace all these with lambdas.
48 
49 struct Assign {
50 
51  template <typename T>
52  void operator()(T & out, double a) const { out = a; }
53 
54 };
55 
56 struct ScaledAdd {
57 
58  explicit ScaledAdd(double s) : scaleBy(s) {}
59 
60  template <typename T>
61  void operator()(T & out, double a) const { out += scaleBy * a; }
62 
63  double scaleBy;
64 };
65 
66 struct Multiply {
67 
68  template <typename T>
69  void operator()(T & out, double a) const { out *= a; }
70 
71 };
72 
73 struct Divide {
74 
75  template <typename T>
76  void operator()(T & out, double a) const { out /= a; }
77 
78 };
79 
80 template <typename T, typename F>
81 void applyToImage(BoundedField const & field, image::Image<T> & img, F functor, bool overlapOnly) {
82  geom::Box2I region(field.getBBox());
83  if (overlapOnly) {
84  region.clip(img.getBBox(image::PARENT));
85  } else if (region != img.getBBox(image::PARENT)) {
86  throw LSST_EXCEPT(
87  pex::exceptions::RuntimeError,
88  "Image bounding box does not match field bounding box"
89  );
90  }
91  for (int y = region.getBeginY(), yEnd = region.getEndY(); y < yEnd; ++y) {
92  typename image::Image<T>::x_iterator rowIter = img.x_at(
93  region.getBeginX() - img.getX0(), y - img.getY0()
94  );
95  for (int x = region.getBeginX(), xEnd = region.getEndX(); x < xEnd; ++x, ++rowIter) {
96  functor(*rowIter, field.evaluate(x, y));
97  }
98  }
99 }
100 
101 } // anonymous
102 
103 PTR(BoundedField) operator*(double const scale, CONST_PTR(BoundedField) bf) {
104  return *bf*scale;
105 }
106 
107 template <typename T>
108 void BoundedField::fillImage(image::Image<T> & img, bool overlapOnly) const {
109  applyToImage(*this, img, Assign(), overlapOnly);
110 }
111 
112 template <typename T>
113 void BoundedField::addToImage(image::Image<T> & img, double scaleBy, bool overlapOnly) const {
114  applyToImage(*this, img, ScaledAdd(scaleBy), overlapOnly);
115 }
116 
117 template <typename T>
118 void BoundedField::multiplyImage(image::Image<T> & img, bool overlapOnly) const {
119  applyToImage(*this, img, Multiply(), overlapOnly);
120 }
121 
122 template <typename T>
123 void BoundedField::divideImage(image::Image<T> & img, bool overlapOnly) const {
124  applyToImage(*this, img, Divide(), overlapOnly);
125 }
126 
127 #define INSTANTIATE(T) \
128  template void BoundedField::fillImage(image::Image<T> &, bool) const; \
129  template void BoundedField::addToImage(image::Image<T> &, double, bool) const; \
130  template void BoundedField::multiplyImage(image::Image<T> &, bool) const; \
131  template void BoundedField::divideImage(image::Image<T> &, bool) const
132 
133 INSTANTIATE(float);
134 INSTANTIATE(double);
135 
136 }}} // namespace lsst::afw::math
int y
void clip(Box2I const &other)
Shrink this to ensure that other.contains(*this).
void fillImage(image::Image< T > &image, bool overlapOnly=false) const
#define PTR(...)
Definition: base.h:41
void multiplyImage(image::Image< T > &image, bool overlapOnly=false) const
#define CONST_PTR(...)
Definition: base.h:47
void addToImage(image::Image< T > &image, double scaleBy=1.0, bool overlapOnly=false) const
int getSize() const
Return the size of a specific dimension.
Definition: ArrayBase.h:126
An integer coordinate rectangle.
Definition: Box.h:53
double scaleBy
Definition: BoundedField.cc:63
virtual double evaluate(geom::Point2D const &position) const =0
tbl::Key< int > field
x_iterator x_at(int x, int y) const
Return an x_iterator to the point (x, y) in the image.
Definition: Image.h:329
#define INSTANTIATE(T)
int getY0() const
Definition: Image.h:255
int x
detail::SimpleInitializer< N > allocate(Vector< int, N > const &shape)
Create an expression that allocates uninitialized memory for an array.
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
geom::Box2I getBBox(ImageOrigin origin=PARENT) const
Definition: Image.h:377
An abstract base class for 2-d functions defined on an integer bounding boxes.
Definition: BoundedField.h:49
A class to represent a 2-dimensional array of pixels.
Definition: PSF.h:43
void divideImage(image::Image< T > &image, bool overlapOnly=false) const
Include files required for standard LSST Exception handling.
int getX0() const
Definition: Image.h:247