Skip to content

Call sourcextractor++ from Python #522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 35 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
99c8950
Make SourceInterface cloneable
ayllon Aug 29, 2022
c221933
EntangledSource owns the wrapped source
ayllon Sep 2, 2022
c0e7295
Fix build on centos7
ayllon Sep 16, 2022
e1314ed
Add method to iterate set properties
ayllon Sep 5, 2022
e8c75c8
Add some consts to OutputConfig
ayllon Sep 5, 2022
51cb42e
Expose column converters
ayllon Aug 17, 2022
4420604
Expose detection stamp
ayllon Sep 9, 2022
355445f
Allow to get property columns by ID and name
ayllon Sep 16, 2022
28cf91a
Expose converters for internal properties
ayllon Sep 16, 2022
f168265
Grouping should forward events
ayllon Sep 21, 2022
48f1147
Rename SourceXtractorPy => SEPythonConfig
ayllon Sep 20, 2022
55ca5a7
Move pure Python code to a separate module
ayllon Sep 20, 2022
1d533fb
Module to call sourcex from Python
ayllon Aug 15, 2022
2a40f56
Add a Python demo
ayllon Sep 20, 2022
55234d7
Fix build in centos7
ayllon Sep 22, 2022
be8eb46
Demo python 3.8 compatible
ayllon Oct 13, 2022
6ff3717
Keep a reference to the thread pool
ayllon Oct 13, 2022
e9cd46a
Translate Python exception to Elements::Exception
ayllon Oct 13, 2022
b113a38
Flush events following the received order
ayllon Oct 13, 2022
908ea61
Properly catch exceptions during measurement
ayllon Oct 13, 2022
36dd2ca
MultithreadedMeasurement must send events in order
ayllon Oct 13, 2022
35bdb17
Add cancel() method to measurement
ayllon Oct 13, 2022
46f1c95
Fix handling of the timeout
ayllon Oct 13, 2022
59ad317
Forgot to override cancel in DummyMeasurement
ayllon Oct 13, 2022
0485f57
Add Context::check_exception
ayllon Oct 14, 2022
c8d0f01
Fix timedelta conversion
ayllon Oct 14, 2022
dc3c234
Make PixelCoordinateList moveable
ayllon Oct 14, 2022
bc9d776
Custom segmentation
ayllon Oct 14, 2022
2f0dd74
Add missing comments to Source python wrappers
ayllon Oct 14, 2022
c95850a
Fix build in centos7
ayllon Oct 14, 2022
a308bc7
Add support for custom grouping
ayllon Oct 17, 2022
c344b90
Do not capture python stdout and stderr
ayllon Oct 17, 2022
1f43d9e
Restore backtrace when raising Python exceptions
ayllon Oct 17, 2022
d2c2be9
Add demo with live preview
ayllon Oct 20, 2022
5d8e42a
merge develop
marcschefer Nov 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ find_package(ElementsProject)
#---------------------------------------------------------------

