SourceXtractorPlusPlus  0.16
Please provide a description of the project.
AssocModeConfig.cpp
Go to the documentation of this file.
1 
19 
20 #include <map>
21 #include <boost/algorithm/string.hpp>
22 
23 #include <CCfits/CCfits>
24 
25 #include "Table/AsciiReader.h"
26 #include "Table/FitsReader.h"
27 
30 
32 
33 using namespace Euclid::Configuration;
34 namespace po = boost::program_options;
35 
36 namespace SourceXtractor {
37 
38 static const std::string ASSOC_CATALOG { "assoc-catalog" };
39 static const std::string ASSOC_MODE { "assoc-mode" };
40 static const std::string ASSOC_RADIUS { "assoc-radius" };
41 static const std::string ASSOC_FILTER { "assoc-filter" };
42 static const std::string ASSOC_COPY { "assoc-copy" };
43 static const std::string ASSOC_COLUMNS { "assoc-columns" };
44 
45 namespace {
46 
48  std::make_pair("", AssocModeConfig::AssocMode::UNKNOWN),
49  std::make_pair("FIRST", AssocModeConfig::AssocMode::FIRST),
50  std::make_pair("NEAREST", AssocModeConfig::AssocMode::NEAREST),
51  std::make_pair("MEAN", AssocModeConfig::AssocMode::MEAN),
52  std::make_pair("MAG_MEAN", AssocModeConfig::AssocMode::MAG_MEAN),
53  std::make_pair("SUM", AssocModeConfig::AssocMode::SUM),
54  std::make_pair("MAG_SUM", AssocModeConfig::AssocMode::MAG_SUM),
55  std::make_pair("MIN", AssocModeConfig::AssocMode::MIN),
56  std::make_pair("MAX", AssocModeConfig::AssocMode::MAX)
57 };
58 
60  std::make_pair("ALL", AssocModeConfig::AssocFilter::ALL),
61  std::make_pair("MATCHED", AssocModeConfig::AssocFilter::MATCHED),
62  std::make_pair("UNMATCHED", AssocModeConfig::AssocFilter::UNMATCHED)
63 };
64 
65 std::vector<int> parseColumnList(const std::string& arg) {
66  if (arg.size() > 0) {
67  try {
69  boost::split(parts, arg, boost::is_any_of(","));
70 
71  std::vector<int> column_list;
72  for (auto& part : parts) {
73  column_list.emplace_back(boost::lexical_cast<int>(part));
74  }
75 
76  return column_list;
77  } catch(...) {
78  throw Elements::Exception() << "Can't parse column list";
79  }
80  } else {
81  return {};
82  }
83 }
84 
85 }
86 
87 AssocModeConfig::AssocModeConfig(long manager_id) : Configuration(manager_id), m_assoc_mode(AssocMode::UNKNOWN), m_assoc_radius(0.) {
88  declareDependency<PartitionStepConfig>();
90 }
91 
93  return { {"Assoc config", {
94  {ASSOC_CATALOG.c_str(), po::value<std::string>(),
95  "Assoc catalog file"},
96  {ASSOC_COLUMNS.c_str(), po::value<std::string>()->default_value("2,3,4"),
97  "Assoc columns"},
98  {ASSOC_MODE.c_str(), po::value<std::string>()->default_value("NEAREST"),
99  "Assoc mode"},
100  {ASSOC_RADIUS.c_str(), po::value<double>()->default_value(2.0),
101  "Assoc radius"},
102  {ASSOC_FILTER.c_str(), po::value<std::string>()->default_value("ALL"),
103  "Assoc catalog filter setting: ALL, MATCHED, UNMATCHED"},
104  {ASSOC_COPY.c_str(), po::value<std::string>()->default_value(""),
105  "List of assoc catalog columns to copy on match"},
106  }}};
107 }
108 
110 
111  auto filter = boost::to_upper_copy(args.at(ASSOC_FILTER).as<std::string>());
112  if (assoc_filter_table.find(filter) != assoc_filter_table.end()) {
113  auto assoc_filter = assoc_filter_table.at(filter);
114  if (assoc_filter == AssocFilter::MATCHED) {
115  getDependency<PartitionStepConfig>().addPartitionStepCreator(
116  [](std::shared_ptr<SourceFactory> source_factory) {
117  return std::make_shared<AssocModePartitionStep>(true);
118  }
119  );
120  } else if (assoc_filter == AssocFilter::UNMATCHED) {
121  getDependency<PartitionStepConfig>().addPartitionStepCreator(
122  [](std::shared_ptr<SourceFactory> source_factory) {
123  return std::make_shared<AssocModePartitionStep>(false);
124  }
125  );
126  }
127  } else {
128  throw Elements::Exception() << "Invalid assoc filter: " << filter;
129  }
130 
131  m_assoc_radius = args.at(ASSOC_RADIUS).as<double>();
132 
133  auto columns = parseColumnList(args.at(ASSOC_COLUMNS).as<std::string>());
134  if (columns.size() < 2) {
135  throw Elements::Exception() << "At least 2 columns must be specified for x,y coordinates in the assoc catalog";
136  }
137  if (columns.size() > 3) {
138  throw Elements::Exception() << "Maximum 3 columns for x, y and weight must be specified in the assoc catalog";
139  }
140 
141  auto copy_columns = parseColumnList(args.at(ASSOC_COPY).as<std::string>());
142 
143  if (args.find(ASSOC_MODE) != args.end()) {
144  auto assoc_mode = boost::to_upper_copy(args.at(ASSOC_MODE).as<std::string>());
145  if (assoc_mode_table.find(assoc_mode) != assoc_mode_table.end()) {
146  m_assoc_mode = assoc_mode_table.at(assoc_mode);
147  } else {
148  throw Elements::Exception() << "Invalid association mode: " << assoc_mode;
149  }
150  }
151 
152  if (args.find(ASSOC_CATALOG) != args.end()) {
153  try {
154  auto filename = args.at(ASSOC_CATALOG).as<std::string>();
155 
157  try {
158  reader = std::make_shared<Euclid::Table::FitsReader>(filename);
159  } catch(...) {
160  // If FITS not successful try reading as ascii
161  reader = std::make_shared<Euclid::Table::AsciiReader>(filename);
162  }
163  auto table = reader->read();
164  readTable(table, columns, copy_columns);
165 
166  } catch(...) {
167  throw Elements::Exception() << "Can't open/read assoc catalog";
168  }
169  }
170 }
171 
173  const Euclid::Table::Table& table, const std::vector<int>& columns, const std::vector<int>& copy_columns) {
174  for (auto& row : table) {
175  // our internal pixel coordinates are zero-based
176  auto coord =
177  ImageCoordinate { boost::get<double>(row[columns.at(0)]) - 1.0, boost::get<double>(row[columns.at(1)]) - 1.0 };
178  m_catalog.emplace_back(CatalogEntry { coord, 1.0, {} });
179  if (columns.size() == 3 && columns.at(2) >= 0) {
180  m_catalog.back().weight = boost::get<double>(row[columns.at(2)]);
181  }
182  for (auto column : copy_columns) {
183  if (row[column].type() == typeid(int)) {
184  m_catalog.back().assoc_columns.emplace_back(boost::get<int>(row[column]));
185  } else if (row[column].type() == typeid(double)) {
186  m_catalog.back().assoc_columns.emplace_back(boost::get<double>(row[column]));
187  } else {
188  throw Elements::Exception() << "Wrong type in assoc column";
189  }
190  }
191  }
192 }
193 
194 
195 }
196 
T at(T... args)
T c_str(T... args)
static ConfigManager & getInstance(long id)
std::map< std::string, OptionDescriptionList > getProgramOptions() override
void initialize(const UserValues &args) override
std::vector< CatalogEntry > m_catalog
void readTable(const Euclid::Table::Table &table, const std::vector< int > &columns, const std::vector< int > &copy_columns)
T emplace_back(T... args)
T end(T... args)
T find(T... args)
ELEMENTS_API auto split(Args &&... args) -> decltype(splitPath(std::forward< Args >(args)...))
T make_pair(T... args)
static const std::string ASSOC_COPY
static const std::string ASSOC_FILTER
static const std::string ASSOC_CATALOG
static const std::string ASSOC_MODE
static const std::string ASSOC_RADIUS
static const std::string ASSOC_COLUMNS
string filename
Definition: conf.py:63
T size(T... args)