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