# Declare project name and version
elements_project(SourceXtractorPlusPlus 0.20 USE Alexandria 2.27.1 DESCRIPTION "SourceXtractor++, the next generation SExtractor")
elements_project(SourceXtractorPlusPlus 0.20 USE Alexandria 2.28 DESCRIPTION "SourceXtractor++, the next generation SExtractor")
75 changes: 44 additions & 31 deletions SEFramework/SEFramework/Output/OutputRegistry.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** Copyright © 2019 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
/**
* Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
Expand Down Expand Up @@ -34,25 +35,55 @@
namespace SourceXtractor {

class OutputRegistry {

public:

template <typename PropertyType, typename OutType>
using ColumnConverter = std::function<OutType(const PropertyType&)>;

using SourceToRowConverter = std::function<Euclid::Table::Row(const SourceInterface&)>;

class ColumnFromSource {
public:
template <typename PropertyType, typename OutType>
explicit ColumnFromSource(ColumnConverter<PropertyType, OutType> converter) {
m_convert_func = [converter](const SourceInterface& source, std::size_t i) {
return converter(source.getProperty<PropertyType>(i));
};
}
Euclid::Table::Row::cell_type operator()(const SourceInterface& source) const {
return m_convert_func(source, index);
}
std::size_t index = 0;

private:
std::function<Euclid::Table::Row::cell_type(const SourceInterface&, std::size_t index)> m_convert_func;
};

struct ColInfo {
std::string unit;
std::string description;
};

public:
template <typename PropertyType, typename OutType>
void registerColumnConverter(std::string column_name, ColumnConverter<PropertyType, OutType> converter,
std::string column_unit="", std::string column_description="") {
m_property_to_names_map[typeid(PropertyType)].emplace_back(column_name);
m_name_to_property_map.emplace(column_name, typeid(PropertyType));
std::type_index conv_out_type = typeid(OutType);
ColumnFromSource conv_func {converter};
m_name_to_converter_map.emplace(column_name,
std::pair<std::type_index, ColumnFromSource>(conv_out_type, conv_func));
m_name_to_col_info_map.emplace(column_name, ColInfo{column_unit, column_description});
}

std::type_index getPropertyForColumn(const std::string& column_name) const {
return m_name_to_property_map.at(column_name);
}

const std::pair<std::type_index, ColumnFromSource>& getColumnConverter(const std::string& column_name) const {
return m_name_to_converter_map.at(column_name);
}

/**
* When there are multiple instances of a given property, generate one column output with the given suffix for each
* instance
Expand Down Expand Up @@ -146,46 +177,28 @@ class OutputRegistry {
m_output_properties.emplace(alias_name, typeid(PropertyType));
}

std::set<std::string> getOutputPropertyNames() {
std::set<std::string> getOutputPropertyNames() const {
std::set<std::string> result {};
for (auto& pair : m_output_properties) {
result.emplace(pair.first);
}
return result;
}

std::set<std::string> getColumns(const std::string& property) const;

std::set<std::string> getColumns(const PropertyId& property) const;

SourceToRowConverter getSourceToRowConverter(const std::vector<std::string>& enabled_optional);

void printPropertyColumnMap(const std::vector<std::string>& properties={});

private:

class ColumnFromSource {
public:
template <typename PropertyType, typename OutType>
explicit ColumnFromSource(ColumnConverter<PropertyType, OutType> converter) {
m_convert_func = [converter](const SourceInterface& source, std::size_t i){
return converter(source.getProperty<PropertyType>(i));
};
}
Euclid::Table::Row::cell_type operator()(const SourceInterface& source) {
return m_convert_func(source, index);
}
std::size_t index = 0;
private:
std::function<Euclid::Table::Row::cell_type(const SourceInterface&, std::size_t index)> m_convert_func;
};

struct ColInfo {
std::string unit;
std::string description;
};

std::map<std::type_index, std::vector<std::string>> m_property_to_names_map {};
std::map<std::string, std::pair<std::type_index, ColumnFromSource>> m_name_to_converter_map {};
std::map<std::string, ColInfo> m_name_to_col_info_map {};
std::multimap<std::string, std::type_index> m_output_properties {};

std::map<std::type_index, std::vector<std::string>> m_property_to_names_map{};
std::map<std::string, std::type_index> m_name_to_property_map{};
std::map<std::string, std::pair<std::type_index, ColumnFromSource>> m_name_to_converter_map{};
std::map<std::string, ColInfo> m_name_to_col_info_map{};
std::multimap<std::string, std::type_index> m_output_properties{};
};

} /* namespace SourceXtractor */
Expand Down
4 changes: 3 additions & 1 deletion SEFramework/SEFramework/Pipeline/Measurement.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
/**
* Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
Expand Down Expand Up @@ -39,6 +40,7 @@ class Measurement : public PipelineReceiver<SourceGroupInterface>, public Pipeli
virtual void startThreads() = 0;
virtual void stopThreads() = 0;
virtual void synchronizeThreads() = 0;
virtual void cancel() = 0;
};

}
Expand Down
21 changes: 17 additions & 4 deletions SEFramework/SEFramework/Property/PropertyHolder.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** Copyright © 2019 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
/**
* Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
Expand Down Expand Up @@ -44,6 +45,8 @@ class PropertyHolder {

public:

using const_iterator = std::unordered_map<PropertyId, std::shared_ptr<Property>>::const_iterator;

/// Destructor
virtual ~PropertyHolder() = default;

Expand All @@ -60,16 +63,26 @@ class PropertyHolder {
const Property& getProperty(const PropertyId& property_id) const;

/// Sets a property, overwriting it if necessary
void setProperty(std::unique_ptr<Property> property, const PropertyId& property_id);
void setProperty(std::shared_ptr<Property> property, const PropertyId& property_id);

/// Returns true if the property is set
bool isPropertySet(const PropertyId& property_id) const;

void clear();

void update(const PropertyHolder& other);

const_iterator begin() const {
return m_properties.begin();
}

const_iterator end() const {
return m_properties.end();
}

private:

std::unordered_map<PropertyId, std::unique_ptr<Property>> m_properties;
std::unordered_map<PropertyId, std::shared_ptr<Property>> m_properties;

}; /* End of ObjectWithProperties class */

