SourceXtractorPlusPlus  0.19
SourceXtractor++, the next generation SExtractor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AssocModeTask.cpp
Go to the documentation of this file.
1 
19 #include <iostream>
20 #include <algorithm>
21 #include <functional>
22 
23 #include "SEUtils/KdTree.h"
24 
27 
30 
31 namespace SourceXtractor {
32 
34 
35 template <>
36 struct KdTreeTraits<AssocModeConfig::CatalogEntry> {
37  static double getCoord(const AssocModeConfig::CatalogEntry& t, size_t index) {
38  if (index == 0) {
39  return t.coord.m_x;
40  } else {
41  return t.coord.m_y;
42  }
43  }
44 };
45 
46 namespace {
47 
48 AssocModeConfig::CatalogEntry getAssocEntryUnknownImpl(const std::vector<AssocModeConfig::CatalogEntry>&) {
49  throw Elements::Exception() << "UNKNOWN association mode";
50 }
51 
52 AssocModeConfig::CatalogEntry getAssocEntryFirstImpl(const std::vector<AssocModeConfig::CatalogEntry>& entries) {
53  return entries.front();
54 }
55 
56 AssocModeConfig::CatalogEntry getAssocEntryNearestImpl(const std::vector<AssocModeConfig::CatalogEntry>& entries,
57  double x, double y) {
58  return *std::min_element(entries.begin(), entries.end(),
59  [x, y](const AssocModeConfig::CatalogEntry &a, const AssocModeConfig::CatalogEntry &b) -> bool {
60  auto dx_a = a.coord.m_x - x;
61  auto dy_a = a.coord.m_y - y;
62  auto dx_b = b.coord.m_x - x;
63  auto dy_b = b.coord.m_y - y;
64  return dx_a*dx_a + dy_a*dy_a < dx_b*dx_b + dy_b*dy_b;
65  });
66 }
67 
68 AssocModeConfig::CatalogEntry getAssocEntryMinImpl(const std::vector<AssocModeConfig::CatalogEntry>& entries) {
69  return *std::min_element(entries.begin(), entries.end(),
70  [](const AssocModeConfig::CatalogEntry &a, const AssocModeConfig::CatalogEntry &b) -> bool {
71  return a.weight < b.weight;
72  });
73 }
74 
75 AssocModeConfig::CatalogEntry getAssocEntryMaxImpl(const std::vector<AssocModeConfig::CatalogEntry>& entries) {
76  return *std::max_element(entries.begin(), entries.end(),
77  [](const AssocModeConfig::CatalogEntry &a, const AssocModeConfig::CatalogEntry &b) -> bool {
78  return a.weight < b.weight;
79  });
80 }
81 
82 AssocModeConfig::CatalogEntry getAssocEntryMeanImpl(const std::vector<AssocModeConfig::CatalogEntry>& entries) {
83  AssocModeConfig::CatalogEntry result{{}, 0., {}};
84  result.assoc_columns.resize(entries.front().assoc_columns.size());
85  double total_weight = 0.0;
86  for (auto& entry : entries) {
87  total_weight += entry.weight;
88  for (size_t i=0; i < result.assoc_columns.size(); i++) {
89  result.assoc_columns[i] += entry.assoc_columns[i] * entry.weight;
90  }
91  }
92 
93  for (size_t i=0; i < result.assoc_columns.size(); i++) {
94  result.assoc_columns[i] /= total_weight;
95  }
96 
97  return result;
98 }
99 
100 AssocModeConfig::CatalogEntry getAssocEntrySumImpl(const std::vector<AssocModeConfig::CatalogEntry>& entries) {
101  AssocModeConfig::CatalogEntry result{{}, 0., {}};
102  result.assoc_columns.resize(entries.front().assoc_columns.size());
103  for (auto& entry : entries) {
104  for (size_t i=0; i < result.assoc_columns.size(); i++) {
105  result.assoc_columns[i] += entry.assoc_columns[i];
106  }
107  }
108  return result;
109 }
110 
111 AssocModeConfig::CatalogEntry getAssocEntryMagMeanImpl(const std::vector<AssocModeConfig::CatalogEntry>& entries) {
112  AssocModeConfig::CatalogEntry result{{}, 0., {}};
113  result.assoc_columns.resize(entries.front().assoc_columns.size());
114  double total_weight = 0.0;
115  for (auto& entry : entries) {
116  double linear_weight = pow(10.0, -0.4 * entry.weight);
117  total_weight += linear_weight;
118  for (size_t i=0; i < result.assoc_columns.size(); i++) {
119  result.assoc_columns[i] += entry.assoc_columns[i] * linear_weight;
120  }
121  }
122 
123  for (size_t i=0; i < result.assoc_columns.size(); i++) {
124  result.assoc_columns[i] /= total_weight;
125  }
126 
127  return result;
128 }
129 
130 AssocModeConfig::CatalogEntry getAssocEntryMagSumImpl(const std::vector<AssocModeConfig::CatalogEntry>& entries) {
131  AssocModeConfig::CatalogEntry result{{}, 0., {}};
132  result.assoc_columns.resize(entries.front().assoc_columns.size());
133  for (auto& entry : entries) {
134  for (size_t i=0; i < result.assoc_columns.size(); i++) {
135  result.assoc_columns[i] += pow(10.0, -0.4 * entry.assoc_columns[i]);
136  }
137  }
138 
139  for (size_t i=0; i < result.assoc_columns.size(); i++) {
140  result.assoc_columns[i] = -2.5 * log10(result.assoc_columns[i]);
141  }
142 
143  return result;
144 }
145 
146 }
147 
149  AssocModeConfig::AssocMode assoc_mode, double radius) :
150  m_assoc_mode(assoc_mode), m_radius(radius) {
151  for (auto& catalog : catalogs) {
152  m_catalogs.emplace_back(catalog);
153  }
154 }
155 
157  using namespace std::placeholders; // for _1, _2, _3...
159 
160  // get the object center
161  const auto& x = source.getProperty<PixelCentroid>().getCentroidX();
162  const auto& y = source.getProperty<PixelCentroid>().getCentroidY();
163 
164  auto hdu_index = source.getProperty<DetectionFrameInfo>().getHduIndex();
165  const auto& catalog = m_catalogs.at(hdu_index);
166 
167  auto nearby_catalog_entries = catalog.findPointsWithinRadius(Tree::Coord { x, y }, m_radius);
168 
169  if (nearby_catalog_entries.size() == 0) {
170  // No match
171  source.setProperty<AssocMode>(false, std::vector<double>());
172  } else {
173  const std::map<AssocModeConfig::AssocMode, AssocModeTask::GetAssocResult> assoc_mode_implementation_table {
174  std::make_pair(AssocModeConfig::AssocMode::UNKNOWN, getAssocEntryUnknownImpl),
175  std::make_pair(AssocModeConfig::AssocMode::FIRST, getAssocEntryFirstImpl),
176  std::make_pair(AssocModeConfig::AssocMode::NEAREST, std::bind(getAssocEntryNearestImpl, _1, x, y)),
177  std::make_pair(AssocModeConfig::AssocMode::MIN, getAssocEntryMinImpl),
178  std::make_pair(AssocModeConfig::AssocMode::MAX, getAssocEntryMaxImpl),
179  std::make_pair(AssocModeConfig::AssocMode::MEAN, getAssocEntryMeanImpl),
180  std::make_pair(AssocModeConfig::AssocMode::SUM, getAssocEntrySumImpl),
181  std::make_pair(AssocModeConfig::AssocMode::MAG_SUM, getAssocEntryMagSumImpl),
182  std::make_pair(AssocModeConfig::AssocMode::MAG_MEAN, getAssocEntryMagMeanImpl)
183  };
184 
185  auto assoc_data = assoc_mode_implementation_table.at(m_assoc_mode)(nearby_catalog_entries);
186  source.setProperty<AssocMode>(true, assoc_data.assoc_columns);
187  }
188 }
189 
190 }
AssocModeConfig::AssocMode m_assoc_mode
Definition: AssocModeTask.h:46
const PropertyType & getProperty(unsigned int index=0) const
Convenience template method to call getProperty() with a more user-friendly syntax.
AssocModeTask(const std::vector< std::vector< AssocModeConfig::CatalogEntry >> &catalogs, AssocModeConfig::AssocMode assoc_type, double radius)
T front(T...args)
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
T max_element(T...args)
void computeProperties(SourceInterface &source) const override
Computes one or more properties for the Source.
T end(T...args)
The centroid of all the pixels in the source, weighted by their DetectionImage pixel values...
Definition: PixelCentroid.h:37
T log10(T...args)
STL class.
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
T make_pair(T...args)
T bind(T...args)
A simple N-dimensional KdTree for speeding-up elements within range types of queries.
Definition: KdTree.h:42
T size(T...args)
STL class.
T begin(T...args)
T pow(T...args)
std::vector< KdTree< AssocModeConfig::CatalogEntry > > m_catalogs
Definition: AssocModeTask.h:45
T min_element(T...args)
static double getCoord(const AssocModeConfig::CatalogEntry &t, size_t index)
The SourceInterface is an abstract &quot;source&quot; that has properties attached to it.