SourceXtractorPlusPlus  0.10
Please provide a description of the project.
VariablePsf.cpp
Go to the documentation of this file.
1 
17 /*
18  * VariablePsf.cpp
19  *
20  * Created on: Jun 25, 2018
21  * Author: Alejandro Álvarez Ayllón
22  */
23 
25 #include <algorithm>
27 
28 
29 namespace SourceXtractor {
30 
31 VariablePsf::VariablePsf(double pixel_sampling, const std::vector<Component> &components,
32  const std::vector<int> &group_degrees,
33  const std::vector<std::shared_ptr<VectorImage<SeFloat>>> &coefficients):
34  m_pixel_sampling(pixel_sampling), m_components(components), m_group_degrees(group_degrees), m_coefficients(coefficients)
35 {
36  selfTest();
38 }
39 
40 VariablePsf::VariablePsf(double pixel_sampling, const std::shared_ptr<VectorImage<SeFloat>> &constant):
41  m_pixel_sampling(pixel_sampling), m_coefficients{constant}
42 {
43  selfTest();
44  calculateExponents();
45 }
46 
47 int VariablePsf::getWidth() const {
48  return m_coefficients[0]->getWidth();
49 }
50 
52  return m_coefficients[0]->getHeight();
53 }
54 
56  return m_pixel_sampling;
57 }
58 
60  return m_components;
61 }
62 
64 {
65  // If we only have the constant, avoid a copy
66  if (m_coefficients.size() == 1) {
67  return m_coefficients[0];
68  }
69 
70  auto scaled_props = scaleProperties(values);
71 
72  // Initialize with the constant component
74 
75  // Add the rest of the components
76  for (auto i = 1u; i < m_coefficients.size(); ++i) {
77  const auto& exp = m_exponents[i];
78  const auto& coef = m_coefficients[i];
79 
80  double acc = 1.;
81  for (auto j = 0u; j < scaled_props.size(); ++j) {
82  acc *= std::pow(scaled_props[j], exp[j]);
83  }
84 
85  for (auto x = 0; x < getWidth(); ++x) {
86  for (auto y = 0; y < getHeight(); ++y) {
87  result->at(x, y) += acc * coef->at(x, y);
88  }
89  }
90  }
91 
92  return result;
93 }
94 
96  // Pre-condition: There is at least a constant component
97  if (m_coefficients.size() == 0) {
98  throw Elements::Exception() << "A variable PSF needs at least one set of coefficients";
99  }
100 
101  // Pre-condition: There is a degree value per unique group
102  std::vector<int> n_component_per_group(m_group_degrees.size());
103  for (auto& component : m_components) {
104  if (component.group_id >= (int) m_group_degrees.size()) {
105  throw Elements::Exception() << "Component group out of range for " << component.name;
106  }
107  ++n_component_per_group[component.group_id];
108  }
109 
110  // Pre-condition: There are enough coefficients - (n+d)!/(n!d!) per group
111  unsigned int n_coefficients = 1;
112  for (unsigned int g = 0; g < n_component_per_group.size(); ++g) {
113  int dmax = m_group_degrees[g];
114  int n = n_component_per_group[g];
115  int d = std::min<int>(dmax, n);
116  int num, den;
117 
118  for (num = 1, den = 1; d > 0; num *= (n+dmax--), den*= d--);
119 
120  n_coefficients *= num / den;
121  }
122 
123  if (n_coefficients != m_coefficients.size()) {
124  throw Elements::Exception() << "Invalid number of coefficients. Got " << m_coefficients.size()
125  << " expected " << n_coefficients;
126  }
127 
128  // Pre-condition: All components have the same size
129  auto psf_width = m_coefficients[0]->getWidth();
130  auto psf_height = m_coefficients[0]->getHeight();
131 
132  for (auto coeff : m_coefficients) {
133  if (coeff->getWidth() != psf_width || coeff->getHeight() != psf_height) {
134  throw Elements::Exception() << "Malformed variable PSF, coefficient matrices do not have the same dimensions";
135  }
136  }
137 }
138 
140 {
141  if (values.size() != m_components.size()) {
142  throw Elements::Exception()
143  << "Expecting " << m_components.size() << " values, got " << values.size();
144  }
145  std::vector<double> scaled(values.size());
146  for (auto i = 0u; i < values.size(); ++i) {
147  scaled[i] = (values[i] - m_components[i].offset) / m_components[i].scale;
148  }
149  return scaled;
150 }
151 
153  std::vector<int> group_exponents(m_group_degrees);
155 
157  if (m_components.empty()) {
158  return;
159  }
160 
161  // Constant
162  m_exponents[0].resize(m_components.size());
163  --group_exponents[m_components[0].group_id];
164 
165  // Polynomial
166  exp[0] = 1;
167  for (auto e = m_exponents.begin() + 1; e != m_exponents.end(); ++e) {
168  *e = exp;
169 
170  size_t ei = 0;
171  for (auto component : m_components) {
172  if (group_exponents[component.group_id] > 0) {
173  --group_exponents[component.group_id];
174  ++exp[ei];
175  break;
176  }
177  else {
178  group_exponents[component.group_id] = exp[ei];
179  exp[ei++] = 0;
180  }
181  }
182  }
183 }
184 
185 } // end SourceXtractor
std::vector::resize
T resize(T... args)
SourceXtractor::VariablePsf::selfTest
void selfTest()
Verify that the preconditions of getPsf are met at construction time.
Definition: VariablePsf.cpp:95
SourceXtractor::VariablePsf::m_coefficients
std::vector< std::shared_ptr< VectorImage< SeFloat > > > m_coefficients
Definition: VariablePsf.h:126
SourceXtractor::VariablePsf::m_components
std::vector< Component > m_components
Definition: VariablePsf.h:124
std::shared_ptr
STL class.
std::vector
STL class.
std::vector::size
T size(T... args)
g
constexpr double g
SourceXtractor::VariablePsf::calculateExponents
void calculateExponents()
Definition: VariablePsf.cpp:152
SourceXtractor::VariablePsf::m_group_degrees
std::vector< int > m_group_degrees
Definition: VariablePsf.h:125
SourceXtractor::VariablePsf::VariablePsf
VariablePsf(double pixel_sampling, const std::vector< Component > &components, const std::vector< int > &group_degrees, const std::vector< std::shared_ptr< VectorImage< SeFloat >>> &coefficients)
Definition: VariablePsf.cpp:31
SourceXtractor
Definition: Aperture.h:30
Exception.h
SourceXtractor::VectorImage::create
static std::shared_ptr< VectorImage< T > > create(Args &&... args)
Definition: VectorImage.h:89
Elements::Exception
SourceXtractor::VariablePsf::getWidth
int getWidth() const
Definition: VariablePsf.cpp:47
SourceXtractor::VariablePsf::scaleProperties
std::vector< double > scaleProperties(const std::vector< double > &values) const
Normalizes the values.
Definition: VariablePsf.cpp:139
e
constexpr double e
SourceXtractor::VariablePsf::m_exponents
std::vector< std::vector< int > > m_exponents
Definition: VariablePsf.h:127
SourceXtractor::VariablePsf::getHeight
int getHeight() const
Definition: VariablePsf.cpp:51
SourceXtractor::VariablePsf::m_pixel_sampling
double m_pixel_sampling
Definition: VariablePsf.h:123
x
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
Definition: MoffatModelFittingTask.cpp:93
std::exp
T exp(T... args)
std::vector::begin
T begin(T... args)
SourceXtractor::VectorImage< SeFloat >
VariablePsf.h
SourceXtractor::VariablePsf::getPsf
std::shared_ptr< VectorImage< SeFloat > > getPsf(const std::vector< double > &values) const
Definition: VariablePsf.cpp:63
SourceXtractor::VariablePsf::getComponents
const std::vector< Component > & getComponents() const
Definition: VariablePsf.cpp:59
std::vector::end
T end(T... args)
y
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
Definition: MoffatModelFittingTask.cpp:93
SourceXtractor::VariablePsf::getPixelSampling
double getPixelSampling() const
Definition: VariablePsf.cpp:55
std::pow
T pow(T... args)