Expand Down
8 changes: 4 additions & 4 deletions SEFramework/SEFramework/Property/PropertyId.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** Copyright © 2019 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
/*
* Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
Expand Down Expand Up @@ -39,6 +40,8 @@ namespace SourceXtractor {

class PropertyId {
public:
PropertyId(std::type_index type_id, unsigned int index) : m_type_id(type_id), m_index(index) {}

/// Templated factory method used to create a PropertyId based on the type of a property.
/// An optional index parameter is used to make the distinction between several properties of the same type.
template<typename T>
Expand Down Expand Up @@ -74,12 +77,9 @@ class PropertyId {
std::string getString() const;

private:
PropertyId(std::type_index type_id, unsigned int index) : m_type_id(type_id), m_index(index) {}

std::type_index m_type_id;
unsigned int m_index;


friend struct std::hash<SourceXtractor::PropertyId>;
};

Expand Down
20 changes: 17 additions & 3 deletions SEFramework/SEFramework/Source/SimpleSource.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** Copyright © 2019 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
/**
* Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
Expand All @@ -24,8 +25,9 @@
#ifndef _SEFRAMEWORK_SOURCE_SIMPLESOURCE_H_
#define _SEFRAMEWORK_SOURCE_SIMPLESOURCE_H_

#include "SEFramework/Source/SourceInterface.h"
#include "AlexandriaKernel/memory_tools.h"
#include "SEFramework/Property/PropertyHolder.h"
#include "SEFramework/Source/SourceInterface.h"

namespace SourceXtractor {

Expand Down Expand Up @@ -54,6 +56,18 @@ class SimpleSource : public SourceInterface {
/// Constructor
SimpleSource() {}

std::unique_ptr<SourceInterface> clone() const override {
auto cloned = Euclid::make_unique<SimpleSource>();
cloned->m_property_holder.update(m_property_holder);
return std::move(cloned);
}

void visitProperties(const PropertyVisitor& visitor) override {
std::for_each(
m_property_holder.begin(), m_property_holder.end(),
[visitor](const std::pair<PropertyId, std::shared_ptr<Property>>& prop) { visitor(prop.first, prop.second); });
}

// Note : Because the get/setProperty() methods of the SourceInterface are
// templated, the overrides of the non-templated versions will hide them. For
// this reason it is necessary to re-introduce the templated methods, which is
Expand All @@ -68,7 +82,7 @@ class SimpleSource : public SourceInterface {
return m_property_holder.getProperty(property_id);
}

void setProperty(std::unique_ptr<Property> property, const PropertyId& property_id) override {
void setProperty(std::shared_ptr<Property> property, const PropertyId& property_id) override {
m_property_holder.setProperty(std::move(property), property_id);
}

Expand Down
9 changes: 7 additions & 2 deletions SEFramework/SEFramework/Source/SimpleSourceGroup.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** Copyright © 2019 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
/**
* Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
Expand Down Expand Up @@ -62,14 +63,18 @@ class SimpleSourceGroup : public SourceGroupInterface {

void merge(SourceGroupInterface&& other) override;

std::unique_ptr<SourceInterface> clone() const override;

void visitProperties(const PropertyVisitor& visitor) override;

using SourceInterface::getProperty;
using SourceInterface::setProperty;

protected:

const Property& getProperty(const PropertyId& property_id) const override;

void setProperty(std::unique_ptr<Property> property, const PropertyId& property_id) override;
void setProperty(std::shared_ptr<Property> property, const PropertyId& property_id) override;

private:

Expand Down
17 changes: 14 additions & 3 deletions SEFramework/SEFramework/Source/SourceGroupInterface.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
/**
* Copyright © 2019-2022 Université de Genève, LMU Munich - Faculty of Physics, IAP-CNRS/Sorbonne Université
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
Expand All @@ -23,6 +24,7 @@
#define _SEFRAMEWORK_SOURCEGROUPINTERFACE_H

#include "SEFramework/Source/SourceInterface.h"
#include "AlexandriaKernel/memory_tools.h"

namespace SourceXtractor {

Expand All @@ -34,7 +36,7 @@ namespace SourceXtractor {
*
*/

class SourceGroupInterface : protected SourceInterface {
class SourceGroupInterface : public SourceInterface {

template <typename Collection>
using CollectionType = typename std::iterator_traits<typename Collection::iterator>::value_type;
Expand All @@ -54,10 +56,18 @@ class SourceGroupInterface : protected SourceInterface {
return m_source->getProperty(property_id);
}

void setProperty(std::unique_ptr<Property> property, const PropertyId& property_id) override {
void setProperty(std::shared_ptr<Property> property, const PropertyId& property_id) override {
m_source->setProperty(std::move(property), property_id);
}

void visitProperties(const PropertyVisitor& visitor) override {
m_source->visitProperties(visitor);
}

std::unique_ptr<SourceInterface> clone() const override {
return Euclid::make_unique<SourceWrapper>(m_source->clone());
}

bool operator<(const SourceWrapper& other) const {
return this->m_source < other.m_source;
}
Expand Down Expand Up @@ -107,6 +117,7 @@ class SourceGroupInterface : protected SourceInterface {
using SourceInterface::getProperty;
using SourceInterface::setProperty;
using SourceInterface::setIndexedProperty;
using SourceInterface::clone;

}; // end of SourceGroupInterface class

Expand Down
Loading