LSST Applications g0f08755f38+82efc23009,g12f32b3c4e+e7bdf1200e,g1653933729+a8ce1bb630,g1a0ca8cf93+50eff2b06f,g28da252d5a+52db39f6a5,g2bbee38e9b+37c5a29d61,g2bc492864f+37c5a29d61,g2cdde0e794+c05ff076ad,g3156d2b45e+41e33cbcdc,g347aa1857d+37c5a29d61,g35bb328faa+a8ce1bb630,g3a166c0a6a+37c5a29d61,g3e281a1b8c+fb992f5633,g414038480c+7f03dfc1b0,g41af890bb2+11b950c980,g5fbc88fb19+17cd334064,g6b1c1869cb+12dd639c9a,g781aacb6e4+a8ce1bb630,g80478fca09+72e9651da0,g82479be7b0+04c31367b4,g858d7b2824+82efc23009,g9125e01d80+a8ce1bb630,g9726552aa6+8047e3811d,ga5288a1d22+e532dc0a0b,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+37c5a29d61,gcf0d15dbbd+2acd6d4d48,gd7358e8bfb+778a810b6e,gda3e153d99+82efc23009,gda6a2b7d83+2acd6d4d48,gdaeeff99f8+1711a396fd,ge2409df99d+6b12de1076,ge79ae78c31+37c5a29d61,gf0baf85859+d0a5978c5a,gf3967379c6+4954f8c433,gfb92a5be7c+82efc23009,gfec2e1e490+2aaed99252,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
image.h
Go to the documentation of this file.
1/*
2 * This file is part of gauss2d.
3 *
4 * Developed for the LSST Data Management System.
5 * This product includes software developed by the LSST Project
6 * (https://www.lsst.org).
7 * See the COPYRIGHT file at the top-level directory of this distribution
8 * for details of code ownership.
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 GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#ifndef LSST_GAUSS2D_IMAGE_H
25#define LSST_GAUSS2D_IMAGE_H
26
27#include <array>
28#include <cstddef>
29#include <iostream>
30#include <iterator>
31#include <memory>
32#include <stdexcept>
33#include <string>
34#include <utility>
35#include <vector>
36
37#include "coordinatesystem.h"
38#include "object.h"
39#include "type_name.h"
40
41namespace lsst::gauss2d {
42
43typedef size_t idx_type;
44
45template <typename T, class Data, class Indices>
47
48template <typename T, class C>
49class Image;
50
51// TODO: Check if this can/should be a static method in Image
52// Consider that T1/T2 might be reversed in two interchangeable functions.
53
69template <typename T1, class C1, typename T2, class C2>
70bool images_compatible(const Image<T1, C1>& img1, const Image<T2, C2>& img2, bool compare_coordsys = true,
71 std::string* msg = nullptr) {
72 bool coordsys_equal = !compare_coordsys || (img1.get_coordsys() == img2.get_coordsys());
73 bool return_msg = msg != nullptr;
74 if (!return_msg && !coordsys_equal) return false;
75 bool cols_equal = img1.get_n_cols() == img2.get_n_cols();
76 bool rows_equal = img1.get_n_rows() == img2.get_n_rows();
77 bool passed = coordsys_equal && cols_equal && rows_equal;
78 if (!passed) {
79 if (return_msg) {
80 if (!coordsys_equal) {
81 *msg += img1.get_coordsys().str() + "!=" + img2.get_coordsys().str() + ",";
82 }
83 if (!cols_equal) {
84 *msg += std::to_string(img1.get_n_cols()) + "!=" + std::to_string(img2.get_n_cols()) + ",";
85 }
86 if (!rows_equal) {
87 *msg += std::to_string(img1.get_n_rows()) + "!=" + std::to_string(img2.get_n_rows());
88 }
89 }
90 return false;
91 }
92 return true;
93}
94
106template <typename T, class C>
107class Image : public Object {
108public:
109 // TODO: Figure out if there's any point to this in CRTP (or otherwise)
110 explicit Image(size_t n_rows, size_t n_cols, const T* value_init = _value_default_ptr(),
112 = delete;
113
114 // Convenience initializer for a coordsys (could be private method?)
116 : _coordsys_ptr(coordsys == nullptr ? nullptr : std::move(coordsys)),
117 _coordsys(_coordsys_ptr == nullptr ? COORDS_DEFAULT : *_coordsys_ptr) {}
118 ~Image() = default;
119
120 static constexpr T _value_default = 0;
121 static const T* _value_default_ptr() { return &_value_default; };
122
123 T& _get_value(size_t row, size_t col) { return static_cast<C&>(*this)._get_value_impl(row, col); }
124 T& _get_value_impl(size_t row, size_t col) {
126 return this->_get_value_unchecked(row, col);
127 }
128 inline T& _get_value_unchecked(size_t row, size_t col) {
129 return self()._get_value_unchecked_impl(row, col);
130 }
131 inline T& _get_value_unchecked_impl(size_t row, size_t col) = delete;
132
133 void _check_row_col(size_t row, size_t col) const { return self_const()._check_row_col_impl(row, col); }
134 void _check_row_col_impl(size_t row, size_t col) const {
135 if (!((row < this->get_n_rows()) && (col < this->get_n_cols()))) {
136 throw std::out_of_range("row,col = " + std::to_string(row) + "," + std::to_string(col)
137 + " n_rows,n_cols = " + std::to_string(this->get_n_rows()) + ","
138 + std::to_string(this->get_n_cols()));
139 }
140 }
141
142 const CoordinateSystem& get_coordsys() const { return _coordsys; };
144
145 size_t get_n_cols() const { return static_cast<const C&>(*this).get_n_cols_impl(); }
146 size_t get_n_cols_impl() const = delete;
147 size_t get_n_rows() const { return static_cast<const C&>(*this).get_n_rows_impl(); }
148 size_t get_n_rows_impl() = delete;
149
150 void add_value(size_t row, size_t col, T value) { self().add_value_impl(row, col, value); }
151 void add_value_impl(size_t row, size_t col, T value) { this->_get_value(row, col) += value; }
152 void add_value_unchecked(size_t row, size_t col, T value) {
153 self().add_value_unchecked_impl(row, col, value);
154 }
155 void add_value_unchecked_impl(size_t row, size_t col, T value) {
156 self()._get_value_unchecked(row, col) += value;
157 }
158 void fill(T value) { self().fill_impl(value); }
159 void fill_impl(T value) {
160 const size_t n_rows = get_n_rows();
161 const size_t n_cols = get_n_cols();
162 for (size_t row = 0; row < n_rows; ++row) {
163 for (size_t col = 0; col < n_cols; ++col) {
164 this->set_value_unchecked(row, col, value);
165 }
166 }
167 }
168 inline T get_value(size_t row, size_t col) const { return self_const().get_value_impl(row, col); }
169 inline T get_value_impl(size_t row, size_t col) const {
171 return self_const().get_value_unchecked(row, col);
172 }
173 inline T get_value_unchecked(size_t row, size_t col) const {
174 return self_const().get_value_unchecked_impl(row, col);
175 }
176 inline T get_value_unchecked_impl(size_t row, size_t col) const = delete;
177 inline void set_value(size_t row, size_t col, T value) { return self().set_value_impl(row, col, value); }
178 inline void set_value_impl(size_t row, size_t col, T value) { self()._get_value(row, col) = value; }
179 inline void set_value_unchecked(size_t row, size_t col, T value) {
180 self().set_value_unchecked_impl(row, col, value);
181 }
182 inline void set_value_unchecked_impl(size_t row, size_t col, T value) {
183 self()._get_value_unchecked(row, col) = value;
184 }
185
186 std::array<size_t, 2> shape() const { return {this->get_n_rows(), this->get_n_cols()}; }
187
188 size_t size() const { return this->get_n_rows() * this->get_n_cols(); };
189
190 std::string repr(bool name_keywords, std::string_view namespace_separator) const override {
191 return type_name_str<C>(false, namespace_separator) + "(" + (name_keywords ? "coordsys=" : "")
192 + _coordsys.repr(name_keywords, namespace_separator) + ", " + (name_keywords ? "n_rows=" : "")
193 + std::to_string(this->get_n_rows()) + ", " + (name_keywords ? "n_cols=" : "")
194 + std::to_string(this->get_n_cols()) + ")";
195 }
196
197 std::string str() const override {
198 return type_name_str<C>(true) + "(coordsys=" + _coordsys.str() + ", n_rows="
199 + std::to_string(this->get_n_rows()) + ", n_cols=" + std::to_string(this->get_n_cols()) + ")";
200 }
201
203 const size_t n_rows = get_n_rows();
204 const size_t n_cols = get_n_cols();
205 for (size_t row = 0; row < n_rows; ++row) {
206 for (size_t col = 0; col < n_cols; ++col) {
207 this->add_value_unchecked(row, col, value);
208 }
209 }
210 return *this;
211 }
212
214 const size_t n_rows = get_n_rows();
215 const size_t n_cols = get_n_cols();
216 for (size_t row = 0; row < n_rows; ++row) {
217 for (size_t col = 0; col < n_cols; ++col) {
218 // Avoid annoying warning for bool case
219 if constexpr (std::is_same_v<T, bool>) {
220 this->set_value_unchecked(row, col, value && this->get_value_unchecked(row, col));
221 } else {
222 this->set_value_unchecked(row, col, value * this->get_value_unchecked(row, col));
223 }
224 }
225 }
226 return *this;
227 }
228
229 // TODO: Implement if deemed worthwhile
230 // void operator+=(T value);
231
232 bool operator==(const Image& other) const {
233 if (images_compatible<T, C, T, C>(*this, other)) {
234 const size_t n_rows = get_n_rows();
235 const size_t n_cols = get_n_cols();
236 for (size_t row = 0; row < n_rows; ++row) {
237 for (size_t col = 0; col < n_cols; ++col) {
238 if (this->get_value_unchecked(row, col) != other.get_value_unchecked(row, col)) {
239 return false;
240 }
241 }
242 }
243 return true;
244 }
245 return false;
246 }
247
248 const bool operator!=(const Image& other) const { return !(*this == other); }
249
250private:
252 const std::shared_ptr<const CoordinateSystem> _coordsys_ptr;
253 const gauss2d::CoordinateSystem& _coordsys;
254
255 inline C& self() { return static_cast<C&>(*this); };
256 inline const C& self_const() const { return static_cast<const C&>(*this); };
257};
258
267template <typename T, class C>
268class ImageArray : public Object {
269public:
272
273 ImageT& operator[](size_t i) { return *(_images[i]); }
274 const ImageT& operator[](size_t i) const { return *(_images[i]); }
275
276 ImageT& at(size_t i = 0) const { return (*_images.at(i)); }
277
278 using iterator = typename Data::iterator;
279 using const_iterator = typename Data::const_iterator;
280
281 typename Data::iterator begin() noexcept { return _images.begin(); }
282 typename Data::iterator end() noexcept { return _images.end(); };
283
284 typename Data::const_iterator cbegin() const noexcept { return _images.cbegin(); };
285 typename Data::const_iterator cend() const noexcept { return _images.begin(); };
286
287 size_t size() const { return _images.size(); }
288
289 std::string repr(bool name_keywords, std::string_view namespace_separator) const override {
290 std::string str = type_name_str<ImageArray<T, C>>(false, namespace_separator) + "("
291 + (name_keywords ? "data=" : "")
292 + repr_iter_ptr(_images, name_keywords, namespace_separator) + ")";
293 return str;
294 }
295
296 std::string str() const override {
297 std::string str = type_name_str<ImageArray<T, C>>(true) + "(data=" + str_iter_ptr(_images) + ")";
298 return str;
299 }
300
301 explicit ImageArray(const Data* data_in) {
302 if (data_in != nullptr) {
303 const Data& data = *data_in;
304 size_t n_data = data.size();
305 if (n_data > 0) {
306 _images.resize(n_data);
307 for (size_t i = 0; i < n_data; ++i) {
308 if (data[i] == nullptr) {
309 throw std::invalid_argument("ImageArray data[" + std::to_string(i)
310 + "] can't be null");
311 }
312 if (!images_compatible<T, C, T, C>(*data[i], *data[0])) {
313 throw std::invalid_argument("ImageArray data[" + std::to_string(i)
314 + "] must be compatible with data[0] (and all others)");
315 }
316 _images[i] = data[i];
317 }
318 }
319 }
320 };
321
322private:
323 Data _images{};
324};
325
326} // namespace lsst::gauss2d
327#endif // LSST_GAUSS2D_IMAGE_H
char * data
Definition BaseRecord.cc:61
T at(T... args)
T begin(T... args)
A coordinate system specifying image scale and orientation.
std::string repr(bool name_keywords=false, std::string_view namespace_separator=Object::CC_NAMESPACE_SEPARATOR) const override
Return a full, callable string representation of this.
std::string str() const override
Return a brief, human-readable string representation of this.
A class that evaluates 2D Gaussians and renders them in images.
Definition evaluate.h:668
An array of compatible Images.
Definition image.h:268
typename Data::const_iterator const_iterator
Definition image.h:279
typename Data::iterator iterator
Definition image.h:278
std::string str() const override
Return a brief, human-readable string representation of this.
Definition image.h:296
Data::const_iterator cbegin() const noexcept
Definition image.h:284
std::string repr(bool name_keywords, std::string_view namespace_separator) const override
Return a full, callable string representation of this.
Definition image.h:289
ImageT & operator[](size_t i)
Definition image.h:273
Data::iterator begin() noexcept
Definition image.h:281
const ImageT & operator[](size_t i) const
Definition image.h:274
ImageT & at(size_t i=0) const
Definition image.h:276
Data::iterator end() noexcept
Definition image.h:282
size_t size() const
Definition image.h:287
ImageArray(const Data *data_in)
Definition image.h:301
Image< T, C > ImageT
Definition image.h:270
std::vector< std::shared_ptr< C > > Data
Definition image.h:271
Data::const_iterator cend() const noexcept
Definition image.h:285
A 2D image with scalar numeric values, using CRTP.
Definition image.h:107
void fill_impl(T value)
Definition image.h:159
bool operator==(const Image &other) const
Definition image.h:232
void set_value_impl(size_t row, size_t col, T value)
Definition image.h:178
void add_value_unchecked_impl(size_t row, size_t col, T value)
Definition image.h:155
size_t get_n_rows_impl()=delete
const CoordinateSystem & get_coordsys() const
Definition image.h:142
std::array< size_t, 2 > shape() const
Definition image.h:186
Image< T, C > & operator*=(T value)
Definition image.h:213
const bool operator!=(const Image &other) const
Definition image.h:248
std::string str() const override
Return a brief, human-readable string representation of this.
Definition image.h:197
Image< T, C > & operator+=(T value)
Definition image.h:202
void set_value(size_t row, size_t col, T value)
Definition image.h:177
void fill(T value)
Definition image.h:158
T & _get_value_impl(size_t row, size_t col)
Definition image.h:124
size_t size() const
Definition image.h:188
std::shared_ptr< const CoordinateSystem > get_coordsys_ptr_const() const
Definition image.h:143
T get_value_unchecked(size_t row, size_t col) const
Definition image.h:173
void set_value_unchecked_impl(size_t row, size_t col, T value)
Definition image.h:182
T get_value(size_t row, size_t col) const
Definition image.h:168
size_t get_n_rows() const
Definition image.h:147
void add_value_impl(size_t row, size_t col, T value)
Definition image.h:151
Image(std::shared_ptr< const CoordinateSystem > coordsys=nullptr)
Definition image.h:115
T get_value_unchecked_impl(size_t row, size_t col) const =delete
void add_value(size_t row, size_t col, T value)
Definition image.h:150
static constexpr T _value_default
Definition image.h:120
void _check_row_col_impl(size_t row, size_t col) const
Definition image.h:134
T & _get_value_unchecked_impl(size_t row, size_t col)=delete
Image(size_t n_rows, size_t n_cols, const T *value_init=_value_default_ptr(), std::shared_ptr< const CoordinateSystem > coordsys=nullptr)=delete
size_t get_n_cols_impl() const =delete
void add_value_unchecked(size_t row, size_t col, T value)
Definition image.h:152
size_t get_n_cols() const
Definition image.h:145
T get_value_impl(size_t row, size_t col) const
Definition image.h:169
std::string repr(bool name_keywords, std::string_view namespace_separator) const override
Return a full, callable string representation of this.
Definition image.h:190
static const T * _value_default_ptr()
Definition image.h:121
void set_value_unchecked(size_t row, size_t col, T value)
Definition image.h:179
void _check_row_col(size_t row, size_t col) const
Definition image.h:133
T & _get_value_unchecked(size_t row, size_t col)
Definition image.h:128
T & _get_value(size_t row, size_t col)
Definition image.h:123
A generic object from the gauss2d library.
Definition object.h:40
T end(T... args)
size_t idx_type
Definition image.h:43
std::string repr_iter_ptr(const T &container, bool name_keywords=false, std::string_view namespace_separator=Object::CC_NAMESPACE_SEPARATOR)
Definition object.h:88
bool images_compatible(const Image< T1, C1 > &img1, const Image< T2, C2 > &img2, bool compare_coordsys=true, std::string *msg=nullptr)
Return if two images are compatible.
Definition image.h:70
std::string str_iter_ptr(const T &container)
Definition object.h:137
STL namespace.
T resize(T... args)
T size(T... args)
int row
Definition CR.cc:145
int col
Definition CR.cc:144
T to_string(T... args)