SourceXtractorPlusPlus 0.19.2
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
DetectionImageConfig.cpp
Go to the documentation of this file.
1
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 DETECTION_IMAGE_GAIN { "detection-image-gain" };
44static const std::string DETECTION_IMAGE_FLUX_SCALE {"detection-image-flux-scale"};
45static const std::string DETECTION_IMAGE_SATURATION { "detection-image-saturation" };
46static const std::string DETECTION_IMAGE_INTERPOLATION { "detection-image-interpolation" };
47static const std::string DETECTION_IMAGE_INTERPOLATION_GAP { "detection-image-interpolation-gap" };
48
50{}
51
53 return { {"Detection image", {
54 {DETECTION_IMAGE.c_str(), po::value<std::string>(),
55 "Path to a fits format image to be used as detection image."},
56 {DETECTION_IMAGE_GAIN.c_str(), po::value<double>(),
57 "Detection image gain in e-/ADU (0 = infinite gain)"},
58 {DETECTION_IMAGE_FLUX_SCALE.c_str(), po::value<double>(),
59 "Detection image flux scale"},
60 {DETECTION_IMAGE_SATURATION.c_str(), po::value<double>(),
61 "Detection image saturation level (0 = no saturation)"},
62 {DETECTION_IMAGE_INTERPOLATION.c_str(), po::value<bool>()->default_value(true),
63 "Interpolate bad pixels in detection image"},
64 {DETECTION_IMAGE_INTERPOLATION_GAP.c_str(), po::value<int>()->default_value(5),
65 "Maximum number if pixels to interpolate over"}
66 }}};
67}
68
70 // Normally we would define this one as required, but then --list-output-properties would be
71 // unusable unless we also specify --detection-image, which is not very intuitive.
72 // For this reason, we check for its existence here
73 if (args.find(DETECTION_IMAGE) == args.end()) {
74 throw Elements::Exception() << "'--" << DETECTION_IMAGE << "' is required but missing";
75 }
76
78
79 boost::regex hdu_regex(".*\\[[0-9]*\\]$");
80
81 for (int i=0;; i++) {
83
84 std::shared_ptr<FitsImageSource> fits_image_source;
85 if (boost::regex_match(m_detection_image_path, hdu_regex)) {
86 if (i==0) {
87 fits_image_source = std::make_shared<FitsImageSource>(m_detection_image_path, 0, ImageTile::FloatImage);
88 } else {
89 break;
90 }
91 } else {
92 try {
93 fits_image_source = std::make_shared<FitsImageSource>(m_detection_image_path, i+1, ImageTile::FloatImage);
94 } catch (...) {
95 if (i==0) {
96 // Skip past primary HDU if it doesn't have an image
97 continue;
98 } else {
99 if (m_extensions.size() == 0) {
100 throw;
101 }
102 break;
103 }
104 }
105 }
106
107 extension.m_image_source = fits_image_source;
109 extension.m_coordinate_system = std::make_shared<WCS>(*fits_image_source);
110
111 double detection_image_gain = 0, detection_image_saturate = 0;
112 auto img_metadata = fits_image_source->getMetadata();
113
114 if (img_metadata.count("GAIN")){
115 // read the keyword GAIN from the metadata
116 if (double* double_gain = boost::get<double>(&img_metadata.at("GAIN").m_value)){
117 detection_image_gain = *double_gain;
118 } else if (int64_t *int64_gain = boost::get<int64_t>(&img_metadata.at("GAIN").m_value)){
119 detection_image_gain = (double) *int64_gain;
120 }
121 else {
122 throw Elements::Exception() << "Keyword GAIN must be either float or int!";
123 }
124 }
125
126 if (img_metadata.count("SATURATE")){
127 // read the keyword SATURATE from the metadata
128 if (double* double_saturate = boost::get<double>(&img_metadata.at("SATURATE").m_value)){
129 detection_image_saturate = *double_saturate;
130 } else if (int64_t *int64_saturate = boost::get<int64_t>(&img_metadata.at("SATURATE").m_value)){
131 detection_image_saturate = (double) *int64_saturate;
132 }
133 else {
134 throw Elements::Exception() << "Keyword SATURATE must be either float or int!";
135 }
136 }
137
138 if (args.find(DETECTION_IMAGE_FLUX_SCALE) != args.end()) {
139 extension.m_flux_scale = args.find(DETECTION_IMAGE_FLUX_SCALE)->second.as<double>();
140 }
141 else if (img_metadata.count("FLXSCALE")) {
142 // read the keyword FLXSCALE from the metadata
143 if (double* f_scale = boost::get<double>(&img_metadata.at("FLXSCALE").m_value)){
144 extension.m_flux_scale = *f_scale;
145 } else if (int64_t *int64_f_scale = boost::get<int64_t>(&img_metadata.at("FLXSCALE").m_value)){
146 extension.m_flux_scale = (double) *int64_f_scale;
147 }
148 else {
149 throw Elements::Exception() << "Keyword FLXSCALE must be either float or int!";
150 }
151 }
152
153 if (args.find(DETECTION_IMAGE_GAIN) != args.end()) {
154 extension.m_gain = args.find(DETECTION_IMAGE_GAIN)->second.as<double>();
155 }
156 else {
157 extension.m_gain = detection_image_gain;
158 }
159
160 if (args.find(DETECTION_IMAGE_SATURATION) != args.end()) {
161 extension.m_saturation = args.find(DETECTION_IMAGE_SATURATION)->second.as<double>();
162 }
163 else {
164 extension.m_saturation = detection_image_saturate;
165 }
166
167 extension.m_interpolation_gap = args.find(DETECTION_IMAGE_INTERPOLATION)->second.as<bool>() ?
168 std::max(0, args.find(DETECTION_IMAGE_INTERPOLATION_GAP)->second.as<int>()) : 0;
169
170 // Adapt image and parameters to take flux_scale into consideration
171 if (extension.m_flux_scale != 1.0) {
172 extension.m_detection_image =
174 extension.m_gain /= extension.m_flux_scale;
175 extension.m_saturation *= extension.m_flux_scale;
176 }
177
178 m_extensions.emplace_back(std::move(extension));
179 }
180}
181
184}
185
187 if (getCurrentState() < State::INITIALIZED) {
188 throw Elements::Exception() << "getDetectionImage() call on not initialized DetectionImageConfig";
189 }
190 return m_extensions.at(index).m_detection_image;
191}
192
194 if (getCurrentState() < State::INITIALIZED) {
195 throw Elements::Exception() << "getCoordinateSystem() call on not initialized DetectionImageConfig";
196 }
197 return m_extensions.at(index).m_coordinate_system;
198}
199
200} // SourceXtractor namespace
201
202
203
T c_str(T... args)
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, P > > 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 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 DETECTION_IMAGE_INTERPOLATION
static const std::string DETECTION_IMAGE_FLUX_SCALE
static const std::string DETECTION_IMAGE
static const std::string DETECTION_IMAGE_SATURATION