Skip to content

Commit 715e3b1

Browse files
authored
Allow disabling PSF renormalization in model fitting (#597)
* psf renormalization on/off option WIP * DownSampledImagePsf renormalization * propagate renormalization configuration from MeasurementImage * remove unsued include, fix warnings in MoffatModelFitting * propagate config for and fix DownsampledPsf
1 parent 12bf768 commit 715e3b1

File tree

18 files changed

+101
-48
lines changed

18 files changed

+101
-48
lines changed

SEImplementation/SEImplementation/Configuration/MeasurementImageConfig.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ class MeasurementImageConfig : public Euclid::Configuration::Configuration {
6565
bool m_is_data_cube;
6666
int m_image_layer;
6767
int m_weight_layer;
68+
69+
bool m_psf_renormalize;
6870
};
6971

7072
explicit MeasurementImageConfig(long manager_id);

SEImplementation/SEImplementation/Image/DownSampledImagePsf.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ namespace SourceXtractor {
4141
class DownSampledImagePsf {
4242
public:
4343

44-
DownSampledImagePsf(double pixel_scale, std::shared_ptr<VectorImage<SeFloat>> image, double down_scaling=1.0);
44+
DownSampledImagePsf(double pixel_scale, std::shared_ptr<VectorImage<SeFloat>> image,
45+
double down_scaling=1.0, bool normalize_psf = true);
4546

4647
virtual ~DownSampledImagePsf() = default;
4748

4849
double getPixelScale() const;
50+
4951
std::size_t getSize() const;
5052
std::shared_ptr<VectorImage<SourceXtractor::SeFloat>> getScaledKernel(SeFloat scale) const;
5153
void convolve(std::shared_ptr<WriteableImage<float>> image) const;
@@ -57,6 +59,7 @@ class DownSampledImagePsf {
5759
private:
5860
double m_down_scaling;
5961
std::shared_ptr<ImagePsf> m_psf;
62+
bool m_normalize_psf { true };
6063
};
6164

6265
} // end of SourceXtractor

SEImplementation/SEImplementation/Plugin/FlexibleModelFitting/FlexibleModelFittingIterativeTask.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "SEImplementation/Plugin/FlexibleModelFitting/FlexibleModelFittingFrame.h"
3333
#include "SEImplementation/Plugin/FlexibleModelFitting/FlexibleModelFittingPrior.h"
3434

35+
#include "SEImplementation/Image/DownSampledImagePsf.h"
36+
3537
namespace SourceXtractor {
3638

3739
class FlexibleModelFittingIterativeTask : public GroupTask {
@@ -54,6 +56,7 @@ class FlexibleModelFittingIterativeTask : public GroupTask {
5456
std::vector<std::shared_ptr<FlexibleModelFittingParameter>> parameters,
5557
std::vector<std::shared_ptr<FlexibleModelFittingFrame>> frames,
5658
std::vector<std::shared_ptr<FlexibleModelFittingPrior>> priors,
59+
std::vector<bool> should_renormalize,
5760
double scale_factor=1.0,
5861
int meta_iterations=3,
5962
double deblend_factor=1.0,
@@ -129,6 +132,11 @@ class FlexibleModelFittingIterativeTask : public GroupTask {
129132
PixelRectangle clipFittingRect(PixelRectangle fitting_rect, SourceInterface& source, int frame_index) const;
130133
PixelRectangle getUnclippedFittingRect(SourceInterface& source, int frame_index) const;
131134

135+
ModelFitting::FrameModel<DownSampledImagePsf, std::shared_ptr<VectorImage<SourceXtractor::SeFloat>>> createFrameModel(
136+
SourceInterface& source, double pixel_scale, FlexibleModelFittingParameterManager& manager,
137+
std::shared_ptr<FlexibleModelFittingFrame> frame, PixelRectangle stamp_rect, double down_scaling=1.0) const;
138+
139+
132140
// Task configuration
133141
std::string m_least_squares_engine;
134142
unsigned int m_max_iterations;
@@ -143,6 +151,7 @@ class FlexibleModelFittingIterativeTask : public GroupTask {
143151
std::vector<std::shared_ptr<FlexibleModelFittingFrame>> m_frames;
144152
std::vector<std::shared_ptr<FlexibleModelFittingPrior>> m_priors;
145153

154+
std::vector<bool> m_should_renormalize;
146155
WindowType m_window_type { WindowType::RECTANGLE };
147156
double m_ellipse_scale = 3.0;
148157
};

SEImplementation/SEImplementation/Plugin/FlexibleModelFitting/FlexibleModelFittingTaskFactory.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class FlexibleModelFittingTaskFactory : public TaskFactory {
6262

6363
double m_scale_factor {1.0};
6464
double m_max_fit_size {100};
65+
66+
// should we renormalize the PSF for each frame?
67+
std::vector<bool> m_should_renormalize;
6568
};
6669

6770
}

SEImplementation/SEImplementation/Plugin/SourcePsf/SourcePsfTask.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ class SourcePsfTask: public SourceTask {
2727
public:
2828
virtual ~SourcePsfTask() = default;
2929

30-
SourcePsfTask(unsigned instance, const std::shared_ptr<Psf> &vpsf);
30+
SourcePsfTask(unsigned instance, const std::shared_ptr<Psf>& vpsf, bool normalize_psf = true)
31+
: m_instance(instance), m_vpsf(vpsf), m_normalize_psf(normalize_psf) {
32+
}
3133

3234
void computeProperties(SourceInterface& source) const override;
3335

@@ -37,6 +39,7 @@ class SourcePsfTask: public SourceTask {
3739
private:
3840
unsigned m_instance;
3941
std::shared_ptr<Psf> m_vpsf;
42+
bool m_normalize_psf { true };
4043
};
4144

4245
} // end SourceXtractor

SEImplementation/SEImplementation/Plugin/SourcePsf/SourcePsfTaskFactory.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ class SourcePsfTaskFactory: public TaskFactory {
3737
std::shared_ptr<Task> createTask(const PropertyId& property_id) const override;
3838

3939
private:
40-
std::map<int, std::shared_ptr<Psf>> m_vpsf;
40+
41+
struct PsfInfo {
42+
std::shared_ptr<Psf> m_psf;
43+
bool m_normalize_psf;
44+
};
45+
46+
std::map<int, PsfInfo> m_psf_infos;
4147
};
4248

4349
} // end SourceXtractor

SEImplementation/SEImplementation/PythonConfig/PyMeasurementImage.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class PyMeasurementImage : public PyId {
5454
bool is_data_cube;
5555
int image_layer;
5656
int weight_layer;
57+
58+
bool psf_renormalize;
5759
};
5860

5961
}

SEImplementation/python/sourcextractor/config/measurement_images.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class MeasurementImage(cpp.MeasurementImage):
107107
For multi-extension FITS file specifies the HDU number for the psf. Defaults to the same value as image_hdu
108108
weight_hdu : int
109109
For multi-extension FITS file specifies the HDU number for the weight. Defaults to the same value as image_hdu
110+
psf_renormalize : bool
111+
If True, the PSF will be renormalized to have a total flux of 1.0. Default True
110112
"""
111113

112114
def _set_checked(self, attr_name, value):
@@ -122,7 +124,7 @@ def __init__(self, fits_file, psf_file=None, weight_file=None, gain=None,
122124
flux_scale=None, flux_scale_keyword='FLXSCALE',
123125
weight_type='none', weight_absolute=False, weight_scaling=1.,
124126
weight_threshold=None, constant_background=None,
125-
image_hdu=0, psf_hdu=None, weight_hdu=None
127+
image_hdu=0, psf_hdu=None, weight_hdu=None, psf_renormalize=True
126128
):
127129
"""
128130
Constructor.
@@ -201,6 +203,8 @@ def __init__(self, fits_file, psf_file=None, weight_file=None, gain=None,
201203
self._set_checked('weight_hdu', image_hdu)
202204
else:
203205
self._set_checked('weight_hdu', weight_hdu)
206+
207+
self.psf_renormalize = psf_renormalize
204208

205209
def __str__(self):
206210
"""

SEImplementation/src/lib/Configuration/MeasurementImageConfig.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ void MeasurementImageConfig::initialize(const UserValues&) {
220220
info.m_psf_hdu = py_image.psf_hdu + 1;
221221
info.m_weight_hdu = py_image.weight_hdu + 1;
222222

223+
info.m_psf_renormalize = py_image.psf_renormalize;
224+
223225
m_image_infos.emplace_back(std::move(info));
224226
}
225227
} else {
@@ -252,10 +254,14 @@ void MeasurementImageConfig::initialize(const UserValues&) {
252254

253255
0, // id
254256

255-
1,1,1 // HDUs
256-
});
257+
1,1,1, // HDUs
257258

259+
false, // is_data_cube
260+
0, // image_layer
261+
0, // weight_layer
258262

263+
true // psf_renormalize
264+
});
259265
}
260266
}
261267

SEImplementation/src/lib/Image/DownSampledImagePsf.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
namespace SourceXtractor {
3131

3232
DownSampledImagePsf::DownSampledImagePsf(
33-
double pixel_scale, std::shared_ptr<VectorImage<SeFloat>> image, double down_scaling)
34-
: m_down_scaling(down_scaling) {
33+
double pixel_scale, std::shared_ptr<VectorImage<SeFloat>> image, double down_scaling, bool normalize_psf)
34+
: m_down_scaling(down_scaling), m_normalize_psf(normalize_psf) {
3535
if (image != nullptr) {
3636
using Traits = ::ModelFitting::ImageTraits<std::shared_ptr<VectorImage<SeFloat>>>;
3737

@@ -52,9 +52,18 @@ DownSampledImagePsf::DownSampledImagePsf(
5252
Traits::addImageToImage(new_image, image, down_scaling, new_size / 2.0, new_size / 2.0);
5353

5454
// renormalize psf
55-
auto psf_sum = std::accumulate(new_image->getData().begin(), new_image->getData().end(), 0.);
56-
for (auto& pixel : new_image->getData()) {
57-
pixel /= psf_sum;
55+
if (m_normalize_psf) {
56+
auto psf_sum = std::accumulate(new_image->getData().begin(), new_image->getData().end(), 0.);
57+
for (auto& pixel : new_image->getData()) {
58+
pixel /= psf_sum;
59+
}
60+
} else {
61+
auto original_psf_sum = std::accumulate(image->getData().begin(), image->getData().end(), 0.);
62+
auto new_psf_sum = std::accumulate(new_image->getData().begin(), new_image->getData().end(), 0.);
63+
64+
for (auto& pixel : new_image->getData()) {
65+
pixel *= original_psf_sum / new_psf_sum;
66+
}
5867
}
5968

6069
m_psf = std::make_shared<ImagePsf>(pixel_scale / down_scaling, new_image);

0 commit comments

Comments
 (0)