SourceXtractorPlusPlus 1.0.3
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
WeightImageConfig.cpp
Go to the documentation of this file.
1
17/*
18 * WeightImageConfig.cpp
19 *
20 * Created on: Oct 7, 2016
21 * Author: mschefer
22 */
23
24#include <limits>
25#include <boost/algorithm/string.hpp>
26#include <boost/regex.hpp>
27using boost::regex;
28using boost::regex_match;
29using boost::smatch;
30
31#include "Configuration/ConfigManager.h"
32
38
40
42
43using namespace Euclid::Configuration;
44namespace po = boost::program_options;
45
46namespace SourceXtractor {
47
48static const std::string WEIGHT_IMAGE {"weight-image" };
49static const std::string WEIGHT_TYPE {"weight-type" };
50static const std::string WEIGHT_ABSOLUTE {"weight-absolute" };
51static const std::string WEIGHT_SCALING {"weight-scaling" };
52static const std::string WEIGHT_THRESHOLD {"weight-threshold" };
53static const std::string WEIGHT_SYMMETRYUSAGE {"weight-use-symmetry" };
54
56 Configuration(manager_id),
57 m_weight_type(WeightType::WEIGHT_TYPE_FROM_BACKGROUND),
58 m_absolute_weight(false),
61 m_symmetry_usage(true) {
62
64}
65
67 return { {"Weight image", {
68 {WEIGHT_IMAGE.c_str(), po::value<std::string>()->default_value(""),
69 "Path to a fits format image to be used as weight image."},
70 {WEIGHT_ABSOLUTE.c_str(), po::value<bool>()->default_value(false),
71 "Is the weight map provided as absolute values or relative to background."},
72 {WEIGHT_TYPE.c_str(), po::value<std::string>()->default_value("none"),
73 "Weight image type [none|background|rms|variance|weight]."},
74 {WEIGHT_SCALING.c_str(), po::value<double>()->default_value(1.0),
75 "Weight map scaling factor."},
76 {WEIGHT_THRESHOLD.c_str(), po::value<double>(),
77 "Threshold for pixels to be considered bad pixels. In same units as weight map."},
78 {WEIGHT_SYMMETRYUSAGE.c_str(), po::value<bool>()->default_value(true),
79 "Use object symmetry to replace pixels above the weight threshold for photometry."},
80 }}};
81}
82
84 using WeightType = WeightImageConfig::WeightType;
85
86 switch (weight_type) {
87 default:
88 case WeightType::WEIGHT_TYPE_FROM_BACKGROUND:
89 case WeightType::WEIGHT_TYPE_RMS:
90 return threshold * threshold;
91 case WeightType::WEIGHT_TYPE_VARIANCE:
92 return threshold;
93 case WeightType::WEIGHT_TYPE_WEIGHT:
94 if (threshold > 0) {
95 return 1.0 / threshold;
96 } else {
98 }
99 }
100}
101
103 static const std::map<std::string, WeightType> WEIGHT_MAP{
109 };
110
111 m_absolute_weight = args.find(WEIGHT_ABSOLUTE)->second.as<bool>();
112 m_symmetry_usage = args.find(WEIGHT_SYMMETRYUSAGE)->second.as<bool>();
113
114 auto weight_image_filename = args.find(WEIGHT_IMAGE)->second.as<std::string>();
115
116 auto weight_type_name = boost::to_upper_copy(args.at(WEIGHT_TYPE).as<std::string>());
117 auto weight_iter = WEIGHT_MAP.find(weight_type_name);
118 if (weight_iter == WEIGHT_MAP.end()) {
119 throw Elements::Exception() << "Unknown weight map type : " << weight_type_name;
120 }
121 m_weight_type = weight_iter->second;
122 m_weight_scaling = args.find(WEIGHT_SCALING)->second.as<double>();
123
124 if (args.count(WEIGHT_THRESHOLD) != 0) {
125 auto threshold = args.find(WEIGHT_THRESHOLD)->second.as<double>();
127 } else {
129 }
130
131 // some safeguards that the user provides reasonable input and gets defined results
132 if (weight_image_filename != "" && m_weight_type == WeightType::WEIGHT_TYPE_FROM_BACKGROUND)
133 throw Elements::Exception() << "Please give an appropriate weight type for image: " << weight_image_filename;
134 if (weight_image_filename != "" && m_weight_type == WeightType::WEIGHT_TYPE_NONE)
135 throw Elements::Exception() << "Please give an appropriate weight type for image: " << weight_image_filename;
136 if (m_absolute_weight && weight_image_filename == "")
137 throw Elements::Exception() << "Setting absolute weight but providing *no* weight image does not make sense.";
138
139 if (weight_image_filename != "") {
140 boost::regex hdu_regex(".*\\[[0-9]*\\]$");
141
142 for (int i=0;; i++) {
143 std::shared_ptr<FitsImageSource> fits_image_source;
144 if (boost::regex_match(weight_image_filename, hdu_regex)) {
145 if (i==0) {
146 fits_image_source = std::make_shared<FitsImageSource>(weight_image_filename, 0, ImageTile::FloatImage);
147 } else {
148 break;
149 }
150 } else {
151 try {
152 fits_image_source = std::make_shared<FitsImageSource>(weight_image_filename, i+1, ImageTile::FloatImage);
153 } catch (...) {
154 if (i==0) {
155 // Skip past primary HDU if it doesn't have an image
156 continue;
157 } else {
158 if (m_weight_images.size() == 0) {
159 throw;
160 }
161 break;
162 }
163 }
164 }
165
167 weight_image = convertWeightMap(weight_image, m_weight_type, m_weight_scaling);
168
169 // we should have a corresponding detection image
170 auto flux_scale = getDependency<DetectionImageConfig>().getOriginalFluxScale(m_weight_images.size());
171
172 WeightImage::PixelType scaled_weight_threshold = m_weight_threshold;
173 if (flux_scale != 1. && m_absolute_weight) {
174 weight_image = MultiplyImage<WeightImage::PixelType>::create(weight_image, flux_scale * flux_scale);
175 if (scaled_weight_threshold < std::numeric_limits<WeightImage::PixelType>::max()){
176 // adjust the weight threshold
177 scaled_weight_threshold *= flux_scale * flux_scale;
178 }
179 }
180
181 m_weight_images.emplace_back(weight_image);
182 m_scaled_weight_thresholds.emplace_back(scaled_weight_threshold);
183 }
184 }
185}
186
187class WeightMapImageSource : public ProcessingImageSource<WeightImage::PixelType> {
188public:
192
193protected:
194
195 std::string getRepr() const override {
196 return "WeightMapImageSource(" + getImageRepr() + ")";
197 }
198
200 ImageTileWithType<WeightImage::PixelType>& tile, int x, int y, int width, int height) const final {
201 auto image_chunk = image->getChunk(x, y, width, height);
202 switch (m_weight_type) {
204 generateFromRms(tile, width, height, *image_chunk);
205 break;
207 generateFromVariance(tile, width, height, *image_chunk);
208 break;
210 generateFromWeight(tile, width, height, *image_chunk);
211 break;
212 default:
214 assert(false);
215 break;
216 }
217 }
218
220 const ImageChunk<WeightImage::PixelType>& image_chunk) const {
221 auto& tile_image = *tile.getImage();
222 for (int iy = 0; iy < height; iy++) {
223 for (int ix = 0; ix < width; ix++) {
224 auto value = image_chunk.getValue(ix, iy) * m_scaling;
225 if (value > 0) {
226 tile_image.setValue(ix, iy, 1.0 / value);
227 }
228 else {
229 tile_image.setValue(ix, iy, std::numeric_limits<WeightImage::PixelType>::infinity());
230 }
231 }
232 }
233 }
234
236 const ImageChunk<WeightImage::PixelType>& image_chunk) const {
237 auto& tile_image = *tile.getImage();
238 for (int iy = 0; iy < height; iy++) {
239 for (int ix = 0; ix < width; ix++) {
240 auto value = image_chunk.getValue(ix, iy) * m_scaling;
241 tile_image.setValue(ix, iy, value);
242 }
243 }
244 }
245
247 const ImageChunk<WeightImage::PixelType>& image_chunk) const {
248 auto& tile_image = *tile.getImage();
249 for (int iy = 0; iy < height; iy++) {
250 for (int ix = 0; ix < width; ix++) {
251 auto value = image_chunk.getValue(ix, iy) * m_scaling;
252 tile_image.setValue(ix, iy, value * value);
253 }
254 }
255 }
256
257private:
260};
261
262
265 WeightImage::PixelType scaling) {
266
267 if (weight_type == WeightType::WEIGHT_TYPE_FROM_BACKGROUND) {
268 return nullptr;
269 }
270 else if (weight_type == WeightType::WEIGHT_TYPE_NONE) {
271 return nullptr;
272 }
273 else {
275 std::make_shared<WeightMapImageSource>(weight_image, weight_type, scaling));
276 return result_image;
277 }
278}
279
280}
281
T at(T... args)
std::map< std::string, boost::program_options::variable_value > UserValues
static std::shared_ptr< BufferedImage< T > > create(std::shared_ptr< const ImageSource > source, std::shared_ptr< TileManager > tile_manager=TileManager::getInstance())
T getValue(int x, int y) const
Returns the value of the pixel with the coordinates (x,y).
Definition ImageChunk.h:58
const std::shared_ptr< VectorImage< T > > & getImage() const
Definition ImageTile.h:178
Interface representing an image.
Definition Image.h:44
static std::shared_ptr< ProcessedImage< T, MultiplyOperation< T > > > create(std::shared_ptr< const Image< T > > image_a, std::shared_ptr< const Image< T > > image_b)
ProcessingImageSource(std::shared_ptr< Image< WeightImage::PixelType > > image)
static std::shared_ptr< WeightImage > convertWeightMap(std::shared_ptr< WeightImage > weight_image, WeightType weight_type, WeightImage::PixelType scaling=1)
WeightImage::PixelType m_weight_threshold
WeightImage::PixelType m_weight_scaling
void initialize(const UserValues &args) override
std::vector< std::shared_ptr< WeightImage > > m_weight_images
std::vector< WeightImage::PixelType > m_scaled_weight_thresholds
std::map< std::string, Configuration::OptionDescriptionList > getProgramOptions() override
void generateFromWeight(ImageTileWithType< WeightImage::PixelType > &tile, int width, int height, const ImageChunk< WeightImage::PixelType > &image_chunk) const
WeightMapImageSource(std::shared_ptr< Image< WeightImage::PixelType > > image, WeightImageConfig::WeightType weight_type, WeightImage::PixelType scaling)
void generateFromRms(ImageTileWithType< WeightImage::PixelType > &tile, int width, int height, const ImageChunk< WeightImage::PixelType > &image_chunk) const
void generateFromVariance(ImageTileWithType< WeightImage::PixelType > &tile, int width, int height, const ImageChunk< WeightImage::PixelType > &image_chunk) const
void generateTile(const std::shared_ptr< Image< WeightImage::PixelType > > &image, ImageTileWithType< WeightImage::PixelType > &tile, int x, int y, int width, int height) const final
WeightImageConfig::WeightType m_weight_type
std::string getRepr() const override
Human readable representation of this source.
T count(T... args)
T end(T... args)
T find(T... args)
T infinity(T... args)
T make_shared(T... args)
T max(T... args)
static const std::string WEIGHT_IMAGE
static const std::string WEIGHT_TYPE
static WeightImage::PixelType computeWeightThreshold(WeightImageConfig::WeightType weight_type, double threshold)
static const std::string WEIGHT_ABSOLUTE
static const std::string WEIGHT_SCALING
Image< SeFloat > DetectionImage
Alias for the detection image, to make easier its type modification.
Definition Image.h:80
static const std::string WEIGHT_SYMMETRYUSAGE
static const std::string WEIGHT_THRESHOLD