Projects
domecam:swift
domecam
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 28
View file
domecam.changes
Changed
@@ -1,4 +1,14 @@ ------------------------------------------------------------------- +Fri Sep 22 08:58:17 UTC 2023 - Matwey V. Kornilov <matwey@sai.msu.ru> + +- Version 0.1.14 + +------------------------------------------------------------------- +Wed Feb 15 12:41:25 UTC 2023 - Matwey V. Kornilov <matwey@sai.msu.ru> + +- Version 0.1.13 + +------------------------------------------------------------------- Mon Nov 7 07:50:45 UTC 2022 - Matwey V. Kornilov <matwey@sai.msu.ru> - Version 0.1.12
View file
domecam.spec
Changed
@@ -1,7 +1,7 @@ # # spec file for package domecam # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -63,7 +63,7 @@ %build %sysusers_generate_pre %{SOURCE1} domecamd domecamd-user.conf -%cmake +%cmake -DBUILD_DOMECAM_PROC:BOOL=OFF %cmake_build %install
View file
_service
Changed
@@ -3,7 +3,7 @@ <param name="url">http://curl.sai.msu.ru/hg/home/matwey/domecam/</param> <param name="scm">hg</param> <param name="versionformat">{latesttag}</param> - <param name="revision">0.1.12</param> + <param name="revision">0.1.14</param> </service> <service name="tar" mode="buildtime" /> <service name="recompress" mode="buildtime">
View file
domecam-0.1.12.obscpio/exe/carriage.cpp
Deleted
@@ -1,285 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0-or-later - * - * Copyright (C) 2017-2022 Matwey V. Kornilov <matwey.kornilov@gmail.com> - */ - -#include <atomic> -#include <iomanip> -#include <iostream> -#include <optional> -#include <string> -#include <thread> - -#include <application.h> -#include <carriage.h> -#include <executor.h> -#include <io.h> - -class application: public abstract_application { -public: - application(); - ~application() override; -protected: - int do_run(const boost::program_options::variables_map& va) override; - int do_run(const boost::program_options::variables_map& va, abstract_carriage& c); -public: - static constexpr const char home_opt = "home"; - static constexpr const char mask_opt = "mask"; - static constexpr const char data_opt = "data"; - static constexpr const char axis_opt = "axis"; - static constexpr const char run_opt = "run"; - static constexpr const char track_opt = "track"; - static constexpr const char speed_opt = "speed"; - static constexpr const char camera_opt = "camera"; - static constexpr const char device_opt = "device"; -}; - -constexpr const char application::home_opt; -constexpr const char application::mask_opt; -constexpr const char application::data_opt; -constexpr const char application::axis_opt; -constexpr const char application::run_opt; -constexpr const char application::track_opt; -constexpr const char application::speed_opt; -constexpr const char application::camera_opt; -constexpr const char application::device_opt; - -class carriage_mask_executor: public carriage_executor { -private: - class runner: public carriage_executor::runner { - private: - std::uint16_t mask_; - public: - runner(const carriage_mask_executor& e, abstract_carriage& c); - - void run(); - }; -public: - explicit carriage_mask_executor(std::uint16_t mask); - - virtual executor_result run(abstract_carriage& c) const override; -private: - std::uint16_t mask_; -}; - -class carriage_data_executor: public carriage_executor { -private: - class runner: public carriage_executor::runner { - private: - std::uint16_t data_; - public: - runner(const carriage_data_executor& e, abstract_carriage& c); - - void run(); - }; -public: - explicit carriage_data_executor(std::uint16_t data); - - virtual executor_result run(abstract_carriage& c) const override; -private: - std::uint16_t data_; -}; - -class carriage_axis_executor: public carriage_executor { -private: - class runner: public carriage_executor::runner { - private: - std::uint16_t axis_; - public: - runner(const carriage_axis_executor& e, abstract_carriage& c); - - void run(); - }; -public: - explicit carriage_axis_executor(std::uint16_t axis); - - virtual executor_result run(abstract_carriage& c) const override; -private: - std::uint16_t axis_; -}; - -class carriage_speed_executor: public carriage_executor { -private: - class runner: public carriage_executor::runner { - private: - std::uint16_t speed_; - public: - runner(const carriage_speed_executor& e, abstract_carriage& c); - - void run(); - }; -public: - explicit carriage_speed_executor(std::uint16_t speed); - - virtual executor_result run(abstract_carriage& c) const override; -private: - std::uint16_t speed_; -}; - -application::application(): abstract_application() { - namespace po = boost::program_options; - - opts_.add_options() - (home_opt, "Home carriage") - (mask_opt, po::value<std::uint16_t>(), "Synchro mask") - (data_opt, po::value<std::uint16_t>(), "User data") - (axis_opt, po::value<std::uint16_t>(), "Set motion axis") - (run_opt, po::value<std::int16_t>(), "Run absolute position") - (track_opt, "Run tracking motion CW") - (speed_opt, po::value<std::uint16_t>(), "Load running speed") - (camera_opt, po::value<std::string>(), "Camera name (GigE is used)") - (device_opt, po::value<std::string>(), "Termios device path (RS232 is used)") - ; -} - -application::~application() = default; - -int application::do_run(const boost::program_options::variables_map& va) { - if (va.count(device_opt)) { - const auto filename = vadevice_opt.as<std::string>(); - - termios_carriage c{filename}; - - std::cerr << "Device: " << filename << std::endl; - - return do_run(va, c); - } else { - camera camera_{va.count(camera_opt) ? vacamera_opt.as<std::string>().c_str() : nullptr}; - - std::cerr << "Device Id: " << camera_.device_id() << std::endl; - std::cerr << "Vendor Id: " << camera_.vendor_id() << std::endl; - std::cerr << "Model: " << camera_.model_name() << std::endl << std::endl; - - carriage c{camera_}; - - return do_run(va, c); - } - - return 0; -} - -int application::do_run(const boost::program_options::variables_map& va, abstract_carriage& c) { - const auto axis = (va.count(axis_opt) ? std::optional{vaaxis_opt.as<std::uint16_t>()} : std::nullopt); - - if (va.count(home_opt)) { - carriage_home_executor executor_(axis); - executor_.run(c); - } else if (va.count(run_opt)) { - carriage_run_executor executor_(axis, varun_opt.as<std::int16_t>()); - executor_.run(c); - } else if (va.count(track_opt)) { - carriage_track_executor executor_(axis, carriage::direction::cw); - executor_.run(c); - } else if (va.count(mask_opt)) { - carriage_mask_executor executor_(vamask_opt.as<std::uint16_t>()); - executor_.run(c); - } else if (va.count(data_opt)) { - carriage_data_executor executor_(vadata_opt.as<std::uint16_t>()); - executor_.run(c); - } else if (va.count(axis_opt)) { - carriage_axis_executor executor_(vaaxis_opt.as<std::uint16_t>()); - executor_.run(c); - } else if (va.count(speed_opt)) { - carriage_speed_executor executor_(vaspeed_opt.as<std::uint16_t>()); - executor_.run(c); - } else { - carriage_executor executor_; - executor_.run(c); - } - - return 0; -} - -carriage_mask_executor::carriage_mask_executor(std::uint16_t mask): - carriage_executor(), - mask_(mask) { -} - -executor_result carriage_mask_executor::run(abstract_carriage& c) const {
View file
domecam-0.1.12.obscpio/.hgtags -> domecam-0.1.14.obscpio/.hgtags
Changed
@@ -10,3 +10,5 @@ 5bde06ef6c04b0a814e8bf9455fcccbda5b90cc8 0.1.9 8e899284f1aef2a9916b0b0c75e182256db68365 0.1.10 93fde07957df3453d10555f403039c3b02e27df3 0.1.11 +f6f2cf7fc69c4b8853498a5242763da583ee9ca9 0.1.12 +5dcf5bbc11e401e323d3faa68458878bfc6052b9 0.1.13
View file
domecam-0.1.12.obscpio/CMakeLists.txt -> domecam-0.1.14.obscpio/CMakeLists.txt
Changed
@@ -1,9 +1,14 @@ cmake_minimum_required (VERSION 3.5) -project(domecam LANGUAGES C CXX VERSION 0.1.12) +project(domecam LANGUAGES C CXX VERSION 0.1.14) + +option(BUILD_DOMECAMD "build domecamd" ON) +option(BUILD_DOMECAM_PROC "build domecam-proc" ON) +option(BUILD_TEST "build test" ON) set(CMAKE_CXX_STANDARD 17) include(GNUInstallDirs) +include(CheckIncludeFileCXX) # CheckIPOSupported module is available since 3.9 # VERSION_GREATER_EQUAL is available since 3.7 @@ -20,7 +25,6 @@ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3 -ffast-math") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DNDEBUG -Os -ffast-math") -find_package(amqpcpp) find_package(Boost ${BOOST_REQUIRED_VERSION} COMPONENTS container REQUIRED filesystem REQUIRED @@ -31,11 +35,12 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(ARAVIS REQUIRED IMPORTED_TARGET aravis-0.8) pkg_check_modules(CFITSIO REQUIRED IMPORTED_TARGET cfitsio) -pkg_check_modules(CPPUNIT REQUIRED IMPORTED_TARGET cppunit) pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl) # float version of FFTW3 pkg_check_modules(FFTW3F REQUIRED IMPORTED_TARGET fftw3f) +CHECK_INCLUDE_FILE_CXX(termios.h HAVE_TERMIOS) + include_directories("${PROJECT_SOURCE_DIR}/include") file(GLOB_RECURSE SOURCES src/*.cpp) @@ -46,44 +51,20 @@ set_property(TARGET domecam PROPERTY INTERPROCEDURAL_OPTIMIZATION True) endif(HAS_LTO_SUPPORT) -enable_testing() -file(GLOB_RECURSE TESTS test/*.cpp) -foreach(test_source IN ITEMS ${TESTS}) - string(REPLACE ${CMAKE_SOURCE_DIR}/ "" test_name ${test_source}) - string(REPLACE / _ test_name ${test_name}) - string(REPLACE .cpp "" test_name ${test_name}) - add_executable(${test_name} ${test_source}) - target_link_libraries(${test_name} domecam PkgConfig::CPPUNIT Threads::Threads) - if(HAS_LTO_SUPPORT) - set_property(TARGET ${test_name} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) - endif(HAS_LTO_SUPPORT) - add_test(${test_name} ${test_name}) -endforeach(test_source) - -file(GLOB EXECS exe/*.cpp) -foreach(exe_source IN ITEMS ${EXECS}) - get_filename_component(exe_name ${exe_source} NAME_WE) - set(target_name "${exe_name}-exe") - add_executable(${target_name} ${exe_source}) - set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${exe_name}) - target_link_libraries(${target_name} domecam) - if(HAS_LTO_SUPPORT) - set_property(TARGET ${target_name} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) - endif(HAS_LTO_SUPPORT) - - install(TARGETS ${target_name} DESTINATION ${CMAKE_INSTALL_BINDIR}) -endforeach(exe_source) - -if(TARGET amqpcpp) - file(GLOB_RECURSE DOMECAMD_SOURCES exe/domecamd/*.cpp) - add_executable(domecamd-exe ${DOMECAMD_SOURCES}) - set_target_properties(domecamd-exe PROPERTIES OUTPUT_NAME domecamd) - target_link_libraries(domecamd-exe domecam amqpcpp) - if(HAS_LTO_SUPPORT) - set_property(TARGET domecamd-exe PROPERTY INTERPROCEDURAL_OPTIMIZATION True) - endif(HAS_LTO_SUPPORT) - - install(TARGETS domecamd-exe DESTINATION ${CMAKE_INSTALL_BINDIR}) -else() - message(WARNING "libamqpcpp not found, so domecamd disabled") +if(BUILD_TEST) + enable_testing() + add_subdirectory(test) +endif() + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +add_subdirectory(exe/carriage) +add_subdirectory(exe/serial_io) +add_subdirectory(exe/domecam) +add_subdirectory(exe/domecam-replay) +if(BUILD_DOMECAMD) +add_subdirectory(exe/domecamd) +endif() +if(BUILD_DOMECAM_PROC) +add_subdirectory(exe/domecam-proc) endif()
View file
domecam-0.1.14.obscpio/exe/carriage
Added
+(directory)
View file
domecam-0.1.14.obscpio/exe/carriage/CMakeLists.txt
Added
@@ -0,0 +1,24 @@ +cmake_minimum_required (VERSION 3.5) + +set(CMAKE_CXX_STANDARD 17) + +include(GNUInstallDirs) + +# CheckIPOSupported module is available since 3.9 +# VERSION_GREATER_EQUAL is available since 3.7 +if(NOT (CMAKE_VERSION VERSION_LESS "3.9.0")) + # check_ipo_supported() returns an error when CMP0069 is OLD + cmake_policy(SET CMP0069 NEW) + + include(CheckIPOSupported) + check_ipo_supported(RESULT HAS_LTO_SUPPORT) +endif() + +add_executable(carriage-exe carriage.cpp) +set_target_properties(carriage-exe PROPERTIES OUTPUT_NAME carriage) +target_link_libraries(carriage-exe domecam) +if(HAS_LTO_SUPPORT) + set_property(TARGET carriage-exe PROPERTY INTERPROCEDURAL_OPTIMIZATION True) +endif(HAS_LTO_SUPPORT) + +install(TARGETS carriage-exe DESTINATION ${CMAKE_INSTALL_BINDIR})
View file
domecam-0.1.14.obscpio/exe/carriage/carriage.cpp
Added
@@ -0,0 +1,286 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2022 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#include <atomic> +#include <iomanip> +#include <iostream> +#include <optional> +#include <string> +#include <thread> + +#include <application.h> +#include <carriage.h> +#include <executor.h> +#include <io.h> + +class application: public abstract_application { +public: + application(); + ~application() override; +protected: + int do_run(const boost::program_options::variables_map& va) override; + int do_run(const boost::program_options::variables_map& va, abstract_carriage& c); +public: + static constexpr const char home_opt = "home"; + static constexpr const char mask_opt = "mask"; + static constexpr const char data_opt = "data"; + static constexpr const char axis_opt = "axis"; + static constexpr const char run_opt = "run"; + static constexpr const char track_opt = "track"; + static constexpr const char speed_opt = "speed"; + static constexpr const char camera_opt = "camera"; + static constexpr const char device_opt = "device"; +}; + +constexpr const char application::home_opt; +constexpr const char application::mask_opt; +constexpr const char application::data_opt; +constexpr const char application::axis_opt; +constexpr const char application::run_opt; +constexpr const char application::track_opt; +constexpr const char application::speed_opt; +constexpr const char application::camera_opt; +constexpr const char application::device_opt; + +class carriage_mask_executor: public carriage_executor { +private: + class runner: public carriage_executor::runner { + private: + std::uint16_t mask_; + public: + runner(const carriage_mask_executor& e, abstract_carriage& c); + + void run(); + }; +public: + explicit carriage_mask_executor(std::uint16_t mask); + + virtual executor_result run(abstract_carriage& c) const override; +private: + std::uint16_t mask_; +}; + +class carriage_data_executor: public carriage_executor { +private: + class runner: public carriage_executor::runner { + private: + std::uint16_t data_; + public: + runner(const carriage_data_executor& e, abstract_carriage& c); + + void run(); + }; +public: + explicit carriage_data_executor(std::uint16_t data); + + virtual executor_result run(abstract_carriage& c) const override; +private: + std::uint16_t data_; +}; + +class carriage_axis_executor: public carriage_executor { +private: + class runner: public carriage_executor::runner { + private: + std::uint16_t axis_; + public: + runner(const carriage_axis_executor& e, abstract_carriage& c); + + void run(); + }; +public: + explicit carriage_axis_executor(std::uint16_t axis); + + virtual executor_result run(abstract_carriage& c) const override; +private: + std::uint16_t axis_; +}; + +class carriage_speed_executor: public carriage_executor { +private: + class runner: public carriage_executor::runner { + private: + std::uint16_t speed_; + public: + runner(const carriage_speed_executor& e, abstract_carriage& c); + + void run(); + }; +public: + explicit carriage_speed_executor(std::uint16_t speed); + + virtual executor_result run(abstract_carriage& c) const override; +private: + std::uint16_t speed_; +}; + +application::application(): abstract_application() { + namespace po = boost::program_options; + + opts_.add_options() + (home_opt, "Home carriage") + (mask_opt, po::value<std::uint16_t>(), "Synchro mask") + (data_opt, po::value<std::uint16_t>(), "User data") + (axis_opt, po::value<std::uint16_t>(), "Set motion axis") + (run_opt, po::value<std::int16_t>(), "Run absolute position") + (track_opt, "Run tracking motion CW") + (speed_opt, po::value<std::uint16_t>(), "Load running speed") + (camera_opt, po::value<std::string>(), "Camera name (GigE is used)") + (device_opt, po::value<std::string>(), "Termios device path (RS232 is used)") + ; +} + +application::~application() = default; + +int application::do_run(const boost::program_options::variables_map& va) { + if (va.count(device_opt)) { + const auto filename = vadevice_opt.as<std::string>(); + + termios_carriage c{filename}; + + std::cerr << "Device: " << filename << std::endl; + + return do_run(va, c); + } else { + camera camera_{va.count(camera_opt) ? vacamera_opt.as<std::string>().c_str() : nullptr}; + + std::cerr << "Device Id: " << camera_.device_id() << std::endl; + std::cerr << "Vendor Id: " << camera_.vendor_id() << std::endl; + std::cerr << "Model: " << camera_.model_name() << std::endl << std::endl; + + carriage c{camera_}; + + return do_run(va, c); + } + + return 0; +} + +int application::do_run(const boost::program_options::variables_map& va, abstract_carriage& c) { + const auto axis = (va.count(axis_opt) ? std::optional{vaaxis_opt.as<std::uint16_t>()} : std::nullopt); + const auto speed = (va.count(speed_opt) ? std::optional{vaspeed_opt.as<std::uint16_t>()} : std::nullopt); + + if (va.count(home_opt)) { + carriage_home_executor executor_(axis, speed); + executor_.run(c); + } else if (va.count(track_opt)) { + carriage_track_executor executor_(axis, speed, carriage::direction::cw); + executor_.run(c); + } else if (va.count(run_opt)) { + carriage_run_executor executor_(axis, varun_opt.as<std::int16_t>()); + executor_.run(c); + } else if (va.count(mask_opt)) { + carriage_mask_executor executor_(vamask_opt.as<std::uint16_t>()); + executor_.run(c); + } else if (va.count(data_opt)) { + carriage_data_executor executor_(vadata_opt.as<std::uint16_t>()); + executor_.run(c); + } else if (va.count(axis_opt)) { + carriage_axis_executor executor_(vaaxis_opt.as<std::uint16_t>()); + executor_.run(c); + } else if (va.count(speed_opt)) { + carriage_speed_executor executor_(vaspeed_opt.as<std::uint16_t>()); + executor_.run(c); + } else { + carriage_executor executor_; + executor_.run(c); + } + + return 0; +} + +carriage_mask_executor::carriage_mask_executor(std::uint16_t mask): + carriage_executor(), + mask_(mask) { +} +
View file
domecam-0.1.14.obscpio/exe/domecam
Added
+(directory)
View file
domecam-0.1.14.obscpio/exe/domecam-proc
Added
+(directory)
View file
domecam-0.1.14.obscpio/exe/domecam-proc/CMakeLists.txt
Added
@@ -0,0 +1,35 @@ +cmake_minimum_required (VERSION 3.5) + +set(CMAKE_CXX_STANDARD 17) + +include(GNUInstallDirs) + +# CheckIPOSupported module is available since 3.9 +# VERSION_GREATER_EQUAL is available since 3.7 +if(NOT (CMAKE_VERSION VERSION_LESS "3.9.0")) + # check_ipo_supported() returns an error when CMP0069 is OLD + cmake_policy(SET CMP0069 NEW) + + include(CheckIPOSupported) + check_ipo_supported(RESULT HAS_LTO_SUPPORT) +endif() + + +find_package(PkgConfig REQUIRED) +pkg_check_modules(WEIF REQUIRED IMPORTED_TARGET weif) + + +if(TARGET PkgConfig::WEIF) + find_package(xtensor REQUIRED) + + add_executable(domecam-proc-exe main.cpp executor.cpp) + set_target_properties(domecam-proc-exe PROPERTIES OUTPUT_NAME domecam-proc) + target_link_libraries(domecam-proc-exe domecam xtensor PkgConfig::WEIF) + if(HAS_LTO_SUPPORT) + set_property(TARGET domecam-proc-exe PROPERTY INTERPROCEDURAL_OPTIMIZATION True) + endif(HAS_LTO_SUPPORT) + + install(TARGETS domecam-proc-exe DESTINATION ${CMAKE_INSTALL_BINDIR}) +else() + message(WARNING "libweif not found, so domecam-proc disabled") +endif()
View file
domecam-0.1.14.obscpio/exe/domecam-proc/executor.cpp
Added
@@ -0,0 +1,416 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2023 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#include <utility> + +#include <xtensor/xpad.hpp> +#include <xtensor/xslice.hpp> +#include <xtensor/xstrided_view.hpp> + +#include <exe/domecam-proc/executor.h> + +#include <weif/spectral_response.h> +#include <weif/af/circular.h> +#include <weif/af/square.h> + +#include <pupil_mask_acf.h> + + +namespace { + +template<class T> T digital_filter(T ux, T uy) noexcept { + using value_type = T; + + constexpr weif::af::square<value_type> square_af{}; + + const auto u2 = ux * ux + uy * uy; + + return std::pow(u2, static_cast<value_type>(5.0/6.0)) / square_af(ux, uy); +} + +} + + +proc_executor::proc_executor(const std::string& pupil_mask_filename): + pupil_mask_filename_{pupil_mask_filename} {} + +typename proc_executor::runner_base::buffer_type +proc_executor::runner_base::load_mask_acf(const std::string& source_uri, const region& roi) { + constexpr auto align = buffer_type::align; + using allocator_type = buffer_type::allocator_type; + + fits aux_fits{source_uri}; + const auto image_region = region::from_fits(aux_fits); + if (!roi.within(image_region)) + throw aux_image_incorrect_position{source_uri, roi.offset(), roi.size()}; + const auto proj_roi = roi.project(image_region); + + return aux_fits.load_image().apply(& (const auto& image) { + using value_type = typename std::decay_t<decltype(image)>::value_type; + + pupil_mask_acf<value_type, align, allocator_type> acf_{proj_roi.size()0, proj_roi.size()1}; + + // FIXME: return xtensor based on buffer_type + return acf_(image.template read_frame_range<align, allocator_type>(0, proj_roi.offset(), proj_roi.size())); + }); +} + + +void tag_invoke(boost::json::value_from_tag, boost::json::value& jv, const proc_executor_indices::runner_result& r) { + using boost::json::value_from; + + jv = {"indices", value_from(r.indices)}; +} + +std::ostream& operator<<(std::ostream& stm, const proc_executor_indices::runner_result& r) { + stm << "A\tAB\tB\tAC\tBC\tC\tAD\tBD\tCD\tD" << std::endl; + + for (const auto& x : r.indices) { + for (const auto& ind: x) { + stm << ind << "\t"; + } + + stm << std::endl; + } + + return stm; +} + +proc_executor_indices::proc_executor_indices(const std::string& pupil_mask_filename, float aperture_scale, float magnification): + proc_executor(pupil_mask_filename), + aperture_scale_{aperture_scale}, + magnification_{magnification} {} + +executor_result proc_executor_indices::run(const fits::variant_image& vi) const { + return vi.apply(runner_visitor<runner_type, proc_executor_indices, runner_result>{*this}); +} + + +void tag_invoke(boost::json::value_from_tag, boost::json::value& jv, const proc_executor_power::runner_result& r) { + using boost::json::value_from; + + jv = {"power", value_from(r.power)}; +} + +std::ostream& operator<<(std::ostream& stm, const proc_executor_power::runner_result& r) { + for (const auto& x : r.power) { + stm << x << std::endl; + } + + return stm; +} + +template<class E> +proc_executor_indices::runner_base::runner_base(const proc_executor_indices& e, const std::array<std::size_t, 2>& size, const xt::xexpression<E>& mask_acf): + weight_{std::array{static_cast<std::size_t>(10), size0, size1}, static_cast<value_type>(0)} { + + constexpr std::array mass_inner = {0.00f, 1.30f, 2.20f, 3.90f}; + constexpr std::array mass_outer = {1.27f, 2.15f, 3.85f, 5.50f}; + + assert(mass_inner.size() == mass_outer.size()); + + const auto impulse_shape = std::array{(size0 + size0 % 2) / 2, (size1 + size1 % 2) / 2}; + const auto mask_shape = mask_acf.derived_cast().shape(); + + const std::array weight_range0 = { + xt::xrange<std::size_t>(0, impulse_shape0), + xt::xrange<std::size_t>(weight_.shape()1 - (impulse_shape0 - 1), weight_.shape()1)}; + const std::array weight_range1 = { + xt::xrange<std::size_t>(0, impulse_shape1), + xt::xrange<std::size_t>(weight_.shape()2 - (impulse_shape1 - 1), weight_.shape()2)}; + + const std::array mask_range0 = { + xt::xrange<std::size_t>(0, impulse_shape0), + xt::xrange<std::size_t>(mask_shape0 - (impulse_shape0 - 1), mask_shape0)}; + const std::array mask_range1 = { + xt::xrange<std::size_t>(0, impulse_shape1), + xt::xrange<std::size_t>(mask_shape1 - (impulse_shape1 - 1), mask_shape1)}; + + const std::array impulse_range0 = { + xt::xstepped_range<std::ptrdiff_t>(0, impulse_shape0, 1), + xt::xstepped_range<std::ptrdiff_t>(impulse_shape0 - 1, 0, -1)}; + const std::array impulse_range1 = { + xt::xstepped_range<std::ptrdiff_t>(0, impulse_shape1, 1), + xt::xstepped_range<std::ptrdiff_t>(impulse_shape1 - 1, 0, -1)}; + + std::size_t m = 0; + for (std::size_t mi = 0; mi < mass_inner.size(); ++mi) { + const auto d1 = mass_outermi; + const auto eps1 = mass_innermi / mass_outermi; + const auto mass_scale = d1 * (e.magnification_ / e.aperture_scale_); + + for (std::size_t mj = 0; mj <= mi; ++mj, ++m) { + const auto d2 = mass_outermj; + const auto eps2 = mass_innermj / mass_outermj; + const weif::af::cross_annular mass_af{d2 / d1, eps1, eps2}; + + const weif::digital_filter_2d<value_type> df{mass_scale, &mass_af(value_type ux, value_type uy) noexcept { + constexpr weif::af::square<value_type> square_af{}; + + return mass_af(mass_scale * ux, mass_scale * uy) / square_af(ux, uy); + }, impulse_shape}; + + for (std::size_t i = 0; i < weight_range0.size(); ++i) { + for (std::size_t j = 0; j < weight_range1.size(); ++j) { + const auto src_mask = xt::view(mask_acf.derived_cast(), mask_range0i, mask_range1j); + const auto src_impulse = xt::view(df.impulse(), impulse_range0i, impulse_range1j); + + auto dst = xt::view(weight_, m, weight_range0i, weight_range1j); + + dst = xt::where(src_mask >= static_cast<value_type>(1), src_impulse / src_mask, xt::zeros<value_type>(dst.shape())); + } + } + } + } +} + +proc_executor_indices::runner_base::runner_base(const proc_executor_indices& e, const std::array<std::size_t, 2>& size, const buffer_type& mask_acf): + runner_base(e, std::array{size1, size0}, // width comes first in size + xt::adapt(mask_acf.data(), mask_acf.size(), xt::no_ownership(), std::array{size1 * 2, size0 * 2}, xt::layout_type::row_major)) {} + +proc_executor_indices::runner_base::runner_base(const proc_executor_indices& e, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size): + runner_base(e, size, + load_mask_acf(e.pupil_mask_filename_, region{offset, size})) {} + +template<class SourceMixin> +class proc_executor_indices::runner: + public SourceMixin, + private runner_base { +private: + using source_mixin = SourceMixin; + using source_type = typename source_mixin::source_type; + +public: + template<class Executor, class... Args> + runner(const Executor& e, Args&&... args): + source_mixin(e, std::forward<Args>(args)...), + runner_base(e, + {this->source().xoffset(), this->source().yoffset()}, + {this->source().width(), this->source().height()}) {} + + proc_executor_indices::runner_result run(); +}; + +template<class SourceMixin> +proc_executor_indices::runner_result proc_executor_indices::runner<SourceMixin>::run() { + using source_type = typename SourceMixin::source_type;
View file
domecam-0.1.14.obscpio/exe/domecam-proc/main.cpp
Added
@@ -0,0 +1,107 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2023 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#include <chrono> + +#include <application.h> + +#include <exe/domecam-proc/executor.h> + + +class application: public abstract_application { +public: + application(); + ~application() override; +protected: + int do_run(const boost::program_options::variables_map& va) override; +public: + static constexpr const char acf_filename_opt = "acf_filename"; + static constexpr const char mask_filename_opt = "mask_filename"; + static constexpr const char spectral_response_opt = "spectral_response"; + static constexpr const char aperture_scale_opt = "aperture_scale"; + static constexpr const char altitude_opt = "altitude"; + static constexpr const char magnification_opt = "magnification"; + static constexpr const char dome_opt = "dome"; + static constexpr const char free_opt = "free"; + static constexpr const char indices_opt = "indices"; +}; + +constexpr const char application::acf_filename_opt; +constexpr const char application::mask_filename_opt; +constexpr const char application::spectral_response_opt; +constexpr const char application::aperture_scale_opt; +constexpr const char application::altitude_opt; +constexpr const char application::magnification_opt; +constexpr const char application::dome_opt; +constexpr const char application::free_opt; +constexpr const char application::indices_opt; + + +application::application(): abstract_application() { + namespace po = boost::program_options; + + opts_.add_options() + (acf_filename_opt, po::value<std::string>()->required(), "Spatial cross-correlation input filename") + (mask_filename_opt, po::value<std::string>()->required(), "The pupil mask") + (spectral_response_opt, po::value<std::vector<std::string>>()->required(), "Spectral response alias name or filename") + (aperture_scale_opt, po::value<float>()->default_value(5.8), "Aperture scale in mm.") + (magnification_opt, po::value<float>()->default_value(16.20), "MASS magnification in mm./mm.") + (altitude_opt, po::value<float>()->default_value(2.0), "Altitude in km.") + (dome_opt, "Evaluate dome optical turbulence") + (free_opt, "Evaluate free atmosphere optical turbulence") + (indices_opt, "Evaluate MASS scintillation indices") + ; +} + +application::~application() = default; + +int application::do_run(const boost::program_options::variables_map& va) { + using duration = std::chrono::duration<double, std::chrono::seconds::period>; + + const auto& acf_filename = vaacf_filename_opt.as<std::string>(); + auto input = fits(acf_filename); + const auto vi = input.load_image(); + + std::cout << "Loaded: " << acf_filename << std::endl; + std::cout << "Format: " << vi.width() << " x " << vi.height() << " x " << vi.depth() << std::endl; + + const auto& mask_filename = vamask_filename_opt.as<std::string>(); + const auto aperture_scale = vaaperture_scale_opt.as<float>(); + const auto is_free = va.count(free_opt) != 0; + const auto is_indices = va.count(indices_opt) != 0; + + const auto time_begin = std::chrono::steady_clock::now(); + + if (is_indices) { + const auto magnification = vamagnification_opt.as<float>(); + + proc_executor_indices e(mask_filename, aperture_scale, magnification); + std::cerr << e.run(vi); + } else { + const auto& spectral_responses = vaspectral_response_opt.as<std::vector<std::string>>(); + const auto altitude = vaaltitude_opt.as<float>(); + + if (is_free) { + proc_executor_free e(mask_filename, spectral_responses, aperture_scale, altitude); + std::cerr << e.run(vi); + } else { // is_dome + proc_executor_dome e(mask_filename, spectral_responses, aperture_scale, altitude); + std::cerr << e.run(vi); + } + } + + const auto time_end = std::chrono::steady_clock::now(); + + std::cout << "Running time: " << std::chrono::duration_cast<duration>(time_end - time_begin).count() << " seconds" << std::endl; + std::cout << " " << vi.depth() / std::chrono::duration_cast<duration>(time_end - time_begin).count() << " fps" << std::endl; + + return 0; +} + +int main(int argc, char** argv) { + application app; + return app.run(argc, argv); +}
View file
domecam-0.1.14.obscpio/exe/domecam-replay
Added
+(directory)
View file
domecam-0.1.14.obscpio/exe/domecam-replay/CMakeLists.txt
Added
@@ -0,0 +1,24 @@ +cmake_minimum_required (VERSION 3.5) + +set(CMAKE_CXX_STANDARD 17) + +include(GNUInstallDirs) + +# CheckIPOSupported module is available since 3.9 +# VERSION_GREATER_EQUAL is available since 3.7 +if(NOT (CMAKE_VERSION VERSION_LESS "3.9.0")) + # check_ipo_supported() returns an error when CMP0069 is OLD + cmake_policy(SET CMP0069 NEW) + + include(CheckIPOSupported) + check_ipo_supported(RESULT HAS_LTO_SUPPORT) +endif() + +add_executable(domecam-replay-exe domecam-replay.cpp) +set_target_properties(domecam-replay-exe PROPERTIES OUTPUT_NAME domecam-replay) +target_link_libraries(domecam-replay-exe domecam) +if(HAS_LTO_SUPPORT) + set_property(TARGET domecam-replay-exe PROPERTY INTERPROCEDURAL_OPTIMIZATION True) +endif(HAS_LTO_SUPPORT) + +install(TARGETS domecam-replay-exe DESTINATION ${CMAKE_INSTALL_BINDIR})
View file
domecam-0.1.14.obscpio/exe/domecam-replay/domecam-replay.cpp
Changed
(renamed from exe/domecam-replay.cpp)
View file
domecam-0.1.14.obscpio/exe/domecam/CMakeLists.txt
Added
@@ -0,0 +1,24 @@ +cmake_minimum_required (VERSION 3.5) + +set(CMAKE_CXX_STANDARD 17) + +include(GNUInstallDirs) + +# CheckIPOSupported module is available since 3.9 +# VERSION_GREATER_EQUAL is available since 3.7 +if(NOT (CMAKE_VERSION VERSION_LESS "3.9.0")) + # check_ipo_supported() returns an error when CMP0069 is OLD + cmake_policy(SET CMP0069 NEW) + + include(CheckIPOSupported) + check_ipo_supported(RESULT HAS_LTO_SUPPORT) +endif() + +add_executable(domecam-exe domecam.cpp) +set_target_properties(domecam-exe PROPERTIES OUTPUT_NAME domecam) +target_link_libraries(domecam-exe domecam) +if(HAS_LTO_SUPPORT) + set_property(TARGET domecam-exe PROPERTY INTERPROCEDURAL_OPTIMIZATION True) +endif(HAS_LTO_SUPPORT) + +install(TARGETS domecam-exe DESTINATION ${CMAKE_INSTALL_BINDIR})
View file
domecam-0.1.14.obscpio/exe/domecam/domecam.cpp
Changed
(renamed from exe/domecam.cpp)
View file
domecam-0.1.14.obscpio/exe/domecamd/CMakeLists.txt
Added
@@ -0,0 +1,31 @@ +cmake_minimum_required (VERSION 3.5) + +set(CMAKE_CXX_STANDARD 17) + +include(GNUInstallDirs) + +# CheckIPOSupported module is available since 3.9 +# VERSION_GREATER_EQUAL is available since 3.7 +if(NOT (CMAKE_VERSION VERSION_LESS "3.9.0")) + # check_ipo_supported() returns an error when CMP0069 is OLD + cmake_policy(SET CMP0069 NEW) + + include(CheckIPOSupported) + check_ipo_supported(RESULT HAS_LTO_SUPPORT) +endif() + +find_package(amqpcpp) + +if(TARGET amqpcpp) + file(GLOB_RECURSE DOMECAMD_SOURCES *.cpp) + add_executable(domecamd-exe ${DOMECAMD_SOURCES}) + set_target_properties(domecamd-exe PROPERTIES OUTPUT_NAME domecamd) + target_link_libraries(domecamd-exe domecam amqpcpp) + if(HAS_LTO_SUPPORT) + set_property(TARGET domecamd-exe PROPERTY INTERPROCEDURAL_OPTIMIZATION True) + endif(HAS_LTO_SUPPORT) + + install(TARGETS domecamd-exe DESTINATION ${CMAKE_INSTALL_BINDIR}) +else() + message(WARNING "libamqpcpp not found, so domecamd disabled") +endif()
View file
domecam-0.1.14.obscpio/exe/serial_io
Added
+(directory)
View file
domecam-0.1.14.obscpio/exe/serial_io/CMakeLists.txt
Added
@@ -0,0 +1,24 @@ +cmake_minimum_required (VERSION 3.5) + +set(CMAKE_CXX_STANDARD 17) + +include(GNUInstallDirs) + +# CheckIPOSupported module is available since 3.9 +# VERSION_GREATER_EQUAL is available since 3.7 +if(NOT (CMAKE_VERSION VERSION_LESS "3.9.0")) + # check_ipo_supported() returns an error when CMP0069 is OLD + cmake_policy(SET CMP0069 NEW) + + include(CheckIPOSupported) + check_ipo_supported(RESULT HAS_LTO_SUPPORT) +endif() + +add_executable(serial_io-exe serial_io.cpp) +set_target_properties(serial_io-exe PROPERTIES OUTPUT_NAME serial_io) +target_link_libraries(serial_io-exe domecam) +if(HAS_LTO_SUPPORT) + set_property(TARGET serial_io-exe PROPERTY INTERPROCEDURAL_OPTIMIZATION True) +endif(HAS_LTO_SUPPORT) + +install(TARGETS serial_io-exe DESTINATION ${CMAKE_INSTALL_BINDIR})
View file
domecam-0.1.14.obscpio/exe/serial_io/serial_io.cpp
Changed
(renamed from exe/serial_io.cpp)
View file
domecam-0.1.14.obscpio/include/aux_image.h
Added
@@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2023 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#ifndef _AUX_IMAGE_H +#define _AUX_IMAGE_H + +#include <array> + +#include <fits.h> + + +struct region { + std::array<std::size_t, 2> offset_; + std::array<std::size_t, 2> size_; + + static region from_fits(const fits& f); + + bool within(const region& other) const noexcept; + bool contains(const region& other) const noexcept; + + const auto& offset() const noexcept { return offset_; } + const auto& size() const noexcept { return size_; } + + region project(const region& other) const noexcept; +}; + +#endif // _AUX_IMAGE_H
View file
domecam-0.1.12.obscpio/include/buffer.h -> domecam-0.1.14.obscpio/include/buffer.h
Changed
@@ -166,7 +166,7 @@ swap(*this, new_buffer); } inline void clear() noexcept { - std::memset(data_.get(), 0, sizeof(T) * size()); + std::memset(reinterpret_cast<void*>(data()), 0, sizeof(T) * size()); } inline const allocator_type& get_allocator() const noexcept { return data_.get_deleter().get_allocator(); }
View file
domecam-0.1.12.obscpio/include/camera.h -> domecam-0.1.14.obscpio/include/camera.h
Changed
@@ -17,12 +17,13 @@ #include <device.h> #include <error.h> +#include <fptr_deleter.h> class stream; class camera_object { protected: - std::unique_ptr<ArvCamera, decltype(&g_object_unref)> camera_; + std::unique_ptr<ArvCamera, fptr_deleter<&g_object_unref>> camera_; public: explicit camera_object(const char* name); };
View file
domecam-0.1.12.obscpio/include/carriage.h -> domecam-0.1.14.obscpio/include/carriage.h
Changed
@@ -127,6 +127,8 @@ } }; + constexpr static std::uint16_t default_speed = 144; + struct command { virtual serialized_type serialize() const = 0; virtual ~command() = 0;
View file
domecam-0.1.12.obscpio/include/curl.h -> domecam-0.1.14.obscpio/include/curl.h
Changed
@@ -29,6 +29,12 @@ class curl { private: struct global_init_guard; + struct deleter { + void operator() (CURL* ptr) const noexcept; + }; + struct list_deleter { + void operator() (struct curl_slist* ptr) const noexcept; + }; public: curl(); @@ -39,12 +45,10 @@ void append_header(const char* string); void perform(); private: - static void deleter(CURL* ptr); - static void list_deleter(struct curl_slist*); static CURL* do_init(); - std::unique_ptr<CURL, decltype(&deleter)> curl_; - std::unique_ptr<struct curl_slist, decltype(&list_deleter)> header_list_; + std::unique_ptr<CURL, deleter> curl_; + std::unique_ptr<struct curl_slist, list_deleter> header_list_; }; template<class T>
View file
domecam-0.1.12.obscpio/include/device.h -> domecam-0.1.14.obscpio/include/device.h
Changed
@@ -11,13 +11,15 @@ #include <memory> #include <arv.h> + #include <error.h> +#include <fptr_deleter.h> class stream; class device { private: - std::unique_ptr<ArvDevice, decltype(&g_object_unref)> device_; + std::unique_ptr<ArvDevice, fptr_deleter<&g_object_unref>> device_; protected: std::uint32_t reg(const std::uint32_t addr); void reg(const std::uint32_t addr, const std::uint32_t value);
View file
domecam-0.1.12.obscpio/include/error.h -> domecam-0.1.14.obscpio/include/error.h
Changed
@@ -15,6 +15,7 @@ #include <glib.h> // for GError +#include <fptr_deleter.h> struct error: public std::runtime_error { explicit error(const std::string& what); @@ -40,6 +41,10 @@ explicit too_many_edge_pixels(std::size_t s); }; +struct too_low_edge_to_noise_ratio: public validation_error { + explicit too_low_edge_to_noise_ratio(float ratio); +}; + struct singular_sample_set: public validation_error { singular_sample_set(); }; @@ -75,7 +80,7 @@ static auto apply_or_throw(U&& F, Args&&... args) -> decltype(F(std::forward<Args>(args)..., static_cast<GError**>(nullptr))); private: - std::unique_ptr<GError, void (*)(GError*)> error_; + std::unique_ptr<GError, fptr_deleter<&g_error_free>> error_; };
View file
domecam-0.1.14.obscpio/include/exe/domecam-proc
Added
+(directory)
View file
domecam-0.1.14.obscpio/include/exe/domecam-proc/executor.h
Added
@@ -0,0 +1,181 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2023 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#ifndef _EXE_DOMECAM_PROC_EXECUTOR_H +#define _EXE_DOMECAM_PROC_EXECUTOR_H + +#include <string> +#include <vector> +#include <utility> + +#include <boost/align/aligned_allocator.hpp> + +#include <xtensor/xexpression.hpp> +#include <xtensor/xtensor.hpp> + +#include <aux_image.h> +#include <executorfwd.h> + +#include <weif/digital_filter_2d.h> +#include <weif/spectral_filter.h> +#include <weif/weight_function_grid_2d.h> + + +class proc_executor: + public replay_executor { +protected: + class runner_base; + +public: + explicit proc_executor(const std::string& pupil_mask_filename); + + executor_result run(const fits::variant_image& vi) const override = 0; + +protected: + std::string pupil_mask_filename_; +}; + +struct proc_executor::runner_base { +protected: + template<class T> + using allocator_type_t = boost::alignment::aligned_allocator<T, 32>; + + template<class T> + using buffer_type_t = buffer<T, 32, allocator_type_t<T>>; + +public: + using value_type = float; + using buffer_type = buffer_type_t<value_type>; + +protected: + static buffer_type load_mask_acf(const std::string& source_uri, const region& roi); +}; + +class proc_executor_indices: + public proc_executor { +public: + struct runner_result; + +private: + class runner_base; + template<class SourceMixin> class runner; + template<class T> using runner_type = runner<source_mixin<T>>; + +public: + proc_executor_indices(const std::string& pupil_mask_filename, float aperture_scale, float magnification); + + executor_result run(const fits::variant_image& vi) const override; + +private: + float aperture_scale_; + float magnification_; +}; + +struct proc_executor_indices::runner_result { + using value_type = float; + using indices_type = std::array<value_type, 10>; + + std::vector<indices_type> indices; +}; + +void tag_invoke(boost::json::value_from_tag, boost::json::value&, const proc_executor_indices::runner_result&); +std::ostream& operator<<(std::ostream& stm, const proc_executor_indices::runner_result& s); + +class proc_executor_indices::runner_base: + private proc_executor::runner_base { +public: + using weight_type = xt::xtensor<value_type, 3>; + +public: + template<class E> + runner_base(const proc_executor_indices& e, const std::array<std::size_t, 2>& size, const xt::xexpression<E>& mask_acf); + runner_base(const proc_executor_indices& e, const std::array<std::size_t, 2>& size, const buffer_type& mask_acf); + runner_base(const proc_executor_indices& e, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size); + + weight_type weight() const noexcept { return weight_; } + +private: + weight_type weight_; +}; + +class proc_executor_power: + public proc_executor { +public: + struct runner_result; + +protected: + class runner_base; + +public: + proc_executor_power(const std::string& pupil_mask_filename, const std::vector<std::string>& spectral_responses, float aperture_scale, float altitude); + + executor_result run(const fits::variant_image& vi) const override = 0; + +private: + std::vector<std::string> spectral_responses_; + float aperture_scale_; + float altitude_; +}; + +struct proc_executor_power::runner_result { + using value_type = float; + + std::vector<value_type> power; +}; + +void tag_invoke(boost::json::value_from_tag, boost::json::value&, const proc_executor_power::runner_result&); +std::ostream& operator<<(std::ostream& stm, const proc_executor_power::runner_result& s); + +class proc_executor_power::runner_base: + public proc_executor::runner_base { +public: + using weight_type = xt::xtensor<value_type, 2>; + +private: + static std::pair<value_type, weif::spectral_filter<value_type>> load_spectral(const std::vector<std::string>& responses); + + template<class E1, class E2, class E3> + runner_base(const std::array<std::size_t, 2>& size, const xt::xexpression<E1>& weif, const xt::xexpression<E2>& impulse, const xt::xexpression<E3>& mask_acf); + template<class E> + runner_base(const proc_executor_power& e, const std::array<std::size_t, 2>& size, const weif::weight_function_grid_2d<value_type>& wf, const weif::digital_filter_2d<value_type>& df, const xt::xexpression<E>& mask_acf); + runner_base(const proc_executor_power& e, const std::array<std::size_t, 2>& size, const weif::digital_filter_2d<value_type>& df, std::pair<value_type, weif::spectral_filter<value_type>> spectral, const buffer_type& mask_acf); + +public: + runner_base(const proc_executor_power& e, const weif::digital_filter_2d<value_type>& df, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size); + + value_type norm() const noexcept { return norm_; } + weight_type weight() const noexcept { return weight_; } + +private: + value_type norm_; + weight_type weight_; +}; + +class proc_executor_dome: + public proc_executor_power { +private: + template<class SourceMixin> class runner; + template<class T> using runner_type = runner<source_mixin<T>>; + +public: + proc_executor_dome(const std::string& pupil_mask_filename, const std::vector<std::string>& spectral_responses, float aperture_scale, float virtual_altitude); + + executor_result run(const fits::variant_image& vi) const override; +}; + +class proc_executor_free: + public proc_executor_power { +private: + template<class SourceMixin> class runner; + template<class T> using runner_type = runner<source_mixin<T>>; + +public: + proc_executor_free(const std::string& pupil_mask_filename, const std::vector<std::string>& spectral_responses, float aperture_scale, float limit_altitude); + + executor_result run(const fits::variant_image& vi) const override; +}; + +#endif // _EXE_DOMECAM_PROC_EXECUTOR_H
View file
domecam-0.1.12.obscpio/include/executor/acf.h -> domecam-0.1.14.obscpio/include/executor/acf.h
Changed
@@ -27,8 +27,8 @@ public: acf_executor_base(const std::string& target_uri, const std::string& bias_source_uri, const std::string& pupil_source_uri, const std::string& mask_source_uri, std::size_t grid_size); - std::size_t grid_size() const { return grid_size_; } - std::size_t history_size() const { return grid_size_ ? 1 << (grid_size() - 1) : 0; } + std::size_t grid_size() const noexcept { return grid_size_; } + std::size_t history_size() const noexcept { return ((1 << grid_size_) >> 2) + 1; } private: std::size_t grid_size_; @@ -68,7 +68,8 @@ this->source().height(), e.history_size() + e.grid_size()), pipeline_mixin::runner_mixin<mean_acf_pipeline_type>( pipeline_mixin::runner_mixin<relative_clean_sp_pipeline_type>::pipeline_.width(), - pipeline_mixin::runner_mixin<relative_clean_sp_pipeline_type>::pipeline_.height()), + pipeline_mixin::runner_mixin<relative_clean_sp_pipeline_type>::pipeline_.height(), + this->source().width()), fits_sink_mixin::runner_mixin< typename mean_acf_pipeline_type::result_type::value_type, mean_acf_pipeline_type::result_type::align>(e, @@ -118,27 +119,25 @@ template<class SourceMixin> void acf_executor_base::runner<SourceMixin>::run() { this->for_each(this (const typename source_type::result_type& b) { - history_elem_type c{ - frame_num(b, frame_num_++), - pipeline_mixin::runner_mixin<relative_clean_sp_pipeline_type>::apply(b, bias(), pupil(), mask())}; - const auto& pos = c.position; - const auto& sp = c.frame; + history_.push_back(history_elem_type{frame_num(b, frame_num_++), + pipeline_mixin::runner_mixin<relative_clean_sp_pipeline_type>::apply(b, bias(), pupil(), mask())}); + + const auto& pos = history_.back().position; + const auto& sp = history_.back().frame; std::for_each(history_.begin(), history_.end(), & (const history_elem_type& h) { const auto pos_diff = pos - h.position; - /* pos_diff is not power of two */ - if ((pos_diff & (pos_diff - 1)) != 0) + /* pos_diff is not zero or power of two */ + if (pos_diff && (pos_diff & (pos_diff - 1))) return; - const auto accum_idx = __builtin_ctzl(pos_diff); - auto& a = accum_accum_idx; + const auto accum_idx = __builtin_ffsl(pos_diff); + auto& acc = accum_accum_idx; - pipeline_mixin::runner_mixin<mean_acf_pipeline_type>::apply(a.frame, h.frame, sp); - a.count++; + pipeline_mixin::runner_mixin<mean_acf_pipeline_type>::apply(acc.frame, h.frame, sp); + acc.count++; }); - - history_.push_back(std::move(c)); }); std::for_each(accum_.begin(), accum_.end(), & (accum_elem_type& a) {
View file
domecam-0.1.12.obscpio/include/executor/binary.h -> domecam-0.1.14.obscpio/include/executor/binary.h
Changed
@@ -44,7 +44,9 @@ this->source().height()), fits_sink_mixin::runner_mixin< typename pipeline_type::result_type::value_type, - pipeline_type::result_type::align>(e, this->source()) {} + pipeline_type::result_type::align>(e, + this->pipeline().width(), this->pipeline().height(), this->source().depth(), + this->source()) {} void run(); };
View file
domecam-0.1.12.obscpio/include/executor/carriage.h -> domecam-0.1.14.obscpio/include/executor/carriage.h
Changed
@@ -16,11 +16,12 @@ public carriage_executor { private: const std::optional<std::uint16_t> axis_; + const std::optional<std::uint16_t> speed_; const abstract_carriage::direction direction_; struct runner; public: - carriage_track_executor(const std::optional<std::uint16_t>& axis, abstract_carriage::direction d); + carriage_track_executor(const std::optional<std::uint16_t>& axis, const std::optional<std::uint16_t>& speed, abstract_carriage::direction d); virtual executor_result run(abstract_carriage& c) const override; }; @@ -42,10 +43,11 @@ public carriage_executor { private: const std::optional<std::uint16_t> axis_; + const std::optional<std::uint16_t> speed_; struct runner; public: - explicit carriage_home_executor(const std::optional<std::uint16_t>& axis); + carriage_home_executor(const std::optional<std::uint16_t>& axis, const std::optional<std::uint16_t>& speed); virtual executor_result run(abstract_carriage& c) const override; };
View file
domecam-0.1.12.obscpio/include/executor/clean.h -> domecam-0.1.14.obscpio/include/executor/clean.h
Changed
@@ -9,6 +9,7 @@ #include <boost/align/aligned_allocator.hpp> +#include <aux_image.h> #include <executorfwd.h> #include <executor/fits_sink_mixin.h> #include <executor/pipeline_mixin.h> @@ -37,16 +38,16 @@ using mask_buffer_type = buffer_type_t<std::uint16_t>; private: - static std::pair<mask_buffer_type, std::size_t> load_mask_image(const std::string& mask_source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size); + static std::pair<mask_buffer_type, std::size_t> load_mask_image(const std::string& mask_source_uri, const region& roi); protected: - buffer_type load_aux_image(const std::string& source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size); + buffer_type load_aux_image(const std::string& source_uri, const region& roi); private: - runner_base(std::pair<mask_buffer_type, std::size_t>&& mask, const std::string& bias_source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size); + runner_base(std::pair<mask_buffer_type, std::size_t>&& mask, const std::string& bias_source_uri, const region& roi); public: - runner_base(const std::string& bias_source_uri, const std::string& mask_source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size); + runner_base(const std::string& bias_source_uri, const std::string& mask_source_uri, const region& roi); runner_base(const clean_executor_base& e, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size); const std::size_t& active_count() const { return active_count_; }
View file
domecam-0.1.12.obscpio/include/executor/grad.h -> domecam-0.1.14.obscpio/include/executor/grad.h
Changed
@@ -44,7 +44,9 @@ this->source().height()), fits_sink_mixin::runner_mixin< typename pipeline_type::result_type::value_type, - pipeline_type::result_type::align>(e, this->source()) {} + pipeline_type::result_type::align>(e, + this->pipeline().width(), this->pipeline().height(), this->source().depth(), + this->source()) {} void run(); };
View file
domecam-0.1.12.obscpio/include/executor/mean_pupil_mask.h -> domecam-0.1.14.obscpio/include/executor/mean_pupil_mask.h
Changed
@@ -108,11 +108,17 @@ static_cast<buffer_view<typename source_type::value_type, mean_pipeline_type::mempool_type::align>>(b)); }); - const auto& r = pipeline_mixin::runner_mixin<pupil_mask_pipeline_type>::apply(accum_buffer_, rng_, nullptr); - this->append_frame(r.second); + const auto geometry, masked = pipeline_mixin::runner_mixin<pupil_mask_pipeline_type>::apply(accum_buffer_, rng_, nullptr); + this->append_frame(masked); this->commit(); - const auto& edge_geom = r.first.edge; + /* ROC AUC for geometry.ratio is 0.98, see + * domecam-empty-vs-pupil/classify.ipynb */ + if (geometry.ratio < 0.25) { + throw too_low_edge_to_noise_ratio{geometry.ratio}; + } + + const auto& edge_geom = geometry.edge; const auto hint_offset, hint_size = this->bounding_box_hint(edge_geom.center, edge_geom.radius); return {edge_geom.center, edge_geom.radius, hint_offset, hint_size};
View file
domecam-0.1.12.obscpio/include/executor/pipeline_mixin.h -> domecam-0.1.14.obscpio/include/executor/pipeline_mixin.h
Changed
@@ -21,11 +21,16 @@ typedef Pipeline pipeline_type; protected: pipeline_type pipeline_; + public: template<class... Args> runner_mixin(Args&&... args): pipeline_(std::forward<Args>(args)...) {} + const pipeline_type& pipeline() const { + return pipeline_; + } + template<class... Args> auto apply(Args&&... args) const -> decltype(pipeline_(std::forward<Args>(args)...)) {
View file
domecam-0.1.12.obscpio/include/executor/pupil.h -> domecam-0.1.14.obscpio/include/executor/pupil.h
Changed
@@ -132,10 +132,14 @@ void pupil_executor_base::runner<SourceMixin>::run_once(const typename source_type::result_type& b) { const auto& init_geometry = (e_.force_initial_ || frame_num_ == 0 ? nullptr : &geometry_); - std::tie(geometry_, std::ignore) = this->apply(b, rng_, init_geometry); const auto& position = frame_num(b, frame_num_++); - runner_base::run_once(geometry_, position); + try { + std::tie(geometry_, std::ignore) = this->apply(b, rng_, init_geometry); + runner_base::run_once(geometry_, position); + } catch(const std::exception& e) { + std::cerr << "Frame " << position << " processing failed due to: " << e.what() << std::endl; + } } template<class SourceMixin>
View file
domecam-0.1.12.obscpio/include/executor/relative_clean.h -> domecam-0.1.14.obscpio/include/executor/relative_clean.h
Changed
@@ -28,7 +28,7 @@ class relative_clean_executor_base::runner_base: public clean_executor_base::runner_base { private: - buffer_type load_pupil_image(const std::string& source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size); + buffer_type load_pupil_image(const std::string& source_uri, const region& roi); public: runner_base(const relative_clean_executor_base& e, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size);
View file
domecam-0.1.12.obscpio/include/fft.h -> domecam-0.1.14.obscpio/include/fft.h
Changed
@@ -13,11 +13,13 @@ #include <fftw3.h> +#include <fptr_deleter.h> + class fft_base { private: std::size_t width_; std::size_t height_; - std::unique_ptr<fftwf_plan_s, void(*)(fftwf_plan_s*)> plan_; + std::unique_ptr<fftwf_plan_s, fptr_deleter<&fftwf_destroy_plan>> plan_; protected: fftwf_plan plan() const noexcept { return plan_.get(); } @@ -26,7 +28,7 @@ fft_base(std::size_t width, std::size_t height, fftwf_plan plan): width_{width}, height_{height}, - plan_{plan, &fftwf_destroy_plan} { + plan_{plan} { assert(plan != nullptr); } @@ -84,13 +86,16 @@ public: /* There is no FFTW_PRESERVE_INPUT for _c2r */ - fft_backward(std::size_t width, std::size_t height, const allocator_type& alloc = allocator_type()): - fft_base(2*(width-1), height, - fftwf_plan_dft_c2r_2d(height, 2*(width-1), + fft_backward(std::size_t width, std::size_t height, std::size_t logic_width, const allocator_type& alloc = allocator_type()): + fft_base(logic_width, height, + fftwf_plan_dft_c2r_2d(height, logic_width, reinterpret_cast<fftwf_complex*>(Align), reinterpret_cast<result_type*>(3*Align), // 3 is a prime number FFTW_ESTIMATE | FFTW_DESTROY_INPUT)), - allocator_type(alloc) {} + allocator_type(alloc) { + + assert(logic_width / 2 + 1 == width); + } template<class AllocatorIn> inline buffer_type operator() (buffer<value_type, Align, AllocatorIn> b) const;
View file
domecam-0.1.12.obscpio/include/fits.h -> domecam-0.1.14.obscpio/include/fits.h
Changed
@@ -120,9 +120,11 @@ class fits { private: - static void deleter(fitsfile* ptr); + struct deleter { + void operator() (fitsfile* ptr) const noexcept; + }; - std::unique_ptr<fitsfile, decltype(&deleter)> file_; + std::unique_ptr<fitsfile, deleter> file_; public: struct dimensions { std::size_t width, height, depth; @@ -153,6 +155,8 @@ template<class T> class image: public image_base { public: + using value_type = T; + image(fits& f, std::size_t width, std::size_t height, std::size_t depth): image_base(f, width, height, depth) { }
View file
domecam-0.1.14.obscpio/include/fptr_deleter.h
Added
@@ -0,0 +1,19 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2022 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#ifndef _FPTR_DELETER_H +#define _FPTR_DELETER_H + +template<auto Fptr> +struct fptr_deleter { + + template<class U> + constexpr void operator() (U* obj) const noexcept { + Fptr(obj); + } +}; + +#endif // _FPTR_DELETER_H
View file
domecam-0.1.12.obscpio/include/grad.h -> domecam-0.1.14.obscpio/include/grad.h
Changed
@@ -226,7 +226,9 @@ auto& gx = std::get<0>(grad_vector); auto& gy = std::get<1>(grad_vector); - buffer_type gn{b.size(), alloc_}; + assert(gx.size() == gy.size()); + + buffer_type gn{gx.size(), alloc_}; norm(gx, gy, gn); return std::make_tuple(std::move(gn), std::move(gx), std::move(gy));
View file
domecam-0.1.12.obscpio/include/pipeline.h -> domecam-0.1.14.obscpio/include/pipeline.h
Changed
@@ -497,10 +497,10 @@ fft_backward_type fft_backward_; public: - mean_acf_pipeline(std::size_t width, std::size_t height): + mean_acf_pipeline(std::size_t width, std::size_t height, std::size_t logic_width): pool_(width * height * sizeof(value_type), 2), multiplies_conj_op_(width, height, multiplies_conj_op_type::allocator_type(pool_)), - fft_backward_(width, height, fft_backward_type::allocator_type(pool_)) {} + fft_backward_(width, height, logic_width, fft_backward_type::allocator_type(pool_)) {} inline buffer_type& operator() (buffer_type& accum, buffer_view<value_type, mempool_type::align> lhs, buffer_view<value_type, mempool_type::align> rhs) const; inline result_type operator() (buffer_type accum, value_type::value_type count) const;
View file
domecam-0.1.12.obscpio/include/pupil_geom.h -> domecam-0.1.14.obscpio/include/pupil_geom.h
Changed
@@ -156,6 +156,8 @@ } variance /= 2 * bg_count; + assert(variance >= static_cast<value_type>(0)); + return ret; } @@ -194,6 +196,9 @@ throw singular_sample_set(); radius = ((mx * mgx - mxgx) + (my * mgy - mygy)) / denom; + if (radius == static_cast<value_type>(0)) + throw singular_sample_set(); + cx = mgx * radius + mx; cy = mgy * radius + my; @@ -203,10 +208,15 @@ const auto dy = cy - y.data()i; const auto& igx = gx.data()i; const auto& igy = gy.data()i; - variance += edge_t.data()i * (dx * (dx - static_cast<value_type>(2) * radius * igx) - + dy * (dy - static_cast<value_type>(2) * radius * igy) + radius * radius); + const auto dn = igx * dx + igy * dy - radius; + const auto dt = igy * dx - igx * dy; + variance += edge_t.data()i * (dn * dn + dt * dt); } variance /= 2 * edge_count; + if (variance == static_cast<value_type>(0)) + throw singular_sample_set(); + + assert(variance > static_cast<value_type>(0)); return ret; } @@ -228,15 +238,17 @@ const auto dy = std::get<1>(edge.center) - s.y.data()i; const auto& igx = s.gx.data()i; const auto& igy = s.gy.data()i; - const auto c = dx * (dx - static_cast<value_type>(2) * edge.radius * igx) - + dy * (dy - static_cast<value_type>(2) * edge.radius * igy) + edge.radius * edge.radius; + const auto dn = igx * dx + igy * dy - edge.radius; + const auto dt = igy * dx - igx * dy; + const auto c = dn * dn + dt * dt; edge_t.data()i = edge_ratio / edge.variance * std::exp(-static_cast<value_type>(0.5) / edge.variance * c); } for (std::size_t i = 0; i < size; ++i) { const auto dx = std::get<0>(bg.center) - s.x.data()i; const auto dy = std::get<1>(bg.center) - s.y.data()i; - bg_t.data()i = bg_ratio / bg.variance * std::exp(-static_cast<value_type>(0.5) / bg.variance * (dx * dx + dy * dy)); + const auto c = dx * dx + dy * dy; + bg_t.data()i = bg_ratio / bg.variance * std::exp(-static_cast<value_type>(0.5) / bg.variance * c); } for (std::size_t i = 0; i < size; ++i) {
View file
domecam-0.1.14.obscpio/include/pupil_mask_acf.h
Added
@@ -0,0 +1,137 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2023 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#ifndef _PUPIL_MASK_ACF_H +#define _PUPIL_MASK_ACF_H + +#include <algorithm> +#include <cassert> +#include <complex> +#include <memory> + +#include <buffer.h> +#include <buffer_view.h> + +#include <fftw3.h> + +#include <fptr_deleter.h> + + +namespace detail { + +template<std::size_t Align, class Allocator = std::allocator<float>> +class pupil_mask_acf_base: + private Allocator { +public: + using value_type = float; + using result_type = value_type; + using allocator_type = Allocator; + using buffer_type = buffer<result_type, Align, allocator_type>; + +protected: + std::size_t width_; + std::size_t height_; + +private: + std::unique_ptr<fftwf_plan_s, fptr_deleter<&fftwf_destroy_plan>> forward_plan_; + std::unique_ptr<fftwf_plan_s, fptr_deleter<&fftwf_destroy_plan>> backward_plan_; + +protected: + const allocator_type& get_allocator() const noexcept { return *this; } + + buffer_type operator() (buffer<value_type, Align, Allocator> b) const; + + ~pupil_mask_acf_base() = default; +public: + pupil_mask_acf_base(std::size_t width, std::size_t height, const allocator_type& alloc = allocator_type()): + Allocator(alloc), + width_{width * 2}, + height_{height * 2}, + forward_plan_{fftwf_plan_dft_r2c_2d(height_, width_, + reinterpret_cast<value_type*>(Align), + reinterpret_cast<fftwf_complex*>(Align), + FFTW_ESTIMATE | FFTW_DESTROY_INPUT)}, + backward_plan_{fftwf_plan_dft_c2r_2d(height_, width_, + reinterpret_cast<fftwf_complex*>(Align), + reinterpret_cast<value_type*>(3 * Align), + FFTW_ESTIMATE | FFTW_DESTROY_INPUT)} { + + assert(forward_plan_ != nullptr); + assert(backward_plan_ != nullptr); + } + + std::size_t width() const noexcept { return width_; } + std::size_t height() const noexcept { return height_; } +}; + +template<std::size_t Align, class Allocator> +typename pupil_mask_acf_base<Align, Allocator>::buffer_type +pupil_mask_acf_base<Align, Allocator>::operator() (buffer<value_type, Align, Allocator> b) const { + buffer_type ret{width_ * height_, this->get_allocator()}; + + fftwf_execute_dft_r2c(forward_plan_.get(), b.data(), reinterpret_cast<fftwf_complex*>(b.data())); + + const auto cbegin = reinterpret_cast<std::complex<value_type>*>(b.data()); + const auto cend = reinterpret_cast<std::complex<value_type>*>(b.data() + b.size()); + std::transform(cbegin, cend, cbegin, (const std::complex<value_type>& z) noexcept { + return std::norm(z); + }); + + fftwf_execute_dft_c2r(backward_plan_.get(), reinterpret_cast<fftwf_complex*>(b.data()), ret.data()); + + const value_type fft_norm = width_ * height_; + std::transform(ret.cbegin(), ret.cend(), ret.begin(), fft_norm (const value_type x) noexcept { + return x / fft_norm; + }); + + return ret; +} + +} // detail + +template<class T, std::size_t Align = alignof(float), class Allocator = std::allocator<float>> +class pupil_mask_acf: + public detail::pupil_mask_acf_base<Align, Allocator> { +public: + using value_type = T; + using result_type = float; + using allocator_type = Allocator; + using buffer_type = buffer<result_type, Align, allocator_type>; + +public: + pupil_mask_acf(std::size_t width, std::size_t height, const allocator_type& alloc = allocator_type()): + detail::pupil_mask_acf_base<Align, Allocator>(width, height, alloc) {} + + buffer_type operator() (buffer_view<T, Align> b) const; +}; + +template<class T, std::size_t Align, class Allocator> +typename pupil_mask_acf<T, Align, Allocator>::buffer_type +pupil_mask_acf<T, Align, Allocator>::operator() (buffer_view<T, Align> b) const { + const auto half_width = this->width_ / 2; + const auto half_height = this->height_ / 2; + + /* Need additional padding for in-place real-to-complex FFT */ + const auto width = (this->width_ + 2 - this->width_ % 2); + + buffer_type padded{width * this->height_, this->get_allocator()}; + padded.clear(); + + auto it = b.cbegin(); + + assert(b.size() == half_width * half_height); + + for (std::size_t i = 0; i < half_height; ++i) { + for (std::size_t j = 0, n = i * width; j < half_width; ++j, ++n, ++it) { + if (*it != static_cast<value_type>(0)) + padded.data()n = static_cast<result_type>(1); + } + } + + return detail::pupil_mask_acf_base<Align, Allocator>::operator() (std::move(padded)); +} + +#endif // _PUPIL_MASK_ACF_H
View file
domecam-0.1.12.obscpio/include/stream.h -> domecam-0.1.14.obscpio/include/stream.h
Changed
@@ -17,6 +17,7 @@ #include <buffer.h> #include <buffer_view.h> #include <error.h> +#include <fptr_deleter.h> #include <mempool.h> struct error_timeout: public error { @@ -50,7 +51,7 @@ template<class T> inline frame<T> dequeue(ArvBuffer* arvbuffer) const noexcept; private: mempool_type mempool_; - std::unique_ptr<ArvStream, decltype(&g_object_unref)> stream_; + std::unique_ptr<ArvStream, fptr_deleter<&g_object_unref>> stream_; public: stream(ArvDevice* device, std::size_t size, std::size_t num);
View file
domecam-0.1.14.obscpio/src/aux_image.cpp
Added
@@ -0,0 +1,59 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2023 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#include <aux_image.h> + + +region region::from_fits(const fits& f) { + return {{f.read_key_optional<std::uint32_t>("XOFFSET").value_or(0), + f.read_key_optional<std::uint32_t>("YOFFSET").value_or(0)}, + {f.image_dimensions().width, + f.image_dimensions().height}}; +} + +bool region::within(const region& other) const noexcept { + const auto& xoffset, yoffset = offset_; + const auto& other_xoffset, other_yoffset = other.offset_; + const auto& width, height = size_; + const auto& other_width, other_height = other.size_; + + if (xoffset < other_xoffset || yoffset < other_yoffset) + return false; + + if (other_width < width || other_height < height) + return false; + + if (other_width - width < other_xoffset - xoffset || other_height - height < other_yoffset - yoffset) + return false; + + return true; +} + +bool region::contains(const region& other) const noexcept { + return other.within(*this); +} + +region region::project(const region& other) const noexcept { + return {{other.offset_0 - offset_0, other.offset_1 - offset_1}, size()}; +} + +#if 0 +aux_image::aux_image(fits& f, const region& requested_region, const region& image_region): + image_{f.load_image()}, + region_{ + {requested_region.offset0 - image_region.offset0, + requested_region.offset1 - image_region.offset1}, requested_region.size} { + + if (!image_region.contains(requested_region)) + throw aux_image_incorrect_position{requested_region.offset, requested_region.size}; +} + +aux_image::aux_image(fits& f, const region& r): + aux_image(f, r, region::from_fits(f)) {} + +aux_image::aux_image(fits& f, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size): + aux_image(f, region{offset, size}) {} +#endif
View file
domecam-0.1.12.obscpio/src/camera.cpp -> domecam-0.1.14.obscpio/src/camera.cpp
Changed
@@ -11,7 +11,7 @@ #include <cstring> camera_object::camera_object(const char* name): - camera_(arv_error::apply_or_throw(&arv_camera_new, name), &g_object_unref) { + camera_(arv_error::apply_or_throw(&arv_camera_new, name)) { assert(camera_ != nullptr); }
View file
domecam-0.1.12.obscpio/src/carriage.cpp -> domecam-0.1.14.obscpio/src/carriage.cpp
Changed
@@ -494,6 +494,8 @@ status_(status) { } +constexpr std::uint16_t abstract_carriage::default_speed; + std::size_t carriage::available() { return serial_io::available(); }
View file
domecam-0.1.12.obscpio/src/curl.cpp -> domecam-0.1.14.obscpio/src/curl.cpp
Changed
@@ -44,9 +44,17 @@ curl_global_cleanup(); } +void curl::deleter::operator() (CURL* ptr) const noexcept { + curl_easy_cleanup(ptr); +} + +void curl::list_deleter::operator() (struct curl_slist* ptr) const noexcept { + curl_slist_free_all(ptr); +} + curl::curl(): - curl_{do_init(), &deleter}, - header_list_{nullptr, &list_deleter} { + curl_{do_init()}, + header_list_{nullptr} { libcurl_error::throw_on_error(curl_easy_setopt(curl_.get(), CURLOPT_FAILONERROR, 1L)); } @@ -79,11 +87,3 @@ return c; } -void curl::deleter(CURL* ptr) { - curl_easy_cleanup(ptr); -} - -void curl::list_deleter(struct curl_slist* ptr) { - curl_slist_free_all(ptr); -} -
View file
domecam-0.1.12.obscpio/src/device.cpp -> domecam-0.1.14.obscpio/src/device.cpp
Changed
@@ -8,7 +8,7 @@ #include <stream.h> device::device(ArvDevice* device): - device_{static_cast<ArvDevice*>(g_object_ref(device)), &g_object_unref} { + device_{static_cast<ArvDevice*>(g_object_ref(device))} { } device::device(const device& other):
View file
domecam-0.1.12.obscpio/src/error.cpp -> domecam-0.1.14.obscpio/src/error.cpp
Changed
@@ -35,6 +35,10 @@ validation_error(reinterpret_cast<std::ostringstream&>(std::ostringstream() << "Too many pixels correspoinding to edges: " << s).str()) { } +too_low_edge_to_noise_ratio::too_low_edge_to_noise_ratio(float ratio): + validation_error(reinterpret_cast<std::ostringstream&>(std::ostringstream() << "Too low edge to noise ratio: " << ratio).str()) { +}; + singular_sample_set::singular_sample_set(): validation_error("Sample set is singular") { } @@ -45,12 +49,12 @@ arv_error::arv_error(GError* error): std::exception(), - error_{error, &g_error_free} { + error_{error} { } arv_error::arv_error(const arv_error& other): std::exception(), - error_{g_error_copy(other.error_.get()), &g_error_free} { + error_{g_error_copy(other.error_.get())} { } arv_error::~arv_error() = default;
View file
domecam-0.1.12.obscpio/src/executor/acf.cpp -> domecam-0.1.14.obscpio/src/executor/acf.cpp
Changed
@@ -4,12 +4,14 @@ * Copyright (C) 2017-2022 Matwey V. Kornilov <matwey.kornilov@gmail.com> */ +#include <algorithm> + #include <executor/acf.h> acf_executor_base::acf_executor_base(const std::string& target_uri, const std::string& bias_source_uri, const std::string& pupil_source_uri, const std::string& mask_source_uri, std::size_t grid_size): relative_clean_executor_base(target_uri, bias_source_uri, pupil_source_uri, mask_source_uri), - grid_size_{grid_size} {} + grid_size_{std::max(grid_size, static_cast<std::size_t>(1))} {} acf_executor::acf_executor(const std::string& target_uri, std::size_t frames_number, const std::string& bias_source_uri, const std::string& pupil_source_uri, const std::string& mask_source_uri, std::size_t grid_size):
View file
domecam-0.1.12.obscpio/src/executor/carriage.cpp -> domecam-0.1.14.obscpio/src/executor/carriage.cpp
Changed
@@ -26,13 +26,17 @@ if (executor_.axis_) { c_.axis(*executor_.axis_); } + if (executor_.speed_) { + c_.speed(*executor_.speed_); + } c_.sync_track(executor_.direction_); } -carriage_track_executor::carriage_track_executor(const std::optional<std::uint16_t>& axis, abstract_carriage::direction d): +carriage_track_executor::carriage_track_executor(const std::optional<std::uint16_t>& axis, const std::optional<std::uint16_t>& speed, abstract_carriage::direction d): carriage_executor(), axis_{axis}, + speed_{speed}, direction_{d} { } @@ -103,12 +107,16 @@ if (executor_.axis_) { c_.axis(*executor_.axis_); } + if (executor_.speed_) { + c_.speed(*executor_.speed_); + } c_.home(); } -carriage_home_executor::carriage_home_executor(const std::optional<std::uint16_t>& axis): +carriage_home_executor::carriage_home_executor(const std::optional<std::uint16_t>& axis, const std::optional<std::uint16_t>& speed): carriage_executor(), - axis_(axis) { + axis_{axis}, + speed_{speed} { } executor_result carriage_home_executor::run(abstract_carriage& c) const {
View file
domecam-0.1.12.obscpio/src/executor/clean.cpp -> domecam-0.1.14.obscpio/src/executor/clean.cpp
Changed
@@ -7,36 +7,6 @@ #include <executor/clean.h> #include <masked.h> -namespace { - std::pair<std::array<std::size_t, 2>, std::array<std::size_t, 2>> unpack_image_region(const fits& f) { - return {{f.read_key_optional<std::uint32_t>("XOFFSET").value_or(0), - f.read_key_optional<std::uint32_t>("YOFFSET").value_or(0)}, - {f.image_dimensions().width, - f.image_dimensions().height}}; - } - - std::optional<std::array<std::size_t, 2>> relative_region(const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size, const std::array<std::size_t, 2>& target_offset, const std::array<std::size_t, 2>& target_size) { - const auto& xoffset, yoffset = offset; - const auto& target_xoffset, target_yoffset = target_offset; - const auto& width, height = size; - const auto& target_width, target_height = target_size; - - if (xoffset < target_xoffset || yoffset < target_yoffset) - return {}; - - if (target_width < width || target_height < height) - return {}; - - const std::array<std::size_t, 2> rel_offset{ - target_xoffset - xoffset, target_yoffset - yoffset}; - - if (target_width - width < rel_offset0 || target_height - height < rel_offset1) - return {}; - - return rel_offset; - } -} - clean_executor_base::clean_executor_base(const std::string& target_uri, const std::string& bias_source_uri, const std::string& mask_source_uri): fits_sink_mixin(target_uri), @@ -45,9 +15,9 @@ mask_source_uri_{mask_source_uri} {} std::pair<clean_executor_base::runner_base::mask_buffer_type, std::size_t> -clean_executor_base::runner_base::load_mask_image(const std::string& mask_source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size) { +clean_executor_base::runner_base::load_mask_image(const std::string& mask_source_uri, const region& roi) { constexpr std::size_t mask_capacity = sizeof(mask_buffer_type::value_type) * 8; - const auto& width, height = size; + const auto& width, height = roi.size(); assert(width > 0); assert(height > 0); @@ -58,13 +28,13 @@ auto mask_it = mask.begin(); fits mask_fits{mask_source_uri}; - const auto image_offset, image_size = unpack_image_region(mask_fits); - const auto rel_offset = relative_region(offset, size, image_offset, image_size); - if (!rel_offset) - throw aux_image_incorrect_position{mask_source_uri, offset, size}; + const auto image_region = region::from_fits(mask_fits); + if (!roi.within(image_region)) + throw aux_image_incorrect_position{mask_source_uri, roi.offset(), roi.size()}; + const auto proj_roi = roi.project(image_region); mask_fits.load_image().apply(& (const auto& image) { - const auto frame = image.read_frame_range(0, *rel_offset, size); + const auto frame = image.read_frame_range(0, proj_roi.offset(), proj_roi.size()); for (auto it = frame.cbegin(); it != frame.cend(); ++mask_it) { *mask_it = 0; @@ -86,17 +56,17 @@ } clean_executor_base::runner_base::buffer_type -clean_executor_base::runner_base::load_aux_image(const std::string& source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size) { +clean_executor_base::runner_base::load_aux_image(const std::string& source_uri, const region& roi) { buffer_type ret{active_count()}; fits aux_fits{source_uri}; - const auto image_offset, image_size = unpack_image_region(aux_fits); - const auto rel_offset = relative_region(offset, size, image_offset, image_size); - if (!rel_offset) - throw aux_image_incorrect_position{source_uri, offset, size}; + const auto image_region = region::from_fits(aux_fits); + if (!roi.within(image_region)) + throw aux_image_incorrect_position{source_uri, roi.offset(), roi.size()}; + const auto proj_roi = roi.project(image_region); maybe_unused const auto last = aux_fits.load_image().apply(& (const auto& image) { - const auto frame = image.read_frame_range(0, *rel_offset, size); + const auto frame = image.read_frame_range(0, proj_roi.offset(), proj_roi.size()); return copy_masked(frame.cbegin(), frame.cend(), mask().cbegin(), ret.begin()); }); @@ -106,16 +76,16 @@ return ret; } -clean_executor_base::runner_base::runner_base(std::pair<mask_buffer_type, std::size_t>&& mask, const std::string& bias_source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size): +clean_executor_base::runner_base::runner_base(std::pair<mask_buffer_type, std::size_t>&& mask, const std::string& bias_source_uri, const region& roi): active_count_{mask.second}, mask_{std::move(mask.first)}, - bias_{load_aux_image(bias_source_uri, offset, size)} {} + bias_{load_aux_image(bias_source_uri, roi)} {} -clean_executor_base::runner_base::runner_base(const std::string& bias_source_uri, const std::string& mask_source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size): - runner_base(load_mask_image(mask_source_uri, offset, size), bias_source_uri, offset, size) {} +clean_executor_base::runner_base::runner_base(const std::string& bias_source_uri, const std::string& mask_source_uri, const region& roi): + runner_base(load_mask_image(mask_source_uri, roi), bias_source_uri, roi) {} clean_executor_base::runner_base::runner_base(const clean_executor_base& e, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size): - runner_base(e.bias_source_uri_, e.mask_source_uri_, offset, size) {} + runner_base(e.bias_source_uri_, e.mask_source_uri_, region{offset, size}) {} clean_executor::clean_executor(const std::string& target_uri, std::size_t frames_number, const std::string& bias_source_uri, const std::string& mask_source_uri):
View file
domecam-0.1.12.obscpio/src/executor/relative_clean.cpp -> domecam-0.1.14.obscpio/src/executor/relative_clean.cpp
Changed
@@ -13,8 +13,8 @@ pupil_source_uri_{pupil_source_uri} {} relative_clean_executor_base::runner_base::buffer_type -relative_clean_executor_base::runner_base::load_pupil_image(const std::string& source_uri, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size) { - auto ret = load_aux_image(source_uri, offset, size); +relative_clean_executor_base::runner_base::load_pupil_image(const std::string& source_uri, const region& roi) { + auto ret = load_aux_image(source_uri, roi); std::transform(ret.cbegin(), ret.cend(), ret.begin(), (const auto& x) { return static_cast<decltype(x)>(1) / x; @@ -25,7 +25,7 @@ relative_clean_executor_base::runner_base::runner_base(const relative_clean_executor_base& e, const std::array<std::size_t, 2>& offset, const std::array<std::size_t, 2>& size): clean_executor_base::runner_base(e, offset, size), - pupil_{load_pupil_image(e.pupil_source_uri_, offset, size)} {} + pupil_{load_pupil_image(e.pupil_source_uri_, region{offset, size})} {} relative_clean_executor::relative_clean_executor(const std::string& target_uri, std::size_t frames_number, const std::string& bias_source_uri, const std::string& pupil_source_uri, const std::string& mask_source_uri): camera_executor(frames_number),
View file
domecam-0.1.12.obscpio/src/fits.cpp -> domecam-0.1.14.obscpio/src/fits.cpp
Changed
@@ -45,7 +45,7 @@ return std::string{err_msg}; } -void fits::deleter(fitsfile* ptr) { +void fits::deleter::operator()(fitsfile* ptr) const noexcept { int status = 0; fits_close_file(ptr, &status); } @@ -62,8 +62,8 @@ cfitsio_error::throw_on_error(status); } -fits::fits(fitsfile* f): file_(f, &deleter) { -} +fits::fits(fitsfile* f): + file_(f) {} fitsfile* fits::do_open(const char* filename) { int status = 0;
View file
domecam-0.1.12.obscpio/src/io.cpp -> domecam-0.1.14.obscpio/src/io.cpp
Changed
@@ -85,12 +85,16 @@ value_to<std::uint16_t>(obj.at("axis")), value_to<std::int16_t>(obj.at("position"))}}; } else if (type == "carriage_track") { + const auto speed = load<std::uint16_t>(obj.if_contains("speed")).value_or(carriage::default_speed); + return std::unique_ptr<executor>{new carriage_track_executor{ - value_to<std::uint16_t>(obj.at("axis")), + value_to<std::uint16_t>(obj.at("axis")), speed, value_to<abstract_carriage::direction>(obj.at("direction"))}}; } else if (type == "carriage_home") { + const auto speed = load<std::uint16_t>(obj.if_contains("speed")).value_or(carriage::default_speed); + return std::unique_ptr<executor>{new carriage_home_executor{ - value_to<std::uint16_t>(obj.at("axis"))}}; + value_to<std::uint16_t>(obj.at("axis")), speed}}; } else if (type == "clean" || type == "normalized_clean" || type == "relative_clean" || type == "acf") { const auto& filename = value_to<std::string>(obj.at("filename")); const auto& frames_number = value_to<std::size_t>(obj.at("frames_number"));
View file
domecam-0.1.12.obscpio/src/mempool.cpp -> domecam-0.1.14.obscpio/src/mempool.cpp
Changed
@@ -19,19 +19,20 @@ assert(size_ % align_ == 0); - const std::size_t full_size = size_ * chunks + align_; + std::size_t space = size_ * chunks + align_; #if __cpp_aligned_new >= 201606L - mem_.reset(new (std::align_val_t(align_)) charfull_size); + mem_.reset(new (std::align_val_t(align_)) charspace); #else - mem_.reset(new charfull_size); + mem_.reset(new charspace); #endif - char* c = mem_.get(); - c = reinterpret_cast<char*>((reinterpret_cast<std::uintptr_t>(c) + align_ - 1) & -align_); + void* ptr = mem_.get(); + char* c = reinterpret_cast<char*>(std::align(align, size_ * chunks, ptr, space)); - for (std::size_t i = 0; i < chunks; ++i, c += size_) { - assert(c + size_ <= mem_.get() + full_size); + assert(c != nullptr); + assert(space >= size_ * chunks); + for (std::size_t i = 0; i < chunks; ++i, c += size_) { /* Add region to free list */ deallocate(reinterpret_cast<void*>(c)); }
View file
domecam-0.1.12.obscpio/src/stream.cpp -> domecam-0.1.14.obscpio/src/stream.cpp
Changed
@@ -45,7 +45,7 @@ stream::stream(ArvDevice* device, std::size_t size, std::size_t num): mempool_(size, num), - stream_(arv_error::apply_or_throw(&arv_device_create_stream, device, nullptr, nullptr), &g_object_unref) { + stream_(arv_error::apply_or_throw(&arv_device_create_stream, device, nullptr, nullptr)) { for (; num > 0; --num) { auto b = arv_buffer_new_full(size, mempool_.allocate(), stream_.get(), nullptr);
View file
domecam-0.1.14.obscpio/test/CMakeLists.txt
Added
@@ -0,0 +1,32 @@ +cmake_minimum_required (VERSION 3.5) + +set(CMAKE_CXX_STANDARD 17) + +include(GNUInstallDirs) + +find_package(Threads REQUIRED) +find_package(PkgConfig REQUIRED) +pkg_check_modules(CPPUNIT REQUIRED IMPORTED_TARGET cppunit) + +# CheckIPOSupported module is available since 3.9 +# VERSION_GREATER_EQUAL is available since 3.7 +if(NOT (CMAKE_VERSION VERSION_LESS "3.9.0")) + # check_ipo_supported() returns an error when CMP0069 is OLD + cmake_policy(SET CMP0069 NEW) + + include(CheckIPOSupported) + check_ipo_supported(RESULT HAS_LTO_SUPPORT) +endif() + +file(GLOB_RECURSE TESTS *.cpp) +foreach(test_source IN ITEMS ${TESTS}) + string(REPLACE ${CMAKE_SOURCE_DIR}/ "" test_name ${test_source}) + string(REPLACE / _ test_name ${test_name}) + string(REPLACE .cpp "" test_name ${test_name}) + add_executable(${test_name} ${test_source}) + target_link_libraries(${test_name} domecam PkgConfig::CPPUNIT Threads::Threads) + if(HAS_LTO_SUPPORT) + set_property(TARGET ${test_name} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) + endif(HAS_LTO_SUPPORT) + add_test(${test_name} ${test_name}) +endforeach(test_source)
View file
domecam-0.1.14.obscpio/test/pupil_mask_acf.cpp
Added
@@ -0,0 +1,110 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright (C) 2017-2023 Matwey V. Kornilov <matwey.kornilov@gmail.com> + */ + +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/ui/text/TestRunner.h> +#include <cppunit/TestAssert.h> + +#include <array> +#include <numeric> + +#include <boost/align/aligned_allocator.hpp> + +#include <buffer.h> +#include <buffer_view.h> +#include <pupil_mask_acf.h> + +namespace CPPUNIT_NS { + +template<class U, std::size_t Align> +struct assertion_traits<buffer_view<U, Align>> { + static bool equal(const buffer_view<U, Align> x, const buffer_view<U, Align> y) { + if (x.size() != y.size()) + return false; + + return std::equal(x.data(), x.data() + x.size(), y.data()); + } + + static std::string toString(const buffer_view<U, Align> x) { + std::ostringstream oss; + oss << "" << x.size() << ""; + for (std::size_t i = 0; i < x.size(); ++i) { + oss << " " << x.data()i; + } + return oss.str(); + } +}; + +} // CPPUNIT_NS + +template<class T> using allocator_type = boost::alignment::aligned_allocator<T, 32>; + +class test_pupil_mask_acf_suite: public CppUnit::TestCase { +CPPUNIT_TEST_SUITE(test_pupil_mask_acf_suite); +CPPUNIT_TEST(test_pupil_mask_acf1); +CPPUNIT_TEST(test_pupil_mask_acf2); +CPPUNIT_TEST(test_pupil_mask_acf3); +CPPUNIT_TEST_SUITE_END(); + +void test_pupil_mask_acf1() { + constexpr std::size_t width = 5; + constexpr std::size_t height = 5; + + buffer<std::size_t, 32, allocator_type<std::size_t>> arr{width * height}; + arr.clear(); + arr.data()0 = 1; + + buffer<float, 32, allocator_type<float>> expected{width * height * 4}; + expected.clear(); + expected.data()0 = 1; + + pupil_mask_acf<std::size_t, 32, allocator_type<float>> pma{width, height}; + const auto res = pma(arr); + + CPPUNIT_ASSERT_EQUAL(expected.as_view(), res.as_view()); +} + +void test_pupil_mask_acf2() { + constexpr std::size_t width = 6; + constexpr std::size_t height = 6; + + buffer<std::size_t, 32, allocator_type<std::size_t>> arr{width * height}; + arr.clear(); + arr.data()12 = 1; + + buffer<float, 32, allocator_type<float>> expected{width * height * 4}; + expected.clear(); + expected.data()0 = 1; + + pupil_mask_acf<std::size_t, 32, allocator_type<float>> pma{width, height}; + const auto res = pma(arr); + + CPPUNIT_ASSERT_EQUAL(expected.as_view(), res.as_view()); +} + +void test_pupil_mask_acf3() { + constexpr std::size_t width = 4; + constexpr std::size_t height = 4; + + buffer<std::size_t, 32, allocator_type<std::size_t>> arr{width * height}; + std::fill(arr.begin(), arr.end(), 1); + + pupil_mask_acf<std::size_t, 32, allocator_type<float>> pma{width, height}; + const auto res = pma(arr); + + CPPUNIT_ASSERT_EQUAL(16.0f, res.data()0); +} + +}; +CPPUNIT_TEST_SUITE_REGISTRATION(test_pupil_mask_acf_suite); + +int main(int argc, char **argv) { + CppUnit::TextUi::TestRunner runner; + CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + runner.addTest(registry.makeTest()); + return !runner.run("", false); +}
View file
domecam.obsinfo
Changed
@@ -1,3 +1,3 @@ name: domecam -version: 0.1.12 -mtime: 1667807318 +version: 0.1.14 +mtime: 1695372994
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.