29 #include <boost/program_options.hpp>
30 #include <boost/algorithm/string/predicate.hpp>
84 namespace po = boost::program_options;
85 namespace fs = boost::filesystem;
99 m_list.push_back(group);
108 m_list.push_back(source);
125 ::setenv(
"LC_ALL",
"C", 1);
136 bool omp_env_present =
getenv(
"OMP_NUM_THREADS") ||
getenv(
"OMP_DYNAMIC");
137 bool mkl_env_present =
getenv(
"MKL_NUM_THREADS") ||
getenv(
"MKL_DYNAMIC");
138 if (!omp_env_present && !mkl_env_present) {
140 void (*set_num_threads)(int) =
reinterpret_cast<void (*)(
int)
>(dlsym(RTLD_DEFAULT,
"MKL_Set_Num_Threads"));
141 void (*set_dynamic)(int) =
reinterpret_cast<void (*)(
int)
>(dlsym(RTLD_DEFAULT,
"MKL_Set_Dynamic"));
142 if (set_num_threads) {
143 logger.debug() <<
"Disabling multithreading";
147 logger.debug() <<
"Disabling dynamic multithreading";
162 std::make_shared<SourceWithOnDemandPropertiesFactory>(task_provider);
164 std::make_shared<SourceGroupWithOnDemandPropertiesFactory>(task_provider);
171 bool config_initialized =
false;
177 : plugin_manager { task_factory_registry, output_registry,
config_manager_id, plugin_path, plugin_list } {
184 if (!config_initialized) {
199 segmentation_factory.reportConfigDependencies(config_manager);
200 partition_factory.reportConfigDependencies(config_manager);
201 grouping_factory.reportConfigDependencies(config_manager);
202 deblending_factory.reportConfigDependencies(config_manager);
203 measurement_factory.reportConfigDependencies(config_manager);
204 output_factory.reportConfigDependencies(config_manager);
206 config_parameters.add(config_manager.closeRegistration());
207 config_initialized =
true;
209 return config_parameters;
214 auto options = getConfigParameters();
217 "List the possible output properties for the given input parameters and exit");
219 "Show the columns created for each property");
221 "Show the columns created for each property, for the given configuration");
223 "Dump parameters with default values into a configuration file");
224 progress_printer_factory.addOptions(options);
227 po::positional_options_description p;
228 p.add(
"python-arg", -1);
234 template <
typename T>
236 out << opt.long_name() <<
'=' << boost::any_cast<T>(default_value) <<
std::endl;
240 template <
typename T>
242 auto values = boost::any_cast<std::vector<T>>(default_value);
243 if (values.empty()) {
244 out <<
"# " << opt.long_name() <<
'=' <<
std::endl;
247 for (
const auto& v : values)
248 out << opt.long_name() <<
'=' << v <<
std::endl;
256 {
typeid(bool), &writeDefault<bool>},
257 {
typeid(int), &writeDefault<int>},
258 {
typeid(double), &writeDefault<double>},
262 decltype(printers)::const_iterator printer;
264 auto config_parameters = getConfigParameters();
265 for (
const auto& p : config_parameters.options()) {
266 boost::any default_value;
269 if (!p->semantic()->apply_default(default_value)) {
272 else if ((printer = printers.find(default_value.type())) == printers.end()) {
273 std::cout <<
'#' << p->long_name() <<
"=<Unknown type " << default_value.type().name() <<
'>' <<
std::endl;
276 printer->second(
std::cout, *p, default_value);
315 if (args.
find(
"config-file") != args.
end()) {
316 auto cfg_file = args.
at(
"config-file").as<fs::path>();
317 if (cfg_file !=
"" && !fs::exists(cfg_file)) {
318 throw Elements::Exception() <<
"The configuration file '" << cfg_file <<
"' does not exist";
323 progress_printer_factory.configure(args);
324 auto progress_mediator = progress_printer_factory.createProgressMediator();
328 config_manager.initialize(args);
331 auto memory_config = config_manager.getConfiguration<
MemoryConfig>();
333 memory_config.getTileSize(), memory_config.getTileMaxMemory());
337 task_factory_registry->
configure(config_manager);
340 segmentation_factory.configure(config_manager);
341 partition_factory.configure(config_manager);
342 grouping_factory.configure(config_manager);
343 deblending_factory.configure(config_manager);
344 measurement_factory.configure(config_manager);
345 output_factory.configure(config_manager);
352 auto segmentation = segmentation_factory.createSegmentation();
361 prefetcher = std::make_shared<Prefetcher>(thread_pool, multithreading_config.
getMaxQueueSize());
365 auto partition = partition_factory.getPartition();
366 auto source_grouping = grouping_factory.createGrouping();
373 prefetcher->requestProperties(source_grouping->requiredProperties());
374 prefetcher->requestProperties(deblending->requiredProperties());
381 segmentation->Observable<ProcessSourcesEvent>::addObserver(prefetcher);
382 prefetcher->Observable<ProcessSourcesEvent>::addObserver(source_grouping);
387 segmentation->Observable<ProcessSourcesEvent>::addObserver(source_grouping);
391 source_grouping->addObserver(deblending);
392 deblending->addObserver(measurement);
395 logger.info() <<
"Writing output following measure order";
396 measurement->addObserver(output);
398 logger.info() <<
"Writing output following segmentation order";
399 auto sorter = std::make_shared<Sorter>();
400 measurement->addObserver(sorter);
401 sorter->addObserver(output);
404 segmentation->Observable<SegmentationProgress>::addObserver(progress_mediator->getSegmentationObserver());
406 deblending->addObserver(progress_mediator->getDeblendingObserver());
407 measurement->addObserver(progress_mediator->getMeasurementObserver());
412 std::make_shared<DetectionIdCheckImage>());
415 measurement->addObserver(
416 std::make_shared<SourceIdCheckImage>());
419 measurement->addObserver(
420 std::make_shared<GroupIdCheckImage>());
423 measurement->addObserver(
424 std::make_shared<MoffatCheckImage>());
426 const auto& detection_frames = config_manager.getConfiguration<
DetectionFrameConfig>().getDetectionFrames();
429 measurement->startThreads();
431 size_t prev_writen_rows = 0;
432 size_t frame_number = 0;
433 for (
auto& detection_frame : detection_frames) {
437 logger.info() <<
"Processing frame "
438 << frame_number <<
" / " << detection_frames.size() <<
" : " << detection_frame->getLabel();
439 segmentation->processFrame(detection_frame);
442 logger.error() <<
"Failed to process the frame! " <<
e.what();
443 measurement->stopThreads();
448 prefetcher->synchronize();
450 measurement->synchronizeThreads();
452 size_t nb_writen_rows = output->flush();
455 logger.info() << (nb_writen_rows - prev_writen_rows) <<
" sources detected in frame, " << nb_writen_rows <<
" total";
457 prev_writen_rows = nb_writen_rows;
463 measurement->stopThreads();
467 progress_mediator->done();
469 if (prev_writen_rows > 0) {
470 logger.info() <<
"total " << prev_writen_rows <<
" sources detected";
472 logger.info() <<
"NO SOURCES DETECTED";
484 m_plugin_path(plugin_path), m_plugin_list(plugin_list) {
492 auto options = config_manager.closeRegistration();
494 options.add_options()(
"*", po::value<std::vector<std::string>>());
500 config_manager.initialize(args);
502 m_plugin_path =
conf.getPluginPath();
503 m_plugin_list =
conf.getPluginList();
517 for (
int i = 0; i < argc; ++i) {
519 if (option ==
"--config-file") {
523 if (boost::starts_with(option,
"--config-file=")) {
526 if (option ==
"--plugin-directory") {
527 plugin_options_input.
emplace_back(
"--plugin-directory");
530 if (boost::starts_with(option,
"--plugin-directory=")) {
533 if (option ==
"--plugin") {
537 if (boost::starts_with(option,
"--plugin=")) {
550 if (local_env[
"ELEMENTS_CONF_PATH"].empty()) {
551 local_env[
"ELEMENTS_CONF_PATH"] =
".:/etc";
553 local_env[
"ELEMENTS_CONF_PATH"] =
".:" + local_env[
"ELEMENTS_CONF_PATH"] +
":/etc";
570 plugin_options_input.emplace_back(
"--log-level");
571 plugin_options_input.emplace_back(
"ERROR");
574 int argc_tmp = plugin_options_input.size();
576 for (
unsigned int i = 0; i < plugin_options_input.size(); ++i) {
577 auto& option_str = plugin_options_input[i];
578 argv_tmp[i] = option_str.
data();
582 plugin_options_program.run(argc_tmp,
const_cast<char **
>(argv_tmp.
data()));
593 logger.fatal() <<
"Unknown exception type!";
594 logger.fatal() <<
"Please, report this as a bug";
static Logging getLogger(const std::string &name="")
static void onTerminate() noexcept
static ConfigManager & getInstance(long id)
virtual void handleMessage(const std::shared_ptr< SourceGroupInterface > &group) override
std::list< std::shared_ptr< SourceGroupInterface > > m_list
boost::program_options::options_description defineSpecificProgramOptions() override
Elements::ExitCode mainMethod(std::map< std::string, boost::program_options::variable_value > &args) override
std::string & m_plugin_path
virtual ~PluginOptionsMain()=default
PluginOptionsMain(std::string &plugin_path, std::vector< std::string > &plugin_list)
std::vector< std::string > & m_plugin_list
po::options_description getConfigParameters()
void printDefaults()
Print a configuration file populated with defaults.
SEMain(const std::string &plugin_path, const std::vector< std::string > &plugin_list)
Elements::ExitCode mainMethod(std::map< std::string, po::variable_value > &args) override
static void writeDefaultMultiple(std::ostream &out, const po::option_description &opt, const boost::any &default_value)
Print a multiple-value option.
std::pair< po::options_description, po::positional_options_description > defineProgramArguments() override
Return the arguments that the program accepts.
static void writeDefault(std::ostream &out, const po::option_description &opt, const boost::any &default_value)
Print a simple option.
PluginManager plugin_manager
po::options_description config_parameters
std::list< std::shared_ptr< SourceWithOnDemandProperties > > m_list
virtual void handleMessage(const std::shared_ptr< SourceWithOnDemandProperties > &source) override
T emplace_back(T... args)
#define CREATE_MANAGER_WITH_ARGS(MANAGER, ELEMENTS_PROGRAM,...)
std::underlying_type< ExitCode >::type ExitCodeType
long getUniqueManagerId() noexcept
T set_terminate(T... args)