mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-13 07:47:13 +02:00
add python bindings
This commit is contained in:
@ -35,6 +35,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
|
|
||||||
option(USE_SANITIZER "Sanitizers for debugging" ON)
|
option(USE_SANITIZER "Sanitizers for debugging" ON)
|
||||||
option(DISABLE_WARNINGS "Disbale compilation warnings" OFF)
|
option(DISABLE_WARNINGS "Disbale compilation warnings" OFF)
|
||||||
|
option(USE_PYTHON "Build python bindings" ON)
|
||||||
|
|
||||||
|
|
||||||
set(OPTIONAL_FLAGS "")
|
set(OPTIONAL_FLAGS "")
|
||||||
@ -46,49 +47,33 @@ if(USE_SANITIZER)
|
|||||||
set(OPTIONAL_FLAGS "${OPTIONAL_FLAGS} -fdiagnostics-parseable-fixits -fdiagnostics-generate-patch -fdiagnostics-show-template-tree -fsanitize=address,undefined,pointer-compare -fno-sanitize-recover -D_FORTIFY_SOURCE=2 -fstack-protector -fno-omit-frame-pointer ")
|
set(OPTIONAL_FLAGS "${OPTIONAL_FLAGS} -fdiagnostics-parseable-fixits -fdiagnostics-generate-patch -fdiagnostics-show-template-tree -fsanitize=address,undefined,pointer-compare -fno-sanitize-recover -D_FORTIFY_SOURCE=2 -fstack-protector -fno-omit-frame-pointer ")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# if(TUNE_LOCAL)
|
|
||||||
# if(UNIX AND NOT APPLE)
|
|
||||||
# message(STATUS "unix")
|
|
||||||
# set(ARCH_FLAGS )
|
|
||||||
# target_compile_options(project_options INTERFACE -mtune=native -march=native )
|
|
||||||
# elseif(APPLE)
|
|
||||||
# message(STATUS "compiling for apple")
|
|
||||||
# target_compile_options(project_options INTERFACE -mtune=apple-m1 -mcpu=apple-m1 )
|
|
||||||
# endif()
|
|
||||||
# #
|
|
||||||
# endif()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
include(CheckIPOSupported)
|
|
||||||
check_ipo_supported(RESULT LTO_AVAILABLE)
|
|
||||||
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND LTO_AVAILABLE)
|
|
||||||
message(STATUS "Building with link time optimization")
|
|
||||||
else()
|
|
||||||
message(STATUS "Building without link time optimization")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(SUPPRESSED_WARNINGS "-Wno-return-type")
|
set(SUPPRESSED_WARNINGS "-Wno-return-type")
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${OPTIONAL_FLAGS} ${OPTIMIZATION_FLAGS} ${SUPPRESSED_WARNINGS}")
|
set(CMAKE_CXX_FLAGS "${OPTIMIZATION_FLAGS} ${SUPPRESSED_WARNINGS}")
|
||||||
|
|
||||||
|
if(USE_PYTHON)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||||
|
endif(USE_PYTHON)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_library(aare INTERFACE)
|
add_library(aare INTERFACE)
|
||||||
|
|
||||||
# target_link_libraries( aare
|
|
||||||
# PRIVATE
|
|
||||||
# nlohmann_json::nlohmann_json
|
|
||||||
# PUBLIC
|
|
||||||
# fmt::fmt
|
|
||||||
# )
|
|
||||||
|
|
||||||
target_link_libraries(aare INTERFACE common core file_io)
|
target_link_libraries(aare INTERFACE common core file_io)
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
|
target_link_libraries(example PUBLIC aare)
|
||||||
|
|
||||||
|
if(USE_PYTHON)
|
||||||
|
find_package (Python 3.11 COMPONENTS Interpreter Development)
|
||||||
|
find_package(pybind11 2.11 REQUIRED)
|
||||||
|
add_subdirectory(python)
|
||||||
|
target_link_libraries(_aare PRIVATE aare nlohmann_json::nlohmann_json fmt::fmt)
|
||||||
|
endif()
|
@ -2,6 +2,5 @@ add_executable(example "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp")
|
|||||||
|
|
||||||
target_include_directories(example PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
target_include_directories(example PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
target_link_libraries(example PUBLIC aare)
|
|
||||||
|
|
||||||
|
|
||||||
|
1
python/CMakeLists.txt
Normal file
1
python/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
pybind11_add_module(_aare src/bindings.cpp)
|
57
python/aare/File.py
Normal file
57
python/aare/File.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import json
|
||||||
|
from typing import Any
|
||||||
|
import _aare
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class File:
|
||||||
|
"""
|
||||||
|
File class. uses proxy pattern to wrap around the pybinding class
|
||||||
|
abstracts the python binding class that is requires type and detector information
|
||||||
|
(e.g. _FileHandler_Jungfrau_16)
|
||||||
|
"""
|
||||||
|
def __init__(self, path):
|
||||||
|
"""
|
||||||
|
opens the master file and checks the dynamic range and detector
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.path = path
|
||||||
|
# check if file exists
|
||||||
|
if not os.path.exists(path):
|
||||||
|
raise FileNotFoundError(f"File not found: {path}")
|
||||||
|
ext = os.path.splitext(path)[1]
|
||||||
|
|
||||||
|
if ext not in (".raw", ".json"):
|
||||||
|
raise ValueError(f"Invalid file extension: {ext}")
|
||||||
|
|
||||||
|
if ext == ".json":
|
||||||
|
# read the master file and get the detector and bitdepth
|
||||||
|
master_data = json.load(open(path))
|
||||||
|
detector = master_data["Detector Type"]
|
||||||
|
bitdepth = None
|
||||||
|
if 'Dynamic Range' not in master_data and detector == "Jungfrau":
|
||||||
|
bitdepth = 16
|
||||||
|
else:
|
||||||
|
bitdepth = master_data["Dynamic Range"]
|
||||||
|
else:
|
||||||
|
NotImplementedError("Raw file not implemented yet")
|
||||||
|
|
||||||
|
# class_name is of the form _FileHandler_Jungfrau_16...
|
||||||
|
class_name = f"_FileHandler_{detector}_{bitdepth}"
|
||||||
|
|
||||||
|
# this line is the equivalent of:
|
||||||
|
# self._file = _FileHandler_Jungfrau_16(path)
|
||||||
|
self._file = getattr(_aare, class_name)(path)
|
||||||
|
|
||||||
|
|
||||||
|
def __getattribute__(self, __name: str) -> Any:
|
||||||
|
"""
|
||||||
|
Proxy pattern to call the methods of the _file
|
||||||
|
"""
|
||||||
|
return getattr(object.__getattribute__(self, "_file"), __name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
16
python/aare/Frame.py
Normal file
16
python/aare/Frame.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
class Frame:
|
||||||
|
"""
|
||||||
|
Frame class. uses proxy pattern to wrap around the pybinding class
|
||||||
|
the intention behind it is to only use one class for frames in python (not Frame_8, Frame_16, etc)
|
||||||
|
"""
|
||||||
|
def __init__(self, frameImpl):
|
||||||
|
self._frameImpl = frameImpl
|
||||||
|
def __getattribute__(self, __name: str) -> Any:
|
||||||
|
"""
|
||||||
|
Proxy pattern to call the methods of the frameImpl
|
||||||
|
"""
|
||||||
|
return getattr(object.__getattribute__(self, "_frameImpl"), __name)
|
||||||
|
|
3
python/aare/__init__.py
Normal file
3
python/aare/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from _aare import *
|
||||||
|
from .Frame import Frame
|
||||||
|
from .File import File
|
0
python/example/__init__.py
Normal file
0
python/example/__init__.py
Normal file
7
python/example/read_frame.py
Normal file
7
python/example/read_frame.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from aare import File, Frame
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
file = File("/home/bb/github/aare/data/jungfrau_single_master_0.json")
|
||||||
|
frame = file.get_frame(0)
|
||||||
|
print(frame.rows, frame.cols)
|
||||||
|
print(frame.get(0,0))
|
41
python/src/bindings.cpp
Normal file
41
python/src/bindings.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "common/defs.hpp"
|
||||||
|
#include "core/Frame.hpp"
|
||||||
|
#include "file_io/FileHandler.hpp"
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
|
||||||
|
PYBIND11_MODULE(_aare, m) {
|
||||||
|
// helps to convert from std::string to std::filesystem::path
|
||||||
|
py::class_<std::filesystem::path>(m, "Path")
|
||||||
|
.def(py::init<std::string>());
|
||||||
|
py::implicitly_convertible<std::string, std::filesystem::path>();
|
||||||
|
|
||||||
|
//TODO: find a solution to avoid code duplication and include other detectors
|
||||||
|
py::class_<FileHandler<DetectorType::Jungfrau, uint16_t>>(m, "_FileHandler_Jungfrau_16")
|
||||||
|
.def(py::init<std::filesystem::path>())
|
||||||
|
.def("get_frame", &FileHandler<DetectorType::Jungfrau, uint16_t>::get_frame);
|
||||||
|
|
||||||
|
|
||||||
|
py::enum_<DetectorType>(m, "DetectorType");
|
||||||
|
|
||||||
|
py::class_<Frame<uint16_t>>(m, "_Frame16")
|
||||||
|
.def(py::init<std::byte*, ssize_t, ssize_t>())
|
||||||
|
.def("get", &Frame<uint16_t>::get)
|
||||||
|
.def_readonly("rows", &Frame<uint16_t>::rows)
|
||||||
|
.def_readonly("cols", &Frame<uint16_t>::cols)
|
||||||
|
.def_readonly("bitdepth", &Frame<uint16_t>::bitdepth);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,27 +1,19 @@
|
|||||||
#include "file_io/JsonFile.hpp"
|
#include "file_io/JsonFile.hpp"
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
template <DetectorType detector,typename DataType>
|
template <DetectorType detector, typename DataType>
|
||||||
Frame<DataType>* JsonFile<detector,DataType>::get_frame(int frame_number){
|
Frame<DataType> *JsonFile<detector, DataType>::get_frame(int frame_number) {
|
||||||
int subfile_id=frame_number/this->max_frames_per_file;
|
int subfile_id = frame_number / this->max_frames_per_file;
|
||||||
std::byte* buffer;
|
std::byte *buffer;
|
||||||
size_t frame_size = this->subfiles[subfile_id]->bytes_per_frame();
|
size_t frame_size = this->subfiles[subfile_id]->bytes_per_frame();
|
||||||
buffer = new std::byte[frame_size];
|
buffer = new std::byte[frame_size];
|
||||||
|
|
||||||
this->subfiles[subfile_id]->get_frame(buffer, frame_number%this->max_frames_per_file);
|
this->subfiles[subfile_id]->get_frame(buffer, frame_number % this->max_frames_per_file);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto f = new Frame<DataType>(buffer, this->rows, this->cols);
|
auto f = new Frame<DataType>(buffer, this->rows, this->cols);
|
||||||
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
return f;
|
return f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template class JsonFile<DetectorType::Jungfrau, uint16_t>;
|
template class JsonFile<DetectorType::Jungfrau, uint16_t>;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user