SourceXtractorPlusPlus  0.12
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SegmentationConfig.cpp
Go to the documentation of this file.
1 
23 #include <iostream>
24 #include <fstream>
25 
26 #include <boost/regex.hpp>
27 using boost::regex;
28 using boost::regex_match;
29 using boost::smatch;
30 
31 #include <boost/algorithm/string.hpp>
32 
34 
36 
39 
42 
43 using namespace Euclid::Configuration;
44 namespace po = boost::program_options;
45 
46 namespace SourceXtractor {
47 
49 
50 static const std::string SEGMENTATION_ALGORITHM {"segmentation-algorithm" };
51 static const std::string SEGMENTATION_DISABLE_FILTERING {"segmentation-disable-filtering" };
52 static const std::string SEGMENTATION_FILTER {"segmentation-filter" };
53 static const std::string SEGMENTATION_LUTZ_WINDOW_SIZE {"segmentation-lutz-window-size" };
54 
55 SegmentationConfig::SegmentationConfig(long manager_id) : Configuration(manager_id),
56  m_selected_algorithm(Algorithm::UNKNOWN), m_lutz_window_size(0) {
57 }
58 
60  return { {"Detection image", {
61  {SEGMENTATION_ALGORITHM.c_str(), po::value<std::string>()->default_value("LUTZ"),
62  "Segmentation algorithm to be used. Currently LUTZ is the only choice"},
63  {SEGMENTATION_DISABLE_FILTERING.c_str(), po::bool_switch(),
64  "Disables filtering"},
65  {SEGMENTATION_FILTER.c_str(), po::value<std::string>()->default_value(""),
66  "Loads a filter"},
67  {SEGMENTATION_LUTZ_WINDOW_SIZE.c_str(), po::value<int>()->default_value(0),
68  "Lutz sliding window size (0=disable)"},
69  }}};
70 }
71 
72 void SegmentationConfig::preInitialize(const UserValues& args) {
73  auto algorithm_name = boost::to_upper_copy(args.at(SEGMENTATION_ALGORITHM).as<std::string>());
74  if (algorithm_name != "LUTZ") {
75  throw Elements::Exception() << "Unknown segmentation algorithm : " << algorithm_name;
76  }
77  if (args.at(SEGMENTATION_DISABLE_FILTERING).as<bool>()) {
78  m_filter = nullptr;
79  } else {
80  auto filter_filename = args.at(SEGMENTATION_FILTER).as<std::string>();
81  if (filter_filename != "") {
82  m_filter = loadFilter(filter_filename);
83  if (m_filter == nullptr)
84  throw Elements::Exception() << "Can not load filter: " << filter_filename;
85  } else {
87  }
88 
89  }
90 
92 }
93 
94 void SegmentationConfig::initialize(const UserValues&) {
96 }
97 
99  segConfigLogger.info() << "Using the default segmentation (3x3) filter.";
100  auto convolution_kernel = VectorImage<SeFloat>::create(3, 3);
101  convolution_kernel->setValue(0,0, 1);
102  convolution_kernel->setValue(0,1, 2);
103  convolution_kernel->setValue(0,2, 1);
104 
105  convolution_kernel->setValue(1,0, 2);
106  convolution_kernel->setValue(1,1, 4);
107  convolution_kernel->setValue(1,2, 2);
108 
109  convolution_kernel->setValue(2,0, 1);
110  convolution_kernel->setValue(2,1, 2);
111  convolution_kernel->setValue(2,2, 1);
112 
113  return std::make_shared<BackgroundConvolution>(convolution_kernel, true);
114 }
115 
117  // check for the extension ".fits"
118  std::string fits_ending(".fits");
119  if (filename.length() >= fits_ending.length()
120  && filename.compare (filename.length() - fits_ending.length(), fits_ending.length(), fits_ending)==0) {
121  // load a FITS filter
122  return loadFITSFilter(filename);
123  }
124  else{
125  // load an ASCII filter
126  return loadASCIIFilter(filename);
127  }
128 }
129 
131 
132  // read in the FITS file
133  auto convolution_kernel = FitsReader<SeFloat>::readFile(filename);
134 
135  // give some feedback on the filter
136  segConfigLogger.info() << "Loaded segmentation filter: " << filename << " height: " << convolution_kernel->getHeight() << " width: " << convolution_kernel->getWidth();
137 
138  // return the correct object
139  return std::make_shared<BackgroundConvolution>(convolution_kernel, true);
140 }
141 
142 static bool getNormalization(std::istream& line_stream) {
143  std::string conv, norm_type;
144  line_stream >> conv >> norm_type;
145  if (conv != "CONV") {
146  throw Elements::Exception() << "Unexpected start for ASCII filter: " << conv;
147  }
148  if (norm_type == "NORM") {
149  return true;
150  }
151  else if (norm_type == "NONORM") {
152  return false;
153  }
154 
155  throw Elements::Exception() << "Unexpected normalization type: " << norm_type;
156 }
157 
158 template <typename T>
159 static void extractValues(std::istream& line_stream, std::vector<T>& data) {
160  T value;
161  while (line_stream.good()) {
162  line_stream >> value;
163  data.push_back(value);
164  }
165 }
166 
168  std::ifstream file;
169 
170  // open the file and check
171  file.open(filename);
172  if (!file.good() || !file.is_open()){
173  throw Elements::Exception() << "Can not load filter: " << filename;
174  }
175 
176  enum class LoadState {
177  STATE_START,
178  STATE_FIRST_LINE,
179  STATE_OTHER_LINES
180  };
181 
182  LoadState state = LoadState::STATE_START;
183  bool normalize = false;
184  std::vector<SeFloat> kernel_data;
185  unsigned int kernel_width = 0;
186 
187  while (file.good()) {
188  std::string line;
189  std::getline(file, line);
190  line = regex_replace(line, regex("\\s*#.*"), std::string(""));
191  line = regex_replace(line, regex("\\s*$"), std::string(""));
192  if (line.size() == 0) {
193  continue;
194  }
195 
196  std::stringstream line_stream(line);
197 
198  switch (state) {
199  case LoadState::STATE_START:
200  normalize = getNormalization(line_stream);
201  state = LoadState::STATE_FIRST_LINE;
202  break;
203  case LoadState::STATE_FIRST_LINE:
204  extractValues(line_stream, kernel_data);
205  kernel_width = kernel_data.size();
206  state = LoadState::STATE_OTHER_LINES;
207  break;
208  case LoadState::STATE_OTHER_LINES:
209  extractValues(line_stream, kernel_data);
210  break;
211  }
212  }
213 
214  // compute the dimensions and create the kernel
215  auto kernel_height = kernel_data.size() / kernel_width;
216  auto convolution_kernel = VectorImage<SeFloat>::create(kernel_width, kernel_height, kernel_data);
217 
218  // give some feedback on the filter
219  segConfigLogger.info() << "Loaded segmentation filter: " << filename << " width: " << convolution_kernel->getWidth() << " height: " << convolution_kernel->getHeight();
220 
221  // return the correct object
222  return std::make_shared<BackgroundConvolution>(convolution_kernel, normalize);
223 }
224 
225 } // SourceXtractor namespace
static const std::string SEGMENTATION_ALGORITHM
void initialize(const UserValues &args) override
T open(T...args)
static const std::string SEGMENTATION_LUTZ_WINDOW_SIZE
static void extractValues(std::istream &line_stream, std::vector< T > &data)
T good(T...args)
static const std::string SEGMENTATION_FILTER
T getline(T...args)
static const std::string SEGMENTATION_DISABLE_FILTERING
void info(const std::string &logMessage)
static std::shared_ptr< VectorImage< T > > create(Args &&...args)
Definition: VectorImage.h:89
STL class.
std::shared_ptr< DetectionImageFrame::ImageFilter > m_filter
STL class.
static bool getNormalization(std::istream &line_stream)
STL class.
std::shared_ptr< DetectionImageFrame::ImageFilter > loadFilter(const std::string &filename) const
T push_back(T...args)
T regex_replace(T...args)
string filename
Definition: conf.py:63
static Elements::Logging segConfigLogger
std::map< std::string, Configuration::OptionDescriptionList > getProgramOptions() override
std::shared_ptr< DetectionImageFrame::ImageFilter > loadFITSFilter(const std::string &filename) const
T length(T...args)
STL class.
T c_str(T...args)
std::shared_ptr< DetectionImageFrame::ImageFilter > loadASCIIFilter(const std::string &filename) const
T is_open(T...args)
void preInitialize(const UserValues &args) override
static Logging getLogger(const std::string &name="")
STL class.
std::shared_ptr< DetectionImageFrame::ImageFilter > getDefaultFilter() const
T compare(T...args)