SourceXtractorPlusPlus 1.0.3
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
DetectionImageConfig.cpp
Go to the documentation of this file.
1
22#include "Configuration/ConfigManager.h"
23
24#include <boost/regex.hpp>
25using boost::regex;
26using boost::regex_match;
27using boost::smatch;
28
32
34
36
37using namespace Euclid::Configuration;
38namespace po = boost::program_options;
39
40namespace SourceXtractor {
41
42static const std::string DETECTION_IMAGE { "detection-image" };
43static const std::string REFERENCE_IMAGE { "reference-image" };
44static const std::string DETECTION_IMAGE_GAIN { "detection-image-gain" };
45static const std::string DETECTION_IMAGE_FLUX_SCALE {"detection-image-flux-scale"};
46static const std::string DETECTION_IMAGE_SATURATION { "detection-image-saturation" };
47static const std::string DETECTION_IMAGE_INTERPOLATION { "detection-image-interpolation" };
48static const std::string DETECTION_IMAGE_INTERPOLATION_GAP { "detection-image-interpolation-gap" };
49
52
54 return { {"Detection image", {
55 {DETECTION_IMAGE.c_str(), po::value<std::string>(),
56 "Path to a fits format image to be used as detection image."},
57 {REFERENCE_IMAGE.c_str(), po::value<std::string>(),
58 "Path to a fits format image to be used as coordinates reference only."},
59 {DETECTION_IMAGE_GAIN.c_str(), po::value<double>(),
60 "Detection image gain in e-/ADU (0 = infinite gain)"},
61 {DETECTION_IMAGE_FLUX_SCALE.c_str(), po::value<double>(),
62 "Detection image flux scale"},
63 {DETECTION_IMAGE_SATURATION.c_str(), po::value<double>(),
64 "Detection image saturation level (0 = no saturation)"},
65 {DETECTION_IMAGE_INTERPOLATION.c_str(), po::value<bool>()->default_value(true),
66 "Interpolate bad pixels in detection image"},
67 {DETECTION_IMAGE_INTERPOLATION_GAP.c_str(), po::value<int>()->default_value(5),
68 "Maximum number if pixels to interpolate over"}
69 }}};
70}
71
73
74 if (args.find(DETECTION_IMAGE) == args.end()) {
75 // Running without a detection image
76
77 // Check if a reference image is provided
78 if (args.find(REFERENCE_IMAGE) != args.end()) {
80
81 auto reference_image_source = std::make_shared<FitsImageSource>(
83 extension.m_coordinate_system = std::make_shared<WCS>(*reference_image_source);
84 m_extensions.emplace_back(std::move(extension));
85
87 }
88
89 return;
90 }
91
92 if (args.find(REFERENCE_IMAGE) != args.end()) {
93 throw Elements::Exception() << "Either detection or reference image can be provided, not both";
94 }
95
97
98 boost::regex hdu_regex(".*\\[[0-9]*\\]$");
99
100 for (int i=0;; i++) {
101 DetectionImageExtension extension;
102
103 std::shared_ptr<FitsImageSource> fits_image_source;
104 if (boost::regex_match(m_detection_image_path, hdu_regex)) {
105 if (i==0) {
107 } else {
108 break;
109 }
110 } else {
111 try {
113 } catch (...) {
114 if (i==0) {
115 // Skip past primary HDU if it doesn't have an image
116 continue;
117 } else {
118 if (m_extensions.size() == 0) {
119 throw;
120 }
121 break;
122 }
123 }
124 }
125
126 extension.m_image_source = fits_image_source;
128 extension.m_coordinate_system = std::make_shared<WCS>(*fits_image_source);
129
130 double detection_image_gain = 0, detection_image_saturate = 0;
131 auto img_metadata = fits_image_source->getMetadata();
132
133 if (img_metadata.count("GAIN")){
134 // read the keyword GAIN from the metadata
135 if (double* double_gain = boost::get<double>(&img_metadata.at("GAIN").m_value)){
136 detection_image_gain = *double_gain;
137 } else if (int64_t *int64_gain = boost::get<int64_t>(&img_metadata.at("GAIN").m_value)){
138 detection_image_gain = (double) *int64_gain;
139 }
140 else {
141 throw Elements::Exception() << "Keyword GAIN must be either float or int!";
142 }
143 }
144
145 if (img_metadata.count("SATURATE")){
146 // read the keyword SATURATE from the metadata
147 if (double* double_saturate = boost::get<double>(&img_metadata.at("SATURATE").m_value)){
148 detection_image_saturate = *double_saturate;
149 } else if (int64_t *int64_saturate = boost::get<int64_t>(&img_metadata.at("SATURATE").m_value)){
150 detection_image_saturate = (double) *int64_saturate;
151 }
152 else {
153 throw Elements::Exception() << "Keyword SATURATE must be either float or int!";
154 }
155 }
156
157 if (args.find(DETECTION_IMAGE_FLUX_SCALE) != args.end()) {
158 extension.m_flux_scale = args.find(DETECTION_IMAGE_FLUX_SCALE)->second.as<double>();
159 }
160 else if (img_metadata.count("FLXSCALE")) {
161 // read the keyword FLXSCALE from the metadata
162 if (double* f_scale = boost::get<double>(&img_metadata.at("FLXSCALE").m_value)){
163 extension.m_flux_scale = *f_scale;
164 } else if (int64_t *int64_f_scale = boost::get<int64_t>(&img_metadata.at("FLXSCALE").m_value)){
165 extension.m_flux_scale = (double) *int64_f_scale;
166 }
167 else {
168 throw Elements::Exception() << "Keyword FLXSCALE must be either float or int!";
169 }
170 }
171
172 if (args.find(DETECTION_IMAGE_GAIN) != args.end()) {
173 extension.m_gain = args.find(DETECTION_IMAGE_GAIN)->second.as<double>();
174 }
175 else {
176 extension.m_gain = detection_image_gain;
177 }
178
179 if (args.find(DETECTION_IMAGE_SATURATION) != args.end()) {
180 extension.m_saturation = args.find(DETECTION_IMAGE_SATURATION)->second.as<double>();
181 }
182 else {
183 extension.m_saturation = detection_image_saturate;
184 }
185
186 extension.m_interpolation_gap = args.find(DETECTION_IMAGE_INTERPOLATION)->second.as<bool>() ?
187 std::max(0, args.find(DETECTION_IMAGE_INTERPOLATION_GAP)->second.as<int>()) : 0;
188
189 // Adapt image and parameters to take flux_scale into consideration
190 if (extension.m_flux_scale != 1.0) {
191 extension.m_detection_image =
193 extension.m_gain /= extension.m_flux_scale;
194 extension.m_saturation *= extension.m_flux_scale;
195 }
196
197 m_extensions.emplace_back(std::move(extension));
198 }
199}
200
204
206 if (getCurrentState() < State::INITIALIZED) {
207 throw Elements::Exception() << "getDetectionImage() call on not initialized DetectionImageConfig";
208 }
210 throw Elements::Exception() << "Trying to access detection image but only a reference image was provided";
211 }
212 return m_extensions.at(index).m_detection_image;
213}
214
216 if (getCurrentState() < State::INITIALIZED) {
217 throw Elements::Exception() << "getCoordinateSystem() call on not initialized DetectionImageConfig";
218 }
219 return m_extensions.at(index).m_coordinate_system;
220}
221
222} // SourceXtractor namespace
223
224
225
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())
std::shared_ptr< DetectionImage > getDetectionImage(size_t index=0) const
std::shared_ptr< CoordinateSystem > getCoordinateSystem(size_t index=0) const
void initialize(const UserValues &args) override
std::vector< DetectionImageExtension > m_extensions
DetectionImageConfig(long manager_id)
Constructs a new DetectionImageConfig object.
std::map< std::string, Configuration::OptionDescriptionList > getProgramOptions() override
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)
T end(T... args)
T find(T... args)
T make_shared(T... args)
T max(T... args)
T move(T... args)
static const std::string DETECTION_IMAGE_GAIN
static const std::string DETECTION_IMAGE_INTERPOLATION_GAP
static const std::string REFERENCE_IMAGE
static const std::string DETECTION_IMAGE_INTERPOLATION
static const std::string DETECTION_IMAGE_FLUX_SCALE
static const std::string DETECTION_IMAGE
static const std::string DETECTION_IMAGE_SATURATION